Procédure pas à pas : hébergement de contenu WPF dans Win32
Windows Presentation Foundation (WPF) fournit un environnement riche pour la création d’applications. Toutefois, lorsque vous avez un investissement substantiel dans le code Win32, il peut être plus efficace d’ajouter des fonctionnalités WPF à votre application plutôt que de réécrire votre code d’origine. WPF fournit un mécanisme simple pour l’hébergement de contenu WPF dans une fenêtre Win32.
Ce tutoriel explique comment écrire un exemple d'application, Hébergement de contenu WPF dans une fenêtre Win32, qui héberge du contenu WPF dans une fenêtre Win32. Vous pouvez étendre cet exemple pour héberger n’importe quelle fenêtre Win32. Étant donné qu’elle implique le mélange de code managé et non managé, l’application est écrite en C++/CLI.
Exigences
Ce tutoriel suppose une connaissance de base de la programmation WPF et Win32. Pour une présentation de base de la programmation WPF, consultez Prise en main. Pour une présentation de la programmation Win32, vous devez faire référence à l’un des nombreux livres sur le sujet, en particulier Programmation Windows par Charles Petzold.
Étant donné que l’exemple qui accompagne ce didacticiel est implémenté dans C++/CLI, ce didacticiel suppose que l’utilisation de C++ permet de programmer l’API Windows, ainsi qu’une compréhension de la programmation de code managé. La connaissance de C++/CLI est utile, mais pas essentielle.
Note
Ce tutoriel inclut plusieurs exemples de code de l’exemple associé. Toutefois, pour une lisibilité, il n’inclut pas l’exemple de code complet. Pour obtenir l’exemple de code complet, consultez Hébergement de contenu WPF dans un exemple de fenêtre Win32.
Procédure de base
Cette section décrit la procédure de base que vous utilisez pour héberger du contenu WPF dans une fenêtre Win32. Les sections restantes expliquent les détails de chaque étape.
La clé permettant d’héberger du contenu WPF dans une fenêtre Win32 est la classe HwndSource. Cette classe encapsule le contenu WPF dans une fenêtre Win32, ce qui lui permet d’être incorporé dans votre interface utilisateur en tant que fenêtre enfant. L’approche suivante combine win32 et WPF dans une seule application.
Implémentez votre contenu WPF en tant que classe managée.
Implémentez une application Windows avec C++/CLI. Si vous commencez par une application existante et un code C++ non managé, vous pouvez généralement l’activer pour appeler du code managé en modifiant les paramètres de votre projet pour inclure l’indicateur du compilateur
/clr
.Définissez le modèle de threading sur un appartement à un seul fil (STA).
Gérez la notification WM_CREATEdans votre procédure de fenêtre et procédez comme suit :
Créez un objet HwndSource avec la fenêtre parente comme paramètre
parent
.Créez une instance de votre classe de contenu WPF.
Affectez une référence à l’objet de contenu WPF à la propriété RootVisual du HwndSource.
Récupérez le HWND pour le contenu. La propriété Handle de l’objet HwndSource contient le handle de fenêtre (HWND). Pour obtenir un HWND que vous pouvez utiliser dans la partie non gérée de votre application, convertissez
Handle.ToPointer()
en HWND.
Implémentez une classe managée qui contient un champ statique pour contenir une référence à votre contenu WPF. Cette classe vous permet d’obtenir une référence au contenu WPF à partir de votre code Win32.
Affectez le contenu WPF au champ statique.
Recevez des notifications du contenu WPF en attachant un gestionnaire à un ou plusieurs des événements WPF.
Communiquez avec le contenu WPF à l’aide de la référence que vous avez stockée dans le champ statique pour définir les propriétés, et ainsi de suite.
Note
Vous pouvez également utiliser du contenu WPF. Toutefois, vous devez le compiler séparément en tant que bibliothèque de liens dynamiques (DLL) et référencer cette DLL à partir de votre application Win32. Le reste de la procédure est similaire à celui décrit ci-dessus.
Implémentation de l’application hôte
Cette section explique comment héberger du contenu WPF dans une application Win32 de base. Le contenu lui-même est implémenté en C++/CLI en tant que classe managée. Pour la plupart, il s’agit d’une programmation WPF simple. Les aspects clés de l’implémentation du contenu sont abordés dans Implémentation du contenu WPF.
Application de base
Le point de départ de l’application hôte était de créer un modèle Visual Studio 2005.
Ouvrez Visual Studio 2005, puis sélectionnez nouveau projet dans le menu Fichier.
Sélectionnez Win32 dans la liste des types de projets Visual C++. Si votre langue par défaut n’est pas C++, vous trouverez ces types de projet sous autres langues.
Sélectionnez un modèle projet Win32
, attribuez un nom au projet, puis cliquez sur OK pour lancer l’Assistant Application Win32. Acceptez les paramètres par défaut de l’Assistant, puis cliquez sur Terminer pour démarrer le projet.
Le modèle crée une application Win32 de base, notamment :
Point d’entrée de l’application.
Fenêtre, avec une procédure de fenêtre associée (WndProc).
Un menu avec Fichier et Aide en-têtes. Le menu Fichier contient un élément Quitter qui ferme l’application. Le menu Aide contient un élément About qui lance une boîte de dialogue simple.
Avant de commencer à écrire du code pour héberger le contenu WPF, vous devez apporter deux modifications au modèle de base.
La première consiste à compiler le projet en tant que code managé. Par défaut, le projet se compile en tant que code non managé. Toutefois, étant donné que WPF est implémenté dans le code managé, le projet doit être compilé en conséquence.
Cliquez avec le bouton droit sur le nom du projet dans Explorateur de solutions, puis sélectionnez Propriétés dans le menu contextuel pour lancer la boîte de dialogue Pages de propriétés.
Sélectionnez Propriétés de configuration dans l’arborescence du volet gauche.
Sélectionnez la prise en charge du Common Language Runtime dans la liste Project Defaults dans le volet droit.
Sélectionnez Prise en charge de Common Language Runtime (/clr) dans une zone de liste déroulante.
Remarque
Cet indicateur de compilateur vous permet d’utiliser du code managé dans votre application, mais votre code non managé est toujours compilé comme avant.
WPF utilise le modèle d'appartement à un seul thread (STA). Pour fonctionner correctement avec le code de contenu WPF, vous devez définir le modèle de thread de l’application sur STA en appliquant un attribut au point d’entrée.
[System::STAThreadAttribute] //Needs to be an STA thread to play nicely with WPF
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
Hébergement du contenu WPF
Le contenu WPF est une application d’entrée d’adresse simple. Il se compose de plusieurs contrôles TextBox pour recueillir le nom d'utilisateur, l'adresse, et autres informations. Il existe également deux contrôles Button, OK et Annuler. Lorsque l’utilisateur clique sur OK, le gestionnaire d’événements Click du bouton collecte les données à partir des contrôles TextBox, l’affecte aux propriétés correspondantes et déclenche un événement personnalisé, OnButtonClicked
. Lorsque l’utilisateur clique sur Annuler, le gestionnaire déclenche simplement OnButtonClicked
. L’objet d’argument d’événement pour OnButtonClicked
contient un champ booléen qui indique quel bouton a été cliqué.
Le code permettant d’héberger le contenu WPF est implémenté dans un gestionnaire pour la notification WM_CREATE sur la fenêtre hôte.
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;
La méthode GetHwnd
prend des informations de taille et de position, ainsi que le handle de fenêtre parent et retourne le handle de fenêtre du contenu WPF hébergé.
Note
Vous ne pouvez pas utiliser une directive #using
pour l’espace de noms System::Windows::Interop
. Cela crée une collision de noms entre la structure MSG dans cet espace de noms et la structure MSG déclarée dans winuser.h. Vous devez plutôt utiliser des noms complets pour accéder au contenu de cet espace de noms.
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();
}
Vous ne pouvez pas héberger le contenu WPF directement dans la fenêtre de votre application. Au lieu de cela, vous créez d’abord un objet HwndSource pour encapsuler le contenu WPF. Cet objet est essentiellement une fenêtre conçue pour héberger un contenu WPF. Vous hébergez l’objet HwndSource dans la fenêtre parente en le créant en tant qu’enfant d’une fenêtre Win32 qui fait partie de votre application. Les paramètres de constructeur HwndSource contiennent beaucoup les mêmes informations que celles que vous transmettez à CreateWindow lorsque vous créez une fenêtre enfant Win32.
Vous créez ensuite une instance de l’objet de contenu WPF. Dans ce cas, le contenu WPF est implémenté en tant que classe distincte, WPFPage
, à l’aide de C++/CLI. Vous pouvez également implémenter le contenu WPF avec XAML. Toutefois, pour ce faire, vous devez configurer un projet distinct et générer le contenu WPF en tant que DLL. Vous pouvez ajouter une référence à cette DLL à votre projet et l’utiliser pour créer une instance du contenu WPF.
Vous affichez le contenu WPF dans votre fenêtre enfant en affectant une référence au contenu WPF à la propriété RootVisual du HwndSource.
La ligne de code suivante attache un gestionnaire d’événements, WPFButtonClicked
, à l’événement de contenu WPF OnButtonClicked
. Ce gestionnaire est appelé lorsque l’utilisateur clique sur le bouton OK ou bouton Annuler. Consultez le contenu communicating_with_the_WPF pour une discussion plus approfondie sur ce gestionnaire d’événements.
La dernière ligne de code affichée retourne le handle de fenêtre (HWND) associé à l’objet HwndSource. Vous pouvez utiliser ce handle à partir de votre code Win32 pour envoyer des messages à la fenêtre hébergée, bien que l’exemple ne le fasse pas. L’objet HwndSource déclenche un événement chaque fois qu’il reçoit un message. Pour traiter les messages, appelez la méthode AddHook pour joindre un gestionnaire de messages, puis traitez les messages dans ce gestionnaire.
Conservation d’une référence au contenu WPF
Pour de nombreuses applications, vous souhaiterez communiquer avec le contenu WPF ultérieurement. Par exemple, vous souhaiterez peut-être modifier les propriétés de contenu WPF, ou avoir peut-être l’objet HwndSource hôte de contenu WPF différent. Pour ce faire, vous avez besoin d’une référence à l’objet HwndSource ou au contenu WPF. L’objet HwndSource et son contenu WPF associé restent en mémoire jusqu’à ce que vous détruisiez le handle de fenêtre. Toutefois, la variable que vous affectez à l’objet HwndSource sortira de la portée dès que vous quittiez la procédure de fenêtre. La façon habituelle de gérer ce problème avec les applications Win32 consiste à utiliser une variable statique ou globale. Malheureusement, vous ne pouvez pas affecter un objet managé à ces types de variables. Vous pouvez affecter le handle de la fenêtre associé à l'objet HwndSource à une variable globale ou statique, mais cela ne fournit pas l'accès à l'objet lui-même.
La solution la plus simple à ce problème consiste à implémenter une classe managée qui contient un ensemble de champs statiques pour contenir des références à tous les objets managés auxquels vous avez besoin d’accéder. L’exemple utilise la classe WPFPageHost
pour contenir une référence au contenu WPF, ainsi que les valeurs initiales d’un certain nombre de ses propriétés qui peuvent être modifiées ultérieurement par l’utilisateur. Cela est défini dans l’en-tête.
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;
};
La dernière partie de la fonction GetHwnd
attribue des valeurs à ces champs pour une utilisation ultérieure, tandis que myPage
est toujours accessible.
Communication avec le contenu WPF
Il existe deux types de communication avec le contenu WPF. L’application reçoit des informations du contenu WPF lorsque l’utilisateur clique sur les boutons OK ou Annuler. L’application dispose également d’une interface utilisateur qui permet à l’utilisateur de modifier différentes propriétés de contenu WPF, telles que la couleur d’arrière-plan ou la taille de police par défaut.
Comme mentionné ci-dessus, lorsque l’utilisateur clique sur l’un des deux boutons, le contenu WPF déclenche un événement OnButtonClicked
. L’application attache un gestionnaire à cet événement pour recevoir ces notifications. Si le bouton OK a été cliqué, le gestionnaire obtient les informations utilisateur à partir du contenu WPF et l’affiche dans un ensemble de contrôles statiques.
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: ");
}
}
Le gestionnaire reçoit un objet d’argument d’événement personnalisé à partir du contenu WPF, MyPageEventArgs
. La propriété IsOK
de l'objet est définie sur true
si le bouton OK a été cliqué, et sur false
si le bouton Annuler a été cliqué.
Si le bouton OK a été cliqué, le gestionnaire obtient une référence au contenu WPF de la classe de conteneur. Il collecte ensuite les informations utilisateur détenues par les propriétés de contenu WPF associées et utilise les contrôles statiques pour afficher les informations sur la fenêtre parente. Étant donné que les données de contenu WPF sont sous la forme d’une chaîne managée, elles doivent être marshalées pour être utilisées par un contrôle Win32. Si le bouton Annuler a été cliqué, le gestionnaire efface les données des contrôles statiques.
L’interface utilisateur de l’application fournit un ensemble de cases d’option qui permettent à l’utilisateur de modifier la couleur d’arrière-plan du contenu WPF et plusieurs propriétés liées à la police. L’exemple suivant est un extrait de la procédure de fenêtre de l’application (WndProc) et de sa gestion des messages qui définit différentes propriétés sur différents messages, y compris la couleur d’arrière-plan. Les autres sont similaires et ne sont pas affichés. Pour plus d’informations et de contexte, consultez l’exemple complet.
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;
Pour définir la couleur d’arrière-plan, obtenez une référence au contenu WPF (hostedPage
) à partir de WPFPageHost
et définissez la propriété de couleur d’arrière-plan sur la couleur appropriée. L’exemple utilise trois options de couleur : la couleur d’origine, le vert clair ou le saumon clair. La couleur d’arrière-plan d’origine est stockée en tant que champ statique dans la classe WPFPageHost
. Pour définir les deux autres, vous créez un objet SolidColorBrush et transmettez au constructeur une valeur de couleurs statiques à partir de l’objet Colors.
Implémentation de la page WPF
Vous pouvez héberger et utiliser le contenu WPF sans connaître l’implémentation réelle. Si le contenu WPF avait été empaqueté dans une DLL distincte, il aurait pu être généré dans n’importe quel langage CLR (Common Language Runtime). Voici une brève procédure pas à pas de l’implémentation C++/CLI utilisée dans l’exemple. Cette section contient les sous-sections suivantes.
Mise en page
Les éléments d’interface utilisateur du contenu WPF se composent de cinq contrôles TextBox, avec des contrôles Label associés : Nom, Adresse, Ville, État et Zip. Il existe également deux contrôles Button, OK et Annuler
Le contenu WPF est implémenté dans la classe WPFPage
. La disposition est gérée avec un élément de mise en page Grid. La classe hérite de Grid, ce qui en fait l’élément racine de contenu WPF.
Le constructeur de contenu WPF prend la largeur et la hauteur requises, et dimensionne le Grid en conséquence. Il définit ensuite la disposition de base en créant un ensemble d’objets ColumnDefinition et RowDefinition et en les ajoutant aux collections de base d’objets GridColumnDefinitions et RowDefinitions, respectivement. Cela définit une grille de cinq lignes et sept colonnes, avec les dimensions déterminées par le contenu des cellules.
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]);
}
Ensuite, le constructeur ajoute les éléments d’interface utilisateur au Grid. Le premier élément est le texte du titre, qui est un contrôle de type Label centré sur la première rangée de la grille.
//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);
La ligne suivante contient le contrôle Name Label et son contrôle TextBox associé. Étant donné que le même code est utilisé pour chaque paire étiquette/zone de texte, il est placé dans une paire de méthodes privées et utilisé pour les cinq paires étiquette/zone de texte. Les méthodes créent le contrôle approprié et appellent les méthodes statiques SetColumn et SetRow de la classe statique Grid pour placer les contrôles dans la cellule appropriée. Une fois le contrôle créé, l’exemple appelle la méthode Add sur la propriété Children du Grid pour ajouter le contrôle à la grille. Le code permettant d’ajouter les paires étiquette/zone de texte restantes est similaire. Pour plus d’informations, consultez l’exemple de code.
//Add the Name Label and TextBox
nameLabel = CreateLabel(0, 1, "Name");
this->Children->Add(nameLabel);
nameTextBox = CreateTextBox(1, 1, 3);
this->Children->Add(nameTextBox);
L’implémentation des deux méthodes est la suivante :
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;
}
Enfin, l’exemple ajoute les boutons OK et Annuler et attache un gestionnaire d’événements à leurs événements Click.
//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);
Renvoi des données à la fenêtre hôte
Lorsque l’un des boutons est cliqué, son événement Click est déclenché. La fenêtre hôte peut simplement attacher des gestionnaires à ces événements et obtenir les données directement à partir des contrôles TextBox. L’exemple utilise une approche un peu moins directe. Il gère l'Click dans le contenu WPF, puis déclenche un événement personnalisé OnButtonClicked
, pour notifier le contenu WPF. Cela permet au contenu WPF d’effectuer une validation de paramètre avant de notifier l’hôte. Le gestionnaire obtient le texte des contrôles TextBox et l’affecte aux propriétés publiques, à partir de laquelle l’hôte peut récupérer les informations.
Déclaration d’événement, dans WPFPage.h :
public:
delegate void ButtonClickHandler(Object ^, MyPageEventArgs ^);
WPFPage();
WPFPage(int height, int width);
event ButtonClickHandler ^OnButtonClicked;
Le gestionnaire d’événements Click, dans 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));
}
Définition des propriétés WPF
L’hôte Win32 permet à l’utilisateur de modifier plusieurs propriétés de contenu WPF. Du côté Win32, il s’agit simplement de modifier les propriétés. L’implémentation dans la classe de contenu WPF est un peu plus compliquée, car il n’existe aucune propriété globale unique qui contrôle les polices pour tous les contrôles. Au lieu de cela, la propriété appropriée pour chaque contrôle est modifiée dans les accesseurs définis par les propriétés. L’exemple suivant montre le code de la propriété DefaultFontFamily
. La définition de la propriété appelle une méthode privée qui définit à son tour les propriétés FontFamily pour les différents contrôles.
À partir de WPFPage.h :
property FontFamily^ DefaultFontFamily
{
FontFamily^ get() {return _defaultFontFamily;}
void set(FontFamily^ value) {SetFontFamily(value);}
};
À partir 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;
}
Voir aussi
.NET Desktop feedback