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 

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











转载于:https://www.cnblogs.com/llguanli/p/8427384.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你月薪多少?

今天跟一个读友聊天&#xff0c;他刚毕业没多久&#xff0c;在一家方案公司上班&#xff0c;月薪6.5&#xff0c;做的Android 开发&#xff0c;用RK方案&#xff0c;有时候也需要做MCU相关的开发&#xff0c;事情多&#xff0c;压力也不少&#xff0c;而且不是双休&#xff0c;…

cx_Oracle安装出现的问题

1.安装cx_Oracle &#xff08;1&#xff09;在线安装 pip install cx_Oracle &#xff08;2&#xff09;源码安装 下载源码&#xff1a;https://pypi.org/project/cx-Oracle/ tar -zxvf cx_Oracle-8.1.0.tar.gz cd cx_Oracle-8.1.0 python setup.py install 2.测试 impo…

凡事想开,心情不坏~

制芰荷以为衣兮&#xff0c;集芙蓉以为裳。 不吾知其亦已兮&#xff0c;苟余情其信芳。 高余冠之岌岌兮&#xff0c;长余佩之陆离。 芳与泽其杂糅兮&#xff0c;唯昭质其犹未亏。 忽反顾以游目兮&#xff0c;将往观乎四荒。 佩缤纷其繁饰兮&#xff0c;芳菲菲其弥章。 民生各有…

Linux C高级编程——网络编程之以太网(2)

Linux网络编程——以太网 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 1、以太网帧格式 源地址和目的地址是指网卡的硬件地址&#xff08;也叫MAC地址&#xff09;&#xff0c;长度是48位&#xff0c;是在网卡出厂时固化的。用ifconfig命令查看&#…

Tomcat 打开jmx

jmx 配置后可以通过windows java客户端自带的jconsole.exe配置登陆&#xff0c;直观的查看jvm的情况及系统的各项指标&#xff1b; 一、配置linux下tomcat的jmx 具体配置如下&#xff0c;如果生产环境可以适当坐下调整。 # head /usr/local/tomcat/bin/catalina.sh #!/bin/shC…

Python学习——常见的字符串匹配

在处理字符串的时候&#xff0c;经常会有需要提取和替换的情况&#xff0c;记录自己常用的方法。 这个涉及正则表达式的用法&#xff0c;因为我是在Series的str属性在用&#xff0c;方法是同宗&#xff0c;存在略微格式的不一致。 1、替换str的中括号 Series.str.replace([\…

我不是编译器专家

这是王垠发表的一篇文章&#xff0c;转给大家看看&#xff0c;希望有些收获王垠是谁&#xff1f;王垠&#xff0c;四川大学97级本科毕业&#xff0c;保送到清华大学计算机系直博。期间曾在清华大学计算机系软件所就读&#xff0c;主要进行集成电路布线算法的研究。在此期间&…

自定义实体类简介

< DOCTYPE html PUBLIC -WCDTD XHTML TransitionalEN httpwwwworgTRxhtmlDTDxhtml-transitionaldtd> 摘要&#xff1a;有些情况下&#xff0c;非类型化的 DataSet 可能并非数据操作的最佳解决方案。本指南的目的就是探讨 DataSet 的一种替代解决方案&#xff0c;即&#…

Linux C高级编程——网络编程之TCP(3)

Linux网络编程&#xff08;三&#xff09;——TCP 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 1、TCP段格式 和UDP协议一样也有源端口号和目的端口号&#xff0c;通讯的双方由IP地址和端口号标识。32位序号、32位确认序号、窗口大小。4位首部长度和I…

机器学习——超参数调优

超参数是在开始学习过程之前设置值的参数&#xff0c;而不是通过训练得到的参数数据。超参数可以分为两种类型&#xff1a;定义模型及结构本身的参数&#xff0c;目标函数与与优化算法所需的参数&#xff0c;前者用于训练和预测阶段&#xff0c;后者用于训练阶段。 在实战过程…

单片机的Bootloader,可以实现用户轻松升级程序

去某新能源大厂出了一次差&#xff0c;这次出差是为了升级程序解决Bug&#xff0c;需要给单片机重新烧录.hex文件&#xff0c;用户已经将产品封装起来&#xff0c;无法开盖&#xff0c;只能使用CAN总线来更新程序&#xff0c;用Bootloader实现。其实就是通过上位机把.bin/hex文…

小结三种控制路由发布的方法

1、分配列表&#xff08;distribute-list&#xff09;直接过滤更新协议中的该条路由。优点是简单&#xff0c;可有效减少更新包中所带路由的数量&#xff0c;直接体现其带宽占用的优势&#xff0c;并且路由器参与的处理较少&#xff0c;节省CPU、内存等资源&#xff1b;缺点是适…

Linux C高级编程——网络编程之UDP(4)

Linux网络编程——UDP 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 下面分析一帧基于UDP的TFTP协议帧。 以太网首部 0000: 00 05 5d 67 d0 b1 00 05 5d 61 58 a8 08 00 IP首部0000: 45 00 0010: 00 53 93 25 00 00 80 11 25 ec c0 a8 00 37 c0 a8…

Android串口通信apk源码

1、SerialPortHelper「Android串口通信」介绍原项目地址https://github.com/freyskill/SerialPortHelperAndroid串口通讯助手可以用于需要使用串口通信的Android外设&#xff0c;该库有如下特点&#xff1a;1、串口通信部分使用C实现&#xff0c;在笔者接触的部分设备上实测&am…

NLP实战-中文新闻文本分类

目录 1、思路 2、基于paddle的ERINE模型进行迁移学习训练 3、分步实现 3.1 获取数据 &#xff08;1&#xff09;数据解压 &#xff08;2&#xff09;将文本转成变量&#xff0c;这里为了好计算&#xff0c;我只选了新闻标题做文本分类 3.2 中文分词 基于jieba的分词 基…

Ken Thompson爷爷的经典复制自身代码程序 - Python版本(只用两行!)

Ken Thompson可是大牛人了&#xff01;不认识的人赶快Google/百度一下。Ken爷爷是Unix创始人&#xff0c;C语言鼻祖&#xff01;Ken 当时大学时候没游戏玩&#xff0c;就自己给自己出题目写程序&#xff0c;就有了这个复制自身代码的程序了&#xff0c;相当经典&#xff0c;当然…

显示日期的指令: date

1.显示日期的指令&#xff1a; date &#xff08;1&#xff09;参数&#xff1a; &#xff08;2&#xff09;实例 转载于:https://www.cnblogs.com/yfacesclub/p/8434369.html

聚类算法——Birch详解

1 原理 1.1 B树 &#xff08;1&#xff09;m路查找树 一棵m路查找树&#xff0c;它或者是一棵空树&#xff0c;或者是满足如下性质的树&#xff1a; 根最多有m棵子树&#xff0c;并具有以下结构&#xff1a; ,是指向子树的指针&#xff0c;是关键码&#xff0c; 在子树中所…

Linux C高级编程——网络编程之API(5)

Linux C网络编程——API 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神的无限的。 一、基本socket函数 Linux系统是通过提供套接字(socket)来进行网络编程的。网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符。socket也有一个类似于打开文件的函数…

机器学习在本体中的应用研究文献综述

机器学习在本体标注中的应用研究文献综述<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />本设计是基于语义搜索引擎展开研究&#xff0c;针对这个新兴的搜索引擎概念的提出&#xff0c;我们搜集了大量的资料并对此进行了一定的研…