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 raíz de todas las clases del entorno 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. Ese proceso de encapsulación se conoce como boxing del valor.
Important
Puede encapsular y desencapsular cualquier tipo que pueda pasar a la 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 de tiempo de ejecución es un tipo de Windows Runtime, pero, por supuesto, puede pasar clases de tiempo de ejecución a las API de Windows Runtime sin necesidad de encapsularlas.
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 desempaquetar un IInspectable en un valor escalar, también existe la función winrt::unbox_value_or.
Ejemplos de encapsulado de un valor
La función de descriptor de acceso LaunchActivatedEventArgs::Arguments devuelve un winrt::hstring, que es un valor escalar. Podemos encapsular ese valor en hstring y pasarlo a una función que espera IInspectable de esta forma.
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 de `hstring` convierte el literal de cadena de caracteres en un hstring. A continuación, se invoca la sobrecarga de winrt::box_value que acepta un hstring.
Ejemplos de unboxing de IInspectable
En sus propias funciones que esperan IInspectable, puede usar winrt::unbox_value para desempaquetar, y puede usar winrt::unbox_value_or para desempaquetar con un valor predeterminado. También puede usar try_as para desempaquetar como un 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);