Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SendInput for mouse movement on Windows #26

Closed
s1hofmann opened this issue Sep 3, 2020 · 2 comments
Closed

SendInput for mouse movement on Windows #26

s1hofmann opened this issue Sep 3, 2020 · 2 comments
Labels
enhancement New feature or request

Comments

@s1hofmann
Copy link
Member

Short overview
The current implementation uses SetCursorPos for mouse movment.
We might consider using SendInput like we do for scrolling and keyboard input.

Use case
Automating multimedia applications like e.g. games

Detailed description
As reported in nut-tree/nut.js#168 it is currently not possible to cause in-game mouse movement with nut.js, although desktop mouse movement works fine.
A possible reason for this could be the usage of SetCursorPos instead of SendInput.
Following the above mentioned docs it seems like SetCursorPos is more desktop centered, whereas SendInput actually inserts events into the keyboard and mouse inputstream.

@s1hofmann s1hofmann added the enhancement New feature or request label Sep 3, 2020
@Reiss-Cashmore
Copy link
Contributor

I have done a crude test to see if I could get SendInput working

This works for relative movements only

void moveMouseRelative(MMPoint point)
{
	// SetCursorPos ((int)point.x, (int)point.y);

        INPUT mouseInput;

	mouseInput.type = INPUT_MOUSE;
	mouseInput.mi.dx = (int)point.x;
	mouseInput.mi.dy = (int)point.y;
	mouseInput.mi.mouseData = 0;     
	mouseInput.mi.time = 0;
        mouseInput.mi.dwFlags = MOUSEEVENTF_MOVE;
        mouseInput.mi.dwExtraInfo = 0;
	SendInput(1, &mouseInput, sizeof(mouseInput));
}

I explored how that snippet could be adapted to work for absolute positioning on the display


int CalculateAbsoluteCoordinateX(int x)
{
	MMSize displaySize = getMainDisplaySize();
        return (x * 65536) / displaySize.width;
}

int CalculateAbsoluteCoordinateY(int y)
{
	MMSize displaySize = getMainDisplaySize();
        return (y * 65536) / displaySize.height;
}

void moveMouseAbsolute(MMPoint point)
{
	// SetCursorPos ((int)point.x, (int)point.y);

        INPUT mouseInput;

	mouseInput.type = INPUT_MOUSE;
	mouseInput.mi.dx = (int) CalculateAbsoluteCoordinateX(point.x);
	mouseInput.mi.dy = (int) CalculateAbsoluteCoordinateY(point.y);
	mouseInput.mi.mouseData = 0;     
	mouseInput.mi.time = 0;
        mouseInput.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_MOVE | MouseEventFlags.MOUSEEVENTF_ABSOLUTE;
        mouseInput.mi.dwExtraInfo = 0;
	SendInput(1, &mouseInput, sizeof(mouseInput));
}

I don't know if you would want to create some more methods within mouse.c or modify the existing moveMouse method and maybe add some flags on the params.

I have not thoroughly tested platform support but it works well on Windows 10 for me locally.

This script has some great examples in it
https://github.com/npocmaka/batch.scripts/blob/master/hybrids/.net/c/mouse.bat

I don't mind raising a PR but this is only prototype code and not very production friendly. I can work on it more if you want

@s1hofmann
Copy link
Member Author

Hi @Reiss-Cashmore 👋

Just modify the moveMouse implementation using SendInput and dwFlags set to MOUSEEVENTF_ABSOLUTE

Thanks for your support!

s1hofmann added a commit that referenced this issue Oct 10, 2021
moveMouse refactor to use sendInput on Windows (#26)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants