Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Note
Puede encapsular y desencapsular no solo valores escalares, sino también la mayoría de los tipos de matrices (con la excepción de las matrices de enumeraciones) mediante las funciones winrt::box_value y winrt::unbox_value. Solo se pueden desboxar los valores escalares mediante la función winrt::unbox_value_or .
La interfaz IInspectable es la interfaz de raíz de todas las clases en tiempo de ejecución de Windows Runtime (WinRT). Esta es una idea análoga a IUnknown esté en la raíz de cada interfaz y clase COM; y a que System.Object esté en la raíz de cada clase del Sistema de tipos común.
Es decir, a una función que espera IInspectable se le puede pasar una instancia de cualquier clase del entorno de ejecución. Pero no se puede pasar directamente a esta función un valor escalar (como un valor numérico o de texto), ni una matriz. En su lugar, es necesario encapsular un valor escalar o una matriz en un objeto de clase de referencia. Dicho proceso de encapsulación se conoce como la conversión boxing del valor.
Important
Puedes aplicar la conversión boxing y unboxing a cualquier tipo que puedas pasar a una API de Windows Runtime. En otras palabras, un tipo de Windows Runtime. Los valores numéricos y de texto (cadenas) y las matrices son algunos ejemplos anteriores. Otro ejemplo es un struct que se define en IDL. Si intenta encapsular un tipo normal de C++ struct (es decir, que no está definido en IDL), el compilador le recordará que solo puede encapsular un tipo de Windows Runtime. Una clase en tiempo de ejecución es un tipo de Windows Runtime, pero claro que puedes pasar clases en tiempo de ejecución a las API de Windows Runtime sin una conversión boxing.
C++/WinRT proporciona la función winrt::box_value, que toma un valor escalar o una matriz y devuelve dicho valor encapsulado en un IInspectable. Para desempaquetar un IInspectable de nuevo en un valor escalar o una matriz, existe la función winrt::unbox_value. Para devolver IInspectable mediante la conversión unboxing a un valor escalar, existe también la función winrt::unbox_value_or.
Ejemplos de conversión boxing de un valor
La función de descriptor de acceso LaunchActivatedEventArgs::Arguments devuelve un winrt::hstring, que es un valor escalar. Podemos hacer la conversión boxing del valor hstring y pasarlo a una función que espera IInspectable de este modo.
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
...
rootFrame.Navigate(winrt::xaml_typename<BlankApp1::MainPage>(), winrt::box_value(e.Arguments()));
...
}
Para establecer la propiedad de contenido de un Button de XAML, se llama a la función mutadora Button::Content. Para establecer la propiedad content en un valor de cadena, puede usar este código.
Button().Content(winrt::box_value(L"Clicked"));
En primer lugar, el constructor de conversión hstring convierte el literal de la cadena en un hstring. Luego, se invoca la sobrecarga de winrt::box_value que toma un hstring.
Ejemplos de conversiones unboxing de IInspectable
En tus propias funciones que esperan IInspectable, puedes usar winrt::unbox_value para realizar una conversión unboxing y winrt::unbox_value_or para realizar una conversión unboxing con un valor predeterminado. También puede usar try_as para usar una conversión unboxing en 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.
}
Determinar el tipo de un valor encapsulado
Si recibe un valor encapsulado y no está seguro de qué tipo contiene (necesita conocer su tipo para poder desencapsularlo), puede consultar la interfaz IPropertyValue del valor encapsulado y, después, llamar a Type sobre ella. Este es un ejemplo de código.
WINRT_ASSERT es una definición de macro y se expande a _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);