如何在同一个应用程序(winapi)中添加多个托盘图标?

问题描述 投票:0回答:1

一个应用程序可以有多个托盘图标吗? (有点像雷鸟:一个用于主应用程序,另一个用于当您收到电子邮件并且通知区域中有一个信封时)

我尝试连续两次使用 ShellNotify_Icon,但第二次只是返回 FALSE。 我也尝试过使用两种不同的 NOTIFYICONDATA 结构,但仍然没有任何结果。它只是添加了一个。

我在文档或谷歌上找不到任何内容说明这是否可能。

有什么想法吗?

c++ winapi system-tray
1个回答
0
投票

假设您的应用程序需要在运行时显示 2 种状态,并且您希望将它们显示为 2 个不同的托盘图标。这是更新它们的代码。当我开发视频捕获软件时,我就有过这样的用例。

BOOL SetTrayIcons(HWND hWnd, int iconType1, int iconType2)
{
    NOTIFYICONDATA iconData1;
    memset(&iconData1, 0, sizeof(NOTIFYICONDATA));

    NOTIFYICONDATA iconData2;
    memset(&iconData2, 0, sizeof(NOTIFYICONDATA));

    // Icon 1
    if (iconType1 == TRAY_DELETE)
    {
        iconData1.cbSize = sizeof(NOTIFYICONDATA);
        iconData1.hWnd = hWnd;
        iconData1.uID = 1; // Change this ID for each icon
        iconData1.uVersion = NOTIFYICON_VERSION;
        iconData1.uFlags = 0;

        Shell_NotifyIcon(NIM_DELETE, &iconData1);
    }
    else
    {
        HICON hIcon1 = NULL;
        if (iconType1 == TRAY_START)
        {
            hIcon1 = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, 32, 32, 0);
            _tcscpy(iconData1.szTip, SGDVR_STATE_NOT_RECORDING);
        }
        else if (iconType1 == TRAY_REC)
        {
            hIcon1 = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_RECORDING), IMAGE_ICON, 32, 32, 0);
            _tcscpy(iconData1.szTip, SGDVR_STATE_RECORDING);
        }
        else if (iconType1 == TRAY_NOTREC)
        {
            hIcon1 = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, 32, 32, 0);
            _tcscpy(iconData1.szTip, SGDVR_STATE_NOT_RECORDING);
        }
        _ASSERTE(hIcon1 != 0);

        iconData1.cbSize = sizeof(NOTIFYICONDATA);
        iconData1.hWnd = hWnd;
        iconData1.uID = 1; // Change this ID for each icon
        iconData1.hIcon = hIcon1;
        iconData1.uVersion = NOTIFYICON_VERSION;
        iconData1.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
        iconData1.uCallbackMessage = SG_NOTIFY_MESSAGE;

        Shell_NotifyIcon(NIM_ADD, &iconData1);
    }

    // Icon 2 (similar to Icon 1)
    if (iconType2 == TRAY_DELETE)
    {
        iconData2.cbSize = sizeof(NOTIFYICONDATA);
        iconData2.hWnd = hWnd;
        iconData2.uID = 2; // Change this ID for each icon
        iconData2.uVersion = NOTIFYICON_VERSION;
        iconData2.uFlags = 0;

        Shell_NotifyIcon(NIM_DELETE, &iconData2);
    }
    else
    {
        HICON hIcon2 = NULL;
        if (iconType2 == TRAY_START)
        {
            hIcon2 = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, 32, 32, 0);
            _tcscpy(iconData2.szTip, SGDVR_STATE_NOT_RECORDING);
        }
        else if (iconType2 == TRAY_REC)
        {
            hIcon2 = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_RECORDING), IMAGE_ICON, 32, 32, 0);
            _tcscpy(iconData2.szTip, SGDVR_STATE_RECORDING);
        }
        else if (iconType2 == TRAY_NOTREC)
        {
            hIcon2 = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, 32, 32, 0);
            _tcscpy(iconData2.szTip, SGDVR_STATE_NOT_RECORDING);
        }
        _ASSERTE(hIcon2 != 0);

        iconData2.cbSize = sizeof(NOTIFYICONDATA);
        iconData2.hWnd = hWnd;
        iconData2.uID = 2; // Change this ID for each icon
        iconData2.hIcon = hIcon2;
        iconData2.uVersion = NOTIFYICON_VERSION;
        iconData2.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
        iconData2.uCallbackMessage = SG_NOTIFY_MESSAGE;

        Shell_NotifyIcon(NIM_ADD, &iconData2);
    }

    return TRUE;
}

我用它在录制过程中显示托盘图标,并在仅捕获视频时显示“静音”图标。

SetTrayIcons(hwnd, TRAY_REC, SGDVRIsMute() ? TRAY_START : TRAY_NOTREC);

然后,当您只想删除 2 个图标时,您可以调用:

BOOL ClearAllTrayIcons(HWND hWnd)
{
    NOTIFYICONDATA iconData;
    memset(&iconData, 0, sizeof(NOTIFYICONDATA));

    iconData.cbSize = sizeof(NOTIFYICONDATA);
    iconData.hWnd = hWnd;
    iconData.uID = 1;
    iconData.uFlags = 0;

    Shell_NotifyIcon(NIM_DELETE, &iconData);

    iconData.uID = 2;
    Shell_NotifyIcon(NIM_DELETE, &iconData);

    return TRUE;
}
© www.soinside.com 2019 - 2024. All rights reserved.