Mouse moves to original location after crossing montiors

680 views Asked by At

I can't test different Windows versions, but I suspect it's a Windows 8 issue (due to the corner and side hotspots).

I'm trying to move the cursor to specified coordinates using SendInput, SetCursorPos, mouse_event and MoveMouse from Autohotkey and AutoIt. It works when moving the cursor on the same monitor, but not when crossing monitors.

When crossing monitors, if my mouse cursor is at (100, 100) on secondary monitor (to the right), moving to (0, 0) (primary monitor) will move and stay there. GetCursorPos will tell me it's at (0, 0). But soon as I move, the cursor starts from (0, 0) on secondary monitor.

How do I move my cursor across my monitor without having it jump to the original monitor again?

SendInput example C++:

int MouseMove(int x, int y) {
    int screenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    int screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);

    INPUT input;
    input.type = INPUT_MOUSE;
    input.mi.dx = round((x * 65535) / (screenWidth - 1));
    input.mi.dy = round((x * 65535) / (screenHeight - 1));
    input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK | MOUSEEVENTF_MOVE;
    input.mi.mouseData = 0;
    input.mi.time = 0;
    input.mi.dwExtraInfo = 0;

    return SendInput(1, &input, sizeof(INPUT));
}

AutoHotkey example:

CoordMode, Mouse, Screen
MouseMove, 0, 0, 0

AutoIt example:

MouseMove(0, 0, 0)
2

There are 2 answers

1
errorseven On

I have no way of testing your issue but maybe I can point you in the right direction.

The only thing I can think of is using MouseGetPos to store your current mouse position,SysGet to grab the 2nd Monitor, and use MouseMove to return you to original position after your SendInput.

Hope this helps.

0
Milos On

This may be a bug in Autoit or Windows.

Try doing MouseMove in a different way and play with $Window.

Local $WM_MOUSEMOVE     =  0x0200

DllCall("user32.dll", "int", "SendMessage", _
        "hwnd",  WinGetHandle( $Window ), _
        "int",   $WM_MOUSEMOVE, _
        "int",   0, _
        "long",  _MakeLong($X, $Y))

Are your monitors set to Extend mode?