Question

I have the code below and know that it is used to move the mouse cursor to a specific point on the screen.

The thing I do not understand is why the X and Y coordinates must be multiplied by 65535 and divided by the size of the screen.

Does it have anything to do with the conversion from a float to an integer type?

public void MoveMouse(PointF p)
{
    if (IntPtr.Size == 8)
    {
        var move = new INPUT64[1];
        move[0] = new INPUT64();
        move[0].mi.dx = (int)(p.X * 65535 / ScreenSize.Width);
        move[0].mi.dy = (int)(p.Y * 65535 / ScreenSize.Height);
        move[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
        SendInput(1, move, Marshal.SizeOf(move[0]));
    }
    else
    {
        var move = new INPUT32[1];
        move[0] = new INPUT32();
        move[0].mi.dx = (int)(p.X * 65535 / ScreenSize.Width);
        move[0].mi.dy = (int)(p.Y * 65535 / ScreenSize.Height);
        move[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
        SendInput(1, move, Marshal.SizeOf(move[0]));
    }
}
Was it helpful?

Solution

To start, .NET essentially wraps the native Win API for mouse programming as an answer to a related SO question explains.

Win API expresses absolute (versus relative) mouse coordinates as normalized 16-bit values (i.e. between 0 and 65,535 since 2^16 = 65,536). See Win API mouse_event documentation.

Now .NET System.Drawing.PointF's X and Y properties are of type Single. Huh? Well, one way to express a 16-bit value is with a real number between 0 and 1, which can then be multiplied by 65,535 (i.e. the maximum 16-bit value)...to arrive at the corresponding value between 0 and 65,535. This is why you see p.X * 65535 and p.Y * 65535.

To map the 16-bit absolute X and Y mouse coordinates to the screen at hand, they need to be scaled to it since it is not 65,536 x 65,536 pixels: dividing them by ScreenSize.Width and ScreenSize.Height respectively achieves this.

There you have it I think.

If you are interested in reading more about all this, Daniel Moth's blog has a reference implementation for moving the mouse cursor and related explanations that you might want to consider in relation to the code you're trying to understand. Also, you might find another related SO question and the answers to it informative.

OTHER TIPS

65535 is the value of unsigned 16-bit interger. The mouse messages like which gives you mouse position etc are of maximum of 16 bits.

It is the maximum size(pixels) of a control in winforms.

You need to use the value 65536 to normalize the x and y coordinates to a value from 0 to 65535

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top