如何激活引用类的实例

How to activate an instance of a ref class

本文关键字:引用 实例 激活 何激活      更新时间:2023-10-16

假设我有这个类:

public ref class Page1 sealed : Windows::UI::Xaml::Controls::Page {};

我可以像这样激活此类的实例:

auto page = ref new Page1();

但是,在原始C++中,我将如何做到这一点呢?

我已经试过这个,但它不起作用:

Microsoft::WRL::Wrappers::HString className;
className.Set(L"App1.Page1");
IInspectable *page;
Windows::Foundation::ActivateInstance(className.Get(), &page);

当我指定Windows运行时类名称(例如"Windows.UI.Xaml.Controls.Button")时,上面的代码确实有效,而不是我自己的引用类"App1.Page1"。


或者,假设我已经在 App1 命名空间中声明了一个名为 Page1 的公共 ref 类,如何从 HSTRING "App1.Page1" 激活此类的实例作为IInspectable*

我想我已经想通了。好吧,这个答案并不能直接解决激活任意类型的问题,但它可以满足我的需求。

细节决定成败。XAML 编译器将生成一堆在解决方案资源管理器中不可见的文件。这些文件具有扩展名 .g.h.g.hpp 。可以单击"解决方案资源管理器"中的"显示所有文件"按钮以查看它们。

App.g.h 中,App 类实现了 Windows::UI::Xaml::Markup::IXamlMetadataProvider 类,我们可以使用它来获取有关 XAML 类型的信息。XamlTypeInfo文件包含生成的类型定义。

下面是一些代码,演示如何从TypeName激活我们的 XAML 类型之一:

Object^ activate(TypeName typeName)
{
    auto app = Application::Current;
    auto provider = static_cast<IXamlMetadataProvider^>(app);
    auto xamlType = provider->GetXamlType(typeName);
    return xamlType->ActivateInstance();
}

无需 WRL,100% C++/CX,这要归功于 XAML 编译器生成的 XAML 类型信息!

我相信 C# 项目也有类似的结构,因为 Application 派生类也将实现IXamlMetadataProvider接口。在后台,Windows 运行时不使用 .NET,因此它没有任何"真实"反射,因此它依赖于静态定义的类型定义。