版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年哈爾濱貨運(yùn)從業(yè)資格考試題目和答案大全
- 人物實(shí)踐調(diào)研報(bào)告范文
- 社會(huì)實(shí)踐報(bào)告表范文
- 2025年昌都貨運(yùn)從業(yè)資格模擬考試題
- 2025年贛州b2考貨運(yùn)資格證要多久
- 2025年湖北貨運(yùn)從業(yè)資格證考試題庫(kù)工具箱
- 2025年北京年貨運(yùn)從業(yè)資格證考試題庫(kù)
- 小兒糖尿病的飲食護(hù)理
- 八年級(jí)英語Howlonghaveyoubeencollectingshells課件
- 【培訓(xùn)課件】軟件開發(fā)過程中的項(xiàng)目管理
- 2020九年級(jí)英語上冊(cè)全冊(cè)Module1-12重點(diǎn)難點(diǎn)易錯(cuò)點(diǎn)整理新版外研版
- 大學(xué)與青年發(fā)展智慧樹知到答案章節(jié)測(cè)試2023年華僑大學(xué)
- ABB變頻器培訓(xùn)學(xué)習(xí)
- 深圳市2021-2022學(xué)年初三年級(jí)中考適應(yīng)性考試試題及答案
- 森林防火制度匯編
- 電石生產(chǎn)能耗的影響因素
- JJF(紡織)060-2010恒溫恒濕箱校準(zhǔn)規(guī)范
- THBFIA 0004-2020 紅棗制品標(biāo)準(zhǔn)
- GB/T 9239.1-2006機(jī)械振動(dòng)恒態(tài)(剛性)轉(zhuǎn)子平衡品質(zhì)要求第1部分:規(guī)范與平衡允差的檢驗(yàn)
- GB/T 818-2000十字槽盤頭螺釘
- GB/T 31545-2015核電工程用硅酸鹽水泥
評(píng)論
0/150
提交評(píng)論