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
版权声明:本文为博主原创文章,未经博主同意不得转载。
GetKeyState(), GetAsyncKeystate(), GetKeyboardSlate()的更多相关文章
- GetKeyState和GetAsyncKeyState以及GetKeyboardState函数的用法与区别
GetKeyState.GetAsyncKeyState.GetKeyboardState函数的区别: 1.BOOL GetKeyboardState( PBYTE lpKeyState );获得所有 ...
- GetKeyState和GetAsyncKeyState以及GetKeyboardState函数的用法与区别2-------C#检查键盘大小写锁定状态
1.命名空间:using System.Runtime.InteropServices;2.导入方法[DllImport("user32.dll", EntryPoint = &q ...
- GetAsyncKeyState()& 0x8000
0x8000 & GetKeyState(VK_SHIFT); 这句是判断是否有按下shift键. 关于GetAsyncKeyState与GetKeyState区别:关于GetAsyncKey ...
- GetKeyState(vk_control)
GetKeyState(vk_control) 返回负数 , 说明按键被按下了
- delphi GetKeyState
GetKeyState(VK_CAPITAL) & 0x0001 0x8000 是键有否按下0x0001 是键的翻转状态 var bF1Down: Boolean;begin bF1Down ...
- 【杂文】虚拟键码表(供函数GetAsyncKeyState()使用)
[杂文]虚拟键码表(供函数GetAsyncKeyState()使用) 什么?你说你不知道 \(GetAsyncKeyState()\) ?\(→\)戳我\(←\) (惊奇的发现 \(0\) ~ \(9 ...
- 使用Sendinput以及GetAsyncKeyState来模拟按键延时
Code: #include <windows.h> #include <tchar.h> #include <iostream> BOOL flag = TRUE ...
- c#文件操作
1.创建文件夹 //using System.IO; Directory.CreateDirectory(%%1); 2.创建文件 //using System.IO; File.Create(% ...
- Windows API 函数列表 附帮助手册
所有Windows API函数列表,为了方便查询,也为了大家查找,所以整理一下贡献出来了. 帮助手册:700多个Windows API的函数手册 免费下载 API之网络函数 API之消息函数 API之 ...
随机推荐
- win10开机时内存使用率达到99%以上
开始,运行,输入msconfig回车就能看到自启的项目. 搞定! 其实,感觉特别像是输入法的某个监听程序导致内存泄漏,造成的系统问题. 再遇到的时候要认真检查下.
- HashMap导致死循环问题
虽然我推测是链表形成闭环,但 没有去证明过.从网上找了一下: http://blog.csdn.net/autoinspired/archive/2008/07/16/2662290.aspx 里面也 ...
- 洛谷 P1529 回家 Bessie Come Home
P1529 回家 Bessie Come Home 题目描述 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出 ...
- JStorm中的并行( parallelismction )介绍
JStorm中的并行( parallelismction )介绍 JStrom中.一个计算任务通过多台机器使得计算分解为多个独立并行执行在集群内执行的任务(tasks).从而得到水平扩展. JStor ...
- (插播)关于使用jenkins + unity +Xcode 来进行自己主动打包的处理。
近期了解了下jenkins流程化服务的东西,个人感觉jenkins是一个非常方便的工具.主要是方便.设置好流程性得命令.仅仅需确定下就能够达到自己主动化. 减轻了错误得发生和简化了带来的复杂得步骤.今 ...
- php 设计模式之工厂模式
php 设计模式之工厂模式 简介: 在开发大型系统过程中,往往会出现这样一种情况: 我有一部分基础数据,是类classA是从数据库A读取出来的,其他很多的功能都是基于这个基础数据来操作的.现在呢,我想 ...
- Ubuntu14.04下Mongodb(在线安装方式|apt-get)安装部署步骤(图文详解)(博主推荐)
不多说,直接上干货! 本博文介绍了MongoDB,并详细指引读者在Ubuntu下MongoDB的安装和使用.本教程在Ubuntu14.04下测试通过. 一.MongoDB介绍 MongoDB 是一个是 ...
- NPOI 给导出Excel添加简单样式
需求分析:如下图为我之前导出的Excel数据,没有一点样式,标题行不明显,各个列的数据紧凑,查看数据时得手动拉宽每列,故这次要针对以上问题对它进行优化 结果展示: 代码: /// <summar ...
- C++之易混淆知识点一-----static详解
1.const.mutable与volatile的区别:const表明内存被初始化以后,程序将不能对它进行修改.volatile则表明,即使程序代码没有对内存单元进行修改,但是里面的值也可能会发生变化 ...
- avalon过滤
<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> ...