4

我正在尝试让 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 方法移动鼠标,但是任何移动都需要非常高的数字。无论如何我可以匹配坐标以将这里移动到屏幕上的像素位置吗?抱歉,如果这似乎是一个显而易见的问题,但我已经用谷歌搜索了将近一个小时,但我找不到任何关于鼠标 x 和 y 位置使用什么单位的讨论,所以我无法设置任何类型的将一个面板上的点击与用户屏幕上的点击相匹配的公式。

4

1 回答 1

6

来自微软的文档

如果指定了 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

附录:正如J3soon 所指出的,上述公式可能不是最好的。根据对AutoHokey 所做的研究,内部以下代码效果更好:

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

请参阅AutoHotkey 源代码以供参考。


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

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

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

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

于 2012-10-13T06:32:38.740 回答