1. 程式人生 > >MFC 系統托盤圖示實現,包括雙擊圖示和右鍵圖示選單

MFC 系統托盤圖示實現,包括雙擊圖示和右鍵圖示選單

首先,必須知道一個結構體NOTIFYICONDATA

,這是MFC中包含系統需要的用來傳遞托盤區域訊息的資訊結構體,有了它,我們今天的任務就完全可以輕鬆完成了!

     這時候,我們可以在我們的類中申明一個NOTIFYICONDATA的成員變數為m_nid。

接下來,我們可以給這個結構體變數賦我們想要的值了,記住賦值語句要寫在OnInitDialog初始化視窗函式裡,不要寫在建構函式中,否則將會無效。

m_nid.cbSize = sizeof( NOTIFYICONDATA );

m_nid.hWnd = m_hWnd;
m_nid.uID = IDR_MAINFRAME;
m_nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
m_nid.uCallbackMessage = WM_SYSTEMTRAY;    //自定義訊息
m_nid.hIcon = m_hIcon;                                              
strcpy(m_nid.szTip, "認證系統客戶端");

::Shell_NotifyIcon(NIM_ADD, &m_nid);

然後,讓我們一句句的解析這段程式碼,

m_nid.cbSize = sizeof( NOTIFYICONDATA );

cbSize表示結構體的大小,以位元組未單位,這裡賦值了NOTIFYICONDATA的結構體標準大小就行了,用sizeof函式就能獲得其位元組大小

m_nid.hWnd = m_hWnd;

hWnd是你想要賦予托盤的視窗控制代碼,MFC的視窗類中因為都是繼承CDialog類,所以其中會有一個成員變數是m_hWnd儲存著當前例項視窗的具體控制代碼,我們將其賦值給它就行了

m_nid.uID = IDR_MAINFRAME;


uID指的是應用程式定義的工作列圖示的識別符號,簡單的時候就是圖片圖示的ID,這裡的ID你可以進入工程下的ResourceView中找到Icon資料夾下的圖示,裡面的ID號就是我們現在要賦值的具體ID,Shell_NotifyIcon函式呼叫時,hWnd和UID成員用來標示具體要操作的圖示,可以通過多次的呼叫,來實現不同uID將多個圖示關聯到一個視窗hWnd上,從而實現托盤圖示切換的效果

m_nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;

uFlags表明具體哪些其他成員為合法資料,簡單的說就是隻有在uFlags中提到過的變數,才能發揮其作用,具體uFlags可以由以下一些成員組合:

NIF_ICON     表示hicon成員起作用。

NIF_MESSAGE  表示uCallbackMessage成員起作用

NIF_TIP      表示szTip成員起作用

當然還有許多別的如:NIF_STATE,NIF_INFO,NIF_GUID,這裡就具體先介紹上面三個,其他想了解的話可以具體查msdn

m_nid.uCallbackMessage = WM_SYSTEMTRAY;

uCallbackMessage是應用程式定義的訊息標示,當滑鼠在托盤滑鼠上點選事件的時候,程式的WM_SYSTEMTRAY就會被髮出,我們只要在WindowProc函式中就能獲得的該訊息,從而做出事件響應,如下:

        switch(message)
{
case WM_SYSTEMTRAY:  //自定義訊息

           //具體響應訊息

        break;

        }

其中,大家可以看出WM_SYSTEMTRAY不是系統訊息,而是自定義的一個訊息,用於表示這個特殊的事件發生了,至於怎麼定義呢,就是用巨集了

#define WM_SYSTEMTRAY WM_USER+1

這裡解釋下,為什麼WM_SYSTEMTRAY要巨集定義成WM_USER+1呢,據我瞭解WM_USER是系統訊息中的最後一個,也就是說這樣定義就不會和系統的訊息衝突成一個同樣的值

m_nid.hIcon = m_hIcon; 

增加、修改或刪除的圖片控制代碼,用於控制托盤的圖示,m_hIcon是自定義的一個視窗圖示控制代碼

HICON m_hIcon;

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

當然你可以直接將m_nid.hIcon = m_hIcon 改成 m_nid.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME)

strcpy(m_nid.szTip, "認證系統客戶端");

szTip是一個字串指標,是在滑鼠放在圖示上的時候,會出現的提示訊息。

::Shell_NotifyIcon(NIM_ADD, &m_nid);

最後一個是一個全域性函式 BOOL Shell_NotifyIcon(DWORD dwMessage,PNOTIFYICONDATA ipdata);

引數dwMessage表示要執行的操作,可選值為:

NIM_ADD      表示在托盤區域增加圖示

NIM_DELETE   表示刪除托盤區域的圖示

NIM_MODIFY   表示修改托盤區域的圖示

NIM_SETFOCUS 表示聚焦到托盤圖示上

第二個引數就是我們上面介紹過的NOTIFYICONDATA結構體的指標了。

如果操作成功函式會返回TRUE,否則返回FALSE。

///////////////////////////////////////////////////////////////////////////////////

OK,托盤的實現就是這麼簡單的啦,但是如果你想具體深入瞭解,可以檢視MSDN裡面具體的解釋,也可以跟本人溝通

下面介紹下應用,具體的應用情況很多。

我們就來簡單的講一下,怎麼實現視窗隱藏後,雙擊托盤使視窗再出現,和右擊托盤出現退出視窗的實現

上面叫到了自定義的訊息,在WindowProc函式中,我們可以具體實現

switch(message)
{
case WM_SYSTEMTRAY:  //自定義訊息

           if (lParam == WM_LBUTTONDBLCLK)

ShowWindow(SW_SHOWNORMAL);
}

        break;

        }

上面的程式碼就實現了,雙擊托盤實現顯示視窗的程式碼,非常簡單,我們就不具體剖析了。

要實現右擊托盤顯示彈出視窗,我們必須先在資源中建立一個選單,然後加入以下程式碼

                case WM_SYSTEMTRAY:  //自定義訊息   
if(lParam == WM_RBUTTONDOWN)

//右擊彈出托盤選單
CMenu menu;
menu.LoadMenu(IDR_MENU1);
CMenu *pPopUp=menu.GetSubMenu(0);
CPoint pt;
GetCursorPos(&pt);

SetForegroundWindow();
pPopUp->TrackPopupMenu(TPM_RIGHTBUTTON,pt.x,pt.y,this);
PostMessage(WM_NULL,0,0);
}
break;

程式碼中,剛開始定義了一個CMenu的物件,然後將我們之前建立的選單ID載入進去,然後獲得滑鼠當前的位置,在這個位置上將選單顯示出來

最後退出要刪除圖示: Shell_NotifyIcon(NIM_DELETE,&m_traydata);