从Unity窗口获取WM_INPUT

时间:2016-08-12 15:34:52

标签: c++ unity3d input windows-messages

关于

我正在尝试为Unity构建一个自定义鼠标输入,直接从HID获取数据。我之所以这样做,是因为我想尝试使用Unity API进行原始鼠标输入时(如果使用我自己的自定义鼠标输入)有任何不同。

另外我需要说的是,我现在所做的一切都不会发生在Unity中。我想构建一个C ++应用程序,然后将数据传递给Unity(这不是这个问题的一部分)。

此链接(MSDN High-Definition Mouse Movement)显示我可以使用三种不同类型的消息。由于我需要所谓的“高清鼠标移动”,我需要使用WM_INPUT

如文档所述,可以使用WinProc处理程序捕获此消息。在该回调中,可以访问原始鼠标数据。这就是我想要实现的目标,也是我需要帮助的地方。

我目前的做法

文档(上面的链接)给了我这个注册鼠标的例子:

RAWINPUTDEVICE Rid[1];
Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
Rid[0].dwFlags = RIDEV_INPUTSINK;
Rid[0].hwndTarget = gameWindowHandle;

regDeviceDone = RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]));

我修改了以下两行:

Rid[0].hwndTarget = gameWindowHandle;

我将Unity窗口定义为目标。 gameWindowHandleEnumWindows设置。

我改变的另一行是最后一行,因为存在语法错误(缺少括号)。

据我所知,文档正确,这应该是它。现在,当有WM_INPUT个消息发送到Unity窗口时,应调用以下回调。

LRESULT CALLBACK WindowProc(
    _In_ HWND   hwnd,
    _In_ UINT   uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
) {
    printf("%d", uMsg);
    switch (uMsg) { 
        case WM_INPUT:
            UINT dwSize = 40;
            static BYTE lpb[40];

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

            RAWINPUT* raw = (RAWINPUT*)lpb;

            if (raw->header.dwType == RIM_TYPEMOUSE)
            {
                int xPosRelative = raw->data.mouse.lLastX;
                int yPosRelative = raw->data.mouse.lLastY;

                printf("X: %d, Y: %d", xPosRelative, yPosRelative);
            }
            break;
    }

    return NULL;
}

我的问题

我遇到的第一个问题是调用此

regDeviceDone = RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]));

不会返回true。相反,它返回false并且GetLastError给我错误87(在谷歌搜索后我发现它与错误的参数有关)。

文档说这样做但不幸的是它不像我这样做。

另一个问题是如何使应用程序保持活跃状态​​。注册设备后,我需要等待回调触发(如果它们可以工作)。如何实现应用程序除了等待回调之外什么都不做?

我的方法是否合理,还是我做错了,必须使用不同的API?

1 个答案:

答案 0 :(得分:1)

你的做法是错误的。首先,RawInput需要Window。用你自己的WndProc控制一个窗口。因此,在C ++库中,您应该定义一个窗口过程。开始一个帖子。在此线程寄存器窗口类中使用该过程。成功注册类后,创建HWND_MESSAGE窗口,注册设备并输入一段时间GetMessage ... DispatchMessage循环。这应该在一个单独的线程中完成。在窗口过程中,您现在必须捕获WM_INPUT消息。请享用。

相关问题