【问题标题】:Trouble catching WM_INPUT message for lParam, to collect Raw Mouse Input无法捕获 lParam 的 WM_INPUT 消息以收集原始鼠标输入
【发布时间】:2018-09-25 12:53:03
【问题描述】:

对于我的大学项目,我正在开发一种解决方案,以区分来自帕金森氏症患者和健康人的鼠标用户数据。我需要鼠标数据,最好是原始数据。

我想我误解了如何从 WM_INPUT 消息中收集原始鼠标输入,但我想不通。

我一直在看以下线程:How to accurately measure mouse movement in inches or centimetres for a mouse with a known DPI 和 github 上的鼠标输入库,所有这些似乎都可以轻松捕获 WM_INPUT 消息,其 lParam 是一些 RawInputData 的句柄,如下所示:

GetMessage(&msg, GetActiveWindow(), WM_INPUT, 0);
if (msg.message == WM_INPUT){  .....

然后从消息中检索 lParam 并收集与该句柄关联的数据:

GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));

但是,当我在主循环中调用 GetMessage 时,函数永远不会退出! 因此,我无法(据我所知)获取 RawInputData 的句柄。特别是因为 MSDN 页面只是假设您已经拥有 lParam。

总之,我需要一种方法让 lParam 传递给 GetRawInputData 函数,无论程序是否在活动窗口中运行,该函数都将保持活动状态。

我正在使用“winuser.h”库在 Visual Studio 中的空白 C++ CLR 项目中运行此代码。

#include "stdafx.h"
#include "Windows.h"
#include "winuser.h"

#ifndef HID_USAGE_PAGE_GENERIC
#define HID_USAGE_PAGE_GENERIC         ((USHORT) 0x01)
#endif
#ifndef HID_USAGE_GENERIC_MOUSE
#define HID_USAGE_GENERIC_MOUSE        ((USHORT) 0x02)
#endif

int main(array<System::String ^> ^args)
{
    RAWINPUTDEVICE Rid[1];
    Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
    Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
    Rid[0].dwFlags = 0; //ideally RIDEV_INPUTSINK but that prevents registration
    Rid[0].hwndTarget = GetActiveWindow(); //ideally this would be Null to be independent of the active window

    if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) {
        //registration failed. Call GetLastError for the cause of the error
        Console::WriteLine("Registration Error");
    }
    MSG msg;

    while (true) {
        while (GetMessage(&msg, GetActiveWindow(), WM_INPUT, 0) != 0) { //this command is never completed
            DispatchMessage(&msg); //this line is never ran
        }
        if (msg.message == WM_INPUT) {
            Console::WriteLine("caught a message!!!");
        }

    }
}

【问题讨论】:

  • WM_INPUT 的文档指出:“仅当应用程序使用有效的设备规范调用 RegisterRawInputDevices 时,原始输入才可用”。你的应用程序这么叫吗?
  • 问题可能在任何地方,我们需要查看minimal reproducible example
  • 抱歉缺少代码,我已经编辑了我的原始帖子,感谢您的反馈:)
  • 好吧,如果我错了,请原谅我,但我从那篇文章中得到的是,我应该通过传递 GetMessage(&amp;msg, NULL, 0, 0) 来从 GetMessage 函数中删除 hwnd 过滤器,但是这会导致与 GetMessage 之前的行为相同,从不返回值。有趣的是peekMessage 确实在msg 对象中返回和设置值。但是我怀疑这是否是完全有效的代码:while (true) { PeekMessage(&amp;msg, NULL, 0, 0, 0); if (msg.message == WM_INPUT) { Console::WriteLine("Found a WMM_INPUT message"); } }

标签: windows winapi c++-cli raw-input


【解决方案1】:

经过更多研究后问题解决了,我发现了 winAPI 演练,我通过添加以下内容来解决上述问题: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE unused, PSTR cmd, int show) {.....} 函数注册设备并创建一个窗口,然后调用GetMessage,它调用LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {....},参数由消息ID、WParam和LParam对应消息事件占用。 对于遇到类似问题的任何人,请遵循此 MSDN 指南:https://msdn.microsoft.com/en-us/library/bb384843.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多