借助 C++ 进行 Windows 开发:Windows 运行时应用程序模型2014-04-03 MSDN Kenny Kerr我们的生活充满了抽象。作为开发人员,如果我们不了解抽象的定义就去使用它,则通常会让我们 陷入困境。抽象有时是零散的,且无法完全隐藏基本复杂性。别误解我的意思,其实抽象是很有用的。 它们能为用户和开发人员提供帮助,而如果您深入研究您通常依赖的抽象来了解其运作方式,则会让您 受益匪浅。此外,承认这一现实的库通常比不承认这一现实的库更为成功,部分是因为前者允许您在必 要时绕过抽象。Windows 运行时 (WinRT) 就是一个这样的抽象,在本月的专栏中,我将通过研究 WinRT 核心应用 程序模型来说明此抽象。此抽象以 CoreWindow 类为中心,并且每个“新型”Windows 应用商店和 Windows Phone 应用中都包含一个该类的实例。但是很少有开发人员知道该实例的存在,更不必说该实 例的运作方式了。这可能是对抽象成功的最好证明。自 Windows 8 API 最初于 2011 年发布以来,已有大量关于通过 Windows 运行时提供抽象的各种 语言投射的报道和文章。但是,了解 Windows 运行时的最佳方式是避开各种语言投射(包括 C++/CX) 并使用标准 C++ 和经典 COM。只有 C++ 能让您透过表象看到实际情况(从技术上说,C 也可以,但会 造成一些不必要的麻烦)。您仍可以选择使用这样或那样的语言投射(但愿是 C++/CX),因为您可能 应该这样做,但您至少要更清楚地了解实际情况。若要开始此操作,请打开 Visual Studio 2012 并为 Windows 应用商店或 Windows Phone 应用创 建新的 Visual C++ 项目。随便您使用哪种模板。加载后,转到解决方案资源管理器并删除一切不重要 的内容。如果您选取了基于 XAML 的模板,则删除所有 XAML 文件。您也可以删除所有 C++ 源文件。 您可能需要保留预编译头,但请务必删除其中包含的所有内容。应保留的内容是部署应用、图像、证书 和 XML 清单所需的包资产。接下来,打开项目的属性页并选择编译器属性 - 树中左侧的 C/C++ 节点。找到称作“使用 Windows 运行时扩展”的 /ZW 编译器选项对应的行,并选择“否”以禁用 C++/CX 语言扩展。这样, 您就可以确保不会有比标准 C++ 编译器更神秘的东西了。到了这一步,您也可以将编译器的警告级别 设置为 /W4。如果您尝试编译项目,则应会收到一个链接器错误,告知您找不到项目的 WinMain 入口点函数。将 新的 C++ 源文件添加到项目,您要做的第一件事是添加缺少的 WinMain 函数:
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int){}
如您所见,这是用于基于 C 运行时库 (CRT) 的 Windows 应用程序的旧 WinMain 函数。 当然,HINSTANCE 和 PWSTR 不是基本 C++ 类型,因此您将需要包含 Windows 头:#include <windows.h>
如果您保留了项目的预编译头,则可在此处包含它。 此外,由 于我还将使用 Windows 运行时 C++ 模板库 (WRL) 中的 ComPtr,因此现在最好是包含它:#include <wrl.h>
在接下来的几个专栏中,我将更详细地介绍 WRL。 现在,我将 利用 ComPtr 类模板来维护 COM 接口指针。 在这一阶段中,您只需记住 WRL ComPtr 只是一个 COM 接口智能指针。 尽管它提供了某些特定于 Windows 运行时的功能,但我不会在本月的专栏中探讨这些 功能。 您可以很轻松地改用活动模板库 (ATL) CComPtr 或您选择的任何 COM 接口智能指针。 WRL ComPtr 是在 Microsoft::WRL 命名空间中定义的: using namespace Microsoft::WRL;
我还将使用 ASSERT 宏和 HR 函数来进行错误处理。 由于我之前已讨论这些,因此在这 里不再讲述。 如果您对这些步骤不确定,请参阅我在 2013 年 5 月撰写的专栏“Direct2D 1.1 简介 ”(msdn.microsoft.com/magazine/dn198239)。最后,若要使用本专栏中提到的任何 WinRT 函 数,您需要为链接器提供 .lib 文件的名称:#pragma comment(lib, "RuntimeObject.lib")