我创建一个系统图标:
BOOL TrayMessage(HWND hWnd, DWORD dwMessage)
{
NOTIFYICONDATA nid;
nid.cbSize = sizeof(nid);
nid.hWnd = hWnd;
nid.uID = 1;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MYAPP));
lstrcpy(nid.szTip, L"MyApp");
nid.uCallbackMessage = WM_NOTIFYICON;
return Shell_NotifyIcon(dwMessage, &nid);
}当应用程序启动/创建窗口时:
case WM_CREATE:
if (!TrayMessage(hWnd, NIM_ADD))
MessageBox(hMainWnd, L"Tray error.", 0, 0);此错误消息框:
当然,当错误发生时,图标不会显示在任务栏中。
可能是什么原因?
WM_CREATE以外的地方吗?编辑:在@RbMm的评论之后,我尝试了如下:
case WM_CREATE:
TrayMessage(hWnd, NIM_ADD);
// I removed MessageBox(...) from here
uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
...
break;
default:
if (message == uTaskbarRestart)
{
TrayMessage(hWnd, NIM_ADD);
MessageBox(hMainWnd, L"TaskbarRestart", 0, 0);
}测试结果:托盘图标未能显示的情况是--当MessageBox TaskbarRestart未显示时,即当TaskbarRestart事件从未出现在消息循环中时.真奇怪..。
注意:这只有在用户注销/重新登录后才会发生。
发布于 2017-07-22 23:17:17
当前版本的MSDN Shell_NotifyIcon不再显示它(真可惜!),但幸运的是,有一个存档版本在这里提供了两个有趣的信息:
1.
如果成功返回TRUE,否则返回FALSE。..。您可以调用GetLastError获取有关故障案例的更多具体信息。最常见的故障原因是任务栏窗口不存在或没有响应的。在这种情况下,GetLastError返回E_FILE_NOT_FOUND。
2.
处理Shell_NotifyIcon故障 在Windows启动期间调用Shell_NotifyIcon时经常会失败(例如,如果您的应用程序列在HKLM\Software\Microsoft\Windows\CurrentVersion\Run.中这似乎是因为系统正忙于启动应用程序。这种故障在低规格的计算机或安装了一些品牌防病毒软件的计算机上更为常见,这些软件在启动时似乎非常密集。 不幸的是,您不能依赖GetLastError返回的错误代码。当Shell_NotifyIcon返回false时,GetLastError返回的一些常见错误是: ERROR_FILE_NOT_FOUND (2) ERROR_TIMEOUT (1460) ERROR_SUCCESS (0) 对Shell_NotifyIcon返回的任何错误最合适的响应是睡眠一段时间,然后重试. 保罗·贝克( Paul )解释了错误代码可能不同的原因,他引用了http://groups.google.com/group/microsoft.public.platformsdk.shell/msg/59235b293cbf5dfa和http://groups.google.com/group/microsoft.public.platformsdk.shell/msg/73973287f15c03fc的话: Shell_NotifyIcon实际上最初调用SetLastError(0)。之后,它基本上使用FindWindow查找托盘通知窗口。如果失败,它通常会返回ERROR_FILE_NOT_FOUND。否则,它将向托盘通知窗口发送WM_COPYDATA消息,使用超时时间仅为4秒的SendMessageTimeout。如果该消息返回零,那么Shell_NotifyIcon将失败,GetLastError返回零。
解决方案:
case WM_CREATE:
...
if (!TrayMessage(hWnd, NIM_ADD))
SetTimer(hWnd, IDT_TIMER1, 4000, (TIMERPROC) NULL);
break;
case WM_TIMER:
TrayMessage(hWnd, NIM_ADD);
KillTimer(IDT_TIMER1);
break;https://stackoverflow.com/questions/45255294
复制相似问题