Nilai tinju dan pembukaan kotak ke IInspectable dengan C++/WinRT

Nota

Anda dapat membungkus dan membongkar tidak hanya nilai skalar, tetapi juga kebanyakan jenis array (dengan pengecualian array enumerasi) dengan menggunakan fungsi winrt::box_value dan winrt::unbox_value. Anda hanya dapat membuka kotak nilai skalar dengan menggunakan fungsi winrt::unbox_value_or.

Antarmuka IInspectable adalah antarmuka akar dari setiap kelas runtime di Windows Runtime (WinRT). Ini adalah ide analog untuk IUnknown berada di akar setiap antarmuka dan kelas COM; dan System.Object berada di akar setiap kelas Sistem Tipe Umum .

Dengan kata lain, fungsi yang mengharapkan IInspectable dapat diberikan instans dari kelas runtime apa pun. Tetapi Anda tidak dapat langsung meneruskan ke fungsi seperti itu nilai skalar (seperti nilai numerik atau teks), atau array. Sebagai gantinya, nilai skalar atau array perlu dibungkus di dalam objek kelas referensi. Proses pembungkusan itu dikenal sebagai mengotakkan nilainya.

Penting

Anda dapat membungkus dan membuka bungkus tipe data apa pun yang dapat Anda gunakan dengan Windows Runtime API. Dengan kata lain, sebuah jenis Windows Runtime. Nilai numerik dan teks (string), dan array, adalah beberapa contoh yang diberikan di atas. Contoh lain adalah struct yang Anda tentukan dalam IDL. Jika Anda mencoba membungkus tipe C++ biasa struct (yang tidak didefinisikan dalam IDL), maka pengompilasi akan mengingatkan Anda bahwa Anda hanya dapat membungkus tipe Windows Runtime. Kelas runtime adalah tipe Windows Runtime, tetapi tentu saja Anda dapat meneruskan kelas runtime ke API Windows Runtime tanpa membungkusnya.

C++/WinRT menyediakan fungsi winrt::box_value, yang mengambil nilai skalar atau array, dan mengembalikan nilai yang dikotak ke dalamIInspectable . Untuk membuka pembungkusan IInspectable kembali ke nilai skalar atau array, digunakan fungsi winrt::unbox_value. Untuk membongkar IInspectable kembali menjadi nilai skalar, ada juga fungsi winrt::unbox_value_or.

Contoh pembungkusan nilai

Fungsi aksesori LaunchActivatedEventArgs::Arguments mengembalikan winrt::hstring , yang merupakan nilai skalar. Kita dapat kotak yang nilai hstring dan meneruskannya ke fungsi yang mengharapkan IInspectable seperti ini.

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

Untuk mengatur properti konten dari tombol XAML, Anda memanggil fungsi mutator Button::Content. Untuk mengatur properti konten ke nilai string, Anda dapat menggunakan kode ini.

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

Pertama, konstruktor konversi hstring mengonversi literal string menjadi hstring . Kemudian kelebihan fungsi winrt::box_value yang menerima sebuah hstring dipanggil.

Contoh pembukaan kotak IInspectable

Dalam fungsi Anda sendiri yang mengharapkan IInspectable, Anda dapat menggunakan winrt::unbox_value untuk meng-unbox, dan gunakan winrt::unbox_value_or untuk meng-unbox dengan nilai default. Anda juga dapat menggunakan try_as untuk mengonversi ke 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.
}

Tentukan jenis nilai terbungkus

Jika Anda menerima nilai kotak dan tidak yakin jenis apa yang dikandungnya (Anda perlu mengetahui jenisnya untuk membuka kotaknya), maka Anda dapat mengkueri nilai kotak untuk antarmuka IPropertyValue, lalu memanggil Jenis tentang itu. Berikut adalah contoh kode.

WINRT_ASSERT adalah definisi makro, dan meluas ke _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);

API penting