免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
Windows消息處理

1,虛擬鍵(VK_*

鍵盤上每一個(gè)鍵對(duì)應(yīng)一個(gè)掃描碼,掃描碼是OEM廠商制定的,不同的廠商生產(chǎn)的鍵盤同樣一個(gè)按鍵的掃描碼都有可能出現(xiàn)不一致的情況,為了擺脫由于系統(tǒng)設(shè)備不一致的情況,通過(guò)鍵盤驅(qū)動(dòng)程序?qū)呙璐a映射為統(tǒng)一的虛擬鍵碼表示,從而達(dá)到所有的設(shè)備都有一個(gè)統(tǒng)一的虛擬鍵,比如回車鍵的虛擬鍵是VK_RETURN。

Windows定義的虛擬鍵都定義在WinUser.h這個(gè)頭文件里面,都是以VK_作為前綴。

 

2,激活/關(guān)閉窗口對(duì)鍵盤的消息

激活/關(guān)閉消息:WM_SETFOCUS/WM_KILLFOCUS

創(chuàng)建光標(biāo):CreateCaret(...)

設(shè)置光標(biāo)位置:SetCaretPos(…)

在窗口中顯示光標(biāo):ShowCaret(…)

銷毀光標(biāo):DestroyCaret()

 

3,鍵盤消息

1)字符消息

系統(tǒng)字符消息

WM_SYSCHAR:系統(tǒng)字符

WM_SYSDEADCHAR:系統(tǒng)死字符

非系統(tǒng)按鍵消息

WM_CHAR:非系統(tǒng)字符

WM_DEADCHAR:非系統(tǒng)死字符

2)按鍵消息

系統(tǒng)按鍵消息:與ALT鍵相組合的組合鍵(無(wú)論用戶處理否,都需要最后調(diào)用DefWindowProc(hWnd,iMessage,wParam,lParam))

WM_SYSKEYDOWN

WM_SYSKEYUP

非系統(tǒng)按鍵消息:

WM_KEYDOWN

WM_KEYUP

注意:

a)  除Print鍵之外都有“按下”消息。

b) 所有鍵都存在“彈起”消息。

c)  根據(jù)MSDN說(shuō)明,只有下面這些鍵才會(huì)產(chǎn)生字符消息:

  • 任何字符鍵
  • 回退鍵(BACKSPACE
  • 回車鍵(carriage return
  • ESC
  • SHIFT + ENTER linefeed 換行)
  • TAB

 

我們是怎么收到WM_CHAR的呢?就是因?yàn)槲覀冊(cè)谙⒀h(huán)時(shí)調(diào)用了TranslateMessage對(duì)鍵盤消息進(jìn)行翻譯,

如果消息為WM_KEYDOWN或者WM_SYSKEYDOWN,并且按鍵與位移狀態(tài)相組合產(chǎn)生一個(gè)字符,則TranslateMessage把字符消息放入消息隊(duì)列中。此字符消息將是GetMessage從消息隊(duì)列中得到的按鍵消息之后的下一個(gè)消息。

 

在我們處理這個(gè)消息時(shí),對(duì)應(yīng)的wParam不是虛擬鍵,而是ANSIUnicode字符代碼,一般情況下我們可以這樣用:  (TCHAR)wParam;

 

4,消息順序

因?yàn)門ranslateMessage函數(shù)從WM_KEYDOWN和WM_SYSKEYDOWN消息產(chǎn)生了字符消息,所以字符消息是夾在按鍵消息之間傳遞給窗口消息處理程序的。例如,如果Caps Lock未打開(kāi),而使用者按下再釋放A鍵,則窗口消息處理程序?qū)⒔邮盏饺绫?-10所示的三個(gè)消息:

 

表6-10

消息

按鍵或者代碼

WM_KEYDOWN

「A」的虛擬鍵碼(0x41)

WM_CHAR

「a」的字符代碼(0x61)

WM_KEYUP

「A」的虛擬鍵碼(0x41)

 

如果您按下Shift鍵,再按下A鍵,然后釋放A鍵,再釋放Shift鍵,就會(huì)輸入大寫的A,而窗口消息處理程序會(huì)接收到五個(gè)消息,如表6-11所示:

 

