系统托盘Shell_NotifyIcon函数的简单运用

来源:互联网 发布:rust知乎 编辑:程序博客网 时间:2024/05/18 21:48

http://blog.csdn.net/pgshow/article/details/7526168


这里为了给同学写一个小工具,要用到系统托盘的功能,编程偶才刚入门,所以花了3个小时才调试好。趁热打铁,把学到的具体内容分享下。

 

要用到的函数是Shell_NotifyIcon,VC里需要包含头文件ShellApi.h。

 

函数就是Shell_NotifyIcon,原型如下:

BOOL Shell_NotifyIcon(DWORD dwMessage,NOTIFYICONDATA  lpdata);

 

首先是第一个参数dwMessage,可以取下面两个值:

NIM_ADD          //这个会添加一个图标到系统托盘处

NIM_DELETE    //我们用这个删除系统托盘处的图片

 

NOTIFYICONDATA的数据结构如下所示:

 

[cpp] view plaincopy
  1. typedef struct _NOTIFYICONDATA {  
  2.     DWORD cbSize;  
  3.     HWND hWnd;  
  4.     UINT uID;  
  5.     UINT uFlags;  
  6.     UINT uCallbackMessage;  
  7.     HICON hIcon;  
  8.     TCHAR szTip[64];  
  9.     DWORD dwState;  
  10.     DWORD dwStateMask;  
  11.     TCHAR szInfo[256];  
  12.     union {  
  13.         UINT uTimeout;  
  14.         UINT uVersion;  
  15.     };  
  16.     TCHAR szInfoTitle[64];  
  17.     DWORD dwInfoFlags;  
  18.     GUID guidItem;  
  19.     HICON hBalloonIcon;  
  20. } NOTIFYICONDATA, *PNOTIFYICONDATA;  


看似很复杂,不过我们只会用到几个参数而已,下面我会说明的:

 

使用步骤:

1.先定义一个全局的变量:

NOTIFYICONDATA nid

2.然后在适当的位置对nid进行初始化,我是在主窗口的 while (GetMessage (&msg, NULL, 0, 0))  语句之前初始化的。

[cpp] view plaincopy
  1.     nid.cbSize = sizeof(NOTIFYICONDATA);     //初始化结构的大小  
  2.     nid.hWnd = hwnd;                         //指定接收托盘消息的句柄  
  3.     nid.uID = IDI_ICON1;                     //指定托盘图标的ID  
  4.     nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;  //设定结构里有效的位置  
  5.              //NIF_ICON:     指定hIcon是有效的,(这里设定自定义系统托盘图标必须的  
  6.              //NIF_MESSAGE:  指定uCallbackMessage是有效的,用于程序接收来自托盘图标的消息,需要自定义一个消息  
  7.                //NIF_TIP:      指定szTip是有效的,功能是当鼠标移动到图标上时,显示提示信息   
  8.     nid.uCallbackMessage = WM_IAWENTRAY;     //自定义的消息,我在一开始定义了一个自定义消息 //#define WM_IAWENTRAY  WM_USER+5  
  9.     nid.hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON1));  //设置图标的句柄  
  10.     _tcscpy(nid.szTip,TEXT("TimeWork正在工作!\r\n点击打开主界面")); //设置鼠标移上托盘图标时的提示信息 //_tcscpy是tchar.h里定义的宏  

完成了上面的设置,就可以调用了。

 

3.我们将在最小化窗口消息里调用 Shell_NotifyIcon(NIM_ADD, &nid)  将图标设置到系统托盘。

[cpp] view plaincopy
  1. case WM_DESTROY:  
  2.   Shell_NotifyIcon(NIM_DELETE, &nid);  
  3.   return TRUE;  
  4. case WM_SYSCOMMAND:  
  5.   switch(wParam)  
  6.   {  
  7.     case SC_CLOSE:  
  8.       DestroyWindow(hDlg);  
  9.       PostQuitMessage(0);  
  10.       return TRUE;  
  11.     case SC_MINIMIZE:  
  12.       ShowWindow(hwnd,SW_HIDE);  
  13.       Shell_NotifyIcon(NIM_ADD, &nid);  
  14.       return TRUE;  
  15.   }  


 

在自定义的 WM_IAWENTRAY 消息里面判断鼠标是否点击,并调用 ShowWindow(hwnd, SW_SHOWNORMAL) 显示主窗口。

[cpp] view plaincopy
  1. case WM_IAWENTRAY:  
  2.   if(wParam == IDI_ICON1){  
  3.     if(lParam == WM_LBUTTONDOWN){  
  4.       ShowWindow(hDlg, SW_SHOWNORMAL);  
  5.       return TRUE;  
  6.     }    
  7.   }  
  8.   return FALSE;  

 

其中消息的wParam参数为指定的图标ID,lParam参数为事件类型,示例里只接收了WM_LBUTTONDOWN事件,即鼠标左键点击事件!

 

完整的代码如下:

 

