Visual C++面向?qū)ο笈c可視化程序設(shè)計(jì)(第5版)課件 -04-鍵盤(pán)與鼠標(biāo)_第1頁(yè)
Visual C++面向?qū)ο笈c可視化程序設(shè)計(jì)(第5版)課件 -04-鍵盤(pán)與鼠標(biāo)_第2頁(yè)
Visual C++面向?qū)ο笈c可視化程序設(shè)計(jì)(第5版)課件 -04-鍵盤(pán)與鼠標(biāo)_第3頁(yè)
Visual C++面向?qū)ο笈c可視化程序設(shè)計(jì)(第5版)課件 -04-鍵盤(pán)與鼠標(biāo)_第4頁(yè)
Visual C++面向?qū)ο笈c可視化程序設(shè)計(jì)(第5版)課件 -04-鍵盤(pán)與鼠標(biāo)_第5頁(yè)
已閱讀5頁(yè),還剩48頁(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)介

第4章

Windows應(yīng)用程序?qū)︽I盤(pán)與鼠標(biāo)的響應(yīng)

掃描碼是依賴(lài)于具體設(shè)備的,為達(dá)到設(shè)備無(wú)關(guān)性的要求,往往使用與具體設(shè)備無(wú)關(guān)的虛擬碼,虛擬碼是由Windows系統(tǒng)定義的與設(shè)備無(wú)關(guān)的鍵的標(biāo)識(shí)由于鍵盤(pán)的輸入產(chǎn)生一條消息掃描碼、虛擬碼以及其他與擊鍵有關(guān)的消息設(shè)備驅(qū)動(dòng)程序截取鍵的掃描碼翻譯虛擬碼它含鍵盤(pán)上的鍵對(duì)應(yīng)一個(gè)唯一的標(biāo)識(shí)值(掃描碼)按下或釋放某鍵時(shí)產(chǎn)生取出鍵盤(pán)消息進(jìn)行處理消息設(shè)備驅(qū)動(dòng)程序把消息放到系統(tǒng)的消息隊(duì)列中Windows從系統(tǒng)消息隊(duì)列中取出消息發(fā)送到相應(yīng)的線程消息隊(duì)列中窗口過(guò)程4.1鍵盤(pán)在應(yīng)用程序中的應(yīng)用

虛擬碼是一種與設(shè)備無(wú)關(guān)的鍵盤(pán)編碼,用以標(biāo)識(shí)哪一個(gè)鍵被按下或釋放,最常用的虛擬碼已經(jīng)在winuser.h中定義(“C:\ProgramFiles(x86)\WindowsKits\10\Include\10.0.19041.0\um\WinUser.h”),(Win11系統(tǒng))符號(hào)常量名稱(chēng)等價(jià)的鍵盤(pán)鍵符號(hào)常量名稱(chēng)等價(jià)的鍵盤(pán)鍵VK_RETURN回車(chē)鍵VK_BACK退格鍵VK_SHIFTShift鍵VK_CONTROLCtrl鍵VK_MENUAlt鍵VK_PAUSEPause鍵VK_CAPITALCapsLock鍵VK_ESCAPEEsc鍵VK_PRIORPageUp鍵VK_NEXTPageDown鍵VK_ENDEnd鍵VK_HOMEHome鍵VK_LEFT左箭頭鍵VK_RIGHT右箭頭鍵VK_UP上箭頭鍵VK_DOWN下箭頭鍵VK_0~VK_9字符0~9鍵VK_A~VK_Z字符A~Z鍵VK_INSERTInsert鍵VK_DELETEDelete鍵VK_TAB制表鍵VK_SPACESPACE條VK_ADD+鍵VK_SUBTRACT-鍵VK_DECIMAL*鍵VK_DIVIDE/鍵操作系統(tǒng)在接收到鍵盤(pán)輸入后把消息發(fā)送給具有“輸入焦點(diǎn)(inputfocus)的窗口應(yīng)用程序一般有幾個(gè)窗口,但當(dāng)按下某一個(gè)鍵時(shí),只有一個(gè)窗口能接收到該鍵盤(pán)消息,接收這個(gè)鍵盤(pán)消息的窗口稱(chēng)為有“輸入焦點(diǎn)”的窗口有“輸入焦點(diǎn)”的窗口應(yīng)是活動(dòng)窗口或者活動(dòng)窗口的子窗口窗口正在接收輸入焦點(diǎn)

