Skip to content
F3rccPublic
forked from chiimyen/TopPin

About

窗口置顶小工具(二创):基于 chiimyen/TopPin,边框外观/不透明度调节/游戏模式/拖动跟随移植自 Microsoft PowerToys 的 AlwaysOnTop 模块。约 65 KB 单文件,Win32 C,无依赖。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

TopPin

简体中文 | English

TopPin 图标

一个只有窗口置顶功能的 Windows 小工具(约 65 KB)。

TopPin 使用原生 Win32 C 编写。它没有主窗口、安装程序、后台服务或联网功能:运行后进入系统托盘,按一次快捷键置顶当前窗口,再按一次取消。

这是二创项目。 本仓库基于原作者 chiimyen/TopPin,并把 Microsoft PowerToys 的 AlwaysOnTop 模块的边框外观、 不透明度调节、游戏模式判定与拖动跟随策略移植了过来。详细署名、源文件对照与许可见 ATTRIBUTION.md。与 Microsoft / PowerToys 官方无任何关系。

二创声明

本项目是二次创作(derivative work),不是原创:

来源 用在本项目的部分 许可
chiimyen/TopPin 原始项目骨架:托盘常驻、单实例、全局热键、置顶/取消、管理员提权、开机自启 MIT,© 2026 chiimyen
Microsoft PowerToys → AlwaysOnTop 边框几何与默认外观、不透明度调节、游戏模式判定、拖动跟随策略 MIT,© Microsoft Corporation

具体对照了 PowerToys 的 src/modules/alwaysontop/AlwaysOnTop/ 下这些文件:WindowBorder.cpp (GetFrameRect、UpdateBorderPosition、100 ms 间隔)、FrameDrawer.cpp(描边内缩 thickness/2+1、 圆环由内外圆角矩形做差)、Settings.h(全部默认值)、WindowCornersUtil.cpp(圆角半径映射)、 AlwaysOnTop.cpp(不透明度步进与 layered 状态还原、EVENT_OBJECT_LOCATIONCHANGE 订阅), 以及 src/common/utils/game_mode.h(游戏判定)。

C 代码是本分支自行编写的,没有从 PowerToys 复制 C++ 源文件;对齐的是几何规则、默认参数和交互语义。 渲染管线也不同:PowerToys 用 Direct2D,本分支用 GDI 位图 + 圆角矩形距离场自算抗锯齿。

上游 TopPin 与 PowerToys 均为 MIT 许可;完整许可文本与免责声明见 ATTRIBUTION.md。

本分支相对上游的改动

在上游 chiimyen/TopPin 基础上加了这些功能:

  • 热键可配置:不再写死 Ctrl+Alt+T,改 TopPin.ini 即可,托盘菜单可直接打开/重载配置。
  • PowerToys 同款置顶边框:几何、默认外观、圆角规则全部照搬 PowerToys AlwaysOnTop 模块(见下方“边框是怎么画的”)。
  • 窗口不透明度调节:默认 Ctrl+Win+= 提高、Ctrl+Win+- 降低,每次 10%,范围 20%–100%,只对已置顶窗口生效,取消置顶时自动还原。
  • 游戏时不激活:独占全屏(D3D fullscreen)运行中不响应置顶,默认开启。

下载与使用

系统要求:Windows 10/11 x64。

  1. 从 Releases 下载 TopPin.exe,或从 Actions 取最新构建产物。
  2. 运行后,TopPin 会进入右下角系统托盘。
  3. 点击需要置顶的窗口。
  4. 按快捷键(默认 Ctrl + Alt + T)置顶;再次按下即可取消。

也可以双击托盘图标切换最近使用的窗口,或者右键托盘图标管理已经置顶的窗口。

TopPin 是本地编译的开源程序,目前没有商业代码签名证书。Windows 可能显示“未知发布者”,你可以从本仓库检查源码并自行编译。

功能

  • 单个便携 EXE,不需要安装。
  • 全局快捷键默认 Ctrl + Alt + T,可在 TopPin.ini 里改成任意组合。
  • 置顶窗口周围显示一圈 PowerToys 风格的边框:默认跟随系统主题色、4px、随窗口圆角、DPI 自适应。
  • 可调已置顶窗口的不透明度(20%–100%,步长 10%),取消置顶自动还原。
  • 独占全屏游戏运行时不激活,默认开启。
  • 托盘菜单可一键「关闭通知 / 开启通知」,状态写回配置。
  • 托盘菜单查看和取消已置顶窗口。
  • 可选开机自动启动,默认关闭。
  • 遇到管理员窗口时按需请求 Windows UAC 权限。
  • 单实例运行;目标窗口关闭后自动清理。
  • 退出 TopPin 时恢复由它置顶的窗口。
  • 不读写用户文档、不联网、不收集数据。

