问题
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.
回答1:
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.
来源:https://stackoverflow.com/questions/12870535/moving-mouse-in-c-sharp-coordinate-units