一个基于 C# / .NET 的 Windows 控制台小工具: 用键盘替代鼠标 ,在不离开键盘的情况下完成鼠标移动、点击、滚轮、Home/End 等操作,移动时不会触发按键本身的字符输入。
本项目通过全局键盘钩子监听按键状态,并使用 Win32 API(SetCursorPos、mouse_event)模拟鼠标行为,配合 WindowsInput 库实现按键拦截。适用于需要在键盘与鼠标之间频繁切换的场景(如阅读、远程操作、单手握持设备等)。
项目采用**整洁架构(Clean Architecture)**分层组织代码:Input 处理键盘状态与业务,Mouse 封装所有鼠标副作用,Native 集中 P/Invoke,Audio 负责提示音,Program 只做装配与启动。
- 双重开关 :
Alt + Q开启功能,CapsLock切换监听状态,防止误触 - 八方向移动 :I / K / J / L 四个方向 + 四个斜向组合
- 六档速度调节 :按住空格 +
-/+增减挡位,带内嵌提示音 - 完整鼠标按键 :左键、中键、右键均支持按下/松开(可拖拽)
- 滚轮控制 :垂直上下滚动
- 补充按键 :Home / End 快捷输入
- 多显示器支持 :通过
SetProcessDPIAware+ 虚拟桌面边界钳制,跨屏坐标不再溢出 - 按键屏蔽 :移动/点击时通过
e.Next_Hook_Enabled = false阻止按键字符输入
- Windows 10 / 11
- .NET 10(项目目标框架为
net10.0-windows) - 依赖库:WindowsInput
6.4.1(使用其WindowsInput.Events.Sources命名空间) - WinForms:
<UseWindowsForms>true</UseWindowsForms>(NotifyIcon依赖,仅 Windows)
- 编译项目,确保
功能手册.txt与音频资源(Key2Mouse.Audio.*.wav)已嵌入/置于输出目录。 - 运行程序,控制台会打印功能手册并进入监听状态。
- 按
Alt + Q激活功能,再按CapsLock打开监听(二重锁)。 - 使用下方操作速查表中的按键控制鼠标。
- 再次按
CapsLock可暂停监听,Alt + Q可完全关闭功能。
Key2Mouse 请以普通用户权限运行,不要使用管理员模式。
- 工具本身不需要管理员权限即可完成日常键盘模拟鼠标操作;
- 以最小权限运行可降低误操作和安全风险;
- 即使以管理员身份运行,也无法覆盖 UAC 安全桌面、锁屏等系统级隔离场景,反而会扩大程序权限暴露面。
在任务管理器(以管理员权限运行时)、UAC 提权弹窗等受限场景中,Windows 的 UIPI / 安全桌面机制会阻止 Key2Mouse 注入鼠标事件,表现为按键被捕获但鼠标无响应。这属于系统安全限制,不是程序 Bug。
此时请启用 Windows 内置「鼠标键」 作为备用方案:
快捷键:左 Alt + 左 Shift + NumLock,弹窗后按回车确认启用/关闭。
启用后小键盘操作:
| 按键 | 功能 |
|---|---|
8 / 2 / 4 / 6 |
上 / 下 / 左 / 右 移动 |
7 / 9 / 1 / 3 |
斜向移动 |
5 |
单击左键 |
+ |
双击 |
- |
进入拖拽模式 |
0 / . |
按住左键 / 释放按键 |
/ |
切换为右键单击 |
* |
同时按下左右键 |
Ctrl / Shift + 移动 |
加速 / 减速 |
若快捷键无反应,请前往 设置 → 辅助功能 → 鼠标 → 打开「使用数字小键盘在屏幕上移动鼠标」。
建议使用顺序:日常场景使用 Key2Mouse;遇到提权页面先尝试 Tab / 方向键导航,确需鼠标时再启用 Windows 鼠标键。
| 按键 | 功能 |
|---|---|
Alt + Q |
开启 / 关闭键盘模拟鼠标功能 |
CapsLock |
功能开启后切换监听状态(需先Alt + Q开启) |
| 按键 | 功能 |
|---|---|
I |
上移 |
K |
下移 |
J |
左移 |
L |
右移 |
J + I |
左上斜移 |
J + K |
左下斜移 |
K + L |
右下斜移 |
I + L |
右上斜移 |
| 按键 | 功能 |
|---|---|
Space + - |
降低一档速度(最低 1 档) |
Space + + |
提高一档速度(最高 6 档) |
基础速率初始为 12,每升一档 ×2,每降一档 ÷2(最低为 1)。切换挡位时播放对应数字的提示音。
| 按键 | 功能 |
|---|---|
A或; |
鼠标左键(按下 / 松开) |
S |
鼠标中键(按下 / 松开) |
F或' |
鼠标右键(按下 / 松开) |
| 按键 | 功能 |
|---|---|
O |
滚轮向上 |
H |
滚轮向下 |
| 按键 | 功能 |
|---|---|
U |
Home 键 |
P |
End 键 |
| 用途 | 实现方式 |
|---|---|
| 全局键盘监听 | WindowsInput.Capture.Global.KeyboardAsync() |
| 按键拦截 | e.Next_Hook_Enabled = false |
| 鼠标坐标获取 | user32.dll!GetCursorPos |
| 鼠标坐标设置 | user32.dll!SetCursorPos |
| 滚轮模拟 | user32.dll!mouse_event(MOUSEEVENTF_WHEEL/MOUSEEVENTF_HWHEEL) |
| DPI 感知 | SetProcessDPIAware(避免多屏不同缩放下坐标错位) |
| 虚拟桌面边界 | GetSystemMetrics(SM_X/Y/CXV/CYVIRTUALSCREEN) |
早期版本使用 Simulate.Events().MoveTo(x, y),该库内部以 SM_CXSCREEN 归一化坐标,导致 副屏(尤其是位于主屏左侧/上方的副屏)坐标溢出,鼠标移动到第二屏后卡死不动 。
当前版本已改为:
- 调用
SetProcessDPIAware()声明 DPI 感知; - 用
GetCursorPos获取当前物理坐标; - 叠加增量后,用 虚拟桌面边界 (
SM_XVIRTUALSCREEN等)做钳制; - 直接调用
SetCursorPos(x, y)设置坐标,绕开库内部的归一化逻辑。
采用整洁架构分层,各层职责单一、互相隔离:
Key2Mouse/
├── Program.cs # 入口:DPI 感知、依赖装配、启动监听、打印手册
├── Key2Mouse.csproj # net10.0-windows + WindowsInput 6.4.1 + 资源声明
├── 功能手册.txt # 启动时读取并打印到控制台
├── README.md
│
├── Native/ # ← 平台互操作层
│ ├── NativeMethods.cs # 所有 user32.dll P/Invoke 与常量
│ └── POINT.cs # 与 Win32 POINT 对齐的结构体
│
├── Audio/ # ← 音频层
│ ├── EmbeddedBeepPlayer.cs # 播放内嵌 wav 提示音
│ ├── 1.wav ~ 6.wav # 六档速度提示音
│ ├── 开启键盘监听.wav
│ ├── 关闭键盘监听.wav
│ ├── 开启键盘模拟鼠标.wav
│ └── 关闭键盘模拟鼠标.wav
│
├── Mouse/ # ← 鼠标动作层
│ ├── MouseController.cs # 移动 / 滚动 / 调速 统一封装
│ └── MouseSpeedSettings.cs # 速度状态 + 档位迁移规则
├── Ui/ # ← 用户反馈层
│ ├── MouseController.cs # 反馈统一入口(日志 + 音效 + 托盘)
│ └── MouseSpeedSettings.cs # 系统托盘图标(ON/OFF 视觉状态)
│
└── Input/ # ← 输入业务层
├── KeyboardToMouseHandler.cs # 键盘事件 → 鼠标动作(核心业务)
└── KeyStateTracker.cs # 按键状态跟踪(Alt/Space/I/J/K/L)
text
Program ──► Input ──► Mouse ──► Audio
│ │ │
└───────────┴─────────┴──► Native
Input只依赖Mouse的抽象接口;Mouse依赖Audio与Native;Native是最底层,不依赖任何上层;Program只负责装配与触发。
- **☑ **多显示器坐标卡死问题(已通过
SetCursorPos+ 虚拟桌面边界钳制修复) - **☑ **单文件"万能 Program.cs"重构为整洁架构多文件分层
- **☑ **斜向移动逻辑集中于
KeyboardToMouseHandler.HandleDiagonal,便于后续合并优化 - **□ **提示音文件依赖嵌入资源路径
Key2Mouse.Audio.{name}.wav,缺少时仅打印提示 - **□ **
功能手册.txt中"滚轮上/下"的描述与代码实际行为(H 向上、O 向下)待核实统一
- 恢复
Alt+Q/CapsLock切换时的内嵌提示音 - 新增系统托盘图标(
Ui/TrayIcon.cs):ON 蓝 i / OFF 默认图标,Tooltip 同步状态,右键退出 - 新增
Ui/Feedback.cs作为用户反馈统一入口(控制台日志 + 音效 + 托盘状态) MouseController/KeyboardToMouseHandler不再直接Console.WriteLine,改为_feedback.Action(...)- 未采用"控制台底部单行原地刷新":极端场景下用户需用 Windows 自带鼠标键(
Alt+左Shift+NumLock)操作终端,原地刷新会破坏日志的可滚动性与可选中/可复制性 - 控制台仍保留逐行日志,可正常滚动、拖选、复制
- 滚轮方向以
功能手册.txt为准:H滚轮向下、O滚轮向上 - 移除"滚轮方向待核实"伪问题(根因是日志文案与
VerticalScroll符号未成对维护) - 新增"滚轮方向约定"小节,明确
MOUSEEVENTF_WHEEL正负语义
- 将单文件
Program.cs拆分为整洁架构多目录(Native/Audio/Mouse/Input) - 速度相关状态收拢到
MouseSpeedSettings - 鼠标副作用统一由
MouseController封装 - 键盘状态由
KeyStateTracker独立管理 - 业务逻辑拆为
KeyboardToMouseHandler中的多个语义化方法 - 命名空间由
ConsoleApp1更名为Key2Mouse
- 新增
'键作为鼠标右键 - 完善多屏坐标处理(
SetCursorPos+ 虚拟桌面边界) - 补充
SetProcessDPIAwareDPI 感知
本项目为个人效率工具,仅供学习与自用。使用全局键盘钩子可能被部分安全软件标记,请自行判断运行环境。