窗口函數(shù)通過(guò)捕獲WM_SETFOCUS和WM_KILLFOCUS消息確定當(dāng)前窗口是否具有輸入焦點(diǎn)。窗口失去輸入焦點(diǎn)鍵盤(pán)消息按鍵消息字符消息按下或松開(kāi)一個(gè)鍵時(shí)就產(chǎn)生了一按鍵消息一個(gè)按鍵的組合產(chǎn)生了一個(gè)可以顯示的字符時(shí),就產(chǎn)生了一個(gè)字符消息系統(tǒng)按鍵消息非系統(tǒng)按鍵消息Alt鍵與相關(guān)輸入鍵的組合產(chǎn)生的消息,這些鍵一般由Windows系統(tǒng)內(nèi)部直接處理,應(yīng)用程序不處理不使用Alt鍵組合的按鍵消息按鍵消息的兩個(gè)變量wParamlParam32位的變量包含了識(shí)別按下的鍵的虛鍵碼只有當(dāng)鍵盤(pán)驅(qū)動(dòng)程序把鍵盤(pán)字符映射成ASCII碼后才能產(chǎn)生WM_CHAR這個(gè)字符消息字符消息系統(tǒng)非系統(tǒng)WM_KEYDOWN和WM_KEYUP的按鍵消息只能產(chǎn)生非系統(tǒng)消息WM_SYSKEYDOWN和WM_SYSKEYUP按鍵消息只能產(chǎn)生系統(tǒng)消息在某些非U.S.英語(yǔ)鍵盤(pán)上,有些鍵用於給字母加上音調(diào)。因?yàn)樗鼈儽旧聿划a(chǎn)生字元,所以稱(chēng)之為「死鍵」。例如,使用德語(yǔ)鍵盤(pán)時(shí),對(duì)於U.S.鍵盤(pán)上的+/=鍵,德語(yǔ)鍵盤(pán)的對(duì)應(yīng)位置就是一個(gè)死鍵,未按下Shift鍵時(shí)它用於標(biāo)識(shí)銳音,按下Shift鍵時(shí)則用於標(biāo)識(shí)抑音。當(dāng)使用者按下這個(gè)死鍵時(shí),系統(tǒng)接收到wParam等於音調(diào)本身的ASCII或者Unicode代碼的WM_DEADCHAR消息。當(dāng)使用者再按下可以帶有此音調(diào)的字母鍵(例如A鍵)時(shí),系統(tǒng)會(huì)接收到WM_CHAR消息,其中wParam等於帶有音調(diào)的字母「a」的ANSI代碼。因此,用戶不需要處理WM_DEADCHAR訊息,原因是WM_CHAR訊息已含有程序所需要的所有消息。Tip:關(guān)于死字符/en-us/library/windows/desktop/ms646277(v=vs.85).aspxWM_DEADCHAR

specifiesacharactercodegeneratedbyadeadkey.Adeadkeyisakeythatgeneratesacharacter,suchastheumlaut(double-dot),thatiscombinedwithanothercharactertoformacompositecharacter.Forexample,theumlaut-Ocharacter(?)isgeneratedbytypingthedeadkeyfortheumlautcharacter,andthentypingtheOkey.【4-1】設(shè)計(jì)一個(gè)窗口,在該窗口中練習(xí)鍵盤(pán)的響應(yīng),要求如下:(1)單擊鍵盤(pán)上的向上箭頭時(shí),窗口中顯示“Youhadpressedtheupkey”;(2)單擊<Shift>鍵時(shí),窗口中顯示“YouhadpressedtheSHIFTkey”;(3)單擊<Ctrl>鍵時(shí),窗口中顯示“YouhadpressedtheCTRLkey”;(4)單擊<Ctrl+A>鍵時(shí),窗口中顯示“YouhadpressedtheCTRLAkey”;(5)單擊<Shift+B>鍵時(shí),窗口中顯示“YouhadpressedtheSHIFTBkey”。對(duì)于這個(gè)問(wèn)題,難點(diǎn)在于如何區(qū)分“單擊Ctrl鍵”和“單擊Ctrl+A鍵”以及“單擊Shift鍵”和“單擊Shift+B”鍵。nUpKeyDown:上箭頭鍵是否按下nCtrlKeyDown:Ctrl鍵是否按下nCtrlAKeyDown:Ctrl+A鍵是否按下nShiftKeyDown:Shift鍵是否按下nShiftBKeyDown:Shift+B鍵是否按下

對(duì)于這個(gè)問(wèn)題,難點(diǎn)在于如何區(qū)分“單擊Ctrl鍵”和“單擊Ctrl+A鍵”以及“單擊Shift鍵”和“單擊Shift+B”鍵。為此定義了變量:nUpKeyDown來(lái)標(biāo)志上箭頭鍵是否按下CtrlKeyDown變量來(lái)標(biāo)志Ctrl鍵是否按下nCtrlAKeyDown來(lái)標(biāo)志Ctrl+A鍵是否按下nShiftKeyDown來(lái)標(biāo)志Shift鍵是否按下nShiftBKeyDown來(lái)標(biāo)志Shift+B鍵是否按下由于我們這里執(zhí)行的是按下鍵的操作,系統(tǒng)提供了按下鍵的消息響應(yīng)方法,就是在類(lèi)向?qū)е许憫?yīng)WM_KEYDOWN消息,此時(shí)系統(tǒng)生成了如下一個(gè)函數(shù):

OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags)nFlags是各位代表的意義如下:第0-7位:掃描碼第8位:擴(kuò)展鍵,比如說(shuō)功能鍵(F1-12),或者數(shù)字區(qū)的鍵第9-10位:沒(méi)有使用第11-12位:供Windows內(nèi)部使用第13位:狀態(tài)描述碼(如果鍵按下時(shí)ATL鍵也是按下的,那么值為1,否則為0)第14位:前一個(gè)鍵的狀態(tài)(如果是按下的,值為1,否則為0)第15位:變換狀態(tài)(如果鍵是正在被按下,值為1,如果是正在放開(kāi),值為0)虛擬鍵碼鍵被重?fù)舻拇螖?shù)16位的UINT型數(shù)據(jù)那么本例要判斷nChar的值:當(dāng)為向上箭頭鍵的虛擬碼時(shí),nUpKeyDown為真;當(dāng)為Ctrl鍵的虛擬碼時(shí),nCtrlKeyDown為真;當(dāng)為Shift鍵時(shí),nShiftKeyDown的值為真。

但此時(shí)還不能簡(jiǎn)單的輸出結(jié)果,因?yàn)榇藭r(shí)還不知是否按下了A或者B鍵。由于當(dāng)我們按下A和B鍵時(shí),系統(tǒng)會(huì)產(chǎn)生WM_CHAR消息,此時(shí)系統(tǒng)生成了如下字符響應(yīng)函數(shù):

