【问题标题】:Moving Mouse in C# (coordinate units)在 C# 中移动鼠标(坐标单位)
【发布时间】:2018-03-07 04:20:09
【问题描述】:

我正在尝试让 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 位置使用什么单位的讨论,所以我无法设置任何类型的将一个面板上的点击与用户屏幕上的点击相匹配的公式。

【问题讨论】:

标签: c# click mouse move


【解决方案1】:

来自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 的呼叫。不需要奇怪的坐标转换。

【讨论】:

  • inputXinPixels * 65536 / SCREEN_WIDTH + 1 在我的情况下效果更好,AutoHotKey 也使用了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 2017-09-30
  • 2020-05-15
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多