使用 SetWindowCompositionAttribute 来控制程序的窗口边框和背景(可以做 Acrylic 亚克力效果、模糊效果、主题色效果等)

本文介绍如何利用SetWindowCompositionAttribute API在Windows上实现亚克力、模糊、主题色等各种窗口特效,详细探讨了 AccentState 枚举值的影响,并提供了试验源代码。在Windows 10中,可以通过该API实现亚克力模糊效果,而在Windows 7上则无明显变化。
摘要由CSDN通过智能技术生成

Windows 系统中有一个没什么文档的 API,SetWindowCompositionAttribute,可以允许应用的开发者将自己窗口中的内容渲染与窗口进行组合。这可以实现很多系统中预设的窗口特效,比如 Windows 7 的毛玻璃特效,Windows 8/10 的前景色特效,Windows 10 的模糊特效,以及 Windows 10 1709 的亚克力(Acrylic)特效。而且这些组合都发生在 dwm 进程中,不会额外占用应用程序的渲染性能。

本文介绍 SetWindowCompositionAttribute 可以实现的所有效果。你可以通过阅读本文了解到与系统窗口可以组合渲染到哪些程度。


试验用的源代码

本文将创建一个简单的 WPF 程序来验证 SetWindowCompositionAttribute 能达到的各种效果。你也可以不使用 WPF,得到类似的效果。

简单的项目文件结构是这样的:

  • [项目] Walterlv.WindowComposition
    • App.xaml
    • App.xaml.cs
    • MainWindow.xaml
    • MainWindow.xaml.cs
    • WindowAccentCompositor

其中,App.xaml 和 App.xaml.cs 保持默认生成的不动。

为了验证此 API 的效果,我需要将 WPF 主窗口的背景色设置为纯透明或者 null,而设置 ControlTemplate 才能彻彻底底确保所有的样式一定是受我们自己控制的,我们在 ControlTemplate 中没有指定任何可以显示的内容。MainWindow.xaml 的全部代码如下:

<Window x:Class="Walterlv.WindowComposition.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="欢迎访问吕毅的博客:blog.walterlv.com" Height="450" Width="800">
    <Window.Template>
        <ControlTemplate TargetType="Window">
            <AdornerDecorator>
                <ContentPresenter />
            </AdornerDecorator>
        </ControlTemplate>
    </Window.Template>
    <!-- 我们注释掉 WindowChrome,是因为即将验证 WindowChrome 带来的影响。 -->
    <!--<WindowChrome.WindowChrome>
        <WindowChrome GlassFrameThickness="-1" />
    </WindowChrome.WindowChrome>-->
    <Grid>
    </Grid>
</Window>

而 MainWindow.xaml.cs 中,我们简单调用一下我们即将写的调用 SetWindowCompositionAttribute 的类型。

using System.Windows;
using System.Windows.Media;
using Walterlv.Windows.Effects;

namespace Walterlv.WindowComposition
{
   
    public partial class MainWindow : Window
    {
   
        public MainWindow()
        {
   
            InitializeComponent();
            var compositor = new WindowAccentCompositor(this);
            compositor.Composite(Color.FromRgb(0x18, 0xa0, 0x5e));
        }
    }
}

还剩下一个 WindowAccentCompositor.cs 文件,因为比较长放到博客里影响阅读,所以建议前往这里查看:

而其中对我们最终渲染效果有影响的就是 AccentPolicy 类型的几个属性。其中 AccentState 属性是下面这个枚举,而 GradientColor 将决定窗口渲染时叠加的颜色。

private enum AccentState
{
   
    ACCENT_DISABLED = 0,
    ACCENT_ENABLE_GRADIENT =
实现Win7窗口的边框半透明效果可以考虑以下步骤: 1. 创建一个自定义的用户控件,并设置其BorderStyle为None,同时设置BackColor为透明。 2. 在用户控件的Paint事件中,使用GDI+绘制窗口边框的半透明效果。可以使用DrawRectangle方法绘制边框,并使用FillRectangle方法填充半透明的颜。 3. 在用户控件中添加窗口控制按钮,如最小化、最大化和关闭按钮等。 4. 在用户控件的MouseDown和MouseMove事件中实现窗口的拖动效果。 实现在Win11里面呈现像Win7那样窗口边框半透明的毛玻璃质感可以考虑以下步骤: 1. 使用Win32 API函数DwmExtendFrameIntoClientArea实现窗口边框的毛玻璃效果。这个函数可以在Windows 7和Windows 11上都可以使用。 2. 在用户控件中添加一个透明的背景层,并在其上面绘制窗口内容。可以使用GDI+绘制窗口内容,或者使用WPF来实现更加复杂的界面效果。 3. 在用户控件的Paint事件中,先绘制背景层,再绘制窗口边框的半透明效果。 4. 在用户控件的Resize事件中,更新背景层和窗口边框的大小和位置。 需要注意的是,在Windows 11中,系统默认开启了Acrylic效果,可以通过在Registry中设置EnableTransparency键值来关闭它。如果希望在Win11系统上实现类似Win7的窗口边框半透明效果,可以考虑关闭Acrylic效果,然后使用DwmExtendFrameIntoClientArea函数来实现毛玻璃效果
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值