Compartilhar via


Demonstra Passo a passo: Hospedagem de conteúdo do Windows Presentation Foundation em um aplicativo Win32

Windows Presentation Foundation (WPF) provides a rich environment for creating applications. No entanto, quando você tem um investimento substancial em Win32 código, talvez seja mais efetivo adicionar WPF funcionalidade de seu aplicativo em vez de reescrever o código original. WPF Fornece um mecanismo simples para hospedagem WPF conteúdo em um Win32 janela.

Este tutorial descreve como escrever um aplicativo de exemplo, Hospedando o conteúdo do Windows Presentation Foundation em um exemplo de janela do Win32, que hospeda conteúdo WPF em uma janela Win32. Você pode estender este exemplo para hospedar qualquer janela Win32. Porque envolve a mistura de código gerenciado e não gerenciado, o aplicativo é escrito em C + + / CLI.

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

  • Requisitos
  • O Procedimento Básico
  • Implementando o Aplicativo Host
  • Implementando a Página WPF
  • Tópicos relacionados

Requisitos

This tutorial assumes a basic familiarity with both WPF and Win32 programming. For a basic introduction to WPF programming, see Guia de Introdução (WPF). Para uma introdução à programação Win32, consulte qualquer dos numerosos livros no assunto, em particular Programming Windows por Charles Petzold.

Porque o exemplo que acompanha este tutorial é implementado em C + + / CLI, este tutorial assume familiaridade com o uso de C++ para programar a Win32 API mais um conhecimento de programação de código gerenciado. Familiaridade com C + + / CLI é útil porém não essencial.

ObservaçãoObservação:

This tutorial includes a number of code examples from the associated sample. However, for readability, it does not include the complete sample code. Para obter o código de exemplo completo, consulte Hospedando o conteúdo do Windows Presentation Foundation em um exemplo de janela do Win32.

O Procedimento Básico

Esta seção descreve o procedimento básico para hospedar conteúdo WPF em uma janela Win32. As seções seguintes explicam os detalhes de cada passo.

A chave para hospedar conteúdo WPF em uma janela Win32 é a classe HwndSource. Esta classe envolve o conteúdo WPF em uma janela Win32, permitindo que esta seja incorporada à sua interface do usuário (UI) como uma janela filho. A abordagem a seguir combina a Win32 e WPF em um aplicativo único.

  1. Implemente seu conteúdo WPF como uma classe gerenciada.

  2. Implemente um aplicativo Win32 como C + + / CLI. Se estiver iniciando com um aplicativo já existente e código C++ não gerenciado, você normalmente poderá habilitá-lo a chamar código gerenciado alterando as configurações do projeto para incluir o sinalizador de compilação /clr.

  3. Defina o modelo de segmentação como compartimento de segmentação única (STA).

  4. Manipular o WM_CREATE notificação no seu procedimento de janela e faça o seguinte:

    1. Crie um novo objeto HwndSource com a 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 HwndSource.

    4. Obtenha o HWND para o conteúdo. A propriedade Handle do objeto HwndSource contém o identificador 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.

  5. Implemente uma classe gerenciada que contenha um campo estático que mantenha uma referência para seu conteúdo WPF. Esta classe permite que você obtenha uma referência para o conteúdo WPF a partir de seu código Win32.

  6. Atribua o conteúdo WPF ao campo estático.

  7. Receba notificações do conteúdo WPF anexando um tratador a um ou mais dos eventos WPF.

  8. Comunique com o conteúdo WPF usando a referência que você armazenou no campo estático para definir propriedades, e assim por diante.

ObservaçãoObservação:

Você também pode usar Extensible Application Markup Language (XAML) para implementar seu WPF conteúdo. Entretanto, você terá de compilar separadamente como uma biblioteca de vínculo dinâmico (DLL) e referenciar esta DLL do seu aplicativo Win32. O restante do procedimento é similar ao descrito acima.

Implementando o Aplicativo Host

Esta seção descreve como hospedar conteúdo WPF em um aplicativo Win32 básico. O conteúdo propriamente é implementado em C + + / CLI com uma classe gerenciada. Na maior parte, é programação WPF direta. Os aspectos chave da implementação de conteúdo são discutidos em Implementando Conteúdo WPF.

  • O Aplicativo Básico

  • Hospedando o Conteúdo WPF

  • Mantendo uma Referência para Conteúdo WPF

  • Comunicação com Conteúdo WPF

