通过 C++/WinRT 将值装箱到 IInspectable 和对其取消装箱

发布时间:2024年01月13日

??备注

不仅可对标量值进行装箱和取消装箱,而可使用?winrt::box_value?和?winrt::unbox_value?函数对大多数类型的数组进行这类操作(枚举数组除外)

只能使用?winrt::unbox_value_or?函数对标量值取消装箱。

IInspectable 接口是 Windows 运行时 (WinRT) 中每个运行时类的根接口。 这类似于位于每个 COM 接口和类的根处的?IUnknown;而且类似于位于每个通用类型系统类的根处的 System.Object。

换言之,可向任何运行时类的实例传递需要 IInspectable 的函数。 但是你无法将标量值(如数值或文本值)直接传递到此类函数,也不能直接传递数组。 相反,标量或数组值需要封装到引用类对象内。 该封装过程称为对值进行装箱

?重要

不管将什么类型传递给 Windows 运行时 API,都可以对该类型进行装箱和取消装箱操作。 换言之,可以对 Windows 运行时类型这样做。 上面给出的一些示例包括数字值、文本值(字符串)和数组。 另一个示例是在 IDL 中定义的?struct。 如果尝试对常规 C++?struct(未在 IDL 中定义)执行装箱操作,编译器会提醒你只能将 Windows 运行时类型装箱。 运行时类是 Windows 运行时类型,不过,我们当然可以将运行时类传递到 Windows 运行时 API,无需将其装箱。

C++/WinRT?提供了?winrt::box_value?函数,该函数采用标量或数组值,并将装箱的值返回到 IInspectable中 。 对于取消 IInspectable 装箱并返回到标量或数组值,提供?winrt::unbox_value?函数 。 对于取消 IInspectable 装箱并返回到标量值,还提供?winrt::unbox_value_or?函数 。

取消值装箱的示例

LaunchActivatedEventArgs::Arguments?访问器函数返回?winrt::hstring,这是一个标量值。 我们可以将该 hstring 值进行装箱并将其传递到需要 IInspectable 的函数,如下所示。

void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
    ...
    rootFrame.Navigate(winrt::xaml_typename<BlankApp1::MainPage>(), winrt::box_value(e.Arguments()));
    ...
}

要设置 XAML?按钮的内容属性,请调用?Button::Content?转变器函数。 要将内容属性设置为字符串值,可以使用此代码。

Button().Content(winrt::box_value(L"Clicked"));

首先,hstring?转换构造函数将此字符串参数转换为 hstring。 然后,调用采用 hstring 的 winrt::box_value 的重载。

取消 IInspectable 装箱的示例

在自己的需要 IInspectable 的函数中,可以使用?winrt::unbox_value?取消装箱,也可以使用?winrt::unbox_value_or?通过默认值取消装箱。 还可以使用?try_as?取消装箱到 std::optional。

void Unbox(winrt::Windows::Foundation::IInspectable const& object)
{
    hstring hstringValue = unbox_value<hstring>(object); // Throws if object is not a boxed string.
    hstringValue = unbox_value_or<hstring>(object, L"Default"); // Returns L"Default" if object is not a boxed string.
    float floatValue = unbox_value_or<float>(object, 0.f); // Returns 0.0 if object is not a boxed float.
    std::optional<int> optionalInt = object.try_as<int>(); // Returns std::nullopt if object is not a boxed int.
}

确定装箱值的类型

如果收到装箱值但不确定它所包含的类型(需要知道类型以便取消装箱),可以查询装箱值的?IPropertyValue?接口,然后对其调用 Type。 下面是代码示例。

WINRT_ASSERT?是宏定义,并且扩展到?_ASSERTE

float pi = 3.14f;
auto piInspectable = winrt::box_value(pi);
auto piPropertyValue = piInspectable.as<winrt::Windows::Foundation::IPropertyValue>();
WINRT_ASSERT(piPropertyValue.Type() == winrt::Windows::Foundation::PropertyType::Single);
文章来源:https://blog.csdn.net/hd51cc/article/details/135568624
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。