Проблема с перехватом сообщения WM_INPUT для lParam, чтобы собрать ввод Raw Mouse
Для моего проекта в колледже я разрабатываю решение, позволяющее отличить данные пользователя мыши от человека с болезнью Паркинсона от здорового человека. Для которого мне нужны данные мыши, в идеале необработанные.
Я полагаю, что я неправильно понял, как собирать необработанные данные мыши из сообщения WM_INPUT, но я не могу понять это.
Я смотрел на следующую ветку: Как точно измерить движение мыши в дюймах или сантиметрах для мыши с известными библиотеками ввода DPI и Mouse на github, которые, похоже, легко перехватывают сообщение WM_INPUT, lParam которого является дескриптором некоторого RawInputData с чем-то вроде этого:
GetMessage(&msg, GetActiveWindow(), WM_INPUT, 0);
if (msg.message == WM_INPUT){ .....
А затем извлекает lParam из сообщения и собирает данные, связанные с этим дескриптором:
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
Однако, когда я звоню GetMessage
в моем основном цикле функция никогда не завершается! Следовательно, для меня нет способа (о котором я знаю) получить указатель на RawInputData. Тем более что страница MSDN предполагает, что у вас уже есть lParam.
В итоге мне нужен метод получения lParam для передачи на GetRawInputData
функция, которая останется активной, если программа запущена в активном окне или нет.
Я запускаю этот код в пустом C++ CLR-проекте в Visual Studio с библиотекой "winuser.h".
#include "stdafx.h"
#include "Windows.h"
#include "winuser.h"
#ifndef HID_USAGE_PAGE_GENERIC
#define HID_USAGE_PAGE_GENERIC ((USHORT) 0x01)
#endif
#ifndef HID_USAGE_GENERIC_MOUSE
#define HID_USAGE_GENERIC_MOUSE ((USHORT) 0x02)
#endif
int main(array<System::String ^> ^args)
{
RAWINPUTDEVICE Rid[1];
Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
Rid[0].dwFlags = 0; //ideally RIDEV_INPUTSINK but that prevents registration
Rid[0].hwndTarget = GetActiveWindow(); //ideally this would be Null to be independent of the active window
if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) {
//registration failed. Call GetLastError for the cause of the error
Console::WriteLine("Registration Error");
}
MSG msg;
while (true) {
while (GetMessage(&msg, GetActiveWindow(), WM_INPUT, 0) != 0) { //this command is never completed
DispatchMessage(&msg); //this line is never ran
}
if (msg.message == WM_INPUT) {
Console::WriteLine("caught a message!!!");
}
}
}
1 ответ
Проблема была решена после долгих исследований, и я обнаружил, что в winAPI я исправил проблему, добавив:int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE unused, PSTR cmd, int show) {.....}
Функция для регистрации устройств и создания окна, затем вызвать GetMessage
какие звонки LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {....}
с параметрами, занятыми идентификатором сообщения,WParam и LParam, соответствующими событию сообщения. Для тех, кто столкнулся с подобной проблемой, следуйте этому руководству MSDN: https://msdn.microsoft.com/en-us/library/bb384843.aspx