[cpp] view plaincopy
  1. #include <windows.h>  
  2. #include <tchar.h>  
  3. #include "ShellAPI.h"  
  4. #include "resource.h"  
  5.   
  6. #define WM_IAWENTRAY    WM_USER+5  //系统托盘的自定义消息  
  7.   
  8. //定义全局变量  
  9. HINSTANCE g_hInst;  
  10. NOTIFYICONDATA nid;  
  11.   
  12. LRESULT CALLBACK WndProc (HWNDUINTWPARAMLPARAM) ;  
  13.   
  14. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,  
  15.     PSTR szCmdLine, int iCmdShow)  
  16. {  
  17.     g_hInst = hInstance; //获取该程序实例句柄  
  18.   
  19.     static TCHAR szAppName[] = TEXT ("TimeWork") ;  
  20.     HWND         hwnd ;  
  21.     MSG          msg ;  
  22.     WNDCLASS     wndclass ;  
  23.   
  24.     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;  
  25.     wndclass.lpfnWndProc   = WndProc ;  
  26.     wndclass.cbClsExtra    = 0 ;  
  27.     wndclass.cbWndExtra    = 0 ;  
  28.     wndclass.hInstance     = hInstance ;  
  29.     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;  
  30.     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;  
  31.     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;  
  32.     wndclass.lpszMenuName  = NULL ;  
  33.     wndclass.lpszClassName = szAppName ;  
  34.   
  35.     if (!RegisterClass (&wndclass))  
  36.     {  
  37.         MessageBox (NULL, TEXT ("This program requires Windows NT!"),   
  38.             szAppName, MB_ICONERROR) ;  
  39.         return 0 ;  
  40.     }  
  41.   
  42.     hwnd = CreateWindow (szAppName,                  // window class name  
  43.         TEXT ("一个Shell_NotifyIcon实例程序"), // window caption  
  44.         WS_OVERLAPPEDWINDOW,        // window style  
  45.         CW_USEDEFAULT,              // initial x position  
  46.         CW_USEDEFAULT,              // initial y position  
  47.         CW_USEDEFAULT,              // initial x size  
  48.         CW_USEDEFAULT,              // initial y size  
  49.         NULL,                       // parent window handle  
  50.         NULL,                       // window menu handle  
  51.         hInstance,                  // program instance handle  
  52.         NULL) ;                     // creation parameters  
  53.   
  54.     ShowWindow (hwnd, iCmdShow) ;  
  55.     UpdateWindow (hwnd) ;  
  56.   
  57.     //初始化NOTIFYICONDATA结构  
  58.     nid.cbSize=sizeof(NOTIFYICONDATA);  
  59.     nid.hWnd=hwnd;  
  60.     nid.uID=IDI_ICON1;  
  61.     nid.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;  
  62.     nid.uCallbackMessage=WM_IAWENTRAY;  
  63.     nid.hIcon=LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON1));  
  64.     _tcscpy(nid.szTip,TEXT("TimeWork正在工作!\r\n点击打开主界面")); //_tcscpy是windows宏,需包含头文件tchar.h  
  65.   
  66.     while (GetMessage (&msg, NULL, 0, 0))  
  67.     {  
  68.         TranslateMessage (&msg) ;  
  69.         DispatchMessage (&msg) ;  
  70.     }  
  71.     return msg.wParam ;  
  72. }  
  73.   
  74. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  75. {  
  76.     HDC         hdc ;  
  77.     PAINTSTRUCT ps ;  
  78.     RECT        rect ;  
  79.   
  80.     switch (message)  
  81.     {  
  82.     case WM_CREATE:  
  83.         return 0 ;  
  84.   
  85.     case WM_PAINT:  
  86.         hdc = BeginPaint (hwnd, &ps) ;  
  87.   
  88.         GetClientRect (hwnd, &rect) ;  
  89.   
  90.         DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,  
  91.             DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;  
  92.   
  93.         EndPaint (hwnd, &ps) ;  
  94.         return 0 ;  
  95.   
  96.     case WM_IAWENTRAY:  
  97.         if(wParam == IDI_ICON1){  
  98.             if(lParam == WM_LBUTTONDOWN){  
  99.                             //还可以在这个地方加入一个菜单,鼠标右键单击时显示  
  100.                 ShowWindow(hwnd, SW_SHOWNORMAL);  
  101.                 return TRUE;  
  102.             }     
  103.         }  
  104.         return FALSE;  
  105.     case WM_SYSCOMMAND:  
  106.         switch(wParam)  
  107.         {  
  108.         case SC_CLOSE:  
  109.             DestroyWindow(hwnd);  
  110.             PostQuitMessage(0);  
  111.             break;  
  112.         case SC_MINIMIZE:  
  113.             ShowWindow(hwnd,SW_HIDE);  
  114.             Shell_NotifyIcon(NIM_ADD,&nid); //最小化时隐藏窗口并设置系统托盘  
  115.             break;  
  116.         }  
  117.         return 0;  
  118.   
  119.     case WM_DESTROY:  
  120.         Shell_NotifyIcon(NIM_DELETE,&nid);  
  121.         PostQuitMessage (0) ;  
  122.         return 0 ;  
  123.     }  
  124.     return DefWindowProc (hwnd, message, wParam, lPar