import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
import subprocess
import time
import keyboard
import pyautogui
import threading
import re


class PureDigitalExecutorApp:
    def __init__(self, root):
        self.root = root
        self.root.title("纯数字执行机器人 v1.0")
        self.root.geometry("800x700")

        # 创建界面组件
        self.create_widgets()

        # 初始化状态
        self.text7_visible = True

        # 初始化指令映射
        self.init_command_mapping()

        # 显示启动信息
        self.log_message("纯数字执行机器人 v1.0 已启动")
        self.log_message("支持 1位、2位、3位、4位数指令映射")
        self.log_message("使用 '-' 作为分隔符,例如: 0-1-2-3-21-70-200-300-700")
        self.log_message("点击 '帮助' 查看完整指令列表")

    def init_command_mapping(self):
        """初始化所有指令映射(1位、2位、3位和4位数)"""

        # ============ 1位数映射 (0-9) ============
        self.one_digit_map = {
            # 0-3: 启动程序1-4
            "0": "launch_prog1",
            "1": "launch_prog2",
            "2": "launch_prog3",
            "3": "launch_prog4",
            # 4-9: 常用操作
            "4": "ctrl+a",  # 全选
            "5": "ctrl+c",  # 复制
            "6": "ctrl+v",  # 粘贴
            "7": "ctrl+s",  # 保存
            "8": "ctrl+z",  # 撤销
            "9": "ctrl+y",  # 重做
        }

        # ============ 2位数映射 (00-99) ============
        self.two_digit_map = {
            # 00-09: Ctrl+数字
            "00": "ctrl+0", "01": "ctrl+1", "02": "ctrl+2", "03": "ctrl+3",
            "04": "ctrl+4", "05": "ctrl+5", "06": "ctrl+6", "07": "ctrl+7",
            "08": "ctrl+8", "09": "ctrl+9",

            # 10-19: Alt+数字
            "10": "alt+0", "11": "alt+1", "12": "alt+2", "13": "alt+3",
            "14": "alt+4", "15": "alt+5", "16": "alt+6", "17": "alt+7",
            "18": "alt+8", "19": "alt+9",

            # 20-29: Shift+数字
            "20": "shift+0", "21": "shift+1", "22": "shift+2", "23": "shift+3",
            "24": "shift+4", "25": "shift+5", "26": "shift+6", "27": "shift+7",
            "28": "shift+8", "29": "shift+9",

            # 30-39: Win+数字
            "30": "win+0", "31": "win+1", "32": "win+2", "33": "win+3",
            "34": "win+4", "35": "win+5", "36": "win+6", "37": "win+7",
            "38": "win+8", "39": "win+9",

            # 40-49: Ctrl+Shift+数字
            "40": "ctrl+shift+0", "41": "ctrl+shift+1", "42": "ctrl+shift+2",
            "43": "ctrl+shift+3", "44": "ctrl+shift+4", "45": "ctrl+shift+5",
            "46": "ctrl+shift+6", "47": "ctrl+shift+7", "48": "ctrl+shift+8",
            "49": "ctrl+shift+9",

            # 50-59: Alt+Shift+数字
            "50": "alt+shift+0", "51": "alt+shift+1", "52": "alt+shift+2",
            "53": "alt+shift+3", "54": "alt+shift+4", "55": "alt+shift+5",
            "56": "alt+shift+6", "57": "alt+shift+7", "58": "alt+shift+8",
            "59": "alt+shift+9",

            # 60-69: Ctrl+Alt+数字
            "60": "ctrl+alt+0", "61": "ctrl+alt+1", "62": "ctrl+alt+2",
            "63": "ctrl+alt+3", "64": "ctrl+alt+4", "65": "ctrl+alt+5",
            "66": "ctrl+alt+6", "67": "ctrl+alt+7", "68": "ctrl+alt+8",
            "69": "ctrl+alt+9",

            # 70-79: 功能键
            "70": "f1", "71": "f2", "72": "f3", "73": "f4",
            "74": "f5", "75": "f6", "76": "f7", "77": "f8",
            "78": "f9", "79": "f10",

            # 80-89: 方向键和编辑键
            "80": "up",  # 上箭头
            "81": "down",  # 下箭头
            "82": "left",  # 左箭头
            "83": "right",  # 右箭头
            "84": "pageup",  # PageUp
            "85": "pagedown",  # PageDown
            "86": "home",  # Home
            "87": "end",  # End
            "88": "insert",  # Insert
            "89": "delete",  # Delete

            # 90-99: 多媒体键
            "90": "volumeup",  # 音量+
            "91": "volumedown",  # 音量-
            "92": "volumemute",  # 静音
            "93": "playpause",  # 播放/暂停
            "94": "stop",  # 停止
            "95": "nexttrack",  # 下一曲
            "96": "prevtrack",  # 上一曲
            "97": "mediaselect",  # 媒体选择
            "98": "printscreen",  # 截图
            "99": "pause",  # Pause/Break
        }

        # ============ 3位数映射 (000-999) ============
        self.three_digit_map = {
            # ===== 标准键盘按键 000-099 =====
            # 字母键 (000-025: a-z)
            "000": "a", "001": "b", "002": "c", "003": "d", "004": "e",
            "005": "f", "006": "g", "007": "h", "008": "i", "009": "j",
            "010": "k", "011": "l", "012": "m", "013": "n", "014": "o",
            "015": "p", "016": "q", "017": "r", "018": "s", "019": "t",
            "020": "u", "021": "v", "022": "w", "023": "x", "024": "y",
            "025": "z",

            # 大写字母 (026-051)
            "026": "A", "027": "B", "028": "C", "029": "D", "030": "E",
            "031": "F", "032": "G", "033": "H", "034": "I", "035": "J",
            "036": "K", "037": "L", "038": "M", "039": "N", "040": "O",
            "041": "P", "042": "Q", "043": "R", "044": "S", "045": "T",
            "046": "U", "047": "V", "048": "W", "049": "X", "050": "Y",
            "051": "Z",

            # 数字键 (052-061)
            "052": "0", "053": "1", "054": "2", "055": "3", "056": "4",
            "057": "5", "058": "6", "059": "7", "060": "8", "061": "9",

            # 特殊键 (062-099)
            "062": "`", "063": "-", "064": "=", "065": "[", "066": "]",
            "067": "\\", "068": ";", "069": "'", "070": ",", "071": ".",
            "072": "/", "073": "space", "074": "tab", "075": "capslock",
            "076": "shift", "077": "ctrl", "078": "alt", "079": "win",
            "080": "printscreen", "081": "scrolllock", "082": "pause",
            "083": "insert", "084": "home", "085": "pageup", "086": "delete",
            "087": "end", "088": "pagedown", "089": "up", "090": "down",
            "091": "left", "092": "right", "093": "numlock", "094": "enter",
            "095": "backspace", "096": "esc", "097": "f1", "098": "f2",
            "099": "f3",

            # ===== 功能键扩展 100-199 =====
            "100": "f4", "101": "f5", "102": "f6", "103": "f7", "104": "f8",
            "105": "f9", "106": "f10", "107": "f11", "108": "f12",

            # F13-F24
            "109": "f13", "110": "f14", "111": "f15", "112": "f16",
            "113": "f17", "114": "f18", "115": "f19", "116": "f20",
            "117": "f21", "118": "f22", "119": "f23", "120": "f24",

            # 键盘锁定键 (121-129)
            "121": "capslock", "122": "numlock", "123": "scrolllock",

            # 键盘指示灯控制 (130-139)
            "130": "capslock_on", "131": "capslock_off",
            "132": "numlock_on", "133": "numlock_off",
            "134": "scrolllock_on", "135": "scrolllock_off",

            # 小键盘 (140-169)
            "140": "num0", "141": "num1", "142": "num2", "143": "num3",
            "144": "num4", "145": "num5", "146": "num6", "147": "num7",
            "148": "num8", "149": "num9",
            "150": "num.", "151": "num,", "152": "num/", "153": "num*",
            "154": "num-", "155": "num+", "156": "numenter",

            # 组合键 (170-180)
            "170": "ctrl+shift", "171": "ctrl+alt", "172": "alt+shift",
            "173": "ctrl+alt+shift", "174": "ctrl+win", "175": "alt+win",
            "176": "win+shift", "177": "ctrl+alt+win", "178": "ctrl+shift+win",
            "179": "alt+shift+win", "180": "ctrl+alt+shift+win",

            # ===== 鼠标操作 200-299 =====
            "200": "mouse_left",  # 鼠标左键
            "201": "mouse_right",  # 鼠标右键
            "202": "mouse_middle",  # 鼠标中键
            "203": "mouse_left_double",  # 鼠标左键双击
            "204": "mouse_scroll_up",  # 滚轮向上
            "205": "mouse_scroll_down",  # 滚轮向下
            "206": "mouse_move_up",  # 鼠标向上移动
            "207": "mouse_move_down",  # 鼠标向下移动
            "208": "mouse_move_left",  # 鼠标向左移动
            "209": "mouse_move_right",  # 鼠标向右移动
            "210": "mouse_click_hold",  # 鼠标按住
            "211": "mouse_click_release",  # 鼠标释放

            # 鼠标高级操作 (212-219)
            "212": "mouse_drag",  # 拖动
            "213": "mouse_drop",  # 释放拖动
            "214": "mouse_hover",  # 悬停

            # 鼠标手势 (220-229)
            "220": "mouse_swipe_up",  # 上滑
            "221": "mouse_swipe_down",  # 下滑
            "222": "mouse_swipe_left",  # 左滑
            "223": "mouse_swipe_right",  # 右滑
            "224": "mouse_zoom_in",  # 放大 (Ctrl+=)
            "225": "mouse_zoom_out",  # 缩小 (Ctrl+-)

            # ===== 文本操作 300-399 =====
            "300": "ctrl+a",  # 全选
            "301": "ctrl+c",  # 复制
            "302": "ctrl+v",  # 粘贴
            "303": "ctrl+x",  # 剪切
            "304": "ctrl+z",  # 撤销
            "305": "ctrl+y",  # 重做
            "306": "ctrl+f",  # 查找
            "307": "ctrl+h",  # 替换
            "308": "ctrl+s",  # 保存
            "309": "ctrl+o",  # 打开
            "310": "ctrl+n",  # 新建
            "311": "ctrl+p",  # 打印
            "312": "ctrl+w",  # 关闭
            "313": "ctrl+shift+esc",  # 任务管理器
            "314": "ctrl+shift+n",  # 新建文件夹
            "315": "ctrl+shift+s",  # 另存为
            "316": "ctrl+shift+z",  # 重做

            # ===== 系统操作 400-499 =====
            "400": "win+d",  # 显示桌面
            "401": "win+e",  # 文件资源管理器
            "402": "win+r",  # 运行
            "403": "win+m",  # 最小化所有
            "404": "win+shift+m",  # 还原所有
            "405": "win+l",  # 锁定电脑
            "406": "win+p",  # 投影设置
            "407": "win+i",  # 设置
            "408": "win+s",  # 搜索
            "409": "win+x",  # 快速链接菜单
            "410": "alt+f4",  # 关闭窗口
            "411": "alt+tab",  # 切换窗口
            "412": "ctrl+alt+delete",  # 安全选项
            "413": "ctrl+shift+esc",  # 任务管理器
            "414": "win+tab",  # 任务视图
            "415": "alt+space",  # 窗口菜单

            # ===== 应用启动 700-799 =====
            "700": "calc",  # 计算器
            "701": "notepad",  # 记事本
            "702": "paint",  # 画图
            "703": "cmd",  # 命令提示符
            "704": "explorer",  # 资源管理器
            "705": "taskmgr",  # 任务管理器
            "706": "control",  # 控制面板
            "707": "snippingtool",  # 截图工具
            "708": "winword",  # Word
            "709": "excel",  # Excel
            "710": "powerpnt",  # PowerPoint
            "711": "outlook",  # Outlook
            "712": "chrome",  # Chrome
            "713": "firefox",  # Firefox
            "714": "edge",  # Edge
            "715": "notepad++",  # Notepad++
            "716": "vscode",  # VS Code
            "717": "pycharm",  # PyCharm

            # ===== 文本输入 800-899 =====
            "800": "text_hello",  # 输入"hello"
            "801": "text_world",  # 输入"world"
            "802": "text_test",  # 输入"test"
            "803": "text_123",  # 输入"123"
            "804": "text_abc",  # 输入"abc"
            "805": "text_password",  # 输入"password"
            "806": "text_date",  # 输入当前日期
            "807": "text_time",  # 输入当前时间
            "808": "text_datetime",  # 输入当前日期时间

            # ===== 特殊符号 900-999 =====
            "900": "key_+", "901": "key_-", "902": "key_*", "903": "key_/",
            "904": "key_=", "905": "key_.", "906": "key_,", "907": "key_;",
            "908": "key_:", "909": "key_?", "910": "key_!", "911": "key_@",
            "912": "key_#", "913": "key_$", "914": "key_%", "915": "key_^",
            "916": "key_&", "917": "key_(", "918": "key_)", "919": "key_~",
            "920": "key_`", "921": "key_[", "922": "key_]", "923": "key_\\",
            "924": "key_{", "925": "key_}", "926": "key_|", "927": "key_<",
            "928": "key_>", "929": "key_\"", "930": "key_'",
        }

        # ============ 4位数映射 (0000-9999) ============
        self.four_digit_map = {
            # ===== 宏操作 =====
            "0001": "macro_copy_paste",  # 复制粘贴
            "0002": "macro_cut_paste",  # 剪切粘贴
            "0003": "macro_undo_redo",  # 撤销重做
            "0004": "macro_select_all",  # 全选复制
            "0005": "macro_save_close",  # 保存关闭
            "0006": "macro_new_save",  # 新建保存
            "0007": "macro_print",  # 打印预览
            "0008": "macro_find_replace",  # 查找替换

            # ===== 窗口操作 =====
            "0100": "window_maximize",  # 最大化
            "0101": "window_minimize",  # 最小化
            "0102": "window_restore",  # 还原
            "0103": "window_close",  # 关闭
            "0104": "window_next",  # 下一个窗口
            "0105": "window_prev",  # 上一个窗口

            # ===== 系统工具 =====
            "0200": "system_properties",  # 系统属性
            "0201": "device_manager",  # 设备管理器
            "0202": "task_scheduler",  # 任务计划
            "0203": "event_viewer",  # 事件查看器
            "0204": "services",  # 服务
            "0205": "registry",  # 注册表

            # ===== 指定坐标点击 =====
            "0300": "mouse_click_100",  # 在(100,100)点击
            "0301": "mouse_click_200",  # 在(200,200)点击
            "0302": "mouse_click_300",  # 在(300,300)点击
            "0303": "mouse_click_400",  # 在(400,400)点击
            "0304": "mouse_click_500",  # 在(500,500)点击

            # ===== 中文输入 =====
            "0400": "text_你好",
            "0401": "text_世界",
            "0402": "text_测试",
            "0403": "text_中文",
            "0404": "text_输入法",
        }

    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        # 工具栏
        toolbar = ttk.Frame(main_frame)
        toolbar.grid(row=0, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=(0, 10))

        ttk.Button(toolbar, text="📖 帮助", command=self.show_help).pack(side=tk.LEFT, padx=2)
        ttk.Button(toolbar, text="📋 示例", command=self.show_examples).pack(side=tk.LEFT, padx=2)
        ttk.Button(toolbar, text="🔄 重置", command=self.reset_all).pack(side=tk.LEFT, padx=2)
        ttk.Button(toolbar, text="❌ 清空日志", command=self.clear_log).pack(side=tk.LEFT, padx=2)
        ttk.Button(toolbar, text="⌨️ 按键测试", command=self.test_keyboard).pack(side=tk.LEFT, padx=2)

        # 第1行:程序路径1 + 启动按钮
        ttk.Label(main_frame, text="程序路径1:").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.text1 = ttk.Entry(main_frame, width=50)
        self.text1.grid(row=1, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        self.btn_start1 = ttk.Button(main_frame, text="▶ 启动1", command=self.command1_click)
        self.btn_start1.grid(row=1, column=3, padx=5, pady=5)

        # 第2行:程序路径2
        ttk.Label(main_frame, text="程序路径2:").grid(row=2, column=0, sticky=tk.W, pady=5)
        self.text2 = ttk.Entry(main_frame, width=50)
        self.text2.grid(row=2, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        self.btn_start2 = ttk.Button(main_frame, text="▶ 启动2", command=self.command3_click)
        self.btn_start2.grid(row=2, column=3, padx=5, pady=5)

        # 第3行:程序路径3
        ttk.Label(main_frame, text="程序路径3:").grid(row=3, column=0, sticky=tk.W, pady=5)
        self.text5 = ttk.Entry(main_frame, width=50)
        self.text5.grid(row=3, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        self.btn_start3 = ttk.Button(main_frame, text="▶ 启动3", command=self.command4_click)
        self.btn_start3.grid(row=3, column=3, padx=5, pady=5)

        # 第4行:程序路径4
        ttk.Label(main_frame, text="程序路径4:").grid(row=4, column=0, sticky=tk.W, pady=5)
        self.text6 = ttk.Entry(main_frame, width=50)
        self.text6.grid(row=4, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        self.btn_start4 = ttk.Button(main_frame, text="▶ 启动4", command=self.command5_click)
        self.btn_start4.grid(row=4, column=3, padx=5, pady=5)

        # 第5行:参数设置
        param_frame = ttk.Frame(main_frame)
        param_frame.grid(row=5, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=5)

        ttk.Label(param_frame, text="延迟(毫秒):").pack(side=tk.LEFT, padx=(0, 5))
        self.text3 = ttk.Entry(param_frame, width=10)
        self.text3.pack(side=tk.LEFT, padx=(0, 20))
        self.text3.insert(0, "100")

        ttk.Label(param_frame, text="执行次数:").pack(side=tk.LEFT, padx=(0, 5))
        self.text_repeat = ttk.Entry(param_frame, width=10)
        self.text_repeat.pack(side=tk.LEFT, padx=(0, 20))
        self.text_repeat.insert(0, "1")

        ttk.Label(param_frame, text="分隔符:").pack(side=tk.LEFT, padx=(0, 5))
        self.text_separator = ttk.Entry(param_frame, width=5)
        self.text_separator.pack(side=tk.LEFT)
        self.text_separator.insert(0, "-")

        # 第6行:指令序列
        ttk.Label(main_frame, text="指令序列:").grid(row=6, column=0, sticky=tk.W, pady=5)
        self.text4 = ttk.Entry(main_frame, width=50)
        self.text4.grid(row=6, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        self.btn_execute = ttk.Button(main_frame, text="⚡ 执行指令", command=self.command2_click)
        self.btn_execute.grid(row=6, column=3, padx=5, pady=5)

        # 第7行:执行状态
        self.status_label = ttk.Label(main_frame, text="就绪", foreground="green")
        self.status_label.grid(row=7, column=0, columnspan=4, sticky=tk.W, pady=5)

        # 第8行:日志区域
        ttk.Label(main_frame, text="执行日志:").grid(row=8, column=0, sticky=tk.W, pady=5)

        log_frame = ttk.Frame(main_frame)
        log_frame.grid(row=9, column=0, columnspan=4, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)

        self.text7 = scrolledtext.ScrolledText(log_frame, width=80, height=12,
                                               font=("Consolas", 9), state='disabled')
        self.text7.pack(fill=tk.BOTH, expand=True)

        # 控制按钮
        control_frame = ttk.Frame(main_frame)
        control_frame.grid(row=10, column=0, columnspan=4, sticky=tk.W, pady=5)

        self.check1 = tk.IntVar(value=1)
        self.chk_show_log = ttk.Checkbutton(control_frame, text="显示日志",
                                            variable=self.check1, command=self.check1_click)
        self.chk_show_log.pack(side=tk.LEFT, padx=5)

        self.chk_auto_scroll = tk.IntVar(value=1)
        ttk.Checkbutton(control_frame, text="自动滚动",
                        variable=self.chk_auto_scroll).pack(side=tk.LEFT, padx=5)

        # 进度条
        self.progress = ttk.Progressbar(control_frame, mode='indeterminate', length=100)
        self.progress.pack(side=tk.RIGHT, padx=5)

        # 配置网格权重
        main_frame.columnconfigure(1, weight=1)
        main_frame.columnconfigure(2, weight=1)
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.rowconfigure(9, weight=1)

    def log_message(self, msg, level="INFO"):
        """在日志框中显示消息"""
        if self.check1.get() == 1:
            self.text7.config(state='normal')

            timestamp = time.strftime("%H:%M:%S")

            tag = None
            if "错误" in msg or "失败" in msg:
                tag = "error"
            elif "警告" in msg:
                tag = "warning"
            elif "完成" in msg or "成功" in msg:
                tag = "success"

            self.text7.tag_config("error", foreground="red")
            self.text7.tag_config("warning", foreground="orange")
            self.text7.tag_config("success", foreground="green")

            line = f"[{timestamp}] {msg}\n"
            if tag:
                self.text7.insert(tk.END, line, tag)
            else:
                self.text7.insert(tk.END, line)

            if self.chk_auto_scroll.get() == 1:
                self.text7.see(tk.END)

            self.text7.config(state='disabled')
            self.root.update()

    def update_status(self, text, color="green"):
        """更新状态栏"""
        self.status_label.config(text=text, foreground=color)
        self.root.update()

    def check1_click(self):
        """复选框点击事件"""
        if self.check1.get() == 1:
            self.text7.grid()
        else:
            self.text7.grid_remove()

    # ============ 程序启动函数 ============
    def command1_click(self):
        program = self.text1.get().strip()
        if program:
            try:
                subprocess.Popen(program, shell=True)
                self.log_message(f"启动程序1: {program}")
                self.update_status("程序1已启动", "green")
            except Exception as e:
                self.log_message(f"启动程序1失败: {e}", "错误")
                self.update_status("启动失败", "red")
        else:
            self.log_message("程序路径1为空", "警告")

    def command3_click(self):
        program = self.text2.get().strip()
        if program:
            try:
                subprocess.Popen(program, shell=True)
                self.log_message(f"启动程序2: {program}")
                self.update_status("程序2已启动", "green")
            except Exception as e:
                self.log_message(f"启动程序2失败: {e}", "错误")
                self.update_status("启动失败", "red")
        else:
            self.log_message("程序路径2为空", "警告")

    def command4_click(self):
        program = self.text5.get().strip()
        if program:
            try:
                subprocess.Popen(program, shell=True)
                self.log_message(f"启动程序3: {program}")
                self.update_status("程序3已启动", "green")
            except Exception as e:
                self.log_message(f"启动程序3失败: {e}", "错误")
                self.update_status("启动失败", "red")
        else:
            self.log_message("程序路径3为空", "警告")

    def command5_click(self):
        program = self.text6.get().strip()
        if program:
            try:
                subprocess.Popen(program, shell=True)
                self.log_message(f"启动程序4: {program}")
                self.update_status("程序4已启动", "green")
            except Exception as e:
                self.log_message(f"启动程序4失败: {e}", "错误")
                self.update_status("启动失败", "red")
        else:
            self.log_message("程序路径4为空", "警告")

    # ============ 鼠标操作函数 ============
    def mouse_action(self, action, x=None, y=None):
        try:
            if action == "mouse_left":
                pyautogui.click(button='left')
                self.log_message("鼠标左键点击")
            elif action == "mouse_right":
                pyautogui.click(button='right')
                self.log_message("鼠标右键点击")
            elif action == "mouse_middle":
                pyautogui.click(button='middle')
                self.log_message("鼠标中键点击")
            elif action == "mouse_left_double":
                pyautogui.doubleClick(button='left')
                self.log_message("鼠标左键双击")
            elif action == "mouse_scroll_up":
                pyautogui.scroll(1)
                self.log_message("滚轮向上")
            elif action == "mouse_scroll_down":
                pyautogui.scroll(-1)
                self.log_message("滚轮向下")
            elif action == "mouse_move_up":
                x, y = pyautogui.position()
                pyautogui.moveTo(x, y - 50)
                self.log_message("鼠标上移")
            elif action == "mouse_move_down":
                x, y = pyautogui.position()
                pyautogui.moveTo(x, y + 50)
                self.log_message("鼠标下移")
            elif action == "mouse_move_left":
                x, y = pyautogui.position()
                pyautogui.moveTo(x - 50, y)
                self.log_message("鼠标左移")
            elif action == "mouse_move_right":
                x, y = pyautogui.position()
                pyautogui.moveTo(x + 50, y)
                self.log_message("鼠标右移")
            elif action == "mouse_click_hold":
                pyautogui.mouseDown()
                self.log_message("鼠标按下")
            elif action == "mouse_click_release":
                pyautogui.mouseUp()
                self.log_message("鼠标释放")
            elif action == "mouse_drag":
                pyautogui.drag(100, 0, duration=0.5)
                self.log_message("鼠标拖动")
            elif action == "mouse_swipe_up":
                pyautogui.scroll(3)
                self.log_message("上滑")
            elif action == "mouse_swipe_down":
                pyautogui.scroll(-3)
                self.log_message("下滑")
            elif action == "mouse_swipe_left":
                keyboard.send("alt+left")
                self.log_message("左滑")
            elif action == "mouse_swipe_right":
                keyboard.send("alt+right")
                self.log_message("右滑")
            elif action == "mouse_zoom_in":
                keyboard.send("ctrl+=")
                self.log_message("放大")
            elif action == "mouse_zoom_out":
                keyboard.send("ctrl+-")
                self.log_message("缩小")
        except Exception as e:
            self.log_message(f"鼠标操作失败: {e}", "错误")

    # ============ 文本输入函数 ============
    def input_text(self, text_key):
        texts = {
            "text_hello": "hello",
            "text_world": "world",
            "text_test": "test",
            "text_123": "123",
            "text_abc": "abc",
            "text_password": "password",
            "text_你好": "你好",
            "text_世界": "世界",
            "text_测试": "测试",
            "text_中文": "中文",
            "text_输入法": "输入法"
        }
        if text_key in texts:
            if any(u'\u4e00' <= c <= u'\u9fff' for c in texts[text_key]):
                try:
                    import pyperclip
                    pyperclip.copy(texts[text_key])
                    keyboard.send("ctrl+v")
                    self.log_message(f"输入中文: {texts[text_key]}")
                except:
                    self.log_message("需要安装 pyperclip 支持中文输入", "警告")
            else:
                pyautogui.write(texts[text_key])
                self.log_message(f"输入文本: {texts[text_key]}")
        elif text_key == "text_date":
            pyautogui.write(time.strftime("%Y-%m-%d"))
            self.log_message("输入当前日期")
        elif text_key == "text_time":
            pyautogui.write(time.strftime("%H:%M:%S"))
            self.log_message("输入当前时间")
        elif text_key == "text_datetime":
            pyautogui.write(time.strftime("%Y-%m-%d %H:%M:%S"))
            self.log_message("输入当前日期时间")

    # ============ 应用程序启动函数 ============
    def launch_app(self, app_name):
        apps = {
            "calc": "calc.exe",
            "notepad": "notepad.exe",
            "paint": "mspaint.exe",
            "cmd": "cmd.exe",
            "explorer": "explorer.exe",
            "taskmgr": "taskmgr.exe",
            "control": "control.exe",
            "snippingtool": "SnippingTool.exe",
            "winword": "WINWORD.EXE",
            "excel": "EXCEL.EXE",
            "powerpnt": "POWERPNT.EXE",
            "outlook": "OUTLOOK.EXE",
            "chrome": "chrome.exe",
            "firefox": "firefox.exe",
            "edge": "msedge.exe",
            "notepad++": "notepad++.exe",
            "vscode": "code.exe",
            "pycharm": "pycharm64.exe"
        }
        if app_name in apps:
            try:
                subprocess.Popen(apps[app_name], shell=True)
                self.log_message(f"启动应用: {app_name}")
            except Exception as e:
                self.log_message(f"启动应用失败: {e}", "错误")

    # ============ 特殊按键函数 ============
    def special_key(self, key_name):
        special_keys = {
            "key_+": "+", "key_-": "-", "key_*": "*", "key_/": "/",
            "key_=": "=", "key_.": ".", "key_,": ",", "key_;": ";",
            "key_:": ":", "key_?": "?", "key_!": "!", "key_@": "@",
            "key_#": "#", "key_$": "$", "key_%": "%", "key_^": "^",
            "key_&": "&", "key_(": "(", "key_)": ")", "key_~": "~",
            "key_`": "`", "key_[": "[", "key_]": "]", "key_\\": "\\",
            "key_{": "{", "key_}": "}", "key_|": "|", "key_<": "<",
            "key_>": ">", "key_\"": "\"", "key_'": "'"
        }
        if key_name in special_keys:
            pyautogui.write(special_keys[key_name])
            self.log_message(f"输入特殊字符: {special_keys[key_name]}")

    # ============ 键盘锁定控制函数 ============
    def toggle_lock(self, lock_type, action):
        try:
            if lock_type == "capslock":
                if action == "on" and not keyboard.is_pressed('capslock'):
                    keyboard.send('capslock')
                elif action == "off" and keyboard.is_pressed('capslock'):
                    keyboard.send('capslock')
                self.log_message(f"Caps Lock: {action}")
            elif lock_type == "numlock":
                if action == "on":
                    pyautogui.press('numlock')
                elif action == "off":
                    pyautogui.press('numlock')
                self.log_message(f"Num Lock: {action}")
            elif lock_type == "scrolllock":
                if action == "on":
                    keyboard.send('scrolllock')
                elif action == "off":
                    keyboard.send('scrolllock')
                self.log_message(f"Scroll Lock: {action}")
        except Exception as e:
            self.log_message(f"锁定键控制失败: {e}", "错误")

    # ============ 宏操作函数 ============
    def macro_action(self, macro_name):
        try:
            if macro_name == "macro_copy_paste":
                keyboard.send("ctrl+c")
                time.sleep(0.1)
                keyboard.send("ctrl+v")
                self.log_message("宏: 复制粘贴")
            elif macro_name == "macro_cut_paste":
                keyboard.send("ctrl+x")
                time.sleep(0.1)
                keyboard.send("ctrl+v")
                self.log_message("宏: 剪切粘贴")
            elif macro_name == "macro_undo_redo":
                keyboard.send("ctrl+z")
                time.sleep(0.1)
                keyboard.send("ctrl+y")
                self.log_message("宏: 撤销重做")
            elif macro_name == "macro_select_all":
                keyboard.send("ctrl+a")
                time.sleep(0.1)
                keyboard.send("ctrl+c")
                self.log_message("宏: 全选复制")
            elif macro_name == "macro_save_close":
                keyboard.send("ctrl+s")
                time.sleep(0.3)
                keyboard.send("alt+f4")
                self.log_message("宏: 保存关闭")
            elif macro_name == "macro_new_save":
                keyboard.send("ctrl+n")
                time.sleep(0.3)
                keyboard.send("ctrl+s")
                self.log_message("宏: 新建保存")
            elif macro_name == "macro_print":
                keyboard.send("ctrl+p")
                time.sleep(0.3)
                keyboard.send("enter")
                self.log_message("宏: 打印预览")
            elif macro_name == "macro_find_replace":
                keyboard.send("ctrl+f")
                time.sleep(0.2)
                keyboard.send("ctrl+h")
                self.log_message("宏: 查找替换")

            # 窗口操作
            elif macro_name == "window_maximize":
                keyboard.send("alt+space")
                time.sleep(0.1)
                keyboard.send("x")
                self.log_message("窗口最大化")
            elif macro_name == "window_minimize":
                keyboard.send("alt+space")
                time.sleep(0.1)
                keyboard.send("n")
                self.log_message("窗口最小化")
            elif macro_name == "window_restore":
                keyboard.send("alt+space")
                time.sleep(0.1)
                keyboard.send("r")
                self.log_message("窗口还原")
            elif macro_name == "window_close":
                keyboard.send("alt+f4")
                self.log_message("关闭窗口")
            elif macro_name == "window_next":
                keyboard.send("alt+tab")
                self.log_message("下一个窗口")
            elif macro_name == "window_prev":
                keyboard.send("alt+shift+tab")
                self.log_message("上一个窗口")

            # 系统工具
            elif macro_name == "system_properties":
                keyboard.send("win+pause")
                self.log_message("系统属性")
            elif macro_name == "device_manager":
                keyboard.send("win+r")
                time.sleep(0.2)
                pyautogui.write("devmgmt.msc")
                time.sleep(0.1)
                keyboard.send("enter")
                self.log_message("设备管理器")
            elif macro_name == "task_scheduler":
                keyboard.send("win+r")
                time.sleep(0.2)
                pyautogui.write("taskschd.msc")
                time.sleep(0.1)
                keyboard.send("enter")
                self.log_message("任务计划")
            elif macro_name == "event_viewer":
                keyboard.send("win+r")
                time.sleep(0.2)
                pyautogui.write("eventvwr.msc")
                time.sleep(0.1)
                keyboard.send("enter")
                self.log_message("事件查看器")
            elif macro_name == "services":
                keyboard.send("win+r")
                time.sleep(0.2)
                pyautogui.write("services.msc")
                time.sleep(0.1)
                keyboard.send("enter")
                self.log_message("服务")
            elif macro_name == "registry":
                keyboard.send("win+r")
                time.sleep(0.2)
                pyautogui.write("regedit")
                time.sleep(0.1)
                keyboard.send("enter")
                self.log_message("注册表")

        except Exception as e:
            self.log_message(f"宏操作失败: {e}", "错误")

    # ============ 测试键盘函数 ============
    def test_keyboard(self):
        test_window = tk.Toplevel(self.root)
        test_window.title("键盘测试")
        test_window.geometry("500x400")

        frame = ttk.Frame(test_window, padding="20")
        frame.pack(fill=tk.BOTH, expand=True)

        ttk.Label(frame, text="点击测试按钮模拟按键", font=("Arial", 12)).pack(pady=10)

        buttons = [
            ("Tab", "tab"), ("Enter", "enter"), ("Space", "space"),
            ("Esc", "esc"), ("Delete", "delete"), ("Home", "home"),
            ("End", "end"), ("PageUp", "pageup"), ("PageDown", "pagedown"),
            ("F1", "f1"), ("F5", "f5"), ("F11", "f11"),
            ("Ctrl+C", "ctrl+c"), ("Ctrl+V", "ctrl+v"), ("Ctrl+A", "ctrl+a"),
            ("Win+D", "win+d"), ("Win+E", "win+e"), ("Alt+Tab", "alt+tab"),
            ("Ctrl++", "ctrl+="), ("Ctrl+-", "ctrl+-")
        ]

        btn_frame = ttk.Frame(frame)
        btn_frame.pack(pady=10)

        for i, (label, key) in enumerate(buttons):
            row = i // 4
            col = i % 4
            ttk.Button(btn_frame, text=label,
                       command=lambda k=key: self.test_single_key(k)).grid(row=row, column=col, padx=2, pady=2)

        ttk.Label(frame, text="请输入自定义按键:", font=("Arial", 10)).pack(pady=(20, 5))

        entry_frame = ttk.Frame(frame)
        entry_frame.pack(pady=5)

        key_entry = ttk.Entry(entry_frame, width=20)
        key_entry.pack(side=tk.LEFT, padx=5)

        def test_custom():
            key = key_entry.get().strip()
            if key:
                self.test_single_key(key)
                key_entry.delete(0, tk.END)

        ttk.Button(entry_frame, text="测试", command=test_custom).pack(side=tk.LEFT)
        ttk.Button(entry_frame, text="关闭", command=test_window.destroy).pack(side=tk.LEFT, padx=5)

    def test_single_key(self, key):
        try:
            keyboard.send(key)
            self.log_message(f"测试按键: {key} (已发送)")
        except Exception as e:
            self.log_message(f"测试按键失败: {key} - {e}", "错误")

    # ============ 执行指令核心函数 ============
    def execute_instruction(self, token, delay_ms):
        try:
            # 1. 检查是否为1位数映射 (0-9)
            if token in self.one_digit_map:
                command = self.one_digit_map[token]

                # 程序启动
                if command == "launch_prog1":
                    self.command1_click()
                elif command == "launch_prog2":
                    self.command3_click()
                elif command == "launch_prog3":
                    self.command4_click()
                elif command == "launch_prog4":
                    self.command5_click()
                else:
                    # 组合键操作
                    keyboard.send(command)
                    self.log_message(f"执行按键: {command}")
                time.sleep(delay_ms / 1000.0)
                return

            # 2. 检查是否为2位数映射
            if token in self.two_digit_map:
                key = self.two_digit_map[token]
                keyboard.send(key)
                self.log_message(f"执行按键: {key}")
                time.sleep(delay_ms / 1000.0)
                return

            # 3. 检查是否为3位数映射
            if token in self.three_digit_map:
                command = self.three_digit_map[token]

                # 锁定键控制
                if command in ["capslock", "numlock", "scrolllock"]:
                    self.toggle_lock(command, "on")
                    time.sleep(delay_ms / 1000.0)
                    return
                elif command in ["capslock_on", "capslock_off"]:
                    lock_type = command.split('_')[0]
                    action = command.split('_')[1]
                    self.toggle_lock(lock_type, action)
                    time.sleep(delay_ms / 1000.0)
                    return
                elif command in ["numlock_on", "numlock_off"]:
                    lock_type = command.split('_')[0]
                    action = command.split('_')[1]
                    self.toggle_lock(lock_type, action)
                    time.sleep(delay_ms / 1000.0)
                    return
                elif command in ["scrolllock_on", "scrolllock_off"]:
                    lock_type = command.split('_')[0]
                    action = command.split('_')[1]
                    self.toggle_lock(lock_type, action)
                    time.sleep(delay_ms / 1000.0)
                    return

                # 鼠标操作
                if command.startswith("mouse_"):
                    self.mouse_action(command)
                    time.sleep(delay_ms / 1000.0)
                    return

                # 文本输入
                if command.startswith("text_"):
                    self.input_text(command)
                    time.sleep(delay_ms / 1000.0)
                    return

                # 应用程序
                if command in ["calc", "notepad", "paint", "cmd", "explorer", "taskmgr", "control", "snippingtool",
                               "winword", "excel", "powerpnt", "outlook", "chrome", "firefox", "edge",
                               "notepad++", "vscode", "pycharm"]:
                    self.launch_app(command)
                    time.sleep(delay_ms / 1000.0)
                    return

                # 特殊按键
                if command.startswith("key_"):
                    self.special_key(command)
                    time.sleep(delay_ms / 1000.0)
                    return

                # 普通按键
                try:
                    keyboard.send(command)
                    self.log_message(f"执行按键: {command}")
                except:
                    pyautogui.press(command)
                    self.log_message(f"执行按键(备用): {command}")
                time.sleep(delay_ms / 1000.0)
                return

            # 4. 检查是否为4位数映射
            if token in self.four_digit_map:
                command = self.four_digit_map[token]

                # 宏操作
                if command.startswith("macro_"):
                    self.macro_action(command)
                    time.sleep(delay_ms / 1000.0)
                    return

                # 窗口操作
                if command.startswith("window_"):
                    self.macro_action(command)
                    time.sleep(delay_ms / 1000.0)
                    return

                # 系统工具
                if command in ["system_properties", "device_manager", "task_scheduler", "event_viewer", "services",
                               "registry"]:
                    self.macro_action(command)
                    time.sleep(delay_ms / 1000.0)
                    return

                # 中文输入
                if command.startswith("text_"):
                    self.input_text(command)
                    time.sleep(delay_ms / 1000.0)
                    return

                # 指定坐标点击
                if command.startswith("mouse_click_"):
                    try:
                        coords = command.split('_')[2]
                        x, y = int(coords[0:1]) * 100, int(coords[1:2]) * 100
                        pyautogui.click(x, y)
                        self.log_message(f"点击坐标: ({x}, {y})")
                    except:
                        pass
                    time.sleep(delay_ms / 1000.0)
                    return

            # 5. 未识别的指令
            self.log_message(f"未知指令: {token}", "警告")

        except Exception as e:
            self.log_message(f"执行指令失败 {token}: {e}", "错误")

    def command2_click(self):
        """执行指令序列"""
        instruction_str = self.text4.get().strip()
        if not instruction_str:
            self.log_message("指令序列为空", "警告")
            return

        separator = self.text_separator.get().strip()
        if not separator:
            separator = "-"

        tokens = instruction_str.split(separator)
        tokens = [t.strip() for t in tokens if t.strip()]

        if not tokens:
            self.log_message("没有有效的指令", "警告")
            return

        delay_str = self.text3.get().strip()
        try:
            delay_ms = int(delay_str) if delay_str else 100
        except ValueError:
            delay_ms = 100
            self.log_message(f"延迟值无效,使用默认值: {delay_ms}ms", "警告")

        repeat_str = self.text_repeat.get().strip()
        try:
            repeat_count = int(repeat_str) if repeat_str else 1
            repeat_count = max(1, min(repeat_count, 999))
        except ValueError:
            repeat_count = 1
            self.log_message(f"执行次数无效,使用默认值: 1", "警告")

        self.log_message(f"开始执行指令序列,共 {len(tokens)} 个指令,重复 {repeat_count} 次")
        self.log_message(f"指令列表: {tokens}")
        self.update_status("执行中...", "orange")
        self.progress.start()

        def execute_thread():
            try:
                total_instructions = len(tokens) * repeat_count
                for rep in range(repeat_count):
                    if rep > 0:
                        self.log_message(f"--- 第 {rep + 1} 次执行 ---")

                    for i, token in enumerate(tokens):
                        current = rep * len(tokens) + i + 1
                        self.log_message(f"[{current}/{total_instructions}] 执行: '{token}'")
                        self.execute_instruction(token, delay_ms)

                self.log_message(f"✅ 指令序列执行完成!共执行 {total_instructions} 个指令")
                self.update_status("执行完成 ✅", "green")

            except Exception as e:
                self.log_message(f"执行过程中发生错误: {e}", "错误")
                self.update_status("执行出错 ❌", "red")
            finally:
                self.progress.stop()

        threading.Thread(target=execute_thread, daemon=True).start()

    # ============ 帮助和示例功能 ============
    def show_help(self):
        help_window = tk.Toplevel(self.root)
        help_window.title("使用帮助 - 纯数字执行机器人 v1.0")
        help_window.geometry("900x700")

        frame = ttk.Frame(help_window)
        frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        text_widget = scrolledtext.ScrolledText(frame, font=("Consolas", 10), wrap=tk.WORD)
        text_widget.pack(fill=tk.BOTH, expand=True)

        help_text = """
╔═══════════════════════════════════════════════════════════════════════════╗
║                   纯数字执行机器人 v1.0                                  ║
║             所有指令均为纯数字,无字母!                                  ║
╚═══════════════════════════════════════════════════════════════════════════╝

【基本用法】
1. 在"指令序列"框中输入数字指令,使用分隔符(默认 -)分隔
2. 设置延迟时间(毫秒)
3. 点击"执行指令"按钮

示例: 0-1-2-3-21-70-200-300-700

【1位数指令 (0-9)】
  0 = 启动程序1    1 = 启动程序2
  2 = 启动程序3    3 = 启动程序4
  4 = Ctrl+A (全选)  5 = Ctrl+C (复制)
  6 = Ctrl+V (粘贴)  7 = Ctrl+S (保存)
  8 = Ctrl+Z (撤销)  9 = Ctrl+Y (重做)

【2位数指令 (00-99)】
  00-09 = Ctrl+0~9    10-19 = Alt+0~9
  20-29 = Shift+0~9   30-39 = Win+0~9
  40-49 = Ctrl+Shift+0~9
  50-59 = Alt+Shift+0~9
  60-69 = Ctrl+Alt+0~9
  70-79 = F1~F10
  80-89 = 方向键/编辑键
  90-99 = 多媒体键

【3位数指令 (000-999)】
  000-025 = a-z (小写字母)
  026-051 = A-Z (大写字母)
  052-061 = 0-9 (数字键)
  062-099 = 特殊符号和功能键
  100-108 = F4~F12
  109-120 = F13~F24
  121-123 = Caps/Num/Scroll Lock
  130-135 = Lock 开关控制
  140-156 = 小键盘
  170-180 = 组合键

  200-211 = 鼠标操作
  220-225 = 鼠标手势

  300-316 = 文本操作 (Ctrl组合)

  400-415 = 系统操作

  700-717 = 应用启动

  800-808 = 文本输入

  900-930 = 特殊符号

【4位数指令 (0000-9999)】
  0001-0008 = 宏操作
  0100-0105 = 窗口操作
  0200-0205 = 系统工具
  0300-0304 = 指定坐标点击
  0400-0404 = 中文输入

【常用指令速查】
鼠标操作:
  200=左键  201=右键  202=中键  203=双击
  204=滚轮上  205=滚轮下  224=放大  225=缩小

系统操作:
  400=显示桌面  401=文件管理器  402=运行
  403=最小化所有  405=锁定电脑  410=关闭窗口

文本操作:
  300=全选  301=复制  302=粘贴  303=剪切
  304=撤销  305=重做  308=保存  309=打开

应用程序:
  700=计算器  701=记事本  702=画图  703=命令提示符
  704=资源管理器  705=任务管理器  712=Chrome  716=VS Code


# ============ 1位数映射 (0-9) ============
self.one_digit_map = {
# 0-3: 启动程序1-4
"0": "launch_prog1",
"1": "launch_prog2",
"2": "launch_prog3",
"3": "launch_prog4",
# 4-9: 常用操作
"4": "ctrl+a",  # 全选
"5": "ctrl+c",  # 复制
"6": "ctrl+v",  # 粘贴
"7": "ctrl+s",  # 保存
"8": "ctrl+z",  # 撤销
"9": "ctrl+y",  # 重做
}

# ============ 2位数映射 (00-99) ============
self.two_digit_map = {
# 00-09: Ctrl+数字
"00": "ctrl+0", "01": "ctrl+1", "02": "ctrl+2", "03": "ctrl+3",
"04": "ctrl+4", "05": "ctrl+5", "06": "ctrl+6", "07": "ctrl+7",
"08": "ctrl+8", "09": "ctrl+9",

# 10-19: Alt+数字
"10": "alt+0", "11": "alt+1", "12": "alt+2", "13": "alt+3",
"14": "alt+4", "15": "alt+5", "16": "alt+6", "17": "alt+7",
"18": "alt+8", "19": "alt+9",

# 20-29: Shift+数字
"20": "shift+0", "21": "shift+1", "22": "shift+2", "23": "shift+3",
"24": "shift+4", "25": "shift+5", "26": "shift+6", "27": "shift+7",
"28": "shift+8", "29": "shift+9",

# 30-39: Win+数字
"30": "win+0", "31": "win+1", "32": "win+2", "33": "win+3",
"34": "win+4", "35": "win+5", "36": "win+6", "37": "win+7",
"38": "win+8", "39": "win+9",

# 40-49: Ctrl+Shift+数字
"40": "ctrl+shift+0", "41": "ctrl+shift+1", "42": "ctrl+shift+2",
"43": "ctrl+shift+3", "44": "ctrl+shift+4", "45": "ctrl+shift+5",
"46": "ctrl+shift+6", "47": "ctrl+shift+7", "48": "ctrl+shift+8",
"49": "ctrl+shift+9",

# 50-59: Alt+Shift+数字
"50": "alt+shift+0", "51": "alt+shift+1", "52": "alt+shift+2",
"53": "alt+shift+3", "54": "alt+shift+4", "55": "alt+shift+5",
"56": "alt+shift+6", "57": "alt+shift+7", "58": "alt+shift+8",
"59": "alt+shift+9",

# 60-69: Ctrl+Alt+数字
"60": "ctrl+alt+0", "61": "ctrl+alt+1", "62": "ctrl+alt+2",
"63": "ctrl+alt+3", "64": "ctrl+alt+4", "65": "ctrl+alt+5",
"66": "ctrl+alt+6", "67": "ctrl+alt+7", "68": "ctrl+alt+8",
"69": "ctrl+alt+9",

# 70-79: 功能键
"70": "f1", "71": "f2", "72": "f3", "73": "f4",
"74": "f5", "75": "f6", "76": "f7", "77": "f8",
"78": "f9", "79": "f10",

# 80-89: 方向键和编辑键
"80": "up",  # 上箭头
"81": "down",  # 下箭头
"82": "left",  # 左箭头
"83": "right",  # 右箭头
"84": "pageup",  # PageUp
"85": "pagedown",  # PageDown
"86": "home",  # Home
"87": "end",  # End
"88": "insert",  # Insert
"89": "delete",  # Delete

# 90-99: 多媒体键
"90": "volumeup",  # 音量+
"91": "volumedown",  # 音量-
"92": "volumemute",  # 静音
"93": "playpause",  # 播放/暂停
"94": "stop",  # 停止
"95": "nexttrack",  # 下一曲
"96": "prevtrack",  # 上一曲
"97": "mediaselect",  # 媒体选择
"98": "printscreen",  # 截图
"99": "pause",  # Pause/Break
}

# ============ 3位数映射 (000-999) ============
self.three_digit_map = {
# ===== 标准键盘按键 000-099 =====
# 字母键 (000-025: a-z)
"000": "a", "001": "b", "002": "c", "003": "d", "004": "e",
"005": "f", "006": "g", "007": "h", "008": "i", "009": "j",
"010": "k", "011": "l", "012": "m", "013": "n", "014": "o",
"015": "p", "016": "q", "017": "r", "018": "s", "019": "t",
"020": "u", "021": "v", "022": "w", "023": "x", "024": "y",
"025": "z",

# 大写字母 (026-051)
"026": "A", "027": "B", "028": "C", "029": "D", "030": "E",
"031": "F", "032": "G", "033": "H", "034": "I", "035": "J",
"036": "K", "037": "L", "038": "M", "039": "N", "040": "O",
"041": "P", "042": "Q", "043": "R", "044": "S", "045": "T",
"046": "U", "047": "V", "048": "W", "049": "X", "050": "Y",
"051": "Z",

# 数字键 (052-061)
"052": "0", "053": "1", "054": "2", "055": "3", "056": "4",
"057": "5", "058": "6", "059": "7", "060": "8", "061": "9",

# 特殊键 (062-099)
"062": "`", "063": "-", "064": "=", "065": "[", "066": "]",
"067": "\\", "068": ";", "069": "'", "070": ",", "071": ".",
"072": "/", "073": "space", "074": "tab", "075": "capslock",
"076": "shift", "077": "ctrl", "078": "alt", "079": "win",
"080": "printscreen", "081": "scrolllock", "082": "pause",
"083": "insert", "084": "home", "085": "pageup", "086": "delete",
"087": "end", "088": "pagedown", "089": "up", "090": "down",
"091": "left", "092": "right", "093": "numlock", "094": "enter",
"095": "backspace", "096": "esc", "097": "f1", "098": "f2",
"099": "f3",

# ===== 功能键扩展 100-199 =====
"100": "f4", "101": "f5", "102": "f6", "103": "f7", "104": "f8",
"105": "f9", "106": "f10", "107": "f11", "108": "f12",

# F13-F24
"109": "f13", "110": "f14", "111": "f15", "112": "f16",
"113": "f17", "114": "f18", "115": "f19", "116": "f20",
"117": "f21", "118": "f22", "119": "f23", "120": "f24",

# 键盘锁定键 (121-129)
"121": "capslock", "122": "numlock", "123": "scrolllock",

# 键盘指示灯控制 (130-139)
"130": "capslock_on", "131": "capslock_off",
"132": "numlock_on", "133": "numlock_off",
"134": "scrolllock_on", "135": "scrolllock_off",

# 小键盘 (140-169)
"140": "num0", "141": "num1", "142": "num2", "143": "num3",
"144": "num4", "145": "num5", "146": "num6", "147": "num7",
"148": "num8", "149": "num9",
"150": "num.", "151": "num,", "152": "num/", "153": "num*",
"154": "num-", "155": "num+", "156": "numenter",

# 组合键 (170-180)
"170": "ctrl+shift", "171": "ctrl+alt", "172": "alt+shift",
"173": "ctrl+alt+shift", "174": "ctrl+win", "175": "alt+win",
"176": "win+shift", "177": "ctrl+alt+win", "178": "ctrl+shift+win",
"179": "alt+shift+win", "180": "ctrl+alt+shift+win",

# ===== 鼠标操作 200-299 =====
"200": "mouse_left",  # 鼠标左键
"201": "mouse_right",  # 鼠标右键
"202": "mouse_middle",  # 鼠标中键
"203": "mouse_left_double",  # 鼠标左键双击
"204": "mouse_scroll_up",  # 滚轮向上
"205": "mouse_scroll_down",  # 滚轮向下
"206": "mouse_move_up",  # 鼠标向上移动
"207": "mouse_move_down",  # 鼠标向下移动
"208": "mouse_move_left",  # 鼠标向左移动
"209": "mouse_move_right",  # 鼠标向右移动
"210": "mouse_click_hold",  # 鼠标按住
"211": "mouse_click_release",  # 鼠标释放

# 鼠标高级操作 (212-219)
"212": "mouse_drag",  # 拖动
"213": "mouse_drop",  # 释放拖动
"214": "mouse_hover",  # 悬停

# 鼠标手势 (220-229)
"220": "mouse_swipe_up",  # 上滑
"221": "mouse_swipe_down",  # 下滑
"222": "mouse_swipe_left",  # 左滑
"223": "mouse_swipe_right",  # 右滑
"224": "mouse_zoom_in",  # 放大 (Ctrl+=)
"225": "mouse_zoom_out",  # 缩小 (Ctrl+-)

# ===== 文本操作 300-399 =====
"300": "ctrl+a",  # 全选
"301": "ctrl+c",  # 复制
"302": "ctrl+v",  # 粘贴
"303": "ctrl+x",  # 剪切
"304": "ctrl+z",  # 撤销
"305": "ctrl+y",  # 重做
"306": "ctrl+f",  # 查找
"307": "ctrl+h",  # 替换
"308": "ctrl+s",  # 保存
"309": "ctrl+o",  # 打开
"310": "ctrl+n",  # 新建
"311": "ctrl+p",  # 打印
"312": "ctrl+w",  # 关闭
"313": "ctrl+shift+esc",  # 任务管理器
"314": "ctrl+shift+n",  # 新建文件夹
"315": "ctrl+shift+s",  # 另存为
"316": "ctrl+shift+z",  # 重做

# ===== 系统操作 400-499 =====
"400": "win+d",  # 显示桌面
"401": "win+e",  # 文件资源管理器
"402": "win+r",  # 运行
"403": "win+m",  # 最小化所有
"404": "win+shift+m",  # 还原所有
"405": "win+l",  # 锁定电脑
"406": "win+p",  # 投影设置
"407": "win+i",  # 设置
"408": "win+s",  # 搜索
"409": "win+x",  # 快速链接菜单
"410": "alt+f4",  # 关闭窗口
"411": "alt+tab",  # 切换窗口
"412": "ctrl+alt+delete",  # 安全选项
"413": "ctrl+shift+esc",  # 任务管理器
"414": "win+tab",  # 任务视图
"415": "alt+space",  # 窗口菜单

# ===== 应用启动 700-799 =====
"700": "calc",  # 计算器
"701": "notepad",  # 记事本
"702": "paint",  # 画图
"703": "cmd",  # 命令提示符
"704": "explorer",  # 资源管理器
"705": "taskmgr",  # 任务管理器
"706": "control",  # 控制面板
"707": "snippingtool",  # 截图工具
"708": "winword",  # Word
"709": "excel",  # Excel
"710": "powerpnt",  # PowerPoint
"711": "outlook",  # Outlook
"712": "chrome",  # Chrome
"713": "firefox",  # Firefox
"714": "edge",  # Edge
"715": "notepad++",  # Notepad++
"716": "vscode",  # VS Code
"717": "pycharm",  # PyCharm

# ===== 文本输入 800-899 =====
"800": "text_hello",  # 输入"hello"
"801": "text_world",  # 输入"world"
"802": "text_test",  # 输入"test"
"803": "text_123",  # 输入"123"
"804": "text_abc",  # 输入"abc"
"805": "text_password",  # 输入"password"
"806": "text_date",  # 输入当前日期
"807": "text_time",  # 输入当前时间
"808": "text_datetime",  # 输入当前日期时间

# ===== 特殊符号 900-999 =====
"900": "key_+", "901": "key_-", "902": "key_*", "903": "key_/",
"904": "key_=", "905": "key_.", "906": "key_,", "907": "key_;",
"908": "key_:", "909": "key_?", "910": "key_!", "911": "key_@",
"912": "key_#", "913": "key_$", "914": "key_%", "915": "key_^",
"916": "key_&", "917": "key_(", "918": "key_)", "919": "key_~",
"920": "key_`", "921": "key_[", "922": "key_]", "923": "key_\\",
"924": "key_{", "925": "key_}", "926": "key_|", "927": "key_<",
"928": "key_>", "929": "key_\"", "930": "key_'",
}

# ============ 4位数映射 (0000-9999) ============
self.four_digit_map = {
# ===== 宏操作 =====
"0001": "macro_copy_paste",  # 复制粘贴
"0002": "macro_cut_paste",  # 剪切粘贴
"0003": "macro_undo_redo",  # 撤销重做
"0004": "macro_select_all",  # 全选复制
"0005": "macro_save_close",  # 保存关闭
"0006": "macro_new_save",  # 新建保存
"0007": "macro_print",  # 打印预览
"0008": "macro_find_replace",  # 查找替换

# ===== 窗口操作 =====
"0100": "window_maximize",  # 最大化
"0101": "window_minimize",  # 最小化
"0102": "window_restore",  # 还原
"0103": "window_close",  # 关闭
"0104": "window_next",  # 下一个窗口
"0105": "window_prev",  # 上一个窗口

# ===== 系统工具 =====
"0200": "system_properties",  # 系统属性
"0201": "device_manager",  # 设备管理器
"0202": "task_scheduler",  # 任务计划
"0203": "event_viewer",  # 事件查看器
"0204": "services",  # 服务
"0205": "registry",  # 注册表

# ===== 指定坐标点击 =====
"0300": "mouse_click_100",  # 在(100,100)点击
"0301": "mouse_click_200",  # 在(200,200)点击
"0302": "mouse_click_300",  # 在(300,300)点击
"0303": "mouse_click_400",  # 在(400,400)点击
"0304": "mouse_click_500",  # 在(500,500)点击

# ===== 中文输入 =====
"0400": "text_你好",
"0401": "text_世界",
"0402": "text_测试",
"0403": "text_中文",
"0404": "text_输入法",

【注意事项】
1. 执行系统操作前请保存工作
2. 鼠标操作会控制实际鼠标
3. 执行过程中可按 Ctrl+C 中断
4. 中文输入需要安装 pyperclip: pip install pyperclip
"""

        text_widget.insert(tk.END, help_text)
        text_widget.config(state='disabled')

    def show_examples(self):
        examples = [
            ("启动程序", "0-1-2-3"),
            ("快捷键", "4-5-6-7-8-9"),
            ("鼠标操作", "200-201-202-203-204-205"),
            ("鼠标手势", "220-221-222-223-224-225"),
            ("键盘锁定", "121-122-123-130-131-132"),
            ("小键盘", "140-141-142-143-144-145-146-147-148-149-150-156"),
            ("系统操作", "400-401-402-403-404-405-406-407-408-409"),
            ("文本操作", "300-301-302-303-304-305-306-307-308"),
            ("组合键", "00-01-10-11-20-21-30-31"),
            ("多媒体", "90-91-92-93-94-95-96-97"),
            ("特殊字符", "900-901-902-903-904-905-906-907-908-909-910"),
            ("宏操作", "0001-0002-0003-0004-0005-0006"),
            ("窗口操作", "0100-0101-0102-0103-0104-0105"),
            ("应用启动", "700-701-702-703-704-705-706-707"),
            ("文本输入", "800-801-802-803-804-805"),
            ("中文输入", "0400-0401-0402-0403-0404"),
            ("完整示例", "0-4-70-200-300-400-700-800-900")
        ]

        example_window = tk.Toplevel(self.root)
        example_window.title("指令示例")
        example_window.geometry("600x500")

        frame = ttk.Frame(example_window, padding="10")
        frame.pack(fill=tk.BOTH, expand=True)

        ttk.Label(frame, text="选择示例指令:", font=("Arial", 12, "bold")).pack(pady=(0, 10))

        listbox = tk.Listbox(frame, height=15, font=("Consolas", 10))
        listbox.pack(fill=tk.BOTH, expand=True, pady=(0, 10))

        for name, cmd in examples:
            listbox.insert(tk.END, f"{name:14} → {cmd}")

        btn_frame = ttk.Frame(frame)
        btn_frame.pack(fill=tk.X)

        def apply_example():
            selection = listbox.curselection()
            if selection:
                idx = selection[0]
                name, cmd = examples[idx]
                self.text4.delete(0, tk.END)
                self.text4.insert(0, cmd)
                self.log_message(f"应用示例: {name}")
                example_window.destroy()
            else:
                messagebox.showwarning("提示", "请先选择一个示例")

        ttk.Button(btn_frame, text="应用示例", command=apply_example).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, text="关闭", command=example_window.destroy).pack(side=tk.RIGHT, padx=5)

    def reset_all(self):
        self.text1.delete(0, tk.END)
        self.text2.delete(0, tk.END)
        self.text5.delete(0, tk.END)
        self.text6.delete(0, tk.END)
        self.text4.delete(0, tk.END)
        self.text3.delete(0, tk.END)
        self.text3.insert(0, "100")
        self.text_repeat.delete(0, tk.END)
        self.text_repeat.insert(0, "1")
        self.text_separator.delete(0, tk.END)
        self.text_separator.insert(0, "-")
        self.log_message("已重置所有设置")
        self.update_status("已重置", "blue")

    def clear_log(self):
        self.text7.config(state='normal')
        self.text7.delete(1.0, tk.END)
        self.text7.config(state='disabled')
        self.log_message("日志已清空")


if __name__ == "__main__":
    try:
        import pyperclip
    except ImportError:
        print("提示: 安装 pyperclip 以支持中文输入: pip install pyperclip")

    root = tk.Tk()
    app = PureDigitalExecutorApp(root)
    root.mainloop()

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