我想抓住按键发送到我的窗口以存储每个键的状态,并区分键的左右实例,如WM_LCONTROL
和WM_RCONTROL
。
由于WM_KEYUP/DOWN
不提供此功能所以我转移到原始输入,我需要处理WM_INPUT
。
问题是来自RAWKEYBOARD
结构的标记here描述不起作用。
当我按下右控制键时,设置RI_KEY_E0
,用于左侧版本
键,当我按左控制键时,RI_KEY_E0
和RI_KEY_E1
都没有设置。
alt键执行类似,但我可以解决此问题,因为左仍然提供右键的不同标志。
但是对于左右移位键,没有设置任何标志来区分左侧版本和右侧版本,因此我无法对它们做任何事情。
WM_INPUT
到达时给出的虚拟密钥代码不区分左右键,并且在扫描代码上使用MapVirtualKey
也不起作用。
原始投入的这种非正统行为是怎么回事?
一些代码:
注册:
RAWINPUTDEVICE rid;
rid.usUsagePage=0x01;
rid.usUsage=0x06;
rid.dwFlags=0; // I also tried RIDEV_APPKEYS,RIDEV_NOHOTKEYS,RIDEV_NOLEGACY, none fixed the problem
rid.hwndTarget=hwnd;
if(!RegisterRawInputDevices(&rid,1,sizeof(RAWINPUTDEVICE)))
ExitError("Failed to register raw input device",true); //displays error and exits
处理WM_INPUT:
case WM_INPUT:
{
RAWINPUT rw;
UINT sz=sizeof(rw);
u_char vk; //used to make code shorter
USHORT flag; //used to make code shorter
if(!GetRawInputData((HRAWINPUT)lparam,RID_INPUT,&rw,&sz,sizeof(RAWINPUTHEADER)))
break;
vk=rw.data.keyboard.VKey;
flag=rw.data.keyboard.Flags;
...Process flags and save the actual key pressed in vk...
keys[vk]=!(flag&RI_KEY_BREAK); //save key's state
break;
}
答案 0 :(得分:1)
WM_KEYDOWN/-UP
会提供您想要的信息,您只需阅读MSDN中的说明。
检查lParam参数的第24位。
答案 1 :(得分:0)
WM_KEYDOWN
和WM_KEYUP
会在VK_CONTROL
中向您发送wParam
。要确定是否按下了右侧控制键,请阅读lParam
的第24位,如MSDN documentation中所述。第24位描述如下:
指示密钥是否为扩展密钥,例如增强型101键或102键键盘上显示的右侧ALT和CTRL键。如果它是扩展密钥,则值为1;否则,它是0。
答案 2 :(得分:0)
RAWKEYBORAD的文档错误。常量RI_KEY_E0
和RI_KEY_E1
不适用于 left 或 right 版本的键;相反,它们适用于扫描码扩展。
转储到RAWKEYBOARD::VKey
的虚拟键值指的是VK_SHIFT
,VK_CONTROL
或VK_MENU
等通用值。
要更正此问题,可以使用RAWKEYBOARD::VKey
和RAWKEYBOARD::MakeCode
成员。不同的键以不同的方式区分不同的方面:
MapVirtualKey
重新分配轮班键并将RAWKEYBOARD::MakeCode
和MAPVK_VSC_TO_VK_EX
作为参数传递,RI_KEY_E0
标志的控制和alt键映射(例如key.VKey = key.Flags & RI_KEY_E0 ? VK_RCONTROL : VK_LCONTROL
)。您想要从小键盘中获得的值取决于您是将NUMLK视为打开还是关闭。
我和你有同样的困惑,我仍在学习键盘如何传输数据,但我发现 Molecular Musings 上的this博客文章特别有帮助。这种方法背后的原因可以在this帖子中找到。