Boxing and unboxing scalar values to IInspectable with C++/WinRT

The IInspectable interface is the root interface of every runtime class in the Windows Runtime (WinRT). This is an analogous idea to IUnknown being at the root of every COM interface and class; and System.Object being at the root of every Common Type System class.

In other words, a function that expects IInspectable can be passed an instance of any runtime class. But you can't directly pass a scalar value, such as a numeric or text value, to such a function. Instead, a scalar value needs to be wrapped inside a reference class object. That wrapping process is known as boxing the value.


You can box and unbox any type that you can pass to a Windows Runtime API. In other words, a Windows Runtime type. Numeric and text values (strings) are the examples given above. Another example is a struct that you define in IDL. If you try to box a regular C++ struct (one that's not defined in IDL), then the compiler will remind you that you can box only a Windows Runtime type. A runtime class is a Windows Runtime type, but you can of course pass runtime classes to Windows Runtime APIs without boxing them.

C++/WinRT provides the winrt::box_value function, which takes a scalar value and returns the value boxed into an IInspectable. For unboxing an IInspectable back into a scalar value, there are the winrt::unbox_value and winrt::unbox_value_or functions.

Examples of boxing a value

The LaunchActivatedEventArgs::Arguments accessor function returns a winrt::hstring, which is a scalar value. We can box that hstring value and pass it to a function that expects IInspectable like this.

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

To set the content property of a XAML Button, you call the Button::Content mutator function. To set the content property to a string value, you can use this code.


First, the hstring conversion constructor converts the string literal into an hstring. Then the overload of winrt::box_value that takes an hstring is invoked.

Examples of unboxing an IInspectable

In your own functions that expect IInspectable, you can use winrt::unbox_value to unbox, and you can use winrt::unbox_value_or to unbox with a default value.

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.

Determine the type of a boxed value

If you receive a boxed value and you're unsure what type it contains (you need to know its type in order to unbox it), then you can query the boxed value for its IPropertyValue interface, and then call Type on that. Here's a code example.

WINRT_ASSERT is a macro definition, and it expands to _ASSERTE.

float pi = 3.14f;
auto piInspectable = winrt::box_value(pi);
auto piPropertyValue =<winrt::Windows::Foundation::IPropertyValue>();
WINRT_ASSERT(piPropertyValue.Type() == winrt::Windows::Foundation::PropertyType::Single);

Important APIs