




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
windows sdk编程系列文章 - 系统托盘2008-04-20 22:54本课中,我们将学习如何把小图标放到系统托盘中去以及如何创建和使用弹出式菜单。理论:系统托盘是指任务条中的一个方形区域,在该区域中可以放入一些小图标,通常您可以在此处看到系统提供的最新时间。您自己当然也可以把快捷小图标放到此处。下面是这么做的步骤: 1. 设置NOTIFYICONDATA型的结构体变量的成员变量的值: o cbSize 该结构体的大小。 o hwnd 窗口的句柄。当鼠标滑过该小图标时,该窗口将接收到相关的消息。 o uID 小图标的ID号。您可以取任意值,只是当您的应用程序有不止一个小图标时,您要能够区分出到底是那一个小图标接收到了鼠标的消息,也即ID号必须唯一。 o uFlags 指定该结构体变量的那些成员变量有效。 NIF_ICON 有效。 NIF_MESSAGE 有效。 NIF_TIP 有效。 o uCallbackMessage 自定义的消息。当鼠标对小图标动作时,WINDOWS外壳将把该消息发送到您的应用程序。该消息的值您可以自己定义。 o hIcon 放入系统托盘中的图标的句柄。 o szTip 64字节的缓冲区,它用来放入提示字符串,当鼠标停留在小图标上时,就会显示该字符串。 2. 调用Shell_NotifyIcon函数。该函数在shell32.inc中定义,其原型如下: BOOL Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA lpdata ); dwMessage 是发送到WINDOWS外壳的消息: NIM_ADD 把小图标加到系统托盘区。 NIM_DELETE 从系统托盘中删除小图标。 NIM_MODIFY 修改小图标。 lpdata 是指向NOTIFYICONDATA型结构体变量的指针。如果您想要加入一个小图标就用NIM_ADD,删除时使用NIM_DELETE消息。基本上的消息就是这些。但是大多数的情况下,您不会仅仅满足把一个小图标放到那里。您还必须要对鼠标事件作出适当的反应。您可以在NOTIFYICONDATA型的结构体变量的成员变量uCallbackMessage 中设置您要处理的消息,然后WINDOWS外壳将在发生这些事件时通知您的应用程序。随着消息传送的参数wParam和lParam的值如下: wParam 小图标的ID号。它和您在NOTIFYICONDATA型结构体变量中的成员变量uID中设置的值一样。 lParam 低字包含鼠标消息。譬如,用户在小图标上按下了右键时,lParam中将包含WM_RBUTTONDOWN消息。 大多数的系统托盘中的小图标,在用户用鼠标右击时都会弹出一个菜单以方便用户选择。我们可先创建菜单,然后调用TrackPopupMenu函数来显示它。步骤如下: 1. 调用CreatePopupMenu函数来创建菜单。该函数创建一个空的菜单。如果成功,将返回该菜单的句柄。 2. 调用AppendMenu, InsertMenu 或 InsertMenuItem来向菜单中加入菜单项。 3. 当您想在当前鼠标位置显示该菜单时,调用GetCursorPosition函数来得到鼠标当前的屏幕位置,然后调用TrackPopupMenu来显示菜单。当用户从弹出式菜单中选择了一个菜单项时,WINDOWS将发送WM_COMMAND消息给您应用程序的消息处理过程,这和通常的菜单选择是一样的。. 注意:当您使用系统托盘中的小图标时有两件比较讨厌的事: 1. 该菜单可能不会像通常那样马上消失掉。这是因为从弹出式接收消息的窗口必须是前景窗口。调用SetForegroundWindow函数就可以纠正该错误; 2. 在调用了SetForegroundWindow函数后,您会发现第一次该弹出式菜单会正常弹出而且工作的很好。但是随后,该菜单只是一弹出就立即消失。根据MSDN,这么做是故意的。为了使得弹出菜单保持住,必须要求下一个切换到的是程序的主窗口。您可以通过邮寄任何消息给该程序的窗口来强行进行任务切换。注意要使用PostMessage而不是SendMessage。 例子:见光盘FirstWindow21#include Windows.h#include tchar.h#define WM_SHELLNOTIFY WM_USER+5#define IDI_TRAY 0#define IDM_RESTORE 1000#define IDM_EXIT 1010TCHAR ClassName = _T(TrayIconWinClass);TCHAR AppName = _T(TrayIcon Demo);TCHAR RestoreString = _T(&Restore);TCHAR ExitString = _T(E&xit Program);HINSTANCE g_hInstance;NOTIFYICONDATA note;HMENU hPopupMenu;INT_PTR CALLBACK ProcWinMain( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ) POINT pt; switch(Msg) case WM_CREATE: hPopupMenu = CreatePopupMenu(); AppendMenu(hPopupMenu,MF_STRING,IDM_RESTORE,RestoreString); AppendMenu(hPopupMenu,MF_STRING,IDM_EXIT,ExitString); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_SIZE: if(wParam = SIZE_MINIMIZED) note.cbSize = sizeof(NOTIFYICONDATA); note.hWnd = hWnd; note.uID = IDI_TRAY; note.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; note.uCallbackMessage = WM_SHELLNOTIFY; note.hIcon = LoadIcon(NULL,IDI_WINLOGO); lstrcpy(note.szTip,AppName); ShowWindow(hWnd,SW_HIDE); Shell_NotifyIcon(NIM_ADD,¬e); break; case WM_COMMAND: if(lParam = 0) Shell_NotifyIcon(NIM_DELETE,¬e); if(LOWORD(wParam) = IDM_RESTORE) ShowWindow(hWnd,SW_RESTORE); else DestroyWindow(hWnd); break; case WM_SHELLNOTIFY: if(wParam = IDI_TRAY) if(lParam = WM_RBUTTONDOWN) GetCursorPos(&pt); TrackPopupMenu(hPopupMenu,TPM_RIGHTALIGN,pt.x, pt.y,NULL,hWnd,NULL); else if(lParam = WM_LBUTTONDBLCLK) SendMessage(hWnd,WM_COMMAND,IDM_RESTORE,0); break; default: return DefWindowProc(hWnd,Msg,wParam,lParam); return 0;int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) WNDCLASSEX wc; MSG msg; HWND hWnd; g_hInstance = hInstance; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW |CS_DBLCLKS; wc.lpfnWndProc = ProcWinMain; wc.cbClsExtra = NULL; wc.cbWndExtra = NULL; wc.hInstance = hInstance; wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE); wc.lpszMenuName = NULL; wc.lpszClassName = ClassName; wc.hIcon = wc.hIconSm = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); RegisterClassEx(&wc); hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,ClassName,AppName,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,350,200,NULL,NULL,hInstance,NULL); ShowWindow(hWnd,SW_SHOWNORMAL); UpdateWindow(hWnd); while(GetMessage(&msg,NULL,0,0) TranslateMessage(&msg); DispatchMessage(&msg); return msg.wParam;分析:该程序将显示一个简单的窗口。当您按下最小化按钮时,该窗口将隐藏,然后放一个小图标到系统托盘中。当您双击小图标时,应用程序将恢复自己,并把小图标从系统托盘中删除。当您右击小图标时,会显示一个弹出式菜单。您可以在菜单中选择是恢复窗口还是退出应用程序。 case WM_CREATE: hPopupMenu = CreatePopupMenu(); AppendMenu(hPopupMenu,MF_STRING,IDM_RESTORE,RestoreString); AppendMenu(hPopupMenu,MF_STRING,IDM_EXIT,ExitString); break;当主窗口创建时,将会创建一个弹出式菜单,并且加入两个菜单项。 AppendMenu的语法如下: BOOL AppendMenu( HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem,LPCTSTR lpNewItem ); hMenu 是将要加入菜单项的菜单的句柄。 uFlags 告诉WINDOWS要加入的菜单项是位图、字符串或自画的项目以及是可用、不可用或灰色显示等。您可以从WIN32 API 指南中得到全部的标志位的信息。在我们的例子中使用标志位MF_STRING,它表示我们加入的菜单项是字符串。 uIDNewItem 是菜单项的ID号。这是一个用户自定义的值,它用来唯一地代表菜单项。. lpNewItem 用来指定菜单项的内容,具体代表什么取决于uFlags中指定的标志。我们前面指定了MF_STRING标志,所以此处代表一个字符串 主窗口创建完成后,用户就可以开始测试了。这时按下最小化键。当一个窗口被最小化时将接收到WM_SIZE消息,其中wParam参数中的值为SIZE_MINIMIZED。 case WM_SIZE: if(wParam = SIZE_MINIMIZED) note.cbSize = sizeof(NOTIFYICONDATA); note.hWnd = hWnd; note.uID = IDI_TRAY; note.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; note.uCallbackMessage = WM_SHELLNOTIFY; note.hIcon = LoadIcon(NULL,IDI_WINLOGO); lstrcpy(note.szTip,AppName); ShowWindow(hWnd,SW_HIDE); Shell_NotifyIcon(NIM_ADD,¬e); break;这时我们来给NOTIFYICONDATA型结构体变量赋值。IDI_TRAY是在代码开始处定义的一个数值常量,您可以任意设定它的值。由于我们仅有一个图标,所以这一点并不重要,如果要同时加入几个系统图标的话,那么每个图标都要有一个唯一的ID号。由于我们指定了一个图标NIF_ICON,所以我们要在uFlags成员变量中指定所有的标志位,我们还指定了一个自定义的消息NIF_MESSAGE和帮助文本NIF_TIP。 WM_SHELLNOTIFY 被定义为WM_USER+5,只要是唯一的值,就无所谓是多少了,只要大于WM_USER。我们这里用的是WINDOWS登录时的图标,当然您可以使用任意您想要用的图标,您可以用LoadIcon函数从资源中装载,该函数返回一个图标的句柄。最后我们在szTip中放入当鼠标放在图标时显示的提示文本。为了达到“最小化然后只显示图标的效果”,我们在这时隐藏掉主窗口。 接下来,我们调用Shell_NotifyIcon函数并指定标志位NIM_ADD把图标加到系统托盘中去。现在我们的主窗口隐藏了,图标显示在系统托盘中。如果您让鼠标从图标上滑过,将看到提示文本。如果您双击小图标,主窗口就会显示,图标将消失。 case WM_SHELLNOTIFY: if(wParam = IDI_TRAY) if(lParam = WM_RBUTTONDOWN) GetCursorPos(&pt); TrackPopupMenu(hPopupMenu,TPM_RIGHTALIGN,pt.x, pt.y,NULL,hWnd,NULL); else if(lParam = WM_LBUTTONDBLCLK) SendMessage(hWnd,WM_COMMAND,IDM_RESTORE,0); break;当在系统托盘中的图标发生鼠标事件时,您的窗口将接收到WM_SHELLNOTIFY消息,该消息是在uCallbackMessage成员变量中指定的。在接收到该消息时,wParam中包含了图标的ID号,lParam中包含了鼠标动作的原始数据。在上面的代码中,我们首先检测是否是我们感兴趣的消息。如果是的话,我们在看看是什么消息。因为我们只对右击和双击事件感兴趣,所以我们仅仅处理WM_RBUTTONDOWN和WM_LBUTTONDBLCLK消息。 如果是WM_RBUTTONDOWN,我们调用GetCursorPos来得到鼠标光标所在的当前屏幕位置。注意我指的是屏幕位置,即,其坐标是相对于整个的屏幕的。譬如,如果屏幕的解析读640*480,那么它的右下角的坐标是x=639 ,y=479。如果您想要把屏幕位置转换成窗口的坐标,可以调用ScreenToClient函数我们想要在当前的位置显示弹出式菜单,我们就调用TrackPopupMenu函数,该函数需要屏幕的坐标,由GetCursorPos函数返回的坐标就可以原封不动的拿过来用。TrackPopupMenu的原型如下:BOOL TrackPopupMenu( HMENU hMenu, UINT uFlag
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年出版专业资格考试(出版专业理论与实务初级)仿真试题及答案二
- 二手房经纪人专业能力提升培训
- 湿地生态修复工程建设与碳汇促进方案
- 2025年时事政治必考题库及答案详解(考点梳理)
- 2025年大学生自主创业能力考试题及答案
- 大米线下营销活动方案
- 生成式人工智能对电子商务课程改革的影响
- 干散货码头全流程自动化方案
- 城市更新公共空间改造建设方案
- xx区集中供热管网工程可行性研究报告
- 食品异物赔偿协议书
- 老年社会支持网络的构建与效果评估-全面剖析
- 学生午托安全管理制度
- 养老院护理九防内容课件
- 人教版三年级数学上册教学计划(及进度表)
- 不要慌太阳下山有月光二部合唱线谱
- 光伏维护合同范本
- 房产查封申请书
- 2024年新疆伊犁州直检察机关招聘聘用制书记员笔试真题
- 《掌骨骨折诊治》课件
- 北师大版六年级数学上册课件 圆周率的历史
评论
0/150
提交评论