首页 / 软件开发 / C++ / 借助 C++ 进行 Windows 开发:Windows 运行时的呈现
借助 C++ 进行 Windows 开发:Windows 运行时的呈现2014-04-03 MSDN Kenny Kerr我的上一个专栏中讨论了 Windows 运行时 (WinRT) 应用程序模型 (msdn.microsoft.com/magazine/dn342867)。 我演示了如何通过标准 C++ 和经典 COM 来编写 Windows 应用商店或 Windows Phone 应用程序,其中仅使用了一些 WinRT API 函数。 毫无疑问,您 不必使用 C++/CX 或 C# 这样的语言投射。 能够绕过这些抽象概念是一种强大的功能,同时也是一种 了解这项技术工作方式的很好的方法。我在 2013 年 5 月的专栏中介绍了 Direct2D 1.1 并演示了如何使用它在桌面应用程序中进行呈现 (msdn.microsoft.com/magazine/dn198239)。 接下来的专栏介绍了 dx.codeplex.com 上提供的 dx.h 库,这可以大幅简化 C++ 中的 DirectX 编程 (msdn.microsoft.com/magazine/dn201741)。上个专栏中的代码对于实现基于 CoreWindow 的应用程序已经足够,但未提供任何呈现。本月,我将演示如何利用这种基本的框架并添加呈现支持。 WinRT 应用程序模型针对使用 DirectX 呈现进行了优化。 我将向您演示,如何利用在之前专栏中学到的有关 Direct2D 和 Direct3D 呈现的 内容,将其应用到基于 CoreWindow 的 WinRT 应用程序,具体而言,通过 dx.h 库使用 Direct2D 1.1 。 大多数情况下,不论您的目标是桌面还是 Windows 运行时,需要编写的实际 Direct2D 和 Direct3D 绘制命令是相同的。 但是,其中有一些细微的差别,当然,使其完全运转起来从一开始就有 很大差别。 因此,我将继续上一次的内容,演示如何在屏幕上显示一些像素!为了正确支持呈现,窗口必须能够意识到特定事件。 至少这包括窗口的可见性和大小的更改,以及 对用户所选择的逻辑显示 DPI 配置的更改。 在上次专栏中介绍的 Activated 事件中,这些新事件都 通过 COM 接口回调报告给应用程序。 ICoreWindow 接口提供注册 VisibilityChanged 和 SizeChanged 事件的方法,但首先我需要实现相应的处理程序。 我需要实现的两个 COM 接口与 Activated 事件处理程序及其 Microsoft 接口定义语言 (MIDL) 生成的类模板非常相似: typedef ITypedEventHandler<CoreWindow *, VisibilityChangedEventArgs *>
IVisibilityChangedEventHandler;
typedef ITypedEventHandler<CoreWindow *, WindowSizeChangedEventArgs *>
IWindowSizeChangedEventHandler;接下来必须实现的 COM 接口称为 IDisplayPropertiesEventHandler,谢天谢地这个接口已经定义 了。 我只需将相关的头文件包括在其中: #include <Windows.Graphics.Display.h>此外,相关类型在以下命名空间中定义: using namespace ABI::Windows::Graphics::Display;根据这些定义,我可以更新上次专栏中介绍的 SampleWindow 类,也从这三个接口继承: struct SampleWindow :
...
IVisibilityChangedEventHandler,
IWindowSizeChangedEventHandler,
IDisplayPropertiesEventHandler同时还需要记住更新我的 QueryInterface 实现以指示对这些接口的支持。 这些内容将让您自行完 成。 当然,如我上次所说,Windows 运行时并不关心在哪里实现这些 COM 接口回调。 它遵循的原则 是,Windows 运行时不假定我的应用程序 IFrameworkView(SampleWindow 类实现的主要接口)也实现 这些回调接口。 因此,虽然 QueryInterface 确实会正确处理这些接口的查询,不过 Windows 运行时 不会为它们进行查询。 相反,我需要注册相应事件,而最佳位置是在 IFrameworkView Load 方法的实 现中。 提醒一下,Load 方法是应该将所有代码粘贴到这里的方法,以便准备应用程序进行初始呈现。 接下来在 Load 方法中注册 VisibilityChanged 和 SizeChanged 事件: EventRegistrationToken token;
HR(m_window->add_VisibilityChanged(this, &token));
HR(m_window->add_SizeChanged(this, &token));这会明确告诉 Windows 运行时在哪里查找前两个接口实现。 第三个也是最后一个接口,它针对 LogicalDpiChanged 事件,但此事件注册由 IDisplayPropertiesStatics 接口提供。 此静态接口由 WinRT DisplayProperties 类实现。 我只需使用 GetActivationFactory 函数模板来获取它(在我最 近的专栏中可以找到 GetActivationFactory 的实现): ComPtr<IDisplayPropertiesStatics> m_displayProperties;
m_displayProperties = GetActivationFactory<IDisplayPropertiesStatics> (
RuntimeClass_Windows_Graphics_Display_DisplayProperties);成员变量保留此接口指针,在窗口的生命周期中,我需要在不同点上调用它。 现在,我可以在 Load 方法中注册 LogicalDpiChanged 事件: HR(m_displayProperties- >add_LogicalDpiChanged(this, &token));稍后将返回到这三个接口的实现。 现在该是准备 DirectX 基础结构的时候了。 我将需要标准的设 备资源处理程序集,这些在以前的专栏中已经多次讨论过: void CreateDeviceIndependentResources() {}
void CreateDeviceSizeResources() {}
void CreateDeviceResources() {}
void ReleaseDeviceResources() {}