GetKeyState(), GetAsyncKeystate(), GetKeyboardSlate()

GetKeyState、GetAsyncKeyState、GetKeyboardState函数的区别:

1、BOOL GetKeyboardState( PBYTE lpKeyState );获得所有的256个键(键盘按键、鼠标按键等等)的状态,lpKeyState是指向一个256bit的数组,存放所有键的状态。

2、SHORT GetAsyncKeyState( int vKey );判断Virtual-KeyCodes为vKey的键是否down或up。用返回值的最高位表示键的状态(up或down),用返回值的最低位表示vKey键在此函数调用之前是否被按下过。GetAsyncKeyState直接侦测键盘的硬件中断。

3、SHORT GetKeyState( int nVirtKey );用于判断nVirtKey的状态。用返回值的最高位表示,最高位为1表示当前键处于down的状态;最高位为0当前键处于up状态。此函数从消息队列中读取消息进行处理。

下面是转载的内容:http://bingtears.iteye.com/blog/663149

0x8000 & GetKeyState(VK_SHIFT); 这句是判断是否有按下shift键

为什么GetAsyncKeyState()&

首先说明,有好多程序或书上是0x8000f,这个f不是十六进制的f而是代表浮点数。其实& 8000才是本质。小鱼我整理后自己写了点东西,总结一下

首先介绍一下几个概念:

按位与运算符"&":是双目运算符,其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。例如:0x11 & 0x12(即0001 0001 & 0001 0010)的结果是0x10(0001 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...

关于GetAsyncKeyState与GetKeyState区别:

GetAsyncKeyState上面已经讲差不多了,关于GetAsyncKeyState与GetKeyState二者最大区别:GetAsyncKeyState在按键不按的情况下为0,而GetKeyState在按键不按的情况下开始为0,当一次‘按下抬起’后变为1,依次循环。

SHORT GetKeyState(int nVirtKey   // virtual-key code);

作用:返回键的状态,按下、释放或锁定(down、up or toggled)

参数:虚拟键代码(VK_)。如果是字母a-z、A-Z 或数字0-9, 则为其对应的ASCII码(比如字母O的ASCII码为十六进制的0x4F)

返回值:返回码的高位显示当前是否有键被按下,低位(0位)则显示NumLock、CapsLock、ScrollLock的状态(ON或OFF,为ON时键盘指示灯亮)。即高位为1,返回值小于0,说明有键按下;最低位为1表示处于锁定(ON)状态(参考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. )

注:此函数不应该在键盘消息处理程序以外使用,因为它返回的信息只有在键盘消息从消息队列中被检索到之后才有效。若确实需要,请使用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

版权声明:本文为博主原创文章,未经博主允许不得转载。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-09 22:28:23

GetKeyState(), GetAsyncKeystate(), GetKeyboardSlate()的相关文章

GetKeyState和GetAsyncKeyState以及GetKeyboardState函数的用法与区别

GetKeyState.GetAsyncKeyState.GetKeyboardState函数的区别: 1.BOOL GetKeyboardState( PBYTE lpKeyState );获得所有的256个键(键盘按键.鼠标按键等等)的状态,lpKeyState是指向一个256bit的数组,存放所有键的状态. 2.SHORT GetAsyncKeyState( int vKey );判断Virtual-KeyCodes为vKey的键是否down或up.用返回值的最高位表示键的状态(up或do

GetKeyState和GetAsyncKeyState以及GetKeyboardState函数的用法与区别2-------C#检查键盘大小写锁定状态

1.命名空间:using System.Runtime.InteropServices;2.导入方法[DllImport("user32.dll", EntryPoint = "GetKeyboardState")]public static extern int GetKeyboardState(byte[] pbKeyState);3.大小写状态public static bool CapsLockStatus{get{byte[] bs = new byte[

用GetKeyState判断指定按键是否按下

SHORT GetKeyState(int nVirtKey /* virtual-key code,eg.VK_F1 */); //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. //例如: GetKeyState(VK_MENU) & 0x8000 //Alt按下 GetKeyState(VK_CONTROL)

龙书dx9 chapter5 light的创建和 GetAsyncKeyState()&amp;0x8000f的问题

笔记1:当我们找个文本,按下物理按键a   aaaaa时候,会发现第一次会有隔断的时间. 参考:http://tieba.baidu.com/p/1829831956 GetAsyncKeyState() 的返回值怎么理解? 实例代码里有if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )这一句,按下→键后,得到 0x1 void main() { static int testInt=0; while (1) { if(short a =( ::GetAsy

【杂文】虚拟键码表(供函数GetAsyncKeyState()使用)

[杂文]虚拟键码表(供函数GetAsyncKeyState()使用) 什么?你说你不知道 \(GetAsyncKeyState()\) ?\(→\)戳我\(←\) (惊奇的发现 \(0\) ~ \(9\) 和 \(A\) ~ \(Z\) 的对应值其实就是我们熟悉的 \(ASCLL\) 编码) 虚拟键码 对应值 对应键 VK_LBUTTON 1 鼠标左键 VK_RBUTTON 2 鼠标右键 VK_CANCEL 3 Cancel VK_MBUTTON 4 鼠标中键 VK_XBUTTON1 5 VK_

【转】《windows核心编程》读书笔记

这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入,但应该是合理的.开头几章由于我追求简洁,往往是很多单独的字句,后面的内容更为连贯. 海量细节. 第1章    错误处理 1.         GetLastError返回的是最后的错误码,即更早的错误码可能被覆盖. 2.         GetLastError可能用于描述成功的原因(CreatEvent)

javascript 调用C++函数

分3步: 一>实现IDispatch 接口 #ifndef _IDISPIMP_H_ #define _IDISPIMP_H_ // idispimp.h class CImpIDispatch : public IDispatch { protected: ULONG m_cRef; public: CImpIDispatch(void); ~CImpIDispatch(void); STDMETHODIMP QueryInterface(REFIID, void **); STDMETHOD

鼠标键盘消息响应及系统热键注册

① 鼠标消息: WM_MOUSEMOVE     鼠标移动位置WM_LBUTTONDOWN       鼠标左键按下WM_LBUTTONUP     鼠标左键弹起WM_LBUTTONDBLCLK                    鼠标左键双击WM_RBUTTONDOWN                      鼠标右键按下WM_RBUTTONUP          鼠标右键弹起WM_RBUTTONDBLCLK   鼠标右键双击WM_MBUTTONDOWN       鼠标中键按下WM_MB

C++实现键盘记录器v1.0

首先,我是也是借鉴别人的源码来学习的.因为如果还是按照从头开始看VC++来做的话肯定是来不及的,那我就直接去分析看懂别的人的代码,从中学习并且自己再重新实现一遍,再做些改进. 先来介绍一下所用到的API: 1.fstream这是一个C++处理文件的一个类,里面有很多关于文件处理的函数.定义这个对象就能够使用其中很多的成员方法. 2.GetAsyncKeyState: 函数GetAsyncKeyState确定在调用它时某个按键处于弹起还是按下的,以及此按键是否在上一次调用GetAsyncKeySt