一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

GetKeyState、GetAsyncKeyState、GetKeyboardState...

 fisher60 2013-07-03

 GetKeyState、GetAsyncKeyState、GetKeyboardState函數(shù)的區(qū)別:

1、BOOL GetKeyboardState( PBYTE lpKeyState );獲得所有的256個(gè)鍵(鍵盤按鍵、鼠標(biāo)按鍵等等)的狀態(tài),lpKeyState是指向一個(gè)256bit的數(shù)組,存放所有鍵的狀態(tài)。

2、SHORT GetAsyncKeyState( int vKey );判斷Virtual-KeyCodes為vKey的鍵是否down或up。用返回值的最高位表示鍵的狀態(tài)(up或down),用返回值的最低位表示vKey鍵在此函數(shù)調(diào)用之前是否被按下過。GetAsyncKeyState直接偵測(cè)鍵盤的硬件中斷。

3、SHORT GetKeyState( int nVirtKey );用于判斷nVirtKey的狀態(tài)。用返回值的最高位表示,最高位為1表示當(dāng)前鍵處于down的狀態(tài);最高位為0當(dāng)前鍵處于up狀態(tài)。此函數(shù)從消息隊(duì)列中讀取消息進(jìn)行處理

 

0x8000 & GetKeyState(VK_SHIFT); 這句是判斷是否有按下shift鍵 

為什么GetAsyncKeyState()& 

首先說明,有好多程序或書上是0x8000f,這個(gè)f不是十六進(jìn)制的f而是代表浮點(diǎn)數(shù)。其實(shí)& 8000才是本質(zhì)。小魚我整理后自己寫了點(diǎn)東西,總結(jié)一下 


首先介紹一下幾個(gè)概念: 
按位與運(yùn)算符"&":是雙目運(yùn)算符,其功能是參與運(yùn)算的兩數(shù)各對(duì)應(yīng)的二進(jìn)位相與。只有對(duì)應(yīng)的兩個(gè)二進(jìn)位均為1時(shí),結(jié)果位才為1 ,否則為0。參與運(yùn)算的數(shù)以補(bǔ)碼方式出現(xiàn)。例如:0x11 & 0x12(即0001 0001 & 0001 0010)的結(jié)果是0x10(0001 0000);(關(guān)于vs取反參考附) 
虛鍵:指的是非字母可以明確表示的鍵.(例如ESC BS TAB NumLock 等,虛鍵列表見附); 
物理鍵狀態(tài):在操作系統(tǒng)的控制面板中設(shè)置鼠標(biāo)左右鍵的映射(實(shí)際的鼠標(biāo)左鍵可以映射成右鍵點(diǎn)擊事件),或者通過程序也可以這樣設(shè)置,這樣就產(chǎn)生了(實(shí)際的)物理鍵狀態(tài); 
邏輯鍵狀態(tài):使用 GetKeyState,GetKeyboardState,等函數(shù)得到的邏輯鍵狀態(tài),模擬按下按鍵; 
GetAsyncKeyState函數(shù)功能:讀取的是物理鍵狀態(tài),也是就是不管你怎么鼠標(biāo)鍵盤映射,它只讀取實(shí)際的按鍵狀態(tài)。MSDN上給出了例子很恰當(dāng)For example, the call GetAsyncKeyState(VK_LBUTTON) always returns the state of the left physical mouse button, regardless of whether it is mapped to the left or right logical mouse button.也就是說如果你重新設(shè)置了映射,GetAsyncKeyState還是只讀取物理狀態(tài); 
GetAsyncKeyState的返回值:表示兩個(gè)內(nèi)容,一個(gè)是最高位bit的值,代表這個(gè)鍵是否被按下,按下為1,抬起為0;一個(gè)是最低位bit的值,在windowsCE下要忽略(參考自MSDNIf the most significant bit is set, the key is down. The least significant bit is not valid in Windows CE, and should be ignored.) 
Asynchronous:英文意思是異步的 

實(shí)際當(dāng)中GetAsyncKeyState的返回值是什么呢?小魚我寫了個(gè)程序來獲取返回值: 
#include <Windows.h> 
#include <stdio.h> 

void main() 

while(1) 

short a = ::GetAsyncKeyState(VK_LSHIFT) 
printf( "0x%x",a); 
sleep(10); 


當(dāng)然,用MessageBox可以這樣寫: 
if(short a = ::GetAsyncKeyState(VK_LSHIFT)) 

char buffer[30]; 
sprintf(buffer, "0x%x",a); 
MessageBox(0, buffer, "a的值", MB_OK); 


GetAsyncKeyState按鍵不按或抬起后不按的返回值0x0        即0000 0000 0000 0000 0000 0000 0000 0000 
GetAsyncKeyState按鍵被按下后的返回值    返回0xffff8001 即1111 1111 1111 1111 1000 0000 0000 0001   (這里并不是返回4字節(jié),而是%x打印出32位,前十六位補(bǔ)f) 
0x8000 即0000 0000 0000 0000 1000 0000 0000 0000 
GetAsyncKeyState(VK_LSHIFT) & 0x8000    返回0x1          即0000 0000 0000 0000 1000 0000 0000 0000 

