Compartilhar via


Arquitetura de entrada de interoperabilidade do Windows Forms e WPF

A interoperação entre o WPF e o Windows Forms requer que ambas as tecnologias tenham o processamento de entrada de teclado apropriado. Este tópico descreve como essas tecnologias implementam o processamento de teclado e mensagens para habilitar a interoperação suave em aplicativos híbridos.

Este tópico contém as seguintes subseções:

  • Formulários e Caixas de Diálogo Sem Modal

  • Processamento de mensagens e teclado do WindowsFormsHost

  • Processamento de mensagens e teclado ElementHost

Formulários e Caixas de Diálogo Sem Modal

Chame o método EnableWindowsFormsInterop no elemento WindowsFormsHost para abrir um formulário não modal ou caixa de diálogo a partir de um aplicativo baseado em WPF.

Chame o EnableModelessKeyboardInterop método no ElementHost controle para abrir uma página do WPF modeless em um aplicativo baseado em Windows Forms.

Processamento de mensagens e teclado do WindowsFormsHost

Quando hospedado por um aplicativo baseado em WPF, o processamento de mensagens e o teclado do Windows Forms consistem no seguinte:

As seções a seguir descrevem essas partes do processo com mais detalhes.

Adquirindo mensagens do Loop de Mensagens do WPF

A ComponentDispatcher classe implementa o gerenciador de loop de mensagens para WPF. A ComponentDispatcher classe fornece ganchos para permitir que clientes externos filtrem mensagens antes que o WPF as processe.

A implementação de interoperação manipula o evento ComponentDispatcher.ThreadFilterMessage, que permite que controles do Windows Forms processem mensagens antes dos controles do WPF.

Loop de mensagens substituto dos Windows Forms

Por padrão, a System.Windows.Forms.Application classe contém o loop de mensagem principal para aplicativos do Windows Forms. Durante a interoperação, o loop de mensagens do Windows Forms não processa mensagens. Portanto, essa lógica deve ser reproduzida. O manipulador do ComponentDispatcher.ThreadFilterMessage evento executa as seguintes etapas:

  1. Filtra a mensagem usando a IMessageFilter interface.

  2. Chama o método Control.PreProcessMessage.

  3. Converte e expedi a mensagem, se ela for necessária.

  4. Passa a mensagem para o controle de hospedagem, se nenhum outro controle processar a mensagem.

Implementação de IKeyboardInputSink

O loop de mensagem alternativa manipula o gerenciamento de teclado. Portanto, o IKeyboardInputSink.TabInto método é o único IKeyboardInputSink membro que requer uma implementação na WindowsFormsHost classe.

Por padrão, a HwndHost classe retorna false para sua IKeyboardInputSink.TabInto implementação. Isso impede a tabulação de um controle WPF para um controle do Windows Forms.

A WindowsFormsHost implementação do IKeyboardInputSink.TabInto método executa as seguintes etapas:

  1. Localiza o primeiro ou último controle do Windows Forms contido no WindowsFormsHost controle e que pode receber o foco. A escolha do controle depende de informações de passagem.

  2. Define o foco no controle e retorna true.

  3. Se nenhum controle puder receber o foco, retornará false.

Registro do WindowsFormsHost

Quando o manipulador de janela de um controle WindowsFormsHost é criado, o controle WindowsFormsHost chama um método estático interno que registra sua presença no loop de mensagens.

Durante o registro, o WindowsFormsHost controle examina o loop de mensagem. Se o loop de mensagem não tiver sido iniciado, o ComponentDispatcher.ThreadFilterMessage manipulador de eventos será criado. O loop de mensagem é considerado em execução quando o ComponentDispatcher.ThreadFilterMessage manipulador de eventos é anexado.

Quando o identificador da janela é destruído, o WindowsFormsHost controle se remove do registro.

Processamento de mensagens e teclado ElementHost

Quando hospedado por um aplicativo do Windows Forms, o processamento de teclado e mensagem do WPF consiste no seguinte:

As seções a seguir descrevem essas partes com mais detalhes.

Implementações de interface

No Windows Forms, as mensagens de teclado são roteadas para o identificador de janela do controle que tem foco. ElementHost No controle, essas mensagens são roteadas para o elemento hospedado. Para fazer isso, o ElementHost controle fornece uma HwndSource instância. Se o ElementHost controle tiver foco, a maior parte da entrada do teclado é roteada pela instância para que possa ser processada pela classe WPF HwndSource.

A HwndSource classe implementa as interfaces IKeyboardInputSink e IKeyboardInputSite.

A interoperação de teclado depende da implementação do OnNoMoreTabStops método para lidar com a entrada da tecla TAB e da tecla de direção que move o foco para fora dos elementos hospedados.

Tecla de tabulação e teclas de setas

A lógica de seleção do Windows Forms é mapeada para os métodos IKeyboardInputSink.TabInto e OnNoMoreTabStops para implementar a navegação por TAB e pelas teclas de seta. Substituir o método Select realiza esse mapeamento.

Teclas de comando e teclas de caixa de diálogo

Para dar ao WPF a primeira oportunidade de processar chaves de comando e chaves de diálogo, o pré-processamento de comando do Windows Forms está conectado ao TranslateAccelerator método. Sobrescrever o método Control.ProcessCmdKey conecta as duas tecnologias.

Com o TranslateAccelerator método, os elementos hospedados podem lidar com qualquer mensagem de chave, como WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN ou WM_SYSKEYUP, incluindo chaves de comando, como teclas TAB, ENTER, ESC e seta. Se uma mensagem chave não for tratada, ela será enviada para a hierarquia ancestral do Windows Forms para manipulação.

Processamento de Aceleradores

Para processar aceleradores corretamente, o processamento do acelerador do Windows Forms deve estar conectado à classe WPF AccessKeyManager . Além disso, todas as mensagens WM_CHAR devem ser roteadas corretamente para elementos hospedados.

Como a implementação padrão HwndSource do TranslateChar método retorna false, WM_CHAR mensagens são processadas usando a seguinte lógica:

  • O Control.IsInputChar método é substituído para garantir que todas as mensagens WM_CHAR sejam encaminhadas para elementos hospedados.

  • Se a tecla ALT for pressionada, a mensagem será WM_SYSCHAR. O Windows Forms não pré-processa essa mensagem por meio do IsInputChar método. Portanto, o ProcessMnemonic método é substituído para consultar o WPF AccessKeyManager para um acelerador registrado. Caso um acelerador registrado seja encontrado, AccessKeyManager o processa.

  • Se a tecla ALT não for pressionada, a classe WPF InputManager processará a entrada sem tratamento. Se a entrada for um acelerador, o AccessKeyManager irá processá-lo. O evento PostProcessInput é tratado para mensagens WM_CHAR que não foram processadas.

Quando o usuário pressiona a tecla ALT, as indicações visuais do acelerador são mostradas em todo o formulário. Para dar suporte a esse comportamento, todos os ElementHost controles no formulário ativo recebem mensagens WM_SYSKEYDOWN, independentemente de qual controle tenha foco.

As mensagens são enviadas apenas para ElementHost controles no formulário ativo.

Consulte também