Esta página foi útil?
Seus comentários sobre este conteúdo são importantes. Queremos saber sua opinião.
Comentários adicionais?
1500 caracteres restantes
Biblioteca MSDN
Este artigo foi traduzido por máquina. Coloque o ponteiro do mouse sobre as frases do artigo para ver o texto original. Mais informações.
Tradução
Original
Informações
O tópico solicitado está sendo mostrado abaixo. No entanto, este tópico não está incluído nesta biblioteca.

Interoperação Win32 e WPF

Este tópico fornece uma visão geral de como interoperar WPF e o código de Win32 . O Windows PresentationFoundation (WPF)forneceum rico ambiente paraa criação de aplicações. No entanto, quando se tem um investimento significativo em código Win32, talvez seja mais eficiente reutilizar parte desse código.

Este tópico contém as seções a seguir.

Há duas técnicas básicas de interoperação entre código WPF e Win32.

  • Hospedar conteúdo WPF em uma janela Win32. Com essa técnica, você pode usar os recursos avançados de elementos gráficos do WPF dentro da estrutura de uma janela ou aplicativo padrão Win32.

  • Hospedar conteúdo Win32 em uma janela WPF. Com essa técnica, você pode usar um controle Win32 personalizado já existente em um contexto de outro conteúdo WPF; e passar dados através dos limites entre eles.

Cada um dessas técnicas é apresentada conceitualmente neste tópico. Para uma exemplificação mais orientada a código sobre hospedagem de conteúdo WPF no Win32, consulte Instruções passo a passo: hospedando conteúdo do WPF em Win32. Para uma exemplificação mais orientada a código sobre hospedagem de conteúdo Win32 no WPF, consulte Instruções passo a passo: hospedando um controle Win32 no WPF.

As APIs do WPF são em código gerenciado, mas a maioria dos programas Win32 existentes são escritos em C++ não gerenciado. Você não pode chamar APIs WPF a partir de um programa verdadeiramente não gerenciado. No entanto, usando a opção /clr do compilador Microsoft Visual C++, você pode criar um programa gerenciado misto onde você pode misturar perfeitamente chamadas de API tanto gerenciadas quanto não gerenciadas.

Uma complicação no nível de projeto é que você não pode compilar arquivos Extensible Application Markup Language (XAML) em um projeto C++. Há várias técnicas de divisão de projeto para compensar isso.

  • Criar uma DLL C# que contém todas as suas páginas XAML como um conjunto de módulos (assembly) compilado e então fazer com que o executável C++ inclua a DLL como uma referência.

  • Criar um executável C# para o conteúdo WPF, e fazer com que ele referencie uma DLL C++ que contém o conteúdo Win32.

  • Usar Load para carregar qualquer arquivo XAML em tempo de execução, em vez de compilar o XAML.

  • Não usar XAML algum e escvrever todo seu conteúdo WPF em código, construíndo a árvore de elementos de Application.

Use a abordagem que funcionar melhor para você.

Observação Observação

Se você não tiver usado C++/CLI antes, você poderá notar algumas palavras-chave novas, como gcnew e nullptr nos exemplos de código de interoperação. Essas palavras-chave substituem a antiga sintaxe com sublinhado duplo (__gc) e fornecem uma sintaxe mais natural para código gerenciado em C++. Para saber mais sobre os recursos de C++/CLI gerenciado, consulte Extensões de componente para plataformas de tempo de execução e Olá C++/CLI .

Para aproveitar ao máximo a "interoperabilidade HWND" do WPF, você precisará compreender como o WPF usa HWNDs. Para qualquer HWND, você não pode misturar renderização WPF com renderização DirectX ou com renderização GDI / GDI+. Isso tem um número de implicações. Basicamente, para misturar esses modelos de renderização, você deve criar uma solução de interoperabilidade e usar segmentos de interoperação designados para cada modelo de renderização que você escolher usar. Além disso, o comportamento de renderização cria uma restrição de "airspace" para o que sua solução de interoperação pode realizar. O conceito de "airspace" é explicado em detalhes no tópico Visão geral das regiões de tecnologia maior.

Todos os elementos WPF na tela são, em última instância, fundamentados em um HWND. Quando você cria uma Window WPF, o WPF cria um HWND de alto nível e usa um HwndSource para colocar a Window e seu conteúdo WPF dentro do HWND. O restante do seu conteúdo WPF no aplicativo compartilha aquele único HWND. Uma exceção são os menus, caixas de combinação e demais pop-ups. Esses elementos criam sua própria janela de alto nível, o que é o motivo pelo qual um menu WPF potencialmente pode passar da borda da janela HWND que a contém. Quando você usa HwndHost para colocar um HWND dentro do WPF, o WPF informa o Win32 como posicionar o novo filho HWND relativo ao HWND da Window WPF.

Um conceito relacionado a HWND é transparência dentro e entre cada HWND. Isso também é discutido no tópico Visão geral das regiões de tecnologia.

A chave para hospedar conteúdo WPF em uma janela Win32 é a classe HwndSource. Essa classe envolve o conteúdo WPF em uma janela Win32 para que o conteúdo WPF possa ser incorporado em sua interface do usuário (UI) como um janela filho. A abordagem a seguir combina a Win32 e WPF em um aplicativo único.

  1. Implemente o seu conteúdo WPF (o elemento conteúdo raiz) como uma classe gerenciada. Normalmente, a classe herda de uma das classes que podem conter vários elementos filho e/ou ser usadas como um elemento raiz, tais como DockPanel ou Page. Nas etapas subseqüentes, essa classe é chamada de classe de conteúdo WPF, e as instâncias da classe são chamadas de objetos de conteúdo WPF.

  2. Implemente um aplicativo Win32 como C++/CLI. Se você estiver começando com um aplicativo não gerenciado C++ já existente, você geralmente pode habilitá-lo a chamar código gerenciado alterando suas configurações de projeto para incluir a opção de compilador /clr (o escopo completo do que pode ser necessário para oferecer suporte à compilação /clr não é descrito neste tópico).

  3. Defina o modelo de segmentação como threaded apartment (STA). WPF usa este modelo.

  4. Trate a notificação WM_CREATE no procedimento de sua janela.

  5. Dentro do manipulador (ou de uma função que o manipulador chame), faça o seguinte:

    1. Crie um novo objeto HwndSource com o HWND da janela pai como seu parâmetro parent.

    2. Crie uma instância da sua classe de conteúdo WPF.

    3. Atribua uma referência ao objeto de conteúdo WPF à propriedade RootVisual do objeto HwndSource.

    4. A propriedade Handle do objeto HwndSource contém o manipulador de janela (HWND). Para obter um HWND que você possa usar na parte não gerenciada de seu aplicativo, converta Handle.ToPointer() para um HWND.

  6. Implemente uma classe gerenciada que contenha um campo estático que mantenha uma referência para seu objeto de conteúdo WPF. Esta classe permite que você obtenha uma referência para o objeto de conteúdo WPF a partir do seu código Win32, mas - mais importante - impede que seu HwndSource seja coletado inadvertidamente pelo coletor de lixo (GC).

  7. Receba notificações do objeto de conteúdo WPF anexando um manipulador a um ou mais eventos de objetos de conteúdo WPF.

  8. Comunique-se com o objeto de conteúdo de WPF usando a referência armazenada no campo estático para definir propriedades, métodos de chamada, etc..

Observação Observação

Você pode fazer algumas ou todas as definições de classes de conteúdo WPF do passo 1 em XAML usando a classe parcial padrão da classe de conteúdo, se você produzir um conjunto de módulos (assembly) separado e, em seguida, fizer referência a ele. Embora geralmente você incluia um objeto Application como parte da compilação XAML em um conjunto de módulos (assembly), você acaba não usando este Application como parte da interoperação, usa-se uma ou mais das classes raiz para os arquivos XAML referenciados pelo aplicativo e se referencia suas classes parciais. O restante do procedimento é esencialmente similar ao descrito acima.

Cada uma dessas etapas é ilustrada através de código no tópico Instruções passo a passo: hospedando conteúdo do WPF em Win32.

A chave para hospedar uma janela Win32 dentro de outro conteúdo WPF é a classe HwndHost. Essa classe envolve a janela em um elemento de WPF que pode ser adicionado a uma árvore de elemento de WPF . HwndHost também suporta APIs que permite que você executar tarefas como processar mensagens para a janela hospedada. O procedimento básico é o seguinte:

  1. Crie uma árvore de elementos para um aplicativo WPF (pode ser por meio de código ou usando linguagem de marcação). Localize um ponto adequado e apropriado na árvore de elementos onde a implementação de HwndHost pode ser adicionada como um elemento filho. No restante dessas etapas, esse elemento é chamado de elemento de reserva.

  2. Derive de HwndHost para criar um objeto que contém o seu conteúdo Win32.

  3. Na classe host, sobrescreva o método BuildWindowCore de HwndHost. Retorne o HWND da janela hospedada. Talvez você deseje envolver o(s) controle(s) com uma janela filho da janela retornada; envolver os controles em uma janela host fornece uma maneira simples para seu conteúdo WPF receber notificações dos controles. Esta técnica ajuda a corrigir alguns problemas do Win32 em relação ao tratamento de mensagens no limiar do controle hospedado.

  4. Sobrescreva os métodos DestroyWindowCore e WndProc de HwndHost. A intenção aqui é processar a limpeza e remover referências para o conteúdo hospedado, especialmente se você tiver criado referências a objetos não gerenciados.

  5. No seu arquvio de código, crie uma instância da classe que hospeda controles e torne-a um filho do elemento de reserva. Normalmente você poderia usar um tratador de eventos como o Loaded, ou o construtor de classe parcial. Mas você pode também adicionar o conteúdo de interoperação através de um comportamento de tempo de execução.

  6. Processe as mensagens de janela selecionadas, como notificações de controle por exemplo. Há duas abordagens. Ambas fornecem acesso idêntico ao fluxo de mensagens, portanto sua escolha é principalmente uma questão de conveniência de programação.

    • Implementar o processamento de todas as mensagens (não apenas mensagens de desligamento) em sua sobrescrita do método WndProc de HwndHost.

    • Fazer com que o elemento WPF de hospedagem processe as mensagens ao tratar o evento MessageHook. Este evento é gerado para cada mensagem que é enviada para o procedimento da janela principal da janela hospedada.

    • Você não pode processar as mensagens de janelas que estão fora do processo usando WndProc.

  7. Comunique-se com a janela hospedada usando invocação de plataforma para chamar a função não gerenciada SendMessage.

