Remarque
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.
Cette rubrique montre comment consommer des API C++/WinRT, qu'elles font partie de Windows, implémentées par un fournisseur de composants tiers ou implémentées par vous-même.
Important
Pour que les exemples de code de cette rubrique soient courts et faciles à essayer, vous pouvez les reproduire en créant un projet d’application console (C++/WinRT) Windows et en collant du code. Toutefois, vous ne pouvez pas utiliser de types Windows Runtime personnalisés arbitraires (tiers) à partir d'une application non empaquetée comme celle-ci. Vous ne pouvez utiliser que des types Windows de cette manière.
Pour consommer des types Windows Runtime personnalisés (de tiers) à partir d'une application de console, vous devez donner à l'application une identité de package afin qu'elle puisse résoudre l'enregistrement des types personnalisés consommés. Pour plus d’informations, consultez Windows Application Packaging Project.
Vous pouvez également créer un projet à partir des modèles de projet Application vierge empaquetée (WinUI 3 in Desktop) pour C++ ou Composant Windows Runtime (C++/WinRT). Ces types d’applications ont déjà une identité de package.
Si l’API se trouve dans un espace de noms Windows
Il s'agit du cas le plus courant dans lequel vous utiliserez une API Windows Runtime. Pour chaque type d’un espace de noms Windows défini dans les métadonnées, C++/WinRT définit un équivalent convivial C++(appelé type projeté). Un type projeté a le même nom complet que le type Windows, mais il est placé dans l'espace de noms winrt C++ à l'aide de la syntaxe C++. Par exemple, Windows ::Foundation ::Uri est projeté en C++/WinRT en tant que winrt ::Windows ::Foundation ::Uri.
Voici un exemple de code simple. Si vous souhaitez copier-coller les exemples de code suivants directement dans le fichier de code source principal d’un projet d’application console Windows (C++/WinRT), commencez par définir Not Using Not Using Precompiled Headers in project properties.
// main.cpp
#include <winrt/Windows.Foundation.h>
using namespace winrt;
using namespace Windows::Foundation;
int main()
{
winrt::init_apartment();
Uri contosoUri{ L"http://www.contoso.com" };
Uri combinedUri = contosoUri.CombineUri(L"products");
}
L’en-tête winrt/Windows.Foundation.h inclus fait partie du Kit de développement logiciel (SDK), trouvé dans le dossier %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt\. Les fichiers d’en-tête de ce dossier contiennent des types d’espace de noms Windows projetés dans C++/WinRT. Dans cet exemple, winrt/Windows.Foundation.h contient winrt ::Windows ::Foundation ::Uri, qui est le type projeté pour la classe runtime Windows ::Foundation ::Uri.
Tip
Chaque fois que vous souhaitez utiliser un type à partir d’un espace de noms Windows, incluez l’en-tête C++/WinRT correspondant à cet espace de noms. Les using namespace directives sont facultatives, mais pratiques.
Dans l’exemple de code ci-dessus, après avoir initialisé C++/WinRT, nous allouons sur la pile une valeur du type projeté winrt::Windows::Foundation::Uri à l’aide de l’un de ses constructeurs publics documentés (Uri(String), dans cet exemple). Dans ce cas, qui est le plus courant, c’est généralement tout ce que vous avez à faire. Une fois que vous avez une valeur de type projetée C++/WinRT, vous pouvez le traiter comme s’il s’agissait d’une instance du type Windows Runtime réel, car il a tous les mêmes membres.
En fait, cette valeur projetée est un proxy ; il s’agit essentiellement d’un pointeur intelligent vers un objet de stockage. Le ou les constructeurs de la valeur projetée appellent RoActivateInstance pour créer une instance de la classe Windows Runtime sous-jacente (Windows.Foundation.Uri, dans ce cas), et stockent l’interface par défaut de cet objet dans la nouvelle valeur projetée. Comme illustré ci-dessous, vos appels aux membres de la valeur projetée sont en fait délégués, via le pointeur intelligent, à l’objet sous-jacent, là où les modifications d’état se produisent.
Lorsque contosoUri sort de la portée, la valeur est détruite et libère sa référence à l’interface par défaut. Si cette référence est la dernière référence à l’objet Windows.Foundation.Uri Windows Runtime sous-jacent, l’objet sous-jacent est également détruit.
Tip
Un type projeté est un encapsuleur autour d’un type Windows Runtime, destiné à permettre l’utilisation de ses API. Par exemple, une interface projetée est un wrapper sur une interface Windows Runtime.
En-têtes de projection C++/WinRT
Pour utiliser les API de l’espace de noms Windows à partir de C++/WinRT, vous incluez les fichiers d’en-tête du dossier %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt. Vous devez inclure les en-têtes correspondant à chaque espace de noms que vous utilisez.
Par exemple, pour l’espace de noms Windows ::Security ::Cryptography ::Certificates, les définitions de type C++/WinRT équivalentes résident dans winrt/Windows.Security.Cryptography.Certificates.h. L’inclusion de cet en-tête vous donne accès à tous les types de l’espace de noms Windows ::Security ::Cryptography ::Certificates.
Parfois, un en-tête d’espace de noms inclut des parties d’en-têtes d’espace de noms associés, mais vous ne devez pas vous appuyer sur ce détail d’implémentation. Incluez explicitement les fichiers d’en-tête pour les espaces de noms que vous utilisez.
Par exemple, la méthode Certificate ::GetCertificateBlob retourne une interface Windows ::Storage ::Streams ::IBuffer.
Avant d’appeler la méthode Certificate ::GetCertificateBlob, vous devez inclure le winrt/Windows.Storage.Streams.h fichier d’en-tête d’espace de noms pour vous assurer que vous pouvez recevoir et utiliser les Windows ::Storage ::Streams ::IBuffer retournés.
Oublier d’inclure les fichiers d’en-tête requis avant d’utiliser des types dans ce même espace de noms est une cause fréquente d’erreurs de compilation.
Accès aux membres via l’objet, via une interface ou via l’ABI
Avec la projection C++/WinRT, la représentation à l’exécution d’une classe Windows Runtime n’est rien de plus que les interfaces ABI sous-jacentes. Mais, pour plus de simplicité, vous pouvez programmer en utilisant les classes comme leur auteur l’avait prévu. Par exemple, vous pouvez appeler la méthode ToString d’un Uri comme s’il s’agissait d’une méthode de la classe (en fait, sous les couvertures, il s’agit d’une méthode sur l’interface IStringable distincte).
WINRT_ASSERT est une définition de macro, et elle s’étend à _ASSERTE.
Uri contosoUri{ L"http://www.contoso.com" };
WINRT_ASSERT(contosoUri.ToString() == L"http://www.contoso.com/"); // QueryInterface is called at this point.
Cette commodité est obtenue via une requête pour l’interface appropriée. Mais tu es toujours en contrôle. Vous pouvez choisir de donner un peu de cette commodité pour un peu de performances en récupérant vous-même l’interface IStringable et en l’utilisant directement. Dans l’exemple de code ci-dessous, vous obtenez un pointeur d’interface IStringable réel au moment de l’exécution (via une requête unique). Après cela, votre appel à ToString est direct et évite tout autre appel à QueryInterface.
...
IStringable stringable = contosoUri; // One-off QueryInterface.
WINRT_ASSERT(stringable.ToString() == L"http://www.contoso.com/");
Vous pouvez choisir cette technique si vous savez que vous appelez plusieurs méthodes sur la même interface.
Au passage, si vous souhaitez accéder aux membres au niveau de l’ABI, vous le pouvez. L’exemple de code ci-dessous montre comment et il existe plus de détails et d’exemples de code dans Interop entre C++/WinRT et l’ABI.
#include <Windows.Foundation.h>
#include <unknwn.h>
#include <winrt/Windows.Foundation.h>
using namespace winrt::Windows::Foundation;
int main()
{
winrt::init_apartment();
Uri contosoUri{ L"http://www.contoso.com" };
int port{ contosoUri.Port() }; // Access the Port "property" accessor via C++/WinRT.
winrt::com_ptr<ABI::Windows::Foundation::IUriRuntimeClass> abiUri{
contosoUri.as<ABI::Windows::Foundation::IUriRuntimeClass>() };
HRESULT hr = abiUri->get_Port(&port); // Access the get_Port ABI function.
}
Initialisation différée
Dans C++/WinRT, chaque type projeté a un constructeur spécial C++/WinRT std ::nullptr_t . À l’exception de ce dernier, tous les constructeurs des types projetés — y compris le constructeur par défaut — entraînent la création d’un objet Windows Runtime sous-jacent et vous fournissent un pointeur intelligent vers celui-ci. Ainsi, cette règle s’applique partout où le constructeur par défaut est utilisé, comme les variables locales non initialisées, les variables globales non initialisées et les variables membres non initialisées.
Si, d’autre part, vous souhaitez construire une variable d’un type projeté sans qu’elle construise à son tour un objet de stockage Windows Runtime (pour que vous puissiez retarder ce travail jusqu’à la fin), vous pouvez le faire. Déclarez votre variable ou votre champ à l’aide de ce constructeur spécial C++/WinRT std ::nullptr_t (que la projection C++/WinRT injecte dans chaque classe runtime). Nous utilisons ce constructeur spécial avec m_gamerPicBuffer dans l’exemple de code ci-dessous.
#include <winrt/Windows.Storage.Streams.h>
using namespace winrt::Windows::Storage::Streams;
#define MAX_IMAGE_SIZE 1024
struct Sample
{
void DelayedInit()
{
// Allocate the actual buffer.
m_gamerPicBuffer = Buffer(MAX_IMAGE_SIZE);
}
private:
Buffer m_gamerPicBuffer{ nullptr };
};
int main()
{
winrt::init_apartment();
Sample s;
// ...
s.DelayedInit();
}
Tous les constructeurs du type projeté à l’exception du constructeur std ::nullptr_t provoquent la création d’un objet de stockage Windows Runtime. Le constructeur std ::nullptr_t est essentiellement un no-op. Il s’attend à ce que l’objet projeté soit initialisé à un moment ultérieur. Par conséquent, si une classe runtime a un constructeur par défaut ou non, vous pouvez utiliser cette technique pour une initialisation différée efficace.
Cette considération affecte d’autres endroits où vous appelez le constructeur par défaut, tel que dans les vecteurs et les cartes. Considérez cet exemple de code pour lequel vous aurez besoin d’une application vide, empaquetée (WinUI 3 dans Desktop) pour un projet C++.
std::map<int, TextBlock> lookup;
lookup[2] = value;
L’affectation crée un TextBlock, puis le remplace immédiatement avec value. Voici le remède.
std::map<int, TextBlock> lookup;
lookup.insert_or_assign(2, value);
Consultez également comment le constructeur par défaut affecte les collections.
N’effectuez pas une initialisation tardive par erreur
Veillez à ne pas appeler le constructeur std ::nullptr_t par erreur. La résolution des conflits du compilateur le favorise par rapport aux constructeurs d’usine. Par exemple, considérez ces deux définitions de classe runtime.
// GiftBox.idl
runtimeclass GiftBox
{
GiftBox();
}
// Gift.idl
runtimeclass Gift
{
Gift(GiftBox giftBox); // You can create a gift inside a box.
}
Supposons que nous voulons construire un cadeau qui n’est pas à l’intérieur d’une boîte (un cadeau construit avec un GiftBox non initialisé). Tout d’abord, examinons la mauvaise façon de le faire. Nous savons qu’il existe un constructeur Gift qui accepte un GiftBox. Mais si nous sommes tentés de passer un GiftBox null (en appelant le constructeur Gift via l’initialisation uniforme, comme nous le faisons ci-dessous), nous n’obtiendrons pas le résultat souhaité.
// These are *not* what you intended. Doing it in one of these two ways
// actually *doesn't* create the intended backing Windows Runtime Gift object;
// only an empty smart pointer.
Gift gift{ nullptr };
auto gift{ Gift(nullptr) };
Ce que vous obtenez ici est un cadeau non initialisé. Vous n’obtenez pas de cadeau avec un GiftBox non initialisé. Voici la bonne façon de le faire.
// Doing it in one of these two ways creates an initialized
// Gift with an uninitialized GiftBox.
Gift gift{ GiftBox{ nullptr } };
auto gift{ Gift(GiftBox{ nullptr }) };
Dans l’exemple incorrect, le fait de passer un littéral nullptr conduit à choisir le constructeur à initialisation différée. Pour résoudre en faveur du constructeur d’usine, le type du paramètre doit être un GiftBox. Vous avez toujours la possibilité de passer un GiftBox dont l’initialisation est explicitement différée, comme indiqué dans l’exemple correct.
Cet exemple suivant est également correct, car le paramètre a le type GiftBox et non std ::nullptr_t.
GiftBox giftBox{ nullptr };
Gift gift{ giftBox }; // Calls factory constructor.
C’est seulement lorsque vous passez un nullptr littéral que l’ambiguïté apparaît.
Ne pas copier-construire par erreur.
Cette prudence est similaire à celle décrite dans la section Ne pas retarder l’initialisation par erreur ci-dessus.
Outre le constructeur d’initialisation différée, la projection C++/WinRT injecte également un constructeur de copie dans chaque classe runtime. Il s’agit d’un constructeur à paramètre unique qui accepte le même type que l’objet en cours de construction. Le pointeur intelligent résultant pointe vers le même objet Windows Runtime sous-jacent que celui pointé par le paramètre de son constructeur. Le résultat est deux objets pointeurs intelligents pointant vers le même objet de stockage.
Voici une définition de classe runtime que nous allons utiliser dans les exemples de code.
// GiftBox.idl
runtimeclass GiftBox
{
GiftBox(GiftBox biggerBox); // You can place a box inside a bigger box.
}
Supposons que nous voulons construire un GiftBox à l’intérieur d’un GiftBox plus grand.
GiftBox bigBox{ ... };
// These are *not* what you intended. Doing it in one of these two ways
// copies bigBox's backing-object-pointer into smallBox.
// The result is that smallBox == bigBox.
GiftBox smallBox{ bigBox };
auto smallBox{ GiftBox(bigBox) };
La bonne façon de le faire consiste à appeler explicitement la fabrique d’activation.
GiftBox bigBox{ ... };
// These two ways call the activation factory explicitly.
GiftBox smallBox{
winrt::get_activation_factory<GiftBox, IGiftBoxFactory>().CreateInstance(bigBox) };
auto smallBox{
winrt::get_activation_factory<GiftBox, IGiftBoxFactory>().CreateInstance(bigBox) };
Si l’API est implémentée dans un composant Windows Runtime
Cette section s’applique si vous avez créé le composant vous-même ou s’il provient d’un fournisseur.
Note
Pour plus d’informations sur l’installation et l’utilisation de l’extension Visual Studio C++/WinRT (VSIX) et du package NuGet (qui fournissent ensemble un modèle de projet et une prise en charge de build), consultez Visual Studio prise en charge de C++/WinRT.
Dans votre projet d'application, ajoutez une référence au fichier de métadonnées Windows Runtime (.winmd) du composant Windows Runtime, puis générez le projet. Pendant la génération, l’outil cppwinrt.exe génère une bibliothèque C++ standard qui décrit intégralement — ou projette — la surface de l’API du composant. En d’autres termes, la bibliothèque générée contient les types projetés pour le composant.
Ensuite, comme pour un type d’espace de noms Windows, vous incluez un en-tête et construisez le type projeté via l’un de ses constructeurs. Le code de démarrage de votre projet d’application inscrit la classe runtime, et le constructeur du type projeté appelle RoActivateInstance pour activer la classe runtime à partir du composant référencé.
#include <winrt/ThermometerWRC.h>
struct App : AppT<App>
{
ThermometerWRC::Thermometer thermometer;
...
};
Pour plus d’informations, du code et une présentation pas à pas de l’utilisation d’API implémentées dans un composant Windows Runtime, consultez Composants Windows Runtime avec C++/WinRT et Créer des événements dans C++/WinRT.
Si l’API est implémentée dans le projet consommateur
L’exemple de code de cette section est extrait des contrôles XAML de la rubrique ; liaison à une propriété C++/WinRT. Pour plus d’informations, de code et pour obtenir une procédure pas à pas sur l’utilisation d’une classe runtime implémentée dans le même projet que celui qui l’utilise, consultez cette rubrique.
Un type consommé à partir de l’interface utilisateur XAML doit être une classe runtime, même s’il se trouve dans le même projet que le code XAML. Pour ce scénario, vous générez un type projeté à partir des métadonnées Windows Runtime de la classe runtime (.winmd). Là encore, vous incluez un en-tête, mais vous avez le choix entre les méthodes C++/WinRT version 1.0 ou version 2.0 de construction de l’instance de la classe runtime. La méthode version 1.0 utilise winrt ::make ; la méthode version 2.0 est appelée construction uniforme. Examinons chacun à son tour.
Construction à l’aide de winrt ::make
Commençons par la méthode par défaut (C++/WinRT version 1.0), car il est judicieux d’être au moins familiarisé avec ce modèle. Vous construisez le type projeté via son constructeur std ::nullptr_t . Ce constructeur n’effectue aucune initialisation. Vous devez donc ensuite affecter une valeur à l’instance via la fonction winrt ::make helper, en passant les arguments de constructeur nécessaires. Une classe d’exécution implémentée dans le même projet que le code appelant n’a pas besoin d’être enregistrée ni d’être instanciée via l’activation Windows Runtime/COM.
Voir Contrôles XAML ; lier à une propriété C++/WinRT pour une présentation détaillée. Cette section présente les extraits de cette procédure pas à pas.
// MainPage.idl
import "BookstoreViewModel.idl";
namespace Bookstore
{
runtimeclass MainPage : Microsoft.UI.Xaml.Controls.Page
{
BookstoreViewModel MainViewModel{ get; };
}
}
// MainPage.h
...
struct MainPage : MainPageT<MainPage>
{
...
private:
Bookstore::BookstoreViewModel m_mainViewModel{ nullptr };
};
...
// MainPage.cpp
...
#include "BookstoreViewModel.h"
MainPage::MainPage()
{
m_mainViewModel = winrt::make<Bookstore::implementation::BookstoreViewModel>();
...
}
Construction uniforme
Avec C++/WinRT version 2.0 et ultérieure, il existe une forme optimisée de construction disponible pour vous, appelée construction uniforme (voir Actualités et modifications, en C++/WinRT 2.0).
Voir Contrôles XAML ; lier à une propriété C++/WinRT pour un guide pas à pas complet. Cette section présente les extraits de cette procédure pas à pas.
Pour utiliser la construction uniforme au lieu de winrt ::make, vous aurez besoin d’une fabrique d’activation. Une bonne façon d’en générer un consiste à ajouter un constructeur à votre IDL.
// MainPage.idl
import "BookstoreViewModel.idl";
namespace Bookstore
{
runtimeclass MainPage : Microsoft.UI.Xaml.Controls.Page
{
MainPage();
BookstoreViewModel MainViewModel{ get; };
}
}
Ensuite, dans MainPage.h déclarer et initialiser m_mainViewModel en une seule étape, comme indiqué ci-dessous.
// MainPage.h
...
struct MainPage : MainPageT<MainPage>
{
...
private:
Bookstore::BookstoreViewModel m_mainViewModel;
...
};
}
...
Et puis, dans le constructeur MainPage dans MainPage.cpp, il n’y a pas besoin du code m_mainViewModel = winrt::make<Bookstore::implementation::BookstoreViewModel>();.
Pour plus d’informations sur la construction uniforme et les exemples de code, consultez Opt in to uniform construction, and direct implementation access.
Instanciation et renvoi de types et d’interfaces projetés
Voici un exemple de ce à quoi peuvent ressembler les types et interfaces projetés dans votre projet client. N’oubliez pas qu’un type projeté (tel que celui de cet exemple) est généré par les outils et n’est pas quelque chose que vous créez vous-même.
struct MyRuntimeClass : MyProject::IMyRuntimeClass, impl::require<MyRuntimeClass,
Windows::Foundation::IStringable, Windows::Foundation::IClosable>
MyRuntimeClass est un type projeté ; les interfaces projetées incluent IMyRuntimeClass, IStringable et IClosable. Cette rubrique a montré les différentes façons dont vous pouvez instancier un type projeté. Voici un rappel et un résumé, à l’aide de MyRuntimeClass comme exemple.
// The runtime class is implemented in another compilation unit (it's either a Windows API,
// or it's implemented in a second- or third-party component).
MyProject::MyRuntimeClass myrc1;
// The runtime class is implemented in the same compilation unit.
MyProject::MyRuntimeClass myrc2{ nullptr };
myrc2 = winrt::make<MyProject::implementation::MyRuntimeClass>();
- Vous pouvez accéder aux membres de toutes les interfaces d’un type projeté.
- Vous pouvez retourner un type projeté à un appelant.
- Les types et interfaces projetés dérivent de winrt ::Windows ::Foundation ::IUnknown. Ainsi, vous pouvez appeler IUnknown::as sur un type ou une interface projetés pour interroger d’autres interfaces projetées, que vous pouvez également utiliser ou renvoyer à l’appelant. La fonction membre as fonctionne comme QueryInterface.
void f(MyProject::MyRuntimeClass const& myrc)
{
myrc.ToString();
myrc.Close();
IClosable iclosable = myrc.as<IClosable>();
iclosable.Close();
}
Usines d’activation
Le moyen pratique et direct de créer un objet C++/WinRT est le suivant.
using namespace winrt::Windows::Globalization::NumberFormatting;
...
CurrencyFormatter currency{ L"USD" };
Mais il peut arriver que vous souhaitiez créer vous-même la fabrique d’activation, puis créer des objets à partir de celui-ci à votre convenance. Voici quelques exemples montrant comment utiliser le modèle de fonction winrt ::get_activation_factory .
using namespace winrt::Windows::Globalization::NumberFormatting;
...
auto factory = winrt::get_activation_factory<CurrencyFormatter, ICurrencyFormatterFactory>();
CurrencyFormatter currency = factory.CreateCurrencyFormatterCode(L"USD");
using namespace winrt::Windows::Foundation;
...
auto factory = winrt::get_activation_factory<Uri, IUriRuntimeClassFactory>();
Uri uri = factory.CreateUri(L"http://www.contoso.com");
Les classes des deux exemples ci-dessus sont des types d’un espace de noms Windows. Dans cet exemple suivant, ThermometerWRC ::Thermometer est un type personnalisé implémenté dans un composant Windows Runtime.
auto factory = winrt::get_activation_factory<ThermometerWRC::Thermometer>();
ThermometerWRC::Thermometer thermometer = factory.ActivateInstance<ThermometerWRC::Thermometer>();
Ambiguïtés entre membre et type
Lorsqu’une fonction membre a le même nom qu’un type, il y a ambiguïté. Les règles de recherche non qualifiée de noms en C++ dans les fonctions membres font que la recherche s’effectue d’abord dans la classe avant de s’effectuer dans les espaces de noms. La règle « l’échec de substitution n’est pas une erreur » (SFINAE) ne s’applique pas (elle s’applique lors de la résolution de surcharge des modèles de fonctions). Par conséquent, si le nom à l’intérieur de la classe n’a pas de sens, le compilateur ne continue pas à rechercher une meilleure correspondance, il signale simplement une erreur.
struct MyPage : Page
{
void DoWork()
{
// This doesn't compile. You get the error
// "'winrt::Windows::Foundation::IUnknown::as':
// no matching overloaded function found".
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<Style>() };
}
}
Ci-dessus, le compilateur pense que vous passez FrameworkElement.Style() (qui, en C++/WinRT, est une fonction membre) comme paramètre de modèle à IUnknown ::as. La solution consiste à forcer le nom Style à interpréter comme le type Microsoft ::UI ::Xaml ::Style.
struct MyPage : Page
{
void DoWork()
{
// One option is to fully-qualify it.
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<Microsoft::UI::Xaml::Style>() };
// Another is to force it to be interpreted as a struct name.
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<struct Style>() };
// If you have "using namespace Windows::UI;", then this is sufficient.
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<Xaml::Style>() };
// Or you can force it to be resolved in the global namespace (into which
// you imported the Microsoft::UI::Xaml namespace when you did
// "using namespace Microsoft::UI::Xaml;".
auto style = Application::Current().Resources().
Lookup(L"MyStyle").as<::Style>();
}
}
La recherche de noms non qualifiée comporte une exception particulière lorsque le nom est suivi de ::, auquel cas la recherche ignore les fonctions, les variables et les valeurs d’énumération. Cela vous permet de faire des choses comme cela.
struct MyPage : Page
{
void DoSomething()
{
Visibility(Visibility::Collapsed); // No ambiguity here (special exception).
}
}
L’appel à Visibility() se résout en nom de la fonction membre UIElement.Visibility. Mais le paramètre Visibility::Collapsed suit le mot Visibility avec ::, et donc le nom de la méthode est ignoré, et le compilateur recherche la classe enum.
API importantes
- QueryInterface, fonction
- Fonction RoActivateInstance
- classe Windows::Foundation::Uri
- modèle de fonction `winrt::get_activation_factory`
- modèle de fonction winrt ::make
- winrt ::Windows ::Foundation ::IUnknown struct
Rubriques connexes
Windows developer