我正在尝试为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窗口定义为目标。 gameWindowHandle
由EnumWindows
设置。
我改变的另一行是最后一行,因为存在语法错误(缺少括号)。
据我所知,文档正确,这应该是它。现在,当有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?
答案 0 :(得分:1)
你的做法是错误的。首先,RawInput需要Window。用你自己的WndProc控制一个窗口。因此,在C ++库中,您应该定义一个窗口过程。开始一个帖子。在此线程寄存器窗口类中使用该过程。成功注册类后,创建HWND_MESSAGE窗口,注册设备并输入一段时间GetMessage ... DispatchMessage循环。这应该在一个单独的线程中完成。在窗口过程中,您现在必须捕获WM_INPUT消息。请享用。