I create a systray icon with:
BOOL TrayMessage(HWND hWnd, DWORD dwMessage)
{
NOTIFYICONDATA nid;
nid.cbSize = sizeof(nid);
nid.hWnd = hWnd;
nid.uID = 1;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MYAPP));
lstrcpy(nid.szTip, L"MyApp");
nid.uCallbackMessage = WM_NOTIFYICON;
return Shell_NotifyIcon(dwMessage, &nid);
}
when the app starts / the window is created:
case WM_CREATE:
if (!TrayMessage(hWnd, NIM_ADD))
MessageBox(hMainWnd, L"Tray error.", 0, 0);
This error messagebox:
never happens when I launch the .exe normally.
only happens after a User Logout / User re-login, once every 5 launches on average (my app is automatically launched on every session startup with a TaskSchedular task)
Of course when the error happens, the icon isn't displayed in taskbar.
What could be the reason?
The systray system is not ready yet (very short after a user logout / login again) ?
The taskbar itself is not ready yet?
Should I move the creation to somewhere outside of
WM_CREATE
?
Edit: after @RbMm's comment, I tried this:
case WM_CREATE:
TrayMessage(hWnd, NIM_ADD);
// I removed MessageBox(...) from here
uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
...
break;
default:
if (message == uTaskbarRestart)
{
TrayMessage(hWnd, NIM_ADD);
MessageBox(hMainWnd, L"TaskbarRestart", 0, 0);
}
Result of this test: the cases for which the tray icon fails to be displayed are exactly the cases when the MessageBox TaskbarRestart
is not shown, i.e. when TaskbarRestart event never comes to the message loop... That's strange...
Note: this only happens after a user logout / re-login.
The current version of MSDN Shell_NotifyIcon doesn't show it anymore (such a shame!), but fortunately, there's an archived version here that gives two interesting informations:
1.
2.
Solution: