This commit is contained in:
2026-06-14 15:54:35 +08:00
commit 3caeb07e54
2804 changed files with 373231 additions and 0 deletions
+521
View File
@@ -0,0 +1,521 @@
//
// Created by misaki on 2026/1/25.
//
#pragma once
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
#include <map>
#include <initializer_list>
#include "Keyboard.h"
#include "Mouse.h"
#include "types.h"
namespace AutoGUI {
// 错误类型
class AutoGUIException : public std::exception {
private:
std::string message;
public:
explicit AutoGUIException(std::string msg) : message(std::move(msg)) {}
[[nodiscard]] const char* what() const noexcept override {
return message.c_str();
}
};
// 鼠标按钮枚举
enum class Button {
LEFT = 0,
RIGHT = 1,
MIDDLE = 2
};
// 将 Button 转换为 Robot::MouseButton
inline Robot::MouseButton toRobotButton(Button button) {
switch (button) {
case Button::LEFT: return Robot::MouseButton::LEFT_BUTTON;
case Button::RIGHT: return Robot::MouseButton::RIGHT_BUTTON;
case Button::MIDDLE: return Robot::MouseButton::CENTER_BUTTON;
default: return Robot::MouseButton::LEFT_BUTTON;
}
}
// 将 Button 枚举转换为字符串
inline std::string buttonToString(Button button) {
switch (button) {
case Button::LEFT: return "left";
case Button::RIGHT: return "right";
case Button::MIDDLE: return "middle";
default: return "left";
}
}
// 键名字符串到 Keyboard::SpecialKey 的映射
inline Robot::Keyboard::SpecialKey stringToSpecialKey(const std::string& key) {
static std::map<std::string, Robot::Keyboard::SpecialKey> keyMap = {
{"backspace", Robot::Keyboard::BACKSPACE},
{"enter", Robot::Keyboard::ENTER},
{"return", Robot::Keyboard::ENTER},
{"tab", Robot::Keyboard::TAB},
{"escape", Robot::Keyboard::ESCAPE},
{"esc", Robot::Keyboard::ESCAPE},
{"up", Robot::Keyboard::UP},
{"down", Robot::Keyboard::DOWN},
{"right", Robot::Keyboard::RIGHT},
{"left", Robot::Keyboard::LEFT},
{"win", Robot::Keyboard::META},
{"command", Robot::Keyboard::META},
{"cmd", Robot::Keyboard::META},
{"alt", Robot::Keyboard::ALT},
{"ctrl", Robot::Keyboard::CONTROL},
{"control", Robot::Keyboard::CONTROL},
{"shift", Robot::Keyboard::SHIFT},
{"capslock", Robot::Keyboard::CAPSLOCK},
{"f1", Robot::Keyboard::F1},
{"f2", Robot::Keyboard::F2},
{"f3", Robot::Keyboard::F3},
{"f4", Robot::Keyboard::F4},
{"f5", Robot::Keyboard::F5},
{"f6", Robot::Keyboard::F6},
{"f7", Robot::Keyboard::F7},
{"f8", Robot::Keyboard::F8},
{"f9", Robot::Keyboard::F9},
{"f10", Robot::Keyboard::F10},
{"f11", Robot::Keyboard::F11},
{"f12", Robot::Keyboard::F12},
{"space", Robot::Keyboard::BACKSPACE} // 特殊处理空格
};
std::string lower = key;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
auto it = keyMap.find(lower);
if (it != keyMap.end()) {
return it->second;
}
// 如果是单个字符,直接返回(会在其他地方处理)
if (lower.length() == 1) {
// 这是单个字符键,不是特殊键
throw AutoGUIException("Unknown key: " + key);
}
throw AutoGUIException("Unknown key: " + key);
}
// 检查字符串是否是特殊键
inline bool isSpecialKey(const std::string& key) {
static std::vector<std::string> specialKeys = {
"backspace", "enter", "return", "tab", "escape", "esc",
"up", "down", "right", "left", "win", "command", "cmd",
"alt", "ctrl", "control", "shift", "capslock",
"f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12",
"space"
};
std::string lower = key;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
return std::find(specialKeys.begin(), specialKeys.end(), lower) != specialKeys.end();
}
// 解决多屏幕移动鼠标问题
struct ScreenInfo {
int id; // 屏幕ID
int x, y; // 相对于虚拟桌面原点的偏移
int width, height;// 屏幕尺寸
bool isPrimary; // 是否主屏
};
// 获取所有屏幕信息
std::vector<ScreenInfo> getAllScreens();
// 获取当前鼠标所在的屏幕
ScreenInfo getCurrentScreen();
// 相对于当前屏幕移动鼠标(以当前屏幕左上角为原点)
void moveToOnCurrentScreen(int x, int y, double duration = 0.0);
// 获取指定屏幕的尺寸(替代原来的size(),支持多屏)
Robot::Point getScreenSize(int screenId = -1); // -1表示当前屏幕
// 主要 API 函数
/**
* @brief 移动鼠标到指定位置
* @param x 目标位置的X坐标
* @param y 目标位置的Y坐标
* @param duration 移动持续时间(秒),0表示立即移动
*/
void moveTo(int x, int y, double duration = 0.0);
/**
* @brief 相对移动鼠标
* @param xOffset X方向偏移量
* @param yOffset Y方向偏移量
* @param duration 移动持续时间(秒),0表示立即移动
*/
void moveRel(int xOffset, int yOffset, double duration = 0.0);
/**
* @brief 单击鼠标
* @param x 点击位置的X坐标,-1表示当前位置
* @param y 点击位置的Y坐标,-1表示当前位置
* @param button 鼠标按钮:left, right, middle
* @param clicks 点击次数
* @param interval 多次点击之间的间隔(秒)
*/
void click(int x = -1, int y = -1,
Button button = Button::LEFT,
int clicks = 1,
double interval = 0.0);
/**
* @brief 左键双击
* @param x 双击位置的X坐标,-1表示当前位置
* @param y 双击位置的Y坐标,-1表示当前位置
*/
void leftDouble(int x = -1, int y = -1);
/**
* @brief 右键单击
* @param x 点击位置的X坐标,-1表示当前位置
* @param y 点击位置的Y坐标,-1表示当前位置
*/
void rightSingle(int x = -1, int y = -1);
/**
* @brief 中键单击
* @param x 点击位置的X坐标,-1表示当前位置
* @param y 点击位置的Y坐标,-1表示当前位置
*/
void middleClick(int x = -1, int y = -1);
/**
* @brief 按下鼠标按钮
* @param button 要按下的鼠标按钮
* @param x 按下位置的X坐标,-1表示当前位置
* @param y 按下位置的Y坐标,-1表示当前位置
*/
void mouseDown(Button button = Button::LEFT, int x = -1, int y = -1);
/**
* @brief 释放鼠标按钮
* @param button 要释放的鼠标按钮
* @param x 释放位置的X坐标,-1表示当前位置
* @param y 释放位置的Y坐标,-1表示当前位置
*/
void mouseUp(Button button = Button::LEFT, int x = -1, int y = -1);
/**
* @brief 从指定位置拖动到另一个位置
* @param x1 起始位置的X坐标
* @param y1 起始位置的Y坐标
* @param x2 目标位置的X坐标
* @param y2 目标位置的Y坐标
* @param duration 拖动持续时间(秒),0表示立即拖动
* @param button 拖动时按住的鼠标按钮
*/
void drag(int x1, int y1, int x2, int y2,
double duration = 0.0,
Button button = Button::LEFT);
/**
* @brief 拖拽鼠标到指定位置
* @param x 目标位置的X坐标
* @param y 目标位置的Y坐标
* @param duration 拖拽持续时间(秒),0表示立即拖拽
* @param button 拖拽时按住的鼠标按钮
*/
void dragTo(int x, int y, double duration = 0.0, Button button = Button::LEFT);
/**
* @brief 相对拖拽鼠标
* @param xOffset X方向偏移量
* @param yOffset Y方向偏移量
* @param duration 拖拽持续时间(秒),0表示立即拖拽
* @param button 拖拽时按住的鼠标按钮
*/
void dragRel(int xOffset, int yOffset, double duration = 0.0, Button button = Button::LEFT);
/**
* @brief 获取当前鼠标位置
* @return 包含x,y坐标的Point结构体
*/
Robot::Point position();
/**
* @brief 滚动鼠标滚轮
* @param clicks 滚动量,正数向上滚动,负数向下滚动
* @param x 水平滚动量(Linux/macOS支持)
*/
void scroll(int clicks, int x = 0);
/**
* @brief 输入文本
* @param text 要输入的文本
* @param interval 字符之间的间隔时间(秒),0表示无间隔
* 注意:只支持ASCII字符
*/
void type(const std::string& text, double interval = 0.0);
/**
* @brief 按下并释放一个键
* @param key 键名(如:"a", "enter", "ctrl"等)
*/
void press(const std::string& key);
/**
* @brief 按下键(不释放)
* @param key 键名
*/
void keyDown(const std::string& key);
/**
* @brief 释放键
* @param key 键名
*/
void keyUp(const std::string& key);
/**
* @brief 按下组合键
* @param keys 键名列表,如 {"ctrl", "c"}
*/
void hotkey(const std::initializer_list<std::string>& keys);
/**
* @brief 按下组合键(向量版本)
* @param keys 键名向量
*/
void hotkey(const std::vector<std::string>& keys);
/**
* @brief 睡眠/等待
* @param seconds 等待的秒数
*/
void sleep(double seconds);
/**
* @brief 获取屏幕尺寸
* @return 包含屏幕宽度和高度的Point结构体
* @note 需要平台特定实现
* @note 注意:不提供屏幕管理功能,如果你有多个屏幕,那么返回的size可能是错误的,对于单个屏幕是没有影响的,对于获取屏幕尺寸,更加推荐使用Qt当中的接口
*/
Robot::Point size();
// 辅助函数
/**
* @brief 检查坐标是否有效
* @param x X坐标
* @param y Y坐标
* @return 如果坐标有效返回true
*/
bool isValidCoord(int x, int y);
/**
* @brief 将字符串转换为小写
* @param str 输入字符串
* @return 小写字符串
*/
std::string toLower(const std::string& str);
namespace ExtendedFunc {
/// drag拓展功能
/**
* @brief 从指定位置开始拖动一个矩形区域
* @param x1 矩形左上角X坐标
* @param y1 矩形左上角Y坐标
* @param width 矩形宽度
* @param height 矩形高度
* @param duration 拖动持续时间(秒)
* @param button 拖动时按住的鼠标按钮
*/
void dragRect(int x1, int y1, int width, int height,
double duration = 0.5, Button button = Button::LEFT);
/**
* @brief 拖动一个圆形区域(从中心开始到边缘)
* @param centerX 圆心X坐标
* @param centerY 圆心Y坐标
* @param radius 圆半径
* @param duration 拖动持续时间(秒)
* @param button 拖动时按住的鼠标按钮
*/
void dragCircle(int centerX, int centerY, int radius,
double duration = 0.5, Button button = Button::LEFT);
/**
* @brief 在区域内随机拖动(用于测试或自动化)
* @param x1 区域左上角X坐标
* @param y1 区域左上角Y坐标
* @param x2 区域右下角X坐标
* @param y2 区域右下角Y坐标
* @param minDuration 最小拖动持续时间(秒)
* @param maxDuration 最大拖动持续时间(秒)
* @param button 拖动时按住的鼠标按钮
*/
void dragRandomInArea(int x1, int y1, int x2, int y2,
double minDuration = 0.1, double maxDuration = 0.5,
Button button = Button::LEFT);
/// 文字输入扩展功能
/**
* @brief 模拟人类打字(带随机延迟和可能的错误)
* @param text 要输入的文本
* @param minDelay 最小延迟(秒)
* @param maxDelay 最大延迟(秒)
* @param errorRate 错误率(0.0-1.0
*/
void typeHumanLike(const std::string& text, double minDelay = 0.05,
double maxDelay = 0.2, double errorRate = 0.0);
/**
* @brief 输入文本并回车
* @param text 要输入的文本
* @param interval 字符间隔
*/
void typewriteEnter(const std::string& text, double interval = 0.0);
/**
* @brief 输入多行文本
* @param lines 文本行数组
* @param interval 字符间隔
* @param lineDelay 行间延迟
*/
void typewriteLines(const std::vector<std::string>& lines,
double interval = 0.0, double lineDelay = 0.1);
/**
* @brief 输入当前日期时间
* @param format 时间格式(如:"%Y-%m-%d %H:%M:%S"
*/
void typeDateTime(const std::string& format = "%Y-%m-%d %H:%M:%S");
/// 键盘快捷键扩展功能
/**
* @brief 保存文件 (Ctrl+S)
*/
void saveFile();
/**
* @brief 打开文件 (Ctrl+O)
*/
void openFile();
/**
* @brief 新建文件 (Ctrl+N)
*/
void newFile();
/**
* @brief 复制 (Ctrl+C)
*/
void copy();
/**
* @brief 粘贴 (Ctrl+V)
*/
void paste();
/**
* @brief 剪切 (Ctrl+X)
*/
void cut();
/**
* @brief 全选 (Ctrl+A)
*/
void selectAll();
/**
* @brief 撤销 (Ctrl+Z)
*/
void undo();
/**
* @brief 重做 (Ctrl+Y 或 Ctrl+Shift+Z)
*/
void redo();
/**
* @brief 查找 (Ctrl+F)
*/
void find();
/**
* @brief 替换 (Ctrl+H)
*/
void replace();
/**
* @brief 打印 (Ctrl+P)
*/
void print();
/**
* @brief 关闭窗口 (Alt+F4 或 Ctrl+W)
*/
void closeWindow(bool useAltF4 = true);
/**
* @brief 切换窗口 (Alt+Tab)
* @param times 切换次数
*/
void switchWindow(int times = 1);
/**
* @brief 刷新 (F5)
*/
void refresh();
/// 游戏/自动化操作功能拓展
/**
* @brief 自动点击器(连续点击)
* @param x 点击位置X坐标
* @param y 点击位置Y坐标
* @param count 点击次数
* @param interval 点击间隔(秒)
* @param button 鼠标按钮
*/
void autoClicker(int x, int y, int count = 10, double interval = 0.1,
Button button = Button::LEFT);
/**
* @brief 连点器(按住连点)
* @param x 点击位置X坐标
* @param y 点击位置Y坐标
* @param duration 持续时间(秒)
* @param clickRate 点击频率(次/秒)
* @param button 鼠标按钮
*/
void rapidClicker(int x, int y, double duration = 1.0,
double clickRate = 10.0,
Button button = Button::LEFT);
/**
* @brief 按键连发(按住按键)
* @param key 按键名称
* @param duration 持续时间(秒)
* @param pressRate 按键频率(次/秒)
*/
void rapidKeyPress(const std::string& key, double duration = 1.0,
double pressRate = 10.0);
/**
* @brief 组合键连发
* @param keys 按键组合
* @param duration 持续时间
* @param pressRate 按键频率
*/
void rapidHotkey(const std::vector<std::string>& keys, double duration = 1.0,
double pressRate = 5.0);
} // namespace ExtendedFunc
} // namespace AutoGUI