清除通知托盘图标,窗口外壳

Clear notification tray icon, windows shell

本文关键字:窗口 外壳 托盘图标 通知 清除      更新时间:2023-10-16

问题:通知图标在哪里注册,当它已经从其他位置注册时如何删除它?

描述:我想使用通知托盘图标,所以我启动了一个 Windows SDK 示例来检查它是如何工作的。

问题是,一旦图标从一个位置注册,它就不能在其他任何地方使用。Shell_NotifyIcon(...) 从其他位置失败。甚至在示例的自述文件中对此进行了描述:

请注意,使用 GUID 指定的通知图标通过验证来防止欺骗 只有一个应用程序注册它们。此注册在您第一次执行时执行 调用 Shell_NotifyIcon(NIM_ADD, ...),并存储调用应用程序的完整路径名。如果你 稍后将您的二进制文件移动到其他位置,系统将不允许再次添加该图标。

我试图在我的应用程序出口处Shell_NotifyIcon(NIM_DELETE,...),但它仍然不起作用,我的应用程序可以从不同的位置启动。大洋洲。我可以通过在每次Shell_NotifyIcon(...)失败时更改guid来破解它,但我宁愿使用更少的蛮力方法。此外,我在系统注册表中搜索了 guid,找不到它。

示例中的 GUID 定义如下:

// Use a guid to uniquely identify our icon
class __declspec(uuid("9D0B8B92-4E1C-488e-A1E1-2331AFCE2CB5")) PrinterIcon;

创建通知图标的代码:

BOOL AddNotificationIcon(HWND hwnd)
{
    NOTIFYICONDATA nid = {sizeof(nid)};
    nid.hWnd = hwnd;
    // add the icon, setting the icon, tooltip, and callback message.
    // the icon will be identified with the GUID
    nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE | NIF_SHOWTIP | NIF_GUID;
    nid.guidItem = __uuidof(PrinterIcon);
    nid.uCallbackMessage = WMAPP_NOTIFYCALLBACK;
    LoadIconMetric(g_hInst, MAKEINTRESOURCE(IDI_NOTIFICATIONICON), LIM_SMALL, &nid.hIcon);
    LoadString(g_hInst, IDS_TOOLTIP, nid.szTip, ARRAYSIZE(nid.szTip));
    Shell_NotifyIcon( NIM_ADD, &nid );
    // NOTIFYICON_VERSION_4 is prefered
    nid.uVersion = NOTIFYICON_VERSION_4;
    return Shell_NotifyIcon(NIM_SETVERSION, &nid);
}

该代码是 Windows SDK 示例的一部分:SDKs/Windows/v7.1/Samples/winui/shell/appshellintegration/NotificationIcon

所以。最终的解决方案是我像这样声明 NOTIFYICONDATA

#define NOTIFICATIONTRAY_UID 666;
[...]
NOTIFYICONDATA nid = { 0 };
nid.cbSize = sizeof( NOTIFYICONDATA );
nid.hWnd = hWnd;
nid.uID = NOTIFICATIONTRAY_UID;
nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE | NIF_SHOWTIP;
nid.uCallbackMessage = WMAPP_NOTIFYCALLBACK;
LoadIconMetric( hInstance, MAKEINTRESOURCE( IDI_NOTIFICATIONICON ), LIM_SMALL, &nid.hIcon );
lstrcpy( nid.szTip, L"Tooltip text" );
Shell_NotifyIcon( NIM_ADD, &nid );
// NOTIFYICON_VERSION_4 is prefered
nid.uVersion = NOTIFYICON_VERSION_4;
return ( Shell_NotifyIcon( NIM_SETVERSION, &nid ) != 0 );

我没有设置NIF_GUID标志和 GUID。稍后使用此图标(销毁、添加气球通知等)我必须提供 HWND 和 uID(感谢 Remy Lebeau 的建议)。