Moving Mouse in C# (coordinate units)

自古美人都是妖i 提交于 2021-02-07 08:29:31

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!