Értékek dobozolása és kicsomagolása az IInspectable-ba C++/WinRT használatával

Note

A winrt::box_value és winrt::unbox_value függvények használatával nem csak a skaláris értékeket, hanem a tömbök legtöbb típusát is be lehet jelölni és ki lehet csomagolni (az enumerálások tömbjei kivételével). A winrt::unbox_value_or függvény használatával csak skaláris értékeket csomagolhat ki.

Az IInspectable interfész a Windows-futtatókörnyezet (WinRT) minden futtatókörnyezeti osztályának gyökérfelülete. Ez hasonló ahhoz az elképzeléshez, hogy az IUnknown minden COM-felület és -osztály őse, és hogy a System.Object minden Common Type System-beli osztály őse.

Más szóval az IInspectable-ra számító függvények bármely futtatókörnyezeti osztály egy példányát átadhatják. Egy ilyen függvénynek azonban közvetlenül nem adhat át skaláris értéket (például numerikus vagy szöveges értéket), sem tömböt. Ehelyett a skaláris vagy tömbértékeket egy referenciaosztály-objektumba kell burkolni. Ezt a becsomagolási folyamatot az érték boxingjának nevezik.

Fontos

Becsomagolhat és kicsomagolhat bármilyen típust, amelyet átadhat egy Windows-futtatókörnyezet API-nak. Más szóval egy Windows-futtatókörnyezet típus. A fenti példák közé tartoznak a numerikus és szöveges értékek (sztringek) és a tömbök. Egy másik példa egy olyan struct, amelyet az IDL-ben definiál. Ha egy normál C++ struct elemet próbál dobozolni (olyat, amely nincs definiálva az IDL-ben), a fordító emlékeztetni fogja arra, hogy csak Windows-futtatókörnyezet-típust lehet dobozolni. A runtimeosztály egy Windows-futtatókörnyezet-típus, de természetesen a runtimeosztályokat boxolás nélkül is átadhatja a Windows-futtatókörnyezet API-knak.

A C++/WinRT a winrt::box_value függvényt biztosítja, amely skaláris vagy tömbértéket vesz fel, és egy IInspectable-ra bekeretezett értéket ad vissza. Az IInspectable skaláris vagy tömbértékbe való visszaküldéséhez a winrt::unbox_value függvény található. Az IInspectable skaláris értékre való visszaküldéséhez a winrt::unbox_value_or függvény is létezik.

Példák értékek boxolására

A LaunchActivatedEventArgs::Arguments kiegészítő függvény egy winrt::hstring értéket ad vissza, amely skaláris érték. A hstring értéket becsomagolhatjuk, és átadhatjuk egy olyan függvénynek, amely IInspectable értéket vár, így.

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

Egy XAML-gomb tartalomtulajdonságának beállításához hívja meg a Button::Content mutáció függvényt. A tartalomtulajdonság sztringértékre való beállításához használhatja ezt a kódot.

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

Először a hstring konverziós konstruktor a karakterlánc-literált hstring típussá konvertálja. Ezután a rendszer meghívja a winrt::box_value túlterhelését, amely egy hstringet vesz igénybe.

Példák az IInspectable kibontására

Az IInspectable típust váró saját függvényeiben a winrt::unbox_value használható a kibontáshoz, a winrt::unbox_value_or pedig az alapértelmezett értékkel történő kibontáshoz. A try_as is használható az std::optional típusba való kicsomagoláshoz.

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.
}

Dobozos érték típusának meghatározása

Ha boxed értéket kap, és nem biztos benne, hogy milyen típust tartalmaz (a kicsomagolásához ismernie kell a típusát), akkor lekérdezheti a boxed érték IPropertyValue interfészét, majd meghívhatja rajta a Type tulajdonságot. Íme egy példa kódra.

WINRT_ASSERT egy makródefiníció, és _ASSERTE kifejezésre bontódik ki.

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);

Fontos API-k