问题描述
|
我开始利用Win32的原始输入功能来检测键盘上的所有键。到目前为止,一切正常!我可以区分第一行的数字和右侧小键盘的数字。我什至可以在左右移动键之间进行检测。但是,control和alt键不会返回唯一的扫描代码。控制键返回29,而alt键返回56。
检查这些键的键状态的常用方法是“ 0”。我已经使用
VK_LCONTROL
和VK_RCONTROL
测试了该功能,并且可以正常工作,但这仅有助于捕获按键事件。我也非常希望能够捕获关键事件。很明显,API可以某种方式知道正在按下哪个键。我如何获得这些信息?
我目前正在从“ 3”结构的“ 4”字段中提取扫描代码。这为我提供了有关除CTRL和ALT之外的每个键(及其左/右对齐)的信息。我将如何捕获关键事件(并知道它是左/右)?是否可以仅使用RAWKEYBOARD
结构?还是我必须炮制某种解决方法?
解决方法
如果您希望获得足够低的级别来检测按键启动事件,则应处理WM_KEYDOWN和WM_KEYUP事件:
http://msdn.microsoft.com/zh-cn/library/ms646267%28v=vs.85%29.aspx#_win32_Keystroke_Messages
按下一个键会导致WM_KEYDOWN或
WM_SYSKEYDOWN消息要放入
附加到的线程消息队列
带有键盘的窗口
焦点。释放钥匙会导致
WM_KEYUP或WM_SYSKEYUP消息为
放在队列中。
按键和按键信息通常
成对出现,但如果用户持有
按下足够长的时间以启动
键盘的自动重复功能,
系统会产生许多
WM_KEYDOWN或WM_SYSKEYDOWN消息
连续。然后生成一个
WM_KEYUP或WM_SYSKEYUP消息何时
用户释放密钥。
要区分Shift,Ctrl或Alt键的左右版本,您必须使用
MapVirtualKey()
函数或随虚拟键消息传递的lParam中的“扩展键”位。以下功能将为您执行该转换-只需从消息中传入虚拟键码和lParam,然后您将视情况取回左/右特定的虚拟键码:
WPARAM MapLeftRightKeys( WPARAM vk,LPARAM lParam)
{
WPARAM new_vk = vk;
UINT scancode = (lParam & 0x00ff0000) >> 16;
int extended = (lParam & 0x01000000) != 0;
switch (vk) {
case VK_SHIFT:
new_vk = MapVirtualKey(scancode,MAPVK_VSC_TO_VK_EX);
break;
case VK_CONTROL:
new_vk = extended ? VK_RCONTROL : VK_LCONTROL;
break;
case VK_MENU:
new_vk = extended ? VK_RMENU : VK_LMENU;
break;
default:
// not a key we map from generic to left/right specialized
// just return it.
new_vk = vk;
break;
}
return new_vk;
}
如果传入的虚拟键码不是映射到左/右版本的虚拟键码,则原始键码会原样传递回去。因此,只要需要在左右变体之间进行区分时,就可以通过函数运行消息参数WM_KEYDOWN
/WM_KEYUP
/WM_SYSKEYDOWN
/WM_SYSKEYUP
。
,GetAsyncKeyState \的文档说:
...如果最高有效位是
设置好了,钥匙按下了...
这也意味着,如果清除了MSB,则表示密钥已打开。