清理系统托盘中不存在的进程的NotifyIcons

时间:2015-11-09 16:19:43

标签: c++ windows winapi windows-7

有很多NotifyIcon属于已终止的进程。 (到目前为止,我已经看到了多达24个这样的图标。) 如果用户将鼠标光标移到这些图标上,它们就会消失。

如何以编程方式清理所有“死”的NotifyIcons?

编辑1:

一些深度Google搜索显示可以枚举NotifyIcons的HWND。

https://social.msdn.microsoft.com/Forums/vstudio/en-US/4c4f60ce-3573-433d-994e-9c17f95187f0/finding-which-applications-and-services-are-listed-in-the-system-tray?forum=csharpgeneral

进一步的工作是微不足道的。稍后再试。

2 个答案:

答案 0 :(得分:1)

这是Windows 7的解决方案。 对于其他版本,窗口类和名称可能不同。 使用spyxx.exe工具检查windows树。

   HWND Get_Notification_Area_1()
    {            
        HWND hWnd = ::FindWindowA("Shell_TrayWnd", NULL);
        if (hWnd)
            hWnd = ::FindWindowExA(hWnd, NULL, "TrayNotifyWnd", NULL);
        if (hWnd)
            hWnd = ::FindWindowExA(hWnd, NULL, "SysPager", NULL);
        if (hWnd)
            hWnd = ::FindWindowExA(hWnd, NULL, "ToolbarWindow32", "User Promoted Notification Area");
        return hWnd;
    }

    HWND Get_Notification_Area_2()
    {            
        HWND hWnd = ::FindWindowA("NotifyIconOverflowWindow", NULL);
        if (hWnd)
            hWnd = ::FindWindowExA(hWnd, NULL, "ToolbarWindow32", "Overflow Notification Area");
        return hWnd;
    }

    void Process_Notification_Area(HWND hWnd)
    {
        if(!hWnd)
            return;
        RECT rcClient;
        BOOL bRet = ::GetClientRect(hWnd, &rcClient);
        if(!bRet)
            return;
        for(int y = rcClient.bottom - 16; y >= 0; y -= 16)
            for(int x = rcClient.right - 16; x >= 0; x -= 16)
                ::PostMessageA(hWnd, WM_MOUSEMOVE, NULL, MAKELPARAM(x, y));
    }

    void Clean_Up_Notification_Area()
    {
        Process_Notification_Area( Get_Notification_Area_1() );
        Process_Notification_Area( Get_Notification_Area_2() );
    }

答案 1 :(得分:0)

  

如何以编程方式清理所有" dead" NotifyIcons?

你做不到。这没有API。我想你可以将鼠标光标移动到屏幕的这一部分上,但这只是你能做的最好的事情。