【问题标题】:Raw Input an alternative keyboard hook?原始输入替代键盘挂钩?
【发布时间】:2011-06-11 10:32:57
【问题描述】:

快速提问--

我正在阅读有关键盘挂钩的信息,有人建议使用原始输入来执行此操作,但我还没有找到任何示例。 例如我正在使用

RAWINPUTDEVICE rid[1];
rid[0].usUsagePage = 0x01;
rid[0].usUsage = 0x06;
rid[0].hwndTarget = hWnd;
rid[0].dwFlags = 0;
RegisterRawInputDevices(rid, 1, sizeof(rid[0]));

并且在应用程序自己的窗口中捕获 WM_INPUT 很好,但在应用程序之外没有。这可能在应用程序之外还是您必须使用 WH_KEYBOARD 或 WH_KEYBOARD_LL? MSDN 没有明确说明 Raw Input 是否可以在全球范围内进行。

编辑:我知道 Hooks,但我想知道你是否也可以使用 Raw 输入来做到这一点!

干杯

【问题讨论】:

    标签: c++ winapi input keyboard hook


    【解决方案1】:

    这就是我初始化RAW INPUT 以全局拦截鼠标和键盘事件的方式。与钩子相比,最大的优势是您不需要 DLL。 您使用WM_INPUT 处理窗口过程中的原始输入事件。欲了解更多信息:RAW INPUT

    #include <Windows.h>
    
    const USHORT HID_MOUSE    = 2;
    const USHORT HID_KEYBOARD = 6;
    
    bool HID_RegisterDevice(HWND hTarget, USHORT usage)
    {
        RAWINPUTDEVICE hid;
        hid.usUsagePage = 1;
        hid.usUsage = usage;
        hid.dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
        hid.hwndTarget = hTarget;
    
        return !!RegisterRawInputDevices(&hid, 1, sizeof(RAWINPUTDEVICE));
    }
    
    void HID_UnregisterDevice(USHORT usage)
    {
        RAWINPUTDEVICE hid;
        hid.usUsagePage = 1;
        hid.usUsage = usage;
        hid.dwFlags = RIDEV_REMOVE;
        hid.hwndTarget = NULL;
    
        RegisterRawInputDevices(&hid, 1, sizeof(RAWINPUTDEVICE));
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR cmd_line, int cmd_show)
    {
        WNDCLASS wc;
        ...
        RegisterClass(&wc);
    
        HWND hwnd = CreateWindow(...);
        ...
    
        HID_RegisterDevice(hwnd, HID_KEYBOARD);
        HID_RegisterDevice(hwnd, HID_MOUSE);
    
        MSG msg;
        while(GetMessage(&msg, NULL, 0, 0))
        {
            ...
        }
    
        HID_UnregisterDevice(HID_MOUSE);
        HID_UnregisterDevice(HID_KEYBOARD);
    
        return (int) msg.wParam;
    }
    

    【讨论】:

      【解决方案2】:

      查看the MSDN documentation for that stuff,有一个名为RIDEV_INPUTSINK 的标志被描述为:“如果设置,即使调用者不在前台,这也使调用者能够接收输入。”

      我自己并没有搞砸,但听起来它对于从应用程序窗口之外获取输入很有用。

      【讨论】:

      • @KaiserJohaan 将此作为公认的最佳答案,因为它是您问题的正确解决方案。我用过很多次了。
      【解决方案3】:

      Windows 挂钩是一种机制,可用于在事件到达应用程序之前对其进行拦截。过滤函数(接收事件的函数)根据事件类型进行分类。如果要附加到 Windows 挂钩,则必须使用 SetWindowsHookEx 安装过滤器功能。不得不提一下,全局钩子必须在一个单独的 dll 文件中。你可以在MSDN阅读更多关于钩子的信息。

      【讨论】:

      • 我说的是原始输入,而不是 Hooks
      • 明白了,尤其是在您编辑了一个问题之后 :) 我认为原始输入消息仅在您的应用程序中可用,而不是全局可用。如果你想全局过滤消息,我认为你必须使用钩子......
      • 其实你可以使用 RIDEV_INPUTSINK 来接收所有键盘输入而不管焦点。
      【解决方案4】:

      不确定原始输入的确切内容,但对于键盘挂钩,通常您需要将其设为 dll 并在系统中注册,以便每个进程都加载它。备注中的一些细节here

      【讨论】:

      • WH_KEYBOARDWH_KEYBOARD_LL 都不需要放在 DLL 中。此外,问题是询问原始输入,原始输入可以监控系统范围的输入事件。
      猜你喜欢
      • 1970-01-01
      • 2016-12-14
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-27
      • 1970-01-01
      相关资源
      最近更新 更多