關(guān)于鍵盤(pán)輸入應(yīng)用程序應(yīng)該像接收鼠標(biāo)輸入一樣可以接收鍵盤(pán)輸入,Windows中的應(yīng)用程序是以窗體消息的形式來(lái)獲取鍵盤(pán)輸入。 本節(jié)包括以下內(nèi)容:
鍵盤(pán)輸入模型系統(tǒng)通過(guò)安裝當(dāng)前鍵盤(pán)的設(shè)備驅(qū)動(dòng)來(lái)實(shí)現(xiàn)與應(yīng)用程序的設(shè)備無(wú)關(guān)性,也可以通過(guò)用戶或應(yīng)用程序的鍵盤(pán)布局設(shè)置來(lái)實(shí)現(xiàn)語(yǔ)言無(wú)關(guān)性。鍵盤(pán)設(shè)備驅(qū)動(dòng)接收鍵盤(pán)的“掃描碼”,然后把“掃描碼”發(fā)送給鍵盤(pán)布局,通過(guò)鍵盤(pán)布局被轉(zhuǎn)換為消息并發(fā)送到應(yīng)用程序的相應(yīng)窗口。 鍵盤(pán)上每一個(gè)鍵都有一個(gè)唯一值,這個(gè)唯一值就稱(chēng)為“掃描碼”(scan code),對(duì)于鍵盤(pán)上每個(gè)鍵來(lái)說(shuō),“掃描碼”是設(shè)備相關(guān)的。當(dāng)用戶按鍵時(shí)會(huì)產(chǎn)生兩次掃描碼,一次是按下鍵時(shí),一次是放開(kāi)時(shí)。 然后,鍵盤(pán)驅(qū)動(dòng)把掃描碼解釋并轉(zhuǎn)換(映射)為“虛鍵碼”(virtual-key code),這個(gè)碼是設(shè)備無(wú)關(guān)的,其值被系統(tǒng)所定義并用來(lái)標(biāo)識(shí)每一個(gè)鍵。轉(zhuǎn)換掃描碼后,鍵盤(pán)布局會(huì)創(chuàng)建一個(gè)包含掃描碼、虛鍵碼以及其他按鍵信息的消息,并把這個(gè)消息放入系統(tǒng)消息隊(duì)列。接著,系統(tǒng)從系統(tǒng)消息隊(duì)列中刪除該消息,再投遞到相應(yīng)線程的消息隊(duì)列中。最后,線程的消息循環(huán)移除該消息并傳遞到相應(yīng)窗口過(guò)程以進(jìn)行處理。下圖即鍵盤(pán)輸入模型:
鍵盤(pán)聚焦及激活系統(tǒng)投遞鍵盤(pán)消息到前臺(tái)線程的消息隊(duì)列中,這個(gè)前臺(tái)線程應(yīng)該是創(chuàng)建當(dāng)前獲得焦點(diǎn)的窗口的線程。鍵盤(pán)聚焦(Keyboard focus)是一個(gè)窗體的臨時(shí)屬性。系統(tǒng)通過(guò)鍵盤(pán)聚焦來(lái)向所有的顯示窗體共享鍵盤(pán),從用戶的角度講,鍵盤(pán)聚焦也就意味著,從一個(gè)窗口轉(zhuǎn)到另外一個(gè)。獲取焦點(diǎn)的窗口接收(從創(chuàng)建它的線程的消息隊(duì)列中)接收所有的鍵盤(pán)消息,直到焦點(diǎn)轉(zhuǎn)移到另外的窗體上。 線程可以通過(guò)調(diào)用GetFocus函數(shù)來(lái)確定那個(gè)窗口為當(dāng)前窗口(已經(jīng)鍵盤(pán)聚焦),也可以通過(guò)SetFocus來(lái)使哪個(gè)窗口獲取焦點(diǎn)。當(dāng)鍵盤(pán)聚焦從一個(gè)窗口換到另外一個(gè)時(shí),系統(tǒng)會(huì)發(fā)送WM_KILLFOCUS到失去焦點(diǎn)的窗口,然后發(fā)送WM_SETFOCUS消息到獲得焦點(diǎn)的窗口。 鍵盤(pán)聚焦與活動(dòng)窗口有一定關(guān)系,活動(dòng)窗口(active window)是最上層用戶正在操作的窗口。鍵盤(pán)聚焦的窗體或者是活動(dòng)窗體,或者是活動(dòng)窗體的子窗體。為了幫助用戶辨別活動(dòng)窗體,系統(tǒng)把它置于Z-order的最上層,并高亮它的標(biāo)題欄及邊框。 用戶可以通過(guò)點(diǎn)擊來(lái)激活一個(gè)頂級(jí)窗體,也可以用ALT+TAB(ALT+ESC)組合鍵或者通過(guò)任務(wù)列表來(lái)選擇一個(gè)窗體。線程可以通過(guò)SetActiveWindow函數(shù)來(lái)激活一個(gè)頂級(jí)窗體,也可以通過(guò)GetActiveWindow函數(shù)來(lái)確定它創(chuàng)建的頂級(jí)窗體是否已被激活。 當(dāng)一個(gè)窗體的活動(dòng)狀態(tài)變更時(shí),系統(tǒng)會(huì)發(fā)送WM_ACTIVATE消息。wParam參數(shù)的低字(譯者注:wParam在Win32中是一個(gè)32位的整數(shù),從高到低依次編碼的話應(yīng)該是31、30、29、……、2、1、0,低字指的是15到0)部分 如果為0表示窗體未激活,否則表示激活。默認(rèn)的窗口處理過(guò)程收到WM_ACTIVATE消息時(shí),會(huì)設(shè)置鍵盤(pán)聚焦到活動(dòng)窗口。 要阻止應(yīng)用程序接收鍵盤(pán)及鼠標(biāo)事件的話,可以使用BlockInput。需要注意的是,BlockInput函數(shù)不會(huì)影響異步的鍵盤(pán)輸入狀態(tài)表,也就是說(shuō),當(dāng)輸入被阻塞時(shí),調(diào)用SendInput函數(shù)會(huì)改變異步鍵盤(pán)輸入狀態(tài)表。(譯者注:原文直譯可能讓人更加摸不著北,應(yīng)該是說(shuō),BlockInput函數(shù)不會(huì)影響異步的鍵盤(pán)輸入,這個(gè)時(shí)候,調(diào)用SendInput的話,還是會(huì)改變異步的鍵盤(pán)輸入狀態(tài)信息)。 按鍵消息按下鍵會(huì)產(chǎn)生WM_KEYDOWN或WM_SYSKEYDOWN消息,然后會(huì)被放置在當(dāng)前鍵盤(pán)聚焦的窗口所在線程的消息隊(duì)列中。同樣釋放按鍵也會(huì)產(chǎn)生消息,這個(gè)消息將會(huì)是WM_KEYUP或者WM_SYSKEYUP。 Key-up與Key-down消息通常應(yīng)該成對(duì)出現(xiàn),但如果用戶按下鍵后呆足夠長(zhǎng)時(shí)間的話,鍵盤(pán)會(huì)自動(dòng)重復(fù)描述這一情況,系統(tǒng)會(huì)對(duì)應(yīng)產(chǎn)生一系列的WM_KEYDOWN或WM_SYSKEYDOWN事件,但不管怎樣,用戶釋放按鍵時(shí),只會(huì)產(chǎn)生一個(gè)WM_KEYUP或WM_SYSKEYUP消息。 本節(jié)包括以下內(nèi)容: 系統(tǒng)及非系統(tǒng)按鍵系統(tǒng)中系統(tǒng)按鍵與非系統(tǒng)按鍵是截然不同的,系統(tǒng)按鍵產(chǎn)生系統(tǒng)按鍵消息:WM_SYSKEYDOWN、WM_SYSKEYUP,而非系統(tǒng)按鍵產(chǎn)生非系統(tǒng)按鍵消息:WM_KEYDOWN與WM_KEYUP。 如果你的窗口處理過(guò)程確實(shí)有必要處理系統(tǒng)按鍵消息的話,一定要確認(rèn)在處理完畢后,該過(guò)程把消息傳遞給了DefWindowProc函數(shù)。否則,所有的系統(tǒng)操作,包括ALT鍵都會(huì)失效,即便窗口的確獲得了焦點(diǎn)。也就是說(shuō),用戶將不能訪問(wèn)窗口菜單或者系統(tǒng)菜單,又或者使用ALT+ESC(ALT+TAB)組合鍵激活其他窗口了。 系統(tǒng)按鍵消息主要是系統(tǒng)使用的,系統(tǒng)用這些消息提供菜單的內(nèi)置鍵盤(pán)接口,以及允許用戶控制激活不同的窗口。系統(tǒng)按鍵消息通常是用戶按下ALT及某個(gè)鍵的組合鍵時(shí)產(chǎn)生的,又或者在用戶按下但沒(méi)有窗體擁有鍵盤(pán)焦點(diǎn)(比如,激活的應(yīng)用程序最小化)時(shí)產(chǎn)生。如果消息產(chǎn)生的話,就會(huì)發(fā)送到激活窗體的消息隊(duì)列中。 非系統(tǒng)按鍵消息是需要應(yīng)用程序窗體處理的,DefWindowProc函數(shù)不會(huì)對(duì)這些消息作任何處理,窗體的處理過(guò)程可以忽略任意的不需要的非系統(tǒng)按鍵消息。 虛鍵碼描述按鍵消息的wParam參數(shù)包含了按鍵的虛鍵碼,窗口處理過(guò)程根據(jù)這個(gè)虛鍵碼來(lái)處理或者忽略一個(gè)按鍵消息。 典型的窗口處理過(guò)程中僅會(huì)處理一小部分按鍵消息,其余的部分只是簡(jiǎn)單的接收并忽略。例如,窗口處理過(guò)程可能僅處理WM_KEYDOWN消息,以及光標(biāo)移動(dòng)鍵、換檔鍵(也可以說(shuō)控制鍵),還有功能鍵的虛鍵碼。窗口處理過(guò)程中一般不會(huì)處理字符鍵的按鍵消息,相反,應(yīng)該使用TranslateMessage函數(shù)把它們轉(zhuǎn)換成字符消息。關(guān)于TranslateMessage與字符消息的更多信息,請(qǐng)參見(jiàn)字符消息(Character Message)。 按鍵消息標(biāo)志按鍵消息的lParam消息中包含了按鍵的額外信息,其中包括:重復(fù)次數(shù)、掃描碼、擴(kuò)充鍵標(biāo)志、上下文標(biāo)志、前鍵狀態(tài)標(biāo)志,以及轉(zhuǎn)換狀態(tài)標(biāo)志。下圖指示了這些標(biāo)志及值在lParam中的位置:
按鍵標(biāo)志中可以存儲(chǔ)以下值:
重復(fù)次數(shù)你可以通過(guò)檢查重復(fù)次數(shù),來(lái)確定一次按鍵是否產(chǎn)生了多個(gè)按鍵消息。如果鍵盤(pán)產(chǎn)生WM_KEYDOWN或WM_SYSKEYDOWN消息后,超過(guò)一定時(shí)間應(yīng)用程序還未處理這些消息的話,系統(tǒng)就會(huì)增加重復(fù)計(jì)數(shù)。通常,是因?yàn)橛脩舯3职存I狀態(tài)較長(zhǎng)時(shí)間,而啟動(dòng)了鍵盤(pán)的自動(dòng)重復(fù)技術(shù)機(jī)制。系統(tǒng)不會(huì)因此產(chǎn)生多個(gè)鍵盤(pán)消息,相反,系統(tǒng)會(huì)組合這些消息,并增加這個(gè)消息的重復(fù)次數(shù)。釋放一個(gè)按鍵時(shí)不會(huì)啟動(dòng)自動(dòng)重復(fù)機(jī)制,所以WM_KEYUP與WM_SYSKEYUP消息的重復(fù)次數(shù)總會(huì)是1。 掃描碼掃描碼是用戶按鍵時(shí)由鍵盤(pán)硬件產(chǎn)生的,這個(gè)值是設(shè)備相關(guān)的,用來(lái)標(biāo)識(shí)不同的鍵,對(duì)于字符也是通過(guò)按鍵來(lái)表示的。應(yīng)用程序通常會(huì)忽略掃描碼,實(shí)際上,它使用設(shè)備無(wú)關(guān)的虛鍵碼來(lái)說(shuō)明按鍵消息。 擴(kuò)充鍵標(biāo)志擴(kuò)充鍵標(biāo)志用來(lái)標(biāo)識(shí)按鍵消息中是否包含了增強(qiáng)型鍵盤(pán)的附加鍵,這些擴(kuò)充鍵包括:鍵盤(pán)右手邊的ALT、CTRL鍵,INS、DEL、HOME、END、PAGE UP、PAGE DOWN,小鍵盤(pán)左邊的方向鍵,NUM LOCK、BREAK(CTRL+PAUSE)、PRINT SCRNT以及小鍵盤(pán)上的除號(hào)(/)鍵及ENTER鍵。如果鍵為以上鍵的話,擴(kuò)充鍵標(biāo)志即會(huì)設(shè)置。 上下文標(biāo)志上下文標(biāo)志是為了說(shuō)明按鍵消息產(chǎn)生時(shí),ALT鍵是否已經(jīng)按下,如果為1,表示ALT鍵已經(jīng)按下,否則沒(méi)有按下。 前鍵狀態(tài)標(biāo)志前鍵狀態(tài)標(biāo)志用來(lái)說(shuō)明產(chǎn)生按鍵消息的鍵原來(lái)是抬起的還是按下的。如果為1,表示原來(lái)是按下的,0原來(lái)是抬起的。你可以通過(guò)該標(biāo)志來(lái)辨別該消息是否是由鍵盤(pán)自動(dòng)重復(fù)機(jī)制產(chǎn)生的。如果為1,表示W(wǎng)M_KEYDOWN與WM_SYSKEYDOWN消息是自動(dòng)產(chǎn)生的,對(duì)于WM_KEYUP與WM_SYSKEYUP消息來(lái)說(shuō),該標(biāo)志總會(huì)為0。 轉(zhuǎn)換狀態(tài)標(biāo)志轉(zhuǎn)換狀態(tài)標(biāo)志用來(lái)說(shuō)明該消息是按下鍵時(shí)還是釋放鍵時(shí)產(chǎn)生的,對(duì)于WM_KEYDOWN、WM_SYSKEYDOWN來(lái)說(shuō)該標(biāo)志總會(huì)為0,對(duì)于WM_KEYUP、WM_SYSKEYUP總會(huì)是1。 字符消息按鍵消息可以提供許多按鍵的基本信息,但卻不提供字符鍵的字符碼,要想得到字符碼,應(yīng)用程序必須在自己的線程循環(huán)中包含TranslateMessage函數(shù),TranslateMessage傳遞WM_KEYDOWN或WM_SYSKEYDOWN消息到鍵盤(pán)布局,通過(guò)檢查消息的虛鍵碼,如果發(fā)現(xiàn)它是一個(gè)字符鍵的話,鍵盤(pán)布局就會(huì)提供一個(gè)字符碼的等價(jià)物(會(huì)考慮SHIFT及CAPS LOCK鍵的狀態(tài)),然后產(chǎn)生一個(gè)包括字符碼的字符消息,并放到消息隊(duì)列的頭部。消息循環(huán)的下一次處理就會(huì)把字符消息從隊(duì)列中刪除,并分發(fā)給相應(yīng)的窗口處理過(guò)程。 本節(jié)包含以下內(nèi)容: 非系統(tǒng)字符消息 在窗口的處理過(guò)程中可以處理如下的字符消息: 應(yīng)用程序處理鍵盤(pán)輸入時(shí)通常會(huì)忽略除WM_CHAR與WM_UNICHAR外的所有消息,只是把它們傳遞給DefWindowProc函數(shù)。注意:WM_CHAR使用了16位Unicode轉(zhuǎn)換格式(UTF),WM_UNICHAR使用了UTF-32格式。系統(tǒng)使用WM_SYSCHAR及WM_SYSDEADCHAR消息實(shí)現(xiàn)了菜單助記符的工程。 所有字符消息中的wParam參數(shù)包含了字符鍵的字符碼,其值取決于接收消息的窗口的窗口類(lèi),如果是用的RegisterClass函數(shù)的Unicode版本注冊(cè)的窗口類(lèi),系統(tǒng)就會(huì)向所有那個(gè)類(lèi)的窗口實(shí)例提供Unicode字符,否則就是ASCII字符碼,更多信息,請(qǐng)參照Unicode及字符集。 字符消息中l(wèi)Param參數(shù)值與key-down消息中l(wèi)Param參數(shù)值相同。更多信息,參照按鍵消息標(biāo)志。 不使用字符的消息有些非English鍵盤(pán)中,包含一些本身不產(chǎn)生字符的字符鍵,它們只是用來(lái)為后續(xù)的按鍵提供一個(gè)區(qū)分(譯者注:或者應(yīng)該說(shuō)是,為了區(qū)分后續(xù)的按鍵吧)。這些鍵就被稱(chēng)為無(wú)用鍵(dead keys),These keys are called dead keys. 德文鍵盤(pán)中的揚(yáng)聲符就是一個(gè)無(wú)用鍵的例子,為了輸入由“o”及揚(yáng)聲符組成的符號(hào)(譯者注:應(yīng)該是類(lèi)似“ó”的符號(hào)),德文的用戶需要按下?lián)P聲符鍵,然后是“o”鍵。獲得焦點(diǎn)的窗口就會(huì)收到以下消息序列:
當(dāng)TranslateMessage處理無(wú)用鍵的WM_KEYDOWN消息時(shí),就會(huì)產(chǎn)生WM_DEADCHAR消息,盡管WM_DEADCHAR消息的wParam參數(shù)中包含了揚(yáng)聲符這個(gè)無(wú)用鍵的字符碼,但應(yīng)用程序通常會(huì)忽略這個(gè)消息,而會(huì)接著處理后續(xù)按鍵的WM_CHAR消息。WM_CHAR消息的WM_CHAR參數(shù)中包含了那個(gè)字母與揚(yáng)聲符的字符碼。如果后續(xù)的按鍵產(chǎn)生的字符不能與揚(yáng)聲符組合,系統(tǒng)就會(huì)產(chǎn)生兩個(gè)WM_CHAR消息,第一個(gè)消息的wParam參數(shù)中包含了揚(yáng)聲符的字符碼,第二個(gè)消息的wParam參數(shù)中包含了后續(xù)字符鍵的字符碼。 當(dāng)TranslateMessage處理一個(gè)系統(tǒng)無(wú)用鍵(與ALT的組合鍵)的WM_SYSKEYDOWN消息時(shí),就會(huì)產(chǎn)生WM_SYSDEADCHAR消息。應(yīng)用程序通常忽略WM_SYSDEADCHAR消息。 鍵狀態(tài) 處理鍵盤(pán)消息時(shí),應(yīng)用程序除了需要處理當(dāng)前按鍵消息的那個(gè)按鍵外,還可能需要確定另外一個(gè)鍵的狀態(tài)。比如,一個(gè)字處理軟件,可能允許用戶使用SHIFT+END來(lái)選擇一個(gè)文本塊,那這個(gè)應(yīng)用程序就必須在任意收到END鍵的按鍵消息時(shí),檢驗(yàn)SHIFT鍵是否已按下。應(yīng)用程序可以處理當(dāng)前的按鍵消息時(shí)使用GetKeyState函數(shù)來(lái)確定一個(gè)虛鍵的狀態(tài),也可以通過(guò) 鍵盤(pán)布局維護(hù)著一個(gè)按鍵名稱(chēng)列表,僅產(chǎn)生一個(gè)字符的按鍵的名稱(chēng)與按鍵的名稱(chēng)相同,非字符鍵如TAB、ENTER的名稱(chēng)以字符串的形式存儲(chǔ)。應(yīng)用程序可以通過(guò)調(diào)用GetKeyNameText函數(shù)來(lái)從設(shè)備驅(qū)動(dòng)中得到任意鍵的名稱(chēng)。 按鍵及字符轉(zhuǎn)換系統(tǒng)包含若干特殊用途的函數(shù)來(lái)轉(zhuǎn)換掃描碼、字符碼、以及虛鍵碼,這些函數(shù)包括:MapVirtualKey,ToAscii,ToUnicode及VkKeyScan。 另外,Microsoft® Rich Edit 3.0 熱鍵支持一個(gè)熱鍵是一個(gè)可以產(chǎn)生WM_HOTKEY消息的鍵組合,系統(tǒng)會(huì)把這個(gè)消息放置到消息隊(duì)列的頂部,而繞開(kāi)任何隊(duì)列中已有的消息。應(yīng)用程序使用熱鍵可以向用戶提供更高優(yōu)先級(jí)的鍵盤(pán)輸入,例如,通過(guò)定義CTRL+C組合鍵,應(yīng)用可以使用戶避免冗長(zhǎng)的操作。 要定義熱鍵的話,應(yīng)用程序需要調(diào)用RegisterHotKey函數(shù)來(lái)指定一個(gè)可以產(chǎn)生WM_HOTKEY的組合鍵,再傳入接收消息的窗體的handle以及熱鍵的唯一標(biāo)識(shí)就可以了。用戶按下熱鍵時(shí),創(chuàng)建那個(gè)窗體的線程的消息隊(duì)列中就會(huì)收到WM_HOTKEY。消息中的wParam參數(shù)包含熱鍵的標(biāo)識(shí)。應(yīng)用程序可以在一個(gè)線程中定義多個(gè)熱鍵,但每個(gè)熱鍵必須有一個(gè)唯一標(biāo)識(shí)。應(yīng)用程序終止前,應(yīng)該調(diào)用UnregisterHotKey函數(shù)來(lái)撤銷(xiāo)熱鍵。 應(yīng)用程序可以使用一個(gè)熱鍵控件,使得用戶能夠方便自定義熱鍵,熱鍵控件通常用來(lái)定義一個(gè)熱鍵,使得能夠激活一個(gè)窗口,他們不使用RegisterHotKey及UnregisterHotKey函數(shù),相反,使用熱鍵控件的應(yīng)用程序通常發(fā)送WM_SETHOTKEY消息來(lái)設(shè)置熱鍵,無(wú)論何時(shí),用戶按下熱鍵,系統(tǒng)會(huì)發(fā)送一個(gè)指定SC_HOTKEY的WM_SYSCOMMAND消息。詳細(xì)信息,可參照“應(yīng)用熱鍵控件”。 瀏覽及其他功能鍵Microsoft Windows®可以支持某些特殊鍵:瀏覽器功能鍵、媒體功能鍵、應(yīng)用程序載入鍵以及電源管理鍵。WM_APPCOMMAND可以提供這些特殊鍵的支持。另外,ShellProc也被修改為可以支持額外鍵的函數(shù)了。 在一個(gè)組件應(yīng)用程序中的一個(gè)子窗體直接執(zhí)行這些額外鍵的命令是不太可能的,因此,一旦有這樣的鍵按下的話,DefWindowProc將發(fā)送一個(gè)WM_APPCOMMAND消息到一個(gè)窗體,DefWindowProc也會(huì)(冒泡式的)引發(fā)(bubble)父窗體處理WM_APPCOMMAND消息。 這同點(diǎn)擊鼠標(biāo)右鍵彈出上下文菜單的模式類(lèi)似,DefWindowProc在鼠標(biāo)右擊時(shí)發(fā)送一個(gè)WM_CONTEXTMENU消息,冒泡式的到它的父親。需要額外說(shuō)明的是,如果DefWindowProc收到一個(gè)給頂級(jí)窗體的WM_APPCOMMAND消息的話,就會(huì)以HSHELL_APPCOMMAND代碼調(diào)用一個(gè)外殼鉤子(shell hook)。 Windows也支持Microsoft IntelliMouse® Explorer,它是一個(gè)有五個(gè)按鍵的鼠標(biāo)。兩個(gè)額外鍵支持瀏覽器的前進(jìn)后退。更多信息,請(qǐng)參照 模擬輸入要模擬一個(gè)連續(xù)的一系列的用戶輸入,就可以使用SendInput函數(shù)。這個(gè)函數(shù)需要三個(gè)參數(shù):第一個(gè)參數(shù)cInputs,表示將要模擬的輸入事件的個(gè)數(shù)(INPUT數(shù)組的大?。?;第二個(gè)參數(shù)rgInputs,是INPUT結(jié)構(gòu)的數(shù)組,每個(gè)元素都描述了輸入事件類(lèi)型及事件的附加信息;最后一個(gè)是cbSize,是按字節(jié)計(jì)的INPUT結(jié)構(gòu)的大小。 SendInput函數(shù)通過(guò)向設(shè)備輸入流中注入一系列的模擬事件來(lái)實(shí)現(xiàn)模擬輸入,效果類(lèi)似于重復(fù)調(diào)用keybd_event或mouse_event函數(shù),除了系統(tǒng)需要確認(rèn)模擬事件件沒(méi)有插入其他輸入事件。一旦調(diào)用結(jié)束,其返回值就會(huì)指出有幾個(gè)輸入事件成功運(yùn)行了,如果為0,則說(shuō)明輸入被阻塞了。 SendInput函數(shù)不會(huì)重設(shè)當(dāng)前的鍵盤(pán)狀態(tài),因此,如果調(diào)用此函數(shù)時(shí),用戶已經(jīng)按下了什么鍵的話,就可能被函數(shù)產(chǎn)生的事件所干擾,如果你擔(dān)心潛在的沖突的話,可以用GetAsyncKeyState函數(shù)檢查鍵盤(pán)狀態(tài),并按需要糾正。 語(yǔ)言、場(chǎng)所及鍵盤(pán)布局語(yǔ)言指的是自然語(yǔ)言,如English、French及Japanese,子語(yǔ)言是某個(gè)特定地理區(qū)域的自然語(yǔ)言的變種,如英語(yǔ)的子語(yǔ)言就包括England語(yǔ)及美國(guó)英語(yǔ)。而應(yīng)用程序所指的是語(yǔ)言標(biāo)識(shí),用來(lái)唯一的辨別語(yǔ)言及子語(yǔ)言。 應(yīng)用程序通常使用場(chǎng)所(locales)來(lái)設(shè)置指定輸入輸出的語(yǔ)言,例如設(shè)置鍵盤(pán)的場(chǎng)所會(huì)影響鍵盤(pán)產(chǎn)生的字符值;設(shè)置顯示器或打印機(jī)的場(chǎng)所會(huì)影響字形顯示或打印。應(yīng)用程序通過(guò)調(diào)入使用鍵盤(pán)布局來(lái)設(shè)置場(chǎng)所,通過(guò)選擇指定場(chǎng)所所支持的字體來(lái)設(shè)置顯示器或打印機(jī)的場(chǎng)所。 鍵盤(pán)布局不僅是用來(lái)自定按鍵的物理位置,而且也是用來(lái)確定那些按鍵所決定的字符值的。每個(gè)布局表示當(dāng)前的輸入語(yǔ)言,也用來(lái)確定哪個(gè)或哪些鍵組合可以產(chǎn)生哪些字符值。 每種鍵盤(pán)布局都有相應(yīng)的標(biāo)識(shí)布局及語(yǔ)言的句柄(handle),句柄的低字部分是語(yǔ)言標(biāo)識(shí)符,高字部分是設(shè)備句柄(描述了物理布局),或者為0,表示使用默認(rèn)的物理布局。用戶可以用任意的輸入語(yǔ)言聯(lián)合到一個(gè)物理布局上。如,說(shuō)English的用戶,可能不時(shí)地要去French工作,他就可以設(shè)置輸入語(yǔ)言為French,而不用變更鍵盤(pán)物理布局,這也意味著用戶可以用自己熟悉的English布局輸入French文字。 應(yīng)用程序不要想直接操作輸入語(yǔ)言,相反,用戶可以設(shè)置語(yǔ)言與布局的組合,然后在他們之間交替變更。當(dāng)用戶點(diǎn)擊進(jìn)入一個(gè)不同語(yǔ)言的文本中時(shí),應(yīng)用程序調(diào)用 ActiveKeyboardLayout函數(shù)為當(dāng)前任務(wù)設(shè)置輸入語(yǔ)言,hkl參數(shù)可以是鍵盤(pán)布局的句柄或者0擴(kuò)充的語(yǔ)言標(biāo)識(shí),鍵盤(pán)布局句柄可以通過(guò)LoadKeyboardLayout或GetKeyboardLayoutList函數(shù)獲得,HKL_NEXT及HKL_PREV也可以用來(lái)選擇下一個(gè)或者上一個(gè)鍵盤(pán)。 LoadKeyboardLayout函數(shù)調(diào)入一個(gè)鍵盤(pán)布局并使它對(duì)用戶可用。應(yīng)用程序可以通過(guò)使用KLF_ACTIVATE使得布局立即對(duì)當(dāng)前線程可用,如果沒(méi)有指定KLF_ACTIVATE也可以使用KLF_REORDER重新設(shè)置布局。應(yīng)用程序應(yīng)該在調(diào)入鍵盤(pán)布局時(shí)使用KLF_SUBSTITUTE_OK,以便確保用戶的優(yōu)先設(shè)置,如果有,就會(huì)被選擇。 要多語(yǔ)言支持的話,LoadKeyboardLayout提供KLF_REPLACELANG與KLF_NOTELLSHELL標(biāo)志。KLF_REPLACELANG標(biāo)志可以不用改變語(yǔ)言而直接替換為一個(gè)存在的鍵盤(pán)布局。嘗試替換為一個(gè)相同語(yǔ)言標(biāo)識(shí)的已存在的布局,不指定KLF_REPLACELANG是錯(cuò)誤的。KLF_NOTELLSHELL標(biāo)志會(huì)組織函數(shù)在布局添加或替換時(shí)通知shell。 在連續(xù)的一系列調(diào)用中,這很有用,除了最后一次調(diào)用外,其他調(diào)用都應(yīng)該使用該標(biāo)志。 |
|
|
來(lái)自: donixli1314 > 《Desktop》