How to get Mouse actual Position



  • Dear all,

    I want to get the mouse position but not related to screen resolution.
    I try to figure out if there is a way to get the actual movement dependent on mouse device DPI. My first approach (and implementation) was by calculating pixel size and printing the mouse move in mm, but this way is not efficient cause screen dependency, results related accuracy to actual system. Thus when I want to measure position change I measure the pixel change and not the real mouse- based resolution movement.

    With other words : Can I get mouse movement event related to mouse - not on screen?


  • Qt Champions 2016

    Hi
    Not sure how you would read the raw values directly from driver.

    Can I ask what you need this for?
    Normally the pixel position is enough.


  • Moderators

    Qt does not go so low. You would have to use native facilities.

    For example on Windows you would register yourself for a raw input with RegisterRawInputDevices and then, in the native event handler, watch for WM_INPUT message and read current values with GetRawInputData .



  • I tried to implement GetRawInputData (based on windows.h) but I 've linker errors all the time. Can I use native facilities in Qt?(I think its not a problem).

    Example 1:

     RAWINPUTDEVICE dev;
        dev.usUsagePage = 0x01;
        dev.usUsage = 0x02;
        dev.dwFlags = 0;
        dev.hwndTarget = 0;
        RegisterRawInputDevices(&dev, 1, sizeof(dev));
    

    Example 2 (not for our occasion):

        POINT pt;
        RECT rect;
        GetCursorPos(&pt);
        ui->showInfoLabel->setText("x: " + QString::number(pt.x) + "mm y:" +  QString::number(pt.y));
    

    All with the same LNK2019 error for RegisterRawInputDevices (1st) and GetCursorPos (2nd).

    LINKER ERROR:

    mainwindow.obj:-1: error: LNK2019: unresolved external symbol __imp__RegisterRawInputDevices@12 referenced in function "public: __thiscall MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QAE@PAVQWidget@@@Z)

    I've already include "windows.h".
    Thanks a lot for your answers.



  • I guess you need to add the Windows libs for linking in your pro file?
    something like
    LIBS += somewindows.lib someotherwindows.lib

    and so on...
    The libraries you need are in the windows docs for the functions you use.


  • Moderators

    As @kenchan said you need to link to the appropriate library. When you go to the MSDN help for given function there's a "Requirements" table on the bottom indicating what lib the function is placed in. In this case you would need to link to user32 like this: LIBS += -luser32.



  • @Chris-Kawa @kenchan

    You 're (obviously) right.

    I have to apologize for my question. I didn't make a closer look since the error.



  • @Chris-Kawa @kenchan
    With https://msdn.microsoft.com/en-us/library/windows/desktop/ee418864(v=vs.100).aspx
    and QAbstractNativeEventFilter class I finally got native events from HID (both mouse and keyboard).

    I can't separate mouse movement events.

    MouseRawMovement.h

    #ifndef MOUSERAWMOVEMENT_H
    #define MOUSERAWMOVEMENT_H
    
    #include <QDebug>
    #include <QAbstractNativeEventFilter>
    #include <Windows.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
    
    class MouseRawMovement : public QAbstractNativeEventFilter
    {
    public:
        MouseRawMovement();
        virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
        int mMove;
    };
    
    #endif // MOUSERAWMOVEMENT_H
    
    

    MouseMovement.cpp

    #include "mouserawmovement.h"
    
    MouseRawMovement::MouseRawMovement()
    {
        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 = 0;
        RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]));
        mMove = 0;
    }
    
    bool MouseRawMovement::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
    {
        MSG *msg = reinterpret_cast<MSG*>(message); // it returns numbers
    //eventType returns "windows_generic_MSG" or "windows_dispatcher_MSG"
        if(msg->message == WM_INPUT)
        {
            qDebug()<<"in";
            UINT dwSize = 40;
            static BYTE lpb[40];
            HRAWINPUT lParam;
            GetRawInputData(lParam, RID_INPUT,
                            lpb, &dwSize, sizeof(RAWINPUTHEADER));
    
            RAWINPUT* raw = (RAWINPUT*)lpb;
            double xPosRelative, yPosRelative;
            if (raw->header.dwType == RIM_TYPEMOUSE)
            {
                xPosRelative = raw->data.mouse.lLastX; //It returns only 0s 
                yPosRelative = raw->data.mouse.lLastY; //So this...
                qDebug()<<raw->data.mouse.lLastX<<raw->data.mouse.lLastY;
            }
        }
        return false;
    }
    

    and main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        a.installNativeEventFilter(&w.mm); // mm is MouseRawMovement obj
        w.show();
    
        return a.exec();
    }
    

    Posted 04 April 2014 - 02:10 PM

    lLastX
    Type: LONG
    The motion in the X direction. This is signed relative motion or absolute motion, depending on the value of usFlags.
    lLastY
    Type: LONG
    The motion in the Y direction. This is signed relative motion or absolute motion, depending on the value of usFlags.

    Thanks for your time



  • I finally find the solution! i get mouse position depending on DPI. Here is
    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    #include <windows.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(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)) != 0)
       {
          qDebug() << "ERROR -- GetRawInputDeviceList ...";
          return 1;
       }
    
       if ((pRawInputDeviceList = (PRAWINPUTDEVICELIST)malloc(sizeof(RAWINPUTDEVICELIST) * nDevices)) == NULL)
       {
          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()<<QString::number(GetLastError());
    
        return a.exec();
    }
    

    and here is the handling

    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;
    }
    

    I 'll soon post entire code on github cause I couldn't find a completed solution to that (for Qt 5.6).

    Thanks a lot!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.