如何在 C++ 中使用 Windows LLKeyboard Hook 进行组合按键
How to use Windows LLKeyboard Hook for Combination Keypresses in C++
我有一个工作 Windows 挂钩来检测 LCTRL + x 和 LCTRL + v 的简单按键组合。我遇到的唯一问题是当我按下 LCTRL,然后释放,然后按下 x 或v,我的程序认为它们仍然被压在一起。
这是我的 Hook 回调函数:
HHOOK hookHandle;
KBDLLHOOKSTRUCT hookdata;
LRESULT __stdcall HookCallback(int code, WPARAM wparam, LPARAM lparam)
{
if (code >= 0)
{
if (wparam == WM_KEYDOWN)
{
hookdata = *((KBDLLHOOKSTRUCT*)lparam);
switch(hookdata.vkCode)
{
case(88):
if(GetAsyncKeyState(VK_LCONTROL))
{
std::cout<<"CTRL X PRESSED";
}
break;
case (86):
if(GetAsyncKeyState(VK_LCONTROL))
{
std::cout<<"CTRL V PRESSED";
}
break;
}
}
}
return CallNextHookEx(hookHandle, code, wparam, lparam);
}
示例输入
Test 1) Press LCTRL, Press X
Test 2) Press LCTRL, Release LCTRL, Press X
预期输出
Test 1) CTRL X PRESSED
Test 2) No Output
实际输出
Test 1) CTRL X PRESSED (WORKING)
Test 2) CTRL X PRESSED (NOT WORKING)
您错误地检查了 GetAsyncKeyState
的 return 值:
If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior; for more information, see the Remarks.
将检查更改为 GetAsyncKeyState(...) & 0x8000
以通过仅检查最高位来解决此问题。
一件小事:Microsoft 使 VK 值与 ASCII 码相同。由于完全可移植性在这里不太重要,您可以使用 'X'
和 'V'
而不是 88
和 86
来更好地表达意图。
我有一个工作 Windows 挂钩来检测 LCTRL + x 和 LCTRL + v 的简单按键组合。我遇到的唯一问题是当我按下 LCTRL,然后释放,然后按下 x 或v,我的程序认为它们仍然被压在一起。 这是我的 Hook 回调函数:
HHOOK hookHandle;
KBDLLHOOKSTRUCT hookdata;
LRESULT __stdcall HookCallback(int code, WPARAM wparam, LPARAM lparam)
{
if (code >= 0)
{
if (wparam == WM_KEYDOWN)
{
hookdata = *((KBDLLHOOKSTRUCT*)lparam);
switch(hookdata.vkCode)
{
case(88):
if(GetAsyncKeyState(VK_LCONTROL))
{
std::cout<<"CTRL X PRESSED";
}
break;
case (86):
if(GetAsyncKeyState(VK_LCONTROL))
{
std::cout<<"CTRL V PRESSED";
}
break;
}
}
}
return CallNextHookEx(hookHandle, code, wparam, lparam);
}
示例输入
Test 1) Press LCTRL, Press X
Test 2) Press LCTRL, Release LCTRL, Press X
预期输出
Test 1) CTRL X PRESSED
Test 2) No Output
实际输出
Test 1) CTRL X PRESSED (WORKING)
Test 2) CTRL X PRESSED (NOT WORKING)
您错误地检查了 GetAsyncKeyState
的 return 值:
If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior; for more information, see the Remarks.
将检查更改为 GetAsyncKeyState(...) & 0x8000
以通过仅检查最高位来解决此问题。
一件小事:Microsoft 使 VK 值与 ASCII 码相同。由于完全可移植性在这里不太重要,您可以使用 'X'
和 'V'
而不是 88
和 86
来更好地表达意图。