# easy_touchpad_switch **Repository Path**: gateslu1986_admin/easy_touchpad_switch ## Basic Information - **Project Name**: easy_touchpad_switch - **Description**: windows下触摸板快捷切换usb插入时的触摸板的开关状态 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-09 - **Last Updated**: 2026-10-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # easy_touchpad_switch 常驻 Windows 系统托盘的小工具:一键切换 **「连接鼠标时保持触摸板开启」**。 - 全局快捷键切换,**组合可自定义**(默认 `Ctrl+Shift+Alt+T`),改完在托盘菜单点「重新加载配置」即可生效,无需重启 - 托盘图标实时反映状态:绿色 = 鼠标连接时触摸板保持开启;灰色带斜杠 = 会被关闭 - 左键单击托盘图标同样可以切换 - 托盘菜单支持「开机自动启动」 - 单实例运行,避免重复注册快捷键、出现多个托盘图标 - 支持命令行:`--status` / `--toggle` / `--on` / `--off`(可挂到鼠标侧键或其它启动器上) ## 安装与卸载 程序本身就是安装包(单文件、免管理员、可卸载): ```powershell .\package.ps1 # 构建并生成 dist\EasyTouchpadSwitch-Setup-<版本>.exe ``` 双击生成的 exe 会询问是否安装;也可以显式安装/卸载: ```powershell EasyTouchpadSwitch-Setup-0.1.0.exe --install # 安装 EasyTouchpadSwitch-Setup-0.1.0.exe --install --silent # 静默安装(无对话框) EasyTouchpadSwitch-Setup-0.1.0.exe --uninstall # 卸载(有确认框) ``` 安装会做这些事(全部在当前用户范围内,**不需要管理员权限**): | 项目 | 位置 | | --- | --- | | 程序文件 | `%LOCALAPPDATA%\Programs\EasyTouchpadSwitch\` | | 开始菜单快捷方式 | `%APPDATA%\Microsoft\Windows\Start Menu\Programs\Easy Touchpad Switch.lnk` | | 开机自动启动 | `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` → `EasyTouchpadSwitch` | | 卸载入口 | 「设置 → 应用 → 已安装的应用 → Easy Touchpad Switch」 | 三种卸载方式:已安装的应用里点卸载、托盘菜单「卸载……」、或 `--uninstall`。 卸载会移除程序目录、快捷方式、开机自启与卸载入口;配置文件与日志 (`%APPDATA%\easy_touchpad_switch`)会保留,需要清理时手动删除该目录即可。 > 开发构建(`cargo run` / `target\...` 下的 exe)不会被安装流程打扰,直接运行即可。 ## 背景:这个开关存在哪里(重要) Windows 设置 → 蓝牙和其他设备 → 触摸板 → 「连接鼠标时让触摸板保持打开状态」。 **Windows 11 build 26027+ / 25H2 起,这个设置由实时 API 承载,而不是注册表:** ```c // WinUser.h #define SPI_GETTOUCHPADPARAMETERS 0x00AE #define SPI_SETTOUCHPADPARAMETERS 0x00AF typedef struct TOUCHPAD_PARAMETERS_V1 { UINT versionNumber; UINT maxSupportedContacts; ... BOOL touchpadPresent : 1; /* 状态位段,设置时被忽略 */ BOOL touchpadEnabled : 1; ... BOOL allowActiveWhenMousePresent : 1; /* ← 就是「连接鼠标时让触摸板保持打开状态」 */ ... } TOUCHPAD_PARAMETERS_V1; ``` 调用方式:先 `SystemParametersInfo(SPI_GETTOUCHPADPARAMETERS, sizeof(params), ¶ms, 0)` 读出 全部设置,改掉 `allowActiveWhenMousePresent` 位后,再用 `SystemParametersInfo(SPI_SETTOUCHPADPARAMETERS, sizeof(params), ¶ms, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)` 写回。 **实测结论(本机 Windows 11 25H2,build 26200):这个 API 的存储与注册表 `HKCU\...\PrecisionTouchPad\LeaveOnWithMouse` 是互相独立的两个位置。** - 把注册表改成 `1` / `0xFFFFFFFF`(开启),API 依然报告 `allowActiveWhenMousePresent = 0`; - 25H2 的「设置」页面读的是 API,所以**只改注册表既不会让设置页的复选框变化,也不会真正生效**; - 而设置应用在勾选时仍会往注册表写一份 `0xFFFFFFFF` 作为镜像,容易让人误以为注册表才是真身。 因此本程序: 1. **主用实时 API**(设置页能读到、立即生效,写完还会回读校验); 2. 同时**写一份注册表镜像**,供 Windows 11 build 26027 之前的老系统使用; 3. 老系统上 API 不存在,会自动回退到注册表。 仅支持精确式触摸板(Precision Touchpad),传统厂商驱动的触摸板没有这些接口。 ## 构建与运行 ```powershell cargo build --release .\target\release\easy_touchpad_switch.exe ``` release 构建为无控制台窗口的 GUI 程序。需要 Rust 1.85+(edition 2024)。 ## 命令行 ```powershell easy_touchpad_switch.exe --status # 查看状态、实时 API 信息与注册表镜像 easy_touchpad_switch.exe --toggle # 切换一次后退出 easy_touchpad_switch.exe --on # 直接开启 easy_touchpad_switch.exe --off # 直接关闭 easy_touchpad_switch.exe --install # 安装到本机(含开机自启) easy_touchpad_switch.exe --uninstall # 卸载(加 --silent 跳过确认框) ``` `--status` 输出示例: ``` 连接鼠标时保持触摸板开启:已开启 实时 API:触摸板存在,外接鼠标已连接,触摸板当前可用 注册表镜像:LeaveOnWithMouse = 4294967295(0xFFFFFFFF) 快捷键配置:Ctrl+Shift+Alt+T ``` 这些子命令不启动托盘、不占用快捷键,适合被 AutoHotkey、鼠标驱动宏等外部工具调用。 发布版是 GUI 子系统程序,终端(PowerShell / cmd)**不会等待它结束**,所以输出可能出现在提示符之后; 脚本里建议这样调用: ```powershell Start-Process .\easy_touchpad_switch.exe -ArgumentList '--toggle' -NoNewWindow -Wait ``` 或者用 debug 构建(`cargo run -- --status`)直接看输出。 ## 配置快捷键 首次运行会在 `%APPDATA%\easy_touchpad_switch\config.toml` 生成: ```toml # 快捷键组合,用 + 连接,大小写不敏感,顺序随意。修饰键:Ctrl / Alt / Shift / Win hotkey = "Ctrl+Shift+Alt+T" ``` 改完在托盘菜单点 **「重新加载配置(快捷键)」** 立即生效(注册失败会保留原快捷键并写入日志),也可以直接重启程序。 写法说明: | 部分 | 可写内容 | | --- | --- | | 修饰键 | `Ctrl` / `Control` / `Ctl`、`Alt`、`Shift`、`Win` / `Super` / `Meta` / `Cmd`(可任意组合、可省略) | | 字母数字 | `T`、`5` | | 功能键 | `F1` ~ `F24` | | 常用键 | `Space`、`Tab`、`Enter`、`Esc`、`Backspace`、`Delete`、`Insert`、`Home`、`End`、`PageUp`、`PageDown`、`Up` / `Down` / `Left` / `Right` | | 符号键 | `` ` ``、`-`、`=`、`[`、`]`、`\`、`;`、`'`、`,`、`.`、`/` | | 小键盘 | `Numpad0` ~ `Numpad9`、`NumpadAdd`、`NumpadDecimal` 等 | | 其它 | 键盘音量/媒体键、`PrintScreen`、`CapsLock`,或直接写 `keyboard-types` 的 Code 名称(如 `ArrowUp`) | 示例:`"Ctrl+Shift+Alt+T"`、`"Ctrl+Alt+F8"`、`"Win+Shift+Space"`、`"F8"`(单键也支持)。 注意:Windows 的 `RegisterHotKey` 无法区分左右修饰键,`LCtrl` / `RCtrl` 会按普通 `Ctrl` 处理。 若组合键已被其它程序占用,程序会记录日志并继续以托盘菜单方式工作。 日志:`%APPDATA%\easy_touchpad_switch\log.txt`(debug 构建下同时回显到终端)。 ## 常见问题 **按了快捷键 / 点了托盘,触摸板行为没变化?** 先确认程序有没有收到输入,打开日志(或 `cargo run` 的终端输出)应当能看到类似: ``` 09-25 12:08:20 [INFO] 触发来源:全局快捷键 Ctrl+Shift+Alt+T 09-25 12:08:20 [INFO] 已开启「连接鼠标时保持触摸板开启」 ``` - 有日志但没有“触发来源”:说明快捷键被别的程序抢走了,换一个组合键(改配置后点「重新加载配置」)或直接用托盘菜单。 - 启动日志里出现「注册全局快捷键 ... 失败」:同样是组合键冲突,日志会写出具体原因。 - 有日志但设置页的复选框没变:设置页面**不会实时刷新**,返回上一级再进来(或重开设置)即可看到最新值。 - 触摸板本身仍不可用:触摸板的“当前可用”状态由驱动在**鼠标连接/断开等设备事件**时重算。 程序已通过实时 API + `Status\Enabled` 尽量让它立即恢复;若仍无效,重新插拔一次鼠标或注销一次。 - 想确认程序看到的状态:运行 `easy_touchpad_switch.exe --status`,它会显示 触摸板是否存在、外接鼠标是否已连接、触摸板当前是否可用。 **重启后程序没有自动启动?** - 运行 `easy_touchpad_switch.exe --status`,看「开机自启」是否为「已启用」; - 没启用就右键托盘图标 → 勾选「开机自动启动」(安装版由安装程序自动设置); - 注意:直接跑 `cargo run` 的开发构建不会、也不应该写入自启项(那会在每次开机时启动 `target\debug` 里的程序)。 **日志里出现「实时 API 不可用,回退到注册表写入」?** 说明系统低于 Windows 11 build 26027,程序会自动改用注册表方式(老系统上这就是有效途径)。 **日志里出现「无法打开注册表项 HKCU\...\PrecisionTouchPad」?** 说明这台机器的触摸板不是精确式触摸板(或由厂商驱动接管),本工具不适用。 ## 已知行为 - Windows 11 25H2 起,「设置」页面的触摸板开关由实时 API 驱动,修改后**设置页需要重新进入才会刷新显示**。 - `LeaveOnWithMouse` 注册表值现在只作为兼容老系统与登录初始化的镜像;在新系统上它不再是生效开关。 ## 项目结构 | 文件 | 作用 | | --- | --- | | `src/main.rs` | 事件循环:分发托盘菜单、托盘点击与全局快捷键事件 | | `src/app.rs` | 应用状态,同步托盘图标/提示/菜单标题与开关状态 | | `src/ptp_api.rs` | Windows 11 25H2 的触摸板实时 API(`SystemParametersInfo` + `TOUCHPAD_PARAMETERS`) | | `src/touchpad.rs` | 对外统一读写接口:优先实时 API,其次注册表;并修正 `Status\Enabled` | | `src/hotkey.rs` | 组合键文本解析(含别名、单键支持)与展示文本,附单元测试 | | `src/icon.rs` | 运行时绘制两种状态的托盘图标 | | `src/autostart.rs` | 开机自启(`HKCU\...\CurrentVersion\Run`) | | `src/install.rs` | 安装 / 卸载:复制文件、快捷方式、自启、卸载入口与延迟清理 | | `package.ps1` | 打包脚本,产出 `dist\EasyTouchpadSwitch-Setup-<版本>.exe` | | `src/config.rs` | 配置文件加载 | | `src/cli.rs` | 命令行子命令 | | `src/logger.rs` | 落盘日志(含时间戳)与致命错误弹窗 | | `src/single_instance.rs` | 命名互斥体实现单实例 |