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

Note

Anda dapat melakukan boxing dan unboxing tidak hanya pada nilai skalar, tetapi juga pada sebagian besar jenis array (kecuali 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 Common Type System .

Dengan kata lain, fungsi yang mengharapkan IInspectable dapat diberi sebuah 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 membungkus tersebut dikenal sebagai boxing nilai.

Important

Anda dapat melakukan boxing dan unboxing pada tipe apa pun yang dapat Anda teruskan ke API Windows Runtime. Dengan kata lain, tipe 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 mem-box C++ struct biasa (yang tidak didefinisikan dalam IDL), pengompilasi akan mengingatkan Anda bahwa Anda hanya dapat mem-box tipe Windows Runtime. Kelas runtime adalah tipe Windows Runtime, tetapi Anda tentu saja dapat meneruskan kelas runtime ke API Windows Runtime tanpa melakukan boxing.

C++/WinRT menyediakan fungsi winrt::box_value , yang mengambil nilai skalar atau array, dan mengembalikan nilai yang dikotak ke dalam IInspectable. Untuk membuka kotak IInspectable kembali ke nilai skalar atau array, ada fungsi winrt::unbox_value . Untuk mengekstrak IInspectable kembali menjadi nilai skalar, tersedia juga fungsi winrt::unbox_value_or.

Contoh tinju nilai

Fungsi aksesori LaunchActivatedEventArgs::Arguments mengembalikan sebuah winrt::hstring, yang merupakan nilai skalar. Kita dapat membungkus nilai hstring itu 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 Tombol XAML, Anda memanggil fungsi Mutator Tombol::Konten . Untuk mengatur properti konten ke nilai string, Anda dapat menggunakan kode ini.

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

Pertama, konstring konversi hstring mengonversi string harfiah menjadi hstring. Kemudian overload winrt::box_value yang menerima hstring dipanggil.

Contoh pembukaan kotak IInspectable

Dalam fungsi Anda sendiri yang mengharapkan IInspectable, Anda dapat menggunakan winrt::unbox_value untuk membuka kotak, dan Anda dapat menggunakan winrt::unbox_value_or untuk membuka kotak dengan nilai default. Anda juga dapat menggunakan try_as untuk mengekstrak nilai menjadi 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.
}

Menentukan jenis nilai yang diboks

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-nya , lalu memanggil Jenis di atasnya. 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