The*_*Saw 5 c c++ keyboard winapi input
我开始利用Win32的原始输入功能来检测键盘上的所有键.到目前为止,一切都很好!我可以区分顶行的数字和右侧键盘的数字.我甚至可以检测左右键之间的键.但是,control和alt键不会返回唯一的扫描码.该control键返回29,和alt键返回56.
检查这些键上的关键状态的流行方法是GetAsyncKeyState
.我已经使用VK_LCONTROL
和测试了该功能VK_RCONTROL
,并且它可以工作,但这只能帮助我捕获按键事件.我真的希望能够捕获关键事件.很明显,API在某种程度上意识到正在按下哪个键; 我如何获得这些信息?
我目前正在从RAWKEYBOARD
结构的MakeCode
字段中提取扫描代码.这给了我关于每个键(及其左/右对齐)的信息,除了CTRL和ALT.我如何捕获关键事件(并知道它是左/右)?是否可以只使用RAWKEYBOARD
结构?或者我是否需要编制某种解决方法?
如果你想获得足够低的水平来检测关键事件,你应该处理WM_KEYDOWN和WM_KEYUP事件:
按一个键会导致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;
}
Run Code Online (Sandbox Code Playgroud)
如果传入的虚拟键码不是映射到左/右版本的虚拟键码,则原始键码将不加改变地传回.因此,只要需要区分左右变体,就可以通过函数运行WM_KEYDOWN
/ WM_KEYUP
/ WM_SYSKEYDOWN
/ WM_SYSKEYUP
message参数.
归档时间: |
|
查看次数: |
4679 次 |
最近记录: |