Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Замечание
С помощью функций winrt::box_value и winrt::unbox_value можно включить и распаковку не только скалярных значений, но и большинство типов массивов (за исключением массивов перечислений). С помощью функции winrt::unbox_value_or можно разупаковывать только скалярные значения.
Интерфейс IInspectable является корневым интерфейсом каждого класса среды выполнения в Windows Runtime (WinRT). Это аналогичная идея IUnknown, находящегося в основе каждого интерфейса и класса COM; и System.Object, находящегося в основе каждого класса Common Type System.
Другими словами, в функцию, которая ожидает IInspectable, можно передать экземпляр любого класса среды выполнения. Но вы не можете напрямую передать такой функции скалярное значение (например, числовое или текстовое значение), а также массив. Вместо этого скалярное или массивное значение необходимо упаковать в объект класса ссылок. Этот процесс упаковки называется упаковкой значения.
Это важно
Вы можете упаковать и распаковать любой тип, который вы можете передать в API среды выполнения Windows. Другими словами, тип среды выполнения Windows. Числовые и текстовые значения (строки) и массивы приведены в некоторых примерах выше. Еще одним примером является struct
, определяемый в IDL. Если вы попытаетесь обернуть обычный C++ struct
(который не определен в IDL), компилятор напомнит вам, что можно обернуть только тип Windows Runtime. Класс среды выполнения является типом среды выполнения Windows, но, конечно, можно передавать классы среды выполнения в API среды выполнения Windows без упаковки их в объекты.
C++/WinRT предоставляет функцию winrt::box_value, которая принимает скалярное или массивное значение и возвращает значение, упакованное в IInspectable. Для распаковки IInspectable обратно в скалярное или массивное значение существует функция winrt::unbox_value. Для преобразования
Примеры упаковки значения
Функция доступа LaunchActivatedEventArgs::Arguments возвращает winrt::hstring, которое представляет собой скалярное значение. Мы можем упаковать значение hstring и передать его в функцию, которая ожидает IInspectable, как это.
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
...
rootFrame.Navigate(winrt::xaml_typename<BlankApp1::MainPage>(), winrt::box_value(e.Arguments()));
...
}
Чтобы задать свойство содержимого кнопки XAML, вызовите функцию мутатора Button::Content. Чтобы задать свойство содержимого строковым значением, можно использовать этот код.
Button().Content(winrt::box_value(L"Clicked"));
Во-первых, конструктор преобразования hstring преобразует строковый литерал в hstring. Затем вызывается перегрузка winrt::box_value, которая принимает hstring.
Примеры распаковки IInspectable
В собственных функциях, ожидающих IInspectable, можно использовать winrt::unbox_value для распаковки и winrt::unbox_value_or для распаковки со значением по умолчанию. Вы также можете использовать try_as для распаковки в 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.
}
Определите тип упакованного значения
Если вы получаете упакованное значение и не уверены, какой тип оно содержит (необходимо знать его тип для распаковки), вы можете выполнить запрос к упакованному значению для его интерфейса IPropertyValue, а затем вызвать Type. Ниже приведен пример кода.
WINRT_ASSERT
— это определение макроса, и оно расширяется до _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);