2016-08-12 5 views
1

О

Я пытаюсь создать пользовательский ввод ввода для 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?

+0

Я портировал все в проект CLR, где я создал экземпляр Windows. К сожалению, я все еще получаю сообщение «Ошибка 87: параметр неверен». –

ответ

1

Ваш подход неправильный. Во-первых, для RawInput требуется Window. Окно под вашим контролем со своим собственным WndProc. Следовательно, в вашей библиотеке C++ вы должны определить процедуру окна. Начать тему. В этом классе окна регистра потока с этой процедурой. После того, как вам удастся зарегистрировать свой класс, создайте окно HWND_MESSAGE, зарегистрируйте свои устройства и введите GetMessage ...DispatchMessage loop. Это должно быть сделано в отдельном потоке. В процедуре окна вы должны теперь улавливать сообщения WM_INPUT. Наслаждаться.

+0

Большое спасибо за ваш ответ! Я, наконец, решил это с помощью приложения C# Windows Forms, где я получаю сообщения WM_INPUT и передаю их в единицу ([ссылка на решение] (http://stackoverflow.com/questions/38959771/weird-values-from-wm-input -casting-ошибка)). Я правильно ответил на ваш ответ, потому что ошибка, которую я совершил, была, как вы сказали, у меня не было окна. Может быть, я пошлю C-решение на C с вашими подсказками. Так что спасибо много! –

+1

Вот мое решение в простой C++-родной DLL, которую вы запускаете/poll/kill со своего сценария C#. Реализация его на C++ даст вам довольно хорошую производительность. C++ DLL: http://pastebin.com/0Szi8ga6 C# wrapper: http://pastebin.com/4h3CqpYy –

 Смежные вопросы

  • Нет связанных вопросов^_^