Bagikan melalui


Panduan: Hosting Konten WPF di Win32

Windows Presentation Foundation (WPF) menyediakan lingkungan yang kaya untuk membuat aplikasi. Namun, ketika Anda memiliki investasi besar dalam kode Win32, mungkin lebih efektif untuk menambahkan fungsionalitas WPF ke aplikasi Anda daripada menulis ulang kode asli Anda. WPF menyediakan mekanisme mudah untuk menghosting konten WPF di jendela Win32.

Tutorial ini menjelaskan cara menulis aplikasi sampel, Hosting Konten WPF dalam Sampel Jendela Win32, yang menghosting konten WPF di jendela Win32. Anda dapat memperluas sampel ini untuk menghosting jendela Win32 apa pun. Karena melibatkan pencampuran kode terkelola dan tidak terkelola, aplikasi ditulis dalam C++/CLI.

Persyaratan

Tutorial ini mengasumsikan keakraban dasar dengan pemrograman WPF dan Win32. Untuk pengenalan dasar pemrograman WPF, lihat Memulai. Untuk pengantar pemrograman Win32, Anda dapat merujuk salah satu dari banyak buku tentang subjek tersebut, khususnya Pemrograman Windows oleh Charles Petzold.

Karena sampel yang menyertai tutorial ini diimplementasikan dalam C++/CLI, tutorial ini mengasumsikan pemahaman tentang penggunaan C++ untuk memprogram WINDOWS API ditambah pemahaman tentang pemrograman kode terkelola. Keakraban dengan C++/CLI sangat membantu tetapi tidak penting.

Nota

Tutorial ini mencakup sejumlah contoh kode dari sampel terkait. Namun, untuk keterbacaan, kode sampel lengkap tidak disertakan. Untuk kode sampel lengkap, lihat Hosting Konten WPF dalam Sampel Jendela Win32.

Prosedur Dasar

Bagian ini menguraikan prosedur dasar yang Anda gunakan untuk menghosting konten WPF di jendela Win32. Bagian yang tersisa menjelaskan detail setiap langkah.

Kunci untuk menghosting konten WPF di jendela Win32 adalah kelas HwndSource. Kelas ini membungkus konten WPF di jendela Win32, memungkinkannya dimasukkan ke dalam antarmuka pengguna (UI) Anda sebagai jendela anak. Pendekatan berikut menggabungkan Win32 dan WPF dalam satu aplikasi.

  1. Terapkan konten WPF Anda sebagai kelas terkelola.

  2. Menerapkan aplikasi Windows dengan C++/CLI. Jika Anda memulai dengan aplikasi yang ada dan kode C++ yang tidak dikelola, Anda biasanya dapat mengaktifkannya untuk memanggil kode terkelola dengan mengubah pengaturan proyek Anda untuk menyertakan bendera pengkompilasi /clr.

  3. Atur model utas ke apartemen berulir tunggal (STA).

  4. Tangani pemberitahuan WM_CREATEdi prosedur penanganan jendela Anda dan lakukan hal berikut:

    1. Buat objek HwndSource baru dengan jendela induk sebagai parameter parent.

    2. Buat instans kelas konten WPF Anda.

    3. Tetapkan referensi objek konten WPF ke properti RootVisual dari HwndSource.

    4. Dapatkan HWND untuk konten. Properti Handle dari objek HwndSource berisi pegangan jendela (HWND). Untuk mendapatkan HWND yang dapat Anda gunakan di bagian aplikasi yang tidak dikelola, transmisikan Handle.ToPointer() ke HWND.

  5. Terapkan kelas terkelola yang berisi bidang statis untuk menyimpan referensi ke konten WPF Anda. Kelas ini memungkinkan Anda untuk mendapatkan referensi ke konten WPF dari kode Win32 Anda.

  6. Tetapkan konten WPF ke bidang statis.

  7. Terima pemberitahuan dari konten WPF dengan menghubungkan pengolah ke satu atau beberapa peristiwa WPF.

  8. Berkomunikasi dengan konten WPF dengan menggunakan referensi yang Anda simpan di bidang statis untuk mengatur properti, dan sebagainya.

