Utilização da API de alojamento UWP XAML

Importante

Este tópico utiliza ou menciona tipos do repositório CommunityToolkit/Microsoft.Toolkit.Win32 GitHub. Para informações importantes sobre o suporte para ilhas UWP XAML, por favor consulte o Aviso XAML Islands nesse repositório.

Aplicações de ambiente de trabalho não UWP (incluindo aplicações desktop C++ (Win32), WPF e Windows Forms) podem usar a UWP XAML hosting API para alojar controlos UWP XAML em qualquer elemento da interface associado a um handle de janela (HWND). Para uma visão geral desta funcionalidade, veja Controlos XAML UWP no Host em aplicações desktop (Ilhas XAML UWP).

A API de alojamento UWP XAML é a escolha certa para a sua aplicação de ambiente de trabalho?

A API de alojamento UWP XAML fornece a infraestrutura de baixo nível para alojar controlos UWP XAML em aplicações de ambiente de trabalho. Alguns tipos de aplicações de ambiente de trabalho têm a opção de usar APIs alternativas e mais convenientes para alcançar este objetivo.

  • Se tiver uma aplicação de desktop em C++ e quiser alojar controlos UWP XAML na sua aplicação, deve usar a API de alojamento UWP XAML. Não existem alternativas para este tipo de aplicações.

  • Para aplicações WPF e Windows Forms, recomendamos vivamente que utilize os controlos .NET XAML Island no Windows Community Toolkit em vez de usar diretamente a API de alojamento UWP XAML. Estes controlos utilizam internamente a API de alojamento UWP XAML e implementam todo o comportamento que teria de gerir se usasse diretamente a API de alojamento UWP XAML, incluindo a navegação do teclado e alterações de layout.

Como recomendamos que apenas as aplicações de ambiente de trabalho em C++ utilizem a API de alojamento UWP XAML, este artigo fornece principalmente instruções e exemplos para aplicações de ambiente de trabalho em C++. No entanto, pode usar a API de alojamento UWP XAML nas aplicações WPF e Windows Forms, se quiser. Este artigo aponta para o código-fonte relevante para os controlos host para WPF e Windows Forms no Windows Community Toolkit, para que possas ver como a API de alojamento UWP XAML é usada por esses controlos.

Aprenda a usar a API de Alojamento XAML

Para seguir instruções passo a passo com exemplos de código para usar a API de Alojamento XAML em aplicações de ambiente de trabalho C++, veja estes artigos:

Samples

A forma como usas a API de alojamento UWP XAML no teu código depende do tipo de aplicação, do design da tua aplicação e de outros fatores. Para ajudar a ilustrar como usar esta API no contexto de uma aplicação completa, este artigo refere-se ao código dos seguintes exemplos.

Área de trabalho C++ (Win32)

Os exemplos seguintes demonstram como usar a API de alojamento UWP XAML numa aplicação de ambiente de trabalho C++:

  • Amostra simples de XAML Island. Este exemplo demonstra uma implementação básica de alojamento de um controlo UWP XAML numa aplicação desktop C++ não empacotada.

  • XAML Island com exemplo de controlo personalizado. Este exemplo demonstra uma implementação completa de alojamento de um controlo UWP XAML personalizado numa aplicação desktop C++ empacotada, bem como a gestão de outros comportamentos como entrada de teclado e navegação de foco.

WPF e Windows Forms

O controlo WindowsXamlHost no Windows Community Toolkit serve como exemplo de referência para usar a API de alojamento UWP XAML em aplicações WPF e Windows Forms. O código-fonte está disponível nos seguintes locais:

Observação

Recomendamos vivamente que utilize os controlos .NET da Ilha XAML no Windows Community Toolkit, em vez de usar a API de alojamento UWP XAML diretamente nas aplicações WPF e Windows Forms. Os links de exemplo do WPF e Windows Forms neste artigo destinam-se apenas a fins ilustrativos.

Arquitetura da API

A API de alojamento UWP XAML inclui estes principais tipos de Windows Runtime e interfaces COM.

Tipo ou interface Description
WindowsXamlManager Esta classe representa o framework UWP XAML. Esta classe fornece um único método estático InitializeForCurrentThread que inicializa a estrutura UWP XAML na thread atual na aplicação de ambiente de trabalho.
DesktopWindowXamlSource Esta classe representa uma instância de conteúdo UWP XAML que está a hospedar na sua aplicação de ambiente de trabalho. O elemento mais importante desta classe é a propriedade Conteúdo . Atribuis esta propriedade a um Windows.UI.Xaml.UIElement que queres hospedar. Esta classe também tem outros membros para encaminhar navegação focada no teclado para dentro e fora das Ilhas XAML.
IDesktopWindowXamlSourceNative Esta interface COM fornece o método AttachToWindow , que utiliza para anexar uma ilha XAML na sua aplicação a um elemento da interface principal. Cada objeto DesktopWindowXamlSource implementa esta interface.
IDesktopWindowXamlSourceNative2 Esta interface COM fornece o método PreTranslateMessage , que permite ao framework XAML UWP processar corretamente certas mensagens do Windows. Cada objeto DesktopWindowXamlSource implementa esta interface.

