關(guān)於電腦鍵盤的基礎(chǔ)知識(shí)_第1頁
關(guān)於電腦鍵盤的基礎(chǔ)知識(shí)_第2頁
關(guān)於電腦鍵盤的基礎(chǔ)知識(shí)_第3頁
關(guān)於電腦鍵盤的基礎(chǔ)知識(shí)_第4頁
關(guān)於電腦鍵盤的基礎(chǔ)知識(shí)_第5頁
已閱讀5頁,還剩66頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

於^^^然的基磁知

在MicrosoftWindows98中,鍵盤和鼠標(biāo)是兩個(gè)標(biāo)準(zhǔn)的使用者輸入來源,在一些連貫操作中

常產(chǎn)生互補(bǔ)作用。當(dāng)然,鼠標(biāo)在今天的應(yīng)用程序中比十年前使用得更為廣泛。甚至在一些應(yīng)用程

序中,我們更習(xí)慣于使用鼠標(biāo),例如在游戲、畫圖程序、音樂程序以及Web瀏覽器等程序中就

是這樣。然而,我們可以不使用鼠標(biāo),但絕對(duì)不能從一般的PC中把鍵盤拆掉。

相對(duì)于個(gè)人計(jì)算機(jī)的其它組件,鍵盤有非常久遠(yuǎn)的歷史,它起源于1874年的第一臺(tái)Remington

打字機(jī)。早期的計(jì)算機(jī)程序員用鍵盤在Hollerith卡片上打孔,后來在終端機(jī)上用鍵盤直接與大

型主機(jī)溝通。PCI:的鍵盤在某些方面進(jìn)行了擴(kuò)充,加上了功能鍵、光標(biāo)移動(dòng)鍵和單獨(dú)的數(shù)字鍵

盤,但它們的輸入原理基本相同。

鍵盤基礎(chǔ)

您大概已經(jīng)猜到Windows程序是如何獲得鍵盤輸入的:鍵盤輸入以消息的形式傳遞給程序的窗

口消息處理程序。實(shí)際上,第一次學(xué)習(xí)消息時(shí),鍵盤事件就是一個(gè)消息如何將不同型態(tài)信息傳遞

給應(yīng)用程序的顯例。

Windows用八種不同的消息來傳遞不同的鍵盤事件。這好像太多了,但是(就像我們所看到的

一樣)程序可以忽略其中至少一半的消息而不會(huì)有任何問題。并且,在大多數(shù)情況下,這些消息

中包含的鍵盤信息會(huì)多于程序所需要的。處理鍵盤的部分工作就是識(shí)別出哪些消息是重要的,哪

些是不重要的。

忽略鍵盤

雖然鍵盤是Windows程序中使用者輸入的主要來源,但是程序不必對(duì)它接收的所有消息都作出

響應(yīng)。Windows本身也能處理許多鍵盤功能。

例如,您可以忽略那些屬于系統(tǒng)功能的按鍵,它們通常用到Alt鍵。程序不必監(jiān)視這些按鍵,因

為Windows會(huì)將按鍵的作用通知程序(當(dāng)然,如果程序想這么做,它也能監(jiān)視這些按鍵)。雖

然呼叫程序菜單的按鍵將通過窗口的窗口消息處理程序,但通常內(nèi)定的處理方式是將按鍵傳遞給

DefWindowProc..最終,窗口消息處理程序?qū)@得一個(gè)消息,表示一個(gè)菜單項(xiàng)被選擇了。通常,

這是所有窗II消息處理程序需要知道的(在第十章將介紹菜單)。

有些Windows程序使用「鍵盤快捷鍵」來啟動(dòng)通用菜單項(xiàng)??旖萱I通常是功能鍵或字母同Ctrl

鍵的組合(例如,Ctrl-S用于保存文件)。這些鍵盤快捷鍵與程序菜單一起在程序的資源描述

文件中定義(我們可以在第十章看到)。Windows將這些鍵盤快捷鍵轉(zhuǎn)換為菜單命令消息,您

不必自己去進(jìn)行轉(zhuǎn)換。

對(duì)話框也有鍵盤接口,但是當(dāng)對(duì)話框處于活動(dòng)狀態(tài)時(shí),應(yīng)用程序通常不必監(jiān)視鍵盤。鍵盤接11由

Windows處理,Windows把關(guān)于按鍵作用的消息發(fā)送給程序。對(duì)話框可以包含用于輸入文字

的編輯控件。它們一般是小方框,使用者可以在框中鍵入字符串。Windows處理所有編輯控件

邏輯,并在輸入完畢后,將編輯控件的最終內(nèi)容傳送給程序。關(guān)于對(duì)話框的詳細(xì)信息,請(qǐng)參見第

H■章。

編輯控件不必局限于單獨(dú)一行,而且也不限于只在對(duì)話框中。一個(gè)在程序主窗口內(nèi)的多行編輯控

件就能夠作為一個(gè)簡(jiǎn)單的文字編輯器了(參見第九、十、十一和十三章的POPPAD程序)。

Windows甚至有一個(gè)RichText文字編輯控件,允許您編輯和顯示格式化的文字(請(qǐng)參見

/PlatformSDK/UserInterfaceServices/Controls/RichEditControls)。

您將會(huì)發(fā)現(xiàn),在開發(fā)Windows程序時(shí),可以使用處理鍵盤和鼠標(biāo)輸入的子窗口控件來將較高層

的信息傳遞回父窗口。只要這樣的控件用得夠多,您就不會(huì)因處理鍵盤消息而煩惱了。

誰獲得了焦點(diǎn)

與所有的個(gè)人計(jì)算機(jī)硬件一樣,鍵盤必須由在Windows下執(zhí)行的所有應(yīng)用程序共享。有些應(yīng)用

程序可能有多個(gè)窗口,鍵盤必須由該應(yīng)用程序內(nèi)的所有窗口共享。

回想一下,程序用來從消息隊(duì)列中檢索消息的MSG結(jié)構(gòu)包括hwnd字段。此字段指出接收消息

的窗口控件碼。消息循環(huán)中的DispatchMessage函數(shù)向窗口消息處理程序發(fā)送該消息,此窗

口消息處理程序與需要消息的窗口相聯(lián)系。在按下鍵盤上的鍵時(shí),只有一個(gè)窗口消息處理程序接

