Проблема с перехватом сообщения 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

Другие вопросы по тегам