鍵盤和鼠標(biāo)在 windows 中的重要性不必多說(shuō),地球人都知道!鍵盤上每一個(gè)有意義的鍵都對(duì)應(yīng)著一個(gè)唯一的標(biāo)識(shí)值,稱之為掃描碼。但是這種掃描碼是硬件相關(guān)的,為了實(shí)現(xiàn)設(shè)備無(wú)關(guān)性的要求,在 windows 應(yīng)用程序中,使用的往往是與設(shè)備無(wú)關(guān)的虛擬碼。
對(duì)鍵盤操作的響應(yīng)過(guò)程基本如下:
用戶按下一個(gè)鍵時(shí),與鍵盤驅(qū)動(dòng)程序( KEYBOARD.DRV )進(jìn)行中斷處理并調(diào)用 windows 用戶模塊( USER.EXE )中的有關(guān)程序來(lái)生成鍵盤消息,然后消息被發(fā)送到系統(tǒng)的消息隊(duì)列中由相應(yīng)的應(yīng)用應(yīng)用程序進(jìn)行處理。鼠標(biāo)的處理過(guò)程與鍵盤類似。但是注意無(wú)論是鼠標(biāo)還是鍵盤的所產(chǎn)生的消息經(jīng)過(guò)操作系統(tǒng)處理后都只會(huì)被發(fā)送給特定的窗口,即具有“輸入焦點(diǎn)”的窗口來(lái)進(jìn)行處理。
???????????
鍵盤消息
鍵盤消息通常可分為按鍵消息和字符消息兩類,用戶按下或松開(kāi)一個(gè)鍵時(shí),就產(chǎn)生一個(gè)按鍵消息,當(dāng)一個(gè)按鍵組合產(chǎn)生了一個(gè)可以顯示的字條時(shí),就產(chǎn)生了一個(gè)字符消息。
按鍵消息一般又可以分為系統(tǒng)按鍵和非系統(tǒng)按鍵。
系統(tǒng)按鍵:是指使用了 Alt 等與相關(guān)輸入鍵組成產(chǎn)生的消息,一般這些消息都由操作系統(tǒng)內(nèi)部直接處理。如果應(yīng)用程序處理了這些系統(tǒng)鍵消息,就要調(diào)用 DefWindowProc 函數(shù),以便不影響 windows 對(duì)它們的處理。
非系統(tǒng)按鍵:對(duì)應(yīng)于那些不使用組合鍵的按鍵消息。
再對(duì)按鍵消息的兩個(gè)變量 wParam 和 lParam 做一些解釋:(名堂還真不少 T_T )
1.????????
wParam
包含了識(shí)別按下鍵的虛鍵碼,這些碼是由系統(tǒng)定義的設(shè)備無(wú)關(guān)的。可以在
windows.h
中找到找到相關(guān)定義。
2.????????
lParam
32
位的變量
lParam
所表示的含義可以分為以下
7
個(gè)部分
(1)????? 重復(fù)計(jì)數(shù)位( 0~15 位) ?????
表示當(dāng)前消息的重復(fù)次數(shù)。
(2)????? OEM 掃描碼( 16~23 位)
OEM 掃描碼是鍵盤發(fā)送的碼值,因?yàn)槭窃O(shè)備相關(guān)的幫一般被忽略掉。
(3)????? 擴(kuò)展鍵標(biāo)志( 24 位)
在有 Alt 或 Ctrl 鍵按下時(shí)為 1, 否則為 0 。
(4)????? 保留位( 25~28 位) ??????????
系統(tǒng)保留,一般不用。
(5)????? 關(guān)聯(lián)碼( 29 位)
主要用來(lái)記錄某鍵與 Alt 等鍵的組合狀態(tài),若按下 Alt 鍵,當(dāng) WM_SYSKEYDOWN 消息發(fā)送到某個(gè)激活窗口時(shí),其值為 1, 否則為 0 。
(6)????? 鍵的先前狀態(tài)( 30 位)
用于記錄先前某鍵的狀態(tài)。
(7)????? 轉(zhuǎn)換狀態(tài)( 31 位)
用于記錄被始終按下的某鍵所產(chǎn)生的消息。
?????? 在 WinMain 函數(shù)里的消息循環(huán)中包含了 TranslateMessage 函數(shù),它的主要功能是把按鍵消息轉(zhuǎn)化為字符消息,即把按鍵所產(chǎn)生的原始的KEYDOWN/KEYUP消息轉(zhuǎn)化成WM_CHAR消息。 同樣,字符消息也可以分為系統(tǒng)和非系統(tǒng)消息兩類。
Windows 系統(tǒng)支持兩類字符集: OEM 和 ANSI 。 OEM 是 IBM 的字符集,在 windows 中使用不多,目前大多使用的是 ANSI 字符集。
???????????
鼠標(biāo)消息
1.???????? 鼠標(biāo)操作
簡(jiǎn)單的單擊操作包含了按下和松開(kāi)這一全過(guò)程;而雙擊操作實(shí)際上是指用戶在知時(shí)間內(nèi)(默認(rèn)為 0.5 秒)的再次單擊操作。
在鼠標(biāo)消息中,參數(shù) lParam 包含了鼠標(biāo)的位置,低字節(jié)是 X 坐標(biāo),高字節(jié)是 Y 坐標(biāo)。參數(shù) wParam 則包含了一個(gè)指示各種虛鍵狀態(tài)的值。
通過(guò)用戶區(qū)消息的 wParam 和 lParam 參數(shù),程序員就可以確定鼠標(biāo)的位置和狀態(tài)。
對(duì)于鼠標(biāo)的消息處理,一般分為兩種,一種要對(duì) Ctrl 等鍵進(jìn)行監(jiān)視,另一種則不需要。下面是一個(gè)示例
case WM_LbUTTONDWON:?????? // 鼠標(biāo)按下時(shí) ctrl 和 shift 都被按下
?????? If(( wParam&MK_CONTROL) && ( wParam&MK_SHIFT) )
?????? …
?????? break;
case WM_LBUTTONDOWN:?????? // 不監(jiān)視組合按鍵
?????? …
?????? break;
此外,要使窗口能監(jiān)視雙擊消息,必須在注冊(cè)窗口類的時(shí)候使該類具有 CS_DBLCLKS 屬性才行,否則只能收到兩條單擊消息。
2.???????? 光標(biāo)
可以使用系統(tǒng)光標(biāo)或者調(diào)用 LoadCursor 加載自定義光標(biāo)資源
???????????
示例程序
在下面的一個(gè)例子中,顯示鼠標(biāo)和鍵盤的消息響應(yīng)。程序的用戶區(qū)被分為四個(gè)區(qū)域,每個(gè)區(qū)域里光標(biāo)設(shè)置成不同的樣式。通過(guò)監(jiān)視鍵盤按鍵,可對(duì)一個(gè)
10
個(gè)字符長(zhǎng)的緩沖區(qū)里輸入字符,并最后顯示在鼠標(biāo)上方,鼠標(biāo)移動(dòng)時(shí)同時(shí)修改字符輸出的位置。可以按下
BACK
鍵刪掉已經(jīng)輸入的字符,緩沖區(qū)滿時(shí)再輸入和空的時(shí)候刪字符的操作都被拒絕,并用消息框進(jìn)行提示。代碼如下:






































































