Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Windows Presentation Foundation (WPF) fornece um ambiente avançado para a criação de aplicativos. No entanto, quando você tem um investimento substancial no código Win32, pode ser mais eficaz adicionar a funcionalidade WPF ao seu aplicativo em vez de reescrever o código original. WPF fornece um mecanismo simples para hospedar conteúdo WPF em uma janela Win32.
Este tutorial descreve como escrever um aplicativo de exemplo, Hospedando conteúdo WPF em um exemplo de janela Win32, que hospeda conteúdo WPF em uma janela Win32. Você pode estender este exemplo para hospedar qualquer janela do Win32. Como envolve a mistura de código gerenciado e não gerenciado, o aplicativo é escrito em C++/CLI.
Requerimentos
Este tutorial pressupõe uma familiaridade básica com a programação WPF e Win32. Para obter uma introdução básica à programação WPF, consulte Introdução. Para uma introdução à programação Win32, você deve consultar qualquer um dos inúmeros livros sobre o assunto, em particular Programming Windows de Charles Petzold.
Como o exemplo que acompanha este tutorial é implementado em C++/CLI, este tutorial pressupõe familiaridade com o uso de C++ para programar a API do Windows, além de uma compreensão da programação de código gerenciado. A familiaridade com C++/CLI é útil, mas não essencial.
Observação
Este tutorial inclui vários exemplos de código do exemplo associado. No entanto, para facilitar a leitura, ele não inclui o código de exemplo completo. Para obter o código de exemplo completo, consulte Hosting WPF Content in a Win32 Window Sample.
Procedimento de base
Esta seção descreve o procedimento básico que você usa para hospedar conteúdo WPF em uma janela do Win32. As restantes secções explicam os detalhes de cada etapa.
A chave para hospedar conteúdo WPF em uma janela Win32 é a HwndSource classe. Esta classe envolve o conteúdo do WPF em uma janela do Win32, permitindo que ele seja incorporado à interface do utilizador (UI) como uma janela filha. A abordagem a seguir combina o Win32 e WPF em um único aplicativo.
Implemente seu conteúdo WPF como uma classe gerenciada.
Implemente um aplicativo do Windows com C++/CLI. Se estiver a começar a partir de uma aplicação existente e código C++ não gerido, poderá normalmente habilitá-la para chamar código gerido alterando as definições do projeto para incluir o flag
/clrdo compilador.Defina o modelo de threading como apartamento de thread único (STA).
Manipule a notificação WM_CREATE no procedimento da janela e faça o seguinte:
Crie um novo objeto HwndSource com a janela pai como seu parâmetro
parent.Crie uma instância da sua classe de conteúdo WPF.
Atribua ao objeto de conteúdo WPF uma referência à propriedade RootVisual do HwndSource.
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 possa ser usado na parte não gerida da sua aplicação, converta
Handle.ToPointer()para um HWND.
Implemente uma classe gerenciada que contenha um campo estático para manter uma referência ao seu conteúdo WPF. Essa classe permite que você obtenha uma referência ao conteúdo do WPF do seu código Win32.
Atribua o conteúdo do WPF ao campo estático.
Receba notificações do conteúdo do WPF anexando um manipulador a um ou mais eventos do WPF.
Comunique-se com o conteúdo do WPF usando a referência que você armazenou no campo estático para definir propriedades e assim por diante.
Observação
Você também pode usar o conteúdo do WPF. No entanto, você terá que compilá-lo separadamente como uma biblioteca de vínculo dinâmico (DLL) e fazer referência a essa DLL do seu aplicativo Win32. O resto do procedimento é semelhante ao acima descrito.
Implementando o aplicativo host
Esta seção descreve como hospedar conteúdo WPF em um aplicativo Win32 básico. O conteúdo em si é implementado em C++/CLI como uma classe gerenciada. Na maioria das vezes, é uma programação WPF simples. Os principais aspetos da implementação de conteúdo são discutidos em Implementando o conteúdo do WPF.
A Aplicação Básica
O ponto de partida para o aplicativo host foi criar um modelo do Visual Studio 2005.
Abra o Visual Studio 2005 e selecione Novo projeto no menu Arquivo .
Selecione Win32 na lista de tipos de projeto Visual C++. Se o idioma padrão não for C++, você encontrará esses tipos de projeto em Outros idiomas.
Selecione um modelo de projeto Win32 , atribua um nome ao projeto e clique em OK para iniciar o Assistente de aplicativo Win32.
Aceite as configurações padrão do assistente e clique em Concluir para iniciar o projeto.
O modelo cria um aplicativo Win32 básico, incluindo:
Um ponto de entrada para o aplicativo.
Uma janela, com um procedimento de janela associado (WndProc).
Um menu com os títulos Arquivo e Ajuda . O menu Arquivo tem um item Sair que fecha o aplicativo. O menu Ajuda tem um item Sobre que inicia uma caixa de diálogo simples.
Antes de começar a escrever código para hospedar o conteúdo do WPF, você precisa fazer duas modificações no modelo básico.
O primeiro é compilar o projeto como código gerenciado. Por padrão, o projeto é compilado como código não gerenciado. No entanto, como o WPF é implementado em código gerenciado, o projeto deve ser compilado de acordo.
Clique com o botão direito do mouse no nome do projeto no Gerenciador de Soluções e selecione Propriedades no menu de contexto para iniciar a caixa de diálogo Páginas de Propriedades .
Selecione Propriedades de configuração na visualização em árvore no painel esquerdo.
Selecione Common Language Runtime support na lista Project Defaults no painel direito.
Selecione Common Language Runtime Support (/clr) na lista suspensa.
Observação
Esse sinalizador de compilador permite que você use código gerenciado em seu aplicativo, mas seu código não gerenciado ainda será compilado como antes.
O WPF usa o modelo de encadeamento de apartamento de uma única thread (STA). Para funcionar corretamente com o código de conteúdo do WPF, você deve definir o modelo de threading do aplicativo como STA aplicando um atributo ao ponto de entrada.
[System::STAThreadAttribute] //Needs to be an STA thread to play nicely with WPF
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
Hospedando o conteúdo do WPF
O conteúdo do WPF é um aplicativo de entrada de endereço simples. Ele consiste em vários TextBox controles para tomar nome de usuário, endereço e assim por diante. Há também dois Button controles, OK e Cancelar. Quando o usuário clica em OK, o manipulador de eventos do Click botão coleta os dados dos TextBox controles, atribui-os às propriedades correspondentes e gera um evento personalizado, OnButtonClicked. Quando o usuário clica em Cancelar, o manipulador simplesmente levanta OnButtonClicked. O objeto de argumento de evento para OnButtonClicked contém um campo booleano que indica qual botão foi clicado.
O código para alojar o conteúdo do WPF é implementado em um manipulador da notificação WM_CREATE na janela do host.
case WM_CREATE :
GetClientRect(hWnd, &rect);
wpfHwnd = GetHwnd(hWnd, rect.right-375, 0, 375, 250);
CreateDataDisplay(hWnd, 275, rect.right-375, 375);
CreateRadioButtons(hWnd);
break;
O GetHwnd método usa informações de tamanho e posição, além do identificador de janela pai e retorna o identificador de janela do conteúdo WPF hospedado.
Observação
Não é possível usar uma #using diretiva para o System::Windows::Interop namespace. Ao fazer isso, há uma colisão de nomes entre a estrutura MSG nesse namespace e a estrutura MSG declarada em winuser.h. Em vez disso, você deve usar nomes totalmente qualificados para acessar o conteúdo desse namespace.
HWND GetHwnd(HWND parent, int x, int y, int width, int height)
{
System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters(
"hi" // NAME
);
sourceParams->PositionX = x;
sourceParams->PositionY = y;
sourceParams->Height = height;
sourceParams->Width = width;
sourceParams->ParentWindow = IntPtr(parent);
sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD; // style
System::Windows::Interop::HwndSource^ source = gcnew System::Windows::Interop::HwndSource(*sourceParams);
WPFPage ^myPage = gcnew WPFPage(width, height);
//Assign a reference to the WPF page and a set of UI properties to a set of static properties in a class
//that is designed for that purpose.
WPFPageHost::hostedPage = myPage;
WPFPageHost::initBackBrush = myPage->Background;
WPFPageHost::initFontFamily = myPage->DefaultFontFamily;
WPFPageHost::initFontSize = myPage->DefaultFontSize;
WPFPageHost::initFontStyle = myPage->DefaultFontStyle;
WPFPageHost::initFontWeight = myPage->DefaultFontWeight;
WPFPageHost::initForeBrush = myPage->DefaultForeBrush;
myPage->OnButtonClicked += gcnew WPFPage::ButtonClickHandler(WPFButtonClicked);
source->RootVisual = myPage;
return (HWND) source->Handle.ToPointer();
}
Você não pode hospedar o conteúdo do WPF diretamente na janela do aplicativo. Em vez disso, você primeiro cria um HwndSource objeto para encapsular o conteúdo do WPF. Este objeto é basicamente uma janela que é projetada para hospedar um conteúdo WPF. Você aloja o objeto HwndSource na janela pai criando-o como filho de uma janela do Win32 que faz parte da sua aplicação. Os parâmetros do HwndSource construtor contêm praticamente as mesmas informações que se passariam para o CreateWindow ao criar uma janela filha Win32.
Em seguida, crie uma instância do objeto de conteúdo WPF. Nesse caso, o conteúdo do WPF é implementado como uma classe separada, WPFPageusando C++/CLI. Você também pode implementar o conteúdo do WPF com XAML. No entanto, para fazer isso, você precisa configurar um projeto separado e criar o conteúdo do WPF como uma DLL. Você pode adicionar uma referência a essa DLL ao seu projeto e usar essa referência para criar uma instância do conteúdo do WPF.
Você exibe o conteúdo do WPF na janela filho atribuindo uma referência ao conteúdo WPF à propriedade RootVisual do HwndSource.
A próxima linha de código anexa um manipulador de eventos, WPFButtonClicked, ao evento de conteúdo OnButtonClicked do WPF. Esse manipulador é chamado quando o usuário clica no botão OK ou Cancelar . Consulte communicating_with_the_WPF conteúdo para obter mais discussões sobre esse manipulador de eventos.
A linha final de código mostrada retorna o identificador de janela (HWND) associado ao HwndSource objeto. Você pode usar esse identificador do seu código Win32 para enviar mensagens para a janela hospedada, embora o exemplo não faça isso. O HwndSource objeto gera um evento toda vez que recebe uma mensagem. Para processar as mensagens, chame o AddHook método para anexar um manipulador de mensagens e, em seguida, processe as mensagens nesse manipulador.
Mantendo uma referência ao conteúdo do WPF
Para muitos aplicativos, você desejará se comunicar com o conteúdo do WPF mais tarde. Por exemplo, você pode querer modificar as propriedades de conteúdo do WPF ou talvez fazer com que o objeto hospede conteúdo HwndSource WPF diferente. Para fazer isto, é necessário ter uma referência ao objeto HwndSource ou ao conteúdo do WPF. O HwndSource objeto e seu conteúdo WPF associado permanecem na memória até que você destrua a alça da janela. No entanto, a variável que atribui ao objeto HwndSource sairá do escopo assim que se retornar do procedimento da janela. A maneira habitual de lidar com esse problema com aplicativos Win32 é usar uma variável estática ou global. Infelizmente, não é possível atribuir um objeto gerenciado a esses tipos de variáveis. Você pode atribuir o identificador de janela associado HwndSource ao objeto a uma variável global ou estática, mas isso não fornece acesso ao objeto em si.
A solução mais simples para esse problema é implementar uma classe gerenciada que contém um conjunto de campos estáticos para manter referências a quaisquer objetos gerenciados aos quais você precise acessar. O exemplo usa a WPFPageHost classe para manter uma referência ao conteúdo do WPF, além dos valores iniciais de várias de suas propriedades que podem ser alteradas posteriormente pelo usuário. Isso é definido no cabeçalho.
public ref class WPFPageHost
{
public:
WPFPageHost();
static WPFPage^ hostedPage;
//initial property settings
static System::Windows::Media::Brush^ initBackBrush;
static System::Windows::Media::Brush^ initForeBrush;
static System::Windows::Media::FontFamily^ initFontFamily;
static System::Windows::FontStyle initFontStyle;
static System::Windows::FontWeight initFontWeight;
static double initFontSize;
};
A última parte da GetHwnd função atribui valores a esses campos para uso posterior enquanto myPage ainda está no escopo.
Comunicar-se com o conteúdo do WPF
Existem dois tipos de comunicação com o conteúdo do WPF. O aplicativo recebe informações do conteúdo do WPF quando o usuário clica nos botões OK ou Cancelar . O aplicativo também tem uma interface do usuário que permite ao usuário alterar várias propriedades de conteúdo WPF, como a cor de fundo ou o tamanho da fonte padrão.
Como mencionado acima, quando o usuário clica em qualquer um dos botões, o conteúdo do WPF gera um OnButtonClicked evento. O aplicativo anexa um manipulador a esse evento para receber essas notificações. Se o botão OK foi clicado, o manipulador obtém as informações do usuário do conteúdo do WPF e as exibe em um conjunto de controles estáticos.
void WPFButtonClicked(Object ^sender, MyPageEventArgs ^args)
{
if(args->IsOK) //display data if OK button was clicked
{
WPFPage ^myPage = WPFPageHost::hostedPage;
LPCWSTR userName = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("Name: " + myPage->EnteredName).ToPointer();
SetWindowText(nameLabel, userName);
LPCWSTR userAddress = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("Address: " + myPage->EnteredAddress).ToPointer();
SetWindowText(addressLabel, userAddress);
LPCWSTR userCity = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("City: " + myPage->EnteredCity).ToPointer();
SetWindowText(cityLabel, userCity);
LPCWSTR userState = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("State: " + myPage->EnteredState).ToPointer();
SetWindowText(stateLabel, userState);
LPCWSTR userZip = (LPCWSTR) InteropServices::Marshal::StringToHGlobalAuto("Zip: " + myPage->EnteredZip).ToPointer();
SetWindowText(zipLabel, userZip);
}
else
{
SetWindowText(nameLabel, L"Name: ");
SetWindowText(addressLabel, L"Address: ");
SetWindowText(cityLabel, L"City: ");
SetWindowText(stateLabel, L"State: ");
SetWindowText(zipLabel, L"Zip: ");
}
}
O manipulador recebe um objeto de argumento de evento personalizado do conteúdo do WPF, MyPageEventArgs. A propriedade do IsOK 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 manipulador obtém uma referência ao conteúdo do WPF da classe container. Em seguida, ele coleta as informações do usuário que são mantidas pelas propriedades de conteúdo WPF associadas e usa os controles estáticos para exibir as informações na janela pai. Como os dados de conteúdo do WPF estão na forma de uma cadeia de caracteres gerenciada, eles devem ser empacotados para uso por um controle Win32. Se o botão Cancelar foi clicado, o manipulador limpa os dados dos controles estáticos.
A interface do usuário do aplicativo fornece um conjunto de botões de opção que permitem ao usuário modificar a cor do plano de fundo do conteúdo do WPF e várias propriedades relacionadas à 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 mensagens diferentes, incluindo a cor do plano de fundo. Os outros são semelhantes e não são mostrados. Consulte o exemplo completo para obter detalhes e contexto.
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
//Menu selections
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
//RadioButtons
case IDC_ORIGINALBACKGROUND :
WPFPageHost::hostedPage->Background = WPFPageHost::initBackBrush;
break;
case IDC_LIGHTGREENBACKGROUND :
WPFPageHost::hostedPage->Background = gcnew SolidColorBrush(Colors::LightGreen);
break;
case IDC_LIGHTSALMONBACKGROUND :
WPFPageHost::hostedPage->Background = gcnew SolidColorBrush(Colors::LightSalmon);
break;
Para definir a cor do plano de fundo, obtenha uma referência ao conteúdo do WPF (hostedPage) a partir de WPFPageHost e defina a propriedade da cor de fundo como a cor apropriada. A amostra usa três opções de cores: a cor original, verde claro ou salmão claro. A cor de fundo original é armazenada como um campo estático na WPFPageHost classe. Para definir os outros dois, crie um novo SolidColorBrush objeto e passe ao construtor um valor de cores estáticas do Colors objeto.
Implementando a página WPF
Você pode hospedar e usar o conteúdo do WPF sem qualquer conhecimento da implementação real. Se o conteúdo do WPF tivesse sido empacotado em uma DLL separada, ele poderia ter sido criado em qualquer linguagem CLR (Common Language Runtime). A seguir está um breve passo a passo da implementação C++/CLI usada no exemplo. Esta secção contém as seguintes subsecções.
Esquema
Os elementos da interface do usuário no conteúdo do WPF consistem em cinco TextBox controles, com controles associados Label : Name, Address, City, State e Zip. Há também dois Button controles, OK e Cancelar
O conteúdo WPF é implementado na classe WPFPage. O layout é gerido com um elemento de layout Grid. A classe herda de Grid, o que efetivamente a torna o elemento raiz do conteúdo do WPF.
O construtor de conteúdo WPF recebe a largura e altura necessárias e dimensiona o Grid de acordo com essas dimensões. Em seguida, ele define o layout básico criando um conjunto de e objetos e adicionando-os à ColumnDefinition base RowDefinition de GridColumnDefinitions objetos e RowDefinitions coleções, respectivamente. Isso define uma grade de cinco linhas e sete colunas, com as dimensões determinadas pelo conteúdo das células.
WPFPage::WPFPage(int allottedWidth, int allotedHeight)
{
array<ColumnDefinition ^> ^ columnDef = gcnew array<ColumnDefinition ^> (4);
array<RowDefinition ^> ^ rowDef = gcnew array<RowDefinition ^> (6);
this->Height = allotedHeight;
this->Width = allottedWidth;
this->Background = gcnew SolidColorBrush(Colors::LightGray);
//Set up the Grid's row and column definitions
for(int i=0; i<4; i++)
{
columnDef[i] = gcnew ColumnDefinition();
columnDef[i]->Width = GridLength(1, GridUnitType::Auto);
this->ColumnDefinitions->Add(columnDef[i]);
}
for(int i=0; i<6; i++)
{
rowDef[i] = gcnew RowDefinition();
rowDef[i]->Height = GridLength(1, GridUnitType::Auto);
this->RowDefinitions->Add(rowDef[i]);
}
Em seguida, o construtor adiciona os elementos da interface do usuário ao Grid. O primeiro elemento é o texto do título, que é um Label controle centralizado na primeira linha da grade.
//Add the title
titleText = gcnew Label();
titleText->Content = "Simple WPF Control";
titleText->HorizontalAlignment = System::Windows::HorizontalAlignment::Center;
titleText->Margin = Thickness(10, 5, 10, 0);
titleText->FontWeight = FontWeights::Bold;
titleText->FontSize = 14;
Grid::SetColumn(titleText, 0);
Grid::SetRow(titleText, 0);
Grid::SetColumnSpan(titleText, 4);
this->Children->Add(titleText);
A próxima linha contém o controle Name Label e seu controle associado TextBox . Como o mesmo código é usado para cada par rótulo/caixa de texto, ele é colocado em um par de métodos privados e usado para todos os cinco pares rótulo/caixa de texto. Os métodos criam o controle apropriado e chamam os métodos estáticos de classe Grid, SetColumn e SetRow para colocar os controles na célula apropriada. Depois que o controle é criado, o exemplo chama o método Add da propriedade Children do Grid para adicionar o controle à grelha. O código para adicionar os pares de rótulo/caixa de texto restantes é semelhante. Consulte o código de exemplo para obter detalhes.
//Add the Name Label and TextBox
nameLabel = CreateLabel(0, 1, "Name");
this->Children->Add(nameLabel);
nameTextBox = CreateTextBox(1, 1, 3);
this->Children->Add(nameTextBox);
A aplicação dos dois métodos é a seguinte:
Label ^WPFPage::CreateLabel(int column, int row, String ^ text)
{
Label ^ newLabel = gcnew Label();
newLabel->Content = text;
newLabel->Margin = Thickness(10, 5, 10, 0);
newLabel->FontWeight = FontWeights::Normal;
newLabel->FontSize = 12;
Grid::SetColumn(newLabel, column);
Grid::SetRow(newLabel, row);
return newLabel;
}
TextBox ^WPFPage::CreateTextBox(int column, int row, int span)
{
TextBox ^newTextBox = gcnew TextBox();
newTextBox->Margin = Thickness(10, 5, 10, 0);
Grid::SetColumn(newTextBox, column);
Grid::SetRow(newTextBox, row);
Grid::SetColumnSpan(newTextBox, span);
return newTextBox;
}
Finalmente, o exemplo adiciona os botões OK e Cancelar e anexa um manipulador de eventos aos seus Click eventos.
//Add the Buttons and atttach event handlers
okButton = CreateButton(0, 5, "OK");
cancelButton = CreateButton(1, 5, "Cancel");
this->Children->Add(okButton);
this->Children->Add(cancelButton);
okButton->Click += gcnew RoutedEventHandler(this, &WPFPage::ButtonClicked);
cancelButton->Click += gcnew RoutedEventHandler(this, &WPFPage::ButtonClicked);
Retornando os dados para a janela do host
Quando um dos botões é clicado, o respetivo evento Click é gerado. A janela do host poderia simplesmente anexar manipuladores a esses eventos e obter os dados diretamente dos TextBox controles. A amostra utiliza uma abordagem um pouco menos direta. Ele manipula o Click dentro do conteúdo do WPF e, em seguida, gera um evento OnButtonClicked personalizado para notificar o conteúdo do WPF. Isso permite que o conteúdo do WPF faça alguma validação de parâmetro antes de notificar o host. O manipulador obtém o texto dos TextBox controles e o atribui a propriedades públicas, das quais o host pode recuperar as informações.
A declaração de evento, em WPFPage.h:
public:
delegate void ButtonClickHandler(Object ^, MyPageEventArgs ^);
WPFPage();
WPFPage(int height, int width);
event ButtonClickHandler ^OnButtonClicked;
O Click manipulador de eventos, em WPFPage.cpp:
void WPFPage::ButtonClicked(Object ^sender, RoutedEventArgs ^args)
{
//TODO: validate input data
bool okClicked = true;
if(sender == cancelButton)
okClicked = false;
EnteredName = nameTextBox->Text;
EnteredAddress = addressTextBox->Text;
EnteredCity = cityTextBox->Text;
EnteredState = stateTextBox->Text;
EnteredZip = zipTextBox->Text;
OnButtonClicked(this, gcnew MyPageEventArgs(okClicked));
}
Definindo as propriedades do WPF
O host Win32 permite que o usuário altere várias propriedades de conteúdo WPF. Do lado do Win32, é simplesmente uma questão de alterar as propriedades. A implementação na classe de conteúdo WPF é um pouco mais complicada, porque não há uma única propriedade global que controla as fontes para todos os controles. Em vez disso, a propriedade apropriada para cada controle é alterada nos acessadores de conjunto de propriedades. O exemplo a seguir mostra o código da DefaultFontFamily propriedade. Ajustar a propriedade aciona um método privado que, por sua vez, ajusta as propriedades FontFamily para os vários controlos.
De WPFPage.h:
property FontFamily^ DefaultFontFamily
{
FontFamily^ get() {return _defaultFontFamily;}
void set(FontFamily^ value) {SetFontFamily(value);}
};
De WPFPage.cpp:
void WPFPage::SetFontFamily(FontFamily^ newFontFamily)
{
_defaultFontFamily = newFontFamily;
titleText->FontFamily = newFontFamily;
nameLabel->FontFamily = newFontFamily;
addressLabel->FontFamily = newFontFamily;
cityLabel->FontFamily = newFontFamily;
stateLabel->FontFamily = newFontFamily;
zipLabel->FontFamily = newFontFamily;
}
Ver também
.NET Desktop feedback