Nota

Anda juga dapat menggunakan konten WPF. Namun, Anda harus mengkompilasinya secara terpisah sebagai pustaka tautan dinamis (DLL) dan mereferensikan DLL tersebut dari aplikasi Win32 Anda. Sisa prosedur mirip dengan yang diuraikan di atas.

Menerapkan Aplikasi Host

Bagian ini menjelaskan cara menghosting konten WPF dalam aplikasi Win32 dasar. Konten itu sendiri diimplementasikan dalam C++/CLI sebagai kelas terkelola. Pada umumnya, ini adalah pemrograman WPF yang sederhana. Aspek utama implementasi konten dibahas dalam Menerapkan Konten WPF.

Aplikasi Dasar

Titik awal untuk aplikasi host adalah membuat templat Visual Studio 2005.

  1. Buka Visual Studio 2005, dan pilih Proyek Baru dari menu File.

  2. Pilih Win32 dari daftar jenis proyek Visual C++. Jika bahasa default Anda bukan C++, Anda akan menemukan jenis proyek ini di bawah Bahasa Lain.

  3. Pilih template Win32 Project, berikan nama pada proyek dan klik OK untuk meluncurkan Win32 Application Wizard.

  4. Terima pengaturan default wizard dan klik Selesaikan untuk memulai proyek.

Templat membuat aplikasi Win32 dasar, termasuk:

  • Titik masuk untuk aplikasi.

  • Jendela, dengan prosedur jendela terkait (WndProc).

  • Menu dengan judul File dan Bantuan. Menu File memiliki item Keluar yang menutup aplikasi. Menu Bantuan memiliki item Tentang yang meluncurkan kotak dialog sederhana.

Sebelum Anda mulai menulis kode untuk menghosting konten WPF, Anda perlu membuat dua modifikasi pada templat dasar.

Yang pertama adalah mengkompilasi proyek sebagai kode terkelola. Secara default, proyek dikompilasi sebagai kode yang tidak dikelola. Namun, karena WPF diimplementasikan dalam kode terkelola, proyek harus dikompilasi dengan sesuai.

  1. Klik kanan nama proyek di Penjelajah Solusi dan pilih Properti dari menu konteks untuk meluncurkan kotak dialog Halaman Properti.

  2. Pilih Properti Konfigurasi dari tampilan pohon di panel kiri.

  3. Pilih dukungan Common Language Runtime dari daftar Project Defaults di panel kanan.

  4. Pilih Dukungan Common Language Runtime (/clr) dari kotak daftar drop-down.

Nota

Bendera kompilator ini memungkinkan Anda menggunakan kode terkelola di aplikasi Anda, tetapi kode Anda yang tidak dikelola masih akan dikompilasi seperti sebelumnya.

WPF menggunakan model apartemen berutas tunggal (STA). Agar dapat berfungsi dengan benar bersama kode konten WPF, Anda harus mengatur model utas aplikasi ke STA dengan menambahkan atribut pada titik masuk.

[System::STAThreadAttribute] //Needs to be an STA thread to play nicely with WPF
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{

Menyajikan Konten WPF

Konten WPF adalah aplikasi entri alamat sederhana. Ini terdiri dari beberapa kontrol TextBox untuk mengambil nama pengguna, alamat, dan sebagainya. Ada juga dua kontrol Button, ok dan Batalkan. Saat pengguna mengklik OK, penangan peristiwa tombol Click mengumpulkan data dari kontrol TextBox, menetapkannya ke properti yang sesuai, dan memicu peristiwa kustom, OnButtonClicked. Ketika pengguna mengklik Batalkan, handler hanya menaikkan OnButtonClicked. Objek argumen peristiwa untuk OnButtonClicked berisi bidang Boolean yang menunjukkan tombol mana yang diklik.

Kode untuk menghosting konten WPF diimplementasikan dalam handler untuk pemberitahuan WM_CREATE di jendela 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;

Metode GetHwnd memperoleh informasi ukuran dan posisi, ditambah handle jendela induk, dan mengembalikan handle jendela dari konten WPF yang sedang dihosting.

Nota

Anda tidak dapat menggunakan direktif #using untuk namespace System::Windows::Interop. Melakukan hal tersebut menyebabkan tabrakan nama antara struktur MSG dalam namespace layanan tersebut dan struktur MSG yang dideklarasikan dalam winuser.h. Anda harus menggunakan nama yang sepenuhnya memenuhi syarat untuk mengakses konten namespace tersebut.

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();
}

Anda tidak dapat menghosting konten WPF langsung di jendela aplikasi Anda. Sebagai gantinya, Anda terlebih dahulu membuat objek HwndSource untuk membungkus konten WPF. Objek ini pada dasarnya adalah jendela yang dirancang untuk menghosting konten WPF. Anda menghosting objek HwndSource di jendela induk dengan membuatnya sebagai anak dari jendela Win32 yang merupakan bagian dari aplikasi Anda. Parameter konstruktor HwndSource berisi banyak informasi yang sama yang akan Anda teruskan ke CreateWindow saat Anda membuat jendela anak Win32.

Anda selanjutnya membuat instans objek konten WPF. Dalam hal ini, konten WPF diimplementasikan sebagai kelas terpisah, WPFPage, menggunakan C++/CLI. Anda juga dapat menerapkan konten WPF dengan XAML. Namun, untuk melakukannya, Anda perlu menyiapkan proyek terpisah dan membangun konten WPF sebagai DLL. Anda dapat menambahkan referensi ke DLL tersebut ke proyek Anda, dan menggunakan referensi tersebut untuk membuat instans konten WPF.

Anda menampilkan konten WPF di jendela anak Anda dengan menetapkan referensi ke konten WPF ke properti RootVisualHwndSource.

Baris kode berikutnya melampirkan pengendali acara, WPFButtonClicked, ke acara konten WPF OnButtonClicked. Handler ini dipanggil ketika pengguna mengklik tombol OK atau Batalkan. Lihat konten communicating_with_the_WPF untuk pembahasan lebih lanjut mengenai penangan kejadian ini.

Baris akhir kode yang ditampilkan mengembalikan handel jendela (HWND) yang terkait dengan objek HwndSource. Anda dapat menggunakan handle ini dalam kode Win32 Anda untuk mengirim pesan ke jendela yang dihosting, meskipun contoh tidak melakukannya. Objek HwndSource memunculkan peristiwa setiap kali menerima pesan. Untuk memproses pesan, panggil metode AddHook untuk melampirkan handler pesan lalu proses pesan di handler tersebut.

Menyimpan Referensi ke Konten WPF

Untuk banyak aplikasi, Anda akan ingin berkomunikasi dengan konten WPF nanti. Misalnya, Anda mungkin ingin mengubah properti konten WPF, atau mungkin memiliki objek HwndSource menghosting konten WPF yang berbeda. Untuk melakukan ini, Anda memerlukan referensi ke objek HwndSource atau konten WPF. Objek HwndSource dan konten WPF terkait tetap berada di memori sampai Anda menghancurkan handle jendela. Namun, variabel yang Anda tetapkan ke objek HwndSource akan keluar dari cakupan segera setelah Anda kembali dari prosedur jendela. Cara kustom untuk menangani masalah ini dengan aplikasi Win32 adalah dengan menggunakan variabel statis atau global. Sayangnya, Anda tidak dapat menetapkan objek terkelola ke jenis variabel tersebut. Anda dapat menetapkan handel jendela yang terkait dengan objek HwndSource ke variabel global atau statis, tetapi itu tidak menyediakan akses ke objek itu sendiri.