表6-11

消息

按鍵或者代碼

WM_KEYDOWN

虛擬鍵碼VK_SHIFT (0x10)

WM_KEYDOWN

「A」的虛擬鍵碼(0x41)

WM_CHAR

「A」的字符代碼(0x41)

WM_KEYUP

「A」的虛擬鍵碼(0x41)

WM_KEYUP

虛擬鍵碼VK_SHIFT(0x10)

 

Shift鍵本身不產(chǎn)生字符消息。

如果使用者按住A鍵,以使自動(dòng)重復(fù)產(chǎn)生一系列的按鍵,那么對(duì)每條WM_KEYDOWN消息,都會(huì)得到一條字符消息,如表6-12所示:

 

表6-12

消息

按鍵或者代碼

WM_KEYDOWN

「A」的虛擬鍵碼(0x41)

WM_CHAR

「a」的字符代碼(0x61)

WM_KEYDOWN

「A」的虛擬鍵碼(0x41)

WM_CHAR

「a」的字符代碼(0x61)

WM_KEYDOWN

「A」的虛擬鍵碼(0x41)

WM_CHAR

「a」的字符代碼(0x61)

WM_KEYDOWN

「A」的虛擬鍵碼(0x41)

WM_CHAR

「a」的字符代碼(0x61)

WM_KEYUP

「A」的虛擬鍵碼(0x41)

 

如果某些WM_KEYDOWN消息的重復(fù)計(jì)數(shù)大于1,那么相應(yīng)的WM_CHAR消息將具有同樣的重復(fù)計(jì)數(shù)。

組合使用Ctrl鍵與字母鍵會(huì)產(chǎn)生從0x01(Ctrl-A)到0x1A(Ctrl-Z)的ASCII控制代碼,其中的某些控制代碼也可以由表6-13列出的鍵產(chǎn)生:

 

表6-13

按鍵

字符代碼

產(chǎn)生方法

ANSI C控制字符

Backspace

0x08

Ctrl-H

\b

Tab

0x09

Ctrl-I

\t

Ctrl-Enter

0x0A

Ctrl-J

\n

Enter

0x0D

Ctrl-M

\r

Esc

0x1B

Ctrl-[

 

 

最右列給出了在ANSI C中定義的控制字符,它們用于描述這些鍵的字符代碼。

 

我們一般可以這樣處理WM_CARH消息:

case WM_CHAR:

{

    switch (wParam)

    {

        case 0x08:

            // Process a backspace.

            break;

 

        case 0x0A:

            // Process a linefeed.

            break;

 

        case 0x1B:

            // Process an escape.

            break;

 

        case 0x09:

            // Process a tab.

            break;

 

        case 0x0D:

            // Process a carriage return.

            break;

 

        default:

            // Process displayable characters.

            break;

    }

}

 

我們可以在WM_CHAR里面判斷當(dāng)前是否有指定的鍵被按下:

 

BOOL bIsCtrl = (::GetAsyncKeyState(VK_CONTROL) & 0x8000); MFC源碼 afxcolordialog.cpp 460行)

BOOL bIsCtrl = (::GetKeyState(VK_CONTROL) & 0x8000);

 

下面我解釋一下鍵盤消息的lParam參數(shù),這個(gè)參數(shù)在MSDN上面都可以查到,只是英文,我這里作一些簡(jiǎn)單的說(shuō)明:(以WM_KEYDOWN為例)

WPARAM:虛擬鍵值,VT_*等值。

LPARAM:根據(jù)其不同的位數(shù)表示的含義不同可以分以下幾部分:

(1) 重復(fù)計(jì)數(shù)位(0 - 15 位):表示消息按鍵數(shù)據(jù)。一般情況下為1,當(dāng)鍵一直按下,窗口過(guò)程就會(huì)連續(xù)收到W_KEYDOWN消息,但有可能窗口過(guò)程來(lái)不及處理這些按鍵消息,那么Windows就會(huì)把幾個(gè)按鍵消息組合成一個(gè),并增加重復(fù)計(jì)數(shù)。比如你處理WM_KEYDOWN時(shí)Sleep(200),那么得到的這個(gè)數(shù)字就可能大于1,一般可以這樣來(lái)得到這個(gè)計(jì)數(shù):

