Reputation: 418
I would like to programmatically synthesize mouse motion to a point (100,100) on a screen with code below, but it moves to left top side instead. What could be wrong?
#include "stdafx.h"
#include<Windows.h>
int main() {
INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = 100;
input.mi.dy = 100;
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
input.mi.mouseData = 0;
input.mi.dwExtraInfo = NULL;
input.mi.time = 0;
SendInput(1, &input, sizeof(INPUT));
return 0;
}
PS. I have compiled it in VS2017 on Windows 10x64. I have run the code on Win7 as well
PPS. When I remove MOUSEEVENTF_ABSOLUTE flag, it moves to relative position.
Upvotes: 4
Views: 1637
Reputation: 51412
The API call follows documented behavior:
MOUSEEVENTF_ABSOLUTE: The dx and dy members contain normalized absolute coordinates. [...] see the following Remarks section.
Normalized coordinates are indeed described in the Remarks section:
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; coordinate (65535,65535) maps onto the lower-right corner. In a multimonitor system, the coordinates map to the primary monitor.
To move the mouse to an absolute position, you first need to query the display surface size (e.g. through a call to GetMonitorInfor), and scale the coordinates appropriately.
The following function normalizes a point, given the point and display surface dimensions in device units as input:
POINT normalize(POINT const& pt_in_px, RECT const& display_size_in_px)
{
POINT pt_normalized{};
auto const width_in_px{ display_size_in_px.right - display_size_in_px.left };
auto const height_in_px{ display_size_in_px.bottom - display_size_in_px.top };
pt_normalized.x = ::MulDiv(pt_in_px.x, 65536, width_in_px);
pt_normalized.y = ::MulDiv(pt_in_px.y, 65536, height_in_px);
return pt_normalized;
}
Upvotes: 7