WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)
在 WPF 中,如果想做一个背景透明的异形窗口,基本上都要设置 WindowStyle="None"、AllowsTransparency="True" 这两个属性。如果不想自定义窗口样式,还需要设置 Background="Transparent"。这样的设置会让窗口变成 Layered Window,WPF 在这种类型窗口上的渲染性能是非常糟糕的。
本文介绍如何使用 WindowChrome 而不设置 AllowsTransparency="True" 制作背景透明的异形窗口,这可以避免异形窗口导致的低渲染性能。
背景透明的异形窗口
如下是一个背景透明异形窗口的示例:

此窗口包含很大的圆角,还包含 DropShadowEffect 制作的阴影效果。对于非透明窗口来说,这是不可能实现的。
如何实现
要实现这种背景透明的异形窗口,需要为窗口设置以下三个属性:
WindowStyle="None"ResizeMode="CanMinimize"或ResizeMode="NoResize"WindowChrome.GlassFrameThickness="-1"或设置为其他较大的正数(可自行尝试设置之后的效果)
如下就是一个最简单的例子,最关键的三个属性我已经高亮标记出来了。
1 |
<Window x:Class="Walterlv.Demo.MainWindow" |
网上流传的主流方法
在网上流传的主流方法中,AllowsTransparency="True" 都是一个必不可少的步骤,另外也需要 WindowStyle="None"。但是我一般都会极力反对大家这么做,因为 AllowsTransparency="True" 会造成很严重的性能问题。
如果你有留意到我的其他博客,你会发现我定制窗口样式的时候都在极力避开设置此性能极差的属性:
性能对比
既然特别说到性能,那也是口说无凭,我们要拿出数据来说话。
以下是我用来测试渲染性能所使用的例子:

相比于上面的例子来说,主要就是加了背景动画效果,这可以用来测试帧率。
1 |
<Window x:Class="Walterlv.Demo.MainWindow" |
那么性能数据表现如何呢?我们让这个窗口在 2560×1080 的屏幕上全屏渲染,得出以下数据:
| 方案 | WindowChrome | AllowsTransparency |
|---|---|---|
| 帧率(fps)数值越大越好,60 为最好 | 59 | 19 |
| 脏区刷新率(rects/s)数值越大越好 | 117 | 38 |
| 显存占用(MB)数值越小越好 | 83.31 | 193.29 |
| 帧间目标渲染数(个)数值越大越好 | 2 | 1 |
另外,对于显存的使用,如果我在 7680×2160 的屏幕上全屏渲染,WindowChrome 方案依然保持在 80+MB,而 AllowsTransparency 已经达到惊人的 800+MB 了。
可见,对于渲染性能,使用 WindowChrome 制作的背景透明异形窗口性能完虐使用 AllowsTransparency 制作的背景透明异形窗口,实际上跟完全没有设置透明窗口的性能保持一致。