那么為什么GetAsyncKeyState要 ‘與’上 0x8000這個(gè)常數(shù)呢? 
答案是:獲取按鍵狀態(tài),屏蔽掉其他的可能狀態(tài),按照MSDN上說低位should ignore。 
網(wǎng)上有人這樣寫,意思很明確: 
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) 
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) 

程序應(yīng)該是: 
if(GetAsyncKeyState(VK_LSHIFT)&&0x8000) 
對(duì)于虛鍵而言下面這樣寫邏輯是不對(duì)的,雖然結(jié)果一樣: 
if(GetAsyncKeyState(VK_LSHIFT)) 

所以讓鍵盤的"上下左右"出發(fā)事件可以這樣寫: 
if( ::GetAsyncKeyState(VK_LEFT) & 0x8000 ) 
code... 
if( ::GetAsyncKeyState(VK_RIGHT)& 0x8000 ) 
code... 
if( ::GetAsyncKeyState(VK_UP) & 0x8000 ) 
code... 
if( ::GetAsyncKeyState(VK_DOWN) & 0x8000 ) 
code... 

關(guān)于GetAsyncKeyState與GetKeyState區(qū)別: 
GetAsyncKeyState上面已經(jīng)講差不多了,關(guān)于GetAsyncKeyState與GetKeyState二者最大區(qū)別:GetAsyncKeyState在按鍵不按的情況下為0,而GetKeyState在按鍵不按的情況下開始為0,當(dāng)一次‘按下抬起’后變?yōu)?,依次循環(huán)。 

SHORT GetKeyState(int nVirtKey   // virtual-key code); 
作用:返回鍵的狀態(tài),按下、釋放或鎖定(down、up or toggled) 
參數(shù):虛擬鍵代碼(VK_)。如果是字母a-z、A-Z 或數(shù)字0-9, 則為其對(duì)應(yīng)的ASCII碼(比如字母O的ASCII碼為十六進(jìn)制的0x4F) 
返回值:返回碼的高位顯示當(dāng)前是否有鍵被按下,低位(0位)則顯示NumLock、CapsLock、ScrollLock的狀態(tài)(ON或OFF,為ON時(shí)鍵盤指示燈亮)。即高位為1,返回值小于0,說明有鍵按下;最低位為1表示處于鎖定(ON)狀態(tài)(參考MSDN:If the high-order bit is 1, the key is down; otherwise, it is up. 
If the low-order bit is 1, the key is toggled. A key, such as the CAPS LOCK key, is toggled if it is turned on. The key is off and untoggled if the low-order bit is 0. A toggle key's indicator light (if any) on the keyboard will be on when the key is toggled, and off when the key is untoggled. ) 
注:此函數(shù)不應(yīng)該在鍵盤消息處理程序以外使用,因?yàn)樗祷氐男畔⒅挥性阪I盤消息從消息隊(duì)列中被檢索到之后才有效。若確實(shí)需要,請(qǐng)使用GetAsyncKeyState 

---------------------------------------- 
網(wǎng)上還找到了一些資料: 

關(guān)于和其他的幾個(gè)函數(shù)的區(qū)別: 
SHORT GetKeyState(int nVirtKey); 
SHORT GetAsyncKeyState(int vKey); 
BOOL GetKeyboardState(PBYTE lpKeyState); 

三個(gè)取key status的函數(shù)的最大區(qū)別是: 
第一個(gè):是從windows消息隊(duì)列中取得鍵盤消息,返回key status. 
第二個(gè):是直接偵測(cè)鍵盤的硬件中斷,返回key status. 
第三個(gè):是當(dāng)從windows消息隊(duì)列中移除鍵盤消息時(shí),才返回key status. 

keybd_event函數(shù),是模擬鍵盤擊鍵,一次完整的擊鍵模擬事件,是"按下"和"彈起"兩個(gè)消息,所以 keybd_event(VK_F12,0,0,0);keybd_event(VK_F12,0,KEYEVENTF_KEYUP,0); 完成了一次完整的點(diǎn)擊 F12 的事件。 

GetAsyncKeyState()函數(shù),是直接偵測(cè)鍵盤的硬件中斷。(有些人說,是一種“實(shí)時(shí)性”的偵測(cè),這種說法,感覺不對(duì),比如你調(diào)用 Sleep(),就算是中斷一年的時(shí)間,只要在這期間程序還在運(yùn)行,它都可以把那個(gè)鍵的狀態(tài)偵測(cè)出來)。自上一次調(diào)用GetAsyncKeyState()函數(shù)以來(在某些循環(huán)中,N次調(diào)用GetAsyncKeyState(),它每次檢查的,都是自上次調(diào)用之后,鍵的狀態(tài)),若鍵已被按過,則返回1,否則,返回0;有些資料顯示:倘若輸入焦點(diǎn)從屬于與調(diào)用函數(shù)的輸入線程不同的另一個(gè)線程,則返回零(例如,在另一個(gè)程序擁有輸入焦點(diǎn)時(shí),應(yīng)該返回零)。實(shí)驗(yàn)證明,這種說法并不完全,函數(shù)實(shí)際是在大部份范圍內(nèi)工作的,只有少數(shù)是另外)。 


