# KeyComboViewer **Repository Path**: r1Way/key-combo-viewer ## Basic Information - **Project Name**: KeyComboViewer - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-10 - **Last Updated**: 2026-04-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # KeyComboViewer 游戏连招录制与键位分析工具。基于 [KeyCastOW](https://github.com/brookhong/KeyCastOW) 的核心 Hook 逻辑,使用 Qt 构建现代化 GUI 前端,帮助玩家清晰回放和分析游戏操作中的键盘与鼠标输入。 ## 问题背景 录制游戏连招视频时,键位变化极快,在视频中很难看清具体按了什么键、按了多久、先后顺序如何。反复调整视频进度条既低效又痛苦。 KeyComboViewer 通过独立录制输入事件并以**键盘可视化 + 甘特图时间线**的方式回放,让每一步操作一目了然。 ## 功能特性 ### 录制 - 全局键盘/鼠标 Hook 捕获,基于 `WH_KEYBOARD_LL` / `WH_MOUSE_LL` - 通过 `QCoreApplication::postEvent()` 线程安全传递事件,**不影响其他任务的性能** - 支持录制、暂停、恢复、停止 - 记录按键的按下/释放时间戳、虚拟键码(VK)、扫描码 - 记录鼠标坐标、按键动作(左/右/中/侧键)、滚轮增量 ### 键盘可视化 - **三种预设布局**:游戏精简(WASD + 方向键 + 功能键)、标准全键盘、仅修饰键 - 按键按下时实时高亮,支持多键同时高亮 - **编辑模式**:可拖拽调整每个按键的位置,自定义布局 - 按键区域分组显示,可按组隐藏/显示(功能键区、主键区、修饰键区、方向键区等) - 可配置颜色主题 ### 时间线回放 - 类似视频剪辑软件/甘特图的时间轴视图 - 每个按键显示为**持续时间色块**(从按下到释放),一眼看出按键时长 - 鼠标事件以三角形标记显示 - **播放头**可拖拽定位,支持播放/暂停回放 - `Ctrl + 滚轮` 缩放时间轴,普通滚轮水平滚动 - 不同类型按键用不同颜色区分(修饰键=红色、特殊键=橙色、字符键=彩色) ### 鼠标轨迹 - 缩略图显示鼠标移动轨迹 - 用颜色区分不同鼠标按键(左键=红、右键=蓝、中键=绿、侧键=橙) - 回放时显示当前鼠标位置的十字准星 ### 筛选与查找 - 按键名搜索(如输入 "W"、"Shift"、"F1") - 按类型筛选:键盘事件 / 鼠标事件 / 仅修饰键 - 按时间范围筛选 - 查找上一个 / 下一个,自动跳转并定位播放头 ### 数据存储 - JSON 格式保存/加载录制文件(`.kcv` / `.json`) - Compact 模式存储,文件体积小 - 记录完整的元数据:录制名称、开始时间、总时长 - 支持多次录制,列表管理 ## 技术架构 ``` KeyComboViewer/ ├── CMakeLists.txt # CMake 构建配置 (Qt5 / Qt6) ├── resources/ │ └── resources.qrc # Qt 资源文件 (图标) └── src/ ├── main.cpp # 程序入口 ├── MainWindow.h/cpp # 主窗口 (工具栏、布局、状态栏) ├── core/ │ ├── InputHook.h/cpp # 全局键盘/鼠标 Hook 管理 │ ├── KeyMapper.h/cpp # VK 码 → 可读名称映射 (移植自 KeyCastOW) │ └── Recorder.h/cpp # 录制状态机 (开始/暂停/停止) ├── models/ │ └── RecordingModel.h/cpp # 数据模型 + JSON 序列化/反序列化 └── widgets/ ├── KeyboardWidget.h/cpp # 键盘可视化组件 (QPainter 自绘) ├── TimelineWidget.h/cpp # 甘特图时间线组件 ├── MouseTrailWidget.h/cpp # 鼠标轨迹可视化组件 └── FilterPanel.h/cpp # 筛选/查找面板 ``` ### 核心设计 | 模块 | 职责 | 关键技术 | |------|------|---------| | `InputHook` | 安装/卸载 Windows Hook,捕获全局输入 | `SetWindowsHookEx` + `postEvent` | | `Recorder` | 管理录制生命周期,收集事件 | 状态机 (Stopped/Recording/Paused) | | `KeyMapper` | 虚拟键码映射为可读名称 | 移植自 KeyCastOW `keylog.cpp` | | `RecordingModel` | 事件数据结构 + JSON I/O | `QJsonDocument` Compact 模式 | | `KeyboardWidget` | 键盘布局渲染 + 按键高亮 | `QPainter` + 比例坐标布局 | | `TimelineWidget` | 时间轴 + 甘特条 + 播放头 | 自绘 `QWidget` + 鼠标交互 | | `MouseTrailWidget` | 鼠标轨迹缩略图 | `QPainter` 路径绘制 | ### 线程模型 ``` Windows Hook 回调 (系统线程) │ 仅做数据拷贝,极轻量 │ QCoreApplication::postEvent() ← 线程安全 ▼ Qt 主线程事件队列 │ customEvent() 处理 ▼ Recorder → 数据收集 → UI 更新 ``` Hook 回调中**禁止任何 IO 操作或耗时计算**,确保不影响系统响应和其他应用程序。 ## 环境要求 | 依赖 | 最低版本 | 说明 | |------|---------|------| | CMake | 3.16+ | 构建系统 | | Qt | 5.15+ / 6.x | 优先检测 Qt6,自动回退 Qt5 | | MSVC | 2019+ | Windows 平台编译器 | | Windows SDK | 10+ | 提供 `user32.lib`, `shell32.lib` 等 | ## 编译 ```bash # 使用 CMake 生成项目 (Visual Studio) cd KeyComboViewer mkdir build && cd build cmake .. -G "Visual Studio 17 2022" -A win32 cmake --build . --config Release # 或使用 Ninja cmake .. -G "Ninja" -DCMAKE_BUILD_TYPE=Release cmake --build . ``` 编译产物为单个 `KeyComboViewer.exe`,运行时依赖 Qt DLL。 ## 使用方法 1. **录制**:点击工具栏 `Record` 按钮开始录制,操作完成后点击 `Stop` 2. **回放**:在录制列表中选择一次录制,点击 `Play` 按钮回放 3. **定位**:在时间线上拖拽播放头,或使用筛选面板的 `Prev` / `Next` 跳转到特定按键 4. **缩放**:`Ctrl + 滚轮` 缩放时间轴,查看细节 5. **自定义键盘**:选择布局预设,或点击 `Edit Layout` 进入编辑模式拖拽按键位置 6. **保存/加载**:点击 `Save` 保存为 `.kcv` 文件,点击 `Load` 加载已有录制 ## 录制文件格式 ```json { "version": "1.0", "app": "KeyComboViewer", "name": "Recording_20260410_143000", "startTime": "2026-04-10T14:30:00", "durationMs": 5230, "events": [ { "t": 0, "vk": 87, "sc": 30, "ts": 0, "ext": false }, { "t": 1, "vk": 65, "sc": 17, "ts": 15, "ext": false }, { "t": 0, "vk": 87, "sc": 30, "ts": 85, "ext": false }, { "t": 2, "mx": 960, "my": 540, "md": 0, "ma": 1, "ts": 120, "vk": 0, "sc": 0, "ext": false } ] } ``` | 字段 | 类型 | 说明 | |------|------|------| | `t` | int | 事件类型:0=KeyDown, 1=KeyUp, 2=MouseAction | | `vk` | int | 虚拟键码 (Virtual Key Code) | | `sc` | int | 扫描码 (Scan Code) | | `ts` | int | 相对于录制开始的毫秒时间戳 | | `ext` | bool | 是否为扩展键 | | `mx/my` | int | 鼠标坐标 (仅鼠标事件) | | `md` | int | 鼠标附加数据:滚轮增量或 XButton 编号 | | `ma` | int | 鼠标动作类型 (仅鼠标事件) | ## 与 KeyCastOW 的关系 本项目参考并使用了 [KeyCastOW](https://github.com/brookhong/KeyCastOW)(Copyright © 2014 Brook Hong,MIT License)的部分代码和数据。KeyCastOW 是一款 Windows 平台的按键可视化工具。以下详细说明本项目对 KeyCastOW 的使用情况,以确保许可证合规。 ### KeyCastOW 许可证 KeyCastOW 使用 **MIT License** 发布。MIT 许可证允许自由使用、复制、修改、合并、发布、分发、再授权和/或销售本软件的副本,唯一条件是在所有副本或重要部分中包含版权声明和许可声明。 ### 本项目中来自 KeyCastOW 的内容 以下内容衍生自 KeyCastOW 的源代码(主要为 `keylog.cpp`): #### 1. 特殊键虚拟键码映射数据表 KeyComboViewer 的 `src/core/KeyMapper.cpp` 中的 `buildMappingTable()` 函数包含了 80+ 条虚拟键码(VK Code)到可读名称的映射数据。这些映射数据直接移植自 KeyCastOW `keylog.cpp` 第 14-133 行的 `specialKeys[]` 数组。 所做的改动仅限于: - 将单一标签拆分为 `name`(完整名称,如 "Backspace")和 `label`(简短标签,如 "Back")两个独立映射 - 对部分标签做了缩写(如 "Snapshot" → "PrtSc","Insert" → "Ins") - 对部分键名做了规范化(如 "Menu" → "Alt","Esc" → "Escape") - 对 OEM 键和数学运算键的标签改用实际字符/符号表示 #### 2. 鼠标动作名称列表 KeyComboViewer 的 `src/core/KeyMapper.cpp` 中的鼠标动作名称映射(15 个条目,如 "LButtonDown"、"RButtonUp"、"MouseWheel" 等)移植自 KeyCastOW `keylog.cpp` 第 137-153 行的 `mouseActions[]` 数组。唯一改动是 "DBLCLK" 统一为 "DblClick" 命名风格。 #### 3. 修饰键判断逻辑 KeyComboViewer `KeyMapper::isModifier()` 中判断修饰键的 VK 码范围条件(`0xA0-0xA5`、`0x5B`、`0x5C`)来自 KeyCastOW `keylog.cpp` 中的对应逻辑。 #### 4. 键盘自动重复过滤 KeyComboViewer `InputHook.cpp` 中通过记录上次按键的 VK 码并与当前按键比较来过滤自动重复事件的逻辑,参考自 KeyCastOW `keylog.cpp` 第 325-328 行。 #### 5. 注入事件过滤 KeyComboViewer 在键盘和鼠标 Hook 回调中过滤 `LLKHF_INJECTED` / `LLMHF_INJECTED` 标志位以忽略程序化注入事件的逻辑,参考自 KeyCastOW `keylog.cpp`。 #### 6. Windows 低级 Hook 使用模式 使用 `SetWindowsHookEx(WH_KEYBOARD_LL, ...)` 和 `SetWindowsHookEx(WH_MOUSE_LL, ...)` 捕获全局输入事件的使用模式参考自 KeyCastOW。这是 Windows API 的标准用法。 ### 本项目中完全原创的内容 以下部分为 KeyComboViewer 原创,不存在于 KeyCastOW 中: - **整个 Qt 应用架构**:QObject 信号/槽机制、自定义 QEvent 事件类、`QCoreApplication::postEvent()` 线程安全通信 - **所有 UI 代码**:主窗口、键盘可视化组件、甘特图时间线、鼠标轨迹图、筛选面板 - **录制/回放引擎**:`Recorder` 状态机、`RecordingModel` 数据模型、JSON 序列化 - **双映射表设计**:`name` + `label` 分离的键名查询系统 - **类型安全的鼠标事件枚举**:替代 KeyCastOW 的原始索引方式 - **MouseWheel 拆分为 WheelUp/WheelDown** - **扩展键标志检测**(`LLKHF_EXTENDED`) - **键盘事件的注入过滤**(KeyCastOW 仅在鼠标 Hook 中做了此过滤) ### KeyCastOW 中未使用的部分 KeyCastOW 的 `keycast.cpp`(约 1296 行)中的所有功能均未被本项目复用,包括但不限于:GDI+ 渲染引擎、分层窗口管理、标签淡出动画、设置对话框、INI 配置读写、系统托盘图标、窗口拖拽、全局热键注册、MiniDump 崩溃转储等。本项目是一个基于 Qt 的全新应用,架构与 KeyCastOW 完全不同。 ### 源代码中的归属标注 本项目在以下源文件中明确标注了代码来源: - `src/core/KeyMapper.h` 第 10 行:`// KeyMapper - 将 Windows 虚拟键码映射为可读的按键名称,移植自 KeyCastOW 的 keylog.cpp` - `src/core/KeyMapper.cpp` 第 17 行:`// 特殊键名称映射 (移植自 KeyCastOW keylog.cpp)` ### 许可证兼容性说明 KeyCastOW 使用 MIT License,本项目同样使用 MIT License。MIT 许可证与 MIT 许可证完全兼容——允许在 MIT 许可的项目中使用、修改和再分发 MIT 许可的代码,只需保留原始版权声明和许可声明。本项目已通过 README 中的致谢和上述详细说明履行了这一义务。 ## 致谢 - [KeyCastOW](https://github.com/brookhong/KeyCastOW) by Brook Hong (MIT License) — 特殊键虚拟键码映射数据表、鼠标动作名称列表、Hook 使用模式及部分事件过滤逻辑 - [Qt](https://www.qt.io/) — 跨平台 GUI 框架 ## 许可证 MIT License Copyright (c) 2026 KeyComboViewer Contributors 本软件包含以下第三方作品的衍生代码: - KeyCastOW, Copyright © 2014 Brook Hong, MIT License (https://github.com/brookhong/KeyCastOW) 上述第三方作品均在其各自的许可证下发布,其版权归各自原作者所有。