C++ shell_notifyicon:尝试引用不存在的令牌,未显示图标
我看到通知气球,但没有显示图标。在成功(返回TRUE)调用Shell_NotifyIcon后,出现windows错误:试图引用不存在的令牌。主要问题是为什么我看不到图标?Windows 7与最新更新一起使用 以下是一段代码片段:C++ shell_notifyicon:尝试引用不存在的令牌,未显示图标,c++,windows,winapi,C++,Windows,Winapi,我看到通知气球,但没有显示图标。在成功(返回TRUE)调用Shell_NotifyIcon后,出现windows错误:试图引用不存在的令牌。主要问题是为什么我看不到图标?Windows 7与最新更新一起使用 以下是一段代码片段: namespace tray_tip { #define FINAL_INIT( tip, title, ic, icon_id, inst )\ if ( icon )\ {\ static const GUID myGUID = \
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.
}
}
好的,这是我关于解决方案的建议。对于Windows 7,有一种特定的方法来标识图标。 通知区域中的每个图标可以通过两种方式识别。 用于在注册表中声明图标的GUID。这是Windows 7及更高版本上的首选方法。 与通知区域图标关联的窗口句柄,加上应用程序定义的图标标识符。此方法在Windows Vista及更早版本上使用。 因此,在指定data.uID时,Windows 7不应使父句柄和uID字段值具有唯一的ID,而应使其具有指定的GUID(全局唯一标识符)。因此,当使用uID将任何消息发送到通知区域图标时,ShellNotify_图标将返回零(错误ID)。但是,当创建GUID时,例如使用VS2010 tools提供的工具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
确保可以在系统路径上找到
task\u dialog\u test.ico
,或构造包含该文件路径的完整文件名。还要检查ExtractIconEx
的返回值是多少。文件是否确实包含小(不是大)图标?当然,句柄在图标提取后是有效的。还使用了带有图标ID的LoadImage。不存在错误@错误,当不向数据结构添加图标时,也会出现指向hr的错误消息。另外,还取消了guid,只放data.uID。相同的结果。ExtractIconEx返回一个。您的代码摘录不完整:不清楚在哪里调用init
。