收鍵盤消息,并且此消息包括接收消息的窗口控件碼。

接收特定鍵盤事件的窗口具有輸入焦點(diǎn)。輸入焦點(diǎn)的概念與活動(dòng)窗口的概念很相近。有輸入焦點(diǎn)

的窗口是活動(dòng)窗口或活動(dòng)窗口的衍生窗口(活動(dòng)窗口的子窗口,或者活動(dòng)窗口子窗口的子窗口等

等)。

通常很容易辨別活動(dòng)窗口。它通常是頂層窗口一也就是說,它的父窗口句柄是NULL。如果活動(dòng)

窗口有標(biāo)題列,Windows將突出顯示標(biāo)題列。如果活動(dòng)窗口具有對(duì)話框架(對(duì)話框中很常見的

格式)而不是標(biāo)題列,Windows將突出顯示框架。如果活動(dòng)窗口目前是最小化的,Windows

將在工作列中突出顯示該項(xiàng),其顯示就像一個(gè)按下的按鈕。

如果活動(dòng)窗11有子窗I」,那么有輸入焦點(diǎn)的窗口既可以是活動(dòng)窗I」也可以是其子窗口。最常見的

子窗口有類似以下控件:出現(xiàn)在對(duì)話框中的下壓按鈕、單選鈕、夏選框、滾動(dòng)條、編輯方塊和清

單方塊。子窗口不能自己成為活動(dòng)窗口。只有當(dāng)它是活動(dòng)窗口的衍生窗口時(shí),子窗口才能有輸入

焦點(diǎn)。子窗口控件一般通過顯示一個(gè)閃爍的插入符號(hào)或虛線來表示它具有輸入焦點(diǎn)。

有時(shí)輸入焦點(diǎn)不在任何窗口中。這種情況發(fā)生在所有程序都是最小化的時(shí)候。這時(shí),Windows

將繼續(xù)向活動(dòng)窗口發(fā)送鍵盤消息,但是這些消息與發(fā)送給非最小化的活動(dòng)窗口的鍵盤消息有不同

的形式。

窗口消息處理程序通過攔截WM_SETFOCUS和WM_KILLFOCUS消息來判定它的窗口何時(shí)

擁有輸入焦點(diǎn)。WM_SETFOCUS指示窗口正在得到輸入焦點(diǎn),WM_K1LLFOCUS表示窗口正

在失去輸入焦點(diǎn)。我將在本章的后面詳細(xì)說明這些消息。

隊(duì)列和同步

當(dāng)使用者按下并釋放鍵盤上的鍵時(shí),Windows和鍵盤驅(qū)動(dòng)程序?qū)⒂布呙璐a轉(zhuǎn)換為格式消息。

然而,這些消息并不保存在消息隊(duì)列中。實(shí)際上,Windows在所謂的「系統(tǒng)消息隊(duì)列」中保存

這些消息。系統(tǒng)消息隊(duì)列是獨(dú)立的消息隊(duì)列,它由Windows維護(hù),用于初步保存使用者從鍵盤

和鼠標(biāo)輸入的信息。只有當(dāng)Windows應(yīng)用程序處理完前一個(gè)使用者輸入消息時(shí),Windows才

會(huì)從系統(tǒng)消息隊(duì)列中取出下一個(gè)消息,并將其放入應(yīng)用程序的消息隊(duì)列中。

此過程分為兩步:首先在系統(tǒng)消息隊(duì)列中保存消息,然后將它們放入應(yīng)用程序的消息隊(duì)列,其原

因是需要同步。就像我們剛才所學(xué)的,假定接收鍵盤輸入的窗口就是有輸入焦點(diǎn)的窗口。使用者

的輸入速度可能比應(yīng)用程序處理按鍵的速度快,并且特定的按鍵可能會(huì)使焦點(diǎn)從一個(gè)窗口切換到

另一個(gè)窗II,后來的按鍵就輸入到了另一個(gè)窗口。但如果后來的按鍵已經(jīng)記下了目標(biāo)窗[.1的地址,

并放入了應(yīng)用程序消息隊(duì)列,那么后來的按鍵就不能輸入到另一個(gè)窗口。

按鍵和字符

應(yīng)用程序從Windows接收的關(guān)于鍵盤事件的消息可以分為按鍵和字符兩類,這與您看待鍵盤的

兩種方式一致。

首先,您可以將鍵盤看作是鍵的集合。鍵盤只有唯一的A鍵,按下該鍵是一次按鍵,釋放該鍵

也是一次按鍵。但是鍵盤也是能產(chǎn)生可顯示字符或控制字符的輸入設(shè)備。根據(jù)Ctrl、Shift和

CapsLock鍵的狀態(tài),A鍵能產(chǎn)生幾個(gè)字符。通常情況下,此字符為小寫a。如果按下Shift

鍵或者打開了CapsLock,則該字符就變成大寫A。如果按下了Ctrl,則該字符為Ctrl-A(它

在ASCII中有意義,但在Windows中可能是某事件的鍵盤快捷鍵)。在一些鍵盤上,A按鍵

之前可能有「死字符鍵(dead-characterkey)」或者Shift、Ctrl或者Alt的不同組合,這些

組合可以產(chǎn)生帶有音調(diào)標(biāo)記的小寫或者大寫,例如,&、&、狡20、或擰?/p>

對(duì)產(chǎn)生可顯示字符的按鍵組合,Windows不僅給程序發(fā)送按鍵消息,而且還發(fā)送字符消息。有

些鍵不產(chǎn)生字符,這些鍵包括shift鍵、功能鍵、光標(biāo)移動(dòng)鍵和特殊字符鍵如Insert和Delete。

對(duì)于這些鍵,Windows只產(chǎn)生按鍵消息。

按鍵消息

當(dāng)您按下一個(gè)鍵時(shí),WindowsJEWM_KEYDOWN或者WM_SYSKEYDOWN消息放入有輸

入焦點(diǎn)的窗口的消息隊(duì)列;當(dāng)您釋放一個(gè)鍵時(shí),Windows把WM_KEYUP或者WM_SYSKEYUP

消息放入消息隊(duì)列中。

表6-1

鍵按下鍵釋放

非系統(tǒng)鍵WM_KEYDOWNWM_KEYUP

系統(tǒng)鍵WM_SYSKEYDOWNWM_SYSKEYUP

通常[down(按下)」和「up(放開)」消息是成對(duì)出現(xiàn)的。不過,如果您按住一個(gè)鍵使得自

動(dòng)重復(fù)功能生效,那么當(dāng)該鍵最后被釋放時(shí),Windows會(huì)給窗口消息處理程序發(fā)送?系列

WM_KEYDOWN(或者WM_SYSKEYDOWN)消息和一個(gè)WM_KEYUP(或者

WM_SYSKEYUP)消息。像所有放入隊(duì)列的消息一樣,按鍵消息也有時(shí)間信息。通過呼叫

GetMessageTime,您可以獲得按下或者釋放鍵的相對(duì)時(shí)間。

系統(tǒng)按鍵與非系統(tǒng)按鍵

WM_SYSKEYDOWN和WM_SYSKEYUP橄「SYS」代表「系統(tǒng)」,它表示該按鍵對(duì)Windows

比對(duì)Windows應(yīng)用程序更加重要。WM_SYSKEYDOWN和WM_SYSKEYUP消息經(jīng)常由與

Alt相組合的按鍵產(chǎn)生,這些按鍵啟動(dòng)程序菜單或者系統(tǒng)菜單上的選項(xiàng),或者用于切換活動(dòng)窗口

等系統(tǒng)功能(Alt-Tab或者Alt-Esc),也可以用作系統(tǒng)菜單快捷鍵(Alt鍵與一個(gè)功能鍵相結(jié)

合,例如Alt-F4用于關(guān)閉應(yīng)用程序)。程序通常忽略WM_SYSKEYL)P和WM_SYSKEYDOWN

消息,并將它們傳送到DefWindowProc。由于Windows要處理所有Alt鍵的功能,所以您無

需攔截這些消息。您的窗口消息處理程序?qū)⒆詈笫盏疥P(guān)于這些按健結(jié)果(如菜單選擇)的其它消

