Delphi7中CoolTrayIcon组件下Shell_NotifyIconGetRect的uID取值问题
解决Delphi7中CoolTrayIcon组件与Shell_NotifyIconGetRect的uID赋值问题
首先咱们得理清楚:NOTIFYICONIDENTIFIER里的uID,就是当初调用Shell_NotifyIcon(NIM_ADD)添加托盘图标时指定的唯一标识。CoolTrayIcon组件内部肯定在调用这个API时设置了这个值,只是没对外暴露,下面给你几种可行的解决办法:
方法1:直接获取组件内部的uID值
大多数CoolTrayIcon的实现(包括你用的TTextTrayIcon),内部会用一个私有变量来存储这个uID,比如FIconID。你可以这么操作:
- 查看组件源码:找到
CoolTrayIcon.pas文件,搜索Shell_NotifyIcon的调用,看它在NIM_ADD时传入的NOTIFYICONDATA结构体里uID字段的取值——很多实现会用1作为默认值,或者组件的Tag属性,甚至是自增整数。 - 运行时读取私有成员:如果不想改组件源码,能借助Delphi的类型转换技巧访问私有变量:
type TTextTrayIconHack = class(TTextTrayIcon); // 定义一个类来突破访问限制 // 在你的按钮点击事件里: S.uID := TTextTrayIconHack(TextTrayIcon1).FIconID;
注意:这种方式依赖组件的内部实现,如果组件版本不同,私有变量名可能有变化,需要对应调整。
方法2:改用GUID标识(更可靠)
NOTIFYICONIDENTIFIER支持两种标识逻辑:要么填uID,要么填guidItem,不用同时设置。如果找不到uID,改用GUID是更稳妥的方案:
- 生成专属GUID:在Delphi IDE里按
Ctrl+Shift+G生成一个唯一GUID,比如:
const MY_TRAY_GUID: TGUID = '{1A2B3C4D-5E6F-7G8H-9I0J-KLNMOPQRSTUV}';
- 给托盘图标绑定GUID:可以在组件添加图标后,调用
Shell_NotifyIcon(NIM_MODIFY)来设置GUID(如果不想改组件源码的话):
var nid: TNotifyIconData; begin FillChar(nid, SizeOf(nid), 0); nid.cbSize := SizeOf(nid); nid.hWnd := TextTrayIcon1.Handle; nid.uID := 1; // 如果之前试出默认uID是1,就填这个,否则用方法1获取的uID nid.uFlags := NIF_GUID; nid.guidItem := MY_TRAY_GUID; Shell_NotifyIcon(NIM_MODIFY, nid); end;
- 调用Shell_NotifyIconGetRect时用GUID:
FillChar(S, SizeOf(S), #0); S.cbSize := SizeOf(NOTIFYICONIDENTIFIER); S.hWnd := form1.TextTrayIcon1.Handle; S.guidItem := MY_TRAY_GUID; // 用GUID替代uID if Shell_NotifyIconGetRect(S, R) = S_OK then Showmessage('OK!') else Showmessage('ERROR!');
方法3:试试通用默认值
不少简单的CoolTrayIcon实现会把uID设为1或者组件的Tag属性,你可以先快速测试这两个值:
S.uID := 1; // 最常见的默认值,先试这个 // 或者 S.uID := TextTrayIcon1.Tag;
另外要提醒:Shell_NotifyIconGetRect是Windows Vista及以上系统才支持的API,你已经手动声明了函数,这点没问题,但要确保程序运行在兼容的系统上。
内容的提问来源于stack exchange,提问作者Atak_Snajpera
相关产品推荐
相关产品推荐