此性能差异的原理解读,请参阅:
功能对比
既然 WindowChrome 方法在性能上完虐网上流传的设置 AllowsTransparency 方法,那么功能呢?
值得注意的是,由于在使用 WindowChrome 制作透明窗口的时候设置了 ResizeMode="None",所以你拖动窗口在屏幕顶部和左右两边的时候,Windows 不会再帮助你最大化窗口或者靠边停靠窗口,于是你需要自行处理。不过窗口的标题栏拖动功能依然保留了下来,标题栏上的右键菜单也是可以继续使用的。
| 方案 | WindowChrome | AllowsTransparency |
|---|---|---|
| 拖拽标题栏移动窗口 | 保留 | 自行实现 |
| 最小化最大化关闭按钮 | 丢失 | 丢失 |
| 拖拽边缘调整窗口大小 | 丢失 | 丢失 |
| 移动窗口到顶部可最大化 | 丢失 | 自行实现 |
| 拖拽最大化窗口标题栏还原窗口 | 保留 | 自行实现 |
| 移动窗口到屏幕两边可侧边停靠 | 丢失 | 自行实现 |
| 拖拽摇动窗口以最小化其他窗口 | 保留 | 自行实现 |
| 窗口打开/关闭/最小化/最大化/还原动画 | 丢失 | 丢失 |
表格中:
保留表示此功能无需任何处理即可继续支持自行实现表示此功能已消失,但仅需要一两行代码即可补回功能丢失表示此功能已消失,如需实现需要编写大量代码
另外,以上表格仅针对鼠标操作窗口。如果算上使用触摸来操作窗口,那么所有标记为 自行实现 的都将变为 丢失。因为虽然你可以一句话补回功能,但在触摸操作下各种 Bug,你解不完……
这两种实现的窗口之间还有一些功能上的区别:
| 方案 | WindowChrome | AllowsTransparency |
|---|---|---|
| 点击穿透 | 在完全透明的部分点击依然点在自己的窗口上 | 在完全透明的部分点击会穿透到下面的其他窗口 |
然而,如果你希望在使用高性能的 WindowChrome 时也依然能点击穿透,那么你需要使用到一点点的小技巧来绕过 WPF 对 WS_EX_LAYERED 窗口样式的锁定。请参见:WPF 制作支持点击穿透的高性能的透明背景异形窗口。
WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)的更多相关文章
- WPF背景透明内嵌WebBrowser不显示问题,即AllowsTransparency = true 和 Webbrowser 等控件显示冲突
首先感谢两位先导者: 1. 解决 WPF AllowsTransparency = true 和 Webbrowser 等控件显示冲突 原文地址:https://www.cnblogs.com/zhi ...
- vs2012用wpf制作透明窗口中报错的解决方案
在开发wpf项目时,需要调用外部com组件,同时需要制作透明窗口,于是问题出现了,当我们在设置 AllowsTransparency="True"后,com组件显示不出来了,只有透 ...
- WPF Window异形窗口演示
我们先通过简单的效果展示,切换展示不同图片: 我们先定义图片资源文件,我们可以在window资源中定义,下面的在app.xaml文件来定义: <Application x:Class=" ...
- Qt 制作透明背景图片与裁剪图片(很实用)
这两天想做一个五子棋游戏,想从零开始自己绘制各种图片素材,将经验心得整理如下. 制作透明背景图片: void MyPainter::DrawKit() { QImage image(30, 30, Q ...
- [用UpdateLayeredWindow实现任意异形窗口]
前面提到,我们可以用SetWindowRgn或SetLayeredWindowAttributes实现不规则以及半透明的效果 对于SetWindowRgn,它通过一个Rgn来设置区域,这个Rgn一般可 ...
- Win32创建异形窗口
大家都见过在windows下各种气泡窗口.输入法窗口以及其他一些窗口,这些窗口看起来不像传统的windows窗那样,上面是标题栏,下面是窗口的客户区.这些窗口形状各异,可以是一个多边形,一幅图,甚至是 ...
- vc下打印透明背景图片
一.前言 刚接到个任务,要把带有透明背景的章子图片打印出来,开始觉得不是很简单吗,直接用vc自动生成的打印功能不就ok了.不过问题却不是想像的那么简单! 二.窗口中显示透明图片 在窗口中显示图片,可以 ...
- WPF制作的小型笔记本
WPF制作的小型笔记本-仿有道云笔记 楼主所在的公司不允许下载外部资源, 不允许私自安装应用程序, 平时记录东西都是用记事本,时间久了很难找到以前记的东西. 平时在家都用有道笔记, 因此就模仿着做了一 ...
- 一个最简单的Delphi2010的PNG异形窗口方法
同事演示了一个.NET的的PNG异形窗口.挺漂亮.于是也想用Delphi显摆一个. 关于Delphi用PNG做异形窗口的资料有不少.都是用GDIPlus或者TPNGImage组件加载PNG图像做的.但 ...
- WPF制作表示透明区域的马赛克画刷
最近在用WPF制作一款软件,需要像ps一样表示透明区域,于是制作了一个马赛克背景的style.实现比较简单,那么过程和思路就不表了,直接上代码 <DrawingBrush TileMode=&q ...
随机推荐
- 今天我们来聊一聊Java中的Semaphore
写在开头 在上几天写<基于AQS手写一个同步器>时,很多同学留言说里面提到的Semaphore,讲得太笼统了,今天趁着周末有空,咱们就一起详细的学习和梳理一把 Semaphore. 什么是 ...
- Android 开发入门(2)
0x04 简单控件 (1)文本显示 a. 添加文本 设置文本内容主要有两种方式: XML:通过属性android:text设置 在 layout 目录下新建 activity_text_view.xm ...
- sql 语句系列(多表之链二)[八百章之第四章]
从多个表中返回缺失值 比如说查询每个员工的部门,且查看部门的所有员工. 这里考虑一种情况就是可能有部门没有员工,同样有些员工还没有分配部门. 解析使用 full outer join. select ...
- Git 中 HEAD、工作树和索引之间的区别
一.HEAD 在git中,可以存在很多分支,其本质上是一个指向commit对象的可变指针,而Head是一个特别的指针,是一个指向你正在工作中的本地分支的指针 简单来讲,就是你现在在哪儿,HEAD 就指 ...
- 4.CSS层次选择器
1.后代选择器:在某个元素的后面 1 /*后代选择器*/ 2 body p{ 3 background: crimson; 4 } 2.子选择器:仅一代 1 /*子选择器*/ 2 body>p{ ...
- 力扣175(MySQL)-组合两个表(简单)
题目: 表: Person 表: Address 编写一个SQL查询来报告 Person 表中每个人的姓.名.城市和州.如果 personId 的地址不在 Address 表中,则报告为空 null ...
- NBF事件中心架构设计与实现
简介:NBF是阿里巴巴供应链中台的基础技术团队打造的一个技术PaaS平台,她提供了微服务FaaS框架,低代码平台和中台基础设施等一系列的PaaS产品,旨在帮助业务伙伴快速复用和扩展中台能力,提升研发 ...
- StarLake:汇量科技云原生数据湖的探索和实践
简介: 快速了解汇量科技在云原生数据湖领域的探索和实践,详解 StarLake 的架构及业务应用案例. 作者:陈绪(汇量科技资深算法架构师,EnginePlus 2.0 产品负责人) 内容框架: 互联 ...
- DataWorks功能实践速览 05——循环与遍历
简介: DataWorks功能实践系列,帮助您解析业务实现过程中的痛点,提高业务功能使用效率!通过往期的介绍,您已经了解到在DataWorks上进行任务运行的最关键的几个知识点,其中上期参数透传中为 ...
- [Caddy2] 无法访问 Lets Encrypt OCSP 的解决方法
更换国内 DNS 为国外 DNS. Caddy 使用对应 DNS 的 provider. 重新运行即可获取到证书,Certificate obtained successfully. 其它参考: [C ...