OnChar(UINT

nChar,UINT

nRepCnt,UINT

nFlags)

OnChar函數(shù)的三個(gè)參數(shù)與前面的介紹的OnKeyDown函數(shù)的三個(gè)參數(shù)含義一樣。由于“Ctrl+a”是組合鍵,WM_CHAR傳入的nChar并不是a的鍵碼,也不是a和Ctrl的與運(yùn)算,而是1,若是其他鍵比如shift+a的話nChar傳入的就是a的鍵碼,所以ctrl+a應(yīng)該是一個(gè)系統(tǒng)組合鍵,所以,這里對(duì)Ctrl+A的判斷用的是“nChar==1”對(duì)于Shift+B的操作,則判斷nChar,當(dāng)是98和66時(shí),表明B/b鍵按下,此時(shí)設(shè)置nShiftBKeyDown的值為“真”,同時(shí)將nShiftKeyDown的值設(shè)為“假”。同理處理nCtrlAKeyDown和nCtrlKeyDown的值。if(nChar==1){if(nCtrlKeyDown==TRUE){nCtrlAKeyDown=TRUE;nCtrlKeyDown=FALSE;}}else

if(nChar==98||nChar==66) //當(dāng)按下b鍵時(shí){if(nShiftKeyDown==TRUE) //檢查shift鍵是否處于按下?tīng)顟B(tài) {nShiftBKeyDown=TRUE; //當(dāng)SHIFT鍵按下時(shí),變量置為真 nShiftKeyDown=FALSE; }}抬起鍵時(shí),系統(tǒng)發(fā)送WM_KEYUP消息,消息處理程序中調(diào)用Invalidate();產(chǎn)生WM_PAINT消息,調(diào)用OnPaint函數(shù)。1:創(chuàng)建基于對(duì)話框的工程文件4_1,并添加如下類(lèi)的成員變量:

CDC*hDC; //定義設(shè)備環(huán)境句柄2:定義一系列BOOL型變量,用來(lái)表示相關(guān)鍵的狀態(tài),并定義一系列操作的響應(yīng)信息字符串:BOOLnUpKeyDown=FALSE;BOOLnShiftKeyDown=FALSE;BOOLnCtrlKeyDown=FALSE;BOOLnCtrlAKeyDown=FALSE;BOOLnShiftBKeyDown=FALSE;LPCWSTRcUp=L"YouhadpressedtheUPkey";LPCWSTRcCtrl=L"YouhadpressedtheCtrlkey";LPCWSTRcShift=L"YouhadpressedtheSHIFTkey";LPCWSTRcCtrl_A=L"YouhadpressedtheCTRLAkey";LPCWSTRcShift_B=L"YouhadpressedtheSHIFTBkey";3:通過(guò)“類(lèi)向?qū)А保憫?yīng)WM_KeyDown按鍵消息,并添加如下代碼:voidCMy41Dlg::OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags){switch(nChar){caseVK_UP: //當(dāng)按上箭頭鍵時(shí),變量置為真 nUpKeyDown=TRUE; break;caseVK_SHIFT: //當(dāng)按shift鍵時(shí),變量置為真 nShiftKeyDown=TRUE; nShiftBKeyDown=FALSE; break;caseVK_CONTROL: //當(dāng)按control鍵時(shí),變量置為真 nCtrlKeyDown=TRUE; nCtrlAKeyDown=FALSE; break;default: break;}CDialogEx::OnKeyDown(nChar,nRepCnt,nFlags);}4:通過(guò)“類(lèi)向?qū)А表憫?yīng)WM_KeyUp消息處理函數(shù),并添加如下的代碼:voidCMy41Dlg::OnKeyUp(UINTnChar,UINTnRepCnt,UINTnFlags){ Invalidate();//發(fā)送刷新請(qǐng)求,由OnPaint函數(shù)進(jìn)行響應(yīng) CDialogEx::OnKeyUp(nChar,nRepCnt,nFlags);}5:通過(guò)“類(lèi)向?qū)А表憫?yīng)WM_CHAR消息,并添加如下斜體代碼:voidCMy41Dlg::OnChar(UINTnChar,UINTnRepCnt,UINTnFlags){if(nChar==1) {if(nCtrlKeyDown==TRUE)//如果按下Ctrl鍵進(jìn) {nCtrlAKeyDown=TRUE; nCtrlKeyDown=FALSE; } }elseif(nChar==98||nChar==66) //當(dāng)按下b鍵時(shí) {if(nShiftKeyDown==TRUE) //檢查shift鍵是否按下 {nShiftBKeyDown=TRUE;//當(dāng)SHIFT鍵按下時(shí),變量置為真 nShiftKeyDown=FALSE; }}CDialogEx::OnChar(nChar,nRepCnt,nFlags);}6:通過(guò)“類(lèi)向?qū)А?,添加虛函?shù)PreTranslateMessage,并添加如下斜體部分的代碼:BOOLCMy41Dlg::PreTranslateMessage(MSG*pMsg){ SendMessage(pMsg->message,pMsg->wParam,pMsg->lParam); returnCDialogEx::PreTranslateMessage(pMsg);}7:編寫(xiě)刷新函數(shù)OnPaint,并添加如下斜體加粗部分的代碼:voidCMy41Dlg::OnPaint(){CPaintDCdc(this); //用于繪制的設(shè)備上下文hDC=GetDC();hDC->SetTextColor(RGB(255,0,0)); //設(shè)置字體顏色為紅色//輸出信息。if(nUpKeyDown==TRUE){hDC->Rectangle(0,0,300,200);//設(shè)置一個(gè)矩形區(qū)域用來(lái)輸出文字hDC->TextOut(20,0,cUp,(int)wcslen(cUp));//輸出文字nUpKeyDown=FALSE;}elseif(nCtrlAKeyDown==TRUE){hDC->Rectangle(0,0,300,200);hDC->TextOut(20,100,cCtrl_A,(int)wcslen(cCtrl_A));nCtrlAKeyDown=FALSE;nCtrlKeyDown=FALSE;}elseif((nCtrlKeyDown==TRUE)&&(nCtrlAKeyDown==FALSE)){hDC->Rectangle(0,0,300,200);hDC->TextOut(20,60,cCtrl,(int)wcslen(cCtrl));nCtrlKeyDown=FALSE;}elseif(nShiftBKeyDown==TRUE){hDC->Rectangle(0,0,300,200);hDC->TextOut(20,0,cShift_B,(int)wcslen(cShift_B));nShiftBKeyDown=FALSE;nShiftKeyDown=FALSE;}elseif((nShiftKeyDown==TRUE)&&(nShiftBKeyDown==FALSE)){hDC->Rectangle(0,0,300,200);hDC->TextOut(20,0,cShift,(int)wcslen(cShift));nShiftKeyDown=FALSE;}else;ReleaseDC(hDC);}用戶窗口區(qū)輸入“這是一個(gè)有關(guān)鍵盤(pán)操作的示例程序”的字符串程序中緩沖區(qū)大小只設(shè)30個(gè)字符,當(dāng)緩沖區(qū)滿時(shí)若再輸入任何字符,就出現(xiàn)(1)號(hào)錯(cuò)誤提示用戶按下左箭頭鍵直至光標(biāo)到達(dá)本行起始位置時(shí),就無(wú)法再往左移動(dòng),則出現(xiàn)(2)號(hào)錯(cuò)誤信息若此時(shí)您按下Esc鍵,就出現(xiàn)(3)號(hào)錯(cuò)誤提示信息若當(dāng)前光標(biāo)位置處于本行的起始位置,此時(shí)按下回退鍵(BackSpace),則出現(xiàn)編號(hào)為(4)的錯(cuò)誤提示信息若字符緩沖區(qū)中已沒(méi)有任何字符,此時(shí)按下了Delete鍵,則出現(xiàn)(5)號(hào)錯(cuò)誤提示信息【例4-2】:本例演示鍵盤(pán)輸入時(shí)所產(chǎn)生的消息序列并在窗口的客戶區(qū)顯示對(duì)應(yīng)的字符1:創(chuàng)建基于對(duì)話框的應(yīng)用程序4_2,并添加類(lèi)成員變量: CDC*hDC; //定義DC TEXTMETRICtm; //定義文字結(jié)構(gòu)的變量tm2:在cpp文件中添加如下變量及宏定義:#defineBufSize10 //設(shè)置存放字符的緩沖區(qū)大小

