Refreshing the Notification Area (System Tray)

Because I am forcibly killing certain processes regularly, I end up with orphaned icons in what is apparently called the Notification Area, not the System Tray.

I found a good StackOverflow answer, but it needed some updates:
Can you send a signal to Windows Explorer to make it refresh the systray icons?

The answer draws its information from this informative post:
REFRESHING THE TASKBAR NOTIFICATION AREA

But the information is from 2008.  The name of the window used in XP has changed in Windows 7 (actually probably in Vista).  In addition to this, the code only works on visible icons, not on those that are currently hiding.  The following code is updated to clear both visible and hidden icons.

 

//WinXP
    GetClientRect(
        hNotificationArea = FindWindowEx(
            FW(FW(FW(NULL, L"Shell_TrayWnd"), L"TrayNotifyWnd"), L"SysPager"),
            NULL,
            L"ToolbarWindow32",
            L"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);

	//Visible icons
    GetClientRect(
        hNotificationArea = FindWindowEx(
            FW(FW(FW(NULL, L"Shell_TrayWnd"), L"TrayNotifyWnd"), L"SysPager"),
            NULL,
            L"ToolbarWindow32",
            L"User Promoted 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);

	//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);

Utility available here: Refresh Notification Area

By the way, if you have the opposite problem as me and are losing the icons of programs still running, see the following:
Can I re-gain a systray icon of a running app that has gone missing?
trayrestore

 

I’ve posted my updates to the StackOverflow answer: http://stackoverflow.com/a/18038441/221018

Advertisements