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.
Con C++/WinRT, puede llamar a las API de Windows Runtime mediante tipos de cadenas anchas de la biblioteca estándar de C++ como std::wstring (nota: no con tipos de cadena estrechos como std::string). C++/WinRT tiene un tipo de cadena personalizado denominado winrt::hstring (definido en la biblioteca base de C++/WinRT, que es %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h). Y ese es el tipo de cadena que los constructores, las funciones y las propiedades de Windows Runtime realmente aceptan y devuelven. Pero en muchos casos —gracias a los constructores y operadores de conversión de hstring— puedes elegir si quieres tener presente o no hstring en el código cliente. Si está desarrollando APIs, es más probable que necesite saber qué es hstring.
Hay muchos tipos de cadena en C++. Existen variantes en muchas bibliotecas además de std::basic_string de la biblioteca estándar de C++. C++17 tiene utilidades de conversión de cadenas y std::basic_string_view, para salvar las brechas entre todos los tipos de cadena. winrt::hstring proporciona convertibilidad con std::wstring_view para proporcionar la interoperabilidad para la que se diseñó std::basic_string_view .
Uso de std::wstring (y, opcionalmente, winrt::hstring) con Uri
Windows::Foundation::Uri se construye a partir de winrt::hstring.
public:
Uri(winrt::hstring uri) const;
Pero hstring tiene constructores de conversión que le permiten trabajar con él sin necesidad de tenerlo en cuenta. Este es un ejemplo de código que muestra cómo crear un URI a partir de un literal de cadena ancho, desde una vista de cadena ancha y desde un std::wstring.
#include <winrt/Windows.Foundation.h>
#include <string_view>
using namespace winrt;
using namespace Windows::Foundation;
int main()
{
using namespace std::literals;
winrt::init_apartment();
// You can make a Uri from a wide string literal.
Uri contosoUri{ L"http://www.contoso.com" };
// Or from a wide string view.
Uri contosoSVUri{ L"http://www.contoso.com"sv };
// Or from a std::wstring.
std::wstring wideString{ L"http://www.adventure-works.com" };
Uri awUri{ wideString };
}
El descriptor de acceso a la propiedad Uri::Domain es de tipo hstring.
public:
winrt::hstring Domain();
Pero, de nuevo, conocer ese detalle es opcional gracias al operador de conversión de hstringa std::wstring_view.
// Access a property of type hstring, via a conversion operator to a standard type.
std::wstring domainWstring{ contosoUri.Domain() }; // L"contoso.com"
domainWstring = awUri.Domain(); // L"adventure-works.com"
// Or, you can choose to keep the hstring unconverted.
hstring domainHstring{ contosoUri.Domain() }; // L"contoso.com"
domainHstring = awUri.Domain(); // L"adventure-works.com"
Del mismo modo, IStringable::ToString devuelve hstring.
public:
hstring ToString() const;
Uri implementa la interfaz IStringable .
// Access hstring's IStringable::ToString, via a conversion operator to a standard type.
std::wstring tostringWstring{ contosoUri.ToString() }; // L"http://www.contoso.com/"
tostringWstring = awUri.ToString(); // L"http://www.adventure-works.com/"
// Or you can choose to keep the hstring unconverted.
hstring tostringHstring{ contosoUri.ToString() }; // L"http://www.contoso.com/"
tostringHstring = awUri.ToString(); // L"http://www.adventure-works.com/"
Puede usar la función hstring::c_str para obtener una cadena ancha estándar de un hstring (igual que puede desde std::wstring).
#include <iostream>
std::wcout << tostringHstring.c_str() << std::endl;
Si tiene un hstring , puede hacer un URI a partir de él.
Uri awUriFromHstring{ tostringHstring };
Considere un método que acepta un hstring.
public:
Uri CombineUri(winrt::hstring relativeUri) const;
Todas las opciones que acaba de ver también se aplican en estos casos.
std::wstring contact{ L"contact" };
contosoUri = contosoUri.CombineUri(contact);
std::wcout << contosoUri.ToString().c_str() << std::endl;
hstring tiene un operador de conversión std::wstring_view miembro y la conversión se logra sin costo alguno.
void legacy_print(std::wstring_view view);
void Print(winrt::hstring const& hstring)
{
legacy_print(hstring);
}
Funciones y operadores winrt::hstring
Se implementa un host de constructores, operadores, funciones e iteradores para winrt::hstring.
Una hstring es un rango, por lo que puede usarla con forbasado en rangos o con std::for_each. También proporciona operadores de comparación para comparar de forma natural y eficaz sus homólogos en la biblioteca estándar de C++. Además, incluye todo lo que necesita para usar hstring como clave para contenedores asociativos.
Reconocemos que muchas bibliotecas de C++ usan std::string y funcionan exclusivamente con texto UTF-8. Como comodidad, proporcionamos asistentes, como winrt::to_string y winrt::to_hstring, para convertir hacia atrás y hacia adelante.
WINRT_ASSERT es una definición de macro y se expande a _ASSERTE.
winrt::hstring w{ L"Hello, World!" };
std::string c = winrt::to_string(w);
WINRT_ASSERT(c == "Hello, World!");
w = winrt::to_hstring(c);
WINRT_ASSERT(w == L"Hello, World!");
Para obtener más ejemplos e información sobre las funciones y operadores de hstring , consulta el tema de referencia de la API winrt::hstring .
La justificación de winrt::hstring y winrt::param::hstring
El Windows Runtime se implementa en términos de caracteres de wchar_t, pero la interfaz binaria de aplicaciones (ABI) del Windows Runtime no es un subconjunto de lo que proporcionan std::wstring o std::wstring_view. El uso de estos provocaría una ineficacia significativa. En su lugar, C++/WinRT proporciona winrt::hstring, que representa una cadena inmutable coherente con el HSTRING subyacente e implementada detrás de una interfaz similar a la de std::wstring.
Es posible que observe que los parámetros de entrada de C++/WinRT que lógicamente deberían aceptar winrt::hstring en realidad esperan winrt::param::hstring. El espacio de nombres param contiene un conjunto de tipos usados exclusivamente para optimizar los parámetros de entrada para enlazar naturalmente a tipos de biblioteca estándar de C++ y evitar copias y otras ineficiencias. No se recomienda usar estos tipos directamente. Si desea usar una optimización para sus propias funciones, use std::wstring_view. Consulte también Pasar parámetros al límite de ABI.
La conclusión es que puedes ignorar en gran medida los detalles de la administración de cadenas de Windows Runtime y simplemente trabajar eficazmente con lo que ya conoces. Y eso es importante, dada la gran cantidad de cadenas que se usan en el Windows Runtime.
Formato de cadenas
Una opción para el formato de cadena es std::wostringstream. Este es un ejemplo que da formato y muestra un mensaje de seguimiento de depuración simple.
#include <sstream>
#include <winrt/Microsoft.UI.Input.h>
#include <winrt/Microsoft.UI.Xaml.Input.h>
...
void MainPage::OnPointerPressed(winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const& e)
{
winrt::Windows::Foundation::Point const point{ e.GetCurrentPoint(nullptr).Position() };
std::wostringstream wostringstream;
wostringstream << L"Pointer pressed at (" << point.X << L"," << point.Y << L")" << std::endl;
::OutputDebugString(wostringstream.str().c_str());
}
La manera correcta de establecer una propiedad
Puede establecer una propiedad pasando un valor a una función de asignación. Este es un ejemplo.
// The right way to set the Text property.
myTextBlock.Text(L"Hello!");
El código siguiente es incorrecto. Compila, pero no hace más que modificar el winrt::hstring temporal devuelto por la función de acceso Text() y luego descartar el resultado.
// *Not* the right way to set the Text property.
myTextBlock.Text() = L"Hello!";