版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第5講 Windows應(yīng)用程序中的鍵盤與鼠標工控機和上位軟件討論:討論上位系統(tǒng):WINCC LABVIEW INTOUCH MATLAB VB VC群 號:20423623電子學(xué)習(xí)共同促進群學(xué)習(xí)探討單片機 電子線路等電子技術(shù)。群 號:234742235電氣制圖軟件交流促進群 號:182667049自動化行業(yè)非標PLC編程群 號:170665069 掃描碼是依賴于具體設(shè)備的,為達到設(shè)備無關(guān)性的要求,往往使用與具體設(shè)備無關(guān)的虛擬碼,虛擬碼是由Windows系統(tǒng)定義的與設(shè)備無關(guān)的鍵的標識由于鍵盤的輸入產(chǎn)生一條消息掃描碼、虛擬碼以及其他與擊鍵有關(guān)的消息設(shè)備驅(qū)動程序截取鍵的掃描碼翻譯虛擬碼它含鍵盤上的鍵
2、對應(yīng)一個唯一的標識值(掃描碼)按下或釋放某鍵時產(chǎn)生取出鍵盤消息進行處理消息設(shè)備驅(qū)動程序把消息放到系統(tǒng)的消息隊列中Windows從系統(tǒng)消息隊列中取出消息發(fā)送到相應(yīng)的線程消息隊列中窗口過程6.1 鍵盤在應(yīng)用程序中的應(yīng)用鍵盤上每一個鍵都有一個唯一值,這個唯一值就稱為“掃描碼”(scan code),對于鍵盤上每個鍵來說,“掃描碼”是設(shè)備相關(guān)的。當(dāng)用戶按鍵時會產(chǎn)生兩次掃描碼,一次是按下鍵時,一次是放開時。 然后,鍵盤驅(qū)動把掃描碼解釋并轉(zhuǎn)換(映射)為“虛鍵碼”(virtual-key code),這個碼是設(shè)備無關(guān)的,其值被系統(tǒng)所定義并用來標識每一個鍵。轉(zhuǎn)換掃描碼后,鍵盤布局會創(chuàng)建一個包含掃描碼、虛鍵碼以
3、及其他按鍵信息的消息,并把這個消息放入系統(tǒng)消息隊列。接著,系統(tǒng)從系統(tǒng)消息隊列中刪除該消息,再投遞到相應(yīng)線程的消息隊列中。最后,線程的消息循環(huán)移除該消息并傳遞到相應(yīng)窗口過程以進行處理。 虛擬碼是一種與設(shè)備無關(guān)的鍵盤編碼,它的值存放在鍵盤消息的wParam參數(shù)中,用以標識哪一個鍵被按下或釋放,最常用的虛擬碼已經(jīng)在Windows.h中定義,鍵盤消息按鍵消息字符消息按下或松開一個鍵時就產(chǎn)生了一按鍵消息一個按鍵的組合產(chǎn)生了一個可以顯示的字符時,就產(chǎn)生了一個字符消息”A”=shift+”a”系統(tǒng)按鍵消息非系統(tǒng)按鍵消息Alt鍵與相關(guān)輸入鍵的組合產(chǎn)生的消息,這些鍵一般由Windows系統(tǒng)內(nèi)部直接處理,應(yīng)用程序
4、不處理若應(yīng)用程序處理了這些系統(tǒng)鍵消息,還要調(diào)用DefWindowsProc()函數(shù),以便不影響系統(tǒng)對它們的處理不使用Alt鍵組合的的按鍵消息按鍵消息的兩個變量wParamlParam32位的變量重復(fù)計數(shù)位(015位)OEM掃描碼(1623位)擴展鍵標志(24位)保留位(2528位)關(guān)聯(lián)碼(29位)鍵的先前狀態(tài)(位30)轉(zhuǎn)換狀態(tài)(31位)包含了識別按下的鍵的虛鍵碼擴充鍵標志擴充鍵標志用來標識按鍵消息中是否包含了增強型鍵盤的附加鍵,這些擴充鍵包括:鍵盤右手邊的ALT、CTRL鍵,INS、DEL、HOME、END、PAGE UP、PAGE DOWN,小鍵盤左邊的方向鍵,NUM LOCK、BREAK(
5、CTRL+PAUSE)、PRINT SCRNT以及小鍵盤上的除號(/)鍵及ENTER鍵。如果鍵為以上鍵的話,擴充鍵標志即會設(shè)置。上下文標志上下文標志是為了說明按鍵消息產(chǎn)生時,ALT鍵是否已經(jīng)按下,如果為1,表示ALT鍵已經(jīng)按下,否則沒有按下。前鍵狀態(tài)標志前鍵狀態(tài)標志用來說明產(chǎn)生按鍵消息的鍵原來是抬起的還是按下的。如果為1,表示原來是按下的,0原來是抬起的。你可以通過該標志來辨別該消息是否是由鍵盤自動重復(fù)機制產(chǎn)生的。如果為1,表示W(wǎng)M_KEYDOWN與WM_SYSKEYDOWN消息是自動產(chǎn)生的,對于WM_KEYUP與WM_SYSKEYUP消息來說,該標志總會為0。轉(zhuǎn)換狀態(tài)標志轉(zhuǎn)換狀態(tài)標志用來說明
6、該消息是按下鍵時還是釋放鍵時產(chǎn)生的,對于WM_KEYDOWN、WM_SYSKEYDOWN來說該標志總會為0,對于WM_KEYUP、WM_SYSKEYUP總會是1。 在WinMain函數(shù)的消息循環(huán)中包含了TranslateMessage函數(shù),其功能是把按鍵消息轉(zhuǎn)化為字符消息,但只有當(dāng)鍵盤驅(qū)動程序把鍵盤字符映射成ASCII碼后才能產(chǎn)生WM_CHAR消息字符消息系統(tǒng)非系統(tǒng)WM_KEYDOWN和WM_KEYUP的按鍵消息只能產(chǎn)生非系統(tǒng)消息WM_SYSKEYDOWN和WM_SYSKEYUP按鍵消息只能產(chǎn)生系統(tǒng)消息消息循環(huán)中 while(GetMessage(&Msg,NULL,0,0) Translat
7、eMessage(&Msg);/翻譯消息 DispatchMessage(&Msg);/將消息傳遞給窗口處理函數(shù) return Msg.wParam; TranslateMessage函數(shù)首先將按健消息轉(zhuǎn)換成字符消息,最后WndProc函數(shù)中進行case選擇。 WM_CHAR能區(qū)分1和! WM_KEYDOWN只處理某個按鍵所以ctrl+E 選WM_KEYDOWN WM_KEYDOWN和WM_CHAR的區(qū)別1、WM_KEYDOWN按下任何鍵都發(fā),WM_CHAR是按下可顯示的符號鍵才有.2、有時用戶按動一下某個鍵, 我們想得到一條表示用戶輸入了某個字符的消息,并在消息補充參數(shù)中提供字符的編碼。Tr
8、anslateMessage能將可行的WM_KEYDOWN, WM_KEYUP消息對轉(zhuǎn)換成一條WM_CHAR消息,當(dāng)按鍵被釋放,Windows會發(fā)送一個WM_KEYUP消息。如果按鍵按的時間長一些,則自動重復(fù)功能就會開啟,多條WM_KEYDOWN消息和WM_CHAR消息會被送出,直到最后鍵被釋放,發(fā)出WM_KEYUP消息。當(dāng)Alt鍵和另一個鍵一起被按下時,上面討論的消息會被WM_SYSKEYDOWN、WM_SYSKEYCHAR和WM_SYSKEYUP消息替代轉(zhuǎn)換過程不會影響原來的消息,只在消息隊列中增加新消息。4、對于WM_KEYDOWN消息中的wParam,假如用到控制鍵如ctrl的時候,可
9、以用VK_CONTROL來表示 /假如用到字母鍵和數(shù)字鍵的時候,(如q)可以用Q來表示,(又如2)可以用2來表示。5、WM_CHAR消息的lParam參數(shù)的含義與其它鍵盤消息一樣, 而它的wParam則表示相應(yīng)字符的ASCII編碼 .6、WM_CHAR消息是俘獲某一個字符的消息,WM_KEYDOWN消息是俘獲某一個鍵按下的消息 /假如分別按下“q”和“shift+q”,發(fā)出的WM_KEYDOWN消息都是代表q鍵,而發(fā)出的WM_CHAR消息分別是“q”和“Q” 7、WM_KEYDOWN消息可以處理鍵盤上的所有鍵,但不能區(qū)分1和!的不同,WM_CHAR消息只能處理某個字符,將1和!作為兩個不同的字
10、符來處理8、對WM_CHAR和WM_SYSCHAR消息來說,wParam的低四位為按鍵的ASCII值,如果該值大于 127表示為中文,和下一個WM_CHAR消息一起組成一個漢字. lParam為該按鍵按的數(shù)次。 多數(shù)情況下,應(yīng)用程序只是處理WM_CHAR消息,而忽略WM_KEYDOWN和WM_KEYUP消息。WM_CHAR消息作為第2級抽象,使應(yīng)用程序不必考慮鍵的釋放或按下狀態(tài),而將精力集中在鍵盤輸入的字符上。WM_CHAR、WM_KEYDOWN、WM_KEYUP這三個消息用來處理用戶的鍵盤數(shù)據(jù),當(dāng)用戶在鍵盤上按下某個鍵的時候,會產(chǎn)生WM_KEYDOWN消息,釋放按鍵的時候又回產(chǎn)生WM_KEY
11、UP消息,所以WM_KEYDOWN與WM_KEYUP消息一般總是成對出現(xiàn)的.至于WM_CHAR消息是在用戶的鍵盤輸入能產(chǎn)生有效的ASCII碼時才會發(fā)生。這里特別提醒要注意前兩個消息與WM_CHAR消息在使用上是有區(qū)別的。在前兩個消息中,伴隨消息傳遞的是按鍵的虛擬鍵碼,所以這兩個消息可以處理非打印字符,如方向鍵,功能鍵等。而伴隨WM_CHAR消息的參數(shù)是所按的鍵的ASCII碼,ASCII碼是可以區(qū)分字母的大小寫的。而虛擬鍵碼是不能區(qū)分大小寫的。按鍵的次序不同,產(chǎn)生的消息也不相同。例如:1、按下并釋放1鍵,讀過程依次產(chǎn)生如表所示三條消息。按下1鍵所產(chǎn)生的消息和wParam的取值消息 wParam變
12、量取值 WM_KEYDOWN 虛擬碼1 WM_CHAR ASCII碼“1” WM_KEYUP 虛擬碼1 2、如果按下Shift鍵后再按下1鍵并釋放,則依次產(chǎn)生如表所示的消息。按下 Shift鍵后按 1健所產(chǎn)生的消息和 wParam的取值消息 wParam變量取值 WM_KEYDOWN 虛擬碼 VK_SHIFT WM_KEYDOWN 虛擬碼 VK_1 WM_CHAR ASCII碼“1” WM_KEYUP 虛擬碼 VK_1 WM_KEYUP 虛擬碼 VK_SHIFT 復(fù)合鍵問題使用復(fù)合鍵不但能減少按鍵數(shù)目,而且操作安全性好,對一些重要操作用復(fù)合鍵可以減少誤碰鍵盤引起的差錯。復(fù)合鍵是利用兩個以上的按
13、鍵同時按下所完成的功能,但實際情況中很難實現(xiàn)真正的“同時按下”,它們的時間差別可以長到50ms左右,這對計算機來說是足夠長了,完全可能產(chǎn)生額外的動作。對WM_CHAR和WM_SYSCHAR消息來說,wParam包含鍵對應(yīng)的Unicode字符。多數(shù)情況下,應(yīng)用程序只是處理WM_CHAR消息,而忽略WM_KEYDOWN和WM_KEYUP消息。WM_CHAR消息作為第2級抽象,使應(yīng)用程序不必考慮鍵的釋放或按下狀態(tài),而將精力集中在鍵盤輸入的字符上。【6-1】 設(shè)計一個窗口,在該窗口中練習(xí)鍵盤的響應(yīng),要求如下:(1) 單擊鍵盤上的向上箭頭時,窗口中顯示“You had hitted the up key
14、”(2) 單擊鍵時,窗口中顯示“You had hitted the SHIFT key”(3) 單擊鍵時,窗口中顯示“You had hitted the CTRL key”(4) 單擊鍵時,窗口中顯示“You had hitted the CTRL A key”(5) 單擊鍵時,窗口中顯示“You had hitted the SHIFT B key”long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam)HDC hDC;/定義設(shè)備環(huán)境句柄. PAINTSTRUCT ps;/定義包含繪圖信息的結(jié)構(gòu)體變量 HPE
15、N hPen;/定義畫筆句柄。 HBRUSH hBrush;/定義畫刷句柄 /以下定義輸出的字符串。 static char cUp=You had hitted the UP key; static char cCtrl=You had hitted the Ctrl key; static char cShift=You had hitted the SHIFT key; static char cCtrl_A=You had hitted the CTRL A key; static char cShift_B=You had hitted the SHIFT B key;/下面定義并初
16、始化按鍵標志變量。 static BOOL nUpKeyDown=FALSE, nShiftKeyDown=FALSE, nCtrlKeyDown=FALSE, nCtrlAKeyDown=FALSE, nShiftBKeyDown=FALSE; switch(iMessage) case WM_KEYDOWN: switch(wParam) case VK_UP:/當(dāng)按上箭頭鍵時,變量置為真。nUpKeyDown = TRUE; break; case VK_SHIFT:/當(dāng)按shift鍵時,變量置為真。nShiftKeyDown = TRUE; break; case VK_CONTROL
17、:/當(dāng)按control鍵時,變量置為真nCtrlKeyDown = TRUE; break; default: break; break; case WM_KEYUP:InvalidateRect(hWnd,NULL,FALSE);break;/輸出信息。if(nUpKeyDown = TRUE) Rectangle(hDC,0,0,300,200); TextOut(hDC,0,0,cUp,strlen(cUp); nUpKeyDown = FALSE; else if(nCtrlAKeyDown = TRUE) Rectangle(hDC,0,0,300,200);TextOut(hDC,
18、0,100,cCtrl_A,strlen(cCtrl_A);nCtrlAKeyDown = FALSE;nCtrlKeyDown = FALSE;else if(nCtrlAKeyDown = TRUE) else if(nCtrlKeyDown = TRUE&nCtrlAKeyDown = FALSE)Rectangle(hDC,0,0,300,200);TextOut(hDC,0,60,cCtrl,strlen(cCtrl);nCtrlKeyDown = FALSE;else if(nShiftBKeyDown = TRUE) Rectangle(hDC,0,0,300,200);Text
19、Out(hDC,0,0,cShift_B,strlen(cShift_B);nShiftBKeyDown = FALSE;nShiftKeyDown = FALSE;else if(nShiftBKeyDown = FALSE&nShiftKeyDown = TRUE)Rectangle(hDC,0,0,300,200);TextOut(hDC,0,0,cShift,strlen(cShift);nShiftKeyDown = FALSE;ElseTextOut(hDC,0,0,Input Error!n,13);break;/刪除畫筆和畫刷DeleteObject(hPen);DeleteO
20、bject(hBrush);EndPaint(hWnd,&ps);break;case WM_DESTROY:PostQuitMessage(0);return 0;default:return(DefWindowProc(hWnd,iMessage,wParam,lParam);return 0;long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam)#define BufSize 15/設(shè)置存放字符的緩沖區(qū)大小static char cCharBufBufSize;/設(shè)置靜態(tài)字符數(shù)組,存放輸入的字符,字符個數(shù)不
21、能超出緩沖區(qū)大小static int nNumChar=0;/現(xiàn)有字符個數(shù)static int nArrayPos=0;/字符的位置static int nLnHeight;static int nCharWidth;int x;HDC hDC;TEXTMETRIC tm;PAINTSTRUCT PtStr; /定義指向包含繪圖信息的結(jié)構(gòu)體變量 switch(iMessage) /處理消息case WM_CHAR: /遇到非系統(tǒng)字符所作的處理if(wParam=VK_BACK) /處理“遇到回退鍵的消息”if(nArrayPos=0) /若已在一行文字的開始處,則提示用戶不能回退 Messag
22、eBox(hWnd,當(dāng)前位置是文本的起始位置,不能回退,NULL,MB_OK); else nArrayPos=nArrayPos-1; /每按一次回退鍵就回退一個字符的位置 nNumChar=nNumChar-1;/對現(xiàn)有字符總數(shù)進行計數(shù) InvalidateRect(hWnd,NULL,TRUE);/刷新用戶區(qū),并序發(fā)送WM_PAINT消息 break;if(wParam=VK_ESCAPE) /處理按下Escape鍵消息MessageBox(hWnd,您現(xiàn)在不能按ESC鍵,請繼續(xù)其它操作,NULL,MB_OK);break;if(nNumChar=BufSize) /如果寫入的字符數(shù)超過
23、緩沖區(qū)大小,則報警MessageBox(hWnd,緩沖區(qū)已滿,不能再輸入字符了n若需要刪除字符,請用BackSpace鍵,NULL,MB_OK);break;for(x=nNumChar;xnArrayPos;x=x-1)cCharBufx=cCharBufx-1;cCharBufnArrayPos=(unsigned char)wParam;nArrayPos=nArrayPos+1;nNumChar=nNumChar+1;InvalidateRect(hWnd,NULL,TRUE);break; case WM_CREATE: /處理窗口創(chuàng)建消息 hDC=GetDC(hWnd); GetT
24、extMetrics(hDC,&tm); /獲取字體信息 nLnHeight=tm.tmHeight+tm.tmExternalLeading; nCharWidth=tm.tmAveCharWidth; ReleaseDC(hWnd,hDC); break;case WM_KEYDOWN: /處理按下鍵消息switch(wParam) case VK_END: /處理按下鍵為End時的消息nArrayPos=nNumChar;/輸入位置從本行的末尾開始break; case VK_HOME:/處理按下鍵為Home時的消息nArrayPos=0;/輸入位置為本行的起始位置break;case
25、VK_DELETE:/處理按下鍵為Delete時的消息 if(nArrayPos=nNumChar) /輸入位置處于本行的末尾 MessageBox(hWnd,緩沖區(qū)已空,沒有字符可供刪除,NULL,MB_OK); else for(x=nArrayPos;x0) nArrayPos=nArrayPos-1; /當(dāng)前輸入位置往前移一個位置 else MessageBox(hWnd,您已經(jīng)移動到起始位置,不能再往左移動了,NULL,MB_OK); break;case VK_RIGHT:/處理按下右方向鍵時的消息 if(nArrayPosnNumChar)/若當(dāng)前位置未到緩沖區(qū)的末尾,可向右移動
26、 nArrayPos=nArrayPos+1; else MessageBox(hWnd,已經(jīng)到緩沖區(qū)的末尾,不能再向右移動了,NULL,MB_OK); break; break; case WM_PAINT: /處理重畫消息 hDC=BeginPaint(hWnd,&PtStr); TextOut(hDC,nCharWidth,nLnHeight,cCharBuf,nNumChar); /輸出文本 EndPaint(hWnd,&PtStr); break;case WM_DESTROY: /處理結(jié)束應(yīng)用程序消息 PostQuitMessage(0);/結(jié)束應(yīng)用程序 break;default
27、:/其他消息處理程序 return(DefWindowProc(hWnd,iMessage,wParam,lParam) ; return 0;6.3 鼠標在應(yīng)用程序中的應(yīng)用鼠標作為定位輸入設(shè)備,通過鼠標單擊、雙擊和拖動功能,用戶可以很容易地操作基于Windows圖形界面的應(yīng)用程序。Windows中通過光標來指示當(dāng)前鼠標的位置,在Windows操作系統(tǒng)中預(yù)定義了幾種光標,并在Windows.h頭文件中加以定義,鼠標常用操作單擊(Click) 按下并迅速釋放鼠標按鈕。 雙擊(Double Click) 連續(xù)快速完成兩次單擊操作。 移動(Move) 鼠標光標移動。 拖動(Drag) 按下鼠標一鍵不
28、放,同時執(zhí)行鼠標移動操作。 與鍵盤的特殊鍵組合 在按下Ctrl鍵或Shift鍵的同時執(zhí)行鼠標單擊操作。其中,前三種操作是最為基本的操作,可以產(chǎn)生Windows內(nèi)部定義的消息,并通過這些消息來判斷用戶具體執(zhí)行了哪種操作。 消息常量WM_MOUSEMOVE 移動鼠標 WM_LVBUTTONDOWN 按下鼠標左鍵 WM_LBUTTONUP 釋放鼠標左鍵 WM_LBUTTONDBLCLK 雙擊鼠標左鍵 WM_RVBUTTONDBLCLK 按下鼠標右鍵 WM_RBUTTONUP 釋放鼠標右鍵 WM_RBUTTONDBLCLK 雙擊鼠標右鍵 WM_MVBUTTONDOWM 按下鼠標中鍵 WM_MBUTTO
29、NUP 釋放鼠標中鍵 WM_MBUTTONDBLCLK 雙擊鼠標中鍵 對于鼠標操作中的最后兩種,不能直接使用Windows定義的消息來判斷,只能通過編程,將多種消息和數(shù)據(jù)組合之后判斷。 例如:1、判斷用戶是否按下鼠標左鍵之后進行拖動操作可以通過以下程序段來實現(xiàn),用case語句來實現(xiàn): case WM_MOUSEMOVE:if (wParam&MK_LBUTTON) /只處理鼠標拖動的消息 / 處理程序 在處理鼠標消息的過程中,消息的wParam參數(shù)和lParam參數(shù)起了重要的作用。wParam參數(shù)中保存了在消息產(chǎn)生時其他操作進行的狀態(tài);用戶可以通過位屏蔽操作來判斷在該消息產(chǎn)生的同時,其余操作是
30、否正在進行。這正是在程序中判斷復(fù)雜鼠標操作的基本方法。例如,上面判斷拖動操作的程序段就用了位操作 wParam MK_LBUTTON, 判斷在鼠標移動(WM_MOUSEMOVE)的同時鼠標左鍵是否同時被接下。如果,鼠標左鍵同時按下,則位操作的結(jié)果為TRUE,說明當(dāng)前操作為拖動操作,程序可以繼續(xù)進行下一步處理 例子2、判斷單擊鼠標左鍵時是否同時按下了Ctrl鍵或Shift鍵,可以用以下程序段來處理:case WM_ LBUTTONDOWN:if(wParam MK_CTROL)/Ctrl鍵同時按下if (wParamMK_ SHIFT)/ Ctrl 鍵和Shift鍵都同時按下 / 處理程序els
31、e / Ctrl健同時按下,但 Shift鍵沒有被按下. / 處理程序else if(wParamMK_ SHIFT) / Shift鍵同時按下,但 Ctrl鍵沒有被接下 / 處理程序 else/ Shift 鍵和Ctrl鍵都未按下 / 處理程序 lParam參數(shù)保存了消息產(chǎn)生時鼠標所在點的坐標,其中低16位為X坐標,高16位為Y坐標 例如,下面的語句為窗口類wndclassWNDCLASS wndclass;wndclass.hCursor=LoadCursor (hThislnst, IDC_WAIT);此外,還可在應(yīng)用程序中調(diào)用LoadCursor函數(shù)改變光標形式用戶自定義光標 自定義光
32、標保存在擴展名為.cur的文件中 光標名 CURSOR 光標文件(.cur)采用自定義光標時,需在資源文件中定義光標資源加載光標資源(常在定義窗口類時進行) LoadCursor(hThisInst,lpszCursorname)當(dāng)前實例句柄當(dāng)前光標鼠標消息lParam包含了鼠標位置低位包含鼠標位置的x坐標值高位包含鼠標位置的y坐標wParam包含了指示各種虛鍵狀態(tài)的值相當(dāng)于窗口的左上角為原點的坐標值對于鼠標消息的處理要對Shift和Ctrl鍵進行監(jiān)測case WM_LBUTTONDOWN: /按下鼠標左鍵 if(wParam&MK_CONTROL)&(wParam&MK_SHIFT) /Sh
33、ift和Ctrl鍵都被按下 break;case WM_LBUTTONUP:/釋放鼠標左鍵 break; case WM_LBUTTONDOWN: /按下鼠標左鍵 break;case WM_LBUTTONUP:/釋放鼠標左鍵 break; 不監(jiān)測消息常量WM_MOUSEMOVE 移動鼠標 WM_LVBUTTONDOWN 按下鼠標左鍵 WM_LBUTTONUP 釋放鼠標左鍵 WM_LBUTTONDBLCLK 雙擊鼠標左鍵 WM_RVBUTTONDBLCLK 按下鼠標右鍵 WM_RBUTTONUP 釋放鼠標右鍵 WM_RBUTTONDBLCLK 雙擊鼠標右鍵 WM_MVBUTTONDOWM 按下
34、鼠標中鍵 WM_MBUTTONUP 釋放鼠標中鍵 WM_MBUTTONDBLCLK 雙擊鼠標中鍵 對于鼠標操作中的最后兩種,不能直接使用Windows定義的消息來判斷,只能通過編程,將多種消息和數(shù)據(jù)組合之后判斷。 例如:1、判斷用戶是否按下鼠標左鍵之后進行拖動操作可以通過以下程序段來實現(xiàn),用case語句來實現(xiàn): case WM_MOUSEMOVE:if (wParam&MK_LBUTTON) /只處理鼠標拖動的消息 / 處理程序 在處理鼠標消息的過程中,消息的wParam參數(shù)和lParam參數(shù)起了重要的作用。wParam參數(shù)中保存了在消息產(chǎn)生時其他操作進行的狀態(tài);用戶可以通過位屏蔽操作來判斷在
35、該消息產(chǎn)生的同時,其余操作是否正在進行。這正是在程序中判斷復(fù)雜鼠標操作的基本方法。例如,上面判斷拖動操作的程序段就用了位操作 wParam MK_LBUTTON, 判斷在鼠標移動(WM_MOUSEMOVE)的同時鼠標左鍵是否同時被接下。如果,鼠標左鍵同時按下,則位操作的結(jié)果為TRUE,說明當(dāng)前操作為拖動操作,程序可以繼續(xù)進行下一步處理 例子2、判斷單擊鼠標左鍵時是否同時按下了Ctrl鍵或Shift鍵,可以用以下程序段來處理:case WM_ LBUTTONDOWN:if(wParam MK_CTROL)/Ctrl鍵同時按下if (wParamMK_ SHIFT)/ Ctrl 鍵和Shift鍵都
36、同時按下 / 處理程序else / Ctrl健同時按下,但 Shift鍵沒有被按下. / 處理程序else if(wParamMK_ SHIFT) / Shift鍵同時按下,但 Ctrl鍵沒有被接下 / 處理程序 else/ Shift 鍵和Ctrl鍵都未按下 / 處理程序 lParam參數(shù)保存了消息產(chǎn)生時鼠標所在點的坐標,其中低16位為X坐標,高16位為Y坐標 Windows系統(tǒng)默認的時間間隔為0.5秒,也可以調(diào)用SetDoubleClickTime()重新設(shè)定間隔值若窗口不包含上述屬性的定義,即使進行了雙擊操作,該窗口也只能接收到兩條WM_BUTTONDOWN消息或兩條WN_BUTTONU
37、P消息。鼠標雙擊wndclass.style=CS_HEADRAW|CS_VERDRAW|CS_DBLCLKS;要使窗口函數(shù)能接收鼠標雙擊產(chǎn)生的消息在注冊窗口類時必須具有CS_DBLCLKS屬性 由于鼠標移動的隨機性,如果要使某一個窗口能不間斷地捕獲鼠標消息,就必須對鼠標加以捕獲SetCapture(hWnd):可以向句柄為hWnd的窗口發(fā)送所有的鼠標消息調(diào)用SetCapture()函數(shù)一旦從窗口捕獲了鼠標,系統(tǒng)的鍵盤功能就暫時失效,其它窗口也無法得到鼠標消息當(dāng)該窗口不再需要捕獲鼠標消息時,應(yīng)及時調(diào)用ReleaseCapture()以釋放鼠標,否則,其他窗口無法接收鼠標信息。菜單、滾動條工具條
38、和標題條等處不由應(yīng)用程序處理而是送往函數(shù)DefWindowProc用戶區(qū)以外的地方產(chǎn)生的鼠標事件產(chǎn)生一個非用戶區(qū)鼠標消息6.4 鼠標應(yīng)用程序?qū)嵗纠?-3】鼠標輸入示范程序,本例介紹如何響應(yīng)鼠標信息、并改變光標形狀等用法,用戶在窗口的不同區(qū)域移動鼠標時,光標將顯示如下圖所標識的不同箭頭的形狀#include#include LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpszCmdLine,int nCmdS
39、how) HWND hwnd;MSG Msg; WNDCLASS wndclass; char lpszClassName=窗口; char lpszTitle=My_Windows; wndclass.style=0; wndclass.lpszClassName=lpszClassName; if(!RegisterClass(&wndclass) MessageBeep(0); return FALSE; hwnd=CreateWindow(lpszClassName,lpszTitle,WS_VISIBLE|WS_SYSMENU|WS_MINIMIZEBOX,50,50,450,450
40、,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg,NULL,0,0) TranslateMessage(&Msg);DispatchMessage(&Msg);return Msg.wParam;LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)PAINTSTRUCT ps;HDC hdc;TEXTMETRIC tm;HBRUSH hbrush;HPE
41、N hpen;HCURSOR hcursor;char str15;static int x,y;switch(message) case WM_MOUSEMOVE:x=LOWORD(lParam);y=HIWORD(lParam);if(x50&x50&y150&x50&y250&x50&y50&x150&y50&x250&y150&x150&y250&x150&y150&x250&y250&x250&y350) hcursor=LoadCursor(NULL,IDC_SIZENS);SetCursor(hcursor); /南北向箭頭hdc=GetDC(hwnd);GetTextMetri
42、cs(hdc,&tm);hbrush=(HBRUSH)GetStockObject(WHITE_BRUSH);SelectObject(hdc,hbrush);hpen=(HPEN)GetStockObject(WHITE_PEN);SelectObject(hdc,hpen);Rectangle(hdc,5,5,tm.tmAveCharWidth*8,tm.tmHeight+3);sprintf(str,%d,%d0,x,y);TextOut(hdc,5,5,str,lstrlen(str);EndPaint(hwnd,&ps);break;case WM_PAINT:hdc=BeginPa
43、int(hwnd,&ps);hpen=(HPEN)GetStockObject(BLACK_PEN);SelectObject(hdc,hpen);Rectangle(hdc,50,50,350,350);MoveToEx(hdc,50,150,NULL);LineTo(hdc,350,150);MoveToEx(hdc,50,250,NULL);LineTo(hdc,350,250);MoveToEx(hdc,150,50,NULL);LineTo(hdc,150,350);MoveToEx(hdc,250,50,NULL);LineTo(hdc,250,350);EndPaint(hwnd
44、,&ps);break;case WM_DESTROY:PostQuitMessage(0);default: return DefWindowProc(hwnd,message,wParam,lParam); return(0);邏輯坐標與設(shè)備坐標的使用一旦設(shè)置了設(shè)備環(huán)境的映射模式,則對大多數(shù)(并不是所有的)CDC成員函數(shù)來說,我們就可以以邏輯坐標為其參數(shù).1、windows鼠標消息(如onlbuttondown的point參數(shù))所獲得的鼠標指針的坐標值是設(shè)備坐標。許多其他的MFC庫函數(shù),尤其是類CRect的成員函數(shù),則只能在設(shè)備坐標下才能正確工作;2、CDC 的所有成員函數(shù)都以邏輯坐標作為
45、其參數(shù);3、CWnd的成員函數(shù)都以設(shè)備坐標作為其參數(shù);4、區(qū)域的定義采用設(shè)備坐標;某些像CRect:PtInrect之類的函數(shù)只有在設(shè)備坐標下才會保證有正確的結(jié)果;如:我們需要知道當(dāng)用戶按下鼠標左鍵時,鼠標指針是否落在某個矩形之內(nèi),則可用如下的代碼:Void cMyView :OnLButtonDown(UNIT nFlags,CPoint point)CRECT rect=m_rect;CClientDC dc(this);dc.SetMapMode(MM_LOENGLISH);dc.LPTODP(rect);If(rect.PtInRect(point)TRACE(“Mouse curso
46、r is inside the rectangle.n”);【6-4】編寫一個鼠標應(yīng)用程序,按下鼠標左鍵在窗口中移動時,將按下左鍵時所在點和當(dāng)前點所形成的矩形涂成灰色,此時光標為十字型。當(dāng)抬起鼠標左鍵時,將前面所繪制度矩形拉伸到整個窗口,拉伸過程中將光標設(shè)置為沙漏型。然后,若雙擊鼠標的左鍵,則灰色消失,窗口恢復(fù)到初始狀態(tài)。void InvertBlock (HWND hwnd, POINT ptBeg, POINT ptEnd) HDC hdc ; hdc = CreateDC (DISPLAY, NULL, NULL, NULL) ; ClientToScreen (hwnd, &ptBeg) ;/轉(zhuǎn)換指定窗口的客戶區(qū)內(nèi)的點的坐標,上下文是windows ClientToScreen (hwnd, &ptEnd) ;/將客戶區(qū)坐標轉(zhuǎn)換成屏幕windows坐標 PatBlt (hdc, ptBeg.x, ptBeg.y, ptEnd.x - ptBeg.x, ptEnd.y - ptBeg.y,DSTINVERT) ;/這個函數(shù)在矩形區(qū)內(nèi)用當(dāng)前的畫筆變換背景和前景*/ DeleteDC (hdc) ; LRESULT CALLBACK WndProc(HW
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 我的家鄉(xiāng)敘事課程設(shè)計
- 弦樂小夜曲課程設(shè)計
- 中西醫(yī)執(zhí)業(yè)醫(yī)師模擬試卷16
- 礦井灌漿設(shè)計課程設(shè)計
- 站姿坐姿課程設(shè)計
- 花藝烘焙課程設(shè)計
- 藥品驗收入門課程設(shè)計
- 互聯(lián)網(wǎng)行業(yè)安全管理實踐
- 領(lǐng)導(dǎo)班子與教學(xué)院校協(xié)調(diào)計劃
- 火災(zāi)中的風(fēng)險評估和分析培訓(xùn)
- 智能化手術(shù)室介紹strykerisuite課件
- 2023年非標自動化工程師年度總結(jié)及來年計劃
- 水利機械施工方案
- 廣東省佛山市南海區(qū)大瀝鎮(zhèn)2023-2024學(xué)年九年級上學(xué)期期中物理試卷
- ESD內(nèi)部審核日程計劃表+內(nèi)審檢查表+內(nèi)審報告全套資料
- HSK標準教程5下-課件-L
- 電腦基礎(chǔ)知識
- 工程竣工預(yù)驗收簽到表
- 靜鉆根植樁施工組織設(shè)計
- 工程精細化管理
- 小學(xué)音樂-(演唱)小拜年教學(xué)設(shè)計學(xué)情分析教材分析課后反思
評論
0/150
提交評論