软件分享 - Windows副屏信息展示软件

给闲置的副屏做一块信息面板

我的显示器支架上一直挂着第二块屏幕,但它绝大部分时间都只是一张壁纸。

所以写了 SubScreen:打开就铺满副屏的信息面板——左边时钟、天气、音乐播控,右边一言和日历。不用的时候从托盘退出,不占任务栏。
已在 GitHub 开源,使用 GPLv3 许可:https://github.com/wyj5211/SubScreen

SubScreen 主界面

它显示什么

  • 左上 · 时钟:年月日、星期、农历、节气、节日
  • 左中 · 天气:实时温度与天气现象,右侧竖排体感温度、湿度、风速、气压,底部是未来三天
  • 左下 · 音乐播控:封面、标题、上一曲 / 播放暂停 / 下一曲,底部一条音量条直接控制系统主音量
  • 右上 · 一言:每小时随机换一句
  • 右下 · 日历:Win11 托盘日历的样子,农历、节气、法定节假日都在格子里
  • 左下角 · 工具条:设置 / 刷新 / 最小化 / 关闭

窗口无边框,打开就铺满指定的那块屏,不在任务栏显示,入口放在托盘图标上。

几个取舍

零第三方依赖。 整套只用 .NET Framework 自带的东西,编译出来就是一个 300 KB 左右的 exe,除了运行时不需要再装任何组件。

背景只支持纯色和静态图片。 最早做过动图(GIF / APNG)支持,后来发现它会一直占着 CPU 和内存,而副屏背景绝大部分时间根本没人看,就砍了。亮度、模糊、遮罩和适应模式(填充 / 适应 / 拉伸 / 平铺 / 居中)都保留。

界面是一整张自绘的表面,没有用任何子控件。 圆角、半透明、hover、点击全部自己处理;每张卡片各自渲染进一张位图缓存,只有内容变化才重绘——所以时钟每秒跳一下,也只是那一张卡片重绘,不会牵动全屏。

图标是逐个实际渲染确认过的。 Windows 自带的图标字体只用私有区码位,网上抄来的对照表不少是错的,所以我把字体里 1572 个已映射码位逐块渲染成图看了一遍。顺带发现:这个字体里根本没有"风"的字形——风速最后用了半圆速度表代替,毕竟风速本身就是个速度指标。

踩过的两个坑

图标文件的小尺寸必须是 DIB 格式。 用 Pillow 直接 save(format="ICO") 生成的多尺寸图标,会把所有档位都写成 PNG 压缩条目。这种 ico 在资源管理器里看着完全正常,但 .NET 读出来是一团彩色噪声。最后改成手写 ico 的目录结构:16~64 用 DIB,128/256 用 PNG。

WinRT 的接口"继承"在底层不等于方法内联。 元数据里 IAsyncOperation<T> 看起来继承了 IAsyncInfo,但在 ABI 上它们是两个独立接口。按"内联"的假设去读状态,实际读到的是另一个方法,结果就是所有异步操作看上去永远不完成(表现为音乐播控一直"请求超时")。后来定的规矩是:要调哪个接口的方法,就先把它单独取出来。

已知限制

  • 背景只支持静态图片,选到 gif / apng 只会显示第一帧
  • 法定节假日只按节日当天判定,不含国务院逐年公布的调休连休安排(那些数据逐年变化,推算不出来)
  • 二十四节气用寿星公式,只覆盖 2001–2100 年
  • 天气走和风天气的新版接口(API Host + 请求头鉴权),API Key 以明文保存在 settings.ini 里

怎么拿到

用 Visual Studio 打开 src\SubScreen.slnx 直接生成,或者命令行:

msbuild src\SubScreen.csproj /t:Rebuild /p:Configuration=Release

生成结果在 src\bin\Release\,所有配置都放在 exe 同级的 config\ 目录下,拷走 exe 和这个目录就是完整的。

程序还带了几个排查用的参数,比如 --capture preview.png --demo 可以不开窗口直接把界面渲染成图片,--selftest report.txt 跑一遍离线自检。


这个项目是在 AI 辅助下做的:我负责定需求和验收标准,AI 负责写实现,每改一处都要跑通自检才算完成。

评论栏

暂无评论,快来抢沙发吧!