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

GetKeyState、GetAsyncKeyState、GetKeyboardState函数的区别:相关推荐

  1. GetKeyState、GetAsyncKeyState、GetKeyboardState函数的区别 以及虚拟键值

    GetKeyState.GetAsyncKeyState.GetKeyboardState函数的区别: 1.BOOL GetKeyboardState( PBYTE lpKeyState );获得所有 ...

  2. C++技术 - GetAsyncKeyState 与 GetKeyboardState 函数

    C++技术 - GetAsyncKeyState 与 GetKeyboardState 函数 GetAsyncKeyState 与 GetKeyboardState 函数的介绍 SHORT GetAs ...

  3. C++技术:GetAsyncKeyState 与 GetKeyboardState 函数

    文章目录 luogu博客链接 C++技术 - GetAsyncKeyState 与 GetKeyboardState 函数 GetAsyncKeyState 与 GetKeyboardState 函数 ...

  4. GetKeyState和GetAsyncKeyState到底有什么区别?

    经常有朋友问起,GetKeyState和GetAsyncKeyState到底有什么区别,分别应该在什么场景下使用. 那么,今天我就来翻译翻译,什么叫惊喜. GetKeyState会返回虚拟按键的状态. ...

  5. GetKeyState(), GetAsyncKeystate(), GetKeyboardSlate()解析

    原文链接: https://www.cnblogs.com/llguanli/p/8427384.html GetKeyState.GetAsyncKeyState.GetKeyboardState函 ...

  6. render函数和redirect函数的区别+反向解析

    render函数和redirect函数的区别+反向解析 1.视图函数:一定是要包含两个对象的(render源码里面有HttpResponse对象)   request对象:----->所有的请求 ...

  7. 友元函数、类的非静态成员函数、静态成员函数的区别

    类中申明的函数相对于类来说有三层意思: 1.有this指针 2.函数在类的作用区域中 3.可以访问类中私有部分 4.可以被继承 非静态成员函数具有1234 静态成员函数具有234 友元函数具有3 静态 ...

  8. 第七周项目一-成员函数、友元函数和一般函数有区别(1)

     /**Copyright(c)2016,烟台大学计算机与控制工程学院*All rights reserved*文件名称:123.cpp*作 者:王蕊*完成日期:2016年4月12日*版 本 号: ...

  9. php怎么输出3个函数和,PHP利用var_dump,var_export,print_r三个函数的区别示例

    感兴趣的小伙伴,下面一起跟随512笔记的小玲来看看吧!下面的示例看看这三个函数的具体的区别,其中var_dump和var_export比较少用,但他们两者又很相似.所以可以看看: 代码如下: /* 5 ...

最新文章

  1. IoT半导体购并案效果难现 服务器合作案后来居上
  2. PMBOK第七版,通往项目管理的新地图
  3. python integer_【Python】string/list/integer常用函数总结
  4. UNIX再学习 -- TCP/UDP 客户机/服务器
  5. 2-2 用Python爬取银河演员网上的演员参演电影的信息进行抓取
  6. 异步复位设计中的亚稳态问题及其解决方案
  7. 如何利用BI搭建电商数据分析平台
  8. ps写php,PS是什么
  9. 虚拟服务器 共享打印机,教你轻松解决打印机共享难题
  10. Java中接口的使用你得知道,最全Java知识总结
  11. 中国医药外包市场发展前景预测与竞争态势分析报告2022-2028年版
  12. html中size是设置什么意思,CSS的font-size-adjust属性有什么用?
  13. 关于torch.load的一点小tip
  14. maven项目中,使用pom文件引入自定义jar包
  15. 【CPU线程和进程绑核】
  16. mac扩展屏幕做主显示器关闭电脑屏幕,关闭键盘背光
  17. 多校园SaaS运营智慧校园云平台源码 智慧校园移动小程序源码
  18. WEEE认证是什么,WEEE认证和WEEE注册有什么区别
  19. 五分钟学会各种环形进度条
  20. CNKI知网论文数据爬取

热门文章

  1. ipad无法更新最新版本ipadOS 16、不再连接到互联网解决方法
  2. 电阻(5)NTC电阻篇
  3. 海贼王热血航线正在连接服务器,《航海王热血航线》登录异常解决方法 无法进入怎么解决...
  4. 论文笔记:ReDet: A Rotation-equivariant Detector for Aerial Object Detection
  5. 谷歌云服务_Google Cloud_使用注意
  6. ACM篇:UVA220黑白棋总结
  7. 北京软件项目外包流程及管理
  8. 用java编国际象棋3之将军与悔棋
  9. 无人机快速三维建模平台
  10. Ubuntu操作系统安装