我用 WPF 做了一个 “苍蝇飞舞” 的屏保

目录

实现原理

核心流程

核心技术点

技术栈与依赖

下载


我本来想做漂亮的蝴蝶飞舞 ,奈何用WPF的矢量图形不好表现蝴蝶,画出来之后,反而像苍蝇在飞舞。


实现原理

基于 WPF 透明窗口 + 原生 GPU 渲染,实现全屏置顶、鼠标穿透的飞虫屏保效果。

效果:

窗口铺满屏幕,背景完全透明,可看到桌面、始终在最前层、点击、移动等操作直接作用于下层窗口、多只飞虫缓慢、柔和、随机飞行,带翅膀扇动效果

关闭方式:Ctrl+Shift+Q


核心流程

  1. **窗口**:WPF 透明窗口 + Win32 扩展样式实现全屏、置顶、鼠标穿透

  2. **动画**:`CompositionTarget.Rendering` 与显示刷新同步,每帧更新位置

  3. **绘制**:`OnRender` + `DrawingContext`,由 WPF 的 GPU 合成管线渲染

  4. **飞虫**:矢量翅膀(PathGeometry)或位图,带位置、角度、翅膀扇动


核心技术点

窗口控制:

cs 复制代码
<Window AllowsTransparency="True"
        WindowStyle="None"
        Background="Transparent"
        WindowState="Maximized"
        Topmost="True" />

鼠标穿透(WS_EX_TRANSPARENT)

通过 Win32 API 为窗口添加 `WS_EX_TRANSPARENT`,使鼠标事件穿透到下层:

cs 复制代码
private const int GWL_EXSTYLE = -20;
private const int WS_EX_TRANSPARENT = 0x00000020;

[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hwnd, int index);


[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);


var hwnd = new WindowInteropHelper(this).Handle;
var exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_TRANSPARENT);

全局热键(因鼠标穿透无法接收键盘)

cs 复制代码
private const int WM_HOTKEY = 0x0312;

[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hwnd, int id, uint fsModifiers, uint vk);

// 注册 Ctrl+Shift+Q
RegisterHotKey(hwnd, HOTKEY_ID, MOD_CTRL | MOD_SHIFT, VK_Q);

// 在 WndProc 中处理
if (msg == WM_HOTKEY && wParam.ToInt32() == HOTKEY_ID)
    Close();

帧同步动画(CompositionTarget.Rendering)

cs 复制代码
System.Windows.Media.CompositionTarget.Rendering += OnRendering;
private void OnRendering(object? sender, EventArgs e)
{
    var args = (RenderingEventArgs)e;
    var now = args.RenderingTime.TotalSeconds;
    var dt = now - _lastUpdate;
    _lastUpdate = now;

    // 更新每只飞虫的位置、角度、翅膀相位
    foreach (var b in _butterflies)
    {
        b.X += b.Vx * dt;
        b.Y += b.Vy * dt;
        b.FlapPhase += dt * b.FlapSpeed;
    }
    InvalidateVisual();  // 触发重绘
}

自定义绘制(OnRender + DrawingContext)

cs 复制代码
protected override void OnRender(DrawingContext dc)
{
    foreach (var b in _butterflies)
    {
        var wingFlap = Math.Sin(b.FlapPhase) * 0.35;
        dc.PushTransform(new TranslateTransform(b.X, b.Y));
        dc.PushTransform(new RotateTransform(b.Angle * 180 / Math.PI, 0, 0));
        dc.PushTransform(new ScaleTransform(1, 1 - wingFlap * 0.15, centerX, centerY));

        // 绘制身体、翅膀(PathGeometry / Ellipse / Image)
        dc.DrawGeometry(brush, pen, wingGeometry);
        dc.Pop(); dc.Pop(); dc.Pop();
    }
}

翅膀矢量绘制(PathGeometry + BezierSegment)

cs 复制代码
private static Geometry CreateMonarchForewing(int side, double w, double h)
{
    var fig = new PathFigure { StartPoint = new Point(0, 0), IsClosed = true };
    fig.Segments.Add(new BezierSegment(
        new Point(side * w * 0.25, -h * 0.15),
        new Point(side * w * 0.85, -h * 0.55),
        new Point(side * w, -h * 0.25), true));
    fig.Segments.Add(new BezierSegment(
        new Point(side * w * 0.9, h * 0.05),
        new Point(side * w * 0.35, h * 0.55),
        new Point(0, h * 0.25), true));
    var geo = new PathGeometry();
    geo.Figures.Add(fig);
    geo.Freeze();
    return geo;
}

技术栈与依赖

框架 : .NET 8 + WPF

渲染 :WPF 原生 DrawingContext(GPU 加速)

透明 :AllowsTransparency + Background="Transparent"

|穿透 : Win32 WS_EX_TRANSPARENT

热键 :Win32 RegisterHotKey

依赖 :无第三方图形库(纯 WPF)


下载

附件下载: https://pan.baidu.com/s/1hLm8aRX0tQLUXAfl4uba9w 提取码: late

程序目录如下:

相关推荐
薛定猫AI10 小时前
【深度解析】Gemini Omni 多模态生成与 Agent 化创作工作流:从视频编辑到 UI 生成的技术演进
人工智能·ui·音视频
赏金术士11 小时前
第七章:状态管理实战与架构总结
android·ui·kotlin·compose
枫叶林FYL13 小时前
项目九:异步高性能爬虫与数据采集中枢 —— 基于 Crawl<sub>4</sub>AI 与 Playwright 的现代化数据采集平台 项目总览
爬虫·python·深度学习·wpf
幽络源小助理15 小时前
全新UI 阅后即焚V2正式版系统源码_全开源_安全加密传输
安全·ui·开源·php源码
她说彩礼65万18 小时前
WPF 多值转换器
wpf
ZC跨境爬虫20 小时前
跟着 MDN 学CSS day_2:(连接样式表与选择器的实战艺术)
java·前端·css·ui·html·媒体
ZC跨境爬虫20 小时前
跟着 MDN 学CSS day_1:(CSS 基石与色彩的艺术)
前端·javascript·css·ui·html
无心水21 小时前
【分布式利器:金融级】金融级分布式架构开源框架全景解读
人工智能·分布式·金融·架构·开源·wpf·金融级框架
前端若水21 小时前
项目初始化:Vite + React + shadcn/ui
前端·react.js·ui
ZC跨境爬虫21 小时前
模块化烹饪小程序开发日记 Day4:网络层基础设施与接口治理实践
前端·javascript·数据库·ui·html