![第四講:鍵盤事件匯總_第1頁](http://file1.renrendoc.com/fileroot_temp2/2020-5/18/97018aba-5394-481b-b9c4-1a9f81539d6a/97018aba-5394-481b-b9c4-1a9f81539d6a1.gif)
![第四講:鍵盤事件匯總_第2頁](http://file1.renrendoc.com/fileroot_temp2/2020-5/18/97018aba-5394-481b-b9c4-1a9f81539d6a/97018aba-5394-481b-b9c4-1a9f81539d6a2.gif)
![第四講:鍵盤事件匯總_第3頁](http://file1.renrendoc.com/fileroot_temp2/2020-5/18/97018aba-5394-481b-b9c4-1a9f81539d6a/97018aba-5394-481b-b9c4-1a9f81539d6a3.gif)
![第四講:鍵盤事件匯總_第4頁](http://file1.renrendoc.com/fileroot_temp2/2020-5/18/97018aba-5394-481b-b9c4-1a9f81539d6a/97018aba-5394-481b-b9c4-1a9f81539d6a4.gif)
![第四講:鍵盤事件匯總_第5頁](http://file1.renrendoc.com/fileroot_temp2/2020-5/18/97018aba-5394-481b-b9c4-1a9f81539d6a/97018aba-5394-481b-b9c4-1a9f81539d6a5.gif)
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第四講:鍵盤事件【事件驅(qū)動】所謂的事件驅(qū)動其實(shí)就是當(dāng)滿足什么樣的條件下發(fā)生另外一件事情。比如當(dāng)你按下按鈕時就會執(zhí)行相應(yīng)的代碼一樣。由于控制臺程序在同一個時刻只能夠執(zhí)行一個任務(wù),這就造成了在處理事件的效率上太過于低下,通?,F(xiàn)代的程序都是面向多任務(wù)的,也就是說同一個時間段可以完成好幾個功能,那么如何才能夠做到這一點(diǎn)呢?就依賴于事件驅(qū)動機(jī)制。理解事件驅(qū)動就必須要先理解事件,所謂的事件(Event)其實(shí)就是觸發(fā)某樣事情發(fā)生的條件,例如鍵盤按下、單擊按鈕、雙擊圖標(biāo)等等。這些稱之為事件。而當(dāng)這些事件發(fā)生之后,就會觸發(fā)另外一件事情。例如當(dāng)我們點(diǎn)擊“百度搜索”按鈕時就會跳轉(zhuǎn)到搜索的結(jié)果界面一樣。當(dāng)然,采用事件驅(qū)動的直接原因就是最大化利用CPU,由于控制臺程序的限制,我們不能夠完成多任務(wù)的操作(早期的DOS操作系統(tǒng)是單用戶單任務(wù)的,即同一個時刻只能夠完成一個任務(wù),效率很慢)故此我們需要事件驅(qū)動這樣的機(jī)制為我們提高效率,為我們最大化利用CPU資源。簡而言之,事件驅(qū)動就是一個用于提高程序效率的機(jī)制。如果上述還沒有讓你明白過來,你可以看看百度百科上的解釋,如下:所謂事件驅(qū)動,簡單地說就是你點(diǎn)什么按鈕(即產(chǎn)生什么事件),電腦執(zhí)行什么操作(即調(diào)用什么函數(shù)).當(dāng)然事件不僅限于用戶的操作. 事件驅(qū)動的核心自然是事件。從事件角度說,事件驅(qū)動程序的基本結(jié)構(gòu)是由一個事件收集器、一個事件發(fā)送器和一個事件處理器組成。事件收集器專門負(fù)責(zé)收集所有事件,包括來自用戶的(如鼠標(biāo)、鍵盤事件等)、來自硬件的(如時鐘事件等)和來自軟件的(如操作系統(tǒng)、應(yīng)用程序本身等)。事件發(fā)送器負(fù)責(zé)將收集器收集到的事件分發(fā)到目標(biāo)對象中。事件處理器做具體的事件響應(yīng)工作,它往往要到實(shí)現(xiàn)階段才完全確定,因而需要運(yùn)用虛函數(shù)機(jī)制(函數(shù)名往往取為類似于HandleMsg的一個名字)。對于框架的使用者來說,他們唯一能夠看到的是事件處理器。這也是他們所關(guān)心的內(nèi)容?!境绦虿樵兎绞健客ǔz測事件有兩種方法,一種稱為程序查詢法,一種稱之為程序中斷法。由于在控制臺中我們無法直接使用系統(tǒng)中斷(系統(tǒng)中斷只有匯編語言可以直接使用),因此我們無法在高級語言中使用程序中斷法檢測指令。故此只能夠使用程序查詢方式進(jìn)行事件的檢測。所謂的程序查詢方式實(shí)際上是利用一個死循環(huán)不停地對事件進(jìn)行查詢,如果事件發(fā)生則執(zhí)行相應(yīng)的代碼,當(dāng)代碼執(zhí)行結(jié)束之后繼續(xù)開始下一輪的查詢,由于CPU的計算速度相當(dāng)快,你不用擔(dān)心會有延時的問題。這樣一輪一輪查詢的方式,我們稱之為程序查詢方式,也叫輪詢法。程序查詢法的流程圖如下:【鍵盤按下事件】所謂的鍵盤事件,是指無論在何時只要鍵盤按鍵被按下,即可被程序所截獲,并執(zhí)行相應(yīng)的功能代碼。故此負(fù)責(zé)監(jiān)聽鍵盤事件的API函數(shù)會一直處于工作狀態(tài),在MFC中我們可以通過死循環(huán)進(jìn)行操作,當(dāng)然也可以通過我們即將接觸到的多線程編程進(jìn)行操作。在這里我們介紹如何利用死循環(huán)監(jiān)聽鍵盤?!綝WORD類型】在MFC中,通常會見到DWORD類型,所謂的DWORD類型就是Double Word類型,即雙字節(jié)類型,MFC中將unsigned long類型使用typedef關(guān)鍵字重新制定為DWROD類型。MFC框架中的聲明如下:typedef unsigned long DWORD; 故此,DWROD類型的本質(zhì)其實(shí)是一個無符號的長整型數(shù)。在MFC中我們可以使用DWORD類型表示任何雙字節(jié)的數(shù)據(jù)。這里筆者將不再重復(fù)如何使用DWORD類型的變量的方法。【INPUT_RECORD結(jié)構(gòu)體】INPUT_RECORD結(jié)構(gòu)體是用于描述輸入設(shè)備事件的結(jié)構(gòu)體,聲明如下:typedef struct _INPUT_RECORD WORD EventType; / 事件類型 union KEY_EVENT_RECORD KeyEvent; /鍵盤事件 MOUSE_EVENT_RECORD MouseEvent; /鼠標(biāo)事件 WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; /窗口緩沖事件 MENU_EVENT_RECORD MenuEvent; /菜單事件 FOCUS_EVENT_RECORD FocusEvent; /攝像頭事件 Event; INPUT_RECORD; 當(dāng)然上述的結(jié)構(gòu)體不像一般的結(jié)構(gòu)體,它有一些復(fù)雜,但是也不影響我們的使用,在此要多說一句的是union一詞,union也是C/C+語言中的關(guān)鍵字,用于描述“共用體”類型,所謂的共用體實(shí)際上是指在進(jìn)行某些算法編程的時候,需要使幾種不同類型的變量存放到同一段內(nèi)存單元中。也就是使用覆蓋技術(shù),幾個變量互相覆蓋。這種幾個不同的變量共同占用一段內(nèi)存的結(jié)構(gòu),在C語言中,被稱作“共用體”類型結(jié)構(gòu),簡稱共用體。也被稱之為“聯(lián)合體”。它是早期的C語言過渡到C+中的產(chǎn)物。當(dāng)然這里我們只需要了解一下就行,并不需要做太多的深究?!臼录愋汀縄NPUT_RECORD結(jié)構(gòu)體中的EnventType成員用于說明事件的類型,通常取值如下:事件取值相關(guān)描述FOCUS_EVENT攝像頭事件,控制對攝像頭的操作KEY_EVENT鍵盤事件,控制對鍵盤的操作MENU_EVENT菜單事件,控制對UI中菜單的操作MOUSE_EVENT鼠標(biāo)事件,控制對鼠標(biāo)的操作WINDOW_BUFFER_SIZE_EVENT窗體緩沖事件小提示:EventType 有5種事件,對應(yīng)五個 RECORD。所以當(dāng)要使用的是鍵盤事件時,應(yīng)該先判斷 EventType 是否為 KeyEvent,然后使用 KEY_EVENT_RECORD,判斷現(xiàn)在的鍵盤是什么情況。其他事件也是一樣的(一般只使用鍵盤和鼠標(biāo)事件)。鍵盤事件通常有字符事件和按鍵事件。之所以稱為事件,當(dāng)它們被按下時,事件被激發(fā)?!綤EY_EVENT_RECORD結(jié)構(gòu)體】KEY_EVENT_RECORD用于記錄鍵盤事件的情況,當(dāng)有鍵盤事件發(fā)生時,我們就可以使用該結(jié)構(gòu)獲取此時鍵盤的情況。KEY_EVENT_RECORD結(jié)構(gòu)體聲明如下;typedef struct _KEY_EVENT_RECORD BOOL bKeyDown; / TRUE表示鍵按下,F(xiàn)ALSE表示鍵釋放 WORD wRepeatCount; / 按鍵次數(shù) WORD wVirtualKeyCode; / 虛擬鍵代碼 WORD wVirtualScanCode; / 虛擬鍵掃描碼 union WCHAR UnicodeChar; / 寬字符 CHAR AsciiChar; / ASCII字符 uChar; / 字符 DWORD dwControlKeyState; / 控制鍵狀態(tài) KEY_EVENT_RECORD; 【虛擬鍵碼】接下來為大家介紹一下虛擬鍵碼的概念,由于鍵盤上的一些特殊鍵,例如ctrl、alt、shift、enter等鍵不能夠直接被控制臺程序所識別,故此在MFC中引入了虛擬鍵碼的概念。虛擬指的是假定存在于思想中而不是現(xiàn)實(shí)世界中的一些事物,也只有熟練使用DOS組合語言編寫應(yīng)用程式的程式寫作者才有可能指出,為什么對Windows鍵盤處理如此基本的鍵碼是虛擬的而不是真實(shí)的。對於早期的程序員來說,真實(shí)的鍵碼由實(shí)際鍵盤硬體產(chǎn)生。在Windows文件中將這些鍵碼稱為掃描碼(scan codes)。在IBM相容機(jī)種上,掃描碼16是Q鍵,17是W鍵,18是E、19是R,20是T,21是Y等等。這時您會發(fā)現(xiàn),掃描碼是依據(jù)鍵盤的實(shí)際布局的。Windows開發(fā)者認(rèn)為這些代碼過於與設(shè)備相關(guān)了,於是他們試圖通過定義所謂的虛擬鍵碼,以便經(jīng)由與裝置無關(guān)的方式處理鍵盤。其中一些虛擬鍵碼不能在IBM相容機(jī)種上產(chǎn)生,但可能會在其他制造商生產(chǎn)的鍵盤中找到,或者在未來的鍵盤上找到。提出虛擬鍵盤碼的好處就在于可以兼容不同布局的鍵盤。(不要忘記即使是筆記本電腦也有小鍵盤和大鍵盤之分的哦?。┏S玫奶摂M鍵盤碼如下:十進(jìn)制十六進(jìn)制WINUSER.H識別字IBM相容鍵盤88VK_BACKBackspace99VK_TABTab120CVK_CLEARLock關(guān)閉時的數(shù)字鍵盤5130DVK_RETURNEnter1610VK_SHIFTShift1711VK_CONTROLCtrl1812VK_MENUAlt1913VK_PAUSEPause2014VK_CAPITALCaps Lock271BVK_ESCAPEEsc3220VK_SPACESpacebar3321VK_PRIORPage Up3422VK_NEXTPage Down3523VK_ENDEnd3624VK_HOMEHome3725VK_LEFT左箭頭3826VK_UP上箭頭3927VK_RIGHT右箭頭4028VK_DOWN下箭頭4129VK_SELECT422AVK_PRINT432BVK_EXECUTE442CVK_SNAPSHOTPrint Screen452DVK_INSERTInsert462EVK_DELETEDelete472FVK_HELP915BVK_LWIN左Windows鍵925CVK_RWIN右Windows鍵1066AVK_MULTIPLY數(shù)字鍵盤上的*1076BVK_ADD數(shù)字鍵盤上的+1086CVK_SEPARATOR1096DVK_SUBTRACT數(shù)字鍵盤上的-1106EVK_DECIMAL數(shù)字鍵盤上的.1116FVK_DIVIDE數(shù)字鍵盤上的/上述是在MFC中常用的一些虛擬鍵碼,更多的大家可以到網(wǎng)上進(jìn)行查詢。使用虛擬鍵碼讀者需要注意以下的幾個要點(diǎn):1、 Windows下的程序通常不需要監(jiān)視shift、ctrl或alt鍵的狀態(tài)2、 鍵盤上的字母和數(shù)字使用其ASCII碼直接表示,而不采用虛擬鍵碼3、 Windows操作系統(tǒng)中使用VK_LWIN以及VK_RWIN兩個鍵打開“開始菜單”或者是啟動“工作管理員模式”,故此需要謹(jǐn)慎使用這兩個虛擬鍵碼。4、 對于鍵盤上的功能鍵(F1 F12)一般不進(jìn)行處理,當(dāng)然虛擬鍵碼表中提供了24個功能鍵的編碼?!炬I盤事件的操作步驟】鍵盤事件的操作步驟如下:while(1)監(jiān)聽鍵盤;if(有鍵盤事件發(fā)生)if(鍵盤上有按鍵被按下)執(zhí)行被觸發(fā)的功能代碼;【監(jiān)聽鍵盤事件】在MFC框架中通常使用ReadConsoleInput函數(shù)對鍵盤事件進(jìn)行偵聽,并通過形參將偵聽到的結(jié)果保存在INPUT_RECORD結(jié)構(gòu)體中。函數(shù)聲明如下:BOOL ReadConsoleInput( HANDLE hConsoleInput, / 輸入設(shè)備句柄 PINPUT_RECORD lpBuffer, / 返回數(shù)據(jù)記錄 DWORD nLength, / 要讀取的記錄數(shù) LPDWORD lpNumberOfEventsRead / 返回已讀取的記錄數(shù) ); 【判斷是否有鍵盤事件發(fā)生】判斷是否有鍵盤事件發(fā)生通常使用INPUT_RECORD結(jié)構(gòu)體中的EnventType進(jìn)行判斷,如果該成員的值與KEY_ENVENT(鍵盤事件)等價時,則證明發(fā)生了鍵盤事件,即:if(rec.EventType = KEY_EVENT)/如果捕捉到了鍵盤事件cout發(fā)生了鍵盤事件!endl;【判斷是否有鍵被按下】那么如何判斷鍵盤上是否有鍵被按下呢?這很簡單,我們需要通過判斷INPUT_RECORD結(jié)構(gòu)體中的成員Event中的KeyEvent中的成員bKeyDown(即Bool KeyDown)是否為true即可。即:if(rec.Event.KeyEvent.bKeyDown = true)/如果此時有鍵按下cout”有鍵被按下!”endl;【判斷鍵盤按下的鍵值】那么我們怎么才能夠知道到底是哪個鍵被按下呢?此時我們可以通過KeyEvent成員中的uChar成員獲取該鍵的ASCII碼或者是Unicode編碼,進(jìn)行判斷。獲取該鍵的ASCII碼的代碼為:char c = rec.Event.KeyEvent.uChar.AsciiChar;/獲取該鍵的ASCII碼獲取該鍵的Unicode編碼的代碼為:WCHAR ch = rec.Event.KeyEvent.uChar.UnicodeChar;通常我們使用ASCII碼判斷該鍵。例 鍵盤事件監(jiān)聽小例子#include #include using namespace std;void main()HANDLE in = GetStdHandle(STD_INPUT_HANDLE);/獲取鍵盤句柄INPUT_RECORD rec;/保存鍵盤事件結(jié)果的結(jié)構(gòu)體DWORD recCount;/已讀取的記錄數(shù)while(1)/始終循環(huán)監(jiān)聽ReadConsoleInput(in, &rec, 1, &recCount);/偵聽鍵盤事件if(rec.EventType = KEY_EVENT)/如果捕捉到了鍵盤事件if(rec.Event.KeyEvent.bKeyDown = true)/如果此時有鍵按下char c = rec.Event.KeyEvent.uChar.AsciiChar;/獲取該鍵的ASCII碼putchar(c);/打印該鍵運(yùn)行效果如下:當(dāng)然,光看圖是不行的,還需要讀者自己去運(yùn)行代碼體會代碼中的含義?!炬I盤事件綜合案例】此處筆者提供一個綜合案例供大家練習(xí)和參考!該案例是一個簡單的文本編輯器,可以模擬打字、按backspace退格刪除、空格、按esc退出等功能。#include #include #include using namespace std;void main()HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);/獲取控制臺輸出句柄HANDLE in = GetStdHandle(STD_INPUT_HANDLE);/獲取控制臺輸出句柄DWORD dwRes,dwState = 0;COORD crHome = 0,0,crPos;INPUT_RECORD keyRec;CONSOLE_SCREEN_BUFFER_INFO bInfo;cout歡迎您使用基于控制臺的文本編輯器!endl;cout請按任意鍵繼續(xù)!endl;getch();system(cls);while(1) ReadConsoleInput(in,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年二手教練車銷售合同格式
- 2025年乳制品代理銷售合同
- 2025年阻沙固沙網(wǎng)項(xiàng)目立項(xiàng)申請報告模板
- 2025年不動產(chǎn)權(quán)購房合同范本
- 2025年家禽購銷合同協(xié)議
- 2025年陶瓷基體項(xiàng)目申請報告模范
- 2025年健身器材購置合同
- 2025年合伙型股權(quán)分配合同
- 2025年度制造業(yè)租賃協(xié)議樣式
- 2025年產(chǎn)品研發(fā)合作協(xié)議范本
- 2025年湖南九嶷職業(yè)技術(shù)學(xué)院高職單招職業(yè)技能測試近5年??及鎱⒖碱}庫含答案解析
- 農(nóng)產(chǎn)品貯運(yùn)與加工考試題(附答案)
- 幼兒園開學(xué)教職工安全教育培訓(xùn)
- 2025年高三歷史教學(xué)工作計劃
- 學(xué)校財務(wù)年終工作總結(jié)4
- 生態(tài)安全課件
- 鋼鐵是怎樣煉成的鋼鐵讀書筆記
- 2025年汽車加氣站作業(yè)人員安全全國考試題庫(含答案)
- 部編高教版2023·職業(yè)模塊 中職語文 《寧夏閩寧鎮(zhèn):昔日干沙灘今日金沙灘》課件
- 化工過程安全管理導(dǎo)則安全儀表管理課件
- 企業(yè)對外溝通與形象塑造制度
評論
0/150
提交評論