wParam和lParam 這兩個是Win16系統遺留下來的產物,在Win16API中WndProc有兩個參數:
一個是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);
3.訊息映射:ON_MESSAGE(WM_TRAY,OnTrayNotify)
4.原函式:
LRESULT CMyDlg::OnTrayNotify(WPARAM wParam,LPARAM lParam)
{
return m_tray.OnTrayNotify(wParam,lParam);
}
托盤類的實現程式Tray.cpp
成員函式:
int OnTrayNotify(WPARAM wID,LPARAM lEvent)
{
if(wID == TRAYNOTIFYDATA.uID)
return 0;
if(lEvent == WM_LBUTTONDOWN){
處理代碼
}
else if(lEvent == WM_RBUTTONDOWN){
處理代碼
}
return 0;
}
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、示例:下面有一段偽代碼演示如何在視窗過程中處理訊息
LONG yourWndProc(HWND hWnd,UINT uMessageType,WPARAM wP,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時間。
相關詞條
-
lParam資訊
計算機中的一個參數,通常用來儲存訊息所需的物件。
簡介 詳細介紹 -
訊息分流器
, WPARAM wParam, LPARAM lParam..., lParam); } 而通過使用訊息分流器,我們可以把每個case都..., WPARAM wParam, LPARAM lParam...
-
head程式
, WPARAM, LPARAM) ; LRESULT CALLBACK ListProc (HWND, UINT, WPARAM, LPARAM... message, WPARAM wParam,LPARAM lParam...
-
WSAAsyncGetServByName()
返回的異步任務句柄.lParam的高16位包含著錯誤代碼.該代碼可以是...小了.在這種情況下,lParam的低16位含有提供所有信息所需的緩衝區大小...().(也就是大於lParam低16位提供的大小.) 錯誤代碼和緩衝區...
簡述: 注釋: -
WSAAsyncGetHostByAddr()
.lParam的高16位包含著錯誤代碼.該代碼可以是winsock.h中...,lParam的低16位含有提供所有信息所需的緩衝區大小數值.如果...lParam低16位提供的大小.) 錯誤代碼和緩衝區大小應使用...
簡述 注釋 -
WSAAsyncGetProtoByName()
包含了初次函式調用時返回的異步任務句柄.lParam的高16位包含著...容納所有的結果信息來說太小了.在這種情況下,lParam的低16位含有...WSAAsyncGetProtoByName().(也就是大於lParam低16位提供的大小...
簡述 注釋 -
WSAAsyncGetServByPort()
.lParam的高16位包含著錯誤代碼.該代碼可以是winsock.h中定義...,lParam的低16位含有提供所有信息所需的緩衝區大小數值.如果應用程式...WSAAsyncGetServByPort().(也就是大於lParam低...
簡述: 注釋: -
WSAAsyncGetHostByName()
. wParam參數包含了初次函式調用時返回的異步任務句柄.lParam的高16位...大小對於容納所有的結果信息來說太小了.在這種情況下,lParam的低...WSAAsyncgethostbyname().(也就是大於lParam低16位提供的大小...
-
WPARAM
WPARAM,訊息回響機制 wParam和lParam..., 32位的變數就被命名為lParam。 到了Win32API中,原來的16位變數也被擴展為32位,因此此時wParam和lParam的大小...