`
lyunabc
  • 浏览: 558932 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

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或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

分享到:
评论

相关推荐

    TranslateMessage、CLOSE和DESTROY、GetAsyncKeyState和GetKeyState1

    至于键盘状态的检测,Windows提供了两个相关函数:`GetAsyncKeyState`和`GetKeyState`。`GetAsyncKeyState`用于实时检测某个键是否被按下,它可以在任何时候调用,并返回当前按键的状态。如果键被按下,它会返回一个...

    GetKeyState(nVirtKeyinteger)函数Delphi 判断按键状态

    在Delphi编程环境中,`GetKeyState`是一个非常重要的函数,它允许开发者获取键盘上特定虚拟键的状态。这个函数主要用于实时检测用户是否按下了某个键,或者键是否被释放。在游戏开发、输入验证或者任何需要实时响应...

    PB常用API汇总,学习下有好处

    28. GetKeyState()函数:该函数用于获得键盘上指定按键的状态。它需要指定的参数包括按键的虚拟键码。 29. GetModuleHandleA()函数:该函数用于获得活动内存中指定模块或动态链接库的句柄。它需要指定的参数包括...

    Window_API_函数大全

    4. **用户输入处理**:GetAsyncKeyState、GetKeyState和GetKeyboardState函数获取键盘状态,GetCursorPos和SetCursorPos用于处理鼠标位置,以及WM_KEYDOWN和WM_MOUSEMOVE等消息处理用户输入。 5. **文件和I/O操作**...

    API-function.rar_visual c

    4. **用户输入**:GetAsyncKeyState、GetKeyState和GetKeyboardState函数用于获取键盘状态,GetCursorPos和SetCursorPos分别用于获取和设置鼠标位置。 5. **文件操作**:CreateFile、ReadFile和WriteFile用于文件的...

    监听键盘代码版

    本文将深入探讨如何使用`GetAsyncKeyState`函数实现全键盘监听,并解释如何处理返回的键盘码来转换为对应的字母数字字符。 `GetAsyncKeyState`是Windows API中的一个函数,用于检测指定虚拟键的状态。它能提供一种...

    API编辑框获取按键.rar

    在易语言中,获取按键信息通常涉及到API函数如GetAsyncKeyState、GetKeyboardState或GetKeyState。这些函数可以实时监测键盘状态,返回当前按键是否被按下。GetAsyncKeyState返回指定虚拟键的状态,而...

    易语言取大写键状态源码

    这段代码首先声明了`GetKeyState`函数,然后在启动子程序中调用该函数,检查返回值的最高位,以此判断Caps Lock的状态,并显示相应的消息。 在压缩包中的"获取 Caps Lock.e"文件,很可能是包含上述易语言源代码的...

    check-num.rar_numlock

    在Windows环境中,可以使用GetKeyState()函数,传入VK_NUMLOCK(虚拟键代码144)来获取其当前状态。 2. Insert键: Insert键在文本编辑中扮演着插入或覆盖模式的角色。当Insert键开启时,新输入的字符会替换当前...

    API取键盘指示灯状态.rar

    例如,"GetKeyState" API函数可以用来检查特定的键是否被按下,而"GetKeyboardState" API函数则可以获取整个键盘的状态,包括指示灯的标志。 `GetKeyState`函数通常用于检查单个键的状态,比如大写锁定键(Caps Lock...

    全局键盘鼠标钩子典型实例

    5. **GetKeyboardState**:获取当前键盘状态。 6. **GetKeyState**:获取指定虚拟键的状态。 此外,还定义了一个委托函数`HookProc`,它负责处理钩子事件。 #### 常量定义 程序中定义了一系列常量来表示不同的消息...

    数据类字符串

    - 判断SHIFT键是否按下,可以使用Windows API中的`GetKeyState`函数。例如,`GetKeyState(VK_LSHIFT)`或`GetKeyState(VK_RSHIFT)`分别检查左Shift和右Shift的状态。如果返回值的高位字为1,表示键被按下,低位字为1...

    HGE 2D游戏制作引擎 函数列表

    1. `bool hge-&gt;Input_GetKeyState(int key)`:检查指定的键盘按键是否被按下。 2. `int hge-&gt;Input_GetMouseX()` 和 `int hge-&gt;Input_GetMouseY()`:获取鼠标当前的屏幕坐标。 3. `int hge-&gt;Input_GetMouseWheel()...

    VB键盘代码,VB键盘

    本文将详细介绍两种常用的方法:`GetKeyboardState` 和 `GetKeyState` 函数,并探讨它们的应用场景。 #### 二、`GetKeyboardState` 函数详解 `GetKeyboardState` 是一个强大的API函数,用于获取整个键盘上所有按键...

    c#全局钩子(键盘,鼠标)

    4. 组合键的检测通常涉及使用GetKeyState或GetAsyncKeyState函数来查询按键状态,因为键盘钩子回调可能只会收到单一的按键事件,而不是组合键。 在提供的C#版全局钩子示例中,你可能看到代码是如何创建这些回调函数...

    Win32 API 硬件与系统函数.pdf

    ### Win32 API 硬件与系统函数详解 #### 概述 Win32 API是一组用于开发基于Microsoft Windows的应用程序的编程接口。本文档主要聚焦于与硬件及系统管理相关的函数,这些函数能够帮助开发者更好地理解如何通过API调...

    delphi-学用钩子函数

    ### Delphi 学用钩子函数详解 #### 钩子函数概述 在现代软件开发领域,特别是针对系统级别的编程,钩子(Hook)技术扮演着至关重要的角色。钩子函数是Windows操作系统提供的一种机制,它允许开发者拦截、监控或修改...

    获取按键消息_ahk_

    - 如果需要实时检查某个键的状态,可以使用`GetKeyState`函数。例如,`GetKeyState, state, A`会返回A键当前是否被按下,`state`变量将存储结果。 4. **OnMessage函数**: - AHK提供了`OnMessage`函数,允许你...

    c语言 控制台窗口界面编程_修正版

    通过`GetKeyState`和`GetAsyncKeyState`函数可以读取用户的键盘输入状态,从而实现实时响应用户输入的功能。 #### 读取鼠标信息 虽然控制台本身并不直接支持鼠标事件处理,但可以通过`GetMessage`函数间接实现对...

    易语言取键盘指示灯状态源码

    2. 定义API函数:声明并定义API函数,如`GetKeyState`,它用于获取特定键盘键的状态。在易语言中,这可以通过`声明`语句完成。 3. 调用API函数:使用`调用`语句来执行API函数。例如,调用`GetKeyState`并传入对应的...

Global site tag (gtag.js) - Google Analytics