任務(wù)欄的右邊(托盤)常駐幾個圖標,如輸入法切換圖標、音量控制圖標等,此外我們還經(jīng)常遇到擁有托盤圖標的軟件,如金山詞霸、有實時監(jiān)測功能的殺毒軟件等。這些軟件在后臺運行,通常不占用太多的屏幕資源,只在通知欄上放一個小小的標志。必要時我們可以通過用鼠標點擊圖標對其進行菜單操作或激活其主窗口。有時我們自己編寫的程序也希望有類似的效果,本文詳細地介紹用VC++6.0設(shè)計這種托盤圖標程序的方法。
---- NOTIFYICONDATA結(jié)構(gòu)包含了系統(tǒng)用來處理托盤圖標的信息,它包括選擇的圖標、回調(diào)消息、提示消息、圖標對應(yīng)的窗口等內(nèi)容。其定義為:
- //系統(tǒng)定義結(jié)構(gòu)體
- typedef struct _NOTIFYICONDATA
- {
- DWORD cbSize; //以字節(jié)為單位的這個結(jié)構(gòu)的大小
- HWND hWnd; //接收托盤圖標通知消息的窗口句柄
- UINT uID; //應(yīng)用程序定義的該圖標的ID號
- UINT uFlags; //設(shè)置該圖標的屬性
- UINT uCallbackMessage; //應(yīng)用程序定義的消息ID號,此消息傳遞給hWnd
- HICON hIcon; //圖標的句柄
- char szTip[64]; //鼠標停留在圖標上顯示的提示信息
- } NOTIFYICONDATA, *PNOTIFYICONDATA;
-
- /*
- 該結(jié)構(gòu)中,成員uFlags可以使下列之一或組合:
- NIF_ICON 設(shè)置成員hIcon有效
- NIF_MESSAGE 設(shè)置成員uCallbackMessage有效
- NIF_TIP 設(shè)置成員szTip有效
- */
Shell_NotifyIcon函數(shù) ---- 全局函數(shù)Shell_NotifyIcon()用于在托盤上增加、刪除或修改圖標。其原型為:
- WINSHELLAPI BOOL WINAPI Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA pnid);
- /*
- ---Pnid是NOTIFYICONDATA結(jié)構(gòu)的指針; dwMessage是被傳遞的消息,可以是以下消息之一:
- NIM_ADD 增加圖標
- NIM_DELETE 刪除圖標
- NIM_MODIFY 修改圖標
- */
使用實例
1) 在所要處理的Frame或Dialog中添加保護成員變量
- protected:
- NOTIFYICONDATA m_tnid;
2) 為對應(yīng)的Frame 或Dialog 添加 WM_CREATE 消息函數(shù),在對應(yīng)實現(xiàn)函數(shù)中添加托盤生成代碼
在對應(yīng)的類聲明文件中定義消息 ,并在OnCreate 函數(shù)中Return 之前添加代碼
- //對應(yīng)的類聲明文件中定義消息
- #define MYWM_NOTIFYICON WM_USER+1
-
- //OnCreate 函數(shù)中return 之前添加托盤生成代碼
- m_tnid.cbSize=sizeof(NOTIFYICONDATA);
- m_tnid.hWnd=this->m_hWnd;
- m_tnid.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
- m_tnid.uCallbackMessage=MYWM_NOTIFYICON;
- //用戶定義的回調(diào)消息
- CString szToolTip;
- szToolTip=_T("托盤圖標實例"); //鼠標在托盤上移動時顯示文本
- _tcscpy(m_tnid.szTip, szToolTip);
- m_tnid.uID=IDR_MAINFRAME;
- HICON hIcon;
- hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- m_tnid.hIcon=hIcon;
- ::Shell_NotifyIcon(NIM_ADD,&m_tnid);
- if(hIcon)::DestroyIcon(hIcon);
3) 編寫消息處理函數(shù)
----為了處理圖標回調(diào)消息,如鼠標左鍵雙擊、鼠標右鍵單擊消息,我們重載WindowProc()函數(shù)。此外,我們還希望在主框架窗口最小化時圖標不在任務(wù)欄空白區(qū)出現(xiàn),在此函數(shù)中同時作相應(yīng)處理。
別忘了編輯屬于你自己的菜單,這里暫且使用 IDR_RIGHT_MENU 標志
- LRESULT ***Frame/*or Dialog*/::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch(message){
- case MYWM_NOTIFYICON:
- //如果是用戶定義的消息
- if(lParam==WM_LBUTTONDBLCLK)
- {
- //鼠標雙擊時主窗口出現(xiàn)
- AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOW);
- }
- else if(lParam==WM_RBUTTONDOWN){
- //鼠標右鍵單擊彈出菜單
- CMenu menu;
- menu.LoadMenu(IDR_RIGHT_MENU);
- //載入事先定義的菜單
- CMenu* pMenu=menu.GetSubMenu(0);
- CPoint pos;
- GetCursorPos(&pos);
- pMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,pos.x,pos.y,AfxGetMainWnd());
- }
- break;
- case WM_SYSCOMMAND:
- //如果是系統(tǒng)消息
- switch(wParam){
- case SC_MINIMIZE:
- //接收到最小化消息時主窗口隱藏
- ShowWindow(SW_HIDE);
- return 0;
- break;
- case SC_CLOSE :
- ::Shell_NotifyIcon(NIM_DELETE,&m_nid); //關(guān)閉時刪除系統(tǒng)托盤圖標
- break;
- }
- break;
- }
- return CFrameWnd/*or CDialog*/::WindowProc(message, wParam, lParam); //其實就是調(diào)用父類的消息處理函數(shù)
- }
至此,托盤圖標程序的常規(guī)功能我們均已實現(xiàn)。我們還可以通過Shell_NotifyIcon()函數(shù)的調(diào)用實現(xiàn)不同狀態(tài)下圖標的改變,
|