As seguintes etapas criam um aplicativo que funciona com a entrada do mouse. Você pode adicionar suporte a TAB para sua janela hospedada implementando a interface IKeyboardInputSink.

Cada uma dessas etapas é ilustrada através de código no tópico Instruções passo a passo: hospedando um controle Win32 no WPF.

ms742522.collapse_all(pt-br,VS.110).gifHwnds no WPF

Você pode pensar no HwndHost como um controle especial. (Tecnicamente, HwndHost é uma classe derivada de FrameworkElement , não uma classe derivada de Control , mas ele pode ser considerado um controle para fins de interoperação.) HwndHost abstrai a natureza de Win32 do conteúdo hospedado de forma que o restante de WPF considera o conteúdo hospedado ser outro controle como o objeto, que deve processar e processar a entrada. HwndHost geralmente se comporta como qualquer outro WPFFrameworkElement, embora existam algumas diferenças importantes em torno de saída (desenho e elementos gráficos) e de entrada (mouse e teclado) com base em limitações do que HWNDs subjacentes podem suportar.

ms742522.collapse_all(pt-br,VS.110).gifDiferenças perceptíveis no comportamento de saída

  • FrameworkElement que é a classe base de HwndHost, tem muito poucas propriedades que impliquem em alterações à interface do usuário. Estas incluem propriedades como FrameworkElement.FlowDirection, que altera o layout dos elementos que têm esse elemento como pai. No entanto, a maioria dessas propriedades não é mapeada para possíveis equivalentes Win32, mesmo se tais equivalentes podem existir. Um número excessivo dessas propriedades e seus significados são específicos demais da tecnologia de renderização para que mapeamentos sejam práticos. Portanto, definir propriedades como FlowDirection em HwndHost não tem efeito.

  • HwndHost não pode ser girado, escalado, inclinado ou afetados de algum outro modo por uma transformação.

  • HwndHost não tem suporte a propriedade Opacity (combinação do canal alfa). Se o conteúdo dentro do HwndHost executa operações de System.Drawing que incluem informações de canal alfa, isto não é propriametne uma violação, mas o HwndHost como um todo só oferece suporte a opacidade = 1,0 (100%).

  • O HwndHost será exibido sobre outros elementos WPF na mesma janela de alto nível. No entanto, um ToolTip ou um menu ContextMenu gerado estão em uma janela de alto nível separada e assim irão se comportar corretamente com o HwndHost.

  • O HwndHost não respeita a região de corte (clipping) de seu UIElement pai. Isso é potencialmente um problema se você tentar colocar uma classe HwndHost dentro de uma região de rolagem ou de um Canvas.

ms742522.collapse_all(pt-br,VS.110).gifDiferenças perceptíveis no comportamento de entrada

  • Em geral, enquanto os dispositivos de entrada tem escopo dentro da região Win32 hospedada pelo HwndHost, eventos de entrada vão diretamente para o Win32.

  • Enquanto o mouse está sobre o HwndHost, seu aplicativo não recebe eventos WPF de mouse, e o valor da propriedade IsMouseOver do WPF será false.

  • Enquanto o HwndHost tem o foco de teclado, seu aplicativo não recebe eventos WPF de teclado e o valor da propriedade IsKeyboardFocusWithin do WPF será false.

  • Quando o foco está dentro do HwndHost e muda para outro controle dentro do HwndHost, seu aplicativo não receberá os eventos GotFocus e LostFocus do WPF.

  • Propriedades e eventos relacionados a caneta (stylus) são análogas e não relatam informações enquanto a caneta está sobre o HwndHost.

As interfaces IKeyboardInputSink e IKeyboardInputSite permitem que você crie uma experiência de teclado uniforme para aplicativos mistos WPF e Win32:

  • Uso de TAB entre componentes Win32 e WPF

  • Mnemônicos e aceleradores que funcionam quando o foco estiver em um componente Win32 e quando ele estiver em um componente WPF.

As classes HwndHost e HwndSource fornecem implementações de IKeyboardInputSink, mas elas podem não tratar todas as mensagens de entrada que você deseje em cenários mais avançados. Sobrescreva os métodos apropriados para obter o comportamento de teclado desejado.

As interfaces somente oferecem suporte para o que acontece na transição entre as regiões WPF e Win32. Dentro da região Win32, o comportamento do uso da tecla TAB é inteiramente controlado pela lógica implementada pelo Win32, se houver.

Contribuições da comunidade

Mostrar:
© 2015 Microsoft