簡介
一個是WORD類型的16位
整型變數;另一個是LONG類型的32位整型變數。因此根據
匈牙利命名法,16位的變數就被命名為
wParam, 32位的變數就被命名為lParam。
到了Win32API中,原來的16位變數也被擴展為32位,因此此時wParam和lParam的大小完全相同。
在Win32API的早期,為了保證和Win16API的代碼可移植性MS定義了
WPARAM和LPARAM兩個宏。
當時保留了w前綴的原因一方面是由於WPARAM宏也以W開頭,還有也因為要提醒程式設計師注意到可移植性,當然到了現在Win16早已退出歷史舞台,這個前綴也就約定俗成的沿用下來了。
例如
主程式MyDlg.cpp
1.自定義訊息:#define WM_TRAY
WM_USER 100
2.函式原形:
afx_msg LRESULT OnTrayNotify(WPARAM wParam,LPARAM lParam);
LRESULTCMyDlg::OnTrayNotify(WPARAMwParam,LPARAMlParam){returnm_tray.OnTrayNotify(wParam,lParam);}
托盤類的實現程式Tray.cpp
成員函式:
intOnTrayNotify(WPARAMwID,LPARAMlEvent){if(wID==TRAYNOTIFYDATA.uID)return0;if(lEvent==WM_LBUTTONDOWN){處理代碼}elseif(lEvent==WM_RBUTTONDOWN){處理代碼}return0;}
WPARAM 和 LPARAM 本質上沒有什麼區別:都是32位數;
但是區別也還是有的:除了上面的關於16位的的歷史問題外,MICROSOFT在使用時兩種參數分別代表不同的含義和內容,
WPARAM常常代表一些控制項的ID或者高位底位組合起來分別表示滑鼠的位置,如果訊息的傳送者需要將某種結構的
指針或者是某種類型的句柄時,習慣上用LPARAM來傳遞,可以參考各種控制項的通知訊息:可以查看:EN_CHANGE (EDIT控制項的一個通知訊息),CBEM_INSERTITEM(可擴展
組合框的可接受訊息)等等來加以領會。
理論上在使用自定義訊息時,WPARAM LPARAM的含義可以程式設計師任意指定的,但是最好遵從MFC中的習慣。在調用SendMessage()函式時,第二個參數是WPARAM,第三個參數是這個訊息的LPARAM,但是你在程式中某個類中寫下
ON_MESSAGE()宏來處理這個訊息時,處理函式SomeHandler(
WPARAM,LPRAM(默認是0))中解釋這兩個參數時必須按照SendMessage調用中的意義來進行。
訊息回響機制
1、訊息的組成:一個訊息由一個訊息名稱(UINT),和兩個參數(WPARAM,LPARAM)組成。當用戶進行了輸入或是視窗的狀態發生改變時系統都會傳送訊息到某一個視窗。例如當選單選中之後會有
WM_COMMAND訊息傳送,WPARAM的低字中(
LOWORD(
wParam))是命令的ID號,對選單來講就是選單ID。當然用戶也可以定義自己的訊息名稱,也可以利用自定義訊息來傳送通知和傳送數據。
2、誰將收到訊息:一個訊息必須由一個視窗接收。在視窗的過程(
WNDPROC)中可以對訊息進行分析,對自己感興趣的訊息進行處理。例如你希望對選單選擇進行處理那么你可以定義對WM_COMMAND進行處理的代碼,如果希望在視窗中進行
圖形輸出就必須對WM_PAINT進行處理。
3、未處理的訊息到哪裡去了:M$為視窗編寫了默認的視窗過程,這個視窗過程將負責處理那些你不處理訊息。正因為有了這個默認視窗過程我們才可以利用Windows的視窗進行開發而不必過多關注視窗各種訊息的處理。例如視窗在被拖動時會有很多訊息傳送,而我們都可以不予理睬讓系統自己去處理。
4、
視窗句柄:說到訊息就不能不說視窗句柄,系統通過視窗句柄來在整個系統中唯一標識一個視窗,傳送一個訊息時必須指定一個視窗句柄表明該訊息由那個視窗接收。而每個視窗都會有自己的視窗過程,所以用戶的輸入就會被正確的處理。例如有兩個視窗共用一個視窗過程代碼,你在視窗一上按下滑鼠時訊息就會通過視窗一的句柄被傳送到視窗一而不是視窗二。
5、示例:下面有一段
偽代碼演示如何在視窗過程中處理訊息
LONGyourWndProc(HWNDhWnd,UINTuMessageType,WPARAMwP,LPARAM){switch(uMessageType){//使用SWITCH語句將各種訊息分開case(WM_PAINT):doYourWindow(...);//在視窗需要重新繪製時進行輸出break;case(WM_LBUTTONDOWN):doYourWork(...);//在滑鼠左鍵被按下時進行處理break;default:callDefaultWndProc(...);//對於其它情況就讓系統自己處理break;}}
接下來談談什麼是
訊息機制:系統將會維護一個或多個
訊息佇列,所有產生的訊息都會被放入或是插入佇列中。系統會在佇列中取出每一條訊息,根據訊息的接收句柄而將該訊息傳送給擁有該視窗的程式的
訊息循環。每一個運行的程式都有自己的訊息循環,在循環中得到屬於自己的訊息並根據接收視窗的句柄調用相應的視窗過程。而在沒有訊息時訊息循環就將控制權交給系統所以Windows可以同時進行多個任務。下面的
偽代碼演示了訊息循環的用法:
while(1){id=getMessage(...);if(id==quit)break;translateMessage(...);}
當該程式沒有訊息通知時getMessage就不會返回,也就不會占用系統的
CPU時間。