WCHARcCharBuf[BufSize];//字符數(shù)組,存放輸入的字符,字符個(gè)數(shù)不能超出緩沖區(qū)大小intnNumChar=0; //現(xiàn)有字符個(gè)數(shù)intnArrayPos=0; //字符的位置intnLnHeight; //字符高度intnCharWidth; //字符寬度3:在初始化函數(shù)中獲取字體信息并建立定時(shí)器: hDC=GetDC(); //獲取當(dāng)前DC hDC->GetTextMetrics(&tm); //獲取字體信息 nLnHeight=tm.tmHeight+tm.tmExternalLeading; //獲取字體高度 nCharWidth=tm.tmAveCharWidth; //獲取字體寬度 SetTimer(1,500,NULL); //設(shè)置定時(shí)器 ReleaseDC(hDC);4:通過(guò)類(lèi)向?qū)?,響?yīng)WM_CHAR這個(gè)字符消息,添加如下代碼:voidCMy42Dlg::OnChar(UINTnChar,UINTnRepCnt,UINTnFlags){if(nChar==VK_BACK) //按回退鍵時(shí)的消息處理{if(nArrayPos==0)//若已在一行文字開(kāi)始處,提示用戶"不能回退"MessageBox(L"當(dāng)前位置是文本的起始位置,不能回退",NULL,MB_OK);else{nArrayPos=nArrayPos-1;//每按一次回退鍵就回退一個(gè)字符位置nNumChar=nNumChar-1; //對(duì)現(xiàn)有字符總數(shù)進(jìn)行計(jì)數(shù)for(inti=nArrayPos;i<nNumChar;i++) cCharBuf[i]=cCharBuf[i+1];//由于按回退鍵,回退位置的后續(xù)字符依次前移 Invalidate();}return;}else

if(nChar==VK_LEFT)//處理按下左方向鍵時(shí)的消息{if(nArrayPos>0)nArrayPos=nArrayPos-1;

//當(dāng)前輸入位置往前移一個(gè)位置,再輸入字符時(shí),等于插入字符else

//已經(jīng)移到起始輸入位置,不能再往前了MessageBox(L"您已經(jīng)移動(dòng)到起始位置,不能再往左移動(dòng)了",NULL,MB_OK);return;}else

if(nChar==VK_RIGHT)//處理按下右方向鍵時(shí)的消息{if(nArrayPos<nNumChar)//如果當(dāng)前位置沒(méi)有到緩沖區(qū)的最后位置,還能向右移動(dòng) nArrayPos=nArrayPos+1;else

MessageBox(L"已經(jīng)到緩沖區(qū)的末尾,不能再向右移動(dòng)了",NULL,MB_OK);return;}CDialogEx::OnKeyDown(nChar,nRepCnt,nFlags);}if(nNumChar>=BufSize)//若寫(xiě)入的字符數(shù)超過(guò)緩沖區(qū)大小,則報(bào)警{MessageBox(L"緩沖區(qū)已滿,不能再輸入字符了\n若需要?jiǎng)h除字符,請(qǐng)用BackSpace鍵",NULL,MB_OK);return;}for(intx=nNumChar;x>nArrayPos;x=x-1) cCharBuf[x]=cCharBuf[x-1];cCharBuf[nArrayPos]=(wchar_t)nChar;nArrayPos=nArrayPos+1;nNumChar=nNumChar+1;Invalidate();CDialogEx::OnChar(nChar,nRepCnt,nFlags);}5:通過(guò)類(lèi)向?qū)?,響?yīng)按下鍵的WM_KEYDOWN消息,添加如下代碼:voidCMy42Dlg::OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags){if(nChar==VK_END) //處理按下鍵為End時(shí)的消息{nArrayPos=nNumChar; //輸入位置從本行的末尾開(kāi)始return;}elseif(nChar==VK_ESCAPE) //處理按下Escape鍵消息{MessageBox(L"您現(xiàn)在不能按ESC鍵,請(qǐng)繼續(xù)其它操作",NULL,MB_OK);return;}elseif(nChar==VK_HOME) //處理按下鍵為Home時(shí)的消息{nArrayPos=0; //輸入位置為本行的起始位置return;}

elseif(nChar==VK_DELETE) //對(duì)Del鍵的操作{if(nArrayPos==nNumChar) //若輸入位置處于本行的末尾MessageBox(L"緩沖區(qū)已空,沒(méi)有字符可供刪除",NULL,MB_OK);else{for(intx=nArrayPos;x<nNumChar;x=x+1) cCharBuf[x]=cCharBuf[x+1]; //每刪除一個(gè)字符,緩沖區(qū)中總字符數(shù)減1 nNumChar=nNumChar-1; Invalidate(); //用戶區(qū)刷新}return;}elseif(nChar==VK_LEFT) //處理按下左方向鍵時(shí)的消息{if(nArrayPos>0)nArrayPos=nArrayPos-1;//當(dāng)前輸入位置前移一個(gè)位置,再輸入字符時(shí),等于插入字符else //已經(jīng)移到起始輸入位置,不能再往前了

MessageBox(L"您已經(jīng)移動(dòng)到起始位置,不能再往左移動(dòng)了",NULL,MB_OK);return;}elseif(nChar==VK_RIGHT) //處理按下右方向鍵時(shí)的消息{if(nArrayPos<nNumChar) //若當(dāng)前位置沒(méi)有到緩沖區(qū)的最后位置,還能向右移動(dòng)nArrayPos=nArrayPos+1;else