息。如果您想在自己的窗口消息處理程序中加上攔截系統(tǒng)按鍵的程序代碼(如本章后面的

KEYVIEW1和KEYVIEW2程序所作的那樣),那么在處理這些消息之后再傳送到

DefWindowProc,Windows就仍然"I以將它們用于通常的目的。

但是,請(qǐng)?jiān)倏紤]一下,幾乎所有會(huì)影響使用者程序窗口的消息都會(huì)先通過使用者窗口消息處理程

序。只有使用者把消息傳送到DefWindowProc,Windows才會(huì)對(duì)消息進(jìn)行處理。例如,如果

您將下面幾行敘述:

caseWM_SYSKEYDOWN:

caseWM._SYSKEYUP:

caseWM_SYSCHAR:

return0;

加入到一個(gè)窗口消息處理程序中,那么當(dāng)您的程序主窗口擁有輸入焦點(diǎn)時(shí),就可以有效地阻止所

有Alt鍵操作(我將在本章的后面討論WM_SYSCHAR),其中包括Alt-Tab.Alt-Esc以及菜

單操作。雖然我懷疑您會(huì)這么做,但是,我相信您會(huì)感到窗口消息處理程序的強(qiáng)大功能。

WM_KEYDOWN和WM_KEYUP消息通常是在按下或者釋放不帶Alt鍵的鍵時(shí)產(chǎn)生的,您的

程序可以使用或者忽略這些消息,Windows本身并不處理這些消息。

對(duì)所有四類按鍵消息,wParam是虛擬鍵代碼,表示按下或釋放的鍵,而IParam則包含屬于

按鍵的其它數(shù)據(jù)。

虛擬鍵碼

虛擬鍵碼保存在WM_KEYDOWN、WM_KE丫UP、WM_SYSKEYDOWN和WM_SYSKEYUP

消息的wParam參數(shù)中。此代碼標(biāo)識(shí)按下或釋放的鍵。

哈,又是「虛擬」,您喜歡這個(gè)詞嗎?虛擬指的是假定存在于思想中而不是現(xiàn)實(shí)世界中的一些事

物,也只有熟練使用DOS匯編語言編寫應(yīng)用程序的程序?qū)懽髡卟庞锌赡苤赋?,為什么?duì)

Windows鍵盤處理如此基本的鍵碼是虛擬的而不是真實(shí)的。

對(duì)于早期的程序?qū)懽髡邅碚f,真實(shí)的鍵碼由實(shí)際犍盤硬件產(chǎn)生。在Windows文件中將這些鍵碼

稱為「掃描碼(scancodes)」。在IBM兼容機(jī)種上,掃描碼16是Q鍵,17是W鍵,18是

E、19是R,20是T,21是Y等等。這時(shí)您會(huì)發(fā)現(xiàn),掃描碼是依據(jù)鍵盤的實(shí)際布局的。Windows

開發(fā)者認(rèn)為這些代碼過于與設(shè)備相關(guān)了,于是他們?cè)噲D通過定義所謂的虛擬鍵碼,以便經(jīng)由與設(shè)

備無關(guān)的方式處理鍵盤。其中?些虛擬鍵碼不能在IBM兼容機(jī)種上產(chǎn)生,但可能會(huì)在其它制造

商生產(chǎn)的鍵盤中找到,或者在未來的鍵盤上找到。

您使用的大多數(shù)虛擬鍵碼的名稱在WINUSER.H表頭文件中都定義為以VK_瑯。表6-2列出

了這些名稱和數(shù)值(十進(jìn)制和十六進(jìn)制),以及與虛擬鍵相對(duì)應(yīng)的IBM兼容機(jī)種鍵盤上的鍵。

下表也標(biāo)出了Windows執(zhí)行時(shí)是否需要這些鍵。下表還按數(shù)字順序列出了虛擬鍵碼。

前四個(gè)虛擬鍵碼中有三個(gè)指的是鼠標(biāo)鍵:

表6-2

卜進(jìn)制十六進(jìn)制WINUSER.H標(biāo)識(shí)符必需?IBM兼容鍵盤

101VK_LBUTTON鼠標(biāo)左鍵

202VK_RBUTTON鼠標(biāo)右鍵

303VK_CANCELCtrl-Break

404VK_MBUTTON鼠標(biāo)中鍵

您永遠(yuǎn)都不會(huì)從鍵盅消息中獲得這些鼠標(biāo)鍵代碼。在下一章可以看到,我們能夠從鼠標(biāo)消息中獲

