从 Unity window 获取 WM_INPUT
Get WM_INPUT from Unity window
关于
我正在尝试为 Unity 构建自定义鼠标输入,以直接从 HID 获取数据。我这样做是因为我想尝试一下(当使用我自己的自定义鼠标输入时)与给我原始鼠标输入的 Unity API 是否有任何区别。
另外我需要说的是,我现在所做的一切都不会发生在 Unity 中。我想构建一个 C++ 应用程序,然后将数据传递给 Unity(这不是这个问题的一部分)。
这个 link (MSDN High-Definition Mouse Movement) 表明我可以使用三种不同类型的消息。由于我需要所谓的 "High-Definition Mouse Movement" 我需要使用 WM_INPUT
.
如文档所述,可以使用 WinProc 处理程序捕获此消息。在该回调中,可以访问原始鼠标数据。这就是我想要实现的目标,也是我需要帮助的地方。
我目前的做法
文档(上面的link)给了我这个注册鼠标的例子:
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 window 定义为目标。 gameWindowHandle
由 EnumWindows
.
设置
由于语法错误(缺少括号),我更改的另一行是最后一行。
据我对文档的理解,应该是这样。现在,当有 WM_INPUT
条消息发送到 Unity window.
时,应调用以下回调
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]));
不 return 正确。相反,它 returns false 和 GetLastError
给我错误 87(谷歌搜索后我发现它与错误的参数有关)。
文档说要这样做,但不幸的是,它并不像我那样工作。
另一个问题是如何保持应用程序的存活。注册设备后,我需要等待回调触发(如果它们可以工作)。我怎样才能让应用程序只等待回调?
我的方法是否合理,或者我做的完全错了,必须使用不同的 APIs?
你的做法是错误的。首先,RawInput 需要 Window。由您自己的 WndProc 控制的 Window。因此,在您的 C++ 库中,您应该定义一个 window 过程。启动线程。在这个线程中用那个程序注册window class。在您成功注册您的 class 后,创建 HWND_MESSAGE window,注册您的设备并进入 while GetMessage... DispatchMessage 循环。这应该在一个单独的线程中完成。在您的 window 过程中,您现在必须捕获 WM_INPUT 消息。享受。
关于
我正在尝试为 Unity 构建自定义鼠标输入,以直接从 HID 获取数据。我这样做是因为我想尝试一下(当使用我自己的自定义鼠标输入时)与给我原始鼠标输入的 Unity API 是否有任何区别。
另外我需要说的是,我现在所做的一切都不会发生在 Unity 中。我想构建一个 C++ 应用程序,然后将数据传递给 Unity(这不是这个问题的一部分)。
这个 link (MSDN High-Definition Mouse Movement) 表明我可以使用三种不同类型的消息。由于我需要所谓的 "High-Definition Mouse Movement" 我需要使用 WM_INPUT
.
如文档所述,可以使用 WinProc 处理程序捕获此消息。在该回调中,可以访问原始鼠标数据。这就是我想要实现的目标,也是我需要帮助的地方。
我目前的做法
文档(上面的link)给了我这个注册鼠标的例子:
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 window 定义为目标。 gameWindowHandle
由 EnumWindows
.
由于语法错误(缺少括号),我更改的另一行是最后一行。
据我对文档的理解,应该是这样。现在,当有 WM_INPUT
条消息发送到 Unity window.
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]));
不 return 正确。相反,它 returns false 和 GetLastError
给我错误 87(谷歌搜索后我发现它与错误的参数有关)。
文档说要这样做,但不幸的是,它并不像我那样工作。
另一个问题是如何保持应用程序的存活。注册设备后,我需要等待回调触发(如果它们可以工作)。我怎样才能让应用程序只等待回调?
我的方法是否合理,或者我做的完全错了,必须使用不同的 APIs?
你的做法是错误的。首先,RawInput 需要 Window。由您自己的 WndProc 控制的 Window。因此,在您的 C++ 库中,您应该定义一个 window 过程。启动线程。在这个线程中用那个程序注册window class。在您成功注册您的 class 后,创建 HWND_MESSAGE window,注册您的设备并进入 while GetMessage... DispatchMessage 循环。这应该在一个单独的线程中完成。在您的 window 过程中,您现在必须捕获 WM_INPUT 消息。享受。