znlgis 博客

GIS开发与技术分享 — GDAL · GeoServer · PostGIS · QGIS · OpenLayers · Cesium · FreeCAD · NPOI

第04章 - 鼠标控制详解

鼠标控制是桌面自动化中最基础、使用频率最高的能力之一。RobotGo 提供了一整套丰富的鼠标 API,从简单的移动点击,到平滑轨迹移动、拖拽、滚轮滚动、相对移动、按键状态切换等,几乎覆盖了所有真实鼠标操作。本章将系统讲解这些函数及其参数细节。

4.1 坐标系与多屏幕

在深入函数之前,先明确坐标系:

  • 坐标原点 (0, 0) 位于主显示器的左上角。
  • x 轴向右为正,y 轴向下为正。
  • 在多显示器环境中,副屏可能位于主屏的左侧或上方,此时落在副屏的坐标可能是负数。RobotGo 的移动函数支持跨屏的负坐标,例如 robotgo.Move(100, -200) 可以把鼠标移动到主屏上方的副屏区域。

读取当前鼠标位置使用:

x, y := robotgo.Location()
fmt.Println("鼠标当前坐标:", x, y)

4.2 鼠标移动

4.2.1 瞬间移动 Move

Move 让鼠标瞬间“跳”到目标坐标,没有中间轨迹:

robotgo.Move(500, 300)

4.2.2 平滑移动 MoveSmooth

MoveSmooth 会让鼠标沿着一条带有缓动效果的轨迹移动到目标点,更接近真人操作,常用于需要规避“瞬移检测”或追求视觉自然的场景:

// 基本用法
robotgo.MoveSmooth(300, 300)

// 带可选参数:low 与 high 控制速度/平滑程度
// 第三、四个参数分别是 low(最低速度系数)和 high(最高速度系数)
robotgo.MoveSmooth(100, 200, 1.0, 10.0)

MoveSmooth 的后两个可选浮点参数用于调节移动的速度曲线,数值越大移动越慢、越平滑。可根据需要微调以获得理想的轨迹效果。

4.2.3 相对移动 MoveRelative

MoveRelative 基于鼠标当前位置进行偏移移动,而不是绝对坐标:

robotgo.Move(100, 100)
robotgo.MoveRelative(0, -10) // 在当前基础上向上移动 10 像素

4.3 鼠标点击

4.3.1 Click

Click 是最常用的点击函数,其签名支持可变参数:

robotgo.Click()                  // 默认点击左键
robotgo.Click("right")           // 点击右键
robotgo.Click("center")          // 点击中键
robotgo.Click("wheelLeft")       // 滚轮向左
robotgo.Click("wheelRight")      // 滚轮向右
robotgo.Click("left", true)      // 双击左键(第二个参数 true 表示双击)

第一个参数指定按键("left""right""center" 等),第二个布尔参数指定是否双击(true 为双击)。

4.3.2 在指定坐标点击

一种常见模式是“先移动再点击”:

robotgo.Move(400, 250)
robotgo.Click()

也可以利用 MouseSleep 在移动和点击之间自动留出延迟,避免目标程序来不及响应:

robotgo.MouseSleep = 100
robotgo.Move(400, 250)
robotgo.Click()

4.4 鼠标按键状态切换 Toggle

有些场景需要“按下不放”或“松开”,例如手动实现拖拽、长按。Toggle 用于切换某个鼠标键的按下/松开状态:

robotgo.Toggle("left")        // 按下左键
// ... 做一些操作,比如移动鼠标 ...
robotgo.Toggle("left", "up")  // 松开左键

第一个参数是按键名,第二个参数指定动作:省略或 "down" 表示按下,"up" 表示松开。

4.5 鼠标拖拽

4.5.1 DragSmooth

DragSmooth 在按住左键的同时平滑移动到目标坐标,实现拖拽:

robotgo.Move(100, 100)        // 先移动到起点
robotgo.DragSmooth(300, 300)  // 按住左键拖拽到 (300, 300)

4.5.2 用 Toggle 手动实现拖拽

