3

我看到通知气球,但没有显示图标。并且在成功(返回 TRUE)调用 Shell_NotifyIcon 后出现 Windows 错误:尝试引用不存在的令牌。主要问题是为什么我看不到图标?Windows 7 与最新更新一起使用。

这是一个代码片段:

namespace tray_tip
{
#define FINAL_INIT( tip, title, ic, icon_id, inst )\
    if ( icon )\
    {\
        static const GUID myGUID = \
        {0x23977b55, 0x10e0, 0x4041, {0xb8, 0x62, 0xb1, 0x95, 0x41, 0x96, 0x36, 0x69}};\
        data.guidItem = myGUID;\
        data.dwInfoFlags |= NIF_ICON;\
        ExtractIconEx( _T("task_dialog_test.ico"), 0, NULL, &(data.hIcon), 1 );\
    }\
    data.dwInfoFlags |= ic;\
    _tcscpy_s( data.szInfo, tip );\
    _tcscpy_s( data.szInfoTitle, title );

    static NOTIFYICONDATA data = {0};
    inline void init( HWND const & parent, UINT const & msg_id, UINT const & time_out = 30 )
    {
        ULONGLONG ullVersion = GetDllVersion( _T( "Shell32.dll" ) );
        if ( ullVersion > MAKEDLLVERULL ( 6,0,0,0 ) )
            data.cbSize = sizeof ( NOTIFYICONDATA );
        else if ( ullVersion == MAKEDLLVERULL( 6,0,0,0 ) )
            data.cbSize = sizeof( NOTIFYICONDATA_V3_SIZE );
        else if ( ullVersion >= MAKEDLLVERULL( 5,0,0,0 ) )
            data.cbSize = NOTIFYICONDATA_V2_SIZE;
        else 
            data.cbSize = NOTIFYICONDATA_V1_SIZE;
        data.hWnd = parent;
        data.uFlags = NIF_INFO | NIF_MESSAGE;// | NIF_SHOWTIP;
        data.uCallbackMessage = msg_id;
        data.uTimeout = time_out;
    }
    inline BOOL show( BOOL show = FALSE, TCHAR tip[256] = _T(""), TCHAR title[64] = _T(""), DWORD const & ic = NIIF_INFO, UINT const & icon = 0, HINSTANCE const & inst_h = NULL )
    {
        FINAL_INIT( tip, title, ic, icon, inst_h );
        return Shell_NotifyIcon( show == TRUE ? NIM_ADD : NIM_DELETE, &data ); // function checks if version can be changed if it was preset.
    }
}
4

1 回答 1

0

O.K., here is my proposal on a solution. For Windows 7 there is a specific way to identify an icon. Each icon in the notification area can be identified in two ways. The GUID with which the icon is declared in the registry. This is the preferred method on Windows 7 and later. The handle of a window associated with the notification area icon, plus an application-defined icon identifier. This method is used on Windows Vista and earlier. Thus, when specifying data.uID Windows 7 should not make unique ID from parent handle and uID field value, but from specified GUID ( Global Unique Identifier ). Therefore, when sending any message to notification area icon using uID there will be zero (error ID) returned by ShellNotify_Icon. However, when creating GUID, for example using tool GuidGen supplied with VS2010 tools, which takes machine network card address and ID, machine configuration, current date and time, random component, Windows 7 will have a unique ID to treat. More information you may get in MSDN from link mentioned in my comment to Hans Passant message.

Here is a code snippet, which works:

namespace tray_tip
{

#define FINAL_INIT( tip, title, ic, icon_id, inst_h )\
    data.uFlags |= NIF_ICON;\
    LoadIconMetric(inst_h, MAKEINTRESOURCE(icon_id), LIM_SMALL, &(data.hIcon));\
    static const GUID ic_guid = { 0xa351efe, 0x9642, 0x4acc, { 0xb3, 0x25, 0xec, 0x1a, 0x49, 0x91, 0x75, 0xaf } };\
    data.uFlags |= NIF_GUID;\
    data.guidItem = ic_guid;\
    data.dwStateMask = NIS_HIDDEN;\
    data.dwInfoFlags |= ic;\
    _tcscpy_s( data.szInfo, tip );\
    _tcscpy_s( data.szInfoTitle, title );

//#define FINAL_INIT( tip, title, ic, icon_id, inst_h )\
//  data.uFlags |= NIF_ICON;\
//  LoadIconMetric(inst_h, MAKEINTRESOURCE(icon_id), LIM_SMALL, &(data.hIcon));\
//  data.uID = icon_id,\
//  data.dwStateMask = NIS_HIDDEN;\
//  data.dwInfoFlags |= ic;\
//  _tcscpy_s( data.szInfo, tip );\
//  _tcscpy_s( data.szInfoTitle, title );
    static NOTIFYICONDATA data = {0};
    inline void init( HWND const & parent, UINT const & msg_id, UINT const & time_out = 30 )
    {
        ULONGLONG ullVersion = GetDllVersion( _T( "Shell32.dll" ) );
        if ( ullVersion > MAKEDLLVERULL ( 6,0,0,0 ) )
            data.cbSize = sizeof ( NOTIFYICONDATA );
        else if ( ullVersion == MAKEDLLVERULL( 6,0,0,0 ) )
            data.cbSize = sizeof( NOTIFYICONDATA_V3_SIZE );
        else if ( ullVersion >= MAKEDLLVERULL( 5,0,0,0 ) )
            data.cbSize = NOTIFYICONDATA_V2_SIZE;
        else 
            data.cbSize = NOTIFYICONDATA_V1_SIZE;
        data.hWnd = parent;
        data.uFlags = NIF_INFO | NIF_MESSAGE;
        data.uCallbackMessage = msg_id;
        data.uTimeout = time_out;
    }
    inline BOOL show( BOOL show = FALSE, TCHAR tip[256] = _T(""), TCHAR title[64] = _T(""), DWORD const & ic = NIIF_INFO, UINT const & icon_id = 0, HINSTANCE const & inst_h = NULL )
    {
        FINAL_INIT( tip, title, ic, icon_id, inst_h );
        data.dwState = show ? 0 : 1;
        static bool added = false;
        if ( added || ( !added && show ) )
        {
            added = true;
            return  Shell_NotifyIcon( show == TRUE ? NIM_ADD : NIM_DELETE, &data ); // function checks if version can be changed if it was preset.
        }
        else 
            return 0;
    }

} // namespace tray_tip
于 2012-10-18T20:36:02.370 回答