Héberger un contrôle XAML WinRT personnalisé dans une application Win32 C++Host a custom WinRT XAML control in a C++ Win32 app

Cet article explique comment utiliser l’API d’hébergement XAML UWP pour héberger un contrôle XAML UWP personnalisé dans une nouvelle application Win32 C++.This article demonstrates how to use the UWP XAML hosting API to host a custom UWP XAML control in a new C++ Win32 app. Si vous disposez déjà d’un projet d’application Win32 C++, vous pouvez adapter ces étapes et exemples de code à votre projet.If you have an existing C++ Win32 app project, you can adapt these steps and code examples for your project.

Pour héberger un contrôle XAML UWP personnalisé, vous allez créer les projets et composants suivants dans le cadre de cette procédure pas à pas :To host a custom UWP XAML control, you'll create the following projects and components as part of this walkthrough:

  • Projet d’application de bureau Windows.Windows Desktop Application project. Ce projet implémente une application de bureau Win32 C++ native.This project implements a native C++ Win32 desktop app. Vous allez ajouter du code à ce projet qui utilise l’API d’hébergement XAML UWP pour héberger un contrôle XAML UWP personnalisé.You'll add code to this project that uses the UWP XAML hosting API to host a custom UWP XAML control.

  • Projet d’application UWP (C++/WinRT) .UWP app project (C++/WinRT). Ce projet implémente un contrôle XAML UWP personnalisé.This project implements a custom UWP XAML control. Il implémente également un fournisseur de métadonnées racine pour le chargement de métadonnées pour les types XAML UWP personnalisés dans le projet.It also implements a root metadata provider for loading metadata for custom UWP XAML types in the project.

Conditions requisesRequirements

  • Visual Studio 2019 version 16.4.3 ou ultérieure.Visual Studio 2019 version 16.4.3 or later.
  • Windows 10, SDK version 1903 (version 10.0.18362) ou ultérieure.Windows 10, version 1903 SDK (version 10.0.18362) or later.
  • Extension Visual Studio C++/WinRT (VSIX) installée avec Visual Studio.C++/WinRT Visual Studio Extension (VSIX) installed with Visual Studio. C++/WinRT est une projection de langage C++17 moderne entièrement standard pour les API Windows Runtime (WinRT), implémentée en tant que bibliothèque basée sur un fichier d’en-tête et conçue pour vous fournir un accès de première classe à l’API Windows moderne.C++/WinRT is an entirely standard modern C++17 language projection for Windows Runtime (WinRT) APIs, implemented as a header-file-based library, and designed to provide you with first-class access to the modern Windows API. Pour plus d’informations, voir C++/WinRT.For more information, see C++/WinRT.

Créer un projet d'application de bureauCreate a desktop application project

  1. Dans Visual Studio, créez un projet Application de bureau Windows nommé MyDesktopWin32App.In Visual Studio, create a new Windows Desktop Application project named MyDesktopWin32App. Ce modèle de projet est disponible sous les filtres de projet C++ , Windows et Desktop.This project template is available under the C++ , Windows , and Desktop project filters.

  2. Dans l’ Explorateur de solutions , cliquez avec le bouton droit sur le nœud de la solution, cliquez sur Recibler la solution , sélectionnez la version 10.0.18362.0 ou une version ultérieure du kit de développement logiciel (SDK), puis cliquez sur OK.In Solution Explorer , right-click the solution node, click Retarget solution , select the 10.0.18362.0 or a later SDK release, and then click OK.

  3. Installez le package NuGet Microsoft.Windows.CppWinRT pour activer la prise en charge de C++/WinRT dans votre projet :Install the Microsoft.Windows.CppWinRT NuGet package to enable support for C++/WinRT in your project:

    1. Cliquez avec le bouton droit sur le projet MyDesktopWin32App dans Explorateur de solutions , puis choisissez Gérer les packages NuGet.Right-click the MyDesktopWin32App project in Solution Explorer and choose Manage NuGet Packages.
    2. Sélectionnez l’onglet Parcourir , recherchez le package Microsoft.Windows.CppWinRT, installez la version la plus récente de ce package.Select the Browse tab, search for the Microsoft.Windows.CppWinRT package, and install the latest version of this package.
  4. Dans la fenêtre Gérer les packages NuGet , installez les packages NuGet supplémentaires suivants :In the Manage NuGet Packages window, install the following additional NuGet packages:

  5. Ajoutez une référence aux métadonnées de Windows Runtime :Add a reference to the Windows Runtime metadata:

    1. Dans l’ Explorateur de solutions , cliquez avec le bouton droit sur le nœud Références de votre projet et sélectionnez Ajouter une référence.In Solution Explorer , right-click on your project References node and select Add Reference.
    2. Cliquez sur le bouton Parcourir en bas de la page et accédez au dossier UnionMetadata dans le chemin d’installation du kit SDK.Click the Browse button at the bottom of the page and navigate to the UnionMetadata folder in your SDK install path. Par défaut, le kit SDK sera installé sur C:\Program Files (x86)\Windows Kits\10\UnionMetadata.By default the SDK will be installed to C:\Program Files (x86)\Windows Kits\10\UnionMetadata.
    3. Ensuite, sélectionnez le dossier nommé d’après la version de Windows que vous ciblez (par exemple, 10.0.18362.0) et à l’intérieur de ce dossier, choisissez le fichier Windows.winmd.Then, select the folder named after the Windows version you are targetting (e.g. 10.0.18362.0) and inside of that folder pick the Windows.winmd file.
    4. Cliquez sur OK pour fermer la boîte de dialogue Ajouter une référence.Click OK to close the Add Reference dialog.
  6. Générez la solution et vérifiez qu’elle est correctement générée.Build the solution and confirm that it builds successfully.