如果需要更精细的控制,也可以用 Toggle 组合实现:

robotgo.Move(100, 100)
robotgo.Toggle("left")         // 按下
robotgo.MoveSmooth(300, 300)   // 平滑移动
robotgo.Toggle("left", "up")   // 松开

这种写法可以在按下与松开之间插入任意复杂的中间逻辑。

4.6 滚轮滚动

RobotGo 提供了多种滚轮滚动方式,适应不同需求。

4.6.1 ScrollDir:按方向滚动

ScrollDir 按指定方向滚动给定的“格数”:

robotgo.ScrollDir(10, "up")    // 向上滚动 10
robotgo.ScrollDir(20, "right") // 向右滚动 20
robotgo.ScrollDir(10, "down")  // 向下滚动 10
robotgo.ScrollDir(10, "left")  // 向左滚动 10

4.6.2 Scroll:按 x、y 偏移滚动

Scroll 接收水平和垂直两个方向的滚动量:

robotgo.Scroll(0, -10)  // 垂直方向滚动 -10
robotgo.Scroll(100, 0)  // 水平方向滚动 100

4.6.3 ScrollSmooth:平滑滚动

ScrollSmooth 提供更平滑的滚动效果:

robotgo.ScrollSmooth(-10, 6)

4.6.4 ScrollRelative:相对滚动

robotgo.ScrollRelative(10, -100)

不同的滚动函数在不同平台、不同应用下表现可能略有差异,建议在实际目标程序上做一些测试,挑选最稳定的一种。

4.7 完整示例

下面是一个综合演示鼠标各项能力的程序,改编自官方示例:

package main

import (
    "fmt"

    "github.com/go-vgo/robotgo"
)

func main() {
    robotgo.MouseSleep = 300

    // 移动与定位
    robotgo.Move(100, 100)
    fmt.Println(robotgo.Location())
    robotgo.Move(100, -200) // 多屏支持
    robotgo.MoveSmooth(120, -150)
    fmt.Println(robotgo.Location())

    // 滚动
    robotgo.ScrollDir(10, "up")
    robotgo.ScrollDir(20, "right")
    robotgo.Scroll(0, -10)
    robotgo.Scroll(100, 0)

    robotgo.MilliSleep(100)
    robotgo.ScrollSmooth(-10, 6)

    // 移动与拖拽
    robotgo.Move(10, 20)
    robotgo.MoveRelative(0, -10)
    robotgo.DragSmooth(10, 10)

    // 点击
    robotgo.Click("wheelRight")
    robotgo.Click("left", true)
    robotgo.MoveSmooth(100, 200, 1.0, 10.0)

    // 按键状态切换
    robotgo.Toggle("left")
    robotgo.Toggle("left", "up")
}

4.8 实战技巧与注意事项

  1. 先慢后快:调试阶段把 MouseSleep 设大一些(如 300ms),方便你用肉眼观察脚本行为;稳定后再调小以提速。
  2. 坐标校准:不同分辨率、不同缩放(DPI)下,同一个 UI 元素的像素坐标可能不同。尽量避免硬编码坐标,结合图像查找(第 8 章)来定位元素更稳健。
  3. 平滑移动反检测:部分应用会检测“鼠标瞬移”,此时优先使用 MoveSmooth / DragSmooth
  4. 多屏负坐标:处理多显示器时要清楚副屏相对主屏的方位,必要时用 GetDisplayBounds(第 7 章)获取各屏边界。
  5. 拖拽稳定性:用 Toggle 手动拖拽时,务必保证最终一定调用 Toggle("left", "up") 松开,否则会导致鼠标“卡在按下状态”。

4.9 小结

本章系统讲解了 RobotGo 的鼠标控制能力:坐标系与多屏概念、瞬间/平滑/相对移动、各种点击方式、按键状态切换、拖拽以及多种滚轮滚动方法。我们还通过完整示例把这些函数串联起来,并总结了实战技巧。下一章我们将转向键盘控制,讲解按键、组合键与文本输入的方方面面。