这个系列中的 "投影” 不太好有准确的翻译,它的原文 是"projection",最开始我觉得可能翻译为 实现,但C++ 本身也有"实现(implementation )",这两个不同的词翻译为一个总觉得怪怪的。
本文展示了如何直接或间接使用 winrt::implements 基本结构来拓展创作 C++/WinRT API 。 在此上下文中,“创作”的同义词有“生成”或“实现” 。 介绍以下在 C++/WinRT 类型上实现 API 的情形(按此顺序)。
下面涉及 Windows 运行时组件,但其中的相关内容仅在 C++/WinRT 上下文中适用。
- 你不是在创作一个 Windows 运行时类(运行时类);你只是想要实现一个或多个 Windows 运行时接口以便在应用内进行本地使用 。 例如, 你直接从 winrt::implements 派生并实现相关函数 ;
- 你正在创作一个运行时类 。 你可能正在创作一个要从某个应用中使用的组件。 或者,你可能正在创作一个要从 XAML 用户接口 (UI) 使用的类型,在此情况下,你在同一个编译单元内实现和使用一个运行时类。 在这些情况下,你使用工具为你生成派生自 winrt::implements 的类 ;
在这两种情况下,实现 C++/WinRT API 的类型被称作“实现类型” 。请务必区分实现类型与投影类型的概念。 投影类型将在通过 C++/WinRT 使用 API 中进行介绍。
非创作运行时类
最简单的方案是,你的类型在实现 Windows 运行时接口,并且你将在同一个应用中使用此类型。 在这种情况下,你的类型不需要是运行时类;只是一个普通的 C++ 类。 例如,你可能会基于 CoreApplication 编写一个应用 。
如果你的类型被 XAML UI 引用,那么它确实必须是运行时类,即使它与 XAML 在同一个项目中,也不例外。 在这种情况下,请参阅若要创作要在 XAML UI 中引用的运行时类部分。
有关安装和使用 C++/WinRT Visual Studio 扩展 (VSIX) 和 NuGet 包。
在 Visual Studio 中,“Visual C++”>“Windows 通用”>核心应用 (C++/WinRT)”项目模板阐释了 CoreApplication 模式 。 该模式首先将 Windows::ApplicationModel::Core::IFrameworkViewSource 的实现传递给 CoreApplication::Run:
using namespace Windows::ApplicationModel::Core;
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
IFrameworkViewSource source = ...
CoreApplication::Run(source);
}
// CoreApplication 使用接口来创建应用的第一个视图 。
// 从概念上来说,IFrameworkViewSource 如下所示 。
struct IFrameworkViewSource : IInspectable
{
IFrameworkView CreateView();
};
// 同样,从概念上来说,CoreApplication::Run 的实现执行此操作 。
void Run(IFrameworkViewSource viewSource) const
{
IFrameworkView view = viewSource.CreateView();
...
}
// 因此,作为开发人员,应实现 IFrameworkViewSource 接口 。
// C++/WinRT 具有基结构模板 winrt::implements,从而可以很容易实现一个或多个接口,
// 而不必求助于 COM 样式的编程 。 你可以从 implements 直接派生类型,然后实现接口的函数 。
// 操作方法如下。
// App.cpp
...
struct App : implements<App, IFrameworkViewSource>
{
IFrameworkView CreateView()
{
return ...
}
}
...
// 这将由 IFrameworkViewSource 处理 。 下一步是返回实现 IFrameworkView 接口的对象 。
// 你也可以选择在 App 上实现该接口 。
// 下一个代码示例表示一个小型应用,该应用将至少会在桌面上运行一个窗口。
// App.cpp
...
struct App : implements<App, IFrameworkViewSource, IFrameworkView>
{
IFrameworkView CreateView()
{
return *this;
}
void Initialize(CoreApplicationView const &) {}
void Load(hstring const&) {}
void Run()
{
CoreWindow window = CoreWindow::GetForCurrentThread();
window.Activate();
CoreDispatcher dispatcher = window.Dispatcher();
dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
}
void SetWindow(CoreWindow const & window)
{
// Prepare app visuals here
}
void Uninitialize() {}
};
...
// 由于 App 类型是 IFrameworkViewSource,因此可以直接传递一个到 Run。
using namespace Windows::ApplicationModel::Core;
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
CoreApplication::Run(winrt::make<App>());
}
在 winrt 组件中创作一个运行时类
如果你的类型打包在 Windows 运行时组件中,以便从另一个二进制文件(另一个二进制文件通常是应用程序)使用它,则你的类型必须是运行时类。 在 Microsoft 接口定义语言 (IDL) (.idl) 文件中声明运行时类(请参阅将运行时类重构到 Midl 文件 (.idl) 中)。
每个 IDL 文件生成一个 .winmd 文件,Visual Studio 会将所有这些合并为一个与根命名空间同名的文件。 最后生成的 .winmd 文件将是组件使用者将参考的文件。
下面是一个在 IDL 文件中声明运行时类的示例。
// MyRuntimeClass.idl
namespace MyProject
{
runtimeclass MyRuntimeClass
{
// Declaring a constructor (or constructors) in the IDL causes the runtime class to be
// activatable from outside the compilation unit.
MyRuntimeClass();
String Name;
}
}
// 此 IDL 声明一个 Windows 运行时类。
// 运行时类是一个可通过现代 COM 接口进行激活和使用(通常跨可执行文件)的类型。
// 当你向项目和生成中添加 IDL 文件时,C++/WinRT 工具链(midl.exe 和 cppwinrt.exe)将
// 会为你生成一个实现类型。
// 对于上面的示例 IDL,在名为 \MyProject\MyProject\Generated Files\sources\MyRuntimeClass.h // 和 MyRuntimeClass.cpp 的源代码文件中,实现类型是一个名为
// winrt::MyProject::implementation::MyRuntimeClass 的 C++ 结构存根 。
// 该实现类型如下所示。
// MyRuntimeClass.h
...
namespace winrt::MyProject::implementation
{
struct MyRuntimeClass : MyRuntimeClassT<MyRuntimeClass>
{
MyRuntimeClass() = default;
winrt::hstring Name();
void Name(winrt::hstring const& value);
};
}
// winrt::MyProject::factory_implementation::MyRuntimeClass is here, too.
// 请注意所使用的 F 边界多态模式(MyRuntimeClass 使用自身作为其基类
// MyRuntimeClassT 的模板参数)。 这也称为奇异递归模板模式 (CRTP)。
// 如果你向上查看继承链,你就会发现 MyRuntimeClass_base 。
// 可以使用 Windows 实现库 (WIL)简化简单属性的实现。 操作步骤如下:
// MyRuntimeClass.h
...
namespace winrt::MyProject::implementation
{
struct MyRuntimeClass : MyRuntimeClassT<MyRuntimeClass>
{
MyRuntimeClass() = default;
wil::single_threaded_rw_property<winrt::hstring> Name;
};
}
template <typename D, typename... I>
struct MyRuntimeClass_base : implements<D, MyProject::IMyRuntimeClass, I...>
因此,在此情况中,继承层次结构的根同样是 winrt::implements 基结构模板 。
标签:windows,C++,MyRuntimeClass,API,Windows,winrt,时类,WinRT From: https://blog.csdn.net/m0_72813396/article/details/140759520