O Aplicativo Básico

O ponto de partida para o aplicativo host foi criar um modelo Microsoft Visual Studio 2005.

  1. Abra Visual Studio 2005, e selecioneNovo Projeto no menu Arquivo.

  2. Selecione Win32 da lista de tipos de projeto Visual C++. Caso sua linguagem padrão não seja C++, você encontrará estes tipos de projeto debaixo de Outros Idiomas.

  3. Selecione um modelo Win32 Project, atribua um nome ao projeto e clique OK para iniciar o Win32 Application Wizard.

  4. Aceite as configurações padrão do assistente e clique Concluir para iniciar o projeto.

O modelo cria um aplicativo Win32 básico, incluindo:

  • Um ponto de entrada para o aplicativo.

  • Uma janela, com o procedimento de janela associado (WndProc).

  • Um menu com cabeçalhos Arquivo e Ajuda. O menu Arquivo possui um item Fechar que fecha o aplicativo. O menu Ajuda possui um item Sobre que inicia uma caixa de diálogo simples.

Antes de iniciar a escrever código para hospedar o conteúdo WPF, você precisa fazer duas modificações no modelo básico.

A primeira é compilar o projeto como código gerenciado. Por padrão, o projeto compila como não gerenciado. Entretanto, porque WPF é implementado como código gerenciado, o projeto precisa ser compilado de acordo.

  1. Na Gerenciador de Soluções, clique com o botão direito do mouse para selecionar o projeto e selecione Propriedades a partir do menu de atalho. A caixa de diálogo Páginas de Propriedade do projeto aparece.

  2. Selecione Propriedades de Configuração no modo de exibição em árvore do painel à esquerda.

  3. Selecione suporte à Common Language Runtime na lista Padrões do Projeto do painel à direita.

  4. Selecione Suporte à Common Language Runtime (/clr) da caixa de lista suspensa.

ObservaçãoObservação:

Este sinalizador de compilação permite que você utilize código gerenciado no seu aplicativo, mas seu código não gerenciado continuará compilando como antes.

WPF usa o modelo de segmentação de compartimento de segmentação única (STA). Para funcionar corretamente com o código de conteúdo WPF, você precisa definir o modelo de segmentação do aplicativo para STA aplicando um atributo ao ponto de entrada.

Hospedando o Conteúdo WPF

O conteúdo WPF é um simples aplicativo para entrada de endereços. Ele consiste de vários controles TextBox para obter o nome de usuário, endereço, e assim em diante. Também tem dois controles Button, OK e Cancelar. Quando o usuário clica OK, o tratador de evento do botão Click coleta os dados dos controles TextBox, os atribui às propriedades correspondentes, e dispara um evento customizado, OnButtonClicked. Quando o usuário clica Cancelar, o tratador simplesmente dispara OnButtonClicked. O objeto argumento do evento para OnButtonClicked contém um campo Booleano que indica se o botão foi clicado.

O código para hospedar o WPF conteúdo é implementado em um manipulador para o WM_CREATE notificação na janela do host.

O método GetHwnd recebe informações de tamanho e posição mais um identificador da janela pai e retorna o indicador de janela do conteúdo hospedado WPF.

ObservaçãoObservação:

Você pode não Use um #using diretiva para o System::Windows::Interop namespace. Isso gera uma colisão de nomes entre o MSG estrutura no namespace e a estrutura de MSG declarado em winuser.h. Você deve usar nomes totalmente qualificados para acesso o Sumário do espaço para nomes.

Não se pode hospedar conteúdo WPF diretamente na sua janela de aplicativo. Ao invés disso, primeiro crie um objeto HwndSource para envolver o conteúdo WPF. Este objeto é basicamente uma janela projetada para hospedar conteúdo WPF. Você hospeda o objeto HwndSource na janela pai criando-o como filho de uma janela Win32 que seja parte de seu aplicativo. Os parâmetros do construtor HwndSource contém informações similares às que você passaria para CreateWindow ao criar uma janela Win32 filha.

Depois você cria uma instância do objeto conteúdo WPF. Neste caso, o conteúdo WPF é implementado como uma classe separada, WPFPage, usando C + + / CLI. Você também pode implementar conteúdo WPF com XAML. Entretanto, para fazer isto você precisa configurar um projeto separado e construir o conteúdo WPF como uma DLL. Você pode adicionar uma referência à DLL no seu projeto, e usá-la para criar uma instância do conteúdo WPF.