DWORD count = (((DWORD)lParam) & 0x0000FFFF);

(2) OEM掃描碼(16~23位):OEM掃描碼是鍵盤發(fā)送的碼值,由于此域是設(shè)備相關(guān)的,因而此值往往被忽略。

(3) 擴(kuò)展鍵標(biāo)志(24位):擴(kuò)展鍵標(biāo)志在有Alt鍵(或Ctrl鍵)按下時(shí)為1,否則為0。

(4) 保留位(25~28位):保留位是系統(tǒng)缺省保留的,一般不用。

(5) 關(guān)聯(lián)碼(29位):關(guān)聯(lián)碼用來(lái)記錄某鍵與Alt鍵的組合狀態(tài),若按下Alt,當(dāng)WM_SYSKEYDOWN消息送到某個(gè)激活的窗口時(shí),其值為1,否則為0。

(6) 鍵的先前狀態(tài)(位30):鍵的先前狀態(tài)用于記錄先前某鍵的狀態(tài),對(duì)于WM_SYSKEYUP消息,其值始終為1。

(7) 轉(zhuǎn)換狀態(tài)(31位):轉(zhuǎn)換狀態(tài)的消息是始終按著某鍵所產(chǎn)生的消息,若某鍵原來(lái)是按下的,則其先前狀態(tài)為0。轉(zhuǎn)換狀態(tài)指示鍵被按下還是被松開(kāi)。當(dāng)鍵被按下時(shí),對(duì)應(yīng)于者WM_SYSKEYDOWN消息,其值始終為0,當(dāng)鍵被松開(kāi)時(shí),其轉(zhuǎn)換狀態(tài)為1,對(duì)應(yīng)于WM_SYSKEYUP消息,其值始終為1。

 

5,死字符消息

Windows程序經(jīng)常忽略WM_DEADCHAR和WM_SYSDEADCHAR消息,但您應(yīng)該明確地知道死字符是什么,以及它們工作的方式。

在某些非U.S.英語(yǔ)鍵盤上,有些鍵用于給字母加上音調(diào)。因?yàn)樗鼈儽旧聿划a(chǎn)生字符,所以稱之為「死鍵」。例如,使用德語(yǔ)鍵盤時(shí),對(duì)于U.S.鍵盤上的+/=鍵,德語(yǔ)鍵盤的對(duì)應(yīng)位置就是一個(gè)死鍵,未按下Shift鍵時(shí)它用于標(biāo)識(shí)銳音,按下Shift鍵時(shí)則用于標(biāo)識(shí)抑音。

當(dāng)使用者按下這個(gè)死鍵時(shí),窗口消息處理程序接收到一個(gè)wParam等于音調(diào)本身的ASCII或者Unicode代碼的WM_DEADCHAR消息。當(dāng)使用者再按下可以帶有此音調(diào)的字母鍵(例如A鍵)時(shí),窗口消息處理程序會(huì)接收到WM_CHAR消息,其中wParam等于帶有音調(diào)的字母「a」的ANSI代碼。

因此,使用者程序不需要處理WM_DEADCHAR消息,原因是WM_CHAR消息已含有程序所需要的所有信息。Windows的做法甚至還設(shè)計(jì)了內(nèi)部錯(cuò)誤處理。如果在死鍵之后跟有不能帶此音調(diào)符號(hào)的字母(例如「s」),那么窗口消息處理程序?qū)⒃谝恍薪邮盏絻蓷lWM_CHAR消息-前一個(gè)消息的wParam等于音調(diào)符號(hào)本身的ASCII代碼(與傳遞到WM_DEADCHAR消息的wParam值相同),第二個(gè)消息的wParam等于字母s的ASCII代碼。

當(dāng)然,要感受這種做法的運(yùn)作方式,最好的方法就是實(shí)際操作。您必須加載使用死鍵的外語(yǔ)鍵盤,例如前面講過(guò)的德語(yǔ)鍵盤。您可以這樣設(shè)定:在「控制臺(tái)」中選擇「鍵盤」,然后選擇「語(yǔ)系」頁(yè)面標(biāo)簽。然后您需要一個(gè)應(yīng)用程序,該程序可以顯示它接收的每一個(gè)鍵盤消息的詳細(xì)信息。下面的KEYVIEW1就是這樣的程序。



