C++ Shell\u NotifyIcon在系统托盘中创建空白、无响应的图标

C++ Shell\u NotifyIcon在系统托盘中创建空白、无响应的图标,c++,winapi,C++,Winapi,我正在尝试制作一个简单的系统托盘图标应用程序。这是代码的核心 WNDCLASSEX wx = {}; wx.cbSize = sizeof( WNDCLASSEX ); wx.lpfnWndProc = WndProc; // function which will handle messages wx.hInstance = hInstance; wx.lpszClassName = szWindowClass; if ( RegisterClassEx( &wx ) =

我正在尝试制作一个简单的系统托盘图标应用程序。这是代码的核心

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;
    }
...
当我从命令提示符编译并运行可执行文件时,它会在系统托盘中创建一个空格。即使进程仍在运行,我也会立即返回(可能是正常的)。当我悬停在空白图标上时,我看不到工具提示,空白点一直持续到我手动终止程序为止。当我单击图标时,它似乎没有将消息传递给
WndProc

可能的线索:根据我看到的每一份文件,这一行

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

LoadIconMetric( NULL, MAKEINTRESOURCE( IDI_ASTERISK ), LIM_LARGE, &(nid.hIcon) );
显然没有其他人这么做,我为什么还要打字呢


这可能与我的问题有关,也可能与我的问题无关,但肯定是可疑的

首先,您不需要设置标志来指示提供了哪些字段:

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

我还怀疑您可能混合了Unicode/ASCII代码。您应该明确使用宽字符版本的函数。

首先,您不需要设置标志来指示提供了哪些字段:

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

我还怀疑您可能混合了Unicode/ASCII代码。您应该明确使用宽字符版本的函数。

您没有检查
LoadIconMetric
的结果-可能会失败。您没有使用UNICODE吗
LoadIconMetric
等待
PCWSTR
MAKEINTRESOURCE
转换为
PCWSTR
时,仅当您使用
UNICODE
时,这类转换肯定是可疑的,无法正常工作。尽管对于资源来说这是可以的,但是第一个参数不能为NULL。您必须检查返回值,还需要
ni.uFlags=NIF_消息| NIF_图标| NIF_提示
您没有检查
LoadIconMetric
的结果-可能会失败。您没有使用UNICODE吗
LoadIconMetric
等待
PCWSTR
MAKEINTRESOURCE
转换为
PCWSTR
时,仅当您使用
UNICODE
时,这类转换肯定是可疑的,无法正常工作。尽管对于资源来说这是可以的,但是第一个参数不能为NULL。您必须检查返回值,还需要
ni.uFlags=NIF_消息| NIF_图标| NIF_提示