WPARAM 和 LPARAM,訊息響應機制
1、訊息的組成:一個訊息由一個訊息名稱(UINT),和兩個引數(WPARAM,LPARAM)。當用戶進行了輸入或是視窗的狀態發生改變時系統都會發送訊息到某一個視窗。例如當選單選中之後會有WM_COMMAND訊息傳送,WPARAM的高字中(HIWORD(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時間。