一、准備工作
在頭文件中做的工作:
1.在對話框的頭文件中定義一個用戶自定義消息。
該消息的用處是,當我們用鼠標點擊任務欄上的圖標時,圖標要發出的消息,消息的接收者就是當前你寫定義語句的窗體。
具體方法是:在對話框的頭文件中聲明消息。如下:
#endif // _MSC_VER > 1000
/////////////////////////////////////////////////////////////////////////////
#define WM_SHOWTASK WM_USER + 100 //定義消息的值
后面沒有分號, 建議自定義消息時至少是WM_USER+100,因為很多新控件也要使用WM_USER消息。
2.在類聲明中定義消息處理函數。
還是這個頭文件的下面:
// Generated message map functions
//{{AFX_MSG(CSendInfoSocketDlg)
afx_msg LRESULT OnShowTask(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
記號afx_msg並沒有什么其他用途,它只是用來表明該函數原型說明是針對消息映射函數而言的。
在源文件中做的工作:
1.實現消息映射
在代碼文件中還需要有一個消息映射宏,該消息映射宏用於將消息函數和應用框架聯系在一起。
BEGIN_MESSAGE_MAP(CSendInfoSocketDlg, CDialog)
//{{AFX_MSG_MAP(CSendInfoSocketDlg)
ON_MESSAGE(WM_SHOWTASK, OnShowTask)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
2.實現消息處理函數(當然可以不實現)。
在Dialog源文件中添加自定義的消息響應代碼,左鍵雙擊彈出應用程序主窗口,右鍵單擊彈出菜單。
LRESULT CSendInfoSocketDlg::OnShowTask(WPARAM wParam, LPARAM lParam)
{
if(wParam != IDR_MAINFRAME)
return 1;
switch(lParam)
{
case WM_RBUTTONUP: // 右鍵起來時彈出菜單
{
LPPOINT lpoint = new tagPOINT;
::GetCursorPos(lpoint); // 得到鼠標位置
CMenu menu;
menu.CreatePopupMenu(); // 聲明一個彈出式菜單
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_SHOWNORMAL); // 顯示主窗口
}
break;
}
return 0;
}
到這里我們已經完成了定義、接收、處理消息的准備工作,接着就是如何把圖標顯示在任務欄中的問題了。
二、顯示圖標
1.MFC對話框程序有一個默認的IDR_MAINFRAME圖標,可以替換成自己喜歡的圖標。
具體做法是:將先前的IDR_MAINFRAME的圖標刪除掉,在資源中的Icon中導入一個自己喜歡的圖標,ID命名為IDR_MAINFRAME。
2.在對話框的頭文件中定義一個變量NOTIFYICONDATA m_nid。
其原型為:
typedef struct _NOTIFYICONDATA {
DWORD cbSize; //為該結構所占的字節數
HWND hWnd; //為接受該圖標所發出的消息的窗口的句柄
UINT uID; //為被顯示圖標的ID
UINT uFlags; //指明其余的幾個成員(hIcon、uCallBackMessage和szTip)的值是否有效
UINT uCallbackMessage; //為一個用戶自定義的消息(就是上面定義的那個賦給它)
HICON hIcon; //為將在任務欄上被顯示圖標的句柄
char szTip[64]; //鼠標停留在該圖標上時顯示的字符串
}NOTIFYICONDATA
3.添加消息響應函數OnInitDialog(),並在該函數中添加以下代碼,這樣程序一啟動,就在托盤中顯示出了自己應用程序的圖標。
顯示圖標是通過這一步是利用系統API函數Shell_NotifyIcon()將一個圖標顯示在任務欄的通告區中。
//---------------------------托盤顯示---------------------------------//
m_nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
m_nid.hWnd = this->m_hWnd;
m_nid.uID = IDR_MAINFRAME;
m_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;
m_nid.uCallbackMessage = WM_SHOWTASK; // 自定義的消息名稱
m_nid.hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
strcpy(m_nid.szTip, "服務器程序"); // 信息提示條為"服務器程序",VS2008 UNICODE編碼用wcscpy_s()函數
Shell_NotifyIcon(NIM_ADD, &m_nid); // 在托盤區添加圖標
4.添加關閉窗口時的消息響應函數,將托盤中的應用程序圖標刪除,讓圖標隨主程序關閉消失。
具體做法是:右擊對話框程序的頭文件,選擇“添加虛函數”菜單項,選擇“DestroyWindow”,點擊“Add and Edit”。在函數中添加紅色部分的代碼。
BOOL CServerDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
// 在托盤區刪除圖標
Shell_NotifyIcon(NIM_DELETE, &m_nid);
return CDialog::DestroyWindow();
}
經過以上的步驟,就編寫出了一個簡單的可以最小化到托盤的程序。該程序在一啟動時,在托盤創建應用程序的圖標,最小化程序時隱藏主窗口,雙擊托盤區的圖標時,顯示主窗口,右鍵點擊托盤區窗口時,彈出菜單進行相應的操作。