分享
 
 
 

系统托盘编程完全指南(二)

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

系统托盘编程完全指南(二)

编译/northtibet

下载本文例子源代码

在本文的第一部分,我们讨论并示范了如何在自己的程序中应用系统托盘图标。通过使用自己创建的一个可重用的

C++ 类——CTrayIcon,我们可以轻松地实现托盘程序。不久以前我用这个类编写了一个程序,开始运行很正常,但是有一次不知什么原因Windows资源管理器死掉了,也就是说非正常关闭,重启资源管理器后,发现托盘程序仍然在运行,但托盘图标显示不出来,在任务栏中看不到托盘图标,只有重新启动机器才能重新显示出托盘图标,让人觉得心里很不舒服,有没有什么办法在这个时候不用重启机器而让Windows自动找回托盘图标并把它添加到任务栏呢?,也就是让它自动恢复托盘图标程序的用户界面,经过一番研究,终于有所收获。

实际上,如果你用的操作系统是Windows 98或者你安装了IE4.0的桌面。那么不论什么时候,只要IE4.0启动了任务栏,那么它就会向所有最顶层父窗口广播一个注册消息:TaskbarCreated。有了这个线索,你就可以重新创建图标。如果你用MFC编程,那么只要定义一个全程变量保存这个注册消息并实现ON_REGISTERED_MESSAGE消息处理例程即可:

const UINT WM_TASKBARCREATED =

::RegisterWindowMessage(_T("TaskbarCreated"));

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

ON_REGISTERED_MESSAGE(WM_TASKBARCREATED,

OnTaskBarCreated)

END_MESSAGE_MAP(CMainFrame, CFrameWnd)

The handler itself should reinstall whatever icons you need.

LRESULT CMainFrame::OnTaskBarCreated(WPARAM wp, LPARAM lp)

{

VERIFY(InstallIcons());

return 0;

}

BOOL CMainFrame::InstallIcons()

{

NOTIFYICONDATA nid;

//

// 准备 nid 参数

//

return Shell_NotifyIcon(NIM_ADD, &nid);

难道就这么容易吗?当然不是,你必须单独实现InstallIcons函数,而不是直接从OnTaskBarCreated中调用Shell_NotifyIcon,因为一般来说,在应用程序启动的时候你也会调用它。

当我搞清楚TaskbarCreated的奥秘之后,我便回到本文第一部分中创建的那个CTrayIcon类,对它进行了修改和完善,改动不是很大。这个类管理的是单个的托盘图标(如果你有多个,那么为每个图标创建一个单独的实例吧)。使用CTrayIcon时,你只要在CMainFrame中创建一个实例m_trayIcon并象下面这样安装它即可:

// 在CMainFrame::OnCreate中

m_trayIcon.SetNotificationWnd(this,

WM_MY_TRAY_NOTIFICATION);

m_trayIcon.SetIcon(IDI_MYICON);

WM_MY_TRAY_NOTIFICATION 是自己的私有消息,只在有事件发生时,托盘图标才发送此消息,如用户单击图标。对于托盘图标来说,你不用对它做什么处理,CTrayIcon全权负责。只是在构造CTrayIcon对象时,你给它一个资源ID就可以了。CTrayIcon用这个ID查找上下文菜单,如果找到的话,它便自动处理右键单击托盘图标事件,这时弹出上下文菜单。如果用户双击图标,CTrayIcon则执行第一个菜单项命令。所以你要做的全部工作只是创建一个菜单资源,将ID传递给构造函数,然后去驱动CTrayIcon就可以了。如果你想要一些非标准的例程,那么只需处理WM_MY_TRAY_NOTIFICATION即可。有关细节请参考源代码。

为了实现图标自动重建特性,我使用了以前很多文章中都用到的一个类CSubclassWnd,这个类在我的编程生涯中几乎无处不在。没有了它,我几乎寸步难行;在我的所有编程诀窍中,它是最有用的一个类。用这个类可以截获Windows消息,并将它发送到另外一个窗口消息处理例程中处理,而不是发送到Windows自己默认的消息处理函数。CTrayIcon用它来截获TaskbarCreated消息,所以你就不必为此编写消息处理器——这个方法非常酷。CSubclassWnd通过安装它自己的窗口过程,从而先于MFC一步对消息进行处理。

当CMainFrame调用CTrayIcon::SetNotificationWnd时,CTrayIcon调用GetTopLevelParent以获取顶层父窗口,然后安装CSubclassWnd窗口过程,这相当于一个钩子,在消息传到任何顶层窗口之前,CSubclassWnd的窗口过程先将它处理掉。这里必须明白一点:Windows只将TaskbarCreated消息发送到顶层父窗口。它有点象WM_QUERYNEWPALETTE、WM_SYSCOLORCHANGE消息以及其它顶层窗口消息。现在当Windows发送TaskbarCreated时,控制将首先被传递到CTrayIcon::CTrayHook::WindowProc。

CTrayIcon::OnTaskBarCreate是CTrayIcon类中新加的一个虚拟函数,其默认实现是在系统托盘中重新安装图标。如果你想做一些其它的事情,可以派生一个新类并改写此默认行为。实际的WindowProc代码比我在本文中描述的要稍微复杂一些,因为它还要处理托盘通知以驱动默认的菜单处理例程,以前,当获得WM_MY_TRAY_NOTIFICATION消息时,你必须自己调用OnTrayNotification。新的CTrayIcon实现请参考本文的源代码。

顺便提及一下,你想知道我是如何测试图标自动重建特性的吗?(如果是你,你用什么办法?),很容易。在Windows 98中,按下Ctrl+Alt+Del,弹出任务管理器的任务清单。选择"资源管理器(Explorer)",然后选择"结束任务(End Task)"。此时会显示关机/重启对话框,此时按下"取消"按钮(不要按"关机"按钮)。然后,等待几秒钟,你得到消息显示"这个任务没有响应",这时你要用"结束任务"来回复。接下来Windows的资源管理器便非正常终止!然后它又会自动起来,这时向所有顶层父窗口广播TaskbarCreated消息。如果你的操作系统是Windows NT/2000/XP,并安装了IE4.0,如法炮制。当任务栏死掉后,从"开始"菜单的"运行"对话框中敲入"explorer"启动器源管理器。不管是用什么操作系统,在杀掉任务栏之前,如果TrayTest程序处于运行状态,那么当资源管理器自己恢复状态时,TrayTest程序的托盘图标会自动创新安装。不信的话,你用本文第一部分的例子程序和本文提供的范例程序试一下就知道了。你会发现本文的例子程序会处理TaskbarCreated消息,而另一个则完全不会。(待续)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有