buck54321
buck54321

Reputation: 847

Shell_NotifyIcon creates blank, unresponsive icon in system tray

I am trying to make a simple system tray icon app. Here is the heart of the code.

WNDCLASSEX wx = {};
wx.cbSize = sizeof( WNDCLASSEX );
wx.lpfnWndProc = WndProc;        // function which will handle messages
wx.hInstance = hInstance;
wx.lpszClassName = szWindowClass;
if ( RegisterClassEx( &wx ) == 0 ) {
    fileLogger->critical("Failed to register class");
    return 0;
}
HWND hWnd = CreateWindowEx(
    0,             // _In_     DWORD     dwExStyle,
    szWindowClass, // _In_opt_ LPCTSTR   lpClassName,
    szTitle,       // _In_opt_ LPCTSTR   lpWindowName,
    0,             // _In_     DWORD     dwStyle,
    0,             // _In_     int       x,
    0,             // _In_     int       y,
    0,             // _In_     int       nWidth,
    0,             // _In_     int       nHeight,
    HWND_MESSAGE,  // _In_opt_ HWND      hWndParent,
    NULL,          // _In_opt_ HMENU     hMenu,
    hInstance,     // _In_opt_ HINSTANCE hInstance,
    NULL           // _In_opt_ LPVOID    lpParam
);
if ( hWnd == NULL )
{
    fileLogger->critical("Failed to create window. Error code "+std::to_string(GetLastError())); 
    return 0;
}

    NOTIFYICONDATA nid = {};
    nid.uVersion = NOTIFYICON_VERSION_4;
    nid.cbSize = sizeof( nid );
    nid.hWnd = hWnd;
    nid.guidItem = myGUID;
    nid.uCallbackMessage = ICON_MESSAGE;
    StringCchCopy( nid.szTip, sizeof( nid.szTip )/sizeof( nid.szTip[0] ), "Starting Client" );

    // Loading a windows system icon for testing
    LoadIconMetric( NULL, (PCWSTR)MAKEINTRESOURCE( IDI_ASTERISK ), LIM_LARGE, &(nid.hIcon) );

    if ( ! Shell_NotifyIcon( NIM_ADD, &nid ) ) {
        fileLogger->critical("Shell_NotifyIcon failure.");
        return 0;
    }
...

When I compile and run the executable from the command prompt, it creates a blank space in the system tray. I also returns immediately (maybe normal) even though the process is still running. I see no tooltip when I hover over the blank icon, and the blank spot persists until I manually terminate the program. The icon does not seem to be passing messages to WndProc when I click it.

Possible clue: According to every piece of documentation I've seen, this line

LoadIconMetric( NULL, (PCWSTR)MAKEINTRESOURCE( IDI_ASTERISK ), LIM_LARGE, &(nid.hIcon) );

Should be

LoadIconMetric( NULL, MAKEINTRESOURCE( IDI_ASTERISK ), LIM_LARGE, &(nid.hIcon) );

Why would I have to typecast it when apparently nobody else does?

That may or may not be related to my problem, but is definitely suspicious.

Upvotes: 0

Views: 420

Answers (1)

user7860670
user7860670

Reputation: 37520

The first thing is that you don't set flags to indicate which fields are supplied:

nid.uFlags = NIF_ICON | NIF_TIP | NIF_GUID | NIF_MESSAGE;

I also suspect that you may have mixed Unicode / ASCII code. You should explicitly use wide char versions of functions.

Upvotes: 4

Related Questions