Для моего проекта в колледже я разрабатываю решение, позволяющее отличить данные пользователя мыши от человека с болезнью Паркинсона от здорового человека.Для которых мне нужны данные мыши, в идеале необработанные.
Полагаю, я неправильно понял, как собирать необработанные данные мыши из сообщения 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!!!");
}
}
}