




已閱讀5頁(yè),還剩5頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第四講:鍵盤事件【事件驅(qū)動(dòng)】所謂的事件驅(qū)動(dòng)其實(shí)就是當(dāng)滿足什么樣的條件下發(fā)生另外一件事情。比如當(dāng)你按下按鈕時(shí)就會(huì)執(zhí)行相應(yīng)的代碼一樣。由于控制臺(tái)程序在同一個(gè)時(shí)刻只能夠執(zhí)行一個(gè)任務(wù),這就造成了在處理事件的效率上太過(guò)于低下,通?,F(xiàn)代的程序都是面向多任務(wù)的,也就是說(shuō)同一個(gè)時(shí)間段可以完成好幾個(gè)功能,那么如何才能夠做到這一點(diǎn)呢?就依賴于事件驅(qū)動(dòng)機(jī)制。理解事件驅(qū)動(dòng)就必須要先理解事件,所謂的事件(Event)其實(shí)就是觸發(fā)某樣事情發(fā)生的條件,例如鍵盤按下、單擊按鈕、雙擊圖標(biāo)等等。這些稱之為事件。而當(dāng)這些事件發(fā)生之后,就會(huì)觸發(fā)另外一件事情。例如當(dāng)我們點(diǎn)擊“百度搜索”按鈕時(shí)就會(huì)跳轉(zhuǎn)到搜索的結(jié)果界面一樣。當(dāng)然,采用事件驅(qū)動(dòng)的直接原因就是最大化利用CPU,由于控制臺(tái)程序的限制,我們不能夠完成多任務(wù)的操作(早期的DOS操作系統(tǒng)是單用戶單任務(wù)的,即同一個(gè)時(shí)刻只能夠完成一個(gè)任務(wù),效率很慢)故此我們需要事件驅(qū)動(dòng)這樣的機(jī)制為我們提高效率,為我們最大化利用CPU資源。簡(jiǎn)而言之,事件驅(qū)動(dòng)就是一個(gè)用于提高程序效率的機(jī)制。如果上述還沒(méi)有讓你明白過(guò)來(lái),你可以看看百度百科上的解釋,如下:所謂事件驅(qū)動(dòng),簡(jiǎn)單地說(shuō)就是你點(diǎn)什么按鈕(即產(chǎn)生什么事件),電腦執(zhí)行什么操作(即調(diào)用什么函數(shù)).當(dāng)然事件不僅限于用戶的操作. 事件驅(qū)動(dòng)的核心自然是事件。從事件角度說(shuō),事件驅(qū)動(dòng)程序的基本結(jié)構(gòu)是由一個(gè)事件收集器、一個(gè)事件發(fā)送器和一個(gè)事件處理器組成。事件收集器專門負(fù)責(zé)收集所有事件,包括來(lái)自用戶的(如鼠標(biāo)、鍵盤事件等)、來(lái)自硬件的(如時(shí)鐘事件等)和來(lái)自軟件的(如操作系統(tǒng)、應(yīng)用程序本身等)。事件發(fā)送器負(fù)責(zé)將收集器收集到的事件分發(fā)到目標(biāo)對(duì)象中。事件處理器做具體的事件響應(yīng)工作,它往往要到實(shí)現(xiàn)階段才完全確定,因而需要運(yùn)用虛函數(shù)機(jī)制(函數(shù)名往往取為類似于HandleMsg的一個(gè)名字)。對(duì)于框架的使用者來(lái)說(shuō),他們唯一能夠看到的是事件處理器。這也是他們所關(guān)心的內(nèi)容?!境绦虿樵兎绞健客ǔz測(cè)事件有兩種方法,一種稱為程序查詢法,一種稱之為程序中斷法。由于在控制臺(tái)中我們無(wú)法直接使用系統(tǒng)中斷(系統(tǒng)中斷只有匯編語(yǔ)言可以直接使用),因此我們無(wú)法在高級(jí)語(yǔ)言中使用程序中斷法檢測(cè)指令。故此只能夠使用程序查詢方式進(jìn)行事件的檢測(cè)。所謂的程序查詢方式實(shí)際上是利用一個(gè)死循環(huán)不停地對(duì)事件進(jìn)行查詢,如果事件發(fā)生則執(zhí)行相應(yīng)的代碼,當(dāng)代碼執(zhí)行結(jié)束之后繼續(xù)開始下一輪的查詢,由于CPU的計(jì)算速度相當(dāng)快,你不用擔(dān)心會(huì)有延時(shí)的問(wèn)題。這樣一輪一輪查詢的方式,我們稱之為程序查詢方式,也叫輪詢法。程序查詢法的流程圖如下:【鍵盤按下事件】所謂的鍵盤事件,是指無(wú)論在何時(shí)只要鍵盤按鍵被按下,即可被程序所截獲,并執(zhí)行相應(yīng)的功能代碼。故此負(fù)責(zé)監(jiān)聽鍵盤事件的API函數(shù)會(huì)一直處于工作狀態(tài),在MFC中我們可以通過(guò)死循環(huán)進(jìn)行操作,當(dāng)然也可以通過(guò)我們即將接觸到的多線程編程進(jìn)行操作。在這里我們介紹如何利用死循環(huán)監(jiān)聽鍵盤?!綝WORD類型】在MFC中,通常會(huì)見到DWORD類型,所謂的DWORD類型就是Double Word類型,即雙字節(jié)類型,MFC中將unsigned long類型使用typedef關(guān)鍵字重新制定為DWROD類型。MFC框架中的聲明如下:typedef unsigned long DWORD; 故此,DWROD類型的本質(zhì)其實(shí)是一個(gè)無(wú)符號(hào)的長(zhǎng)整型數(shù)。在MFC中我們可以使用DWORD類型表示任何雙字節(jié)的數(shù)據(jù)。這里筆者將不再重復(fù)如何使用DWORD類型的變量的方法?!綢NPUT_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ù)雜,但是也不影響我們的使用,在此要多說(shuō)一句的是union一詞,union也是C/C+語(yǔ)言中的關(guān)鍵字,用于描述“共用體”類型,所謂的共用體實(shí)際上是指在進(jìn)行某些算法編程的時(shí)候,需要使幾種不同類型的變量存放到同一段內(nèi)存單元中。也就是使用覆蓋技術(shù),幾個(gè)變量互相覆蓋。這種幾個(gè)不同的變量共同占用一段內(nèi)存的結(jié)構(gòu),在C語(yǔ)言中,被稱作“共用體”類型結(jié)構(gòu),簡(jiǎn)稱共用體。也被稱之為“聯(lián)合體”。它是早期的C語(yǔ)言過(guò)渡到C+中的產(chǎn)物。當(dāng)然這里我們只需要了解一下就行,并不需要做太多的深究?!臼录愋汀縄NPUT_RECORD結(jié)構(gòu)體中的EnventType成員用于說(shuō)明事件的類型,通常取值如下:事件取值相關(guān)描述FOCUS_EVENT攝像頭事件,控制對(duì)攝像頭的操作KEY_EVENT鍵盤事件,控制對(duì)鍵盤的操作MENU_EVENT菜單事件,控制對(duì)UI中菜單的操作MOUSE_EVENT鼠標(biāo)事件,控制對(duì)鼠標(biāo)的操作WINDOW_BUFFER_SIZE_EVENT窗體緩沖事件小提示:EventType 有5種事件,對(duì)應(yīng)五個(gè) RECORD。所以當(dāng)要使用的是鍵盤事件時(shí),應(yīng)該先判斷 EventType 是否為 KeyEvent,然后使用 KEY_EVENT_RECORD,判斷現(xiàn)在的鍵盤是什么情況。其他事件也是一樣的(一般只使用鍵盤和鼠標(biāo)事件)。鍵盤事件通常有字符事件和按鍵事件。之所以稱為事件,當(dāng)它們被按下時(shí),事件被激發(fā)?!綤EY_EVENT_RECORD結(jié)構(gòu)體】KEY_EVENT_RECORD用于記錄鍵盤事件的情況,當(dāng)有鍵盤事件發(fā)生時(shí),我們就可以使用該結(jié)構(gòu)獲取此時(shí)鍵盤的情況。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; 【虛擬鍵碼】接下來(lái)為大家介紹一下虛擬鍵碼的概念,由于鍵盤上的一些特殊鍵,例如ctrl、alt、shift、enter等鍵不能夠直接被控制臺(tái)程序所識(shí)別,故此在MFC中引入了虛擬鍵碼的概念。虛擬指的是假定存在于思想中而不是現(xiàn)實(shí)世界中的一些事物,也只有熟練使用DOS組合語(yǔ)言編寫應(yīng)用程式的程式寫作者才有可能指出,為什么對(duì)Windows鍵盤處理如此基本的鍵碼是虛擬的而不是真實(shí)的。對(duì)於早期的程序員來(lái)說(shuō),真實(shí)的鍵碼由實(shí)際鍵盤硬體產(chǎn)生。在Windows文件中將這些鍵碼稱為掃描碼(scan codes)。在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)為這些代碼過(guò)於與設(shè)備相關(guān)了,於是他們?cè)噲D通過(guò)定義所謂的虛擬鍵碼,以便經(jīng)由與裝置無(wú)關(guān)的方式處理鍵盤。其中一些虛擬鍵碼不能在IBM相容機(jī)種上產(chǎn)生,但可能會(huì)在其他制造商生產(chǎn)的鍵盤中找到,或者在未來(lái)的鍵盤上找到。提出虛擬鍵盤碼的好處就在于可以兼容不同布局的鍵盤。(不要忘記即使是筆記本電腦也有小鍵盤和大鍵盤之分的哦?。┏S玫奶摂M鍵盤碼如下:十進(jìn)制十六進(jìn)制WINUSER.H識(shí)別字IBM相容鍵盤88VK_BACKBackspace99VK_TABTab120CVK_CLEARLock關(guān)閉時(shí)的數(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)行查詢。使用虛擬鍵碼讀者需要注意以下的幾個(gè)要點(diǎn):1、 Windows下的程序通常不需要監(jiān)視shift、ctrl或alt鍵的狀態(tài)2、 鍵盤上的字母和數(shù)字使用其ASCII碼直接表示,而不采用虛擬鍵碼3、 Windows操作系統(tǒng)中使用VK_LWIN以及VK_RWIN兩個(gè)鍵打開“開始菜單”或者是啟動(dòng)“工作管理員模式”,故此需要謹(jǐn)慎使用這兩個(gè)虛擬鍵碼。4、 對(duì)于鍵盤上的功能鍵(F1 F12)一般不進(jìn)行處理,當(dāng)然虛擬鍵碼表中提供了24個(gè)功能鍵的編碼。【鍵盤事件的操作步驟】鍵盤事件的操作步驟如下:while(1)監(jiān)聽鍵盤;if(有鍵盤事件發(fā)生)if(鍵盤上有按鍵被按下)執(zhí)行被觸發(fā)的功能代碼;【監(jiān)聽鍵盤事件】在MFC框架中通常使用ReadConsoleInput函數(shù)對(duì)鍵盤事件進(jìn)行偵聽,并通過(guò)形參將偵聽到的結(jié)果保存在INPUT_RECORD結(jié)構(gòu)體中。函數(shù)聲明如下:BOOL ReadConsoleInput( HANDLE hConsoleInput, / 輸入設(shè)備句柄 PINPUT_RECORD lpBuffer, / 返回?cái)?shù)據(jù)記錄 DWORD nLength, / 要讀取的記錄數(shù) LPDWORD lpNumberOfEventsRead / 返回已讀取的記錄數(shù) ); 【判斷是否有鍵盤事件發(fā)生】判斷是否有鍵盤事件發(fā)生通常使用INPUT_RECORD結(jié)構(gòu)體中的EnventType進(jìn)行判斷,如果該成員的值與KEY_ENVENT(鍵盤事件)等價(jià)時(shí),則證明發(fā)生了鍵盤事件,即:if(rec.EventType = KEY_EVENT)/如果捕捉到了鍵盤事件cout發(fā)生了鍵盤事件!endl;【判斷是否有鍵被按下】那么如何判斷鍵盤上是否有鍵被按下呢?這很簡(jiǎn)單,我們需要通過(guò)判斷INPUT_RECORD結(jié)構(gòu)體中的成員Event中的KeyEvent中的成員bKeyDown(即Bool KeyDown)是否為true即可。即:if(rec.Event.KeyEvent.bKeyDown = true)/如果此時(shí)有鍵按下cout”有鍵被按下!”endl;【判斷鍵盤按下的鍵值】那么我們?cè)趺床拍軌蛑赖降资悄膫€(gè)鍵被按下呢?此時(shí)我們可以通過(guò)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)/如果此時(shí)有鍵按下char c = rec.Event.KeyEvent.uChar.AsciiChar;/獲取該鍵的ASCII碼putchar(c);/打印該鍵運(yùn)行效果如下:當(dāng)然,光看圖是不行的,還需要讀者自己去運(yùn)行代碼體會(huì)代碼中的含義?!炬I盤事件綜合案例】此處筆者提供一個(gè)綜合案例供大家練習(xí)和參考!該案例是一個(gè)簡(jiǎn)單的文本編輯器,可以模擬打字、按backspace退格刪除、空格、按esc退出等功能。#include #include #include using namespace std;void main()HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);/獲取控制臺(tái)輸出句柄HANDLE in = GetStdHandle(STD_INPUT_HANDLE);/獲取控制臺(tái)輸出句柄DWORD dwRes,dwState = 0;COORD crHome = 0,0,crPos;INPUT_RECORD keyRec;CONSOLE_SCREEN_BUFFER_INFO bInfo;cout歡迎您使用基于控制臺(tái)的文本編輯器!endl;cout請(qǐng)按任意鍵繼續(xù)!endl;getch();system(cls);while(1) ReadConsoleInput(in,
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 臨床實(shí)踐示范試題及答案
- 醫(yī)療健康與區(qū)塊鏈數(shù)據(jù)安全與隱私保護(hù)
- 醫(yī)療健康領(lǐng)域的透明化革新區(qū)塊鏈技術(shù)助力
- 辦公自動(dòng)化與區(qū)塊鏈在版權(quán)管理中的結(jié)合
- 2025年中級(jí)會(huì)計(jì)考試決勝策略及試題與答案
- 消防教育與培訓(xùn)效果評(píng)估的標(biāo)準(zhǔn)試題及答案
- 醫(yī)療旅游行業(yè)的廣告策略與市場(chǎng)分析
- 醫(yī)患溝通技巧與商務(wù)談判能力提升
- 2025年建造師常考知識(shí)試題及答案
- 應(yīng)試經(jīng)驗(yàn)2025中級(jí)會(huì)計(jì)試題及答案
- 專利代繳年費(fèi)合同協(xié)議
- 高級(jí)激光應(yīng)用試題及答案
- 2024中國(guó)國(guó)新基金管理有限公司相關(guān)崗位招聘7人筆試參考題庫(kù)附帶答案詳解
- GB 28050-2025食品安全國(guó)家標(biāo)準(zhǔn)預(yù)包裝食品營(yíng)養(yǎng)標(biāo)簽通則
- 登高車安全培訓(xùn)
- 人教版七年級(jí)地理下冊(cè) 第九章第三節(jié) 撒哈拉以南的非洲(上課、學(xué)習(xí)課件)
- 大型活動(dòng)安全保障職責(zé)與分工
- 健康生活方式指導(dǎo)手冊(cè)含飲食、運(yùn)動(dòng)
- 2025年數(shù)獨(dú)考試試題及答案
- 2025年福建福州電子信息集團(tuán)有限公司招聘筆試參考題庫(kù)含答案解析
- 電力基礎(chǔ)知識(shí)題庫(kù)單選題100道及答案
評(píng)論
0/150
提交評(píng)論