配置文件 TopPin.ini

首次运行时自动在 TopPin.exe 同目录生成(UTF-16 LE,带 BOM,记事本可直接编辑):

[TopPin]
Hotkey=Ctrl+Alt+T
OpacityUpHotkey=Ctrl+Win+=
OpacityDownHotkey=Ctrl+Win+-
Border=1
BorderColor=auto
BorderOpacity=100
BorderThickness=4
BorderCorner=1
BlockInGameMode=1
Notify=1
键 说明 PowerToys 默认
Hotkey 置顶/取消热键。修饰键 Ctrl/Alt/Shift/Win 至少一个,加一个主键 Win+Ctrl+T(本分支沿用 Ctrl+Alt+T)
OpacityUpHotkey 提高不透明度 Ctrl+Win+=
OpacityDownHotkey 降低不透明度 Ctrl+Win+-
Border 1 显示边框,0 关闭 1
BorderColor auto 跟随系统主题色;也可写 #RRGGBB 主题色(拿不到时 #00ADEF)
BorderOpacity 边框不透明度,1–100 100
BorderThickness 边框粗细(像素,会乘 DPI 缩放),1–32 4
BorderCorner 1 跟随窗口圆角,0 直角 1
BlockInGameMode 1 独占全屏游戏时不激活 1
Notify 1 显示托盘气泡提示,0 关闭;也可直接用托盘菜单的「关闭通知」切换(会自动写回本文件) 1

热键主键支持 A-Z、0-9、F1-F24、Space、Tab、Enter、Esc、Insert、Delete、Home、End、PageUp、PageDown、Up、Down、Left、Right、Num0-Num9、PrintScreen、Pause,以及 - = , . ; / [ \ ] ' 和反引号。大小写不敏感,空格会被忽略。

改完在托盘菜单点 重新加载配置 即可生效,不用重启;写错了会自动退回默认值并在托盘气泡里提示。

关掉 Border 后连边框定时器都不会启动,回归“零额外开销”的上游行为。

边框是怎么画的

全部照搬 PowerToys src/modules/alwaysontop/AlwaysOnTop:

  1. 取 DWMWA_EXTENDED_FRAME_BOUNDS(窗口可见边框),向外各扩 BorderThickness,这就是边框窗口的矩形——所以圆环画在窗口外面,只压住 1px,不遮内容。
  2. 描边中心线 = 客户区向内 thickness / 2 + 1 的圆角矩形,描边宽度 = thickness;圆角半径取窗口的 DWMWA_WINDOW_CORNER_PREFERENCE(ROUND=8 / ROUNDSMALL=4 / 其它=0)再乘 DPI 缩放。
  3. 逐像素用圆角矩形有符号距离场算覆盖率做抗锯齿,写进 32 位预乘 ARGB 位图,再用 UpdateLayeredWindow 贴上去——和 PowerToys 用 D2D 画出来的结果一致。
  4. 只遍历靠近四边的“边框带”,中间像素直接跳过,所以即使 4K 窗口渲染开销也可忽略。
  5. 边框窗口是 WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW,点击完全穿透、不进任务栏和 Alt-Tab。

拖动跟随(和 PowerToys 同一套)

边框跟随窗口位置用的是 Windows 事件,不是提高定时器频率:

  • 注册 SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, ...)(外加 EVENT_SYSTEM_MOVESIZEEND),拿到事件后先用 hwnd 过滤(只认 OBJID_WINDOW 且在置顶列表里的窗口);
  • 命中就只做一次 SetWindowPos(边框窗口, 新坐标, SWP_NOSIZE | SWP_NOREDRAW)——只挪,不重画,单次开销微秒级;
  • 100 ms 定时器仍然保留,负责重新渲染内容和校正(尺寸变了也走这条完整路径)。

所以拖动时边框跟着每一个位置事件走(接近屏幕刷新率),而重绘仍然只有 10 Hz,CPU 不会因为"更顺"而上涨。

主题色只在启动和「重新加载配置」时读取一次并缓存,避免每个拖动事件都去读注册表;运行中改了系统主题色需要重新加载配置才会更新。

