You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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));
}
}
}
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 的全部代码如下:
而 MainWindow.xaml.cs 中,我们简单调用一下我们即将写的调用 SetWindowCompositionAttribute 的类型。
还剩下一个 WindowAccentCompositor.cs 文件,因为比较长放到博客里影响阅读,所以建议前往这里查看:Walterlv.Packages/WindowAccentCompositor.cs at master · walterlv/Walterlv.Packages
而其中对我们最终渲染效果有影响的就是 AccentPolicy 类型的几个属性。其中 AccentState 属性是下面这个枚举,而 GradientColor 将决定窗口渲染时叠加的颜色。
影响因素
经过试验,对最终显示效果有影响的有这些:
使用 WindowChrome,你可以用你自己的 UI 覆盖掉系统的 UI 窗口样式。关于 WindowChrome 让客户区覆盖非客户区的知识,可以阅读:
[WPF 自定义控件] Window(窗体)的 UI 元素及行为 - dino.c - 博客园
需要注意的是,WindowChrome 的 GlassFrameThickness 属性可以设置窗口边框的粗细,设置为 0 将导致窗口没有阴影,设置为负数将使得整个窗口都是边框。
排列组合
AccentState=ACCENT_DISABLED
使用 ACCENT_DISABLED 时,GradientColor 叠加色没有任何影响,唯一影响渲染的是 WindowChrome 和操作系统。
总结
由于 Windows 7 上所有的值都是同样的效果,所以下表仅适用于 Windows 10。
在以上的特效之下,WindowChrome 可以让客户区覆盖非客户区,或者让整个窗口都获得特效,而不只是标题栏。
附源代码
请参见 GitHub 地址以获得最新代码。如果不方便访问,那么就看下面的吧。
Walterlv.Packages/WindowAccentCompositor.cs at master · walterlv/Walterlv.Packages
The text was updated successfully, but these errors were encountered: