Windows作業系統中的某些程式運行時不顯示運行視窗,只在工作列上顯示一個表徵圖,表示程式正在運行,使用者可以通過滑鼠與應用程式互動,比如金山毒霸等應用程式,我們有時也需要編製一些僅在後台啟動並執行類似程式,為了不干擾前景程式的運行介面和不顯示不必要的視窗,應使程式運行時的主視窗不可見。同時將一個表徵圖顯示在工作列右端靜態通告區中並響應使用者的滑鼠動作。下面介紹Visual
C++開發這類程式的設計方法。
一、隱藏程式的主視窗
首先,要使程式的主視窗不可見,並且不在工作列上出現任務按鈕,要做到這兩點,需分別設定主邊框視窗的風格和擴充風格:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { cs.style =WS_POPUP;//使主視窗不可見 cs.dwExStyle |=WS_EX_TOOLWINDOW;//不顯示任務按鈕 return CFrameWnd::PreCreateWindow(cs); } |
二、將表示程式啟動並執行表徵圖加入工作列
在主架構視窗的CMainFrame::OnCreate()函數中調用上述函數,就可以在任務條上顯示表徵圖這一步是利用系統API函數Shell_NotifyIcon()將一個表徵圖顯示在工作列的通告區中。該函數的原型為:在調用該函數之前,需要確定其參數的取值。其中Shell_NotifyIcon()函數的第一個參數是一個預定義的訊息,可以取如下值之一:NIM_ADD、NIM_DELETE或NIM_MODIFY,分別表示添加表徵圖、刪除表徵圖或修改表徵圖。另一個參數為指向NOTIFYICONDATA類型的指標。其原型為:
typedef struct _NOTIFYICONDATA { DWORD cbSize; HWND hWnd; UINT uID; UINT uFlags; UINT uCallbackMessage; HICON hIcon; charszTip[64]; } NOTIFYICONDATA |
在該結構的成員中,cbSize為該結構所佔的位元組數,hWnd為接受該表徵圖所發出的訊息的視窗的控制代碼(滑鼠在工作列上程式表徵圖上動作時表徵圖將發出訊息,這個訊息使用者要自己定義),uID為被顯示表徵圖的ID,uFlags指明其餘的幾個成員(hIcon、uCallBackMessage和szTip)的值是否有效,uCallbackMessage為一個使用者自訂的訊息,當使用者在該表徵圖上作用一些滑鼠動作時,表徵圖將嚮應用程式的主架構視窗(hWnd成員中指定的視窗)發出該訊息,。hIcon為將在工作列上被顯示表徵圖的控制代碼,szTip滑鼠停留在該表徵圖上時顯示的字串。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { NOTIFYICONDATA tnd; tnd.cbSize=sizeof(NOTIFYICONDATA); tnd.hWnd=this->m_hWnd; tnd.uID=IDR_MAINFRAME; tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP; tnd.uCallbackMessage=WM_MYMESSAGE; file://使用者自訂的訊息,即滑鼠在工作列上程式表徵圖上動作時表徵圖發送的訊息 tnd.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME)); strcpy(tnd.szTip,"測試程式");//表徵圖提示為"測試程式" Shell_NotifyIcon(NIM_ADD,&tnd);//向工作列添加表徵圖} |
三、使用者與程式互動的實現
使用者進行互動,也就是當使用者在該表徵圖上單擊或雙擊滑鼠左鍵或右鍵時要執行相應的操作,至少也要響應使用者終止該程式的意願。上面已經提到,當使用者在表徵圖上進行滑鼠動作時,將向hWnd成員中指定的視窗發出自訂的訊息,該訊息為uCallbackMessage成員所指定的WM_MYESSAGE,取值為WM_USER+101(如何自訂訊息,我就不多說了)。我們要實現任務就是在hWnd視窗中響應該自訂訊息:
void CMainFrame::OnMYMESSAGE(WPARAM wParam,LPARAM lParam) { UINT uID;//發出該訊息的表徵圖的ID UINT uMouseMsg;//滑鼠動作 POINT pt; uID=(UINT) wParam; uMouseMsg=(UINT) lParam; if(uMouseMsg==WM_RBUTTONDOWN)//如果是單擊右鍵 { switch(uID) { case IDR_MAINFRAME://如果是我們的表徵圖 GetCursorPos(&pt);//取得滑鼠位置 AfxGetApp( )-> m_pMainWnd->ShowWindow(SW_SHOWNORMAL);//顯示程式視窗 break; default: } } return; } |
四、程式結束時刪除程式表徵圖
當程式結束時,需要刪去通告區中的表徵圖,這時還應該調用Shell_NotifyIcon函數,只不過第一個參數是表示刪除表徵圖的NIM_DELETE了:
void CMainFrame::~CmainFrame() { NOTIFYICONDATA tnid; tnid.cbSize=sizeof(NOTIFYICONDATA); tnid.hWnd=this->m_hWnd; tnid.uID=IDR_MAINFRAME;//保證刪除的是我們的表徵圖 Shell_NotifyIcon(NIM_DELETE,&tnid); } |