符號(hào)常量 十六進(jìn)制值 指定的鼠標(biāo)或鍵盤按鍵
  VK_LBUTTON 01 鼠標(biāo)左鍵
  VK_RBUTTON 02 鼠標(biāo)右鍵
  VK_CANCEL 03 Control-break 過(guò)程
  VK_MBUTTON 04 鼠標(biāo)中鍵
  VK_BACK 08 BACKSPACE 鍵
  VK_TAB 09 TAB 鍵
  VK_CLEAR 0C CLEAR 鍵
  VK_RETURN 0D ENTER 鍵
  VK_SHIFT 10 SHIFT 鍵
  VK_CONTROL 11 CTRL 鍵
  VK_MENU 12 ALT 鍵
  VK_PAUSE 13 PAUSE 鍵
  VK_CAPITAL 14 CAPS LOCK 鍵
  VK_ESCAPE 1B ESC 鍵
  VK_SPACE 20 SPACEBAR
  VK_PRIOR 21 PAGE UP 鍵
  VK_NEXT 22 PAGE DOWN 鍵
  VK_END 23 END 鍵
  VK_HOME 24 HOME 鍵
  VK_LEFT 25 LEFT ARROW 鍵
  VK_UP 26 UP ARROW 鍵
  VK_RIGHT 27 RIGHT ARROW 鍵
  VK_DOWN 28 DOWN ARROW 鍵
  VK_SELECT 29 SELECT 鍵
  VK_EXECUTE 2B EXECUTE 鍵
  VK_SNAPSHOT 2C PRINT SCREEN鍵(用于Windows 3.0及以后版本)
  VK_INSERT 2D INS 鍵
  VK_DELETE 2E DEL 鍵
  VK_HELP 2F HELP 鍵
  ///////////////////////////////////////////////////
  對(duì)于字母鍵和非小鍵盤上的數(shù)字鍵,直接在單引號(hào)中加入該鍵就行.
  比如:a鍵:'A'
   1鍵:'1'
  //////////////////////////////////////////////

  VK_LWIN 5B Left Windows 鍵 (Microsoft自然鍵盤)
  VK_RWIN 5C Right Windows 鍵 (Microsoft自然鍵盤)
  VK_APPS 5D Applications 鍵 (Microsoft自然鍵盤)
  VK_NUMPAD0 60 數(shù)字小鍵盤上的 0 鍵
  VK_NUMPAD1 61 數(shù)字小鍵盤上的 1 鍵
  VK_NUMPAD2 62 數(shù)字小鍵盤上的 2 鍵
  VK_NUMPAD3 63 數(shù)字小鍵盤上的 3 鍵
  VK_NUMPAD4 64 數(shù)字小鍵盤上的 4 鍵

       VK_NUMPAD5 65 數(shù)字小鍵盤上的 5 鍵
  VK_NUMPAD6 66 數(shù)字小鍵盤上的 6 鍵
  VK_NUMPAD7 67 數(shù)字小鍵盤上的 7 鍵
  VK_NUMPAD8 68 數(shù)字小鍵盤上的 8 鍵
  VK_NUMPAD9 69 數(shù)字小鍵盤上的 9 鍵
  VK_MULTIPLY 6A Multiply 鍵
  VK_ADD 6B Add 鍵
  VK_SEPARATOR 6C Separator 鍵
  VK_SUBTRACT 6D Subtract 鍵
  VK_DECIMAL 6E Decimal 鍵
  VK_DIVIDE 6F Divide 鍵
  VK_F1 70 F1 鍵
  VK_F2 71 F2 鍵
  VK_F3 72 F3 鍵
  VK_F4 73 F4 鍵
  VK_F5 74 F5 鍵
  VK_F6 75 F6 鍵
  VK_F7 76 F7 鍵
  VK_F8 77 F8 鍵
  VK_F9 78 F9 鍵
  VK_F10 79 F10 鍵
  VK_F11 7A F11 鍵
  VK_F12 7B F12 鍵
  VK_F13 7C F13 鍵
  VK_F14 7D F14 鍵
  VK_F15 7E F15 鍵
  VK_F16 7F F16 鍵
  VK_F17 80H F17 鍵
  VK_F18 81H F18 鍵
  VK_F19 82H F19 鍵
  VK_F20 83H F20 鍵
  VK_F21 84H F21 鍵
  VK_F22 85H F22 鍵
  VK_F23 86H F23 鍵
  VK_F24 87H F24 鍵
  VK_NUMLOCK 90 NUM LOCK 鍵
  VK_SCROLL 91 SCROLL LOCK 鍵
  VK_ATTN F6 Attn 鍵
  VK_CRSEL F7 CrSel 鍵
  VK_EXSEL F8 ExSel 鍵
  VK_EREOF F9 Erase EOF 鍵

       VK_PLAY FA Play 鍵
  VK_ZOOM FB Zoom 鍵
  VK_OEM_CLEAR FE Clear 鍵
  
  舉例:
  
  (一)響應(yīng)單獨(dú)的按鍵:
  先添加PreTranslateMessage()(響應(yīng)WM_CHAR)也是同樣的效果,因?yàn)楸纠徊蹲芥I盤)
  BOOL CMydilog::PreTranslateMessage(MSG* pMsg) 
  {

   // TODO: Add your specialized code here and/or call the base class
   if (pMsg->message == WM_KEYDOWN)
   {
   if(pMsg->wParam=='M')//直接用上面的虛碼代替就可以響應(yīng)所指鍵
   MessageBox("hello");//如果按下M鍵彈出消息.比如想當(dāng)按下小鍵盤1時(shí)
   //彈出就用VK_NUMPAD1代替'M'
  }
   return CDialog::PreTranslateMessage(pMsg);
  }

  (二)組合鍵的用法:(本例響應(yīng)Ctrl+X鍵)
  BOOL CMydilog::PreTranslateMessage(MSG* pMsg) 
  {
   // TODO: Add your specialized code here and/or call the base class
   
   if (pMsg->message == WM_KEYDOWN)
   {
   switch (pMsg->wParam)
   { 
   case VK_ESCAPE:
   SetFocus ();
   return TRUE;
   case 'X':
   if(::GetKeyState(VK_CONTROL) < 0)//如果是Shift+X這里就
   //改成VK_SHIFT
   MessageBox("hello");
   return TRUE;
   
   }
   }
   return CDialog::PreTranslateMessage(pMsg);
  }