Solusi paling sederhana untuk masalah ini adalah menerapkan kelas terkelola yang berisi sekumpulan bidang statis untuk menyimpan referensi ke objek terkelola apa pun yang perlu Anda akses. Sampel menggunakan kelas WPFPageHost untuk menyimpan referensi ke konten WPF, ditambah nilai awal sejumlah propertinya yang mungkin diubah nanti oleh pengguna. Ini didefinisikan di header.

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;
};

Bagian terakhir dari fungsi GetHwnd menetapkan nilai ke bidang tersebut untuk digunakan nanti saat myPage masih dalam cakupan.

Berkomunikasi dengan Konten WPF

Ada dua jenis komunikasi dengan konten WPF. Aplikasi menerima informasi dari konten WPF ketika pengguna mengklik tombol OK atau Batalkan. Aplikasi ini juga memiliki UI yang memungkinkan pengguna mengubah berbagai properti konten WPF, seperti warna latar belakang atau ukuran font default.

Seperti disebutkan di atas, ketika pengguna mengklik salah satu tombol, konten WPF memicu peristiwa OnButtonClicked. Aplikasi melampirkan handler ke kejadian ini untuk menerima pemberitahuan ini. Jika tombol OK diklik, handler mendapatkan informasi pengguna dari konten WPF dan menampilkannya dalam sekumpulan kontrol statis.

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: ");
    }
}

Handler menerima objek argumen peristiwa kustom dari konten WPF, MyPageEventArgs. Properti IsOK objek diatur ke true jika tombol OK diklik, dan false jika tombol Batalkan diklik.

Jika tombol OK diklik, handler mendapatkan referensi ke konten WPF dari kelas kontainer. Kemudian mengumpulkan informasi pengguna yang dipegang oleh properti konten WPF terkait dan menggunakan kontrol statis untuk menampilkan informasi di jendela induk. Karena data konten WPF dalam bentuk string terkelola, data tersebut harus diproses untuk digunakan oleh kontrol Win32. Jika tombol Batalkan diklik, handler akan menghapus data dari kontrol statis.

Antarmuka pengguna aplikasi menyediakan sekumpulan tombol radio yang memungkinkan pengguna mengubah warna latar belakang konten WPF, dan beberapa properti terkait font. Contoh berikut adalah kutipan dari prosedur jendela aplikasi (WndProc) dan penanganan pesannya yang mengatur berbagai properti pada pesan yang berbeda, termasuk warna latar belakang. Yang lain serupa, dan tidak ditampilkan. Lihat sampel lengkap untuk detail dan konteks.

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;

Untuk mengatur warna latar belakang, dapatkan referensi ke konten WPF (hostedPage) dari WPFPageHost dan atur properti warna latar belakang ke warna yang sesuai. Sampel menggunakan tiga opsi warna: warna asli, hijau muda, atau salmon ringan. Warna latar belakang asli disimpan sebagai bidang statis di kelas WPFPageHost. Untuk mengatur dua lainnya, Anda membuat objek SolidColorBrush baru dan meneruskan konstruktor nilai warna statis dari objek Colors.

Menerapkan Halaman WPF

Anda dapat menghosting dan menggunakan konten WPF tanpa mengetahui implementasi aktual. Jika konten WPF telah dikemas dalam DLL terpisah, konten tersebut dapat dibangun dalam bahasa common language runtime (CLR) apa pun. Berikut ini adalah panduan singkat implementasi C++/CLI yang digunakan dalam sampel. Bagian ini berisi subbagian berikut.

Tata letak

Elemen UI dalam konten WPF terdiri dari lima kontrol TextBox, dengan kontrol Label terkait: Nama, Alamat, Kota, Status, dan Zip. Ada juga dua kontrol Button, OK dan Batalkan

Konten WPF diimplementasikan di kelas WPFPage. Tata letak ditangani dengan elemen tata letak Grid. Kelas mewarisi dari Grid, yang secara efektif menjadikannya elemen akar konten WPF.

