Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving the mouse without acceleration in C++ using mouse_event

Tags:

c++

winapi

Right now when I try a loop that contains something like:

mouse_event(MOUSEEVENTF_MOVE,dx,dy,0,0);

The mouse tends to move more than (dx,dy). Researching this online, I think it's because of the acceleration applied by the operating system. How can I move the mouse an absolute amount?

MOUSEEVENTF_ABSOLUTE seems to maybe be what I'm looking for, but I can't see how to use it.

I've tried:

mouse_event(MOUSEEVENTF_ABSOLUTE || MOUSEEVENTF_MOVE,dx,dy,0,0);

but that doesn't work either. I'd prefer to use mouse_event rather than SetCursorPos or other methods, what should I do? Thanks.

like image 790
Dave61 Avatar asked Nov 22 '25 08:11

Dave61


2 Answers

The coordinates are not pixel coordinates and must be normalized.

#include <Windows.h>
#include <tchar.h>

int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) {
  INPUT input = {0};

  int screenX = GetSystemMetrics( SM_CXVIRTUALSCREEN );
  int screenY = GetSystemMetrics( SM_CYVIRTUALSCREEN );

  for( unsigned int i = 0; i < 10; i++ ) {
    input.mi.dx = i*10 * ( 65535/screenX );
    input.mi.dy = i*10 * ( 65535/screenY );
    input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK | MOUSEEVENTF_MOVE;
    input.type = INPUT_MOUSE;

    SendInput( 1, &input, sizeof INPUT );
    Sleep( 1000 );
  }

  return ERROR_SUCCESS;
}

I have used SendInput() here instead of mouse_event() because the latter has been superseded according to the docs. If you do want to convert it back, the parameters should be much the same.

like image 118
Mike Kwan Avatar answered Nov 23 '25 20:11

Mike Kwan


from winuser.h

#define MOUSEEVENTF_MOVE        0x0001
#define MOUSEEVENTF_ABSOLUTE    0x8000

MOUSEEVENTF_MOVE || MOUSEEVENTF_ABSOLUTE is the same thing as 0x0001 || 0x8001 which evaluates to true, which just happens to be 1!

Try it again with MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE and it will probably work.

Edit: after looking at the docs a bit, it appears that either you want MOUSEEVENTF_ABSOLUTE all by itself. or you need to account for the fact that the range of values it is looking for is 0-65535 scaled over the entire display.

If MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain normalized absolute coordinates between 0 and 65,535. The event procedure maps these coordinates onto the display surface. Coordinate (0,0) maps onto the upper-left corner of the display surface, (65535,65535) maps onto the lower-right corner.

like image 42
John Knoeller Avatar answered Nov 23 '25 20:11

John Knoeller



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!