Utilisation de l’API d’hébergement XAML WinRT dans une application de bureau C++ (Win32)

Depuis Windows 10 version 1903, les applications de bureau non UWP (notamment les applications de bureau C++ (Win32), les applications WPF et les applications Windows Forms) peuvent utiliser l’API d’hébergement XAML WinRT pour héberger des contrôles XAML WinRT dans tout élément d’interface utilisateur associé à un handle de fenêtre (HWND). Cette API permet aux applications de bureau non UWP d’utiliser les dernières fonctionnalités de l’interface utilisateur Windows 10 qui sont disponibles uniquement via des contrôles XAML WinRT. Par exemple, des applications de bureau non UWP peuvent utiliser cette API pour héberger des contrôles XAML WinRT qui utilisent le Système de conception Fluent et prennent en charge Windows Ink.

L’API d’hébergement XAML WinRT constitue le fondement d’un ensemble plus large de contrôles que nous fournissons pour permettre aux développeurs d’intégrer l’interface utilisateur Fluent dans des applications de bureau non UWP. Cette fonctionnalité est nommée îlots XAML. Pour en obtenir une vue d’ensemble, consultez Héberger des contrôles XAML WinRT dans des applications de bureau (îlots XAML).

Notes

Si vous avez des choses à nous dire sur XAML Islands, ouvrez un nouveau problème dans le dépôt Microsoft.Toolkit.Win32 et laissez-y vos commentaires.

L’API d’hébergement XAML WinRT est-elle le bon choix pour votre application de bureau ?

L’API d’hébergement XAML WinRT fournit l’infrastructure de bas niveau pour l’hébergement de contrôles XAML WinRT dans des applications de bureau. Certains types d’applications de bureau ont la possibilité d’utiliser d’autres API plus pratiques pour atteindre cet objectif.

  • Si vous avez une application de bureau C++ dans laquelle vous souhaitez héberger des contrôles XAML WinRT, vous devez utiliser l’API d’hébergement XAML WinRT. Il n’existe aucune alternative pour ces types d’applications.

  • Pour des applications WPF et Windows Forms, nous vous recommandons vivement d’utiliser les contrôles .NET d’îlots XAML disponibles dans le Kit de ressources Communauté Windows au lieu d’utiliser directement l’API d’hébergement XAML WinRT. Ces contrôles utilisent l’API d’hébergement XAML WinRT en interne et implémentent tous les comportements que vous devriez gérer vous-même si vous utilisiez cette API directement, comme la navigation au clavier et les changements de disposition.

Étant donné que nous recommandons que seules les applications de bureau C++ utilisent l’API d’hébergement XAML WinRT, cet article fournit principalement des instructions et des exemples pour les applications de bureau C++. Vous pouvez cependant utiliser l’API d’hébergement XAML WinRT dans des applications WPF et Windows Forms si vous le souhaitez. Cet article pointe vers du code source pertinent pour les contrôles hôtes pour WPF et Windows Forms figurant dans le Kit de ressources Communauté Windows. Vous pouvez ainsi voir comment ces contrôles utilisent l’API d’hébergement XAML WinRT.

Découvrez comment utiliser l’API d’hébergement XAML

Pour suivre des instructions pas à pas avec des exemples de code pour l’utilisation de l’API d’hébergement XAML dans des applications de bureau C++, consultez les articles suivants :

Exemples

La façon dont vous utilisez l’API d’hébergement XAML WinRT dans votre code dépend de votre type d’application, de la conception de votre application et d’autres facteurs. Pour illustrer l’utilisation de cette API dans le contexte d’une application complète, cet article fait référence au code des exemples suivants.

Application de bureau C++ (Win32)

Les exemples suivants montrent comment utiliser l’API d’hébergement XAML WinRT dans une application de bureau C++ :

  • Exemple d’îlot XAML simple. Cet exemple montre une implémentation de base de l’hébergement d’un contrôle XAML WinRT dans une application de bureau C++ non empaquetée (c’est-à-dire, non intégrée à un package MSIX).

  • Exemples d’îlot XAML avec contrôle personnalisé. Cet exemple montre une implémentation complète de l’hébergement d’un contrôle XAML WinRT personnalisé dans une application de bureau C++ empaquetée, ainsi que la gestion d’autres comportements tels que la saisie au clavier et la navigation dans le focus.

WPF et Windows Forms

Le contrôle WindowsXamlHost dans le Kit de ressources Communauté Windows fait référence pour l’utilisation de l’API d’hébergement XAML WinRT dans des applications WPF et Windows Forms. Le code source est disponible aux emplacements suivants :

Notes

Nous vous recommandons vivement d’utiliser les contrôles .NET d’îlots XAML disponibles dans le Kit de ressources Communauté Windows au lieu d’utiliser l’API d’hébergement XAML WinRT directement dans des applications WPF et Windows Forms. Les exemples de liens WPF et Windows Forms dans cet article sont fournis uniquement à titre d’illustration.

Architecture de l’API

L’API d’hébergement XAML WinRT comprend les principaux types de Windows Runtime et interfaces COM suivants.

Type ou interface Description
WindowsXamlManager Cette classe représente l’infrastructure XAML UWP. Cette classe fournit une méthode statique InitializeForCurrentThread unique qui initialise l’infrastructure XAML UWP sur le thread actuel de l’application de bureau.
DesktopWindowXamlSource Cette classe représente une instance du contenu XAML UWP que vous hébergez dans votre application de bureau. Le membre le plus important de cette classe est la propriété Content. Vous attribuez cette propriété à un objet Windows.UI.Xaml.UIElement que vous souhaitez héberger. Cette classe comprend également d’autres membres pour le routage de la navigation en mode focus au clavier à destination et à partir des îlots XAML.
IDesktopWindowXamlSourceNative Cette interface COM fournit la méthode AttachToWindow que vous utilisez pour attacher un îlot XAML dans votre application à un élément d’interface utilisateur parent. Chaque objet DesktopWindowXamlSource implémente cette interface.
IDesktopWindowXamlSourceNative2 Cette interface COM fournit la méthode PreTranslateMessage qui permet à l’infrastructure XAML UWP de traiter correctement certains messages Windows. Chaque objet DesktopWindowXamlSource implémente cette interface.

Le diagramme suivant illustre la hiérarchie d’objets dans un îlot XAML hébergé dans une application de bureau.

  • Au niveau de base se trouve l’élément d’interface utilisateur dans votre application où vous souhaitez héberger l’îlot XAML. Cet élément d’interface utilisateur doit avoir un identificateur de fenêtre (HWND). Les exemples d’éléments d’interface utilisateur dans lesquels vous pouvez héberger un îlot XAML incluent une fenêtre pour les applications de bureau C++, un System.Windows.Interop.HwndHost pour les applications WPF, et un System.Windows.Interop.HwndHost pour les applications Windows Forms.

  • Au niveau suivant se trouve un objet DesktopWindowXamlSource. Cet objet fournit l’infrastructure pour l’hébergement de l’îlot XAML. Votre code est chargé de créer cet objet et de l’attacher à l’élément d’interface utilisateur parent.

  • Lorsque vous créez un objet DesktopWindowXamlSource, celui-ci crée automatiquement une fenêtre enfant native pour héberger votre contrôle XAML WinRT. Cette fenêtre enfant native est principalement abstraite de votre code, mais vous pouvez accéder à son identificateur (HWND) si nécessaire.

  • Enfin, au niveau supérieur figure le contrôle XAML WinRT que vous souhaitez héberger dans votre application de bureau. Il peut s’agir de n’importe quel objet UWP dérivant de Windows.UI.Xaml.UIElement, notamment de tout contrôle XAML WinRT fourni par le SDK Windows, ainsi que de contrôles utilisateur personnalisés.

Architecture de DesktopWindowXamlSource

Notes

Quand vous hébergez XAML Islands dans une application de bureau, plusieurs arborescences de contenu XAML peuvent s’exécuter simultanément sur le même thread. Pour accéder à l’élément racine d’une arborescence de contenu XAML dans un XAML Islands et obtenir des informations connexes sur le contexte de son hébergement, utilisez la classe XamlRoot. Les classes CoreWindow, ApplicationView et Window ne fournissent pas les informations correctes pour les îlots XAML. Pour plus d’informations, consultez cette section.

Meilleures pratiques

Quand vous utilisez l’API d’hébergement XAML WinRT, suivez ces bonnes pratiques pour chaque thread qui héberge des contrôles XAML WinRT :

Résolution des problèmes

Erreur lors de l’utilisation de l’API d’hébergement XAML WinRT dans une application UWP

Problème Résolution
Votre application reçoit une COMException avec le message suivant : « Impossible d’activer DesktopWindowXamlSource. Ce type ne peut pas être utilisé dans une application UWP.» ou «impossible d’activer WindowsXamlManager. Ce type ne peut pas être utilisé dans une application UWP. » Cette erreur indique que vous essayez d’utiliser l’API d’hébergement XAML WinRT (en particulier, vous essayez d’instancier les types DesktopWindowXamlSource ou WindowsXamlManager) dans une application UWP. L’API d’hébergement XAML WinRT est destinée à être utilisée uniquement dans les applications de bureau non UWP, telles que les applications WPF, les applications Windows Forms et les applications de bureau C++.

Erreur lors de la tentative d’utilisation des types WindowsXamlManager ou DesktopWindowXamlSource

Problème Résolution
votre application reçoit une exception avec le message suivant : «WindowsXamlManager et DesktopWindowXamlSource sont pris en charge pour les applications ciblant Windows version 10.0.18226.0 et ultérieures. Vérifiez le manifeste de l’application ou le manifeste du package et assurez-vous que la propriété MaxTestedVersion est à jour. » Cette erreur indique que votre application a tenté d’utiliser les types WindowsXamlManager ou DesktopWindowXamlSource dans l’API d’hébergement XAML WinRT, mais que le système d’exploitation ne peut pas déterminer si l’application a été créée pour cibler Windows 10, version 1903 ou ultérieure. L’API d’hébergement XAML WinRT a été introduite pour la première fois en préversion dans une version antérieure de Windows 10, mais elle n’est prise en charge que depuis Windows 10 version 1903.

Pour résoudre ce problème, créez un package MSIX pour l’application et exécutez-la à partir du package, ou installez le package NuGet Microsoft.Toolkit.Win32.UI.SDK dans votre projet.

Erreur lors de l’attachement à une fenêtre sur un autre thread

Problème Résolution
Votre application reçoit une COMException avec le message suivant : « Échec de la méthode AttachToWindow, car le HWND spécifié a été créé sur un autre thread ». Cette erreur indique que votre application a appelé la méthode IDesktopWindowXamlSourceNative::AttachToWindow et lui a passé le HWND d’une fenêtre qui a été créée sur un autre thread. Vous devez passer à cette méthode le HWND d’une fenêtre créée sur le même thread que le code à partir duquel vous appelez la méthode.

Erreur lors de l’attachement à une fenêtre dans une fenêtre de niveau supérieur différente

Problème Résolution
Votre application reçoit une COMException avec le message suivant : « échec de la méthode AttachToWindow, car le HWND spécifié descend d’une fenêtre de niveau supérieur à celle du HWND précédemment passé à AttachToWindow sur le même thread. » Cette erreur indique que votre application a appelé la méthode IDesktopWindowXamlSourceNative::AttachToWindow et lui a passé le HWND d’une fenêtre qui descend d’une fenêtre de niveau supérieur différente d’une fenêtre que vous avez spécifiée dans un appel précédent à cette méthode sur le même thread.

Après que votre application appelle la méthode AttachToWindow sur un thread particulier, tous les autres objets DesktopWindowXamlSource sur le même thread peuvent être attachés uniquement à des fenêtres qui descendent de la fenêtre de niveau supérieur qui a été passée dans le premier appel à la méthode AttachToWindow. Lorsque tous les objets DesktopWindowXamlSource sont fermés pour un thread particulier, l’objet DesktopWindowXamlSource suivant est libre de s’attacher à nouveau à toute fenêtre.

Pour résoudre ce problème, fermez tous les objets DesktopWindowXamlSource liés à d’autres fenêtres de niveau supérieur sur ce thread, ou créez un thread pour cet objet DesktopWindowXamlSource.