我用 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

程序目录如下:

相关推荐
qq_452396233 小时前
第十二篇:《Cypress实战:从安装到第一个端到端测试》
ui·自动化
七夜zippoe4 小时前
DolphinDB在工业物联网中的优势
物联网·wpf·工业物联网·优势·dolphindb
wuyoula4 小时前
全新多平台电商代付商城源码
开发语言·c++·ui·小程序·php源码
xzl044 小时前
LVGL Coffee UI 接入实战:问题解决全记录
ui·rt-thread·lvgl
霍格沃兹测试学院-小舟畅学5 小时前
我用一个自定义Skill,把UI自动化维护时间从4小时压到15分钟
运维·ui·自动化
for_ever_love__5 小时前
UI学习:UITableViewCell的创建及复用机制
学习·ui·objective-c
heimeiyingwang7 小时前
【架构实战】观察者模式在分布式系统中的应用
观察者模式·架构·wpf
伽蓝_游戏7 小时前
UGUI源码剖析 (24):常用插件扩展介绍
ui·unity·c#·游戏引擎·游戏程序
bugcome_com10 小时前
WPF + Microsoft.ToolKit.Mvvm 技术指南与实战项目
microsoft·wpf
apollowing1 天前
Avalonia UI 12.0.0 正式发布:架构演进和性能飞跃
ui·架构