Créer un projet d’application UWPCreate a UWP app project

Ajoutez ensuite un projet d’application UWP (C++/WinRT) à votre solution et apportez des modifications de configuration à ce projet.Next, add a UWP (C++/WinRT) app project to your solution and make some configuration changes to this project. Plus loin dans cette procédure pas à pas, vous ajouterez du code à ce projet pour implémenter un contrôle XAML UWP personnalisé et définir une instance de la classe Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication.Later in this walkthrough, you'll add code to this project to implement a custom UWP XAML control and define an instance of the Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication class.

  1. Dans l’ Explorateur de solutions , cliquez avec le bouton droit sur le nœud de la solution, puis sélectionnez Ajouter -> Nouveau projet.In Solution Explorer , right-click the solution node and select Add -> New Project.

  2. Ajoutez un projet Blank App (C++/WinRT) à votre solution.Add a Blank App (C++/WinRT) project to your solution. Nommez le projet MyUWPApp et assurez-vous que la version cible et la version minimale sont toutes les deux définies sur Windows 10, version 1903 ou ultérieure.Name the project MyUWPApp and make sure the target version and minimum version are both set to Windows 10, version 1903 or later.

  3. Installez le package NuGet Microsoft.Toolkit.Win32.UI.XamlApplication dans le projet MyUWPApp.Install the Microsoft.Toolkit.Win32.UI.XamlApplication NuGet package in the MyUWPApp project. Ce package définit la classe Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication, que vous utiliserez plus tard dans cette procédure pas à pas.This package defines the Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication class, which you will use later in this walkthrough.

    1. Cliquez avec le bouton droit sur le projet MyUWPApp et choisissez Gérer les packages NuGet.Right-click the MyUWPApp project and choose Manage NuGet Packages.
    2. Sélectionnez l’onglet Parcourir , recherchez le package Microsoft.Toolkit.Win32.UI.XamlApplication, puis installez la dernière version stable de ce package.Select the Browse tab, search for the Microsoft.Toolkit.Win32.UI.XamlApplication package, and install the latest stable version of this package.
  4. Cliquez avec le bouton droit sur le nœud MyUWPApp et sélectionnez Propriétés.Right-click the MyUWPApp node and select Properties. Sur la page Propriétés communes -> C++/WinRT , définissez la propriété Verbosité sur normal , puis cliquez sur Appliquer.On the Common Properties -> C++/WinRT page, set the Verbosity property to normal and then click Apply. Lorsque vous avez terminé, la page Propriétés devrait ressembler à ceci.When you are done, the properties page should look like this.

    Propriétés du projet C++/WinRT

  5. Sur la page Propriétés de configuration -> Général de la fenêtre des propriétés, définissez Type de configuration sur Bibliothèque dynamique (.dll) , puis cliquez sur OK pour fermer la fenêtre des propriétés.On the Configuration Properties -> General page of the properties window, set Configuration Type to Dynamic Library (.dll) , and then click OK to close the properties window.

    Propriétés générales du projet

  6. Ajoutez un fichier exécutable d’espace réservé au projet MyUWPApp.Add a placeholder executable file to the MyUWPApp project. Ce fichier exécutable d’espace réservé est requis pour permettre à Visual Studio de créer les fichiers projet nécessaires et de générer correctement le projet.This placeholder executable file is required for Visual Studio to generate the required project files and properly build the project.

    1. Dans Explorateur de solutions , cliquez avec le bouton droit sur le nœud de projet MyUWPApp , puis sélectionnez Ajouter -> Nouvel élément.In Solution Explorer , right-click the MyUWPApp project node and select Add -> New Item.

    2. Dans la boîte de dialogue Ajouter un nouvel élément , sélectionnez Utilitaire dans la page gauche, puis choisissez Fichier texte (.txt) .In the Add New Item dialog, select Utility in the left page, and then select Text File (.txt). Entrez le nom placeholder.exe , puis cliquez sur Ajouter.Enter the name placeholder.exe and click Add. Ajouter un fichier texteAdd text file

    3. Dans Explorateur de solutions , sélectionnez le fichier placeholder.exe.In Solution Explorer , select the placeholder.exe file. Dans la fenêtre Propriétés , assurez-vous que la propriété Contenu est définie sur Vrai.In the Properties window, make sure the Content property is set to True.

    4. Dans Explorateur de solutions , cliquez avec le bouton droit sur le fichier Package.appxmanifest dans le projet MyUWPApp , sélectionnez Ouvrir avec , choisissez Éditeur XML (Texte) , puis cliquez sur OK.In Solution Explorer , right-click the Package.appxmanifest file in the MyUWPApp project, select Open With , and select XML (Text) Editor , and click OK.

    5. Recherchez l’élément <Application> et remplacez l’attribut Exécutable par la valeur placeholder.exe.Find the <Application> element and change the Executable attribute to the value placeholder.exe. Lorsque vous avez terminé, l'élément <Application> devrait ressembler à ceci.When you are done, the <Application> element should look similar to this.

      <Application Id="App" Executable="placeholder.exe" EntryPoint="MyUWPApp.App">
        <uap:VisualElements DisplayName="MyUWPApp" Description="Project for a single page C++/WinRT Universal Windows Platform (UWP) app with no predefined layout"
          Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" BackgroundColor="transparent">
          <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
          </uap:DefaultTile>
          <uap:SplashScreen Image="Assets\SplashScreen.png" />
        </uap:VisualElements>
      </Application>
      
    6. Enregistrez puis fermez le fichier Package.appxmanifest.Save and close the Package.appxmanifest file.

  7. Dans Explorateur de solutions , cliquez avec le bouton droit sur le nœud MyUWPApp , puis sélectionnez Décharger le projet.In Solution Explorer , right-click the MyUWPApp node and select Unload Project.

  8. Cliquez avec le bouton droit sur le nœud MyUWPApp et sélectionnez Modifier MyUWPApp.vcxproj.Right-click the MyUWPApp node and select Edit MyUWPApp.vcxproj.

  9. Recherchez l’élément <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> et remplacez-le par le code XML suivant.Find the <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> element and replace it with the following XML. Ce code XML ajoute plusieurs nouvelles propriétés immédiatement avant l’élément.This XML adds several new properties immediately before the element.

    <PropertyGroup Label="Globals">
        <WindowsAppContainer>true</WindowsAppContainer>
        <AppxGeneratePriEnabled>true</AppxGeneratePriEnabled>
        <ProjectPriIndexName>App</ProjectPriIndexName>
        <AppxPackage>true</AppxPackage>
    </PropertyGroup>
    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
    
  10. Enregistrez et fermez le fichier projet.Save and close the project file.

  11. Dans Explorateur de solutions , cliquez avec le bouton droit sur le nœud MyUWPApp , puis sélectionnez Recharger le projet.In Solution Explorer , right-click the MyUWPApp node and select Reload Project.

