Skip to content

Repository files navigation

ThinkCanvas

ThinkCanvas 是一个 Windows WPF 输入验证 Demo,用于验证数位板、鼠标与桌面 Overlay 的输入路由,并提供简单的屏幕书写和区域截图功能。

本项目采用 GNU General Public License v3.0(GPL-3.0-only)授权。

当前版本:0.0.6

项目结构

ThinkCanvas/
├── src/
│   ├── Configuration/  # 应用设置、校验与持久化
│   ├── Interop/        # Windows 原生 API 封装
│   ├── Models/         # 领域模型与状态类型
│   ├── Rendering/      # 笔迹渲染
│   ├── Services/       # 截图等应用服务
│   └── Views/          # WPF 窗口及其后台代码
├── tests/              # 交互式桌面烟雾测试
├── App.xaml(.cs)       # WPF 应用入口
├── CHANGELOG.md        # 更新日志
└── ThinkCanvas.csproj  # 主项目配置

根目录仅保留应用入口、项目配置和仓库级文档;新增实现应按职责放入 src 下对应目录。

功能概览

  • 操作模式:Overlay 对鼠标和笔穿透到底层应用。
  • 书写模式:优先处理 PT_PEN,读取 WM_POINTER 压力并显示笔迹。
  • 橡皮擦模式:鼠标或笔划过已有笔迹时整笔擦除。
  • 兼容输入:支持 WPF Stylus;仅模拟鼠标的数位板也可以绘画,但无法提供真实压感。
  • 屏幕截图:全屏框选桌面和笔迹,支持复制到剪贴板或保存为 PNG。
  • 工具栏:切换模式、选择颜色、清空笔迹、截图、打开设置和退出程序。
  • 退出确认:点击退出按钮弹出确认弹窗,可选择最小化到系统托盘或退出程序,并支持“不再询问”;最小化后工具栏与快捷键停用,点击托盘图标恢复,确认提示可在设置中重新开启。

快捷键

快捷键 操作
Ctrl+Shift+Q 功能切换:在勾选的模式(鼠标(操作)、手写、橡皮擦,默认全选)之间循环(默认快捷键,优先级高于其他快捷键)
Ctrl+Shift+A 在操作模式和书写模式之间切换
Esc 在书写模式下返回操作模式
Ctrl+Shift+S 启动鼠标框选截图(默认快捷键)
Ctrl+Shift+E 切换到橡皮擦模式(默认快捷键)

所有快捷键都可以在设置中点击输入框右侧的 × 或按 Delete 清空以停用。

数位板侧键可以在驱动中映射为 Ctrl+Shift+A,程序不依赖具体厂商 API。

截图与设置

截图

点击工具栏的截图按钮,或按下截图快捷键后进入全屏框选。按住鼠标左键拖动选区,松开后显示预览;预览中可以复制到剪贴板或保存 PNG。框选时按右键或 Esc 可取消。截图期间工具栏与绘画窗口会隐藏,完成或取消后恢复原来的模式。

默认截图包含桌面与笔迹。截图预览窗口中可在复制按钮左侧快速切换背景:保留背景(桌面原图与笔迹)或自定义背景(纯色底 + 笔迹),自定义时可选预设色或输入 #RRGGBB,复制和保存均按当前所选背景输出。设置中的“使用纯色背景(仅保留笔迹)”仅决定框选阶段与预览的初始背景。

退出与托盘

点击工具栏退出按钮时会弹出确认弹窗:选择“最小化到托盘”会隐藏工具栏并停用全部快捷键,点击托盘图标或托盘菜单即可恢复;选择“退出程序”则直接退出。勾选“不再询问”后,下次点击退出按钮将直接执行所选操作,该提示可在设置中重新开启。

快捷键设置

点击设置中的快捷键输入框并按下新的组合键,保存后立即生效;点击输入框右侧的 × 或按 Delete/Backspace 可清空该快捷键(显示灰色的“未设置”,即停用)。已启用的快捷键不能相同;快捷键被其他程序占用时会显示错误并回退。功能切换下方的“循环切换”复选框决定参与循环的模式(至少保留一个),当前模式不在候选中时,按下功能切换会切到最左侧的候选模式。设置中还可以启用当前用户的 Windows 开机自启动。设置保存在 %AppData%/ThinkCanvas/settings.json,下次启动时自动恢复。

运行与构建

项目目标框架为 .NET 10 Windows,构建需要安装 .NET 10 SDK。当前可运行版本位于 bin/Release/net10.0-windows/ThinkCanvas.exe;更新后请先退出旧实例,再启动新版本。

推送 v* 标签会触发 GitHub Actions 的 Release 打包流程,使用 Release 配置生成 win-x64 自包含单文件 ThinkCanvas.exe,并同时提供 ZIP 压缩包。手动运行工作流只上传 Actions artifact,不会创建 Release。

本地打包使用项目自带的 SDK(.tools/dotnet),运行 packaging 目录下的脚本即可:

packaging\publish-self-contained.ps1          # 自包含单文件 -> publish\ThinkCanvas.exe(零依赖)
packaging\publish-framework-dependent.ps1     # 框架依赖单文件 -> publish-fdd\ThinkCanvas.exe(需 .NET 10 Desktop Runtime)

两个脚本都会把 NuGet 缓存指向 .tools/packages(离线可用);CI 发版使用相同参数,本地与 Release 产物一致。

发版同时需维护 CHANGELOG.md:开始新的 fix / feature 当天,在顶部新增或复用 Temp 日期 版本头记录变更;发版时将 Temp 重命名为实际版本号 vX.Y.Z(日期保持为开发开始日),更新 csproj 版本号并推送 v* 标签。

输入回归验证

测试项目为 tests/ThinkCanvas.SmokeTests.csproj,需要交互式 Windows 桌面。先构建测试项目,再运行生成的 ThinkCanvas.SmokeTests.exe。测试会短暂显示窗口、移动鼠标并模拟拖动;运行期间请勿同时操作鼠标。

测试覆盖以下场景:

  • 全透明背景缺陷复现与修复
  • 书写模式空白区域命中
  • 实际鼠标拖动产生笔迹
  • 清空后的继续书写
  • 操作模式穿透
  • 工具栏布局与置顶

测试会生成 toolbar-smoke.png,验证的是鼠标兼容输入链路;数位板的原生笔输入及真实压感仍需使用目标设备验证。

实现说明与当前限制

书写模式背景使用 1/255 不透明度的黑色。完全透明的分层窗口会在 Windows 命中测试阶段穿透,导致 WPF 的 Stylus/Mouse 处理程序无法收到输入;操作模式会恢复全透明并设置窗口穿透,已有笔迹继续显示。

这是输入路由 Demo,不是最终渲染引擎。笔迹使用 WPF InkPresenter,每个采样点的真实压力参与笔宽计算。目前尚未加入 Direct2D、撤销/重做、笔划级橡皮擦和多屏独立 Overlay。

工具栏压力显示 -- 表示当前输入没有提供压力,不代表固定 50% 的真实笔压。数位板若只模拟鼠标,需要在驱动的应用配置中开启 Windows Ink 才可能收到笔压;鼠标事件本身无法恢复真实压力。

友情链接

About

易用的Windows手写批注的工具,在任意页面自由书写

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages