О
Я пытаюсь создать пользовательский ввод ввода для Unity, который получает данные непосредственно из HID. Я делаю это, потому что хочу попробовать, если есть какая-либо разница (при использовании моего собственного пользовательского ввода мыши) в Unity API, который дает мне исходный ввод мыши.Получить WM_INPUT из окна 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
.
Другая строка, которую я изменил, является последней из-за ошибки синтаксиса (отсутствующая скобка).
Насколько я понял право на документацию, это должно быть так. Теперь следует вызвать следующий обратный вызов, если в окне Unity отправлено WM_INPUT
сообщений.
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]));
не возвращает истину, как это должно быть. Вместо этого он возвращает false, и GetLastError
дает мне ошибку 87 (после этого я выяснил, что это связано с неправильными параметрами).
В документации говорится об этом, но, к сожалению, это не работает так, как я это делаю.
Другая проблема заключается в том, как сохранить приложение в живых. После регистрации устройства мне нужно дождаться, когда вызовы будут активированы (если они будут работать). Как я могу добиться того, что приложение ничего не делает, кроме ожидания обратных вызовов?
Является ли мой подход разумным или я совершенно ошибаюсь и должен использовать разные API?
Я портировал все в проект CLR, где я создал экземпляр Windows. К сожалению, я все еще получаю сообщение «Ошибка 87: параметр неверен». –