Configurer la solutionConfigure the solution

Dans cette section, vous allez mettre à jour la solution qui contient les deux projets pour configurer les dépendances du projet et les propriétés de génération requises afin que les projets soient correctement créés.In this section, you'll update the solution that contains both projects to configure project dependencies and build properties required for the projects to build correctly.

  1. Dans l’ Explorateur de solutions , cliquez avec le bouton droit sur le nœud de la solution, puis ajoutez un nouveau fichier XML nommé Solution.props.In Solution Explorer , right-click the solution node and add a new XML file named Solution.props.

  2. Ajoutez le code XML suivant au fichier Solution.props.Add the following XML to the Solution.props file.

    <?xml version="1.0" encoding="utf-8"?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <IntDir>$(SolutionDir)\obj\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</IntDir>
        <OutDir>$(SolutionDir)\bin\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</OutDir>
        <GeneratedFilesDir>$(IntDir)Generated Files\</GeneratedFilesDir>
      </PropertyGroup>
    </Project>
    
  3. Dans le menu Affichage , cliquez sur Gestionnaire de propriétés (selon votre configuration, cette option peut apparaître sous Affichage -> Autres fenêtres ).From the View menu, click Property Manager (depending on your configuration, this may be under View -> Other Windows ).

  4. Dans la fenêtre Gestionnaire de propriétés , cliquez avec le bouton droit sur MyDesktopWin32App , puis sélectionnez Ajouter une feuille de propriétés existante.In the Property Manager window, right-click MyDesktopWin32App and select Add Existing Property Sheet. Accédez au fichier Solution.props que vous venez d’ajouter, puis cliquez sur Ouvrir.Navigate to the Solution.props file you just added and click Open.

  5. Répétez l’étape précédente pour ajouter le fichier Solution.props au projet MyUWPApp dans la fenêtre Gestionnaire de propriétés.Repeat the previous step to add the Solution.props file to the MyUWPApp project in the Property Manager window.

  6. Fermez la fenêtre Gestionnaire de propriétés.Close the Property Manager window.

  7. Vérifiez que les modifications apportées à la feuille de propriétés ont été correctement enregistrées.Confirm that the property sheet changes were saved properly. Dans Explorateur de solutions , cliquez avec le bouton droit sur le projet MyDesktopWin32App , puis choisissez Propriétés.In Solution Explorer , right-click the MyDesktopWin32App project and choose Properties. Cliquez sur Propriétés de configuration -> Général , puis confirmez que les propriétés Répertoire de sortie et Répertoire intermédiaire affichent les valeurs que vous avez ajoutées au fichier Solution.props.Click Configuration Properties -> General , and confirm that the Output Directory and Intermediate Directory properties have the values you added to the Solution.props file. Vous pouvez également confirmer les mêmes propriétés pour le projet MyUWPApp.You can also confirm the same for the MyUWPApp project. Propriétés du projetProject properties

  8. Dans l’ Explorateur de solutions , cliquez avec le bouton droit sur le nœud de la solution, puis choisissez Dépendances du projet.In Solution Explorer , right-click the solution node and choose Project Dependencies. Dans la liste déroulante Projets , vérifiez que l’option MyDesktopWin32App est sélectionnée, puis choisissez MyUWPApp dans la liste Dépend de.In the Projects drop-down, make sure that MyDesktopWin32App is selected, and select MyUWPApp in the Depends On list. Dépendances du projetProject dependencies

  9. Cliquez sur OK.Click OK.

Ajouter du code au projet d’application UWPAdd code to the UWP app project

Vous pouvez maintenant ajouter du code au projet MyUWPApp afin d’effectuer les tâches suivantes :You're now ready to add code to the MyUWPApp project to perform these tasks:

  • Implémenter un contrôle XAML UWP personnalisé.Implement a custom UWP XAML control. Plus loin dans cette procédure pas à pas, vous ajouterez le code qui héberge ce contrôle dans le projet MyDesktopWin32App.Later in this walkthrough, you'll add code that hosts this control in the MyDesktopWin32App project.
  • Définir un type dérivé de la classe Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication dans le Kit de ressources Communauté Windows.Define a type that derives from the Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication class in the Windows Community Toolkit.

