Moving Mouse in C# (coordinate units)

14,874

From Microsoft's documentation:

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.

You can use that to convert the input in pixels to the desired value, like this:

var inputXinPixels = 200;
var inputYinPixels = 200;
var screenBounds = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
var outputX = inputXinPixels * 65535 / screenBounds.Width;
var outputY = inputYinPixels * 65535 / screenBounds.Height;
MoveTo(outputX, outputY);

Please keep in mind that this may not be correct for multiple monitors. Also notice that the documention says:

This function has been superseded. Use SendInput instead.

Addendum: As pointed by J3soon the above formula might not be the best. Based on research done for AutoHokey the internal the following code works better:

var outputX = (inputXinPixels * 65536 / screenBounds.Width) + 1;
var outputY = (inputYinPixels * 65536 / screenBounds.Height) + 1;

See AutoHotkey source code for reference.


If I were in your position I would use Cursor.Position. The following code works as expected:

System.Windows.Forms.Cursor.Position = new System.Drawing.Point(200, 200);

Yes, it places the mouse pointer in the coordinates (200, 200) pixels of the screen [Tested on LinqPad].

Addendum: I had a look at what does System.Windows.Forms.Cursor.Position use internally - On Mono on Windows at least. It is a call to SetCursorPos. No weird coordinate conversion needed.

Share:
14,874
user1742916
Author by

user1742916

Updated on August 21, 2022

Comments

  • user1742916
    user1742916 over 1 year

    I'm trying to make Teamviewer like piece of software for fun, which allows one person to view another person's screen and click and all that. Anyway, I have most all of the socket stuff done, but I don't know how to get the mouse clicks to work correctly. Here is the code I found online for moving the mouse programmatically:

      public static class VirtualMouse
    {
        // import the necessary API function so .NET can
        // marshall parameters appropriately
        [DllImport("user32.dll")]
        static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
    
        // constants for the mouse_input() API function
        private const int MOUSEEVENTF_MOVE = 0x0001;
        private const int MOUSEEVENTF_LEFTDOWN = 0x0002;
        private const int MOUSEEVENTF_LEFTUP = 0x0004;
        private const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
        private const int MOUSEEVENTF_RIGHTUP = 0x0010;
        private const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
        private const int MOUSEEVENTF_MIDDLEUP = 0x0040;
        private const int MOUSEEVENTF_ABSOLUTE = 0x8000;
    
    
        // simulates movement of the mouse.  parameters specify changes
        // in relative position.  positive values indicate movement
        // right or down
        public static void Move(int xDelta, int yDelta)
        {
            mouse_event(MOUSEEVENTF_MOVE, xDelta, yDelta, 0, 0);
        }
    
    
        // simulates movement of the mouse.  parameters specify an
        // absolute location, with the top left corner being the
        // origin
        public static void MoveTo(int x, int y)
        {
            mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x, y, 0, 0);
        }
    
    
        // simulates a click-and-release action of the left mouse
        // button at its current position
        public static void LeftClick()
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN, Control.MousePosition.X, Control.MousePosition.Y, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, Control.MousePosition.X, Control.MousePosition.Y, 0, 0);
        }
    }
    

    Now I want to move the mouse using the MoveTo method, but it requires crazy high numbers for any movement. Is there anyway I can match coordinates for moving here to the position on screen in pixels? Sorry if this seems like an obvious question, but I've googled for almost an hour and I can't find any discussion of what units are being used for the mouse x and y position, so I can't set up any sort of formula to match clicks on one panel to clicks on the user's screen.

  • J3soon
    J3soon about 6 years
    inputXinPixels * 65536 / SCREEN_WIDTH + 1 works better in my case, which is also used in AutoHotKey.