MessageBox(L"已經(jīng)到緩沖區(qū)的末尾,不能再向右移動(dòng)了",NULL,MB_OK);return;}CDialogEx::OnKeyDown(nChar,nRepCnt,nFlags);}7:響應(yīng)字符消息的預(yù)處理,添加如下的代碼:BOOLCMy42Dlg::PreTranslateMessage(MSG*pMsg){ SendMessage(pMsg->message,pMsg->wParam,pMsg->lParam); if(pMsg->message==WM_KEYDOWN&&pMsg->wParam==VK_ESCAPE)//添加這一段代碼,使得按下Esc健時(shí)不會(huì)關(guān)閉窗口 { returnTRUE; } returnCDialogEx::PreTranslateMessage(pMsg);}

8:定時(shí)器消息處理函數(shù),添加如下斜體加粗部分的代碼:voidCMy42Dlg::OnTimer(UINT_PTRnIDEvent){ Invalidate(); CDialogEx::OnTimer(nIDEvent);}9:刷新函數(shù),添加如下斜體加粗部分的代碼voidCMy42Dlg::OnPaint(){CPaintDCdc(this); //用于繪制的設(shè)備上下文hDC=GetDC();hDC->TextOut(nCharWidth,nLnHeight,cCharBuf,nNumChar);//輸出緩沖區(qū)中的文本ReleaseDC(hDC);}4.3鼠標(biāo)在應(yīng)用程序中的應(yīng)用鼠標(biāo)作為定位輸入設(shè)備,通過(guò)鼠標(biāo)單擊、雙擊和拖動(dòng)功能,用戶可以很容易地操作基于Windows圖形界面的應(yīng)用程序。Windows中通過(guò)光標(biāo)來(lái)指示當(dāng)前鼠標(biāo)的位置,在Windows操作系統(tǒng)中預(yù)定義了幾種光標(biāo),并在afxwin.h頭文件中加以定義,代表預(yù)定義光標(biāo)的常量光標(biāo)屬性描述IDC_APPSTARTING標(biāo)準(zhǔn)箭頭和小沙漏IDC_ARROW箭頭光標(biāo)IDC_CROSS十字光標(biāo)IDC_HAND手形光標(biāo)IDC_HELP箭頭加問(wèn)號(hào)IDC_IBEAMI形文本光標(biāo)IDC_NO按下鼠標(biāo)左鍵后,光標(biāo)變成圓圈中帶一斜線IDC_SIZEALL帶東西南北箭頭的十字光標(biāo)IDC_SIZENESW帶有指向東北方和西南方箭頭的光標(biāo)IDC_SIZENS帶有上下箭頭的光標(biāo)IDC_SIZENWSE帶有指向西北方和東南方箭頭的光標(biāo)ISC_SIZEWE帶有左右箭頭的光標(biāo)IDC_UPARROW垂直向上箭頭光標(biāo)IDC_WAIT等待光標(biāo)可調(diào)用LoadCursor函數(shù)改變光標(biāo)形式,如加載等待光標(biāo)LoadCursor(NULL,IDC_WAIT);用戶自定義光標(biāo)自定義光標(biāo)保存在擴(kuò)展名為.cur的文件中

光標(biāo)名CURSOR光標(biāo)文件(.cur)采用自定義光標(biāo)時(shí),需在資源文件中定義光標(biāo)資源加載光標(biāo)資源(常在定義窗口類(lèi)時(shí)進(jìn)行)

LoadCursor(NULL,lpszCursorname)當(dāng)前光標(biāo)鼠標(biāo)消息lParam包含了鼠標(biāo)位置低位包含鼠標(biāo)位置的x坐標(biāo)值高位包含鼠標(biāo)位置的y坐標(biāo)wParam包含了指示各種虛鍵狀態(tài)的值相當(dāng)于窗口的左上角為原點(diǎn)的坐標(biāo)值在鼠標(biāo)消息中,可以定義一個(gè)點(diǎn)的結(jié)構(gòu)參數(shù):POINTpt;可通過(guò)GetCursorPos(&pt);來(lái)獲取當(dāng)前光標(biāo)的位置消息含義WM_LBUTTONDOWN用戶區(qū)內(nèi)單擊鼠標(biāo)左鍵WM_LBUTTONUP用戶區(qū)內(nèi)松開(kāi)鼠標(biāo)左鍵WM_LBUTTONDBLCLK用戶區(qū)內(nèi)雙擊鼠標(biāo)左鍵WM_MBUTTONDOWN用戶區(qū)內(nèi)單擊鼠標(biāo)中鍵WM_MBUTTONUP用戶區(qū)內(nèi)松開(kāi)鼠標(biāo)中鍵WM_MBUTTONDBLCLK用戶區(qū)內(nèi)雙擊鼠標(biāo)中鍵WM_RBUTTONDOWN用戶區(qū)內(nèi)單擊鼠標(biāo)右鍵WM_RBUTTONUP用戶區(qū)內(nèi)松開(kāi)鼠標(biāo)右鍵WM_RBUTTONDBLCLK用戶區(qū)內(nèi)雙擊鼠標(biāo)右鍵WM_MOUSEMOVE鼠標(biāo)在用戶區(qū)內(nèi)移動(dòng)WM_MOUSEWHEEL鼠標(biāo)滾輪轉(zhuǎn)動(dòng)WM_MOUSEACTIVATE鼠標(biāo)指針在非激活窗口的時(shí)候按下了鼠標(biāo)按鈕WM_MOUSEHOVER鼠標(biāo)的光標(biāo)在窗口的客戶區(qū)盤(pán)旋時(shí)發(fā)出的消息用戶區(qū)鼠標(biāo)消息對(duì)于鼠標(biāo)消息的處理要對(duì)Shift和Ctrl鍵進(jìn)行監(jiān)測(cè)監(jiān)測(cè)是否同時(shí)按下Ctrl鍵和Shift鍵:if(nFlags&MK_CONTROL)&&(nFlags&MK_SHIFT))

… //Shift和Ctrl鍵都被按下

不監(jiān)測(cè)在按下鼠標(biāo)左鍵的時(shí)候,系統(tǒng)會(huì)創(chuàng)建一個(gè)單擊鼠標(biāo)左鍵的消息響應(yīng)函數(shù),具體如下:OnLButtonDown(UINTnFlags,CPointpoint)Windows系統(tǒng)默認(rèn)的時(shí)間間隔為0.5秒,也可以調(diào)用SetDoubleClickTime()重新設(shè)定間隔值若窗口不包含上述屬性的定義,即使進(jìn)行了雙擊操作,該窗口也只能接收到兩條WM_BUTTONDOWN消息或兩條WM_BUTTONUP消息。鼠標(biāo)雙擊wndclass.style=CS_HEADRAW|CS_VERDRAW|CS_DBLCLKS;要使窗口函數(shù)能接收鼠標(biāo)雙擊產(chǎn)生的消息在注冊(cè)窗口類(lèi)時(shí)必須具有CS_DBLCLKS屬性

由于鼠標(biāo)移動(dòng)的隨機(jī)性,如果要使某一個(gè)窗口能不間斷地捕獲鼠標(biāo)消息,就必須對(duì)鼠標(biāo)加以捕獲調(diào)用SetCapture()函數(shù)一旦從窗口捕獲了鼠標(biāo),系統(tǒng)的鍵盤(pán)功能就暫時(shí)失效,其它窗口也無(wú)法得到鼠標(biāo)消息當(dāng)該窗口不再需要捕獲鼠標(biāo)消息時(shí),應(yīng)及時(shí)調(diào)用ReleaseCapture()以釋放鼠標(biāo),否則,其他窗口無(wú)法接收鼠標(biāo)信息。菜單、滾動(dòng)條工具條和標(biāo)題條等處不由應(yīng)用程序處理而是送往函數(shù)DefWindowProc用戶區(qū)以外的地方產(chǎn)生的鼠標(biāo)事件產(chǎn)生一個(gè)非用戶區(qū)鼠標(biāo)消息4.4鼠標(biāo)應(yīng)用程序?qū)嵗纠?-3】設(shè)計(jì)一個(gè)鼠標(biāo)程序,在按下Ctrl鍵的同時(shí)按下鼠標(biāo)左鍵,在窗口中拖動(dòng)鼠標(biāo),可畫(huà)出一個(gè)圓;在按下Shift鍵的同時(shí)按下鼠標(biāo)左鍵,在窗口中拖動(dòng)鼠標(biāo),畫(huà)出一個(gè)矩形。首先在窗口處理函數(shù)中加入兩個(gè)靜態(tài)BOOL變量:bCircle,bRect,此兩個(gè)變量用來(lái)標(biāo)志當(dāng)前所繪的是圓形還是矩形,還要定義全局變量矩形結(jié)構(gòu)體rect1用來(lái)記錄圓形和矩形的信息。對(duì)于這個(gè)問(wèn)應(yīng)考慮如下幾個(gè)方面:創(chuàng)建基于對(duì)話框的應(yīng)用程序4_3,添加類(lèi)成員變量如下:CDC*hDC;RECTrect1; //定義矩形結(jié)構(gòu)體.記錄了圖形的信息intx,y; //定義鼠標(biāo)的位置坐標(biāo)BOOLbCircle=FALSE,bRect=FALSE;//設(shè)置繪制圓和矩形的標(biāo)志變量(2)依次響應(yīng)按下鼠標(biāo)左鍵及鼠標(biāo)移動(dòng)的消息響應(yīng):voidCMy43Dlg::OnLButtonDown(UINTnFlags,CPointpoint){GetCursorPos(&point); //獲取當(dāng)前光標(biāo)的位置ScreenToClient(&point); //將屏幕坐標(biāo)轉(zhuǎn)換為窗口坐標(biāo)if(nFlags&MK_CONTROL) //同時(shí)按下Ctrl鍵時(shí){bCircle=TRUE; //畫(huà)圓bRect=FALSE;rect1.left=point.x; //圓的左上角坐標(biāo)為當(dāng)前鼠標(biāo)位置rect1.top=point.y;}elseif(nFlags&MK_SHIFT) //同時(shí)按下shift鍵時(shí){bRect=TRUE; //畫(huà)矩形bCircle=FALSE;rect1.left=point.x;//矩形的左上角坐標(biāo)為當(dāng)前鼠標(biāo)位置rect1.top=point.y;}else{ bRect=FALSE; bCircle=FALSE;}CDialogEx::OnLButtonDown(nFlags,point);}voidCMy43Dlg::OnLButtonUp(UINTnFlags,CPointpoint){ bRect=FALSE;

