如何监听Winapi中的所有按键并取消其中的一些?

How to listen to all keypresses in Winapi and cancel some of them?

我正在尝试用 C(++) 为我糟糕的双击键盘编写一个键盘软件去抖动程序。

我显然需要为 WM_KEYBOARD_LL 设置一个挂钩,但我 a) 做不到,我有“无效句柄”错误和 b) 不知道如何取消按键,因为我也想为游戏做这个。

我该如何正确实施?

提前致谢!

编辑:这是我在某处找到的无效代码

#include "windows.h"
#include <iostream>
using namespace std;

HHOOK hookHandle;

LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam);

int main(int argc, char *argv[])
{

  hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, keyHandler, NULL, 0);

  if (hookHandle == NULL)
  {
    cout << "ERROR CREATING HOOK: ";
    cout << GetLastError() << endl;
    getchar();
    return 0;
  }

  MSG message;

  while (GetMessage(&message, NULL, 0, 0) != 0)
  {
    TranslateMessage(&message);
    DispatchMessage(&message);
  }

  cout << "Press any key to quit...";
  getchar();

  UnhookWindowsHookEx(hookHandle);

  return 0;
}

LRESULT CALLBACK keyHandler(int nCode, WPARAM wParam, LPARAM lParam)
{
  cout << "Hello!" << endl;

  // Checks whether params contain action about keystroke
  if (nCode == HC_ACTION)
  {
    cout << ((KBDLLHOOKSTRUCT *)lParam)->vkCode << endl;
  }

  return CallNextHookEx(hookHandle, nCode,
                        wParam, lParam);
}

我在 Linux 上使用 Mingw-W64 编译它,但在 Windows 上的 MSVC 和 Mingw-W64 上重现错误。

I apparently need to set a hook to WM_KEYBOARD_LL, but I ... couldn't do it, I have "invalid handle" errors

根据 SetWindowsHookEx() 文档:

An error may occur if the hMod parameter is NULL and the dwThreadId parameter is zero or specifies the identifier of a thread created by another process.

这正是您正在做的。

因此,如果您的目标是全局挂钩每个 运行 进程(即 dwThreadId=0),则需要将 non-NULL HMODULE 传递给 hMod 参数。 Low-level 挂钩不需要作为 DLL 实现,因此您应该能够使用 GetModuleHandle() 函数(例如,使用 lpModuleName=NULLlpModuleName="kernel32.dll" 就足够了)。

[I] don't know how to cancel the keypresses

根据 LowLevelKeyboardProc 文档:

Return value

...

If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD_LL hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.