Konstruktor konten WPF mengambil lebar dan tinggi yang diperlukan, dan menentukan ukuran Grid yang sesuai. Kemudian mendefinisikan tata letak dasar dengan membuat sekumpulan objek ColumnDefinition dan RowDefinition, lalu menambahkannya ke dalam basis objek Grid dan koleksi ColumnDefinitions dan RowDefinitions, masing-masing. Ini mendefinisikan kisi dengan lima baris dan tujuh kolom, dengan dimensi yang ditentukan oleh isi sel-sel tersebut.

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]);
  }

Selanjutnya, konstruktor menambahkan elemen UI ke Grid. Elemen pertama adalah teks judul, yang merupakan kontrol Label yang dipusatkan di baris pertama kisi.

//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);

Baris berikutnya berisi kontrol Nama Label dan kontrol TextBox terkait. Karena kode yang sama digunakan untuk setiap pasangan label/kotak teks, kode tersebut ditempatkan dalam sepasang metode privat dan digunakan untuk kelima pasangan label/kotak teks. Metode-metode ini membuat kontrol yang sesuai, dan memanggil metode-metode statis Grid dan SetColumn dari kelas SetRow untuk menempatkan kontrol di sel yang sesuai. Setelah kontrol dibuat, sampel memanggil metode Add pada properti Children dari Grid untuk menambahkan kontrol ke dalam grid. Kode untuk menambahkan pasangan label/kotak teks yang tersisa serupa. Lihat kode sampel untuk detailnya.

//Add the Name Label and TextBox
nameLabel = CreateLabel(0, 1, "Name");
this->Children->Add(nameLabel);
nameTextBox = CreateTextBox(1, 1, 3);
this->Children->Add(nameTextBox);

Implementasi dari dua metode tersebut adalah sebagai berikut:

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;
}

Terakhir, sampel menambahkan tombol OK dan tombol Batalkan, serta melampirkan penanganan peristiwa ke peristiwa Click mereka.

//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);

Mengembalikan Data ke Jendela Host

Saat salah satu tombol diklik, peristiwa Click dipicu. Jendela host hanya dapat melampirkan handler ke peristiwa ini dan mendapatkan data langsung dari kontrol TextBox. Sampel menggunakan pendekatan yang agak tidak langsung. Ini menangani Click dalam konten WPF, lalu memicu peristiwa kustom OnButtonClickeduntuk memberi tahu konten WPF. Ini memungkinkan konten WPF untuk melakukan beberapa validasi parameter sebelum memberi tahu host. Handler mendapatkan teks dari kontrol TextBox dan menetapkannya sebagai properti publik, agar host dapat memperoleh informasi.

Deklarasi acara, dalam WPFPage.h:

public:
  delegate void ButtonClickHandler(Object ^, MyPageEventArgs ^);
  WPFPage();
  WPFPage(int height, int width);
  event ButtonClickHandler ^OnButtonClicked;

Pengendali acara Click pada 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));
}

Mengatur Properti WPF

Host Win32 memungkinkan pengguna untuk mengubah beberapa properti konten WPF. Dari sisi Win32, itu hanya soal mengubah properti. Implementasi dalam kelas konten WPF agak lebih rumit, karena tidak ada satu pun properti global yang mengontrol font untuk semua kontrol. Sebagai gantinya, properti yang sesuai untuk setiap kontrol diubah dalam pengaturan aksesornya. Contoh berikut menunjukkan kode untuk properti DefaultFontFamily. Mengatur properti memanggil metode privat yang pada gilirannya mengatur properti FontFamily untuk berbagai kontrol.

Dari WPFPage.h:

property FontFamily^ DefaultFontFamily
{
  FontFamily^ get() {return _defaultFontFamily;}
  void set(FontFamily^ value) {SetFontFamily(value);}
};

Dari 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;
}

Lihat juga