性能注意事项和最佳做法

本主题介绍一组有关使用桌面窗口管理器 (DWM) API 的最佳做法。

本主题包含以下各节:

DWM 的应用程序实践

如果应用程序处理每英寸点数 (dpi) 缩放,则可以通过在程序清单中设置 dpi 感知标志或在程序初始化期间调用 SetProcessDPIAware 函数,将应用程序声明为 dpi 感知并阻止自动缩放。

打开 DWM 组合后,被遮盖的应用程序不再接收 WM_PAINT 消息,也不需要重新呈现。 每个窗口的内容都已可用于撰写屏幕图像。

顶级 WS_EX_TRANSPARENT 窗口应与 WS_EX_LAYERED 样式结合使用,以便进行命中测试。 经典意义上的WS_EX_TRANSPARENT (不重定向)对于属于同一线程的窗口层次结构中的子窗口很有用,但不适用于顶级窗口。

使用区域或分层创建形状或混合窗口。 请注意,在 Windows Vista 和更高版本的 Windows 中,自定义绘图仅顶级窗口的一部分不会在未绘制的区域中提供所需的过时内容。

GetDCOrgEx 等 API 可用于确定某些实际值。 如果设备上下文 (重定向窗口的 DC) , 则 GetDCOrgEx 返回的源与屏幕上窗口的原点不匹配。 原点将改为窗口的后台缓冲区表面的原点: (0,0) 。

当所有其他操作都失败时,通过调用 DwmSetWindowAttribute 函数来禁用窗口呈现。

DWM 的绘图实践

避免直接绘制到主显示图面。 这样做将强制 DWM 禁用组合,直到应用程序释放主设备图面。

评估应用程序是否必须提供自己的双重缓冲。 DWM 有效地对内容进行双重缓冲,并在单个帧中显示窗口。

避免从显示 DC 读取或写入显示 DC。 尽管 DWM 支持,但由于性能降低,我们不建议这样做。

避免在非工作区中绘图。 尽管应用程序可以访问此区域,并且 Microsoft Win32 API 支持绘制该区域,但这样做可能会导致窗口失去其具有的任何玻璃边框。

避免将 Windows 图形设备接口 (GDI) 和 Microsoft DirectX 混合使用,除非它们不重叠。 如果需要混合,可将 GDI 内容绘制到 DirectX 软件图面中,然后在组合到屏幕之前将其组合在一起,或者在单独的窗口中绘制它们。

使用 BitBltStretchBlt 函数(而不是 Windows GDI+)呈现绘图以供呈现。 GDI+ 使用软件呈现一次呈现一条扫描行。 这可能会导致应用程序中闪烁。

DWM Blur-Behind客户端区域

呈现模糊隐藏效果是 CPU 和图形处理单元 (GPU) 的资源密集型操作。 敦促应用程序开发人员考虑使用工作区模糊的影响,以便它不会消耗过多的资源。 在以下情况下,应格外小心:

  • 如果预期工作区模糊的大小会很大,即使模糊区域本身不会发生任何更新也是如此。 如果任何更新在窗口的模糊区域下发生,则必须呈现模糊,这会导致 CPU 和 GPU 成本。 此外,窗口上的窗口操作 (移动/调整大小/转换) 会产生更多成本。
  • 在模糊的工作区中预期有重大更新时。 这将需要在每次更新时重新绘制模糊,并消耗过多的资源。
  • 如果模糊预期覆盖一个重要区域,并且预期也会更新该区域,我们强烈建议你不要模糊工作区。