Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Windows Presentation Foundation (WPF) biedt een uitgebreide omgeving voor het maken van toepassingen. Als u echter een aanzienlijke investering in Win32-code hebt, is het mogelijk effectiever om WPF-functionaliteit toe te voegen aan uw toepassing in plaats van de oorspronkelijke code opnieuw te schrijven. WPF biedt een eenvoudig mechanisme voor het hosten van WPF-inhoud in een Win32-venster.
In deze handleiding wordt beschreven hoe u een voorbeeldapplicatie schrijft, Hosting WPF Content in a Win32 Window Sample, die WPF-inhoud in een Win32-venster host. U kunt dit voorbeeld uitbreiden om elk Win32-venster te hosten. Omdat het gaat om het combineren van beheerde en onbeheerde code, wordt de toepassing geschreven in C++/CLI.
Behoeften
In deze zelfstudie wordt ervan uitgegaan dat u bekend bent met zowel WPF- als Win32-programmering. Zie Aan de slag voor een eenvoudige inleiding tot WPF-programmering. Voor een inleiding tot Win32 programmeren, moet u verwijzen naar een van de vele boeken over het onderwerp, met name Programmeren van Windows door Charles Petzold.
Omdat het voorbeeld dat bij deze zelfstudie hoort, wordt geïmplementeerd in C++/CLI, wordt in deze zelfstudie ervan uitgegaan dat u bekend bent met het gebruik van C++ om de Windows-API te programmeren plus inzicht in programmeren van beheerde code. Bekendheid met C++/CLI is nuttig, maar niet essentieel.
Opmerking
Deze zelfstudie bevat een aantal codevoorbeelden uit het bijbehorende voorbeeld. Voor leesbaarheid bevat het echter niet de volledige voorbeeldcode. Zie WpF-inhoud hosten in een Win32-venstervoorbeeld voor de volledige voorbeeldcode.
De basisprocedure
In deze sectie wordt een overzicht gegeven van de basisprocedure die u gebruikt voor het hosten van WPF-inhoud in een Win32-venster. In de overige secties worden de details van elke stap uitgelegd.
De sleutel voor het hosten van WPF-inhoud in een Win32-venster is de HwndSource klasse. Deze klasse verpakt de WPF-inhoud in een Win32-venster, zodat deze kan worden opgenomen in uw gebruikersinterface (UI) als een onderliggend venster. De volgende benadering combineert win32 en WPF in één toepassing.
Implementeer uw WPF-inhoud als een beheerde klasse.
Implementeer een Windows-toepassing met C++/CLI. Als u begint met een bestaande toepassing en onbeheerde C++-code, kunt u deze meestal inschakelen om beheerde code aan te roepen door de projectinstellingen te wijzigen zodat deze de
/clrcompilervlag bevat.Stel het threadingmodel in op Single-Threaded Apartment (STA).
Werk de WM_CREATEmelding in uw vensterprocedure af en ga als volgt te werk:
Maak een nieuw HwndSource object met het bovenliggende venster als
parentparameter.Maak een exemplaar van uw WPF-inhoudsklasse.
Ken een referentie van het WPF-inhoudsobject toe aan de RootVisual eigenschap van de HwndSource.
Haal de HWND voor de inhoud op. De Handle eigenschap van het HwndSource object bevat de venstergreep (HWND). Als u een HWND wilt verkrijgen dat u kunt gebruiken in het onbeheerde deel van uw toepassing, cast dan
Handle.ToPointer()naar een HWND.
Implementeer een beheerde klasse die een statisch veld bevat om een verwijzing naar uw WPF-inhoud te bewaren. Met deze klasse kunt u een verwijzing krijgen naar de WPF-inhoud uit uw Win32-code.
Wijs de WPF-inhoud toe aan het statische veld.
Ontvang meldingen van de WPF-inhoud door een handler toe te voegen aan een of meer wpf-gebeurtenissen.
Communiceer met de WPF-inhoud met behulp van de verwijzing die u in het statische veld hebt opgeslagen om eigenschappen in te stellen, enzovoort.
Opmerking
U kunt ook WPF-inhoud gebruiken. U moet deze echter afzonderlijk compileren als een DLL (Dynamic Link Library) en verwijzen naar dat DLL-bestand vanuit uw Win32-toepassing. De rest van de procedure is vergelijkbaar met de procedure die hierboven wordt beschreven.
De implementatie van de hostapplicatie
In deze sectie wordt beschreven hoe u WPF-inhoud host in een eenvoudige Win32-toepassing. De inhoud zelf wordt geïmplementeerd in C++/CLI als een beheerde klasse. Voor het grootste deel is het eenvoudig WPF programmeren. De belangrijkste aspecten van de inhoudsdistributie worden besproken in het implementeren van de WPF-inhoud.
De basisapplicatie
Het beginpunt voor de hosttoepassing was het maken van een Visual Studio 2005-sjabloon.
Open Visual Studio 2005 en selecteer Nieuw project in het menu Bestand .
Selecteer Win32 in de lijst met Visual C++-projecttypen. Als uw standaardtaal niet C++ is, vindt u deze projecttypen onder Andere talen.
Selecteer een Win32-projectsjabloon , wijs een naam toe aan het project en klik op OK om de wizard Win32-toepassing te starten.
Accepteer de standaardinstellingen van de wizard en klik op Voltooien om het project te starten.
Met de sjabloon maakt u een eenvoudige Win32-toepassing, waaronder:
Een toegangspunt voor de toepassing.
Een venster, met een bijbehorende vensterprocedure (WndProc).
Een menu met koppen Bestand en Help . Het menu Bestand bevat een afsluititem waarmee de toepassing wordt gesloten. Het Menu Help bevat een item Info waarmee een eenvoudig dialoogvenster wordt gestart.
Voordat u begint met het schrijven van code om de WPF-inhoud te hosten, moet u twee wijzigingen aanbrengen in de basissjabloon.
De eerste is het compileren van het project als beheerde code. Standaard wordt het project gecompileerd als onbeheerde code. Omdat WPF echter in beheerde code is geïmplementeerd, moet het project dienovereenkomstig worden gecompileerd.
Klik met de rechtermuisknop op de projectnaam in Solution Explorer en selecteer Eigenschappen in het contextmenu om het dialoogvenster Eigenschappenpagina's te openen.
Selecteer Configuratie-eigenschappen in de structuurweergave in het linkerdeelvenster.
Selecteer Common Language Runtime-ondersteuning in de lijst Met standaardinstellingen van Project in het rechterdeelvenster.
Selecteer Common Language Runtime Support (/clr) in de vervolgkeuzelijst.
Opmerking
Met deze compilervlag kunt u beheerde code in uw toepassing gebruiken, maar uw onbeheerde code wordt nog steeds gecompileerd zoals voorheen.
WPF maakt gebruik van het sta-threadingmodel (single-threaded apartment). Als u goed wilt werken met de WPF-inhoudscode, moet u het threadingmodel van de toepassing instellen op STA door een kenmerk toe te passen op het toegangspunt.
[System::STAThreadAttribute] //Needs to be an STA thread to play nicely with WPF
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
De WPF-inhoud hosten
De WPF-inhoud is een eenvoudige toepassing voor adresinvoer. Het bestaat uit verschillende TextBox bedieningselementen voor het verzamelen van gebruikersnaam, adres, enzovoort. Er zijn ook twee Button besturingselementen, OK en Annuleren. Wanneer de gebruiker op OK klikt, verzamelt de gebeurtenis-handler van Click de knop de gegevens van de TextBox besturingselementen, wijst deze toe aan de bijbehorende eigenschappen en genereert een aangepaste gebeurtenis. OnButtonClicked Wanneer de gebruiker op Annuleren klikt, wordt de handler gewoon geactiveerd OnButtonClicked. Het gebeurtenisargumentobject voor OnButtonClicked bevat een Booleaans veld dat aangeeft op welke knop is geklikt.
De code voor het hosten van de WPF-inhoud wordt geïmplementeerd in een handler voor de WM_CREATE melding in het hostvenster.
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;
De GetHwnd methode neemt informatie over grootte en positie plus het oudervensterhandvat en retourneert het vensterhandvat van de gehoste WPF-inhoud.
Opmerking
U kunt geen #using instructie gebruiken voor de System::Windows::Interop naamruimte. Hierdoor ontstaat er een naamconflict tussen de MSG structuur in die naamruimte en de MSG-structuur die is gedeclareerd in winuser.h. U moet in plaats daarvan volledig gekwalificeerde namen gebruiken om toegang te krijgen tot de inhoud van die naamruimte.
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();
}
U kunt de WPF-inhoud niet rechtstreeks in uw toepassingsvenster hosten. In plaats daarvan maakt u eerst een HwndSource object om de WPF-inhoud te verpakken. Dit object is in feite een venster dat is ontworpen om een WPF-inhoud te hosten. U host het HwndSource object in het bovenliggende venster door het te maken als een onderliggend element van een Win32-venster dat deel uitmaakt van uw toepassing. De HwndSource constructorparameters bevatten veel dezelfde informatie die u zou doorgeven aan CreateWindow wanneer u een Win32-onderliggend venster maakt.
Vervolgens maakt u een exemplaar van het WPF-inhoudsobject. In dit geval wordt de WPF-inhoud geïmplementeerd als een afzonderlijke klasse, WPFPagemet C++/CLI. U kunt ook de WPF-inhoud implementeren met XAML. Hiervoor moet u echter een afzonderlijk project instellen en de WPF-inhoud bouwen als dll-bestand. U kunt een verwijzing naar dat DLL-bestand toevoegen aan uw project en deze verwijzing gebruiken om een exemplaar van de WPF-inhoud te maken.
U geeft de WPF-inhoud weer in het venster van uw kind door een verwijzing naar de WPF-inhoud toe te wijzen aan de RootVisual eigenschap van de HwndSource.
De volgende regel code koppelt een gebeurtenis-handler WPFButtonClicked, aan de WPF-inhoudsevenement OnButtonClicked . Deze handler wordt aangeroepen wanneer de gebruiker op de knop OK of Annuleren klikt. Zie communicating_with_the_WPF inhoud voor een verdere bespreking van deze eventhandler.
De laatste regel code die wordt weergegeven, retourneert de venstergreep (HWND) die is gekoppeld aan het HwndSource object. U kunt deze ingang van uw Win32-code gebruiken om berichten naar het gehoste venster te verzenden, hoewel het voorbeeld dit niet doet. Het HwndSource object genereert een gebeurtenis telkens wanneer het een bericht ontvangt. Als u de berichten wilt verwerken, roept u de AddHook methode aan om een berichthandler toe te voegen en vervolgens de berichten in die handler te verwerken.
Een verwijzing naar de WPF-inhoud bevatten
Voor veel toepassingen wilt u later communiceren met de WPF-inhoud. U kunt bijvoorbeeld de WPF-inhoudseigenschappen wijzigen of misschien het HwndSource-object verschillende WPF-inhoud laten hosten. Hiervoor hebt u een verwijzing naar het HwndSource object of de WPF-inhoud nodig. Het HwndSource object en de bijbehorende WPF-inhoud blijven in het geheugen totdat u de venstergreep vernietigt. De variabele die u aan het object toewijst, valt echter buiten het HwndSource bereik zodra u terugkeert uit de vensterprocedure. De aangepaste manier om dit probleem met Win32-toepassingen af te handelen, is door een statische of globale variabele te gebruiken. Helaas kunt u geen beheerd object toewijzen aan deze typen variabelen. U kunt de venstergreep die aan een object is HwndSource gekoppeld, toewijzen aan een globale of statische variabele, maar die heeft geen toegang tot het object zelf.
De eenvoudigste oplossing voor dit probleem is het implementeren van een beheerde klasse die een set statische velden bevat voor verwijzingen naar beheerde objecten waartoe u toegang nodig hebt. In het voorbeeld wordt de WPFPageHost klasse gebruikt om een verwijzing naar de WPF-inhoud te bewaren, plus de initiële waarden van een aantal eigenschappen die later door de gebruiker kunnen worden gewijzigd. Dit wordt gedefinieerd in de koptekst.
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;
};
In het laatste deel van de GetHwnd-functie worden waarden toegewezen aan die velden voor later gebruik, terwijl myPage nog steeds binnen het bereik is.
Communiceren met de WPF-inhoud
Er zijn twee soorten communicatie met de WPF-inhoud. De toepassing ontvangt informatie van de WPF-inhoud wanneer de gebruiker op de knoppen OK of Annuleren klikt. De toepassing heeft ook een gebruikersinterface waarmee de gebruiker verschillende WPF-inhoudseigenschappen kan wijzigen, zoals de achtergrondkleur of de standaardtekengrootte.
Zoals hierboven vermeld, wordt er een gebeurtenis gegenereerd wanneer de gebruiker op een van de OnButtonClicked knoppen klikt. De toepassing koppelt een handler aan deze gebeurtenis om deze meldingen te ontvangen. Als op de knop OK is geklikt, haalt de handler de gebruikersgegevens op uit de WPF-inhoud en wordt deze weergegeven in een set statische besturingselementen.
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: ");
}
}
De handler ontvangt een aangepast gebeurtenisargumentobject van de WPF-inhoud. MyPageEventArgs De eigenschap van IsOK het object is ingesteld op true als op de knop OK is geklikt en op false als op de knop Annuleren is geklikt.
Als op de knop OK is geklikt, krijgt de handler een verwijzing naar de WPF-inhoud van de containerklasse. Vervolgens worden de gebruikersgegevens verzameld die worden bewaard door de bijbehorende WPF-inhoudseigenschappen en worden de statische controles gebruikt om de informatie weer te geven in het oudervenster. Omdat de WPF-inhoudsgegevens de vorm hebben van een beheerde tekenreeks, moet deze worden gebruikt door een Win32-besturingselement. Als op de knop Annuleren is geklikt, wist de handler de gegevens van de statische bedieningselementen.
De gebruikersinterface van de toepassing biedt een set keuzerondjes waarmee de gebruiker de achtergrondkleur van de WPF-inhoud en verschillende lettertype-gerelateerde eigenschappen kan wijzigen. Het volgende voorbeeld is een fragment uit de vensterprocedure van de toepassing (WndProc) en de berichtafhandeling waarmee verschillende eigenschappen voor verschillende berichten worden ingesteld, inclusief de achtergrondkleur. De andere zijn vergelijkbaar en worden niet weergegeven. Zie het volledige voorbeeld voor details en context.
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;
Als u de achtergrondkleur wilt instellen, haalt u een verwijzing op naar de WPF-inhoud (hostedPage) van WPFPageHost en stelt u de eigenschap achtergrondkleur in op de juiste kleur. In het voorbeeld worden drie kleuropties gebruikt: de oorspronkelijke kleur, lichtgroen of lichte zalm. De oorspronkelijke achtergrondkleur wordt opgeslagen als een statisch veld in de WPFPageHost klasse. Als u de andere twee wilt instellen, maakt u een nieuw SolidColorBrush object en geeft u de constructor een waarde voor statische kleuren van het Colors object door.
De WPF-pagina implementeren
U kunt de WPF-inhoud hosten en gebruiken zonder enige kennis van de daadwerkelijke implementatie. Als de WPF-inhoud in een afzonderlijke DLL was verpakt, had deze kunnen worden ingebouwd in een common language runtime-taal (CLR). Hieronder volgt een kort overzicht van de C++/CLI-implementatie die in het voorbeeld wordt gebruikt. Deze sectie bevat de volgende subsecties.
Indeling
De ui-elementen in de WPF-inhoud bestaan uit vijf TextBox besturingselementen, met bijbehorende Label besturingselementen: Naam, Adres, Plaats, Staat en Zip. Er zijn ook twee Button besturingselementen: OK en Annuleren
De WPF-inhoud wordt geïmplementeerd in de WPFPage klasse. De indeling wordt beheerd met een Grid layoutelement. De klasse erft van Grid, waardoor het effectief het WPF-inhoudshoofdelement wordt.
De WPF-inhoudsconstructor neemt de vereiste breedte en hoogte, en past de grootte van Grid dienovereenkomstig aan. Vervolgens wordt de basisindeling gedefinieerd door een set ColumnDefinition en RowDefinition objecten te maken en deze respectievelijk toe te voegen aan de Grid objectbasis ColumnDefinitions en RowDefinitions verzamelingen. Hiermee definieert u een raster van vijf rijen en zeven kolommen, met de afmetingen die worden bepaald door de inhoud van de cellen.
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]);
}
Vervolgens voegt de constructor de UI-elementen toe aan de Grid. Het eerste element is de titeltekst, een Label besturingselement dat is gecentreerd in de eerste rij van het raster.
//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);
De volgende rij bevat het besturingselement Naam Label en het bijbehorende TextBox besturingselement. Omdat dezelfde code wordt gebruikt voor elk label-/tekstvakpaar, wordt deze in een paar privémethoden geplaatst en gebruikt voor alle vijf label-/tekstvakparen. De methoden maken het juiste besturingselement en roepen de Grid klasse statisch SetColumn aan en SetRow methoden aan om de besturingselementen in de juiste cel te plaatsen. Nadat het besturingselement is gemaakt, roept het voorbeeld de Add-methode aan op de Children-eigenschap van Grid om het aan het raster toe te voegen. De code voor het toevoegen van de resterende label-/tekstvakparen is vergelijkbaar. Zie de voorbeeldcode voor meer informatie.
//Add the Name Label and TextBox
nameLabel = CreateLabel(0, 1, "Name");
this->Children->Add(nameLabel);
nameTextBox = CreateTextBox(1, 1, 3);
this->Children->Add(nameTextBox);
De implementatie van de twee methoden is als volgt:
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;
}
Ten slotte voegt het voorbeeld de knoppen OK en Annuleren toe en koppelt een gebeurtenis-handler aan hun Click gebeurtenissen.
//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);
De gegevens retourneren naar het hostvenster
Wanneer op een van de knoppen wordt geklikt, wordt de Click gebeurtenis gegenereerd. Het hostvenster kan handlers eenvoudig aan deze gebeurtenissen koppelen en de gegevens rechtstreeks ophalen uit de TextBox besturingselementen. In het voorbeeld wordt een iets minder directe benadering gebruikt. Het verwerkt de Click binnen de WPF-inhoud en genereert vervolgens een aangepaste gebeurtenis OnButtonClicked om de WPF-inhoud te informeren. Hierdoor kan de WPF-inhoud enige parametervalidatie uitvoeren voordat de host wordt geïnformeerd. De handler haalt de tekst op uit de TextBox besturingselementen en wijst deze toe aan openbare eigenschappen, waaruit de host de informatie kan ophalen.
De gebeurtenisdeclaratie, in WPFPage.h:
public:
delegate void ButtonClickHandler(Object ^, MyPageEventArgs ^);
WPFPage();
WPFPage(int height, int width);
event ButtonClickHandler ^OnButtonClicked;
De Click eventhandler in 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));
}
De WPF-eigenschappen instellen
Met de Win32-host kan de gebruiker verschillende WPF-inhoudseigenschappen wijzigen. Vanuit de Win32-zijde is het gewoon een kwestie van het wijzigen van de eigenschappen. De implementatie in de WPF-inhoudsklasse is iets ingewikkelder, omdat er geen enkele globale eigenschap is waarmee de lettertypen voor alle besturingselementen worden beheerd. In plaats daarvan wordt de juiste eigenschap voor elk besturingselement gewijzigd in de set accessors van de eigenschappen. In het volgende voorbeeld ziet u de code voor de DefaultFontFamily eigenschap. Als u de eigenschap instelt, wordt een privémethode aangeroepen waarmee de FontFamily eigenschappen voor de verschillende besturingselementen worden ingesteld.
Van WPFPage.h:
property FontFamily^ DefaultFontFamily
{
FontFamily^ get() {return _defaultFontFamily;}
void set(FontFamily^ value) {SetFontFamily(value);}
};
Vanuit 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;
}
Zie ook
.NET Desktop feedback