得它們。VK_CANCEL代碼是一個(gè)虛擬鍵碼,它包括同時(shí)按下兩個(gè)鍵(Ctrl-Break)。Windows

應(yīng)用程序通常不使用此鍵。

表6-3中的鍵--Backspace、Tab、Enter>Escape和Spacebar一通常用于Windows程序。

不過,Windows一般用字符消息(而不是鍵盤消息)來處理這些鍵。

表6-3

十進(jìn)制十六進(jìn)制WINUSER.H標(biāo)識(shí)符必需?IBM兼容鍵盤

808VK_BACKVBackspace

909VK_TABVTab

120CVK_CLEARNumLock關(guān)閉時(shí)的數(shù)字鍵盤5

130DVK_RETURNEnter(或者另一個(gè))

1610VK_SHIFTVShift(或者另一個(gè))

1711VK_CONTROLVCtrl(或者另一個(gè))

1812VK_MENUAlt(或者另一個(gè))

1913VK_PAUSEPause

2014VK_CAPITALVCapsLock

271BVK_ESCAPEVEsc

3220VK_SPACEVSpacebar

另外,Windows程序通常不需要監(jiān)視Shift、Ctrl或Alt鍵的狀態(tài)。

表6-4列出的前八個(gè)碼可能是與VK」NSERT和VK_DELETE?起最常用的虛擬鍵碼:

表6-4

卜進(jìn)制十六進(jìn)制WINUSER.H標(biāo)識(shí)符必需?IBM兼容鍵盤

3321VK_PRIORVPageUp

3422VK_NEXTVPageDown

3523VK_ENDVEnd

3624VK_HOMEVHome

3725VK_LEFTV左箭頭

3826VK_UPV上箭頭

3927VK_RIGHTV右箭頭

4028VK_DOWNVF箭頭

4129VK_SELECT

422AVK_PRINT

432BVK_EXECUTE

442CVK_SNAPSHOTPrintScreen

452DVK_INSERTVInsert

462EVK_DELETEDelete

472FVK_HELP

注意,許多名稱(例如VK_PRIOR和VK_NEXT)都與鍵上的標(biāo)志不同,而且也與滾動(dòng)條中的

標(biāo)識(shí)符不統(tǒng)一。PrintScreen鍵在平時(shí)都被Windows應(yīng)用程序所忽略。Windows本身響應(yīng)

此鍵時(shí)會(huì)將視訊顯示的位圖影本存放到剪貼板中。假使有鍵盤提供了VK_SELECT、

VK_PRINT、VK_EXECUTE和VK_HELP,大概也沒幾個(gè)人看過那樣的鍵盤。

Windows也包括在主鍵盤上的字母和數(shù)字鍵的虛擬鍵碼(數(shù)字鍵盤將單獨(dú)處理)。

表6-5

十進(jìn)制十六進(jìn)制WINUSER.H標(biāo)識(shí)符必需?IBM兼容鍵盤

48-5730-39無V主鍵盤上的0到9

65-9041-5A無VA至

注意,數(shù)字和字母的虛擬鍵碼是ASCII碼。Windows程序幾乎從不使用這些虛擬鍵碼;實(shí)際

上,程序使用的是ASCII碼字符的字符消息。

表6-6所示的代碼是由MicrosoftNaturalKeyboard及其兼容鍵盤產(chǎn)生的:

表6-6

十進(jìn)制十六進(jìn)制WINUSER.H標(biāo)識(shí)符必需?IBM兼容鍵盤

915BVK_LWIN左Windows鍵

925CVK_RWIN右Windows鍵

935DVK_APPSApplications鍵

Windows用VK_LWIN和VK_RWIN鍵打開「開始」菜單或者(在以前的版本中)啟動(dòng)「工

作管理員程序」。這兩個(gè)都可以用于登錄或注銷Windows(只在MicrosoftWindowsNT中

有效),或者登錄或注銷網(wǎng)絡(luò)(在WindowsforApplications中)。應(yīng)用程序能夠通過顯示

輔助信息或者當(dāng)成快捷方式鍵看待來處理application鍵。

表6-7所示的代碼用于數(shù)字鍵盤上的鍵(如果有的話):

表6-7

十進(jìn)制十六進(jìn)制WINUSER.H標(biāo)識(shí)符必需?IBM兼容鍵盤

96-10560-69VK_NUMPAD0至I」VK_NUMPAD9NumLock打開時(shí)數(shù)字鍵盤上的0到9

1066AVK_MULTIPLY數(shù)字鍵盤上的*

1076BVK_ADD數(shù)字鍵盤上的+

1086CVK_SEPARATOR

1096DVK_SUBTRACT數(shù)字鍵盤上的-

1106EVK_DECIMAL數(shù)字鍵盤上的.

1116FVK_DIVIDE數(shù)字鍵盤上的/

最后,雖然多數(shù)的鍵盤都有12個(gè)功能鍵,但Windows只需要10個(gè),而位旗標(biāo)卻有24個(gè)。

另外,程序通常用功能鍵作為鍵盤快捷鍵,這樣,它們通常不處理表6-8所示的按鍵:

表6-8

十進(jìn)制十六進(jìn)制WINUSER.H標(biāo)識(shí)符必需?IBM兼容鍵盤

112-12170-79VK_F1JiJVK_F107功能鍵F1至IJF10

122-1357A-87VK_F11至!)VK_F24功能鍵F11到F24

14490VK_NUMLOCKNumLock

14591VK_SCROLLScrollLock

另外,還定義了一些其它虛擬犍碼,但它們只用于非標(biāo)準(zhǔn)鍵盤上的鍵,或者通常在大型主機(jī)終端

機(jī)上使用的鍵。查看/PlatformSDK/UserIinterfaceServices/UserInput/Virtual-Key

Codes,可得到完整的列表。

IParam信息

在四個(gè)按鍵消息(WM一KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN和WM_SYSKEYUP)

中,wParam消息參數(shù)含有上面所討論的虛擬鍵碼,而IParam消息參數(shù)則含有對(duì)了解按鍵非

常有用的其它信息。IParam的32位分為6個(gè)字段,如圖6-1所示。

圖6-1IParam變量的6個(gè)按鍵消息字段

重復(fù)計(jì)數(shù)

