Skip to content
lhr03Public

About

把实体键盘当成触摸屏用 · Use your physical keyboard as a touchscreen on Windows (multi-touch injection, portable, no deps)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

key2touch

把实体键盘当成触摸屏用。 Windows 绿色单文件工具,把主键盘区按物理拓扑映射成屏幕上的触点 —— 按下键就是手指按下,松开就是抬起,支持真多点触控。

Platform Python Dependencies License

Turn your physical keyboard into a touchscreen. The main key block is mapped onto the screen following its physical layout, so finger position ≈ screen position. Real multi-touch injection via the Windows Touch Injection API, with automatic mouse fallback. Single portable .exe, no installer, no registry, no network.


这是什么

用键盘玩需要触摸/点划操作的游戏、安卓模拟器里的手游、展厅触控内容调试时,鼠标点击的效率明显不够:一次点击要走"移过去 + 按下"两步,且同一时刻只能有一个指针。

这个工具换了个思路:把键盘当成一块触摸屏。

   键盘键位                      屏幕触点
   ┌───┬───┬───┐              ·   ·   ·
   │ Q │ W │ E │    ────►     ·   ·   ·      Q 在 A 的左上方
   ├───┼───┼───┤              ·   ·   ·      屏幕上的 Q 也在 A 的左上方
   │ A │ S │ D │    ────►    ·   ·   ·
   └───┴───┴───┘             ·   ·   ·

按下 A,屏幕坐标 (30%, 50%) 处就有一个手指按下;A、S 同时按住,就是两根手指同时按。全程不用移光标,多个键可以同时按。

它不是什么

  • ❌ 不是「给 PC/平板用的屏幕虚拟键盘」(方向相反:它不往屏幕画键盘,而是让键盘冒充触摸屏)
  • ❌ 不是远程控制 / 自动化脚本工具
  • ❌ 不注入进程、不修改目标程序、不读写目标内存 —— 只调用系统公开的输入注入 API

快速开始

方式一:直接用(下载 exe)

  1. 到 Releases 下载 key2touch.exe (或直接下最新版:key2touch.exe);
  2. 双击运行,免安装,不写注册表,不联网;
  3. 选目标显示器 → 点右上角「点此启用」,或按 Scroll Lock;
  4. 现在按键盘上的字母/数字键就是"触摸"了。再按一次 Scroll Lock 关闭,键盘立刻恢复打字。

第一次用建议点底部蓝框的 「① 点我做自动诊断」:程序自己弹靶子、自己注入一次点击、自己判定结果, 直接告诉你"注入链路是否正常",不用你猜。

方式二:从源码运行

git clone https://github.com/lhr03/key2touch.git
cd key2touch
python key2touch.py

运行时只依赖 Python 标准库(ctypes + tkinter),不需要 pip install 任何东西。需要 Python 3.9+ 且带 tkinter(官方安装包默认包含)。


键位映射

主键盘区(不含小键盘)按物理错位关系映射到屏幕,所以「手指位置 ≈ 屏幕位置」,肌肉记忆可以直接迁移。