Você exibe o conteúdo WPF na sua janela filho atribuindo uma referência do conteúdo WPF à propriedade RootVisual do HwndSource.

A linha de código a seguir anexa um tratador de evento, WPFButtonClicked, ao evento OnButtonClicked do conteúdo WPF. Este tratador é chamado quando o usuário clica nos botões OK ou Cancelar. Consulte communicating_with_the_WPF content para mais informações sobre este tratador de eventos.

A linha de código final returna o identificador de janela (HWND) que é associado ao objeto HwndSource. Você pode usar este identificador de seu código Win32 para enviar mensagens à janela hospedada, apesar de o exemplo não fazê-lo. O objeto HwndSource dispara um evento a cada vez que recebe uma mensagem. Para processar as mensagens, chame o método AddHook para anexar um tratador de mensagem e depois processe a mensagem naquele tratador.

Mantendo uma Referência para Conteúdo WPF

Para muitos aplicativos, você desejará se comunicar com o conteúdo WPF posteriormente. Por exemplo, você pode desejar modificar as propriedades do conteúdo WPF, ou talvez fazer o objeto HwndSource hospedar um conteúdo WPF diferente. Para isso, você precisa de uma referência para o objeto HwndSource ou conteúdo WPF. O objeto HwndSource e seu conteúdo WPF associado permanecem em memória até que você destrua seu identificador de janela. Entretanto, a variável que você atribui ao objeto HwndSource sairá de escopo logo que você retorna do procedimento da janela. O modo habitual de tratar esta questão com aplicativos Win32 é usando uma variável estática ou global. Infelizmente, você não pode atribuir um objeto gerenciado a esses tipos de variáveis. Você pode atribuir um identificador de janela associado ao objeto HwndSource a uma variável global ou estática, mas isto não fornece acesso ao objeto propriamente.

A solução mais simples para esse questão é implementar uma classe gerenciada que contém um conjunto de campos estáticos para manter referências a quaisquer objetos gerenciados que você precise ter acesso. O exemplo usa a classe WPFPageHost para manter uma referência ao conteúdo WPF, mais os valores iniciais de várias propriedades que podem ser alteradas posteriormente pelo usuário. Isto é definido no cabeçalho.

A parte final da função GetHwnd atribui valores àqueles campos para uso posterior, enquanto myPage ainda está em escopo.

Comunicação com Conteúdo WPF

Existem dois tipos de comunicação com o conteúdo WPF. O aplicativo recebe informações do conteúdo WPF quando o usuário clica nos botões OK ou Cancelar. O aplicativo também possui uma UI que permite ao usuário alterar várias propriedades WPF, como a cor de fundo ou o tamanho padrão de fonte.

Como dito acima, quando o usuário qualquer botão o conteúdo WPF dispara um evento OnButtonClicked. O aplicativo anexa um tratador a este evento para receber essas notificações. Se o botão OK foi clicado, o tratador obtém as informações do usuário do conteúdo WPF e as exibe em uma série de controles.

O tratador recebe um objeto argumento do evento customizado do conteúdo WPF, MyPageEventArgs. A propriedade IsOK do objeto é definida como true se o botão OK foi clicado, e false se o botão Cancelar foi clicado.

Se o botão OK foi clicado, o tratador recebe uma referência para o conteúdo WPF da classe contêiner. Depois ele coleta informações do usuário mantidas pelas propriedades do conteúdo WPF associado e usa controles estáticos para exibir estas informações na janela pai. Porque os dados do conteúdo WPF estão na forma de string gerenciada, eles precisam ser empacotados para serem usador por um controle Win32. Se o botão Cancelar foi clicado, o tratador limpa os dados dos controles estáticos.

O aplicativo UI fornece um conjunto de botões de opção que permitem ao usuário modificar a cor do plano de fundo do conteúdo WPF, e diversas propriedades relacionados à fonte. O exemplo a seguir é um trecho do procedimento de janela do aplicativo (WndProc) e seu tratamento de mensagens que define várias propriedades em diferentes mensagens, incluindo a cor do plano de fundo. Os outros são similares, e não são exibidos. Veja o exemplo completo para detalhes e contexto.

Para definir a cor do plano de fundo, obtenha uma referência para o conteúdo WPF (hostedPage) do WPFPageHost e defina a propriedade cor do plano de fundo para a cor apropriada. O exemplo utiliza três opções de cor: a cor original, verde claro ou salmon luz. A cor de plano de fundo original é armazenada como um campo estático na classe WPFPageHost. Para ver as outras duas, crie um objeto SolidColorBrush e passe ao construtor um valor de cor estática do objeto Colors.

Implementando a Página WPF

Você pode hospedar e usar conteúdo WPF sem nenhum conhecimento da implementação. Se o conteúdo WPF tiver sido empacotado em uma DLL separada, ele pode ter sido construído em qualquer linguagem common language runtime (CLR). A seguir um breve passo a passo da implementação do C + + / CLI que foi usado no exemplo. Esta seção contém as seguintes subseções.

  • Layout

  • Retornando Dados à Janela Hospedeira

  • Definindo Propriedades WPF

Layout

The UI elementos de WPF conteúdo consistem em cinco TextBox controles, com associado Label controles: Nome, endereço, cidade, estado e CEP. Também tem dois controles Button, OK e Cancelar.

O conteúdo WPF é implementado na classe WPFPage. Layout é tratado com um elemento de layout Grid. A classe herda de Grid, o que efetivamente o torna o elemento de conteúdo WPF raiz.

O construtor de conteúdo WPF recebe a largura e altura exigidos, e dimensiona o Grid de acordo. Depois ele define o layout básico criando um conjunto de objetos ColumnDefinition e RowDefinition e adicionando-os ao objeto base Grid e às coleções ColumnDefinitions e RowDefinitions, respectivamente. Isto define uma grade com cinco linhas e sete colunas, com as dimensões determinadas pelos conteúdos das células.

Em seguida, o construtor adiciona os elementos UI ao Grid. O primeiro elemento é o texto do título, que é um controle Label centralizado na primeira linha da grade.

A linha seguinte contém o controle Label Nome e seu controle TextBox associado. Porque o mesmo código pode ser usado para cada par rótulo/caixa de texto, ele é colocado em um par de métodos privados e usado em todos os cinco pares rótulo/caixa de texto. Os métodos criam o controle apropriado, e chamam os métodos estáticos SetColumn e SetRow da classe Grid para posicionar os controles na célula apropriada. Depois do controle ser criado, o exemplo chama o método Add na propriedade Children do Grid para adicionar o controle ao grid. O código para adicionar os pares rótulo/caixa de texto restantes é similar. Consulte o código do exemplo para detalhes.

A implementação dos dois métodos é a seguinte:

Finalmente, o exemplo adiciona os botões OK e Cancelar e anexa o tratador de eventos aos eventos Click.

Retornando Dados à Janela Hospedeira

Quando qualquer botão é clicado, seu evento Click é disparado. A janela hospedeira poderia simplesmente anexar tratadores para esses eventos e obter os dados diretamente dos controles TextBox. O exemplo usa uma abordagem de certa forma menos direta. Ele trata o Click de dentro do conteúdo WPF, e depois dispara um evento customizado OnButtonClicked, para notificar o conteúdo WPF. Isto permite ao conteúdo WPF fazer alguma validação de parâmetro antes de notificar o hospedeiro. O tratador obtém o texto dos controles TextBox e os atribui às propriedades, das quais o hospedeiro pode recuperar as informações.

A declaração de evento, em WPFPage.h:

O tratador de evento Click, em WPFPage.cpp:

Definindo Propriedades WPF

O hospedeiro Win32 permite ao usuário alterar várias propriedades do conteúdo WPF. Do lado Win32, é simplesmente uma questão de alterar propriedades. A implementação na classe conteúdo WPF é de certa forma mais complicada, porque não existe uma propriedade global que controle a fonte para todos os controles. Ao invés disso, a propriedade adequada para cada controle é alterada nos acessadores set das propriedades. O exemplo a seguir mostra o código para a propriedade DefaultFontFamily. Definindo a propriedade um método privado é chamado que, por sua vez, define propriedades FontFamily para os vários controles.

Em WPFPage.h:

Em WPFPage.cpp:

Consulte também

Conceitos

Visão geral sobre interoperabilidade entre WPF e Win32

Referência

HwndSource