--------------- 
附: 
VC++編譯器,計(jì)算~10,得出的結(jié)果是-11。為什么不是5呢 

10的二進(jìn)制表示為1010,按位取反應(yīng)該為0101,也就是十進(jìn)制的5,為什么會(huì)得出-11? 


VC是32位編譯器,所以 

10 = 00000000 00000000 00000000   00001010 

~10 = 11111111 11111111   11111111   11110101 =   -11 

可以通過掩碼(位與) 與15位與 

15 = 00000000 00000000 00000000   00001111 

~10 = 00000000 00000000 00000000   00000101   =   -11 
附: 
VK_LBUTTON             鼠標(biāo)左鍵                      0x01 
VK_RBUTTON             鼠標(biāo)右鍵                      0x02 
VK_CANCEL              Ctrl + Break                  0x03 
VK_MBUTTON             鼠標(biāo)中鍵                      0x04 

VK_BACK                Backspace 鍵       0x08 
VK_TAB                 Tab 鍵                        0x09 

VK_RETURN              回車鍵                        0x0D 


VK_SHIFT               Shift 鍵                      0x10 
VK_CONTROL             Ctrl 鍵                       0x11 
VK_MENU                Alt 鍵                 0x12 
VK_PAUSE               Pause 鍵                      0x13 
VK_CAPITAL             Caps Lock 鍵                  0x14 

VK_ESCAPE              Esc 鍵                        0x1B 

VK_SPACE               空格鍵         0x20 
VK_PRIOR               Page Up 鍵                    0x21 
VK_NEXT                Page Down 鍵                  0x22 
VK_END                 End 鍵                        0x23 
VK_HOME                Home 鍵                       0x24 
VK_LEFT                左箭頭鍵                      0x25 
VK_UP                  上箭頭鍵                      0x26 
VK_RIGHT               右箭頭鍵                      0x27 
VK_DOWN                下箭頭鍵                      0x28 
VK_SNAPSHOT            Print Screen 鍵               0x2C 
VK_Insert              Insert 鍵                     0x2D 
VK_Delete              Delete 鍵                     0x2E 

'0' – '9'             數(shù)字 0 - 9                    0x30 - 0x39 
'A' – 'Z'             字母 A - Z                    0x41 - 0x5A 

VK_LWIN                左WinKey(104鍵盤才有)         0x5B 
VK_RWIN                右WinKey(104鍵盤才有)         0x5C 
VK_APPS                AppsKey(104鍵盤才有)          0x5D 

VK_NUMPAD0            小鍵盤 0 鍵                    0x60 
VK_NUMPAD1            小鍵盤 1 鍵                    0x61 
VK_NUMPAD2            小鍵盤 2 鍵                    0x62 
VK_NUMPAD3            小鍵盤 3 鍵                    0x63 
VK_NUMPAD4            小鍵盤 4 鍵                    0x64 
VK_NUMPAD5            小鍵盤 5 鍵                    0x65 
VK_NUMPAD6            小鍵盤 6 鍵                    0x66 
VK_NUMPAD7            小鍵盤 7 鍵                    0x67 
VK_NUMPAD8            小鍵盤 8 鍵                    0x68 
VK_NUMPAD9            小鍵盤 9 鍵                    0x69 

VK_F1 - VK_F24        功能鍵F1 – F24               0x70 - 0x87 

VK_NUMLOCK            Num Lock 鍵                   0x90 
VK_SCROLL             Scroll Lock 鍵                0x91 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    午夜精品一区二区av| 黄色在线免费高清观看| 亚洲天堂国产精品久久精品| 超碰在线播放国产精品| 国产女性精品一区二区三区| 午夜精品成年人免费视频| 玩弄人妻少妇一区二区桃花| 丰满人妻少妇精品一区二区三区| 91福利免费一区二区三区| 黑丝袜美女老师的小逼逼| 麻豆印象传媒在线观看| 久草国产精品一区二区| 婷婷色香五月综合激激情| 国产亚洲中文日韩欧美综合网 | 国产美女精品午夜福利视频| 亚洲国产成人av毛片国产| 亚洲国产黄色精品在线观看| 国产免费观看一区二区| 高中女厕偷拍一区二区三区| 色涩一区二区三区四区| 日韩精品中文字幕亚洲| 日韩中文字幕在线不卡一区| 中文字幕在线区中文色| 二区久久久国产av色| 日本99精品在线观看| 在线视频三区日本精品| 国产不卡最新在线视频| 国产一二三区不卡视频| 亚洲中文字幕视频在线观看| 99热在线播放免费观看| 人体偷拍一区二区三区| 福利视频一区二区在线| 91欧美亚洲精品在线观看| 丰满少妇被粗大猛烈进出视频| 欧美尤物在线视频91| 日本一本不卡免费视频| 亚洲一区二区三区国产| 亚洲天堂久久精品成人| 国产成人精品午夜福利| 国产成人精品午夜福利av免费| 日本女优一色一伦一区二区三区|