bCircle=FALSE; CDialogEx::OnLButtonUp(nFlags,point);}

在OnLButtonUp函數(shù)中,當(dāng)鼠標(biāo)左鍵抬起后,表征矩形的變量bRect和表征橢圓的變量bRect均設(shè)置為FALSE。voidCMy43Dlg::OnMouseMove(UINTnFlags,CPointpoint){

GetCursorPos(&point); //獲取當(dāng)前光標(biāo)的位置ScreenToClient(&point); //將屏幕坐標(biāo)轉(zhuǎn)換為窗口坐標(biāo)rect1.right=point.x;//圖形的右下角坐標(biāo)為當(dāng)前鼠標(biāo)位置

rect1.bottom=point.y;if(bRect==TRUE||bCircle==TRUE)//任一個(gè)參數(shù)為真就發(fā)送刷新請(qǐng)求 Invalidate(); //發(fā)出重繪信息CDialogEx::OnMouseMove(nFlags,point);}最后還需要響應(yīng)刷新函數(shù)

voidCMy43Dlg::OnPaint(){CPaintDCdc(this); //用于繪制的設(shè)備上下文hDC=GetDC();if(bCircle==TRUE) //繪制圓形

hDC->Ellipse(rect1.left,rect1.top,rect1.right,rect1.bottom);if(bRect==TRUE) //繪制矩形

hDC->Rectangle(rect1.left,rect1.top,rect1.right,rect1.bottom);}【例4-4】編寫(xiě)一個(gè)應(yīng)用程序,其中,要求鼠標(biāo)的光標(biāo)始終指向一個(gè)字符串的起始位置,隨著鼠標(biāo)的移動(dòng),字符串跟隨移動(dòng),而且字符串的顏色在整個(gè)字符串中實(shí)現(xiàn)漸變。1:創(chuàng)建基于對(duì)話框的應(yīng)用程序4_4,添加類(lèi)成員變量如下:CDC*hDC;HFONThF; //定義字體句柄TCHARstr[20]=_T("VisualC++"); //輸出的字符串inti=0;intx[11],y[11],color[11];//字符所在位置的坐標(biāo)以及設(shè)置的顏色POINTpt; //記錄鼠標(biāo)所在的位置2:在對(duì)話框的4_4Dle.cpp文件中定義創(chuàng)建自定義字體的函數(shù)原型:HFONTCreateFont(intnCharHeight,BOOLbItalic);

這先定義函數(shù)原型,函數(shù)的完整實(shí)現(xiàn),在程序的最后面。3:在初始化函數(shù)中進(jìn)行如下操作:SetTimer(1000,500,NULL);//設(shè)置計(jì)時(shí)器ID為1000,每隔500毫秒發(fā)送一個(gè)TIMER消息GetCursorPos(&pt); //獲取當(dāng)前鼠標(biāo)箭頭的的位置ScreenToClient(&pt); //將屏幕坐標(biāo)轉(zhuǎn)換為窗口坐標(biāo)for(i=1;i<11;i++) //初始化表示位置的數(shù)組和顏色{x[i]=pt.x+(i-1)*10;y[i]=pt.y;color[i]=25*(i-1);}這里需要獲取鼠標(biāo)箭頭的位置,第一個(gè)字符就在鼠標(biāo)箭頭的位置,在for循環(huán)中,定義了數(shù)組元素所存放的字符的位置以及定義的顏色4:響應(yīng)定時(shí)器函數(shù),添加如下斜體加粗的代碼如下:voidCMy44Dlg::OnTimer(UINT_PTRnIDEvent){if(nIDEvent==1000)Invalidate(); CDialogEx::OnTimer(nIDEvent);}5:編寫(xiě)自定義字體的函數(shù),代碼如下:HFONTCreateFont(intnCharHeight,BOOLbItalic){HFONThFont;hFont=CreateFont( //定義字體句柄 nCharHeight, //字體高度 0, //系統(tǒng)根據(jù)高寬比選取字體最佳寬度值 0, //文本傾斜度,表示水平 0, //字體傾斜度為 400, //字體粗度,為正常 bItalic, //是斜體字 0, //無(wú)下劃線 0, //無(wú)刪除線 ANSI_CHARSET, //ANSI_CHARSET字符集 OUT_DEFAULT_PRECIS, //刪除精度為默認(rèn)值 CLIP_DEFAULT_PRECIS, //裁剪精度為默認(rèn)值 DEFAULT_QUALITY, //輸出質(zhì)量為默認(rèn)值 DEFAULT_PITCH|FF_DONTCARE, //字間距 _T("Arial")); //字體名稱(chēng) if(hFont==NULL)returnNULL; else returnhFont;}6:編寫(xiě)刷新函數(shù),添加如下斜體加粗的代碼:voidCMy44Dlg::OnPaint(){CPaintDCdc(this); //用于繪制的設(shè)備上下文hDC=GetDC(); //獲得設(shè)備環(huán)境指針hF=CreateFont(30,0); //創(chuàng)建字體hDC->SelectObject(hF); //選入字體for(i=10;i>0;i--) //調(diào)整每個(gè)字的位置,后一個(gè)字的位置調(diào)整到前一個(gè)字的位置{x[i]=x[i-1]+30;y[i]=y[i-1];}GetCursorPos(&pt);ScreenToClient(&pt);x[0]=pt.x;y[0]=pt.y;//第一個(gè)字位置是當(dāng)前鼠標(biāo)的位置,這樣所有的字就會(huì)跟隨鼠標(biāo)不斷移動(dòng)for(i=1;i<11;i++){hDC->SetTextColor(RGB(255-color[i],color[i],255));//字體顏色hDC->TextOut(x[i],y[i],&str[i],1);//輸出從第1到第nChar個(gè)字符}

color[1]=color[10]; //把最后一個(gè)字符的顏色值賦給第一個(gè)字符for(i=10;i>1;i--) //調(diào)整顏色,使顏色不斷循環(huán)變化 color[i]=color[i-1];DeleteObject(hF); //刪除字體句柄ReleaseDC(hDC); //刪除設(shè)備用戶指針}為了實(shí)現(xiàn)顏色循環(huán),上述代碼中的語(yǔ)句“color[1]=color[10];”是重要的,如果不把最后一個(gè)字符的顏色值賦給第一個(gè)字符,那么久無(wú)法實(shí)現(xiàn)顏色循環(huán)。【例4-5】編寫(xiě)一個(gè)鼠標(biāo)應(yīng)用程序,按下鼠標(biāo)左鍵在窗口中移動(dòng)時(shí),將按下左鍵時(shí)所在點(diǎn)和當(dāng)前點(diǎn)所形成的矩形涂成灰色,此時(shí)光標(biāo)為十字型。當(dāng)抬起鼠標(biāo)左鍵時(shí),將前面所繪制的矩形拉伸到整個(gè)窗口,拉伸過(guò)程中將光標(biāo)設(shè)置為等待光標(biāo)。然后,若雙擊鼠標(biāo)的左鍵,則灰色消失,窗口恢復(fù)到初始狀態(tài)。1:添加如下類(lèi)成員: CDC*hdc; //創(chuàng)建DC句柄 HBRUSHhBrush; //創(chuàng)建畫(huà)刷2:在4_5Dlg.cpp文件中添加如下全局變量: BOOLoperate=FALSE,ready=TRUE;

//用來(lái)記錄是否處于操作狀態(tài)或準(zhǔn)備操作狀態(tài) POINTBeginP,EndP; //記錄矩形的起始點(diǎn)和終止點(diǎn)坐標(biāo) RECTrect={0,0,0,0}; //定義一個(gè)矩形區(qū)域3:由于要進(jìn)行如題目要求的鼠標(biāo)操作,因此需要通過(guò)“類(lèi)向?qū)А庇成淙缦孪㈨憫?yīng)函數(shù),他們分別是鼠標(biāo)左鍵單擊、鼠標(biāo)移動(dòng)、鼠標(biāo)左鍵彈起和鼠標(biāo)左鍵雙擊,此時(shí)在類(lèi)的頭文件中會(huì)出現(xiàn)以下的函數(shù):afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);afx_msgvoidOnMouseMove(UINTnFlags,CPointpoint);afx_msgvoidOnLButtonUp(UINTnFlags,CPointpoint);afx_msgvoidOnLButtonDblClk(UINTnFlags,CPointpoint);4:畫(huà)圖過(guò)程需要刷新,因此需要定義刷新處理函數(shù),具體代碼如下:voidCMy45Dlg::OnPaint(){CPaintDCdc(this);//用于繪制的設(shè)備上下文if(ready==FALSE) {hdc=GetDC();

hBrush=(HBR

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論