技术区域概述

如果在应用程序中使用多种呈现技术(例如 WPF、Win32 或 DirectX),则这些呈现技术必须共享公共顶级窗口中的呈现区域。 本主题介绍可能会对 WPF 互操作应用程序的呈现和输入造成影响的问题。

区域

在顶级窗口内,可以这么想:每个包含互操作应用程序某个技术的 HWND 都具有自己的区域(也称为“空域”)。 窗口内的每个像素都只属于一个特定 HWND,这构成了该 HWND 的区域。 (严格地说,如果有多个 WPF HWND,便会有多个 WPF 区域,但为了便于讨论,可以假定只有一个区域。) 区域暗含了这样一层含义:应用程序生存期内尝试在该像素之上呈现的所有层或其他窗口都必须是同一呈现级技术的一部分。 尝试在 Win32 上方呈现 WPF 像素会导致意外结果,应尽量通过互操作 API 禁止这种尝试。

区域示例

下图显示一个混合使用 Win32、DirectX 和 WPF 的应用程序。 每种技术都使用属于自己的且互不重叠的一组像素,因此不存在区域问题。

混合使用 Win32、DirectX 和 WPF 的应用程序的示例。

假设此应用程序使用鼠标指针位置来创建想要在这三个区域中任一区域上方呈现的动画。 无论动画本身采用哪一种技术,该技术都会与其他两种技术的区域发生冲突。 下图演示在一个 Win32 区域上呈现 WPF 圆形的尝试。

在一个 Win32 区域上呈现 WPF 圆形的尝试。

如果尝试在不同技术间使用透明度/Alpha 混合,也会发生冲突。 在下图中,WPF 框与 Win32 和 DirectX 区域存在冲突。 因为该 WPF 框中的像素是半透明的,所以它们必须由 DirectX 和 WPF 共同拥有,但这是不可能的。 因此,这是另一种冲突情况,且不可生成。

显示 WPF 框与 Win32 和 DirectX 区域存在冲突的示意图。

前面三个示例使用矩形区域,但也可以使用其他形状。 例如,区域可以具有一个孔。 下图显示了一个带有矩形孔的 Win32 区域,其大小为 WPF 和 DirectX 区域的总大小。

显示一个带有矩形孔的 Win32 区域的示意图。

区域也可以完全不是矩形,或可以是可由 Win32 HRGN(区域)描述的任何形状。

显示一个非矩形区域的示意图。

透明度和顶级窗口

Windows 中的窗口管理器实际上仅处理 Win32 HWND。 因此,每个 WPF Window 都是 HWND。 Window HWND 必须遵守适用于任何 HWND 的通用规则。 在该 HWND 内,WPF 代码可以执行整个 WPF API 支持的任何操作。 但是,为实现与桌面上其他 HWND 的交互,WPF 必须遵循 Win32 处理和呈现规则。 WPF 通过使用 Win32 API 来支持非矩形窗口,HRGN 用于非矩形窗口,分层窗口用于每像素 Alpha。

不支持常量 Alpha 和颜色键。 Win32 分层窗口的功能因平台而异。

分层窗口可通过指定要应用于窗口中每个像素的 Alpha 值来使整个窗口呈现为半透明状。 (Win32 实际上支持每像素 Alpha,但这在实际的程序中很难应用,因为在此模式下需要自行绘制任何子 HWND,包括对话框和下拉列表)。

WPF 支持 HRGN;但是,对于此功能,没有相应的托管 API。 可以使用平台调用和 HwndSource 来调用相关的 Win32 API。 有关详细信息,请参阅从托管代码调用本机函数

WPF 分层窗口在不同操作系统上具有不同的功能。 这是因为 WPF 使用 DirectX 进行呈现,而分层窗口主要用于 GDI 呈现,而非 DirectX 呈现。

  • WPF 支持硬件加速的分层窗口。

  • WPF 不支持透明度颜色键,因为 WPF 无法保证准确呈现所请求的颜色,尤其当呈现采用了硬件加速时更是如此。

有关互操作区域限制的更多信息,请参阅 WPF 内部的 HWND

另请参阅