重復(fù)計(jì)數(shù)是該消息所表示的按鍵次數(shù),大多數(shù)情況下,重復(fù)計(jì)數(shù)設(shè)定為1。不過,如果按下一個(gè)

鍵之后,您的窗口消息處理程序不夠快,以致不能處理自動(dòng)重復(fù)速率(您可以在「控制臺(tái)」的「鍵

盤」中進(jìn)行設(shè)定)下的按鍵消息,Windows就把幾個(gè)WM_KEYDOWN或者

WM_SYSKEYDOWN消息組合到單個(gè)消息中,并相應(yīng)地增加重復(fù)計(jì)數(shù)。WM_KEYUP或

WM_SYSKEYUP消息的重夏計(jì)數(shù)總是為1。

因?yàn)橹貜?fù)計(jì)數(shù)大丁T指示按鍵速率大于您程序的處理能力,所以您也可能想在處理鍵盤消息時(shí)

忽略重復(fù)計(jì)數(shù)。幾乎每個(gè)人都有文書處理或執(zhí)行電子表格時(shí)畫面卷過頭的經(jīng)驗(yàn),因?yàn)槎嘤嗟陌存I

堆滿了鍵盤緩沖區(qū),所以當(dāng)程序用一些時(shí)間來處理每一次按鍵時(shí),如果忽略您程序中的重復(fù)計(jì)數(shù),

就能夠解決此問題。不過,有時(shí)可能也會(huì)用到重復(fù)計(jì)數(shù),您應(yīng)該嘗試使用兩種方法執(zhí)行程序,并

從中找出一種較好的方法。

OEM掃描碼

OEM掃描碼是由硬件(鍵盤)產(chǎn)生的代碼。這對(duì)中古時(shí)代的匯編程序?qū)懽髡邅碚f應(yīng)該很熟悉,

它是從PC相容機(jī)種的ROMBIOS服務(wù)中所獲得的值(OEM指的是PC的原始設(shè)備制造商

(OriginalEquipmentManufacturer)及其與「IBM標(biāo)準(zhǔn)」同步的內(nèi)容)。在此我們不需要

更多的信息。除非需要依賴實(shí)際犍盤布局的樣貌,不然Windows程序可以忽略掉幾乎所有的

OEM掃描碼信息,參見第二十二章的程序KBMIDI。

擴(kuò)充鍵旗標(biāo)

如果按鍵結(jié)果來自IBM增強(qiáng)鍵盤的附加鍵之一,那么擴(kuò)充鍵旗標(biāo)為1(IBM增強(qiáng)型鍵盤有101

或102個(gè)鍵。功能鍵在鍵盤頂端,光標(biāo)移動(dòng)鍵從數(shù)字鍵盤中分離出來,但在數(shù)字鍵盤上還保留

有光標(biāo)移動(dòng)鍵的功能)。對(duì)鍵盤右端的Alt和Ctrl鍵,以及不是數(shù)字鍵盤那部分的光標(biāo)移動(dòng)鍵

(包括Insert和Delete鍵)、數(shù)字鍵盤上的斜線(/)和Enter鍵以及NumLock鍵等,此

旗標(biāo)均被設(shè)定為1?Windows程序通常忽略擴(kuò)充鍵旗標(biāo)。

內(nèi)容代碼

右按鍵時(shí),假如同時(shí)壓下ALT鍵,那么內(nèi)容代碼為1。對(duì)WM_SYSKEYUP與

WM_SYSKEYDOWN而言,此位總視為1;而對(duì)WM_SYSKEYUP'jWM_KEYDOW消息而

言,此位為0。除了兩個(gè)之外:

如果活動(dòng)窗口最小化了,則它沒有輸入焦點(diǎn)。這時(shí)候所有的按鍵都會(huì)產(chǎn)生WM_SYSKEYUP和

WM_SYSKEYDOWN消息。如果Alt鍵未被按下,則內(nèi)容代碼字段被設(shè)定為0。Windows使用

WM_SYSKEYUP和WM_SYSKEYDOWN消息,從而使最小化了的活動(dòng)窗口不處理這些按鍵。

對(duì)于一些外國(guó)語文(非英文)鍵盤,有些字符是通過Shift、Ctrl或者Alt鍵與其它鍵相組合而產(chǎn)

生的。這時(shí)內(nèi)容代碼為1,但是此消息并非系統(tǒng)按鍵消息。

鍵的先前狀態(tài)

如果在此之前鍵是釋放的,則鍵的先前狀態(tài)為0,否則為1。對(duì)WM_KEYUP或者

WM_SYSKEYUP消息,它總是設(shè)定為1;但思寸WM_KEYDOWN或者WM_SYSKEYDOWN

消息,此位可以為0,也可以為1。如果為1,則表示該鍵是自動(dòng)重復(fù)功能所產(chǎn)生的第二個(gè)或者

后續(xù)消息。

轉(zhuǎn)換狀態(tài)

如果鍵正被按下,則轉(zhuǎn)換狀態(tài)為0;如果鍵正被釋放,則轉(zhuǎn)換狀態(tài)為1。對(duì)WM—KEYDOWN或

者WM_SYSKEYDOWN消息,此字段為0;對(duì)WM_KEYUP或者-WM_SYSKEYUP消息,此

字段為1。

位移狀態(tài)

在處理按鍵消息時(shí),您可能需要知道是否按下了位移鍵(Shift、Ctrl和Alt)或開關(guān)鍵(Caps

Lock、NumLock和ScrollLock).通過呼叫GetKeyState函數(shù),您就能獲得此信息。例如:

iState=GetKeyState(VK_SHIFT);

如果按下了Shift,則iState值為負(fù)(即設(shè)定了最高位置位)。如果CapsLock鍵打開,則從

iState=GetKeyState(VK_CAPITAL);

傳回的值低位被設(shè)為1。此位與鍵盤上的小燈保持一致。

通常,您在使用GetKeyState時(shí),會(huì)帶有虛擬鍵碼VK_SHIFT、VK_CONTROL和VK_MENU

(在說明Alt鍵時(shí)呼叫)。使用GetKeyState時(shí),您也可以用下面的標(biāo)識(shí)符來確定按下的Shift、

Ctrl或Alt鍵是左邊的還是右邊的:VK_LSHIFT、VK_RSHIFT、VK_LCONTROL,

VK_RCONTROL.VK_LMENU、VK_RMENU。這些標(biāo)識(shí)符只用于GetKeyState和

