Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Program Windows Presentation Foundation (WPF) udostępnia bogate środowisko do tworzenia aplikacji. Jednak jeśli masz znaczną inwestycję w kod Win32, może być bardziej skuteczne dodanie funkcji WPF do aplikacji zamiast ponownego zapisywania oryginalnego kodu. WPF zapewnia prosty mechanizm hostowania zawartości WPF w oknie Win32.
W tym samouczku opisano sposób pisania przykładowej aplikacji hostingu zawartości WPF w przykładzie okna Win32 hostującego zawartość WPF w oknie Win32. Ten przykład można rozszerzyć tak, aby hostować dowolne okno Win32. Ponieważ obejmuje mieszanie kodu zarządzanego i niezarządzanego, aplikacja jest napisana w języku C++/CLI.
Wymagania
W tym samouczku założono podstawową znajomość programowania zarówno WPF, jak i Win32. Aby zapoznać się z podstawowym wprowadzeniem do programowania WPF, zobacz Wprowadzenie. Aby zapoznać się z wprowadzeniem do programowania Win32, należy odwołać się do dowolnej z licznych książek na ten temat, w szczególności programowania windows autorstwa Charlesa Petzolda.
Ponieważ przykład dołączony do tego samouczka jest implementowany w języku C++/CLI, w tym samouczku przyjęto założenie znajomości używania języka C++ do programowania interfejsu API systemu Windows oraz zrozumienia programowania kodu zarządzanego. Znajomość języka C++/CLI jest przydatna, ale nie jest niezbędna.
Uwaga / Notatka
Ten samouczek zawiera szereg przykładów kodu ze skojarzonego przykładu. Jednak w celu zapewnienia czytelności nie zawiera kompletnego przykładowego kodu. Pełny przykładowy kod można znaleźć w temacie Hostowanie zawartości WPF w przykładzie okna Win32.
Procedura podstawowa
W tej sekcji opisano podstawową procedurę służącą do hostowania zawartości WPF w oknie Win32. W pozostałych sekcjach opisano szczegóły poszczególnych kroków.
Kluczem do hostowania zawartości WPF w oknie Win32 jest HwndSource klasa . Ta klasa opakowuje zawartość WPF w oknie Win32, co pozwala na włączenie jej do interfejsu użytkownika jako okna podrzędnego. Poniższe podejście łączy win32 i WPF w jednej aplikacji.
Zaimplementuj zawartość WPF jako klasę zarządzaną.
Zaimplementuj aplikację systemu Windows przy użyciu języka C++/interfejsu wiersza polecenia. Jeśli zaczynasz od istniejącej aplikacji i niezarządzanego kodu języka C++, zwykle możesz włączyć wywoływanie kodu zarządzanego przez zmianę ustawień projektu w celu uwzględnienia flagi kompilatora
/clr.Ustaw model STA na jednowątkowy.
Obsłuż powiadomienie WM_CREATEw procedurze okna i wykonaj następujące czynności:
Utwórz nowy HwndSource obiekt z oknem nadrzędnym jako jego
parentparametrem.Utwórz wystąpienie klasy zawartości WPF.
Przypisz odwołanie do obiektu zawartości WPF do RootVisual właściwości HwndSource.
Uzyskaj HWND dla zawartości. Właściwość HandleHwndSource obiektu zawiera uchwyt okna (HWND). Aby uzyskać HWND do użycia w części niezarządzanej aplikacji, przekształć
Handle.ToPointer()na HWND.
Zaimplementuj klasę zarządzaną zawierającą pole statyczne do przechowywania odwołania do zawartości WPF. Ta klasa umożliwia uzyskanie odwołania do zawartości WPF z kodu Win32.
Przypisz zawartość WPF do pola statycznego.
Odbieranie powiadomień z zawartości WPF przez dołączenie programu obsługi do co najmniej jednego zdarzenia WPF.
Aby komunikować się z zawartością WPF, użyj odwołania przechowywanego w polu statycznym do ustawiania właściwości itp.
Uwaga / Notatka
Możesz również użyć zawartości Windows Presentation Foundation (WPF). Należy jednak skompilować ją oddzielnie jako bibliotekę DLL (dynamic-link), a następnie dokonać odwołania do tej biblioteki DLL w aplikacji Win32. Pozostała część procedury jest podobna do przedstawionej powyżej.
Implementowanie aplikacji hosta
W tej sekcji opisano sposób hostowania zawartości WPF w podstawowej aplikacji Win32. Sama zawartość jest implementowana w języku C++/CLI jako klasa zarządzana. W większości przypadków jest to proste programowanie WPF. Kluczowe aspekty implementacji zawartości zostały omówione w temacie Implementowanie zawartości WPF.
Podstawowa aplikacja
Punktem wyjścia dla aplikacji hosta było utworzenie szablonu programu Visual Studio 2005.
Otwórz program Visual Studio 2005 i wybierz pozycję Nowy projekt z menu Plik .
Wybierz pozycję Win32 z listy typów projektów Visual C++. Jeśli domyślny język nie jest językiem C++, te typy projektów znajdziesz w obszarze Inne języki.
Wybierz szablon projektu Win32 , przypisz nazwę do projektu i kliknij przycisk OK , aby uruchomić Kreatora aplikacji Win32.
Zaakceptuj ustawienia domyślne kreatora i kliknij przycisk Zakończ , aby uruchomić projekt.
Szablon tworzy podstawową aplikację Win32, w tym:
Punkt wejścia dla aplikacji.
Okno z powiązaną procedurą okna (WndProc).
Menu z nagłówkami Plik i Pomoc . W menu Plik znajduje się element Zakończ , który zamyka aplikację. Menu Pomoc zawiera element Informacje , który uruchamia proste okno dialogowe.
Przed rozpoczęciem pisania kodu do hostowania zawartości WPF należy wprowadzić dwie modyfikacje szablonu podstawowego.
Pierwszym z nich jest skompilowanie projektu jako kodu zarządzanego. Domyślnie projekt kompiluje się jako niezarządzany kod. Jednak ze względu na to, że WPF jest implementowany w kodzie zarządzanym, projekt musi być odpowiednio skompilowany.
Kliknij prawym przyciskiem myszy nazwę projektu w Eksploratorze rozwiązań i wybierz polecenie Właściwości z menu kontekstowego, aby uruchomić okno dialogowe Strony właściwości .
Wybierz Właściwości konfiguracji z widoku drzewa w lewym panelu.
Wybierz pozycję Obsługa środowiska uruchomieniowego języka wspólnego z listy Project Defaults w okienku po prawej stronie.
Z listy rozwijanej wybierz pozycję Obsługa środowiska uruchomieniowego języka wspólnego (/clr).
Uwaga / Notatka
Ta flaga kompilatora umożliwia używanie kodu zarządzanego w aplikacji, ale niezarządzany kod będzie nadal kompilowany tak jak poprzednio.
WPF używa modelu wątkowania jednowątkowego (STA). Aby prawidłowo pracować z kodem zawartości WPF, należy ustawić model wątków aplikacji na STA, stosując atrybut do punktu wejścia.
[System::STAThreadAttribute] //Needs to be an STA thread to play nicely with WPF
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
Hostowanie zawartości WPF
Zawartość WPF jest prostą aplikacją do wprowadzania adresów. Składa się z kilku TextBox kontrolek, które mają przyjmować nazwę użytkownika, adres itd. Istnieją również dwie Button kontrolki: OK i Anuluj. Gdy użytkownik kliknie przycisk OK, program obsługi zdarzeń przycisku Click zbiera dane z TextBox kontrolek, przypisuje je do odpowiednich właściwości i zgłasza zdarzenie niestandardowe. OnButtonClicked Gdy użytkownik kliknie Anuluj, procedura obsługi po prostu zgłosi OnButtonClicked. Obiekt argumentu zdarzenia dla OnButtonClicked zawiera logiczne pole wskazujące, który przycisk został kliknięty.
Kod hostowania zawartości WPF jest implementowany w procedurze obsługi dla powiadomienia WM_CREATE w oknie hosta.
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;
Metoda GetHwnd pobiera informacje dotyczące rozmiaru i pozycji oraz uchwyt okna nadrzędnego, a następnie zwraca uchwyt okna zawartości hostowanej w WPF.
Uwaga / Notatka
Nie można użyć dyrektywy #using dla przestrzeni nazw System::Windows::Interop. Spowoduje to utworzenie kolizji nazw między strukturą MSG w tej przestrzeni nazw a strukturą MSG zadeklarowaną w pliku winuser.h. Zamiast tego należy używać w pełni kwalifikowanych nazw, aby uzyskać dostęp do zawartości tej przestrzeni nazw.
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();
}
Nie można hostować zawartości WPF bezpośrednio w oknie aplikacji. Zamiast tego najpierw utwórz obiekt HwndSource w celu uwrapowania zawartości WPF. Ten obiekt jest w zasadzie oknem przeznaczonym do hostowania zawartości WPF. Obiekt HwndSource hostujesz w oknie nadrzędnym, tworząc go jako dziecko okna Win32, które jest częścią twojej aplikacji. HwndSource Parametry konstruktora zawierają praktycznie takie same informacje, które należy przekazać do funkcji CreateWindow przy tworzeniu okna podrzędnego Win32.
Następnie utworzysz wystąpienie obiektu zawartości WPF. W takim przypadku zawartość WPF jest implementowana jako oddzielna klasa , WPFPageprzy użyciu języka C++/CLI. Możesz również zaimplementować zawartość WPF za pomocą języka XAML. Jednak w tym celu należy skonfigurować oddzielny projekt i skompilować zawartość WPF jako bibliotekę DLL. Możesz dodać odwołanie do tej biblioteki DLL do projektu i użyć tego odwołania, aby utworzyć wystąpienie zawartości WPF.
Wyświetlasz zawartość WPF w oknie podrzędnym, przypisując referencję do zawartości WPF do właściwości RootVisual elementu HwndSource.
Następny wiersz kodu dołącza obsługujący zdarzenie, WPFButtonClicked, do zdarzenia zawartości OnButtonClicked WPF. Ta procedura obsługi jest wywoływana, gdy użytkownik kliknie przycisk OK lub Anuluj . Zobacz communicating_with_the_WPF content dla dalszej dyskusji na temat tego programu obsługi zdarzeń.
Ostatni wiersz pokazanego kodu zwraca uchwyt okna (HWND), który jest skojarzony z obiektem HwndSource . Możesz użyć tego uchwytu w kodzie Win32 do wysyłania komunikatów do okna hostowanego, chociaż przykład tego nie robi. Obiekt HwndSource zgłasza zdarzenie za każdym razem, gdy otrzymuje komunikat. Aby przetworzyć komunikaty, wywołaj metodę AddHook , aby dołączyć procedurę obsługi komunikatów, a następnie przetworzyć komunikaty w tej procedurze obsługi.
Przechowywanie odwołania do zawartości w systemie WPF
W przypadku wielu aplikacji warto później komunikować się z zawartością WPF. Możesz na przykład zmodyfikować właściwości zawartości WPF lub sprawić, aby obiekt HwndSource zawierał inną zawartość WPF. W tym celu potrzebne jest odwołanie do HwndSource obiektu lub zawartości WPF. Obiekt HwndSource i skojarzona zawartość WPF pozostają w pamięci do momentu zniszczenia uchwytu okna. Jednak zmienna przypisana do HwndSource obiektu będzie wychodzić z zakresu zaraz po powrocie z procedury okna. Standardowym sposobem obsługi tego problemu w aplikacjach Win32 jest użycie zmiennej statycznej lub globalnej. Niestety nie można przypisać obiektu zarządzanego do tych typów zmiennych. Uchwyt okna skojarzony z obiektem HwndSource można przypisać do zmiennej globalnej lub statycznej, ale nie zapewnia dostępu do samego obiektu.
Najprostszym rozwiązaniem tego problemu jest zaimplementowanie klasy zarządzanej zawierającej zestaw pól statycznych do przechowywania odwołań do wszystkich zarządzanych obiektów, do których potrzebujesz dostępu. W przykładzie WPFPageHost użyto klasy do przechowywania odwołania do zawartości WPF oraz początkowych wartości wielu jego właściwości, które mogą zostać później zmienione przez użytkownika. Jest to zdefiniowane w nagłówku.
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;
};
Druga część GetHwnd funkcji przypisuje wartości do tych pól do późniejszego użycia, chociaż myPage jest nadal w zakresie.
Komunikacja z zawartością WPF
Istnieją dwa typy komunikacji z zawartością WPF. Aplikacja odbiera informacje z zawartości WPF, gdy użytkownik kliknie przyciski OK lub Anuluj . Aplikacja ma również interfejs użytkownika, który umożliwia użytkownikowi zmianę różnych właściwości zawartości WPF, takich jak kolor tła lub domyślny rozmiar czcionki.
Jak wspomniano powyżej, gdy użytkownik kliknie dowolny przycisk, zawartość WPF zgłasza OnButtonClicked zdarzenie. Aplikacja dołącza program obsługi do tego zdarzenia, aby otrzymywać te powiadomienia. Jeśli przycisk OK został kliknięty, program obsługi pobiera informacje o użytkowniku z zawartości WPF i wyświetla go w zestawie kontrolek statycznych.
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: ");
}
}
Procedura obsługi zdarzeń otrzymuje niestandardowy obiekt argumentu zdarzenia z zawartości WPF. MyPageEventArgs Właściwość obiektu IsOK jest ustawiona na true wartość , jeśli przycisk OK został kliknięty, a false jeśli przycisk Anuluj został kliknięty.
Jeśli przycisk OK został kliknięty, program obsługi pobiera odwołanie do zawartości WPF z klasy kontenera. Następnie zbiera informacje o użytkowniku przechowywane przez skojarzone właściwości zawartości WPF i używa kontrolek statycznych do wyświetlania informacji w oknie nadrzędnym. Ponieważ dane zawartości WPF są w postaci ciągu zarządzanego, musi być przekazywane do użytku przez element sterujący Win32. Jeśli przycisk Anuluj został kliknięty, program obsługi czyści dane z kontrolek statycznych.
Interfejs użytkownika aplikacji udostępnia zestaw przycisków radiowych, które umożliwiają użytkownikowi modyfikowanie koloru tła zawartości WPF oraz kilka właściwości związanych z czcionką. W poniższym przykładzie przedstawiono fragment procedury okna aplikacji (WndProc) i jego obsługi komunikatów, który ustawia różne właściwości różnych komunikatów, w tym kolor tła. Pozostałe są podobne i nie są wyświetlane. Zobacz kompletny przykład, aby uzyskać szczegółowe informacje i kontekst.
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;
Aby ustawić kolor tła, pobierz odwołanie do zawartości WPF (hostedPage) z WPFPageHost i ustaw właściwość koloru tła na odpowiedni kolor. W przykładzie użyto trzech opcji kolorów: oryginalny kolor, jasnozielony lub jasny łosoś. Oryginalny kolor tła jest przechowywany jako pole statyczne w WPFPageHost klasie. Aby ustawić pozostałe dwa, należy utworzyć nowy SolidColorBrush obiekt i przekazać konstruktorowi wartość kolorów statycznych z Colors obiektu.
Implementowanie strony WPF
Możesz hostować i używać zawartości WPF bez znajomości rzeczywistej implementacji. Jeśli zawartość WPF została spakowana w osobnej biblioteki DLL, mogła zostać skompilowana w dowolnym języku środowiska uruchomieniowego języka wspólnego (CLR). Poniżej przedstawiono krótki przewodnik po implementacji języka C++/interfejsu wiersza polecenia, która jest używana w przykładzie. Ta sekcja zawiera następujące podsekcje.
Układ
Elementy interfejsu użytkownika w zawartości WPF składają się z pięciu TextBox kontrolek, z skojarzonymi Label kontrolkami: Name, Address, City, State i Zip. Istnieją również dwie Button kontrolki: OK i Anuluj
Zawartość WPF jest implementowana w WPFPage klasie . Układ jest obsługiwany za pomocą Grid elementu układu. Klasa dziedziczy z Grid, co skutecznie czyni ją elementem głównym treści w architekturze WPF.
Konstruktor zawartości WPF przyjmuje wymaganą szerokość i wysokość, a następnie odpowiednio dostosowuje rozmiar Grid. Następnie definiuje podstawowy układ, tworząc zestaw ColumnDefinition obiektów i RowDefinition i dodając je odpowiednio do Grid bazy ColumnDefinitions obiektów i RowDefinitions kolekcji. Definiuje siatkę pięciu wierszy i siedem kolumn z wymiarami określonymi przez zawartość komórek.
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]);
}
Następnie konstruktor dodaje elementy interfejsu użytkownika do elementu Grid. Pierwszy element to tekst tytułu, który jest kontrolką Label wyśrodkowaną w pierwszym wierszu siatki.
//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);
Następny wiersz zawiera kontrolkę Nazwa Label i powiązaną kontrolkę TextBox. Ponieważ ten sam kod jest używany dla każdej pary etykiet/pola tekstowego, jest umieszczany w parze metod prywatnych i używany dla wszystkich pięciu par etykiet/pola tekstowego. Metody tworzą odpowiednią kontrolkę i wywołują statyczne metody klasy GridSetColumn i SetRow, aby umieścić kontrolki w odpowiedniej komórce. Po utworzeniu kontrolki przykład wywołuje metodę Add na właściwości Children obiektu Grid, aby dodać kontrolkę do siatki. Kod dodawania pozostałych par etykiet/pola tekstowego jest podobny. Aby uzyskać szczegółowe informacje, zobacz przykładowy kod.
//Add the Name Label and TextBox
nameLabel = CreateLabel(0, 1, "Name");
this->Children->Add(nameLabel);
nameTextBox = CreateTextBox(1, 1, 3);
this->Children->Add(nameTextBox);
Implementacja tych dwóch metod jest następująca:
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;
}
Na koniec przykład dodaje przyciski OK i Anuluj oraz dołącza procedurę obsługi zdarzeń do ich Click zdarzeń.
//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);
Zwracanie danych do okna hosta
Po kliknięciu dowolnego przycisku zostanie wywołane jego Click zdarzenie. Okno hosta może po prostu dołączyć programy obsługi do tych zdarzeń i pobrać dane bezpośrednio z TextBox kontrolek. W przykładzie użyto nieco mniej bezpośredniego podejścia. Obsługuje Click w zawartości WPF, a następnie zgłasza niestandardowe zdarzenie OnButtonClicked, aby powiadomić zawartość WPF. Dzięki temu zawartość WPF może przeprowadzić weryfikację parametru przed powiadomieniem hosta. Program obsługi pobiera tekst z TextBox kontrolek i przypisuje go do właściwości publicznych, z których host może pobrać informacje.
Deklaracja zdarzenia w pliku WPFPage.h:
public:
delegate void ButtonClickHandler(Object ^, MyPageEventArgs ^);
WPFPage();
WPFPage(int height, int width);
event ButtonClickHandler ^OnButtonClicked;
Procedura Click obsługi zdarzeń w 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));
}
Ustawianie właściwości WPF
Host Win32 umożliwia użytkownikowi zmianę kilku właściwości zawartości WPF. Z boku Win32 jest to po prostu kwestia zmiany właściwości. Implementacja w klasie zawartości WPF jest nieco bardziej skomplikowana, ponieważ nie ma jednej właściwości globalnej, która kontroluje czcionki dla wszystkich kontrolek. Zamiast tego właściwość właściwa dla każdej kontrolki jest zmieniana w zestawach dostępu właściwości. W poniższym przykładzie pokazano kod właściwości DefaultFontFamily . Ustawienie właściwości wywołuje metodę prywatną, która z kolei ustawia FontFamily właściwości dla różnych kontrolek.
Z pliku WPFPage.h:
property FontFamily^ DefaultFontFamily
{
FontFamily^ get() {return _defaultFontFamily;}
void set(FontFamily^ value) {SetFontFamily(value);}
};
Z 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;
}
Zobacz także
.NET Desktop feedback