MSG结构体和WndProc窗口过程详解
MSG結(jié)構(gòu)體和WndProc窗口過程對于Windows編程非常重要,如果不了解它們,可以說就沒有學(xué)會Windows編程。
MSG結(jié)構(gòu)體
MSG 結(jié)構(gòu)體用來表示一條消息,各個字段的含義如下:
對各個字段的說明:
1) 最后兩個字段 time 和 pt 一般由系統(tǒng)使用,我們很少用到。
2) message 為消息類型,也就是以 WM 開頭的消息(WM 是 Window Message 的縮寫 ),例如 WM_CREATE、WM_PAINT、WM_DESTROY、WM_COMMAND 等。
2) wParam 和 lParam 是要重點說明的,它們都表示附加消息。例如,當(dāng)收到一個字符消息的時,message 的值為 WM_CHAR,但用戶到底輸入的是什么字符,那么就由 wParam 和 lParam 來說明。wParam、lParam 表示的信息隨消息類型的不同而不同,具體細(xì)節(jié)可以到MSDN中查看。
WPARAM 和 LPARAM 這兩種數(shù)據(jù)類型的定義分別為:
在現(xiàn)代操作系統(tǒng)中(32位和64位操作系統(tǒng)),它們一般都表示 32 位的整數(shù)。
但在16位操作系統(tǒng)中,WPARAM 表示16位整數(shù),而 LPARAM 表示32位整數(shù),根據(jù)匈牙利命名法,16 位的變量通常以W開頭,32 位變量通常以L開頭。升級到32位操作系統(tǒng)后,WPARAM也被擴展到32位,此時 WPARAM 和 LPARAM 的大小完全相同。
在 Win32 API 的早期,由于還有很多 Win16 API 的軟件,為了保證和 Win16 API 的代碼可移植性,微軟依然保留了 WPARAM 和 LPARAM 兩個宏。
不過16位系統(tǒng)早已成為歷史,現(xiàn)在你可以認(rèn)為這兩個參數(shù)的長度相同。讀者可以在 VC / VS 中通過 F12 鍵或者“轉(zhuǎn)到定義”菜單查看。
wParam 和 lParam 到底表示什么信息
可以肯定的是,消息類型 message 不同,wParam 和 lParam 兩個字段表示的附加消息一般也不同。那么,它們到底表示什么呢?其實這個真的不一定,沒有什么規(guī)律,它們本來就是一個歷史遺留問題,也不知道微軟到底怎么安排的,只能根據(jù)不同的消息類型去 MSDN 中查找。
一般約定,wParam 用來表示控件的ID,或者高 16 位和低 16 位組合起來分別表示鼠標(biāo)的位置,如果發(fā)送消息時需要附帶某種結(jié)構(gòu)的指針或者是某種類型的句柄時,習(xí)慣上用 lParam。
不過這也不一定是對的,例如對于一個鼠標(biāo)左鍵按下的消息 WM_LBUTTONDOW,就用 lParam 來表示鼠標(biāo)的坐標(biāo):
LOWORD 和 HIWORD 都是宏定義:LOWORD 用來取一個 32 位數(shù)的低 16 位,HIWORD 用來取一個32 位數(shù)的高 16 位。對于?WM_LBUTTONDOW 消息,低 16 位存放的是 x 坐標(biāo),而高 16 位存放的是 y 坐標(biāo)。
WndProc 窗口過程
窗口過程一般定義為如下的形式:
WndProc 的各個參數(shù)和 MSG 結(jié)構(gòu)體的前四個字段是一一對應(yīng)的。需要銘記的是:每產(chǎn)生一條消息,都會調(diào)用一次 WndProc 函數(shù)。
當(dāng)用戶點擊按鈕、編輯框、下拉列表框等控件的時候,會產(chǎn)生WM_COMMAND消息。對于不同來源的 WM_COMMAND 消息,wParam、lParam 參數(shù)也不同,見下表:
| 菜單 | 0 | 菜單ID | 0 |
| 快捷鍵 | 1 | 快捷鍵ID | 0 |
| 控件 | 控件通知碼 | 控件ID | 控件句柄 |
注意:
- 上面說的菜單是指窗口標(biāo)題下方、客戶區(qū)上方的下拉菜單,而不是客戶區(qū)的下拉列表框控件。
- 控件通知碼用來識別控件的操作。例如?Button 控件一般有兩種通知碼,BN_CLICKED 和 BN_DOUBLECLICKED,前者表示 Button 被單擊,后者表示 Button 被雙擊。
對于 Button 控件,我們可以通過LOWORD(wParam)來獲取它的 ID,這就是上節(jié)最后一個例子的原理,請參考上節(jié)的代碼體會。
總結(jié)
以上是生活随笔為你收集整理的MSG结构体和WndProc窗口过程详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab时域转复频域,信号与系统实验
- 下一篇: 16道嵌入式C语言面试题(转载)