窗口区域与分层窗口

Posted

技术标签:

【中文标题】窗口区域与分层窗口【英文标题】:Window regions vs layered windows 【发布时间】:2018-07-05 01:09:37 【问题描述】:

我希望为应用程序窗口创建一个自定义圆角框架(边框半径和阴影) 从性能的角度来看,最好的技术是什么?

一个。为圆形应用程序窗口使用区域 (SetWindowRgn),为阴影使用分层窗口 (UpdateLayeredWindow)。

b.对圆形应用程序窗口和阴影使用分层窗口。

UpdateLayeredWindow 的docs 指定:

为了通过分层窗口和任何底层实现最佳绘图性能 窗口,分层窗口应尽可能小。

我是专门针对应用程序主窗口提出这个问题的,所以一个大窗口可能具有很高的复杂性并且大部分时间都在屏幕上可见。

我应该为应用程序窗口选择区域还是分层窗口?哪一个在 CPU/内存上会更轻?

【问题讨论】:

我投票结束这个“主要基于意见”。如果您想知道哪一种更有效,请自行测试,看看哪一种更适合您的需求。 唯一的办法就是测试。但是,我希望分层窗口更有效,因为窗口实际使用它们。窗口区域是在 windows 95 中引入的 - 总是有点新奇,并且不要像分层窗口那样抗锯齿。 从性能的角度来看,最好保留默认窗口框架。我敢打赌,在您的应用程序中,有很多重要的事情需要改进,而不是圆形框架。 @RemyLebeau 我相信与两者合作过的人可能会从他们的经验中获得一些见解。结束问题不会让人们知道这些见解。 【参考方案1】:

SetWindowRgn 为给定窗口禁用 DWM。 DWM 是负责使用可用图形硬件高效绘制窗口框架的组件。那应该几乎排除SetWindowRgn。此外,SetWindowRgn 会产生非常“古老”的结果,因为抗锯齿是不可能的。像素可以是完全透明的,也可以是完全不透明的。

为了通过分层窗口和任何底层实现最佳绘图性能 窗口,分层窗口应尽可能小。

我相信在 2018 年,这个提示不太重要。该文档是在 18 年前编写的,当时硬件比今天更加有限。

不过,UpdateLayeredWindow 并不是绘制自定义窗口框架的最快方法,尤其是当您必须经常更新位图时(例如在调整窗口大小期间)。瓶颈是这些更新必须从系统内存到图形内存。要最小化窗口大小,请创建四个小窗口,它们的大小仅足以绘制窗口的边框/角。例如,这个技巧是由 Visual Studio 提供的。使用 Spy++ 可以看到 4 个“VisualStudioGlowWindow”实例,它们是只有 9 像素宽/高的分层窗口(在我的系统上):

如果您想获得最佳性能,您还可以查看Direct Composition,结合WS_EX_NOREDIRECTIONBITMAP extended window style,如文章“High-Performance Window Layering Using the Windows Composition Engine”中所述。此技术至少需要 Windows 8。

【讨论】:

根据我的经验,分层窗口非常快。您还可以实现直接拖动它,这也非常流畅 - 无需任何特殊的视频硬件。

以上是关于窗口区域与分层窗口的主要内容,如果未能解决你的问题,请参考以下文章

使用分层窗口时未绘制下方的窗口

在分层窗口的子对话框中未单击 CMFCButton

两万字总结Windows系统中的Layered分层窗口技术

窗口内的 DirectX 覆盖

Visual-C Win32 API 分层窗口闪烁

将 HBITMAP 绘制到分层窗口上。怎么了?