C++/WinRT ile değerleri IInspectable'a kutulama ve kutudan çıkarma

Note

Winrt::box_value ve winrt::unbox_value işlevlerini kullanarak yalnızca skaler değerleri değil, aynı zamanda çoğu dizi türünü de (numaralandırma dizileri dışında) kutulayabilir ve kaldırabilirsiniz. winrt::unbox_value_or işlevini kullanarak yalnızca skaler değerleri kutudan çıkarabilirsiniz.

IInspectable arabirimi, Windows Çalışma Zamanı (WinRT) içindeki her çalışma zamanı sınıfının kök arabirimidir. Bu, her COM arabiriminin ve sınıfının kökünde yer alan IUnknown'a benzer bir fikirdir; ve System.Object her Common Type System sınıfının kökündedir.

Başka bir deyişle, IInspectable bekleyen bir işlev herhangi bir çalışma zamanı sınıfının bir örneğine geçirilebilir. Ancak, böyle bir işleve doğrudan skaler değer (sayısal veya metin değeri gibi) veya dizi geçiremezsiniz. Bunun yerine, bir skaler veya dizi değerinin bir başvuru sınıfı nesnesi içinde sarmalanması gerekir. Bu sarmalama işlemi, değerin kutulanması olarak bilinir.

Önemli

Windows Çalışma Zamanı API'sine geçirebileceğiniz herhangi bir türü kutulayabilir ve kutusundan çıkarabilirsiniz. Başka bir deyişle, bir Windows Çalışma Zamanı türü. Sayısal değerler ve metin değerleri (dizeler) ve diziler, yukarıda verilen örneklerden bazılarıdır. Bir diğer örnek de IDL'de tanımladığınız bir struct örnektir. Normal bir C++ struct’ı (IDL’de tanımlanmamış olanı) kutulamaya çalışırsanız, derleyici size yalnızca bir Windows Çalışma Zamanı türünü kutulayabileceğinizi hatırlatır. Çalışma zamanı sınıfı, bir Windows Çalışma Zamanı türüdür, ancak elbette çalışma zamanı sınıflarını kutulama yapmadan Windows Çalışma Zamanı API'lerine aktarabilirsiniz.

C++/WinRT, skaler veya dizi değeri alan ve IInspectable içinde kutulanmış değeri döndüren winrt::box_value işlevini sağlar. Bir IInspectable değerini yeniden skaler veya dizi değerine dönüştürmek için winrt::unbox_value işlevi vardır. Bir IInspectable öğesini yeniden skaler bir değere çıkarmak için winrt::unbox_value_or işlevi de bulunur.

Bir değeri kutulama örnekleri

LaunchActivatedEventArgs::Arguments erişimci işlevi, skaler bir değer olan winrt::hstring değerini döndürür. Bu hstring değerini kutulayabilir ve bunun gibi IInspectable bekleyen bir işleve geçirebiliriz.

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

XAML Düğmesinin içerik özelliğini ayarlamak için Button::Content mutator işlevini çağırırsınız. İçerik özelliğini bir dize değerine ayarlamak için bu kodu kullanabilirsiniz.

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

İlk olarak, hstring dönüştürme kurucusu dize değişmezini bir hstring'e dönüştürür. Ardından bir hstring alan winrt::box_value aşırı yüklemesi çağrılır.

IInspectable kutusunu kaldırma örnekleri

IInspectable bekleyen kendi işlevlerinizde, kutudan çıkarmak için winrt::unbox_value kullanabilir, varsayılan bir değerle kutudan çıkarmak içinse winrt::unbox_value_or kullanabilirsiniz. Ayrıca, try_as kullanarak bir std::optional türüne kutudan çıkarma işlemi de yapabilirsiniz.

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

Kutulanmış değerin türünü belirleme

Kutulanmış bir değer alırsanız ve hangi türü içerdiğinden emin değilseniz (kutusundan çıkarmak için türünü bilmeniz gerekir), kutulanmış değeri IPropertyValue arabirimi açısından sorgulayabilir ve ardından bunun üzerinde Type çağrısı yapabilirsiniz. İşte bir kod örneği.

WINRT_ASSERT bir makro tanımıdır ve _ASSERTE genişletilir.

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

Önemli API'ler