利用工作列上的圖示與使用者互動 (轉)

worldblog發表於2007-12-06
利用工作列上的圖示與使用者互動 (轉)[@more@]

利用工作列上的圖示與互動



作者:李奔

我們有時需要編制一些僅在後臺的,為了不干擾前臺程式的執行介面和不顯示不必要的視窗,應使其執行時的主視窗不可見。同時,應該讓使用者知道該程式正在執行,並且達到與使用者進行互動的目的。將一個圖示顯示在工作列右端靜態通告區中並響應使用者的滑鼠動作是當前非常流行的方法,它體現了 95友好的介面風格。下面以一個SDI(單文件介面)程式為例,講述採用 Visual C++ 5.0開發這類程式的主要步驟。

首先,要使程式的主視窗不可見,並且不在工作列上出現任務按鈕,要做到這兩點,需分別設定主邊框視窗的風格和擴充套件風格:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

cs.style =WS_POPUP;//使主視窗不可見

cs.dwExStyle |=WS_EX_TOOLWINDOW;//不顯示任務按鈕

return CFrameWnd::PreCreateWindow(cs);

}

其次,利用_NotifyIcon將一個圖示顯示在工作列的通告區中。該函式的原型為:

WINSHELL BOOL WINAPI Shell_NotifyIcon(

D dwMessage,

PNOTIFYICONDATA pnid

);

下例中被顯示的是主邊框視窗的圖示,實際上可以顯示任何圖示:

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_LIBEN;

tnd.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRE(IDR_MAINFRAME));

strcpy(tnd.szTip,"提示資訊");

Shell_NotifyIcon(NIM_ADD,&tnd);



}

在該函式之前,需要確定其引數的取值,其中之一為一個具有NOTIFYICONDATA型別的結構。其原型為:

typedef struct _NOTIFYICONDATA { // nid

DWORD cbSize;

HWND hWnd;

UINT uID;

UINT uFlags;

UINT uCallbackMessage;

HICON hIcon;

charszTip[64]; }

NOTIFYICONDATA, *PNOTIFYICONDATA;

在該結構的成員中,cbSize為該結構所佔的位元組數,hWnd為接受該圖示所發出的訊息的視窗的控制程式碼,uID為被顯示圖示的ID,uFlags指明其餘的幾個成員(hIcon、uCallBackMessage和szTip)的值是否有效,uCallbackMessage為一個自定義的訊息,當使用者在該圖示上作用一些滑鼠動作時,將向hWnd成員中指定的視窗發出該訊息,可以定義該訊息為WM_USER+100。hIcon為被顯示圖示的控制程式碼,szTip為一字元陣列,當滑鼠停留在該圖示上時,將其內容顯示在浮動的提示資訊框中。Shell_NotifyIcon函式的另一個引數是一個預定義的訊息,可以取如下值之一:NIM_ADD、NIM_DELETE或NIM_MODIFY,分別表示新增圖示、刪除圖示或修改圖示。

最後,要與使用者進行互動,也就是當使用者在該圖示上單擊或雙擊滑鼠左鍵或右鍵時要相應的操作,至少也要響應使用者終止該程式的意願。上面已經提到,當使用者在圖示上進行滑鼠動作時,將向hWnd成員中指定的視窗發出自定義的訊息,該訊息由uCallbackMessage成員指定(在上例中為WM_LIBEN,取值為WM_USER+100)。因此,我們的任務就是在hWnd視窗中響應該自定義訊息:

void CMainFrame::OnLiben(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);//取得滑鼠位置

…//執行相應操作

break;



default:



}

}

return;

}

需要注意的是,首先要在該視窗類的頭中給出該訊息對映函式的原型說明:

afx_msg void OnLiben(WPARAM wParam,LPARAM lParam);

並且要在CPP檔案中的訊息對映中加入相應的條目,注意一定要加在//{{AFX_MSG_MAP(CMainFrame)和//}}AFX_MSG_MAP之外:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

//{{AFX_MSG_MAP(CMainFrame)

ON_WM_CREATE()

ON_COMMAND(ID_APP_EXIT, OnAppExit)

//}}AFX_MSG_MAP

ON_MESSAGE(WM_LIBEN,OnLiben)

END_MESSAGE_MAP()

當程式結束時,需要刪去通告區中的圖示,這時同樣應該呼叫Shell_NotifyIcon函式,只不過第一個引數是表示刪除圖示的NIM_DELETE了:

void CMainFrame::OnAppExit()

{

// TODO: Add your command handler code here

NOTIFYICONDATA tnid;

tnid.cbSize=sizeof(NOTIFYICONDATA);

tnid.hWnd=this->m_hWnd;

tnid.uID=IDR_MAINFRAME;//保證刪除的是我們的圖示

Shell_NotifyIcon(NIM_DELETE,&tnid);

AfxPostQuitMessage(0);

}

透過類似的步驟,讀者可以響應其他的訊息,完成更加高階的互動功能,這裡不再贅述。上文所述是筆者所得,肯定有不到之處,歡迎指正。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988847/,如需轉載,請註明出處,否則將追究法律責任。

相關文章