Cenários avançados das Ilhas XAML em aplicativos de desktop C++ (Win32)
Importante
Este tópico usa ou menciona tipos do repositório GitHub CommunityToolkit/Microsoft.Toolkit.Win32. Para saber mais sobre o suporte a ilhas XAML, confira o Aviso de ilhas XAML nesse repositório.
Os artigos Hospedar um controle UWP padrão e Hospedar um controle UWP personalizado fornecem instruções e exemplos para hospedar Ilhas XAML em um aplicativo de desktop C++ (Win32). No entanto, os exemplos de código desses artigos não tratam de muitos cenários avançados que os aplicativos da área de trabalho podem precisar manipular para fornecer uma experiência de usuário agradável. Este artigo fornece diretrizes para alguns desses cenários e ponteiros para exemplos de código relacionados.
Entrada por teclado
Para lidar corretamente com a entrada de teclado para cada Ilha XAML, seu aplicativo deve passar todas as mensagens do Windows para a estrutura UWP XAML para que determinadas mensagens possam ser processadas corretamente. Para fazer isso, em algum lugar do aplicativo que possa acessar o loop de mensagem, converta o objeto DesktopWindowXamlSource para cada Ilha XAML em uma interface COM IDesktopWindowXamlSourceNative2. Em seguida, chame o método PreTranslateMessage dessa interface e passe a mensagem atual.
C++ de desktop (Win32) : O aplicativo pode chamar PreTranslateMessage diretamente em seu loop de mensagem principal. Para obter um exemplo, veja o arquivo XamlBridge.cpp.
WPF: O aplicativo pode chamar PreTranslateMessage do manipulador de eventos para o evento ComponentDispatcher.ThreadFilterMessage. Para obter um exemplo, confira o arquivo WindowsXamlHostBase.Focus.cs no Windows Community Toolkit.
Windows Forms: O aplicativo pode chamar PreTranslateMessage de uma substituição para o método Control.PreprocessMessage. Para obter um exemplo, confira o arquivo WindowsXamlHostBase.KeyboardFocus.cs no Windows Community Toolkit.
Navegação de foco de teclado
Quando o usuário navega pelos elementos da interface do usuário em seu aplicativo usando o teclado (por exemplo, pressionando Tab ou tecla de direção/seta), você precisará mover o foco programaticamente para dentro e para fora do objeto DesktopWindowXamlSource. Quando a navegação do teclado do usuário alcançar o DesktopWindowXamlSource, mova o foco para o primeiro objeto Windows.UI.Xaml.UIElement na ordem de navegação da sua interface do usuário, continue a mover o foco para os objetos Windows.UI.Xaml.UIElement posteriores, conforme o usuário percorre os elementos e, em seguida, move o foco de volta para o DesktopWindowXamlSource e para o elemento de interface do usuário pai.
A API de hospedagem UWP XAML oferece vários tipos e membros para ajudá-lo a realizar essas tarefas.
Quando a navegação do teclado entrar no DesktopWindowXamlSource, o evento GotFocus será gerado. Manipule esse evento e mova o foco por meio de programação para o primeiro Windows.UI.Xaml.UIElement hospedado usando o método NavigateFocus.
Quando o usuário estiver no último elemento que pode ser focado em seu DesktopWindowXamlSource e pressionar a tecla TAB ou uma tecla de direção, o evento TakeFocusRequested será gerado. Manipule esse evento e mova o foco programaticamente para o próximo elemento que pode ser focado no aplicativo host. Por exemplo, em um aplicativo WPF em que o DesktopWindowXamlSource está hospedado em um System.Windows.Interop.HwndHost, você pode usar o método MoveFocus para transferir o foco para o próximo elemento que pode ser focalizado no aplicativo host.
Para obter exemplos que demonstram como fazer isso no contexto de um aplicativo de exemplo funcional, confira os seguintes arquivos de código:
C++ de desktop (Win32) : confira o arquivo XamlBridge.cpp.
WPF: Veja o arquivo WindowsXamlHostBase.Focus.cs no Windows Community Toolkit.
Windows Forms: Veja o arquivo WindowsXamlHostBase.KeyboardFocus.cs no Windows Community Toolkit.
Manipular alterações de layout
Quando o usuário alterar o tamanho do elemento pai da interface do usuário, você precisará lidar com as alterações de layout necessárias para garantir que os controles UWP sejam exibidos como esperado. Aqui estão alguns cenários importantes a considerar.
Em um aplicativo para desktop C++, quando seu aplicativo manipula a mensagem WM_SIZE, ele pode reposicionar a Ilha XAML hospedada usando a função SetWindowPos. Para obter um exemplo, confira o arquivo de código SampleApp.cpp.
Quando o elemento pai da interface do usuário precisa obter o tamanho da área retangular necessária para ajustar o Windows.UI.Xaml.UIElement que você está hospedando no DesktopWindowXamlSource, chame o método Measure do Windows.UI.Xaml.UIElement. Por exemplo:
Em um aplicativo WPF, você pode fazer isso por meio do método MeasureOverride do HwndHost que hospeda o DesktopWindowXamlSource. Para obter um exemplo, confira o arquivo WindowsXamlHostBase.Layout.cs no Windows Community Toolkit.
Em um aplicativo do Windows Forms, você pode fazer isso por meio do método GetPreferredSize do Control que hospeda o DesktopWindowXamlSource. Para obter um exemplo, confira o arquivo WindowsXamlHostBase.Layout.cs no Windows Community Toolkit.
Quando o tamanho do elemento pai da interface do usuário é alterado, chame o método Arrange do Windows.UI.Xaml.UIElement raiz que você está hospedando no DesktopWindowXamlSource. Por exemplo:
Em um aplicativo WPF, você pode fazer isso por meio do método ArrangeOverride do objeto HwndHost que hospeda o DesktopWindowXamlSource. Para obter um exemplo, confira o arquivo WindowsXamlHost.Layout.cs no Windows Community Toolkit.
Em um aplicativo do Windows Forms, você pode fazer isso por meio do manipulador do evento SizeChanged do Control que hospeda o DesktopWindowXamlSource. Para obter um exemplo, confira o arquivo WindowsXamlHost.Layout.cs no Windows Community Toolkit.
Manipular alterações de DPI
A estrutura UWP XAML manipula alterações de DPI para controles UWP hospedados automaticamente (por exemplo, quando o usuário arrasta a janela entre monitores com DPI de tela diferente). Para obter a melhor experiência, recomendamos que seu aplicativo para desktop Windows Forms, WPF ou C++ esteja configurado para ter reconhecimento de DPI por monitor.
Para configurar seu aplicativo para ter reconhecimento de DPI por monitor, adicione um manifesto do assembly lado a lado ao seu projeto e defina o elemento <dpiAwareness> como PerMonitorV2. Para obter mais informações sobre esse valor, confira a descrição de DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
</assembly>
Tópicos relacionados
- Hospedar controles UWP XAML em aplicativos da área de trabalho (Ilhas XAML)
- Como usar a API de hospedagem XAML da UWP em um aplicativo para desktop C++
- Hospedar um controle UWP padrão em um aplicativo para desktop C++
- Hospedar um controle UWP personalizado em um aplicativo para desktop C++
- Exemplos de código de Ilhas XAML
- Exemplo de Ilhas XAML do C++ de desktop
Windows developer