Win32 API 实现系统托盘程序

本文介绍如何使用 Win32 API 开发具备托盘菜单、图标、气泡提示等功能的系统托盘程序。文章详细展示了创建托盘程序的过程,包括初始化托盘、处理消息、显示托盘提示等步骤。

托盘程序就是运行在系统托盘区域的程序,显示为桌面右下角显示区域的一个小图标。通常托盘程序带有几种功能:托盘菜单,托盘图标,气泡提示,托盘提示。例如QQ收到消息后,会在系统右下角显示闪动QQ图标。

主程序Tray.cpp

[cpp]  view plain copy
  1. #include <windows.h>  
  2. #include "resource.h"  
  3.   
  4. #define WM_TRAY (WM_USER + 100)  
  5. #define WM_TASKBAR_CREATED RegisterWindowMessage(TEXT("TaskbarCreated"))  
  6.   
  7. #define APP_NAME    TEXT("托盘程序")  
  8. #define APP_TIP     TEXT("Win32 API 实现系统托盘程序")  
  9.   
  10. NOTIFYICONDATA nid;     //托盘属性  
  11. HMENU hMenu;            //托盘菜单  
  12.   
  13. //实例化托盘  
  14. void InitTray(HINSTANCE hInstance, HWND hWnd)  
  15. {  
  16.     nid.cbSize = sizeof(NOTIFYICONDATA);  
  17.     nid.hWnd = hWnd;  
  18.     nid.uID = IDI_TRAY;  
  19.     nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;  
  20.     nid.uCallbackMessage = WM_TRAY;  
  21.     nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TRAY));  
  22.     lstrcpy(nid.szTip, APP_NAME);  
  23.   
  24.     hMenu = CreatePopupMenu();//生成托盘菜单  
  25.     //为托盘菜单添加两个选项  
  26.     AppendMenu(hMenu, MF_STRING, ID_SHOW, TEXT("提示"));  
  27.     AppendMenu(hMenu, MF_STRING, ID_EXIT, TEXT("退出"));  
  28.   
  29.     Shell_NotifyIcon(NIM_ADD, &nid);  
  30. }  
  31.   
  32. //演示托盘气泡提醒  
  33. void ShowTrayMsg()  
  34. {  
  35.     lstrcpy(nid.szInfoTitle, APP_NAME);  
  36.     lstrcpy(nid.szInfo, TEXT("收到一条消息!"));  
  37.     nid.uTimeout = 1000;  
  38.     Shell_NotifyIcon(NIM_MODIFY, &nid);  
  39. }  
  40.   
  41. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
  42. {  
  43.     switch (uMsg)  
  44.     {  
  45.     case WM_TRAY:  
  46.         switch(lParam)  
  47.         {  
  48.         case WM_RBUTTONDOWN:  
  49.             {  
  50.                 //获取鼠标坐标  
  51.                 POINT pt; GetCursorPos(&pt);  
  52.   
  53.                 //解决在菜单外单击左键菜单不消失的问题  
  54.                 SetForegroundWindow(hWnd);  
  55.   
  56.                 //使菜单某项变灰  
  57.                 //EnableMenuItem(hMenu, ID_SHOW, MF_GRAYED);      
  58.   
  59.                 //显示并获取选中的菜单  
  60.                 int cmd = TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, NULL, hWnd,  
  61.                      NULL);  
  62.                 if(cmd == ID_SHOW)  
  63.                     MessageBox(hWnd, APP_TIP, APP_NAME, MB_OK);  
  64.                 if(cmd == ID_EXIT)   
  65.                     PostMessage(hWnd, WM_DESTROY, NULL, NULL);  
  66.             }  
  67.             break;  
  68.         case WM_LBUTTONDOWN:  
  69.             MessageBox(hWnd, APP_TIP, APP_NAME, MB_OK);  
  70.             break;  
  71.         case WM_LBUTTONDBLCLK:  
  72.             break;  
  73.         }  
  74.         break;  
  75.     case WM_DESTROY:  
  76.         //窗口销毁时删除托盘  
  77.         Shell_NotifyIcon(NIM_DELETE, &nid);  
  78.         PostQuitMessage(0);  
  79.         break;  
  80.     case WM_TIMER:  
  81.         ShowTrayMsg();  
  82.         KillTimer(hWnd, wParam);  
  83.         break;  
  84.     }  
  85.     if (uMsg == WM_TASKBAR_CREATED)  
  86.     {  
  87.         //系统Explorer崩溃重启时,重新加载托盘  
  88.         Shell_NotifyIcon(NIM_ADD, &nid);  
  89.     }  
  90.     return DefWindowProc(hWnd, uMsg, wParam, lParam);  
  91. }  
  92.   
  93. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,   
  94.     LPSTR /*lpCmdLine*/int iCmdShow)  
  95. {  
  96.     HWND hWnd;  
  97.     MSG msg;  
  98.     WNDCLASS wc = { 0 };  
  99.     wc.style = NULL;  
  100.     wc.hIcon = NULL;  
  101.     wc.cbClsExtra = 0;  
  102.     wc.cbWndExtra = 0;  
  103.     wc.hInstance = hInstance;  
  104.     wc.lpfnWndProc = WndProc;  
  105.     wc.hbrBackground = NULL;  
  106.     wc.lpszMenuName = NULL;  
  107.     wc.lpszClassName = APP_NAME;  
  108.     wc.hCursor = NULL;  
  109.   
  110.     if (!RegisterClass(&wc)) return 0;  
  111.   
  112.     hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, APP_NAME, APP_NAME, WS_POPUP, CW_USEDEFAULT,  
  113.         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);  
  114.   
  115.     ShowWindow(hWnd, iCmdShow);  
  116.     UpdateWindow(hWnd);  
  117.   
  118.     InitTray(hInstance, hWnd);          //实例化托盘  
  119.     SetTimer(hWnd, 3, 1000, NULL);      //定时发消息,演示气泡提示功能  
  120.   
  121.     while (GetMessage(&msg, NULL, 0, 0))  
  122.     {  
  123.         TranslateMessage(&msg);  
  124.         DispatchMessage(&msg);  
  125.     }  
  126.     return msg.wParam;  
  127. }  

资源头文件 resource.h

[cpp]  view plain copy
  1. #define IDI_TRAY    101  
  2. #define ID_SHOW     40001  
  3. #define ID_EXIT     40002  

资源文件 resource.rc

[cpp]  view plain copy
  1. #include "resource.h"  
  2.   
  3. IDI_TRAY ICON DISCARDABLE "ico.ico"  

编译很简单,使用 Visual Studio建立一个空项目,建好以上3个文件,再找一个ico图标,保存为ico.ico,即可编译。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值