Définir un contrôle XAML UWP personnaliséDefine a custom UWP XAML control

  1. Dans Explorateur de solutions , cliquez avec le bouton droit sur MyUWPApp , puis sélectionnez Ajouter -> Nouvel élément.In Solution Explorer , right-click MyUWPApp and select Add -> New Item. Sélectionnez le nœud Visual C++ dans le volet gauche, choisissez Contrôle utilisateur vide (C++/WinRT) , nommez-le MyUserControl , puis cliquez sur Ajouter.Select the Visual C++ node in the left pane, select Blank User Control (C++/WinRT) , name it MyUserControl , and click Add.

  2. Dans l’éditeur XAML, remplacez le contenu du fichier MyUserControl.xaml par le code XAML suivant, puis enregistrez le fichier.In the XAML editor, replace the contents of the MyUserControl.xaml file with the following XAML and then save the file.

    <UserControl
        x:Class="MyUWPApp.MyUserControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:MyUWPApp"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <StackPanel HorizontalAlignment="Center" Spacing="10" 
                    Padding="20" VerticalAlignment="Center">
            <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" 
                           Text="Hello from XAML Islands" FontSize="30" />
            <TextBlock HorizontalAlignment="Center" Margin="15" TextWrapping="Wrap"
                           Text="😍❤💋🌹🎉😎�🐱‍👤" FontSize="16" />
            <Button HorizontalAlignment="Center" 
                    x:Name="Button" Click="ClickHandler">Click Me</Button>
        </StackPanel>
    </UserControl>
    

Définir une classe XamlApplicationDefine a XamlApplication class

Modifiez ensuite la classe App par défaut du projet MyUWPApp afin de la dériver de la classe Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication fournie par le Kit de ressources Communauté Windows.Next, revise the default App class in the MyUWPApp project to derive from the Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication class provided by the Windows Community Toolkit. Cette classe prend en charge l’interface IXamlMetadataProvider, qui permet à votre application de découvrir et de charger des métadonnées pour les contrôles XAML UWP personnalisés dans les assemblys du répertoire actif de votre application au moment de l’exécution.This class supports the IXamlMetadataProvider interface, which enables your app to discover and load metadata for custom UWP XAML controls in assemblies in the current directory of your application at run time. Cette classe initialise également le framework XAML UWP pour le thread actuel.This class also initializes the UWP XAML framework for the current thread. Plus loin dans cette procédure pas à pas, vous allez mettre à jour le projet Desktop pour créer une instance de cette classe.Later in this walkthrough you'll update the desktop project to create an instance of this class.

Notes

Chaque solution qui utilise XAML Islands ne peut contenir qu’un seul projet définissant un objet XamlApplication.Each solution that uses XAML Islands can contain only one project that defines a XamlApplication object. Tous les contrôles XAML UWP personnalisés de votre application partagent le même objet XamlApplication.All custom UWP XAML controls in your app share the same XamlApplication object.

  1. Dans Explorateur de solutions , cliquez avec le bouton droit sur le fichier MainPage.xaml dans le projet MyUWPApp.In Solution Explorer , right-click the MainPage.xaml file in the MyUWPApp project. Cliquez sur Retirer puis Supprimer pour supprimer définitivement ce fichier du projet.Click Remove and then Delete to delete this file permamently from the project.

  2. Dans le projet MyUWPApp , développez le fichier App.xaml.In the MyUWPApp project, expand App.xaml file.

  3. Remplacez le contenu des fichiers App.xaml , App.cpp , App.h et App.idl par le code suivant.Replace the contents of the App.xaml , App.cpp , App.h , and App.idl files with the following code.

    • App.xaml  :App.xaml :

      <Toolkit:XamlApplication
          x:Class="MyUWPApp.App"
          xmlns:Toolkit="using:Microsoft.Toolkit.Win32.UI.XamlHost"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:local="using:MyUWPApp">
      </Toolkit:XamlApplication>
      
    • App.idl  :App.idl :

      namespace MyUWPApp
      {
           [default_interface]
           runtimeclass App : Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication
           {
              App();
           }
      }
      
    • App.h  :App.h :

      #pragma once
      #include "App.g.h"
      #include "App.base.h"
      namespace winrt::MyUWPApp::implementation
      {
          class App : public AppT2<App>
          {
          public:
              App();
              ~App();
          };
      }
      namespace winrt::MyUWPApp::factory_implementation
      {
          class App : public AppT<App, implementation::App>
          {
          };
      }
      
    • App.cpp  :App.cpp :

      #include "pch.h"
      #include "App.h"
      #include "App.g.cpp"
      using namespace winrt;
      using namespace Windows::UI::Xaml;
      namespace winrt::MyUWPApp::implementation
      {
          App::App()
          {
              Initialize();
              AddRef();
              m_inner.as<::IUnknown>()->Release();
          }
          App::~App()
          {
              Close();
          }
      }
      

      Notes

      L’instruction #include "App.g.cpp" est nécessaire quand la propriété Optimisé sur la page Propriétés communes -> C++/WinRT des propriétés de projet est définie sur Oui.The #include "App.g.cpp" statement is necessary when the Optimized property on the Common Properties -> C++/WinRT page of the project properties is set to Yes. Il s’agit de la valeur par défaut pour les nouveaux projets C++/WinRT.This is the default for new C++/WinRT projects. Pour plus d’informations sur les effets de la propriété Optimisé , consultez cette section.For more details about the effects of the Optimized property, see this section.

  4. Ajoutez un nouveau fichier d’en-tête au projet MyUWPApp nommé app.base.h.Add a new header file to the MyUWPApp project named app.base.h.

  5. Ajoutez le code suivant au fichier app.base.h , enregistrez le fichier, puis fermez-le.Add the following code to the app.base.h file, save the file, and close it.

    #pragma once
    namespace winrt::MyUWPApp::implementation
    {
        template <typename D, typename... I>
        struct App_baseWithProvider : public App_base<D, ::winrt::Windows::UI::Xaml::Markup::IXamlMetadataProvider>
        {
            using IXamlType = ::winrt::Windows::UI::Xaml::Markup::IXamlType;
            IXamlType GetXamlType(::winrt::Windows::UI::Xaml::Interop::TypeName const& type)
            {
                return AppProvider()->GetXamlType(type);
            }
            IXamlType GetXamlType(::winrt::hstring const& fullName)
            {
                return AppProvider()->GetXamlType(fullName);
            }
            ::winrt::com_array<::winrt::Windows::UI::Xaml::Markup::XmlnsDefinition> GetXmlnsDefinitions()
            {
                return AppProvider()->GetXmlnsDefinitions();
            }
        private:
            bool _contentLoaded{ false };
            winrt::com_ptr<XamlMetaDataProvider> _appProvider;
            winrt::com_ptr<XamlMetaDataProvider> AppProvider()
            {
                if (!_appProvider)
                {
                    _appProvider = winrt::make_self<XamlMetaDataProvider>();
                }
                return _appProvider;
            }
        };
        template <typename D, typename... I>
        using AppT2 = App_baseWithProvider<D, I...>;
    }
    
  6. Générez la solution et vérifiez qu’elle est correctement générée.Build the solution and confirm that it builds successfully.

