鼠标提示拼接文本超过 1024 字符时偶发弹出 “Encountered an improper argument.” 错误
Author: ObnubiladOCreated Sep 9, 2026Updated Sep 9, 2026
前置条件
您当前使用的TrafficMonitor版本
1.86(x64)
您当前使用的操作系统版本
Windows 11 x64
发生了什么?
TrafficMonitor 会偶发弹出标题为 "TrafficMonitor"、内容为 "Encountered an improper argument." 的错误弹窗(错误图标)。通常在启动后一分钟内出现,也可能稍晚出现,关闭后还可能再次弹出;程序本身不会崩溃,能继续正常运行。
这是 MFC 的 CInvalidArgException。根本原因:TrafficMonitor 每隔一次数据刷新(大约每秒一次)都会重新拼接完整的“鼠标提示”字符串并传给 CToolTipCtrl::UpdateTipText,而 MFC 在该函数中强制限制提示文本不能超过 1024 个字符,超长即抛出异常:
// VS2022 MFC, atlmfc/include/afxcmn.h, 第 22 行:
const size_t MAX_TIP_TEXT_LENGTH = 1024;
// VS2022 MFC, atlmfc/src/mfc/tooltip.cpp, CToolTipCtrl::UpdateTipText:
void CToolTipCtrl::UpdateTipText(LPCTSTR lpszText, CWnd* pWnd, UINT_PTR nIDTool)
{
ENSURE(::IsWindow(m_hWnd));
ENSURE_ARG(pWnd != NULL);
if (lpszText != LPSTR_TEXTCALLBACK)
{
ENSURE_ARG(AtlStrLen(lpszText) <= MAX_TIP_TEXT_LENGTH); // <-- 超长时抛 CInvalidArgException
}
...
}
而 TrafficMonitor 拼接出来的提示文本没有任何长度上限:
CTrafficMonitorDlg::GetMouseTipsInfo()(TrafficMonitorDlg.cpp:133)拼接主窗口提示文本,并在第 217 行追加所有已加载插件的提示文本拼接结果;CTaskBarDlg::GetMouseTipsInfo()(TaskBarDlg.cpp:698)对任务栏窗口做同样的事(第 790 行追加插件提示);CTrafficMonitorApp::GetPlauginTooltipInfo()(TrafficMonitor.cpp:1209)用\r\n把所有插件的GetTooltipInfo()拼在一起;CTrafficMonitorDlg::OnMonitorInfoUpdated()(TrafficMonitorDlg.cpp:2845)每次刷新都会调用m_tool_tips.UpdateTipText(tip_info, this)(第 2854 行),任务栏窗口则通过CTaskBarDlg::UpdateToolTips()(TaskBarDlg.cpp:943,第 949 行)调用。
提示文本里包含动态内容(传感器名称/数值、被隐藏项目的行、各插件文本),每次刷新长度都在变化,因此只在偶然超过 1024 时弹窗,表现为时有时无。插件作者无法预知剩余长度预算(取决于内置文本和其他插件的文本长度),所以这个问题应在主程序内部处理。
复现方法
- 加载一个或多个
GetTooltipInfo()输出较长的插件,使插件文本与内置提示文本相加超过 1024 字符。单个插件返回约 950 个以上字符即可稳定触发;两个各约 600 字符的插件也可以。 - 现象:弹窗出现(在报告者机器上约 1 分钟内)。
建议修复
在两个调用点(TrafficMonitorDlg.cpp:2854 与 TaskBarDlg.cpp:949)把拼接好的提示文本截断到上限内再传给 MFC,例如:
constexpr size_t kMaxTipChars = 1024;
if (tip_info.GetLength() > static_cast<int>(kMaxTipChars))
tip_info = tip_info.Left(kMaxTipChars - 1); // 或改为在末尾加 L"…"
另外建议:
- 在插件开发指南中说明 1024 字符的合并预算,提醒插件作者控制提示长度;
- 也可以考虑对每个插件的提示单独截断(加省略号),而不是只做最终一刀切。
日志输出
(为空 —— 该错误不会写入 error.log,因此看起来与插件无关。)
附加信息
- 通过进程内
MessageBoxW钩子验证:弹窗文本正是 "Encountered an improper argument.",标题 "TrafficMonitor",MB_ICONERROR,在 UI 线程上由mfc140u.dll(MFC 异常报告路径)弹出,即上面ENSURE_ARG抛出的CInvalidArgException。 - 同一台机器上的受控重启试验(每次约 70 秒):
| 配置 | 弹窗次数 |
|---|---|
| 无额外插件 | 0 / 8 |
| 插件提示约 150 字符 | 5 / 9 |
| 同一插件但提示为空 | 0 / 5 |
| 空提示插件 + 用户正常配置 | 0 / 4 |
- 目前的用户侧临时规避:让受影响的插件返回空提示文本。这样不再弹窗,但没有真正修复问题——任何提示较长的插件或插件组合都可能再次触发。
Source: zhongyang219/TrafficMonitor