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?
-
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. -
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) andGetCursorPos
(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. -
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
. -
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!