2012-10-18 40 views
2

我看到通知氣球,但未顯示圖標。並且在successfull(返回TRUE)後調用Shell_NotifyIcon後會出現一個窗口錯誤:試圖引用一個不存在的標記。主要問題是爲什麼我沒有看到圖標? Windows 7與最新的更新一起使用。shell_notifyicon:嘗試引用不存在的令牌,但未顯示圖標

下面的代碼片段:

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

確保'task_dialog_test.ico'能系統路徑上找到或構建完整的文件名,包括路徑,文件。還要檢查'ExtractIconEx'的返回值是什麼。該文件是否實際包含小(不大)圖標? – Stan

+0

當然,圖標提取後句柄有效。還使用帶圖標ID的LoadImage。錯誤不在那裏。在沒有向數據結構添加圖標時,也會出現@ err,hr指向的錯誤消息。附:也解僱了guid並且只放了data.uID。同樣的結果。 – John

+0

一個由ExtractIconEx返回。 – John

回答

0

知道了,以後這裏是我的解決方案。對於Windows 7,有一種識別圖標的特定方法。 通知區域中的每個圖標可以通過兩種方式標識。 圖標在註冊表中聲明的GUID。這是Windows 7及更高版本的首選方法。 與通知區域圖標關聯的窗口句柄,以及應用程序定義的圖標標識符。此方法在Windows Vista和更早版本上使用。 因此,在指定data.uID時,Windows 7不應從父句柄和uID字段值中生成唯一標識,而應從指定的GUID(全局唯一標識符)中生成唯一標識。因此,使用uID向通知區域圖標發送任何消息時,ShellNotify_Icon將返回零(錯誤ID)。但是,當創建GUID時,例如使用隨VS2010工具提供的工具GuidGen,它需要機器網卡地址和ID,機器配置,當前日期和時間,隨機組件,Windows 7將有一個唯一的ID來處理。 您可能會從我的評論中提到的鏈接中獲得有關Hans Passant消息的更多信息。

下面的代碼片段,它的工作原理:

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 
相關問題