从Unity窗口获取WM_INPUT

Get WM_INPUT from Unity window

本文关键字:INPUT WM 获取 Unity 窗口      更新时间:2023-10-16

关于

我正在尝试为Unity构建一个自定义鼠标输入,它直接从HID获取数据。我这么做是因为我想尝试一下(当使用我自己的自定义鼠标输入时(给我原始鼠标输入的Unity API是否有任何差异。

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

这个链接(MSDN高清鼠标移动(显示我可以使用三种不同类型的消息。由于我需要所谓的"高清鼠标运动",我需要使用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窗口定义为目标。CCD_ 2由CCD_。

由于语法错误(缺少括号(,我更改的另一行是最后一行。

就我对文档的理解而言,应该就是这样。现在,当有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?

您的方法是错误的。首先,RawInput需要Window。一个窗口在您的控制下与您自己的WndProc。因此,在C++库中,应该定义一个窗口过程。启动线程。在这个线程中,用那个过程注册窗口类。成功注册类后,创建HWND_MESSAGE窗口,注册设备并输入一段时间GetMessage。。。DispatchMessage循环。这应该在一个单独的线程中完成。在窗口过程中,您现在必须捕获WM_INPUT消息。享受