Configurer le projet de bureau pour utiliser des types de contrôles personnalisésConfigure the desktop project to consume custom control types

Pour que l’application MyDesktopWin32App puisse héberger un contrôle XAML UWP personnalisé dans un îlot XAML, l’application doit être configurée pour utiliser des types de contrôles personnalisés provenant du projet MyUWPApp.Before the MyDesktopWin32App app can host a custom UWP XAML control in a XAML Island, it must be configured to consume custom control types from the MyUWPApp project. Il existe deux façons de procéder, et vous pouvez choisir l’une ou l’autre de ces deux options à mesure que vous effectuez cette procédure pas à pas.There are two ways to do this, and you can choose either option as you complete this walkthrough.

Option 1 : Empaqueter l’application à l’aide de MSIXOption 1: Package the app using MSIX

Vous pouvez empaqueter l’application dans un package MSIX en vue du déploiement.You can package the app in an MSIX package for deployment. MSIX est une technologie d’empaquetage moderne pour Windows, basée sur une combinaison des technologies d’installation MSI, .appx, App-V et ClickOnce.MSIX is the modern app packaging technology for Windows, and it is based on a combination of MSI, .appx, App-V and ClickOnce installation technologies.

  1. Ajoutez un nouveau projet d’empaquetage d’application Windows à votre solution.Add a new Windows Application Packaging Project to your solution. À mesure que vous créez le projet, nommez-le MyDesktopWin32Project et sélectionnez Windows 10, version 1903 (10.0 ; Build 18362) à la fois pour la version cible et la version minimale.As you create the project, name it MyDesktopWin32Project and select Windows 10, version 1903 (10.0; Build 18362) for both the Target version and Minimum version.

  2. Dans le projet d’empaquetage, cliquez avec le bouton droit sur le nœud Applications , puis choisissez Ajouter une référence.In the packaging project, right-click the Applications node and choose Add reference. Dans la liste des projets, activez la case à cocher en regard du projet MyDesktopWin32App , puis cliquez sur OK.In the list of projects, select the check box next to the MyDesktopWin32App project and click OK. Projet de référenceReference project

Notes

Si vous choisissez de ne pas empaqueter votre application dans un package MSIX pour la déployer, Visual C++ Runtime doit être installé sur les ordinateurs qui exécutent votre application.If you choose to not package your application in an MSIX package for deployment, computers that run your app must have the Visual C++ Runtime installed.

Option 2 : Créer un manifeste d'applicationOption 2: Create an application manifest

Vous pouvez ajouter un manifeste d’application à votre application.You can add an application manifest to your app.

  1. Cliquez avec le bouton droit sur le projet MyDesktopWin32App , puis sélectionnez Ajouter -> Nouvel élément.Right-click the MyDesktopWin32App project and select Add -> New Item.

  2. Dans la boîte de dialogue Ajouter un nouvel élément , cliquez sur Web dans le volet gauche, puis sélectionnez Fichier XML (.xml) .In the Add New Item dialog, click Web in the left pane and select XML File (.xml).

  3. Nommez le nouveau fichier app.manifest , puis cliquez sur Ajouter.Name the new file app.manifest and click Add.

  4. Remplacez le contenu du nouveau fichier par le code XML ci-dessous.Replace the contents of the new file with the following XML. Ce code XML inscrit les types de contrôles personnalisés dans le projet MyUWPApp.This XML registers custom control types in the MyUWPApp project.

    <?xml version="1.0" encoding="utf-8"?>
    <assembly
     xmlns="urn:schemas-microsoft-com:asm.v1"
     xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"
     manifestVersion="1.0">
      <asmv3:file name="MyUWPApp.dll">
        <activatableClass
            name="MyUWPApp.App"
            threadingModel="both"
            xmlns="urn:schemas-microsoft-com:winrt.v1" />
        <activatableClass
            name="MyUWPApp.XamlMetadataProvider"
            threadingModel="both"
            xmlns="urn:schemas-microsoft-com:winrt.v1" />
        <activatableClass
            name="MyUWPApp.MyUserControl"
            threadingModel="both"
            xmlns="urn:schemas-microsoft-com:winrt.v1" />
      </asmv3:file>
    </assembly>
    

Configurer d’autres propriétés de projet de bureauConfigure additional desktop project properties

Mettez à jour le projet MyDesktopWin32App afin de définir une macro pour des répertoires Include supplémentaires et de configurer d’autres propriétés.Next, update the MyDesktopWin32App project to define a macro for additional include directories and configure additional properties.

  1. Dans Explorateur de solutions , cliquez avec le bouton droit sur le projet MyDesktopWin32App , puis choisissez Décharger le projet.In Solution Explorer , right-click the MyDesktopWin32App project and select Unload Project.

  2. Cliquez avec le bouton droit sur MyDesktopWin32App (déchargé) , puis sélectionnez Modifier MyDesktopWin32App.vcxproj.Right-click MyDesktopWin32App (Unloaded) and select Edit MyDesktopWin32App.vcxproj.

  3. Ajoutez le code XML suivant juste avant la balise de fermeture </Project> à la fin du fichier.Add the following XML just before the closing </Project> tag at the end of the file. Enregistrez et fermez le fichier.Then, save and close the file.

      <!-- Configure these for your UWP project -->
      <PropertyGroup>
        <AppProjectName>MyUWPApp</AppProjectName>
      </PropertyGroup>
      <PropertyGroup>
        <AppIncludeDirectories>$(SolutionDir)\obj\$(Platform)\$(Configuration)\$(AppProjectName)\;$(SolutionDir)\obj\$(Platform)\$(Configuration)\$(AppProjectName)\Generated Files\;</AppIncludeDirectories>
      </PropertyGroup>
      <ItemGroup>
        <ProjectReference Include="..\$(AppProjectName)\$(AppProjectName).vcxproj" />
      </ItemGroup>
      <!-- End Section-->
    
  4. Dans l’ Explorateur de solutions , cliquez avec le bouton droit sur MyDesktopWin32App (déchargé) , puis sélectionnez Recharger le projet.In Solution Explorer , right-click MyDesktopWin32App (unloaded) and select Reload Project.

  5. Cliquez avec le bouton droit sur le projet MyDesktopWin32App , sélectionnez Propriétés , puis développez Outil Manifeste -> Entrée et sortie dans le volet gauche.Right-click the MyDesktopWin32App project, select Properties , and expand Manifest Tool -> Input and Output in the left pane. Définissez la propriété Prise en charge DPI sur Reconnaissant les résolutions élevées par moniteur.Set the DPI Awareness property to Per Monitor High DPI Aware. Si vous ne définissez pas cette propriété, vous risquez de rencontrer une erreur de configuration de manifeste dans certains scénarios impliquant des résolutions élevées.If you do not set this property, you may encounter a manifest configuration error in certain high DPI scenarios.

    Capture d’écran des paramètres de projet C/ C++.

  6. Cliquez sur OK pour fermer la boîte de dialogue Pages de propriétés.Click OK to close the Property Pages dialog.

Héberger le contrôle XAML UWP personnalisé dans le projet de bureauHost the custom UWP XAML control in the desktop project

Vous êtes enfin prêt à ajouter du code au projet MyDesktopWin32App pour héberger le contrôle XAML UWP personnalisé que vous avez défini précédemment dans le projet MyUWPApp.Finally, you're ready to add code to the MyDesktopWin32App project to host the custom UWP XAML control you defined earlier in the MyUWPApp project.

  1. Dans le projet MyDesktopWin32App , ouvrez le fichier framework.h et commentez la ligne de code suivante.In the MyDesktopWin32App project, open the framework.h file and comment out the following line of code. Enregistrez le fichier une fois que vous avez terminé.Save the file when you're done.

    #define WIN32_LEAN_AND_MEAN
    
  2. Ouvrez le fichier MyDesktopWin32App.h et remplacez le contenu de ce fichier par le code suivant pour référencer les fichiers d’en-tête C++/WinRT requis.Open the MyDesktopWin32App.h file and replace the contents of this file with the following code to reference necessary C++/WinRT header files. Enregistrez le fichier une fois que vous avez terminé.Save the file when you're done.

    #pragma once
    
    #include "resource.h"
    #include <winrt/Windows.Foundation.Collections.h>
    #include <winrt/Windows.system.h>
    #include <winrt/windows.ui.xaml.hosting.h>
    #include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
    #include <winrt/windows.ui.xaml.controls.h>
    #include <winrt/Windows.ui.xaml.media.h>
    #include <winrt/Windows.UI.Core.h>
    #include <winrt/MyUWPApp.h>
    
    using namespace winrt;
    using namespace Windows::UI;
    using namespace Windows::UI::Composition;
    using namespace Windows::UI::Xaml::Hosting;
    using namespace Windows::Foundation::Numerics;
    using namespace Windows::UI::Xaml::Controls;
    
  3. Ouvrez le fichier MyDesktopWin32App.cpp et ajoutez le code suivant à la section Global Variables:.Open the MyDesktopWin32App.cpp file and add the following code to the Global Variables: section.

    winrt::MyUWPApp::App hostApp{ nullptr };
    winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource _desktopWindowXamlSource{ nullptr };
    winrt::MyUWPApp::MyUserControl _myUserControl{ nullptr };
    
  4. Dans le même fichier, ajoutez le code suivant à la section Forward declarations of functions included in this code module:.In the same file, add the following code to the Forward declarations of functions included in this code module: section.

    void AdjustLayout(HWND);
    
  5. Dans le même fichier, ajoutez le code suivant immédiatement après le commentaire TODO: Place code here. dans la fonction wWinMain.In the same file, add the following code immediately after the TODO: Place code here. comment in the wWinMain function.

    // TODO: Place code here.
    winrt::init_apartment(winrt::apartment_type::single_threaded);
    hostApp = winrt::MyUWPApp::App{};
    _desktopWindowXamlSource = winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource{};
    
  6. Dans le même fichier, remplacez la fonction InitInstance par défaut par le code suivant.In the same file, replace the default InitInstance function with the following code.

    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
        hInst = hInstance; // Store instance handle in our global variable
    
        HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
    
        if (!hWnd)
        {
            return FALSE;
        }
    
        // Begin XAML Islands walkthrough code.
        if (_desktopWindowXamlSource != nullptr)
        {
            auto interop = _desktopWindowXamlSource.as<IDesktopWindowXamlSourceNative>();
            check_hresult(interop->AttachToWindow(hWnd));
            HWND hWndXamlIsland = nullptr;
            interop->get_WindowHandle(&hWndXamlIsland);
            RECT windowRect;
            ::GetWindowRect(hWnd, &windowRect);
            ::SetWindowPos(hWndXamlIsland, NULL, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_SHOWWINDOW);
            _myUserControl = winrt::MyUWPApp::MyUserControl();
            _desktopWindowXamlSource.Content(_myUserControl);
        }
        // End XAML Islands walkthrough code.
    
        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);
    
        return TRUE;
    }
    
  7. Dans le même fichier, ajoutez la nouvelle fonction suivante à la fin du fichier.In the same file, add the following new function to the end of the file.

    void AdjustLayout(HWND hWnd)
    {
        if (_desktopWindowXamlSource != nullptr)
        {
            auto interop = _desktopWindowXamlSource.as<IDesktopWindowXamlSourceNative>();
            HWND xamlHostHwnd = NULL;
            check_hresult(interop->get_WindowHandle(&xamlHostHwnd));
            RECT windowRect;
            ::GetWindowRect(hWnd, &windowRect);
            ::SetWindowPos(xamlHostHwnd, NULL, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_SHOWWINDOW);
        }
    }
    
  8. Dans le même fichier, recherchez la fonction WndProc.In the same file, locate the WndProc function. Remplacez le gestionnaire WM_DESTROY par défaut dans l’instruction switch par le code suivant.Replace the default WM_DESTROY handler in the switch statement with the following code.

    case WM_DESTROY:
        PostQuitMessage(0);
        if (_desktopWindowXamlSource != nullptr)
        {
            _desktopWindowXamlSource.Close();
            _desktopWindowXamlSource = nullptr;
        }
        break;
    case WM_SIZE:
        AdjustLayout(hWnd);
        break;
    
  9. Enregistrez le fichier.Save the file.

  10. Générez la solution et vérifiez qu’elle est correctement générée.Build the solution and confirm that it builds successfully.

Ajouter au contrôle personnalisé un contrôle de la bibliothèque WinUI 2.xAdd a control from the WinUI 2.x library to the custom control

Traditionnellement, les contrôles XAML WinRT ont été publiés dans le cadre du système d’exploitation Windows 10 et mis à la disposition des développeurs via le SDK Windows.Traditionally, WinRT XAML controls have been released as part of the Windows 10 OS and made available to developers through the Windows SDK. La bibliothèque WinUI est une autre approche, dans laquelle les versions mises à jour des contrôles XAML WinRT du SDK Windows sont distribuées dans un package NuGet qui n’est pas lié aux versions de SDK Windows.The WinUI library is an alternative approach, where updated versions of WinRT XAML controls from the Windows SDK are distributed in a NuGet package that is not tied to Windows SDK releases. Cette bibliothèque comprend également de nouveaux contrôles qui ne font pas partie du SDK Windows et de la plateforme UWP par défaut.This library also includes new controls that aren't part of the Windows SDK and the default UWP platform. Pour plus d’informations, consultez notre feuille de route de la bibliothèque WinUI.See our WinUI library roadmap for more details.

Cette section montre comment ajouter un contrôle XAML WinRT de la bibliothèque WinUI 2.x à votre contrôle utilisateur.This section demonstrates how to add a WinRT XAML control from the WinUI 2.x library to your user control.

Notes

XAML Islands prend uniquement en charge l’hébergement des contrôles issus de la bibliothèque WinUI 2.x.Currently, XAML Islands only supports hosting controls from the WinUI 2.x library. La prise en charge de l’hébergement des contrôles de la bibliothèque WinUI 3 sera disponible dans une version ultérieure.Support for hosting controls from the WinUI 3 library is coming in a later release.

  1. Dans le projet MyUWPApp , installez la dernière version ou la dernière version préliminaire du package NuGet Microsoft.UI.Xaml.In the MyUWPApp project, install the latest prerelease or release version of the Microsoft.UI.Xaml NuGet package.

    • Si vous avez choisi d’empaqueter le projet MyDesktopWin32App à l’aide de MSIX précédemment dans cette procédure, vous pouvez installer la préversion ou la version finale du package NuGet Microsoft.UI.Xaml.If you chose to package the MyDesktopWin32App project using MSIX earlier in this walkthrough, you can install either the prerelease or release version of the Microsoft.UI.Xaml NugGet package. Les applications de bureau empaquetées peuvent utiliser la préversion ou la version finale de ce package.Packaged desktop apps can use either the prerelease or release version of this package.
    • Si vous avez choisi de ne pas empaqueter le projet MyDesktopWin32App , vous devez installer la préversion du package NuGet Microsoft.UI.Xaml.If you chose not to package the MyDesktopWin32App project, you must install the prerelease version of the Microsoft.UI.Xaml NuGet package. Les applications de bureau non empaquetées doivent utiliser la préversion de ce package.Unpackaged desktop apps must use the prerelease version of this package.
  2. Dans le fichier pch.h de ce projet, ajoutez les instructions #include suivantes et enregistrez vos modifications.In the pch.h file in this project, add the following #include statements and save your changes. Ces instructions apportent un ensemble obligatoire d’en-têtes de projection depuis la bibliothèque WinUI vers votre projet.These statements bring a required set of projection headers from the WinUI library into your project. Cette étape est requise pour tout projet C++/WinRT qui utilise la bibliothèque WinUI.This step is required for any C++/WinRT project that uses the WinUI library. Pour plus d’informations, consultez cet article.For more information, see this article.

    #include "winrt/Microsoft.UI.Xaml.Automation.Peers.h"
    #include "winrt/Microsoft.UI.Xaml.Controls.Primitives.h"
    #include "winrt/Microsoft.UI.Xaml.Media.h"
    #include "winrt/Microsoft.UI.Xaml.XamlTypeInfo.h"
    
  3. Dans le fichier App.xaml du même projet, ajoutez l’élément enfant suivant à l’élément <xaml:XamlApplication> et enregistrez vos modifications.In the App.xaml file in the same project, add the following child element to the <xaml:XamlApplication> element and save your changes.

    <Application.Resources>
        <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
    </Application.Resources>
    

    Après avoir ajouté cet élément, le contenu de ce fichier devrait maintenant ressembler à ce qui suit.After adding this element, the contents of this file should now look similar to this.

    <Toolkit:XamlApplication
        x:Class="MyUWPApp.App"
        xmlns:Toolkit="using:Microsoft.Toolkit.Win32.UI.XamlHost"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:MyUWPApp">
        <Application.Resources>
            <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/>
        </Application.Resources>
    </Toolkit:XamlApplication>
    
  4. Dans le même projet, ouvrez le fichier MyUserControl.xaml, puis ajoutez la déclaration d’espace de noms suivante à l’élément <UserControl>.In the same project, open the MyUserControl.xaml file and add the following namespace declaration to the <UserControl> element.

    xmlns:winui="using:Microsoft.UI.Xaml.Controls"
    
  5. Dans le même fichier, ajoutez un élément <winui:RatingControl /> en tant qu’enfant de l’élément <StackPanel> et enregistrez vos modifications.In the same file, add a <winui:RatingControl /> element as a child of the <StackPanel> and save your changes. Cet élément ajoute une instance de la classe RatingControl issue de la bibliothèque WinUI.This element adds an instance of the RatingControl class from the WinUI library. Après avoir ajouté cet élément, l’élément <StackPanel> devrait maintenant ressembler à ce qui suit.After adding this element, the <StackPanel> should now look similar to this.

    <StackPanel HorizontalAlignment="Center" Spacing="10" 
                Padding="20" VerticalAlignment="Center">
        <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" 
                       Text="Hello from XAML Islands" FontSize="30" />
        <TextBlock HorizontalAlignment="Center" Margin="15" TextWrapping="Wrap"
                       Text="😍❤💋🌹🎉😎�🐱‍👤" FontSize="16" />
        <Button HorizontalAlignment="Center" 
                x:Name="Button" Click="ClickHandler">Click Me</Button>
        <winui:RatingControl />
    </StackPanel>
    
  6. Générez la solution et vérifiez qu’elle est correctement générée.Build the solution and confirm that it builds successfully.

Tester l'applicationTest the app

Exécutez la solution et vérifiez que MyDesktopWin32App s’ouvre dans la fenêtre suivante.Run the solution and confirm that MyDesktopWin32App opens with the following window.

Application MyDesktopWin32App

Étapes suivantesNext steps

De nombreuses applications de bureau qui hébergent XAML Islands doivent gérer des scénarios supplémentaires pour offrir une expérience utilisateur fluide.Many desktop applications that host XAML Islands will need to handle additional scenarios in order to provide a smooth user experience. Par exemple, des applications de bureau peuvent devoir gérer la saisie au clavier dans des îlots XAML, la navigation en mode focus entre les îlots XAML et d’autres éléments d’interface utilisateur, et des changements de disposition.For example, desktop applications may need to handle keyboard input in XAML Islands, focus navigation between XAML Islands and other UI elements, and layout changes.

Pour plus d’informations sur la gestion de ces scénarios et des pointeurs vers des exemples de code connexes, consultez Scénarios avancés pour les îlots XAML dans les applications Win32 C++.For more information about handling these scenarios and pointers to related code samples, see Advanced scenarios for XAML Islands in C++ Win32 apps.