MFC系統托盤的實現
阿新 • • 發佈:2018-12-29
怎麼實現呢?這裡需要運用到的Windows API函式:
BOOL Shell_NotifyIcon(
DWORD dwMessage,
PNOTIFYICONDATA lpdata
);
函數了裡面的引數對於實現不同的效果尤其重要,包括托盤圖示、托盤選單等等。那麼我們來了解一下兩個引數吧:
dwMessage可以取以下值:
NIM_ADD 向托盤中加入一個圖示
NIM_MODIFY 修改托盤中的圖示
NIM_DELETE 從托盤中刪除一個圖示
引數pnid是NOTIFYICONDATA結構的一個引用。該結構的原型如下:
[cpp] view plain- typedefstruct _NOTIFYICONDATA {
- DWORD cbSize; // 結構的大小,必須在程式中給出
- HWND hWnd; // 程式中將要接收托盤訊息的視窗控制代碼
- UINT uID; // 應用程式中定義的托盤圖示ID,此引數用作標識
- UINT uFlags; //設定屬性 標記下邊3個引數是否有效
- UINT uCallbackMessage;// 自定義的訊息ID值
- HICON hIcon;//顯示在系統托盤上的Icon的控制代碼
-
#if (_WIN32_IE < 0x0500)
- TCHAR szTip[64;// 用於圖示顯示的提示字串
- #else
- TCHAR szTip[128];
- #endif
- #if (_WIN32_IE >= 0x0500)
- DWORD dwState;
- DWORD dwStateMask;
- TCHAR szInfo[256];
- union {
- UINT uTimeout;
- UINT uVersion;
-
} DUMMYUNIONNAME;
- TCHAR szInfoTitle[64];
- DWORD dwInfoFlags;
- #endif
- #if (_WIN32_IE >= 0x600)
- GUID guidItem;
- #endif
- } NOTIFYICONDATA, *PNOTIFYICONDATA;
1.在程式中增加一個私有的NOTIFYICONDAT物件
[cpp] view plain copy print?- private:
- NOTIFYICONDATA m_tnid;
- m_notify.cbSize=sizeof NOTIFYICONDATA;
- m_notify.hWnd=this->m_hWnd;
- m_notify.uID=IDR_MAINFRAME;
- m_notify.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
- strcpy(m_notify.szTip,"Michael_Chen is a good man");
- m_notify.uCallbackMessage=WM_USER_NOTIFYICON;
- m_notify.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; //OK,下面就是托盤產生了.
- Shell_NotifyIcon(NIM_ADD,&m_notify);
1)運用自定義訊息
i,WM_USER_NOTIFYICON是自定義的訊息 在標頭檔案中進行宣告;
[cpp] view plain copy print?- #define WM_USER_NOTIFYICON WM_USER+1
- afx_msg LRESULT OnNotifyMsg(WPARAM wparam,LPARAM lparam);
- BEGIN_MESSAGE_MAP(CNotifyiconDlg, CDialog)
- //{{AFX_MSG_MAP(CNotifyiconDlg)
- ...
- ON_MESSAGE(WM_USER_NOTIFYICON,OnNotifyMsg)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- LRESULT CNotifyiconDlg::OnNotifyMsg(WPARAM wparam,LPARAM lparam)
- //wParam接收的是圖示的ID,而lParam接收的是滑鼠的行為
- {
- if(wparam!=IDR_MAINFRAME)
- return 1;
- switch(lparam)
- {
- case WM_RBUTTONUP://右鍵起來時彈出快捷選單,這裡只有一個“關閉”
- {
- LPPOINT lpoint=new tagPOINT;
- ::GetCursorPos(lpoint);//得到滑鼠位置
- CMenu menu;
- menu.CreatePopupMenu();//宣告一個彈出式選單
- //增加選單項“關閉”,點選則傳送訊息WM_DESTROY給主視窗(已
- //隱藏),將程式結束。
- menu.AppendMenu(MF_STRING,WM_DESTROY,"關閉");
- //確定彈出式選單的位置
- menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);
- //資源回收
- HMENU hmenu=menu.Detach();
- menu.DestroyMenu();
- delete lpoint;
- }
- break;
- case WM_LBUTTONDBLCLK://雙擊左鍵的處理
- {
- this->ShowWindow(SW_SHOW);//簡單的顯示主視窗完事兒
- }
- break;
- }
- return 0;
- }
2)過載WindowProc函式
i,過載WindowProc函式(方法略)
ii,在WindowProc中增加的訊息相應程式碼
- //WindowProc中增加的程式碼
- LRESULT CNotifyiconDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
- {
- // TODO: Add your specialized code here and/or call the base class
- switch(message) //判斷訊息型別
- {
- case WM_USER_NOTIFYICON:
- //如果是使用者定義的訊息
- if(lParam==WM_LBUTTONDBLCLK)
- {
- //滑鼠雙擊時主窗口出現
- if(AfxGetApp()->m_pMainWnd->IsWindowVisible()) //判斷視窗當前狀態
- {
- AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE); //隱藏視窗
- }
- else
- {
- AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOW); //顯示視窗
- }
- }
- elseif(lParam==WM_RBUTTONDOWN)
- { //滑鼠右鍵單擊彈出選單
- CMenu menu;
- menu.LoadMenu(IDR_MENU1); //載入事先定義的選單
- CMenu *pMenu=menu.GetSubMenu(0);
- CPoint pos;
- GetCursorPos(&pos);
- pMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,pos.x,pos.y,AfxGetMainWnd());
- }