Search code examples
c++qtwinapimouseeventraw-input

Get Raw Mouse Movement in Qt


After working on this and QAbstractNativeEventFilter class I finally got native events from HID (both mouse and keyboard).

I've read many similar questions but none solved my problem. I try to get mouse movement based on dpi. I work on Qt 5.5 cause my whole project built there.

I can't separate mouse movement events from other HID events (mouse and keyboard) even with RIM_TYPEMOUSE flag.

Here is some code from my implementation:

bool MouseRawMovement::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{   
    if(eventType == "windows_generic_MSG")
    {
        MSG *msg = reinterpret_cast<MSG*>(message);
        qDebug()<<msg->message; // It prints numbers such as 6,26,28,141 on each event
        if(msg->message == WM_INPUT) //it never gets in
        {
        UINT dwSize = 40;
        static BYTE lpb[40];
        GetRawInputData((HRAWINPUT)msg->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;

            qDebug()<<xPosRelative<<yPosRelative ;
        }
        }
    }
    return false;
}

Also here is my constructor

    MouseRawMovement::MouseRawMovement()
    {
       Rid[0].usUsagePage = 0x01;
       Rid[0].usUsage = 0x02;
       Rid[0].dwFlags = RIDEV_INPUTSINK;
       Rid[0].hwndTarget = 0;
       if(!RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])))
           qDebug()<<QString::number(GetLastError()); //I see error msg 6 - Ref. ERROR_INVALID_HANDLE
    }

Output shows me zeros (0) all time.

Whats going on with hWnd. I tried to give this:

HWND hWnd =::GetConsoleWindow();

but I had the same result.

In main.cpp I install native Filter

MainWindow w;
a.installNativeEventFilter(&w.mm);

I try for days and I could not find the solution. Is there anyone...(???)


Solution

  • @nnatarr your help was substantial! Thank you!!!

    I finally find the solution.

    I had to call RegisterRawInputDevices in main.cpp and change lot of things.

    Here is main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    #include <windows.h>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        a.installNativeEventFilter(&w.mm);
        w.show();
    
        UINT nDevices;
       PRAWINPUTDEVICELIST pRawInputDeviceList;
    
       if (!GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)))
       {
          qDebug() << "ERROR -- GetRawInputDeviceList ...";
          return 1;
       }
    
       if (!(pRawInputDeviceList = (PRAWINPUTDEVICELIST)malloc(sizeof(RAWINPUTDEVICELIST) * nDevices)))
       {
          qDebug() << "Initialization failed...";
          return 1;
       }
    
        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 = (HWND)w.effectiveWinId();
        if(!RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])))
            qDebug()<<"Huston Problem.";
        qDebug()<<QString::number(GetLastError());
    
        return a.exec();
    }
    

    And here is a part from Mouse Handlig Class

    bool MouseRawMovement::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
    {
        if(eventType == "windows_generic_MSG")
        {
            MSG *msg = reinterpret_cast<MSG*>(message);
    
            if(msg->message == WM_INPUT)
            {
                UINT dwSize = 40;
                static BYTE lpb[40];
                if(!GetRawInputData((HRAWINPUT)msg->lParam, RID_INPUT,lpb, &dwSize, sizeof(RAWINPUTHEADER)))
                    qDebug()<<"Error GetRawInputData";
                else
                {
                    RAWINPUT* raw = (RAWINPUT*)lpb;
                    if (raw->header.dwType == RIM_TYPEMOUSE)
                    {
                        int xPosRelative = raw->data.mouse.lLastX;
                        int yPosRelative = raw->data.mouse.lLastY;
                        //qDebug()<<xPosRelative<<yPosRelative;
                    }
                }
    
            }
        }
        return false;
    }