C++/WinRT を使用した IInspectable へのスカラー値のボックス化とボックス化解除Boxing and unboxing scalar values to IInspectable with C++/WinRT

IInspectable インターフェイス は、Windows ランタイム (WinRT) のすべてのランタイム クラスのルート インターフェイスです。The IInspectable interface is the root interface of every runtime class in the Windows Runtime (WinRT). これは、すべての COM インターフェイスとクラスのルートである IUnknown や、すべての 共通型システム クラスのルートである System.Object と似た概念です。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.

つまり、IInspectable を想定している関数は、任意のランタイム クラスのインスタンスに渡すことができます。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.

C++/WinRT では、スカラー値を取得してボックス化した値を IInspectable へ返す winrt::box_value 関数を提供します。C++/WinRT provides the winrt::box_value function, which takes a scalar value and returns the value boxed into an IInspectable. IInspectable をボックス化解除してスカラー値に戻すために、winrt::unbox_value および winrt::unbox_value_or 関数があります。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

LaunchActivatedEventArgs::Arguments アクセサー関数は、スカラー値である winrt::hstring を返します。The LaunchActivatedEventArgs::Arguments accessor function returns a winrt::hstring, which is a scalar value. その hstring 値をボックス化し、次のように IInspectable を想定している関数に渡します。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()));
    ...
}

XAML Button のコンテンツ プロパティを設定するには、Button::Content ミューテーター関数を呼び出します。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.

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

まず、hstring 変換コンストラクターが文字列リテラルを hstring に変換します。First, the hstring conversion constructor converts the string literal into an hstring. 次に hstring を受け取る winrt::box_value のオーバーロードが呼び出されます。Then the overload of winrt::box_value that takes an hstring is invoked.

IInspectable をボックス化解除する例Examples of unboxing an IInspectable

IInspectable を想定する独自の関数では、winrt::unbox_value を使用してボックス化解除することができます。また winrt::unbox_value_or を使用して既定値でボックス化解除することができます。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

ボックス化された値を受け取って、その値に含まれる型が不明な場合は (型はボックス化解除するために知っておく必要があります)、その IPropertyValue でボックス化された値を照会し、そこで Type を呼び出すことができます。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 はマクロ定義であり、_ASSERTE に展開されます。WINRT_ASSERT is a macro definition, and it expands to _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);

重要な APIImportant APIs