GetAsyncKeyState

首先介紹一下幾個概念:
按位與運算符"&":是雙目運算符,其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均爲1時,結果位才爲1 ,否則爲0。參與運算的數以補碼方式出現。例如:0x11 & 0x12(即0001 0001 & 0001 0010)的結果是0x100001 0000);(關於vs取反參考附)
虛鍵:指的是非字母可以明確表示的鍵.(例如ESC BS TAB NumLock ,虛鍵列表見附);
物理鍵狀態:在操作系統的控制面板中設置鼠標左右鍵的映射(實際的鼠標左鍵可以映射成右鍵點擊事件),或者通過程序也可以這樣設置,這樣就產生了(實際的)物理鍵狀態;
邏輯鍵狀態:使用 GetKeyState,GetKeyboardState,等函數得到的邏輯鍵狀態,模擬按下按鍵;
GetAsyncKeyState
函數功能:讀取的是物理鍵狀態,也就是不管你怎麼鼠標鍵盤映射,它只讀取實際的按鍵狀態。MSDN上給出了例子很恰當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.也就是說如果你重新設置了映射,GetAsyncKeyState還是隻讀取物理狀態;
GetAsyncKeyState
的返回值:表示兩個內容,一個是最高位bit的值,代表這個鍵是否被按下,按下爲1,擡起爲0;一個是最低位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
:英文意思是異步的

實際當中GetAsyncKeyState的返回值是什麼呢?小魚我寫了個程序來獲取返回值:
#include <Windows.h>
#include <stdio.h>

void main()
{
while(1)
{
short a = ::GetAsyncKeyState(VK_LSHIFT)
printf( "0x%x",a);
sleep(10);
}
}
當然,用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字節,而是%x打印出32位,前十六位補
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這個常數呢?
答案是:獲取按鍵狀態,屏蔽掉其他的可能狀態,按照MSDN上說低位should ignore

網上有人這樣寫,意思很明確:
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

程序應該是:
if(GetAsyncKeyState(VK_LSHIFT)&&0x8000)
對於虛鍵而言下面這樣寫邏輯是不對的,雖然結果一樣:
if(GetAsyncKeyState(VK_LSHIFT))

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

關於GetAsyncKeyStateGetKeyState區別:
GetAsyncKeyState
上面已經講差不多了,關於GetAsyncKeyStateGetKeyState二者最大區別:GetAsyncKeyState在按鍵不按的情況下爲0,而GetKeyState在按鍵不按的情況下開始爲0,當一次按下擡起後變爲1,依次循環。

SHORT GetKeyState(int nVirtKey   // virtual-key code);
作用:返回鍵的狀態,按下、釋放或鎖定(downup or toggled

參數:虛擬鍵代碼(VK_)。如果是字母a-zA-Z 或數字0-9 則爲其對應的ASCII碼(比如字母OASCII碼爲十六進制的0x4F
返回值:返回碼的高位顯示當前是否有鍵被按下,低位(0位)則顯示NumLockCapsLockScrollLock的狀態(ONOFF,爲ON時鍵盤指示燈亮)。即高位爲1,返回值小於0,說明有鍵按下;最低位爲1表示處於鎖定(ON)狀態(參考MSDNIf 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. )
注:此函數不應該在鍵盤消息處理程序以外使用,因爲它返回的信息只有在鍵盤消息從消息隊列中被檢索到之後纔有效。若確實需要,請使用GetAsyncKeyState

----------------------------------------
網上還找到了一些資料:

關於和其他的幾個函數的區別:
SHORT GetKeyState(int nVirtKey);
SHORT GetAsyncKeyState(int vKey);
BOOL GetKeyboardState(PBYTE lpKeyState);

三個取key status的函數的最大區別是:
第一個:是從windows消息隊列中取得鍵盤消息,返回key status.
第二個:是直接偵測鍵盤的硬件中斷,返回
key status.
第三個:是當從windows消息隊列中移除鍵盤消息時,才返回key status.

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

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


---------------
附:
VC++
編譯器,計算~10,得出的結果是-11。爲什麼不是5

10的二進制表示爲1010,按位取反應該爲0101,也就是十進制的5,爲什麼會得出-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            
鼠標左鍵                      0x01
VK_RBUTTON            
鼠標右鍵
                      0x02
VK_CANCEL              Ctrl + Break                  0x03
VK_MBUTTON            
鼠標中鍵                      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'             數字 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章