GetAsyncKeyState(下面將詳細(xì)說明)。

使用虛擬鍵碼VK_LBL)TTON、VK_RBUTTONfIJVK_MBUTTON,您也可以獲得鼠標(biāo)鍵的狀

態(tài)。不過,大多數(shù)需要監(jiān)視鼠標(biāo)鍵與按鍵相組合的Windows應(yīng)用程序都使用其它方法來做到這

一點(diǎn)一即在接收到鼠標(biāo)消息時(shí)檢查按鍵。實(shí)際上,位移狀態(tài)信息包含在鼠標(biāo)信息中,正如您在下

一章中將看到的一樣。

請(qǐng)注意GetKeyState的使用,它并非實(shí)時(shí)檢查鍵盤狀態(tài),而只是檢查直到目前為止正在處理的

消息的鍵盤狀態(tài)。多數(shù)情況下,這正符合您的要求。如果您需要確定使用者是否按下了

Shift-Tab,請(qǐng)?jiān)谔幚鞹ab鍵的WM_KEYDOWN消息時(shí)呼叫GetKeyState,帶有參數(shù)

VK_SHIFTo如果GetKeyState傳回的值為負(fù),那么您就知道在按下Tab鍵之前按下了Shift

鍵。并且,如果在您開始處理Tab鍵之前,已經(jīng)釋放了Shift鍵也沒有關(guān)系。您知道,在按下

Tab鍵的時(shí)候Shift鍵是按下的。

GetKeyState不會(huì)讓您獲得獨(dú)立于普通鍵盤消息的鍵盤信息。例如,您或許想暫停窗11消息處

理程序的處理,直到您按下F1功能鍵為止:

while(GetKeyState(VK_F1)>=0);//WRONG!!!

不要這么做!這將讓程序當(dāng)死(除非在執(zhí)行此敘述之前早就從消息隊(duì)列中接收到了F1的

WM_KEYDOWN)?如果您確實(shí)需要知道目前某鍵的狀態(tài),那么您可以使用

GetAsyncKeyState。

使用按鍵消息

如果程序能夠獲得每個(gè)按鍵的信息,這當(dāng)然很理想,但是大多數(shù)Windows程序忽略了幾乎所有

的按鍵,而只處理部分的按鍵消息。WM_SYSKEYDOWN和WM_SYSKEYUP消息是由

Windows系統(tǒng)函數(shù)使用的,您不必為此費(fèi)心,就算您要處理WM_KEYDOWN消息,通常也可

以忽略WM_KEYUP消息。

Windows程序通常為不產(chǎn)生字符的按鍵使用WM_KEYDOWN消息。雖然您可能認(rèn)為借助按鍵

消息和位移鍵狀態(tài)信息能將按鍵消息轉(zhuǎn)換為字符消息,但是不要這么做,因?yàn)槟鷮⒂龅絿?guó)際鍵盤

間的差異所帶來的問題。例如,如果您得到wParam等于0x33的WM_KEYDQWN消息,您

就可以知道使用者按下了鍵3,到此為止一切正常。這時(shí),如果用GetKeyState發(fā)現(xiàn)Shift鍵

被按下,您就可能會(huì)認(rèn)為使用者輸入了#號(hào),這可不?定。比如英國(guó)使用者就是在輸入

對(duì)于光標(biāo)移動(dòng)鍵、功能鍵、Insert和Delete鍵,WM_KEYDOWN消息是最有用的。不過,

InsertsDelete和功能鍵經(jīng)常作為菜單快捷鍵。因?yàn)閃indows能把菜單快捷鍵翻譯為菜單命

令消息,所以您就不必自己來處理按鍵。

在Windows之前的MS-DOS應(yīng)用程序中大量使用功能鍵與Shift、Ctrl和Alt鍵的組合,同

樣地,您也可以在Windows程序中使用(實(shí)際上,MicrosoftWord將大量的功能鍵用作命令

快捷方式),但并不推薦這樣做。如果您確實(shí)希望使用功能鍵,那么這些鍵應(yīng)該是重復(fù)菜單命令。

Windows的目標(biāo)之一就是提供不需要記憶或者使用發(fā)雜命令流程的使用者接口。

因此,可以歸納如下:多數(shù)情況下,您將只為光標(biāo)移動(dòng)鍵(有時(shí)也為Insert和Delete鍵)處

理WM_KEYDOWN消息。在使用這些鍵的時(shí)候,您可以通過GetKeyState來檢查Shift鍵和

Ctrl鍵的狀態(tài)。例如,Windows程序經(jīng)常使用Shift與光標(biāo)鍵的組合鍵來擴(kuò)大文書處理里選中

的范圍。Ctrl鍵常用于修改光標(biāo)鍵的意義。例如,Ctrl與右箭頭鍵相組合可以表示光標(biāo)右移一

個(gè)字。

決定您的程序中使用鍵盤方式的最佳方法之一是了解現(xiàn)有的Windows程序使用鍵盤的方式。如

果您不喜歡那些定義,當(dāng)然可以對(duì)其加以修改,但是這樣做不利于其它人很快地學(xué)會(huì)使用您的程

序。

為SYSMETS加上犍盤處理功能

在編寫第四章中三個(gè)版本的SYSMETS程序時(shí),我們還不了解鍵盤,只能使用滾動(dòng)條和鼠標(biāo)來

卷動(dòng)文字?,F(xiàn)在我們知道了處理鍵盤消息的方法,那么不妨在程序中加入鍵盤接口。顯然,這是

處理光標(biāo)移動(dòng)鍵的工作。我們將大多數(shù)光標(biāo)鍵(Home、EndsPageUp、PageDown>UpArrow

和DownArrow)用于垂直卷動(dòng),左箭頭鍵和右箭頭鍵用于不太重要的水平卷動(dòng)。

建立鍵盤接口的一種簡(jiǎn)單方法是在窗口消息處理程序中加入與WM_VSCROLL和

WMJHSCROLL處理方式相仿,而且本質(zhì)上相同的WM_KEYDOWN處理方法。不過這樣子做

是不聰明的,因?yàn)槿绻薷臐L動(dòng)條的做法,就必須相對(duì)應(yīng)地修改WM_KEYDOWN。

為什么不簡(jiǎn)單地將每一種WM_KEYDOWN消息都翻譯成同等效用的WM_VSCROLL或者

