1、在資源中的Icon中導入一個自己喜歡的圖標,ID命名為IDR_MAINFRAME,將先前的IDR_MAINFRAME的圖標刪除掉;
2、在自己的Dialog頭文件中定義一個變量? NOTIFYICONDATA?m_nid,關于該結構體的具體信息可以查閱MSDN;
3、添加消息響應函數OnInitDialog(),并在該函數中添加以下代碼,這樣程序一啟動,就在托盤中顯示出了自己應用程序的圖標。
??? //---------------------------托盤顯示---------------------------------//
??? 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);??????????? ??? // 在托盤區添加圖標
??? 這時候編譯,會報WM_SHOWTASK的錯,因為該消息要自己定義。
4、在Dialog頭文件中聲明消息函數原型????? ???????????????????????????????????
????LRESULT OnShowTask(WPARAM wParam, LPARAM lParam);
5、在Dialog源文件中進行消息映射
????ON_MESSAGE(WM_SHOWTASK,OnShowTask)
6、在Dialog源文件中添加自定義的消息響應代碼,左鍵雙擊彈出應用程序主窗口,右鍵單擊彈出菜單。
????LRESULT CServerDlg::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;
??? }
7、添加OnSize消息響應函數,處理最小化時的操作。
????void CServerDlg::OnSize(UINT nType, int cx, int cy)
??? {
?????????? CDialog::OnSize(nType, cx, cy);
?????????? // TODO: Add your message handler code here
?????????? if(nType == SIZE_MINIMIZED)??
?????????? {??
????????????????? ShowWindow(SW_HIDE); // 當最小化市,隱藏主窗口 ?????????????
?????????? }??
??? }
8、添加關閉窗口時的消息響應函數,將托盤中的應用程序圖標刪除
????BOOL CServerDlg::DestroyWindow()
??? {
?????????? // TODO: Add your specialized code here and/or call the base class
?????????? // 在托盤區刪除圖標
?????????? Shell_NotifyIcon(NIM_DELETE, &m_nid);?????????????
?????????? return CDialog::DestroyWindow();
??? }
??? 經過以上的步驟,就編寫出了一個簡單的可以最小化到托盤的程序。該程序在一啟動時,在托盤創立應用程序的圖標,最小化程序時隱藏主窗口,雙擊托盤區的圖標時,顯示主窗口,右鍵點擊托盤區窗口時,彈出菜單進行相應的操作。
*****************************************************************************************************************************************************************************
以工程為例說明過程:此程序編程環境是VS2008,在調試過程中,將字符集修改為“使用多字節字符集”(項目->屬性->配置屬性->字符集)。
例如新建一個MFC對話框工程Dialogtest,程序實現的功能是,修改對話框標題欄上默認的圖標,在程序中改為添加的資源Icon?IDI_ICON1,最小化對話框到托盤。
首先,在對話框資源屬性頁,選擇Minimize Box為TRUE。這樣可以實現對話框的最小化,但是這時最小化到了任務欄,為了使其最小化到托盤,還必須添加一些代碼,步驟如下:
首先添加變量NOTIFYICONDATA?m_nid;//NOTIFYICONDATA作用是用來向任務欄托盤區域發送消息和自定義消息響應函數OnShowTask?,自定義消息響應函數主要是添加三處代碼:
1)頭文件中聲明部分添加#define?WM_SHOWTASK WM_USER+1,代碼部分添加afx_msg LRESULT OnShowTask(WPARAMwParam,LPARAM lParam);
2)在源程序中添加:BEGIN_MESSAGE_MAP(CDialogtestDlg, CDialog)
?????ON_WM_SYSCOMMAND()
?????ON_WM_PAINT()
?????ON_WM_QUERYDRAGICON()
????
?????//}}AFX_MSG_MAP
?????ON_MESSAGE(WM_SHOWTASK,OnShowTask)//此處為添加部分
END_MESSAGE_MAP()
3)源程序中的響應函數代碼
在本實現中源程序中總共添加了五處代碼:(紅色為添加的代碼)
1、修改圖標資源:
CDialogtestDlg::CDialogtestDlg(CWnd*pParent?/*=NULL*/)
???? :CDialog(CDialogtestDlg::IDD,?pParent)
{
?????//m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);// IDR_MAINFRAME為系統默認
?????m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
}
2、同上自定義消息2
BEGIN_MESSAGE_MAP(CDialogtestDlg,CDialog)
?????ON_WM_SYSCOMMAND()
?????ON_WM_PAINT()
?????ON_WM_QUERYDRAGICON()
????
?????//}}AFX_MSG_MAP
?????ON_MESSAGE(WM_SHOWTASK,OnShowTask)
?????ON_WM_SIZE()//為了隱藏最小化到任務欄的圖標而添加的消息響應函數,這個函數系統自帶直接添加
END_MESSAGE_MAP()
3、修改對話框標題欄圖標并在托盤區添加圖標:
BOOL?CDialogtestDlg::OnInitDialog()
{
?????CDialog::OnInitDialog();
?
?????//?將“關于...”菜單項添加到系統菜單中。
?
?????// IDM_ABOUTBOX?必須在系統命令范圍內。
?????ASSERT((IDM_ABOUTBOX& 0xFFF0) ==?IDM_ABOUTBOX);
?????ASSERT(IDM_ABOUTBOX< 0xF000);
?
?????CMenu*?pSysMenu=?GetSystemMenu(FALSE);
?????if?(pSysMenu?!=?NULL)
???? {
?????????CString?strAboutMenu;
?????????strAboutMenu.LoadString(IDS_ABOUTBOX);
?????????if?(!strAboutMenu.IsEmpty())
???????? {
??????????????pSysMenu->AppendMenu(MF_SEPARATOR);
??????????????pSysMenu->AppendMenu(MF_STRING,?IDM_ABOUTBOX,strAboutMenu);
???????? }
???? }
?
?????//?設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動
?????//??執行此操作
?????SetIcon(m_hIcon,TRUE);??????????//?設置大圖標
?????SetIcon(m_hIcon,FALSE);?????????//?設置小圖標
?????// TODO:?在此添加額外的初始化代碼
?????m_nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
???? m_nid.hWnd = this->m_hWnd;
???? m_nid.uID = IDI_ICON1;
???? m_nid.uFlags = NIF_ICON|NIF_MESSAGE |NIF_TIP;
???? m_nid.uCallbackMessage = WM_SHOWTASK;
???? m_nid.hIcon?? = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
???? strcpy_s(m_nid.szTip,strlen("對話框")+1,"對話框");
???? Shell_NotifyIcon(NIM_ADD,&m_nid); // 在托盤區添加圖標
?????return?TRUE;??//?除非將焦點設置到控件,否則返回TRUE
}
4、自定義的消息響應函數代碼:
LRESULT CDialogtestDlg::OnShowTask(WPARAMwParam, LPARAM lParam)
{
???? if(wParam != IDI_ICON1) return 1;
?
???? switch(lParam)
???? {
???? case WM_RBUTTONUP:?????????????? //右鍵起來時彈出菜單
???????? {
????????????? LPPOINT lpoint = new tagPOINT;
????????????? ::GetCursorPos(lpoint);??????????????????? // 得到鼠標位置
????????????? CMenu menu;
????????????? menu.CreatePopupMenu();??????????????????? // 聲明一個彈出式菜單
????????????? menu.AppendMenu(MF_STRING, WM_DESTROY, "退出");//Appends a new item to the end ofthis menu
????????????? //Displays a floating pop-up menu at the specifiedlocation and tracks the selection of items on the pop-up menu
????????????? 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;
}
5、處理最小化時任務欄出現圖標的程序:
void CDialogtestDlg::OnSize(UINTnType, int cx, int cy)
{
?????CDialog::OnSize(nType, cx, cy);
?????// TODO:?在此處添加消息處理程序代碼
?????if (nType == SIZE_MINIMIZED)
???? {
???????? ShowWindow(SW_HIDE);//隱藏最小化到任務欄的圖標
???? }
}