Проблема с перехватом сообщения WM_INPUT для lParam, чтобы собрать ввод Raw Mouse - PullRequest
0 голосов
/ 25 сентября 2018

Для моего проекта в колледже я разрабатываю решение, позволяющее отличить данные пользователя мыши от человека с болезнью Паркинсона от здорового человека.Для которых мне нужны данные мыши, в идеале необработанные.

Полагаю, я неправильно понял, как собирать необработанные данные мыши из сообщения 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 Ответ

0 голосов
/ 08 октября 2018

Проблема решена после гораздо большего количества исследований. Я обнаружил, что пошаговое руководство по 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

...