標籤:自己 處理滑鼠 col bottle 簽名 switch sof 應該 windows
編寫視窗過程(Writing the Window Procedure)
DispatchMessage函數調用作為訊息目標視窗的視窗過程。視窗過程具有以下籤名(signature)。
C++
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
4個參數:
- hwnd 是對應視窗的一個控制代碼。
- uMsg是訊息代碼;例如, WM_SIZE訊息表明視窗被調整了大小。
- wParam和lParam包含與訊息相關的其他資料。確切的含義取決於訊息代碼。
LRESULT是你的程式返回給Windows的一個整數值。它包含程式對特定訊息的響應。這個值的含義取決於訊息代碼。CALLBACK是函數的呼叫慣例。
一個典型的視窗過程就是一個大型的switch語句,它會開啟訊息代碼。為要處理的每個訊息添加case。
C++
switch (uMsg){case WM_SIZE: // Handle window resizing // etc }
訊息的其他資料包含在lParam和wParam參數中。這兩個參數都是指標寬度(32位或64位)大小的整數值。它們的含義取決於訊息代碼(uMsg)。對於每個訊息,您需要在MSDN上尋找訊息代碼,並將參數轉換為正確的資料類型。通常資料要麼是數值,要麼是指向結構的指標。有些訊息沒有任何資料。
例如, WM_SIZE訊息的文檔表明:
- wParam是一個標誌,指示視窗是否被最小化、最大化或調整大小。
- lParam包含視窗的新寬度和高度,將16位值打包成一個32位或64位元字。您將需要執行一些位移位(bit-shifting)來擷取這些值。幸運的是,標頭檔WinDef.h包含執行此操作的輔助宏。
一個典型的視窗過程(window procedure)處理幾十條訊息,因此它可以長得相當長。使代碼更模組化的一種方法是將處理每個訊息的邏輯放在一個單獨的函數中。在視窗過程中,將wParam和lParam參數轉換為正確的資料類型,並將這些值傳遞給函數。例如,要處理WM_SIZE訊息,視窗過程如下所示:
C++
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (uMsg) { case WM_SIZE: { int width = LOWORD(lParam); // Macro to get the low-order word. int height = HIWORD(lParam); // Macro to get the high-order word. // Respond to the message: OnSize(hwnd, (UINT)wParam, width, height); } break; }} void OnSize(HWND hwnd, UINT flag, int width, int height){ // Handle resizing}
LOWORD 和HIWORD 宏從lParam獲得16位的寬度和高度值。(您可以在MSDN文檔中尋找每個訊息代碼的詳細資料)。視窗過程提取寬度和高度,然後將這些值傳遞給自己編寫的OnSize函數。
預設訊息處理(Default Message Handling)
如果不處理視窗過程中的特定訊息,則將訊息參數直接傳遞給DefWindowProc函數。此函數執行訊息的預設操作,該操作因訊息類型而異。
C++
return DefWindowProc(hwnd, uMsg, wParam, lParam);
避免視窗過程中的瓶頸(Avoiding Bottlenecks in Your Window Procedure)
在執行視窗過程時,它會阻止(block)在同一線程上建立的視窗的任何其他訊息。因此,避免在視窗過程中進行冗長的處理。例如,假設您的程式開啟一個TCP串連並無限期地等待伺服器響應。如果您在視窗過程中這樣做,那麼在請求完成之前,您的UI將不會響應。在此期間,視窗無法處理滑鼠或鍵盤輸入、重新繪製自身,甚至無法關閉。
相反,您應該將工作轉移到另一個線程,使用Windows內建的多任務處理設施之一:
- Create a new thread. 建立新線程
- Use a thread pool. 使用線程池
- Use asynchronous I/O calls. 使用非同步I/O調用
- Use asynchronous procedure calls. 使用非同步程式調用
1.3 Writing the Window Procedure(編寫視窗過程)