WM_HSCROLL消息呢?通過向窗口消息處理程序發(fā)送假冒消息,我們可能會(huì)讓W(xué)ndProc認(rèn)

為它獲得了卷動(dòng)信息。

在Windows中,這種方法是可行的。發(fā)送消息的函數(shù)叫做SendMessage,它所用的參數(shù)均

傳遞到窗口消息處理程序的參數(shù)是相同的:

SendMessage(hwnd,message,wParam,IParam);

在呼叫SendMessage時(shí),Windows呼叫窗口句柄為hwnd的窗口消息處理程序,并把這四

個(gè)參數(shù)傳給它。當(dāng)窗11消息處理程序完成消息處理之后,Windows把控制傳回到

SendMessage呼叫之后的下一道敘述。您發(fā)送消息過去的窗口消息處理程序,可以是同一個(gè)

窗口消息處理程序、同程序中的其它窗口消息處理程序或者其它應(yīng)用程序,中的窗口消息處理

程序。

下面說明在SYSMETS程序中使用SendMessage處理WM_KEYDOWN代碼的方法:

caseWM_KEYDOWN:

switch(wParam)

(

caseVK_HOME:

SendMessage(hwnd,WM_VSCROLL,SB_TOP,0)

break;

caseVK_END:

SendMessage(hwnd,WM_VSCROLL,SB_BOTTOM,0);

break;

caseVK_PRI0R:

SendMessage(hwnd,WM_VSCR0LL,SB_PAGEUP,0);

break;

至此,您已經(jīng)有了大概觀念了吧。我們的目標(biāo)是為滾動(dòng)條添加鍵盤接口,并且也正在這么做。通

過把卷動(dòng)消息發(fā)送到窗口消息處理程序,我們實(shí)作了用光標(biāo)移動(dòng)鍵進(jìn)行卷動(dòng)列的功能?,F(xiàn)在您知

道在SYSMETS3中為WM_VSCROLL消息加」:SB_TOP和SB_BOTTOM處理碼的原因了吧。

在那里并沒有用到它,但是現(xiàn)在處理Home和End鍵時(shí)就有用了。如程序6-1所示的

SYSENTS4就加上了這些變化。編譯這個(gè)程序時(shí)還需要用到第四章的SYSMETS.H文件。

程序6-1SYSMETS4

SYSMETS4.C

/*一""一''''''''-'''一—一

SYSMETS4.C--SystemMetricsDisplayProgramNo.4

(c)CharlesPetzold,1998

Sinclude<windows.h>

Sinclude〃sysmets.h〃

LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);

intWINAPIWinMain(HINSTANCEhlnstance,HINSTANCEhPrevInstance,

PSTRszCmdLine,intiCmdShow)

!

staticTCHARszAppName[]=TEXT(〃SysMets4〃);

HWNDhwnd;

MSGmsg;

WNDCLASSwndclass

wndclass.style=CS_HREDRAWCS_VREDRAW;

wndclass.IpfnWndProc=WndProc;

wndclass.cbClsExtra=0;

wndclass.cbWndExtra=0;

wndclass.hlnstance=hlnstance;

wndclass.hlcon=Loadicon(NULL,IDI_APPLICATION)

wndclass.hCursor=LoadCursor(NULL,IDC?_ARR0W);

wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

wndclass.lpszMenuName=NULL;

wndclass.lpszClassName=szAppName;

if(!RegisterClass(fewndclass))

(

MessageBox(NULL,TEXT(/zProgramrequiresWindowsNT!〃),

szAppName,MB_ICONERROR);

return0;

)

hwnd=CreateWindow(szAppName,TEXT("GetSystemMetricsNo.4〃),

WS_OVERLAPPEDWINDOWWS_VSCROLL|WS_HSCROLL,

CW_USEDEFAULT,CW_USEDEFAULT,

CW_USEDEFAULT,CWUSEDEFAULT,

NULL,NULL,hlnstance,NULL);

ShowWindow(hwnd,iCmdShow);

UpdateWindow(hwnd);

while(GetMessage(&msg,NULL,0,0))

Trans1ateMessage(&msg)

DispatchMessage(&msg);

)

returnmsg.wParam;

)

LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAM

1Param)

staticintexChar,exCaps,cyChar,cxClient,cyClient,iMaxWidth;

HDChdc;

inti,x,y,iVertPos,iHorzPos,iPaintBeg,

iPaintEnd;

PAINTSTRUCTps;

SCROLLINFOsi;

TCHARszBuffer[10];

TEXTMETRICtm;

switch(message)

caseWM_CREATE:

hdc=GetDC(hwnd);

GetTextMetrics(hdc,&tm)

cxChar=tm.tmAveCharWidth;

cxCaps=(tm.tmPitchAndFamily&1?3:2)*exChar/2

cyChar=tm.tmHeight+tm.tmExternalLeading;

ReleaseDC(hwnd,hdc);

//Savethewidthofthethreecolumns

iMaxWidth=40*exChar+22*exCaps

return0;

caseWM_SIZE:

cxClient=LOWORD(IParam);

cyClient=HIWORD(IParam);

//Setverticalscrollbarrangeandpagesize

si.cbSize=sizeof(si);

si.fMask=SIF_RANGESIF_PAGE;

si.nMin=0;

si.nMax=NUMLINES-1;

si.nPage=cyClient/cyChar;

SetScrollInfo(hwnd,SB_VERT,&si,TRUE);

//Sethorizontalscrollbarrangeandpagesize

si.cbSize=sizeof(si);

si.fMask=SIF_RANGESIF_PAGE;

si.nMin=o;

si.nMax=2+iMaxWidth/exChar;

si.nPage=cxClient/exChar;

SetScrollInfo(hwnd,SBJ10RZ,&si,TRUE);

return0;

caseWM_VSCROLL:

//Getalltheverticalscrollbarinformation

si.cbSize=sizeof(si);

si.fMask=SIF_ALL;

GetScrollInfo(hwnd,SBVERT,&si);

//Savethepositionforcomparisonlateron

iVertPos=si.nPos;

switch(LOWORD(wParam))

(

caseSB_TOP:

si.nPos=si.nMin;

break;

caseSB_BOTTOM:

si.nPos=si.nMax

break

caseSBJINEUP:

si.nPos-=1;

break;

caseSB_LINEDOWN:

si.nPos+=1;

break;

caseSB_PAGEUP:

si.nPos-=si.nPage;

break;

caseSB_PAGEDOWN:

si.nPos+=si.nPage;

break;

caseSB_THUMBTRACK:

si.nPos=si.nTrackPos;

break;

default:

break;

)

//Setthepositionandthenretrieveit.Duetoadjustments

//byWindowsitmightnotbethesameasthevalueset.

si.fMask=SIF_POS;

SetScrollInfo(hwnd,SB_VERT,&si,TRUE);

GetScrollInfo(hwnd,SBVERT,&si);

//Ifthepositionhaschanged,scrollthewindowandupdateit

if(si.nPos!=iVertPos)

ScrollWindow(hwnd,0,cyChar*(iVertPos-si.nPos),

NULL,NULL);

UpdateWindow(hwnd);

)

return0;

caseWM_HSCROLL:

//Getalltheverticalscrollbarinformation

si.cbSize=sizeof(si);

si.fMask=SIF_ALL;

//Savethepositionforcomparisonlateron

GetScrollInfo(hwnd,SBJIORZ,&si);

iHorzPos=si.nPos;

switch(LOWORD(wParam))

(

caseSB_LINELEFT:

si.nPos-=1;

break;

caseSB_LINERIGHT:

si.nPos+=1;

break;

caseSB_PAGELEFT:

si.nPos-=si.nPage;

break;

caseSB_PAGERIGHT:

si.nPos+=si.nPage;

break;

caseSB_THUMBPOSITION:

si.nPos=si.nTrackPos;

break;

default:

break;

)

//Setthepositionandthenretrieveit.Duetoadjustments

//byWindowsitmightnotbethesameasthevalueset.

si.fMask=SIF_POS;

SetScrollInfo(hwnd,SB_H0RZ,&si,TRUE);

GetScrollInfo(hwnd,SB_H0RZ,&si);

//Ifthepositionhaschanged,scrollthewindow

if(si.nPos!=iHorzPos)

(

Scrollwindow(hwnd,exChar*(iHorzPos-si.nPos),0,

NULL,NULL);

)

return0;

caseWM__KEYDOWN:

switch(wParam)

(

caseVK_H0ME:

SendMessage(hwnd,WM_VSCROLL,SB_T0P,0);

break;

caseVK_END:

SendMessage(hwnd,WM_VSCR0LL,SB_B0TT0M,0);

break;

caseVK_PRI0R:

SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,0);

break;

caseVK_NEXT:

SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,0);

break;

caseVK一UP:

SendMessage(hwnd,WMJSCROLL,SB_LINEUP,0):

break;

caseVK_DOWN:

SendMessage(hwnd,WM_VSCROLL,SB_LINEDOWN,0);

break;

caseVK_LEFT:

SendMessage(hwnd,WM_HSCROLL,SB_PAGEUP,0);

break;

caseVK_RIGHT:

SendMessage(hwnd,WMJISCROLL,SB_PAGEDOWN,0);

break;

)

return0;

caseWM_PAINT:

hdc=BeginPaint(hwnd,&ps);

//Getverticalscrollbarposition

si.cbSize=sizeof(si);

si.fMask=SIF_POS;

GetScrolHnfo(hwnd,SB_VERT,&si);

iVertPos=si.nPos;

//Gethorizontalscrollbarposition

GetScrollInfo(hwnd,SBHORZ,&si);

iHorzPos=si.nPos;

//Findpaintinglimits

iPaintBeg=max(0,iVertPos+ps.rePaint.top/cyChar)

iPaintEnd=min(NUMLINES-1,

iVertPos+ps.rePaint,bottom/cyChar);

for(i=iPaintBeg;i<=iPaintEnd;i++)

xexChar*(1-iHorzPos);

y二cyChar*(i-iVertPos);

TextOut(hdc,x,y,

sysmetrics[i].szLabel,

Istrlen(sysmetrics[i].szLabel));

TextOut(hdc,x+22*exCaps,y,

sysmetrics[i].szDesc,

Istrlen(sysmetrics[ij.szDesc));

SetTextAlign(hdc,TA_RIGHT|TA_TOP);

TextOut(hdc,x+22*exCaps+40*exChar,y,szBuffer,

wsprintf(szBuffer,TEXT(線5d〃),

GetSystemMetries(sysmetrics[i].iIndex)));

SetTextAlign(hdc,TA_LEFT|TA_TOP);

)

EndPaint(hwnd,&ps);

return0;

caseWM_DESTROY:

PostQuitMessage(0);

return0;

)

returnDefWindowProc(hwnd,message,wParam,IParam);

)

字符消息

前面討論了利用位移狀態(tài)信息把按鍵消息翻譯為字符消息的方法,并且提到,僅利用轉(zhuǎn)換狀態(tài)信

息還不夠,因?yàn)檫€需要知道與國(guó)家/地區(qū)有關(guān)的鍵盤配置。由于這個(gè)原因,您不應(yīng)該試圖把按鍵

消息翻譯為字符代碼。Windows會(huì)為您完成這一工作,在前面我們?cè)吹竭^以下的程序代碼:

while(GetMessage(&msg,NULL,0,0))

!

Trans1ateMessage(&msg);

DispatchMessage(&msg);

)

這是WinMain中典型的消息循環(huán)。GetMessage函數(shù)用隊(duì)列中的下一個(gè)消息填入msg結(jié)構(gòu)的

字段。DispatchMessage以此消息為參數(shù)呼叫適當(dāng)?shù)拇翱谙⑻幚沓绦颉?/p>

在這兩個(gè)函數(shù)之間是TranslateMessage函數(shù),它將按鍵消息轉(zhuǎn)換為字符消息。如果消息為

WM_KEYDOWN或者WM_SYSKEYDOWN,并且按鍵與位移狀態(tài)相組合產(chǎn)生一個(gè)字符,則

TranslateMessage把字符消息放入消息隊(duì)列中。此字符消息將是GetMessage從消息隊(duì)列中

得到的按鍵消息之后的下一個(gè)消息。

四類字符消息

字符消息可以分為四類,如表6-9所示。

表6-9

字符死字符

非系統(tǒng)字符WM_CHARWM_DEADCHAR

系統(tǒng)字符WM_SYSCHARWM_SYSDEADCHAR

WM_CHAR和W

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論