O diagrama seguinte ilustra a hierarquia de objetos numa ilha XAML alojada numa aplicação de ambiente de trabalho.

  • Ao nível básico está o elemento de interface na tua aplicação onde queres alojar a ilha XAML. Este elemento UI deve ter um handle de janela (HWND). Exemplos de elementos de interface em que pode hospedar uma ilha XAML incluem um window para aplicações de ambiente de trabalho em C++, um System.Windows.Interop.HwndHost para WPF apps, e um System.Windows.Forms.Control para Windows Forms apps.

  • No nível seguinte está um objeto DesktopWindowXamlSource . Este objeto fornece a infraestrutura para alojar a Ilha XAML. O teu código é responsável por criar este objeto e anexá-lo ao elemento da interface principal.

  • Quando crias um DesktopWindowXamlSource, este objeto cria automaticamente uma janela filha nativa para alojar o teu controlo UWP XAML. Esta janela filha nativa está na maior parte abstraída do teu código, mas podes aceder ao seu handle (HWND) se necessário.

  • Por fim, no topo está o controlo UWP XAML que queres alojar na tua aplicação de ambiente de trabalho. Isto pode ser qualquer objeto UWP que derive de Windows. UI. Xaml.UIElement, incluindo qualquer controlo UWP XAML fornecido pelo Windows SDK, bem como controlos personalizados de utilizador.

Arquitetura DesktopWindowXamlSource

Observação

Quando alojas ilhas XAML UWP numa aplicação de ambiente de trabalho, podes ter várias árvores de conteúdo XAML a correr no mesmo tópico ao mesmo tempo. Para aceder ao elemento raiz de uma árvore de conteúdo XAML numa ilha XAML e obter informações relacionadas sobre o contexto em que está alojado, use a classe XamlRoot. As APIs CoreWindow, ApplicationView e Window não fornecem a informação correta para as ilhas XAML UWP. Para obter mais informações, consulte esta seção.

Melhores práticas

Ao utilizar a API de alojamento UWP XAML, siga estas melhores práticas para cada thread que aloja controlos UWP XAML:

Solução de problemas

Erro ao usar a API de alojamento UWP XAML numa aplicação UWP

Questão Resolução
A sua aplicação recebe uma COMException com a seguinte mensagem: "Não é possível ativar o DesktopWindowXamlSource. Este tipo não pode ser usado numa aplicação UWP." ou "Não é possível ativar o WindowsXamlManager. Este tipo não pode ser usado numa aplicação UWP." Este erro indica que está a tentar usar a API de alojamento UWP XAML (especificamente, está a tentar instanciar os tipos DesktopWindowXamlSource ou WindowsXamlManager ) numa aplicação UWP. A API de alojamento UWP XAML destina-se apenas a ser usada em aplicações de ambiente de trabalho não UWP, como WPF, Windows Forms e aplicações de ambiente de trabalho C++.

Erro ao tentar usar os tipos WindowsXamlManager ou DesktopWindowXamlSource

Questão Resolução
A sua aplicação recebe uma exceção com a seguinte mensagem: "WindowsXamlManager e DesktopWindowXamlSource são suportados para aplicações direcionadas ao Windows versão 10.0.18226.0 e posteriores. Por favor, verifique o manifesto da aplicação ou o manifesto do pacote e certifique-se de que a propriedade MaxTestedVersion está atualizada." Este erro indica que a sua aplicação tentou usar os tipos WindowsXamlManager ou DesktopWindowXamlSource na API de alojamento UWP XAML, mas o sistema operativo não consegue determinar se a aplicação foi concebida para Windows 10, versão 1903 ou posterior. A API de alojamento UWP XAML foi introduzida pela primeira vez como uma pré-visualização numa versão anterior do Windows 10, mas só é suportada a partir do Windows 10, versão 1903.

Para resolver este problema, crie um pacote MSIX para a aplicação e execute-o a partir do pacote, ou instale o pacote NuGet Microsoft.Toolkit.Win32.UI.SDK no seu project.

Erro ao anexar a uma janela numa thread diferente

Questão Resolução
A sua aplicação recebe uma COMException com a seguinte mensagem: "O método AttachToWindow falhou porque o HWND especificado foi criado numa thread diferente." Este erro indica que a sua aplicação chamou o método IDesktopWindowXamlSourceNative::AttachToWindow e passou-lhe o HWND de uma janela criada numa thread diferente. Deve passar a este método o HWND de uma janela que foi criada no mesmo thread do código de onde está a chamar o método.

Erro ao anexar a uma janela numa janela superior diferente

Questão Resolução
A sua aplicação recebe uma COMException com a seguinte mensagem: "O método AttachToWindow falhou porque o HWND especificado desce de uma janela de topo diferente do HWND que foi anteriormente passado para o AttachToWindow na mesma thread." Este erro indica que a sua aplicação chamou o método IDesktopWindowXamlSourceNative::AttachToWindow e passou-lhe o HWND de uma janela que desce de uma janela de topo diferente daquela que especificou numa chamada anterior a este método no mesmo thread.

Depois de a sua aplicação chamar o AttachToWindow num determinado thread, todos os outros objetos DesktopWindowXamlSource no mesmo thread só podem ser ligados a janelas que sejam descendentes da mesma janela de topo que foi passada na primeira chamada ao AttachToWindow. Quando todos os objetos DesktopWindowXamlSource estão fechados para um determinado thread, o próximo DesktopWindowXamlSource fica então livre para se ligar novamente a qualquer janela.

Para resolver este problema, ou feche todos os objetos DesktopWindowXamlSource que estejam ligados a outras janelas de topo neste tópico, ou crie um novo thread para este DesktopWindowXamlSource.