【发布时间】:2009-11-28 01:02:43
【问题描述】:
在 Win32 上,我想知道如何使用 Perl、Python 或 Ruby(甚至在 C 中)检测是否按下了 Left Shift 或 Right ALT?
不仅针对当前窗口,还针对整个全局环境。示例:当我在输入文档时,可以按右 ALT 键启动用 Ruby 编写的音乐播放器,然后再按右 ALT 键可以暂停或停止程序。谢谢。
【问题讨论】:
标签: ruby perl user-interface events winapi
在 Win32 上,我想知道如何使用 Perl、Python 或 Ruby(甚至在 C 中)检测是否按下了 Left Shift 或 Right ALT?
不仅针对当前窗口,还针对整个全局环境。示例:当我在输入文档时,可以按右 ALT 键启动用 Ruby 编写的音乐播放器,然后再按右 ALT 键可以暂停或停止程序。谢谢。
【问题讨论】:
标签: ruby perl user-interface events winapi
您需要设置一个低级键盘挂钩。为此,您可以使用 LowLevelKeyboardProc 调用 SetWindowsHookEx,然后注意寻找合适的 virtual key code。
有左右shift和alt键的键码。
【讨论】:
我相信您也可以通过 GetKeyState 获取虚拟密钥的状态,例如GetKeyState(VK_RSHIFT)。尽管使用 Reed Copsey 描述的钩子可能更适合您的目的,而不是轮询此函数。
【讨论】:
如果您想知道按键的当前状态现在,您可以使用GetAsyncKeyState() 和VK_LSHIFT 或VK_RMENU 参数分别表示左移和右移。确保测试结果的最高有效位,因为结果包含不止一位信息,例如
if(GetAsyncKeyState(VK_LSHIFT) & 0x8000)
; // left shift is currently down
如果您希望收到按键通知而不是异步轮询按键,则应收听WM_KEYDOWN 窗口通知。在窗口的消息处理程序中添加这样的内容:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
...
case WM_KEYDOWN:
if(wparam == VK_LSHIFT)
; // left shift was pressed
// etc.
break;
}
}
您还必须处理 WM_KEYUP 消息才能知道何时释放键。
【讨论】:
使用 WM_SYSKEYDOWN 和 WM_SYSKEYUP 代替 WM_KEYDOWN 和 WM_KEYUP;然后您可以检查它是 VK_LSHIFT 还是 VK_MENU 等,它会在这些事件发生时捕获它们。
【讨论】:
WM_SYSKEY[DOWN|UP] 被发送,如果用户在按住 [Alt] 键的同时键入一个键。这不是OP所要求的。他们希望在按下右 [Alt] 键时得到通知。 WM_KEYDOWN 在低级键盘钩子中是正确的解决方案。