用C#移动鼠标(坐标单位)

时间:2012-10-13 06:19:25

标签: c# click mouse move

我正在尝试让Teamviewer像一块软件一样有趣,它允许一个人查看另一个人的屏幕并点击所有这些。无论如何,我完成了大部分套接字的工作,但我不知道如何让鼠标点击才能正常工作。以下是我在网上找到的用于以编程方式移动鼠标的代码:

  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);
    }
}

现在我想使用MoveTo方法移动鼠标,但它需要疯狂的高数字才能进行任何移动。无论如何我可以匹配坐标移动到屏幕上的位置像素?对不起,如果这似乎是一个显而易见的问题,但我用Google搜索了近一个小时,我找不到任何关于鼠标x和y位置使用的单位的讨论,所以我无法设置任何类型的用于匹配一个面板上的点击以点击用户屏幕的公式。

1 个答案:

答案 0 :(得分:5)

来自Microsoft's documentation

  

如果指定了MOUSEEVENTF_ABSOLUTE值,则dx和dy包含   标准化的绝对坐标在0到65,535之间。事件   程序将这些坐标映射到显示表面上。坐标   (0,0)映射到显示表面的左上角,   (65535,65535)映射到右下角。

您可以使用它将输入(以像素为单位)转换为所需的值,如下所示:

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);

请注意,对于多台显示器而言,这可能不正确。另请注意该文档说:

  

此功能已被取代。请改用SendInput

附录:作为pointed by J3soon,上述公式可能不是最好的。基于research done for AutoHokey内部,以下代码更好用:

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

请参阅AutoHotkey source code以供参考。


如果我在你的位置,我会使用Cursor.Position。以下代码按预期工作:

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

是的,它将鼠标指针放在屏幕的坐标(200,200)像素[在LinqPad上测试]。

附录:我看了System.Windows.Forms.Cursor.Position内部使用的内容 - 至少在Windows上使用Mono。这是对SetCursorPos的调用。不需要奇怪的坐标转换。