Can you send a signal to Windows Explorer to make it refresh the systray icons?

前端 未结 8 756
执笔经年
执笔经年 2020-12-03 00:22

This problem has been afflicting me for quite a while and it\'s been really annoying.

Every time I login after a reboot/power cycle the explorer takes some time to s

相关标签:
8条回答
  • 2020-12-03 00:28

    I covered this issue last year on my Codeaholic weblog in an article entitled [Delphi] Updating SysTray.

    My solution is a Delphi ActiveX/COM DLL. The download link still works (though for how much longer I don't know as my PLUG membership has lapsed.)

    0 讨论(0)
  • 2020-12-03 00:34

    I use the following C++ code to get the window handle to the tray window. Note: this has only been tested on Windows XP.

    HWND FindSystemTrayIcons(void)
    {
        // the system tray icons are contained in a specific window hierarchy;
        // use the Spy++ utility to see the chain
        HWND hwndTray = ::FindWindow("Shell_TrayWnd", "");
        if (hwndTray == NULL)
            return NULL;
        HWND hwndNotifyWnd = ::FindWindowEx(hwndTray, NULL, "TrayNotifyWnd", "");
        if (hwndNotifyWnd == NULL)
            return NULL;
        HWND hwndSysPager = ::FindWindowEx(hwndNotifyWnd, NULL, "SysPager", "");
        if (hwndSysPager == NULL)
            return NULL;
        return ::FindWindowEx(hwndSysPager, NULL, "ToolbarWindow32", "Notification Area");
    }
    

    0 讨论(0)
  • 2020-12-03 00:42

    Two important details for anyone using Louis's answer (from REFRESHING THE TASKBAR NOTIFICATION AREA) on Windows 7 or Windows 8:

    First, as the answer was reflected to show, the window titled "Notification Area" in XP is now titled "User Promoted Notification Area" in Windows 7 (actually probably Vista) and up.

    Second, this code does not clear icons that are currently hidden. These are contained in a separate window. Use the original code to refresh visible icons, and the following to refresh hidden icons.

    //Hidden icons
    GetClientRect(
        hNotificationArea = FindWindowEx(
            FW(NULL, L"NotifyIconOverflowWindow"),
            NULL,
            L"ToolbarWindow32",
            L"Overflow Notification Area"),
        &r);
    
    for (LONG x = 0; x < r.right; x += 5)
        for (LONG y = 0; y < r.bottom; y += 5)
            SendMessage(
                hNotificationArea,
                WM_MOUSEMOVE,
                0,
                (y << 16) + x);
    

    For anyone who just needs a utility to run to accomplish this, rather than code, I built a simple exe with this update: Refresh Notification Area

    0 讨论(0)
  • 2020-12-03 00:44

    After lots of times trying I found that there are three issues you must to know:

    • The parent of hidden tray window is NotifyIconOverflowWindow, other than Shell_TrayWnd.
    • You shouldn't use caption parameter of FindWindowEx to find a window, because these is lots of langue versions of Windows OS, they are not always be the same title Obviously.
    • Use spy++ of Visual Studio to find or make assurance what you want.

    So, I changed code from @Stephen Klancher and @Louis Davis, thank you guys.

    The following code worked for me.

    #define FW(x,y) FindWindowEx(x, NULL, y, L"")
    void RefreshTaskbarNotificationArea()
    {
        HWND hNotificationArea;
        RECT r;
        GetClientRect(hNotificationArea = FindWindowEx(FW(NULL, L"NotifyIconOverflowWindow"), NULL, L"ToolbarWindow32", NULL), &r);
        for (LONG x = 0; x < r.right; x += 5)
        {
            for (LONG y = 0; y < r.bottom; y += 5)
            {
                SendMessage(hNotificationArea, WM_MOUSEMOVE, 0, (y << 16) + x);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-03 00:47

    As far as I know that isn't possible Gustavo - it's up to each application to put its notifyicon in the systray, and ensure it's kept in the right state.

    You'll notice sometimes when explorer.exe crashes that certain icons don't reappear - this isn't because their process has crashed, simply that their application hasn't put the notifyicon in the systray when the new instance of explorer.exe started up. Once again, it's the application that's responsible.

    Sorry not to have better news for you!

    0 讨论(0)
  • 2020-12-03 00:48

    @Skip R, and anyone else wanting to do this in C, with this code verified compiled in a recent (most recent) mingw on Windows 10 64 bit (but with the mingw 32 bit package installed), this seems to work in Windows XP / 2003 to get rid of stale notification area icons.

    I installed mingw via Chocolatey, like this:

    choco install mingw --x86 --force --params "/exception:sjlj"
    

    (your mileage may vary on that, on my system, the compiler was then installed here:

    C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw32\bin\gcc.exe
    

    and then a simple

    gcc refresh_notification_area.c
    

    yielded an a.exe which solved a stale notification area icon problem I was having on Windows 2003 (32 bit).

    The code, adapted from @Stephen Klancher above is (note this may only work on Windows XP/2003, which fulfilled my purposes):

    #include <windows.h>
    
    #define FW(x,y) FindWindowEx(x, NULL, y, "")
    
    int main ()
    {
    
        HWND hNotificationArea;
        RECT r;
    
        //WinXP
        // technique found at:
        // https://stackoverflow.com/questions/74723/can-you-send-a-signal-to-windows-explorer-to-make-it-refresh-the-systray-icons#18038441
        GetClientRect(
            hNotificationArea = FindWindowEx(
                FW(FW(FW(NULL, "Shell_TrayWnd"), "TrayNotifyWnd"), "SysPager"),
                NULL,
                "ToolbarWindow32",
                "Notification Area"),
            &r);
    
        for (LONG x = 0; x < r.right; x += 5)
            for (LONG y = 0; y < r.bottom; y += 5)
                SendMessage(
                    hNotificationArea,
                    WM_MOUSEMOVE,
                    0,
                    (y << 16) + x);
    
      return 0;
    
    }
    
    0 讨论(0)
提交回复
热议问题