屏幕纵向位置 键盘行 按键
顶部 (0%) 数字行 ` 1 2 3 4 5 6 7 8 9 0 - = Backspace
25% Q 行 Q W E R T Y U I O P [ ] \
50% A 行 A S D F G H J K L ; '
75% Z 行 Z X C V B N M , . /
底部 (100%) 空格行 Space(正下方居中)
  • 默认四周内缩 3%,避免最外侧触点贴死在屏幕边缘(可在 0–20% 之间调)
  • 勾选「启用边缘扩展键」后,Tab / Caps / 左Shift / Enter / 右Shift 也会加入映射(共 54 点)
  • 1920×1080 下默认 49 个触点,平均每个触点覆盖约 240×200 像素 —— 精度不足时用方向键微调(见下)

默认热键

功能 默认键 可自定义
总开关 Scroll Lock ✅(Scroll/Caps/F9–F12/Insert 等)
按住才生效 右 Alt ✅(可设为"不使用")
开关键位覆盖层 F12 ✅
切到上一屏 / 下一屏 F9 / F10 ❌(面板下拉亦可切)

功能

类别 功能 说明
注入 真·触摸注入 Windows Touch Injection API(InitializeTouchInjection / InjectTouchInput),产生真实触摸事件,系统会投递 WM_TOUCH 并自动提升为点击
注入 鼠标事件 SendInput,先移动再按下,任何程序都认。默认模式,最可靠
注入 触摸 + 鼠标双发 两种一起发。注意触摸本身会转成一次鼠标点击,双发等于点两次
动作 点击 / 长按 按下即触点按下,松开抬起;按住不放就是长按
动作 真多点触控 同时按住多个键 = 多指同时按下,最多 10 指,可做双指缩放
动作 连点 / 连发 按住超过设定延迟后按设定频率自动重复点击(1–60 Hz)
精度 方向键微调 按住任意映射键时,方向键移动该触点(Shift 加速 5×),可当拖拽/划动用
精度 自定义映射区域 把整块映射限定在某个窗口内(如模拟器),等效精度大幅提升
显示 键位覆盖层 显示每个键对应的触点与键名,按下高亮;鼠标可穿透,不挡游戏
多屏 显示器切换 下拉选择 / F9 F10 循环 / 自动跟随鼠标所在屏幕
安全 防误触 开关 + 按住双模式;Ctrl/Alt/Win 组合键永远放行
其他 最短按压时长 防止点击过快被系统或游戏忽略(默认 80 ms)
其他 长按心跳 每 0.8 s 重发一次触点状态,避免长按被判定失效

不误触的三道保险

  1. 总开关关闭时,键盘 100% 正常打字,程序完全不干扰;
  2. 也可以只用「按住生效键」(默认右 Alt):按住时才变成触摸屏,松开立刻恢复;
  3. Ctrl / Alt / Win 组合键永远放行 —— Alt+Tab、Ctrl+C 不受任何影响。

多显示器

  • 自动枚举所有显示器,支持不同分辨率、不同 DPI、上下左右任意排列、含负坐标的副屏
  • 三种切换方式:面板下拉、F9/F10 循环、勾选「自动跟随鼠标所在屏幕」
  • 做了 Per-Monitor DPI 感知(SetProcessDpiAwarenessContext(-4)),坐标按物理像素计算,缩放后不偏移
  • 推荐玩法:把模拟器窗口拖到副屏 → 点「取当前窗口区域」,整块键盘映射只覆盖这个窗口。分辨率越小,等效精度越高

工作原理

程序由三部分组成,都在 key2touch.py 单文件内:

 ① 低级键盘钩子          ② 坐标映射                ③ 输入注入
 SetWindowsHookEx      物理拓扑 → 归一化 → 屏幕像素   InjectTouchInput
 WH_KEYBOARD_LL   ──►  (支持自定义区域/内缩/多屏) ──►  SendInput
      │                      │                        │
   捕获按键              算出触点坐标              产生真实输入事件
   决定吞掉还是放行
  • 钩子线程:独立线程跑消息循环(低级钩子必须由安装它的线程处理消息)。命中「需要吞掉」的键就返回 1,否则放行;只识别 WM_KEYDOWN/WM_KEYUP,不干扰 WM_SYSKEYDOWN 系列。
  • 注入:触摸指针用 PID 池管理,最多 10 个并发触点;鼠标模式拆成「先移动 → 再按下」两次 SendInput,比一条指令里同时塞移动和点击更可靠。
  • 配置:JSON 存 exe 同目录;目录只读时自动退到 %APPDATA%\key2touch\。

踩过的坑(实测记录)

这些都是真机验证过、而不是从文档推断的结论,写在这里希望能省下后来者的时间:

1. InitializeTouchInjection 成功 ≠ 触摸可用 必须真的发一次 InjectTouchInput 才算数。远程桌面、无触摸屏设备上初始化也可能返回成功,但注入会被静默丢弃 —— 只剩下系统画的一个视觉圆点,看起来"点到了",其实什么都没发生。

2. 填 rcContact / rcContactRaw / ptPixelLocationRaw 会返回 ERROR_INVALID_PARAMETER (87) 只填 ptPixelLocation + touchMask = CONTACTAREA|ORIENTATION|PRESSURE 才通过(接触区域留空系统会自己补)。

3. 多点触控必须一帧内一次性提交全部触点 第二个手指单独 InjectTouchInput 一定失败。正确做法是每次把「所有活跃触点」组成数组一次提交(count = N);抬起一个触点后,要把它从活跃集合里移除再提交。

4. 低级键盘钩子不能传 GetModuleHandleW(None) 源码运行时正常,打包成 PyInstaller 单文件 exe 后返回 err=126(找不到模块),钩子装不上,程序界面一切正常但完全没反应。WH_KEYBOARD_LL 不需要 DLL 注入,模块句柄传 NULL 即可。

5. 分层窗口的「色键」与「全局 alpha」互斥 用色键(LWA_COLORKEY,把某颜色变透明)做透明背景时,再设 LWA_ALPHA 会把色键顶掉 —— 背景色不再透明,整块窗口以设定不透明度铺在屏幕上。两者属于同一组标志的不同分支,只能选一个。

6. 透明 ≠ 鼠标穿透 WS_EX_TRANSPARENT 需要配合 WS_EX_LAYERED 才真正生效,改完还要让系统刷新窗口样式。一个"看不见但吃掉所有点击"的覆盖层是最难排查的 bug —— 现在程序打开覆盖层时会用 WindowFromPoint 自查落点下方是不是自己,不通过就自动关闭。

7. UIPI:低权限进程不能向高权限窗口注入 目标以管理员运行时,光标照样会动,但点击被系统拦掉。程序会在状态栏提示,并提供「以管理员重启」。


从源码构建 exe

# 需要 Python 3.9+(带 tkinter)
powershell -ExecutionPolicy Bypass -File .\build.ps1

脚本会建 .venv、装 PyInstaller、输出 dist\key2touch.exe(约 11 MB,单文件、无控制台窗口)。也可以手动执行:

pip install -r requirements-dev.txt
python -m PyInstaller --onefile --noconsole --name key2touch --clean --noconfirm key2touch.py

调试时加 --console 打包,可以看到标准输出。


出问题了?

先点 「① 点我做自动诊断」:程序自建靶子窗口 → 自动注入一次点击 → 自己判定结果,结论直接写在屏幕上。

  • ✓ 注入完全正常 → 程序这一侧没问题,问题在目标程序(见下表第 1、2 条)
  • ✗ 没有生效 → 按它给出的下一步做(改模式 / 以管理员重启)

状态栏还常驻两个有用的信息:「前台目标」(当前最前面的程序是谁、是否管理员权限)和 「落点窗口」(每按一次键就显示这个落点下面是哪个窗口)。如果落点窗口又是 key2touch.exe,说明自己的面板挡住了 —— 这是"没反应"最常见的原因。

exe 同目录会生成 key2touch_debug.log,记录每次按键的「捕获/放行」、落点坐标、落点窗口与注入结果。

现象 原因与解决
鼠标移过去了,却点不动东西 ① 本程序面板/诊断画布挡在落点上(看「落点窗口」是不是自己,启用后会自动最小化);② 目标程序是管理员权限 → 点「以管理员重启」;③ 覆盖层未穿透(已内置自检,会自动关闭)
完全没反应 ① 看是不是「已启用」;② 目标显示器选错;③ 先跑「自动诊断」
触摸模式没反应,鼠标模式有 目标程序只认鼠标 → 改成「鼠标事件」或「双发」
提示「触摸注入不可用」 远程桌面 / 无触摸屏 / 部分虚拟机不支持 → 自动回退鼠标模式
点得到但位置偏 调「边缘内缩」;改用「取当前窗口区域」;让本程序与游戏保持一致的 DPI 行为
精度不够 ① 缩小映射区域(最有效);② 方向键微调;③ 勾选边缘扩展键增加触点密度
打字被吞了 总开关开着或按住键被压着 → 按总开关热键关闭
恢复默认 删掉同目录的 key2touch.config.json,或点「恢复默认」

别被"触摸圆点"骗了:Windows 在触摸时会画一个小圆点/涟漪,那只是视觉反馈,不代表点中了任何东西。 本程序默认关闭该圆点(可在「注入方式」那一行重新打开)。


已知限制

  1. 精度天花板:49(或 54)个触点是物理决定的,绝对定位精度天然不如真触摸屏。缓解手段是缩小映射区域 + 方向键微调。
  2. 滑动类操作:目前没有独立的"划动手势"快捷键,靠「按住 + 方向键微调」实现连续位移。高频划动场景(音游、切水果)建议等摇杆模式。
  3. 鼠标模式不支持多点(鼠标协议本身只有一个指针)。
  4. 注入权限:受 Windows UIPI 限制,不能向更高完整性级别的窗口注入 —— 目标以管理员运行时,本程序也必须以管理员运行。
  5. 反作弊:使用反作弊内核驱动的游戏可能过滤模拟输入,此类情况无法绕过。

Roadmap

  • 精确模式:按住修饰键后进入当前区域的 3×3 细分网格,第二次按键精确落点(49 → 400+ 点)
  • 摇杆模式:按住某键 = 虚拟摇杆推到某个方向,偏移量连续可调(高频划动场景)
  • 配置 Profile:不同游戏各一套映射(区域、连点频率),热键秒切
  • 绑定目标窗口:现在区域是静态矩形,绑定 HWND 后可跟随窗口移动/缩放
  • 比例锁定:键盘与屏幕长宽比差异大(21:9、16:10)时,只铺中间同比例区域

免责声明

本工具通过 Windows 公开 API 注入输入事件,不修改、不注入任何目标进程。请在合规范围内使用; 在游戏中用于自动化操作可能违反该游戏的服务条款,风险自负。

License

MIT

About

把实体键盘当成触摸屏用 · Use your physical keyboard as a touchscreen on Windows (multi-touch injection, portable, no deps)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages