根据 MSDN wparam 应该保存关键代码。问题是,当按下 shift 时,代码是 16(VK_SHIFT),但我需要区分 VK_LSHIFT 和 VK_RSHIFT。
对于 VK_CONTROL,似乎有一个解决方法:
if(wParam == VK_CONTROL) {
if ( lParam&EXTENDED_KEYMASK )
wParam = VK_RCONTROL;
else
wParam = VK_LCONTROL;
}
但是,这对 VK_SHIFT 不起作用:
if(wparam == VK_SHIFT) {
if ( lParam&EXTENDED_KEYMASK )
wParam = VK_RSHIFT;
else
wParam = VK_LSHIFT;
}
在后一个示例中,它将始终假设为 LSHIFT。
最佳答案
要区分 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
消息参数区分左右变体。
通过使用 MapVirtualKey()
,您无需了解有关左移和右移扫描码为 0x2a 和 0x36 的知识 - API 会处理这些细节。如果它们碰巧发生了不同(不会真的发生),Windows 将负责处理它,而不是你。
因此,在您的 WM_KEYDOWN
/WM_KEYUP
/WM_SYSKEYDOWN
/WM_SYSKEYUP
处理程序中,您只需添加一行看起来像的代码:
wparam = MapLeftRightKeys(wparam, lparam);
您的其余代码可以对左/右特定 VK 代码执行操作,就好像系统消息首先将它们提供给您一样。
关于c - 在 WM_KEYDOWN 事件中如何区分 LSHIFT 和 RSHIFT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15966642/