【问题标题】:shell_notifyicon : an attempt was made to reference a token that does not exist, no icon shownshell_notifyicon :尝试引用不存在的令牌,未显示图标
【发布时间】:2012-10-18 12:34:23
【问题描述】:

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

这是一个代码sn-p:

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.
    }
}

【问题讨论】:

  • 确保可以在系统路径上找到task_dialog_test.ico 或构造完整的文件名,包括该文件的路径。还要检查ExtractIconEx 的返回值是多少。该文件实际上是否包含小(不是大)图标?
  • 当然,handle在图标提取后有效。还使用了带有图标 ID 的 LoadImage。错误不存在。 @err,hr 指出的错误消息在未向数据结构中添加图标时也会出现。附言还解雇了 guid,只放了 data.uID。结果相同。
  • ExtractIconEx 返回一个。
  • 您的代码摘录不完整:不清楚在哪里调用了init

标签: c++ windows winapi


【解决方案1】:

好的,这是我的解决方案建议。对于 Windows 7,有一种特定的方式来识别图标。 可以通过两种方式识别通知区域中的每个图标。 在注册表中声明图标的 GUID。这是 Windows 7 及更高版本上的首选方法。 与通知区域图标关联的窗口句柄,加上应用程序定义的图标标识符。此方法用于 Windows Vista 和更早版本。 因此,在指定 data.uID 时,Windows 7 不应从父句柄和 uID 字段值中创建唯一 ID,而是从指定的 GUID(全局唯一标识符)中创建唯一 ID。因此,当使用 uID 向通知区域图标发送任何消息时,ShellNotify_Icon 返回零(错误 ID)。但是,在创建 GUID 时,例如使用 VS2010 工具提供的工具 GuidGen,它需要机器网卡地址和 ID、机器配置、当前日期和时间、随机组件,Windows 7 将有一个唯一的 ID 来处理。 您可以从我对 Hans Passant 消息的评论中提到的链接在 MSDN 中获得更多信息。

这是一个代码 sn-p,它可以工作:

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

【讨论】:

    猜你喜欢
    • 2013-11-13
    • 2023-02-03
    • 2011-02-15
    • 2018-05-15
    • 2016-12-03
    • 1970-01-01
    • 2013-08-04
    • 2021-01-03
    相关资源
    最近更新 更多