首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在用户注销/登录后创建Tray图标时出现的罕见错误

在用户注销/登录后创建Tray图标时出现的罕见错误
EN

Stack Overflow用户
提问于 2017-07-22 13:49:25
回答 1查看 980关注 0票数 2

我创建一个系统图标:

代码语言:javascript
复制
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);
}

当应用程序启动/创建窗口时:

代码语言:javascript
复制
case WM_CREATE:
    if (!TrayMessage(hWnd, NIM_ADD))
        MessageBox(hMainWnd, L"Tray error.", 0, 0);

此错误消息框:

  • 当我正常启动.exe时,从未发生过这种情况。
  • 只有在用户登录/用户重新登录后才会发生,平均每5次启动一次(我的应用程序在每个会话启动时都会自动启动TaskSchedular任务)。

当然,当错误发生时,图标不会显示在任务栏中。

可能是什么原因?

  1. 系统系统还没有准备好(在用户再次登出/登录后很短)?
  2. 任务栏本身还没有准备好吗?
  3. 我应该把创作移到WM_CREATE以外的地方吗?

编辑:在@RbMm的评论之后,我尝试了如下:

代码语言:javascript
复制
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事件从未出现在消息循环中时.真奇怪..。

注意:这只有在用户注销/重新登录后才会发生。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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/59235b293cbf5dfahttp://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返回零。

解决方案:

代码语言:javascript
复制
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;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45255294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档