不透明度与游戏模式

  • 调节只作用在已置顶窗口上,内部用的是 WS_EX_LAYERED + SetLayeredWindowAttributes,并会缓存窗口原本的 layered/alpha/colorkey 状态,取消置顶或退出程序时原样还原。
  • 游戏判定与 PowerToys 相同:SHQueryUserNotificationState() == QUNS_RUNNING_D3D_FULL_SCREEN(独占全屏)。命中时置顶热键直接不响应,透明度和退出的热键不受影响。

托盘菜单

  • 切换当前窗口置顶:与快捷键相同,右括号里显示当前配置的组合键。
  • 已置顶窗口:查看并单独取消当前置顶窗口。
  • 取消全部置顶:一次恢复所有窗口。
  • 重新加载配置:重新读取 TopPin.ini 并重注册快捷键。
  • 打开配置文件…:用默认编辑器打开 TopPin.ini。
  • 关闭通知 / 开启通知:一键开运气泡提示,状态会写回 TopPin.ini 的 Notify。
  • 开机自动启动:写入或删除当前用户的 Windows Run 启动项。
  • 以管理员身份重新启动:通过标准 UAC 流程控制管理员窗口。
  • 退出 TopPin:恢复窗口后退出。

管理员窗口与开机启动

TopPin 默认以普通权限运行,因此不会每次开机都弹出 UAC。目标程序以管理员身份运行时,TopPin 会询问是否继续;确认后,普通实例先恢复当前窗口状态,再由管理员实例接管并重试置顶。

“开机自动启动”默认关闭,不会创建服务或计划任务。启用后请不要随意移动 TopPin.exe;如果移动了文件,在新位置重新勾选一次即可更新启动路径。

已知限制

  • 管理员提权必须经过 Windows UAC 确认,不能静默绕过。
  • Windows 只保证置顶窗口位于普通窗口之上;多个置顶窗口之间没有唯一的最高层。
  • 独占全屏游戏不属于普通桌面窗口,无法保证覆盖。
  • 游戏判定与 PowerToys 相同,只认「独占全屏(D3D fullscreen)」;无边框全屏窗口不会被判定为游戏。
  • 调节不透明度的原理是给目标窗口加 WS_EX_LAYERED,个别硬件加速/自绘界面的程序可能出现短暂闪烁或完全无效;取消置顶时会把原始 layered 状态还原。
  • 直角边框(BorderCorner=0)走的是矩形抗锯齿分支,视觉效果与 PowerToys 的 D2D 描边一致,但不是同一套渲染管线。

从源码编译

云端(推荐,什么都不用装)

推送到 main 或手动触发 .github/workflows/build.yml,GitHub Actions 会在 windows-latest 上用 MSYS2 UCRT64 的 MinGW-w64 编译,产物作为 TopPin-exe artifact 上传;打 v* tag 会自动发布到 Releases。

本地

安装 MinGW-w64 GCC,并确保 gcc.exe 与 windres.exe 位于 PATH,然后运行:

build.cmd

成品位于 dist\TopPin.exe。

图标的矢量母版是 Assets/TopPin.svg。只有重新生成 ICO 时才需要 Python 和 Pillow:

python tools\build_icon.py

测试

tests\build-smoke.cmd
build\TopPinSmoke.exe

烟雾测试会短暂创建一个窗口,验证:

  • 单实例运行
  • 开机启动开启与撤销
  • 真实快捷键置顶与取消
  • 退出后恢复窗口

注意:烟雾测试固定发送默认的 Ctrl+Alt+T,所以它要求 TopPin.ini 里保持默认 Hotkey(或者直接删掉 ini 文件)。

测试开始前如果发现 TopPin 正在运行,会通过正常退出消息关闭它。

源码结构

  • TopPin.c:全部程序逻辑。
  • TopPin.rc、app.manifest:图标、版本信息和 Windows 权限清单。
  • Assets/TopPin.svg、Assets/TopPin.ico:图标源文件与多尺寸资源。
  • tools/build_icon.py:图标生成脚本。
  • tests/TopPinSmoke.c:原生烟雾测试。

许可证

MIT License

About

窗口置顶小工具(二创):基于 chiimyen/TopPin,边框外观/不透明度调节/游戏模式/拖动跟随移植自 Microsoft PowerToys 的 AlwaysOnTop 模块。约 65 KB 单文件,Win32 C,无依赖。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages