Compartir a través de


Uso de la API de hospedaje XAML de WinRT en una aplicación de escritorio de C++ (Win32)

Importante

En este tema se usan o mencionan tipos del repositorio de GitHub CommunityToolkit/Microsoft.Toolkit.Win32. Para obtener información importante sobre la compatibilidad con islas XAML, consulte el Aviso de islas XAML en ese repositorio.

A partir de Windows 10, versión 1903, las aplicaciones de escritorio que no son para UWP (incluidas las aplicaciones de escritorio de C++ (Win32), WPF y Windows Forms pueden usar la API de hospedaje XAML de WinRT para hospedar controles XAML de WinRT en cualquier elemento de interfaz de usuario asociado a un identificador de ventana (HWND). Esta API permite que las aplicaciones de escritorio que no sean para UWP usen las características más recientes de la interfaz de usuario de Windows que solo están disponibles a través de controles XAML de WinRT. Por ejemplo, las aplicaciones de escritorio que no son para UWP pueden usar esta API para hospedar controles XAML de WinRT que usan el sistema Fluent Design y admiten Windows Ink.

La API de hospedaje XAML de WinRT proporciona la base para un conjunto más amplio de controles que proporcionamos para permitir a los desarrolladores llevar la interfaz de usuario de Fluent a aplicaciones de escritorio que no son para UWP. Esta característica se denomina Islas XAML. Para obtener información general sobre esta característica, consulta Hospedar controles XAML de WinRT en aplicaciones de escritorio (islas XAML).

Nota:

Si tienes comentarios sobre las islas XAML, crea un nuevo problema en el repositorio de Microsoft.Toolkit.Win32 y deja los comentarios allí.

¿La API de hospedaje XAML de WinRT es la opción adecuada para la aplicación de escritorio?

La API de hospedaje XAML de WinRT proporciona la infraestructura de bajo nivel para hospedar controles XAML de WinRT en aplicaciones de escritorio. Algunos tipos de aplicaciones de escritorio tienen la opción de usar API alternativas y más cómodas para lograr este objetivo.

  • Si tienes una aplicación de escritorio de C++ y quieres hospedar controles XAML de WinRT en tu aplicación, debes usar la API de hospedaje XAML de WinRT. No hay alternativas para estos tipos de aplicaciones.

  • En el caso de las aplicaciones de WPF y Windows Forms, se recomienda encarecidamente usar los controles .NET de isla XAML en el Kit de herramientas de la comunidad de Windows en lugar de usar directamente la API de hospedaje XAML de WinRT. Estos controles usan la API de hospedaje XAML de WinRT internamente e implementan todo el comportamiento que, de lo contrario, tendrías que controlarte si usaste directamente la API de hospedaje XAML de WinRT, incluidos los cambios de navegación y diseño del teclado.

Como se recomienda que solo las aplicaciones de escritorio de C++ usen la API de hospedaje XAML de WinRT, este artículo proporciona principalmente instrucciones y ejemplos para aplicaciones de escritorio de C++. Sin embargo, puedes usar la API de hospedaje XAML de WinRT en aplicaciones de WPF y Windows Forms si eliges. En este artículo se apunta al código fuente pertinente para los controles host para WPF y Windows Forms en el Kit de herramientas de la comunidad de Windows para que puedas ver cómo esos controles usan la API de hospedaje XAML de WinRT.

Obtenga información sobre cómo usar la API de hospedaje XAML

Para seguir instrucciones paso a paso con ejemplos de código para usar la API de hospedaje XAML en aplicaciones de escritorio de C++, consulta estos artículos:

Muestras

La forma en que usas la API de hospedaje XAML de WinRT en tu código depende del tipo de aplicación, del diseño de la aplicación y de otros factores. Para ayudar a ilustrar cómo usar esta API en el contexto de una aplicación completa, en este artículo se hace referencia al código de los ejemplos siguientes.

C++ de escritorio (Win32)

En los ejemplos siguientes se muestra cómo usar la API de hospedaje XAML de WinRT en una aplicación de escritorio de C++:

  • Ejemplo sencillo de isla XAML. En este ejemplo se muestra una implementación básica de hospedar un control XAML de WinRT en una aplicación de escritorio de C++ sin empaquetar.

  • Isla XAML con ejemplo de control personalizado. En este ejemplo se muestra una implementación completa de hospedar un control XAML personalizado de WinRT en una aplicación de escritorio de C++ empaquetada, así como controlar otro comportamiento, como la entrada del teclado y la navegación de foco.

WPF y Windows Forms

El control WindowsXamlHost del Kit de herramientas de la comunidad de Windows sirve como ejemplo de referencia para usar la API de hospedaje XAML de WinRT en aplicaciones de WPF y Windows Forms. El código fuente está disponible en las siguientes ubicaciones:

Nota:

Se recomienda encarecidamente usar los controles .NET de isla XAML en el Kit de herramientas de la comunidad de Windows en lugar de usar la API de hospedaje XAML de WinRT directamente en aplicaciones de WPF y Windows Forms. Los vínculos de ejemplo de WPF y Windows Forms de este artículo solo tienen fines ilustrativos.

Arquitectura de la API

La API de hospedaje XAML de WinRT incluye estos tipos principales de Windows Runtime e interfaces COM.

Tipo o interfaz Description
WindowsXamlManager Esta clase representa el marco XAML de UWP. Esta clase proporciona un único método InitializeForCurrentThread estático que inicializa el marco XAML de UWP en el subproceso actual de la aplicación de escritorio.
DesktopWindowXamlSource Esta clase representa una instancia de contenido XAML de UWP que hospedas en tu aplicación de escritorio. El miembro más importante de esta clase es la propiedad Content . Asignas esta propiedad a un windows.UI.Xaml.UIElement que quieras hospedar. Esta clase también tiene otros miembros para enrutar la navegación del foco del teclado hacia y hacia fuera de las islas XAML.
IDesktopWindowXamlSourceNative Esta interfaz COM proporciona el método AttachToWindow , que se usa para adjuntar una isla XAML en la aplicación a un elemento primario de la interfaz de usuario. Cada objeto DesktopWindowXamlSource implementa esta interfaz.
IDesktopWindowXamlSourceNative2 Esta interfaz COM proporciona el método PreTranslateMessage , que permite que el marco XAML de UWP procese determinados mensajes de Windows correctamente. Cada objeto DesktopWindowXamlSource implementa esta interfaz.

En el diagrama siguiente se muestra la jerarquía de objetos de una isla XAML hospedada en una aplicación de escritorio.

  • En el nivel base es el elemento de interfaz de usuario de la aplicación donde quieres hospedar la isla XAML. Este elemento de interfaz de usuario debe tener un identificador de ventana (HWND). Algunos ejemplos de elementos de interfaz de usuario en los que puedes hospedar una isla XAML incluyen una ventana para aplicaciones de escritorio de C++, un System.Windows.Interop.HwndHost para aplicaciones WPF y un control System.Windows.Forms.Control para aplicaciones de Windows Forms.

  • En el siguiente nivel, es un objeto DesktopWindowXamlSource . Este objeto proporciona la infraestructura para hospedar la isla XAML. El código es responsable de crear este objeto y adjuntarlo al elemento primario de la interfaz de usuario.

  • Al crear un DesktopWindowXamlSource, este objeto crea automáticamente una ventana secundaria nativa para hospedar el control XAML de WinRT. Esta ventana secundaria nativa se abstrae principalmente del código, pero puede acceder a su identificador (HWND) si es necesario.

  • Por último, en el nivel superior se encuentra el control XAML de WinRT que quieres hospedar en tu aplicación de escritorio. Puede ser cualquier objeto de UWP que derive de Windows.UI.Xaml.UIElement, incluido cualquier control XAML de WinRT proporcionado por windows SDK, así como controles de usuario personalizados.

Arquitectura DesktopWindowXamlSource

Nota:

Al hospedar islas XAML en una aplicación de escritorio, puedes tener varios árboles de contenido XAML que se ejecuten en el mismo subproceso a la vez. Para acceder al elemento raíz de un árbol de contenido XAML en una isla XAML y obtener la información relacionada sobre el contexto en el que se hospeda, usa la clase XamlRoot. Las API CoreWindow, ApplicationView y Window no proporcionarán la información correcta para las islas XAML. Para obtener más información, consulta esta sección.

procedimientos recomendados

Al usar la API de hospedaje XAML de WinRT, siga estos procedimientos recomendados para cada subproceso que hospeda controles XAML de WinRT:

Solución de problemas

Error al usar la API de hospedaje XAML de WinRT en una aplicación para UWP

Cuestión Resolución
La aplicación recibe una excepción COMException con el siguiente mensaje: "No se puede activar DesktopWindowXamlSource. Este tipo no se puede usar en una aplicación para UWP" o "No se puede activar WindowsXamlManager. Este tipo no se puede usar en una aplicación para UWP". Este error indica que estás intentando usar la API de hospedaje XAML de WinRT (en concreto, intentas crear instancias de los tipos DesktopWindowXamlSource o WindowsXamlManager ) en una aplicación para UWP. La API de hospedaje XAML de WinRT solo está pensada para usarse en aplicaciones de escritorio que no sean para UWP, como aplicaciones de escritorio de WPF, Windows Forms y C++.

Error al intentar usar los tipos WindowsXamlManager o DesktopWindowXamlSource

Cuestión Resolución
La aplicación recibe una excepción con el siguiente mensaje: "WindowsXamlManager y DesktopWindowXamlSource se admiten para aplicaciones destinadas a Windows versión 10.0.18226.0 y posteriores. Compruebe el manifiesto de aplicación o el manifiesto del paquete y asegúrese de que la propiedad MaxTestedVersion está actualizada". Este error indica que la aplicación intentó usar los tipos WindowsXamlManager o DesktopWindowXamlSource en la API de hospedaje XAML de WinRT, pero el sistema operativo no puede determinar si la aplicación se creó para tener como destino Windows 10, versión 1903 o posterior. La API de hospedaje XAML de WinRT se introdujo por primera vez como versión preliminar en una versión anterior de Windows 10, pero solo se admite a partir de Windows 10, versión 1903.

Para resolver este problema, cree un paquete MSIX para la aplicación y ejecútelo desde el paquete o instale el paquete NuGet Microsoft.Toolkit.Win32.UI.SDK en el proyecto.

Error al asociarse a una ventana en un subproceso diferente

Cuestión Resolución
La aplicación recibe una excepción COMException con el siguiente mensaje: "Error en el método AttachToWindow porque se creó el HWND especificado en un subproceso diferente". Este error indica que la aplicación llamó al método IDesktopWindowXamlSourceNative::AttachToWindow y le pasó el HWND de una ventana que se creó en otro subproceso. Debe pasarle a este método el HWND de una ventana que se creó en el mismo subproceso que el código desde el cual está llamando al método.

Error al asociarse a una ventana en otra ventana de nivel superior

Cuestión Resolución
La aplicación recibe una excepción COMException con el siguiente mensaje: "Error en el método AttachToWindow porque el HWND especificado desciende de una ventana de nivel superior diferente a la HWND que se pasó anteriormente a AttachToWindow en el mismo subproceso". Este error indica que la aplicación llamó al método IDesktopWindowXamlSourceNative::AttachToWindow y le pasó el HWND de una ventana que desciende de una ventana de nivel superior diferente a una ventana que especificó en una llamada anterior a este método en el mismo subproceso.

Una vez que la aplicación llama a AttachToWindow en un subproceso determinado, todos los demás objetos DesktopWindowXamlSource del mismo subproceso solo pueden asociarse a ventanas que son descendientes de la misma ventana de nivel superior que se pasó en la primera llamada a AttachToWindow. Cuando todos los objetos DesktopWindowXamlSource están cerrados para un subproceso determinado, el siguiente DesktopWindowXamlSource puede conectarse a cualquier ventana de nuevo.

Para resolver este problema, cierre todos los objetos DesktopWindowXamlSource enlazados a otras ventanas de nivel superior de este subproceso o cree un subproceso para este DesktopWindowXamlSource.