Waarden voor boksen en opheffen voor IInspectable met C++/WinRT

Note

U kunt niet alleen scalaire waarden, maar ook de meeste soorten arrays (met uitzondering van arrays van enumeraties) inpakken en uitpakken met behulp van de functies winrt::box_value en winrt::unbox_value. U kunt alleen scalaire waarden uitpakken met behulp van de functie winrt::unbox_value_or .

De IInspectable-interface is de hoofdinterface van elke runtimeklasse in de Windows Runtime (WinRT). Dit is een vergelijkbaar idee aan IUnknown als basis van elke COM-interface en -klasse; en System.Object als basis van elke Common Type System-klasse.

Met andere woorden, aan een functie die IInspectable verwacht, kan een exemplaar van elke runtime-klasse worden doorgegeven. Maar u kunt een dergelijke functie niet rechtstreeks doorgeven aan een scalaire waarde (zoals een numerieke waarde of tekstwaarde), noch aan een matrix. In plaats daarvan moet een scalaire waarde of matrixwaarde in een verwijzingsklasseobject worden verpakt. Dat inpakproces staat bekend als het boxen van de waarde.

Belangrijk

U kunt elk type dat u aan een Windows Runtime-API kunt doorgeven boxen en unboxen. Met andere woorden, een Windows Runtime-type. Numerieke en tekstwaarden (tekenreeksen) en matrices zijn enkele voorbeelden hierboven. Een ander voorbeeld is een struct die u in IDL definieert. Als u probeert een gewone C++ struct te boxen (een type dat niet in IDL is gedefinieerd), laat de compiler u weten dat u alleen een Windows Runtime-type kunt boxen. Een runtimeklasse is een Windows Runtime type, maar u kunt natuurlijk runtimeklassen doorgeven aan Windows Runtime API's zonder deze te boksen.

C++/WinRT biedt de functie winrt::box_value , die een scalaire of matrixwaarde gebruikt en de waarde retourneert die in een IInspectable is geplaatst. Voor het weer uitpakken van een IInspectable naar een scalaire waarde of arraywaarde bestaat de functie winrt::unbox_value. Voor het uitpakken van een IInspectable terug naar een scalaire waarde is er ook de functie winrt::unbox_value_or.

Voorbeelden van het boxen van een waarde

De accessorfunctie LaunchActivatedEventArgs::Arguments retourneert een winrt::hstring, een scalaire waarde. We kunnen die hstring-waarde in een vak zetten en doorgeven aan een functie die IInspectable als volgt verwacht.

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

Als u de inhoudseigenschap van een XAML-knop wilt instellen, roept u de functie Button::Content mutator aan. Als u de inhoudseigenschap wilt instellen op een tekenreekswaarde, kunt u deze code gebruiken.

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

Eerst converteert de hstring-conversieconstructor de letterlijke tekenreeks naar een hstring. Vervolgens wordt de overbelasting van winrt::box_value die een hstring gebruikt, aangeroepen.

Voorbeelden van het uitpakken van een IInspectable

In uw eigen functies waarin IInspectable wordt verwacht, kunt u winrt::unbox_value gebruiken om het postvak uit te schakelen en u kunt winrt::unbox_value_or gebruiken om het postvak uit te schakelen met een standaardwaarde. U kunt ook try_as gebruiken om uit te pakken naar een 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.
}

Het type van een geboxte waarde bepalen

Als u een geboxte waarde ontvangt en u niet zeker weet welk type deze bevat (u moet het type weten om de box ervan ongedaan te maken), kunt u de geboxte waarde opvragen via de interface IPropertyValue en vervolgens Type daarop aanroepen. Hier volgt een codevoorbeeld.

WINRT_ASSERT is een macrodefinitie en wordt uitgebreid naar _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);

Belangrijke API's