SetCapture 函數(shù)功能:該函數(shù)在屬于當(dāng)前線程的指定窗口里設(shè)置鼠標(biāo)捕獲。一旦窗口捕獲了鼠標(biāo),所有鼠標(biāo)輸入都針對(duì)該窗口,無(wú)論光標(biāo)是否在窗口的邊界內(nèi)。同一時(shí)刻只能有一個(gè)窗口捕獲鼠標(biāo)。如果鼠標(biāo)光標(biāo)在另一個(gè)線程創(chuàng)建的窗口上,只有當(dāng)鼠標(biāo)鍵按下時(shí)系統(tǒng)才將鼠標(biāo)輸入指向指定的窗口。

LRESULT CALLBACK TestProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){    switch (msg)    {    case WM_LBUTTONDOWN: //左鍵按下        {            SetCapture(hwnd);        }        break;    case WM_MOUSEMOVE: //鼠標(biāo)按下移動(dòng)        {                if(GetCapture() ==  hwnd)                {                   //鼠標(biāo)按下并移動(dòng)...                }        }        break;    case WM_LBUTTONUP: //左鍵彈起        {            if(GetCapture()  ==  hwnd)                ReleaseCapture(); //當(dāng)前線程中的窗口釋放鼠標(biāo)捕獲,并恢復(fù)通常的鼠標(biāo)輸入處理。        }        break;        return 0;    }}
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
VC鍵盤消息大全
如何模擬鍵盤操作(c++版本)
WM
如何使對(duì)話框不響應(yīng)Enter鍵與ESC鍵
PostMessage到底能不能發(fā)送組合鍵?
添加鍵盤響應(yīng)事件
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服