Moving Mouse in C# (coordinate units)
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.
user1742916
Updated on August 21, 2022Comments
-
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.
-
chris over 11 years
Cursor.Position
looks promising.
-
-
J3soon about 6 years
inputXinPixels * 65536 / SCREEN_WIDTH + 1
works better in my case, which is also used in AutoHotKey.