Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Avec C++/WinRT, vous pouvez appeler des API Windows Runtime à l’aide de types de chaînes larges de la bibliothèque standard C++ comme std::wstring (remarque : pas avec des types de chaîne étroits comme std::string). C++/WinRT a un type de chaîne personnalisé appelé winrt ::hstring (défini dans la bibliothèque de base C++/WinRT, autrement dit %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h
). Et c’est le type de chaîne que les constructeurs, fonctions et propriétés Windows Runtime prennent et retournent réellement. Toutefois, dans de nombreux cas, grâce aux constructeurs de conversion et opérateurs de conversion de hstring, vous pouvez choisir si vous souhaitez être conscient de hstring dans votre code client. Si vous création d’API, il est plus probable que vous deviez connaître hstring.
Il existe de nombreux types de chaînes en C++. Les variantes existent dans de nombreuses bibliothèques en plus de std ::basic_string de la bibliothèque C++ Standard. C++17 a des utilitaires de conversion de chaîne et std ::basic_string_view, pour combler les écarts entre tous les types de chaînes. winrt::hstring permet une convertibilité avec std::wstring_view afin d'assurer l’interopérabilité pour laquelle std::basic_string_view a été conçu.
Utilisation de std::wstring (et éventuellement winrt::hstring) avec Uri
Windows::Foundation::Uri est construit à partir d’un winrt::hstring.
public:
Uri(winrt::hstring uri) const;
Mais hstring a des constructeurs de conversion qui vous permettent de travailler avec lui sans avoir besoin de le savoir. Voici un exemple de code montrant comment créer un uri à partir d’un littéral de chaîne large, d’une vue de chaîne large et d’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 };
}
L’accesseur de propriété Uri::Domain est de type hstring.
public:
winrt::hstring Domain();
Mais, encore une fois, sachez que ce détail est facultatif grâce à 'opérateur de conversion de en 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"
De même, IStringable ::ToString retourne hstring .
public:
hstring ToString() const;
Uri implémente l’interface 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/"
Vous pouvez utiliser la fonction hstring ::c_str pour obtenir une chaîne large standard à partir d’une chaîne hstring (comme vous pouvez à partir d’un std ::wstring).
#include <iostream>
std::wcout << tostringHstring.c_str() << std::endl;
Si vous avez une chaîne hstring , vous pouvez créer un URI à partir de celui-ci.
Uri awUriFromHstring{ tostringHstring };
Pensez à une fonction qui prend un hstring.
public:
Uri CombineUri(winrt::hstring relativeUri) const;
Toutes les options que vous venez de voir s’appliquent également dans ce cas.
std::wstring contact{ L"contact" };
contosoUri = contosoUri.CombineUri(contact);
std::wcout << contosoUri.ToString().c_str() << std::endl;
hstring a un membre opérateur de conversion std ::wstring_view, et la conversion est obtenue sans coût.
void legacy_print(std::wstring_view view);
void Print(winrt::hstring const& hstring)
{
legacy_print(hstring);
}
fonctions et opérateurs winrt ::hstring
Un ensemble de constructeurs, d’opérateurs, de fonctions et d’itérateurs est implémenté pour winrt::hstring.
Un hstring est une plage, vous pouvez donc l'utiliser avec for
basés sur des plages ou avec std::for_each
. Il fournit également des opérateurs de comparaison pour comparer naturellement et efficacement ses équivalents dans la bibliothèque C++ Standard. Il inclut tout ce dont vous avez besoin pour utiliser hstring comme clé pour les conteneurs associatifs.
Nous reconnaissons que de nombreuses bibliothèques C++ utilisent std ::string et fonctionnent exclusivement avec du texte UTF-8. En guise de commodité, nous fournissons des outils, tels que winrt::to_string et winrt::to_hstring, pour la conversion dans les deux sens.
WINRT_ASSERT
est une définition de macro, et elle s’étend à _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!");
Pour plus d'exemples et d'informations sur les fonctions et opérateurs hstring de , consultez la section de référence de l'API winrt::hstring.
Justification de winrt::hstring et winrt::param::hstring
Le Windows Runtime est implémenté en termes de caractères wchar_t, mais l'interface binaire d'application (ABI) de Windows Runtime ne constitue pas un sous-ensemble de ce que fournissent soit std::wstring, soit std::wstring_view. L’utilisation de ces éléments entraînerait une inefficacité importante. Au lieu de cela, C++/WinRT fournit winrt ::hstring, qui représente une chaîne immuable cohérente avec le HSTRING sous-jacent et implémentée derrière une interface similaire à celle de std ::wstring.
Vous remarquerez peut-être que les paramètres d’entrée C++/WinRT qui devraient logiquement accepter winrt::hstring attendent réellement winrt::param::hstring. L’espace de noms param contient un ensemble de types utilisés exclusivement pour optimiser les paramètres d’entrée afin de permettre une liaison naturelle avec les types de la Bibliothèque Standard C++ et d'éviter les copies et autres inefficacités. Vous ne devez pas utiliser ces types directement. Si vous souhaitez utiliser une optimisation pour vos propres fonctions, utilisez std ::wstring_view. Consultez également Passage de paramètres dans la limite ABI.
Le résultat est que vous pouvez en grande partie ignorer les spécificités de la gestion des chaînes Windows Runtime, et travailler efficacement avec ce que vous savez. Et c’est important, étant donné la façon dont les chaînes sont utilisées dans Windows Runtime.
Chaînes de mise en forme
Une option pour la mise en forme de chaîne est std ::wostringstream. Voici un exemple qui met en forme et affiche un message de trace de débogage simple.
#include <sstream>
#include <winrt/Windows.UI.Input.h>
#include <winrt/Windows.UI.Xaml.Input.h>
...
void MainPage::OnPointerPressed(winrt::Windows::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 bonne façon de définir une propriété
Vous définissez une propriété en transmettant une valeur à une fonction setter. Voici un exemple.
// The right way to set the Text property.
myTextBlock.Text(L"Hello!");
Le code ci-dessous est incorrect. Cela compile, mais cela consiste uniquement à modifier la variable temporaire winrt::hstring retournée par la fonction accesseur Text(), puis à jeter le résultat.
// *Not* the right way to set the Text property.
myTextBlock.Text() = L"Hello!";