Bagikan melalui


Cara Membuat Wizard

Wizard adalah jenis lembar properti yang menyediakan cara sederhana dan canggih untuk memandu pengguna melalui prosedur.

Wizard adalah salah satu kunci untuk menyederhanakan pengalaman pengguna. Mereka memungkinkan Anda untuk mengambil operasi yang kompleks, seperti konfigurasi aplikasi, dan memecahnya menjadi serangkaian langkah sederhana. Pada setiap titik dalam proses, Anda dapat memberikan penjelasan tentang apa yang diperlukan, dan kontrol tampilan yang memungkinkan pengguna untuk membuat pilihan dan memasukkan teks.

Wizard sebenarnya adalah jenis lembar properti. Lembar properti pada dasarnya adalah kontainer untuk kumpulan halaman, di mana setiap halaman adalah kotak dialog terpisah. Sedangkan lembar properti reguler memungkinkan pengguna untuk mengakses halaman apa pun kapan saja, wizard menyajikan halaman secara berurutan. Alih-alih tab, tombol digunakan untuk menavigasi maju dan mundur. Urutan halaman yang ditampilkan dikontrol oleh aplikasi dan dapat dimodifikasi berdasarkan input pengguna.

Ada dua gaya utama wizard: gaya Wizard97 yang lebih lama, dan gaya Aero yang diperkenalkan di Windows Vista. Untuk ilustrasi, lihat Tentang Lembar Properti. (Gaya ketiga, hanya menggunakan bendera PSH_WIZARD atau PSH_WIZARD_LITE, menyajikan urutan sederhana lembar properti tanpa header atau marka air.)

Catatan

"Marka air" dalam konteks wizard adalah bitmap yang muncul di margin kiri beberapa halaman.

 

Diskusi di sebagian besar dokumen ini mengasumsikan bahwa Anda menerapkan wizard untuk sistem dengan kontrol umum versi 5.80 atau yang lebih baru. Jika Anda mencoba menggunakan gaya Wizard97 dengan versi kontrol umum yang lebih lama, aplikasi Anda dapat dikompilasi tetapi tidak akan ditampilkan dengan benar. Untuk diskusi tentang cara membuat wizard yang kompatibel dengan Wizard97 pada sistem sebelumnya, lihat Panduan Kompatibel Mundur nanti dalam topik ini.

Apa yang perlu Anda ketahui

Teknologi

Prasyarat

  • C/C++
  • Pemrograman Antarmuka Pengguna Windows

Petunjuk

Implementasi Wizard

Menerapkan wizard mirip dengan menerapkan lembar properti reguler. Pada tingkat yang paling dasar, ini adalah masalah pengaturan salah satu bendera atau kombinasi bendera berikut dalam struktur PROPSHEETHEADER yang menentukan lembar properti.

Bendera Gaya
PSH_WIZARD Wizard sederhana tanpa header atau bitmap.
PSH_WIZARD_LITE Mirip dengan PSH_WIZARD, dengan beberapa perbedaan kecil dalam penampilan; misalnya, pembagi di atas tombol diatur ke lebar penuh jendela.
PSH_WIZARD97 Wizard Wizard97 dengan header (opsional), bitmap header, dan marka air.
PSH_WIZARD | PSH_AEROWIZARD Wizard Aero. Panduan Aero tidak menggunakan marka air atau bitmap header. Mereka memerlukan model apartemen berulir tunggal (STA).

 

Prosedur dasar untuk menerapkan wizard adalah sebagai berikut:

  1. Buat templat kotak dialog untuk setiap halaman.
  2. Tentukan halaman dengan membuat struktur PROPSHEETPAGE untuk setiap halaman. Struktur ini mendefinisikan halaman, dan berisi penunjuk ke templat kotak dialog dan bitmap atau sumber daya lainnya.
  3. Teruskan struktur PROPSHEETPAGE yang dibuat pada langkah sebelumnya ke fungsi CreatePropertySheetPage untuk membuat handel HPROPSHEETPAGE halaman.
  4. Tentukan wizard dengan membuat struktur PROPSHEETHEADER untuk wizard tersebut.
  5. Teruskan struktur PROPSHEETHEADER ke fungsi PropertySheet untuk menampilkan wizard.
  6. Terapkan prosedur kotak dialog untuk setiap halaman untuk menangani pesan pemberitahuan dari kontrol halaman dan tombol wizard dan untuk memproses pesan Windows lainnya.

Membuat Templat Kotak Dialog

Ada dua jenis dasar halaman wizard: eksterior dan interior. Halaman eksterior adalah halaman pengenalan (selamat datang) dan penyelesaian. Semua lainnya adalah halaman interior.

Templat Kotak Dialog Halaman Eksterior

Tata letak dasar halaman pengenalan dan penyelesaian identik. Ilustrasi berikut ini memperlihatkan contoh halaman pengenalan Wizard97, dengan cap air tempat penampung.

screen shot showing a wizard page with a graphic on the left, title and body text on the right, and back, next and cancel buttons at the bottom

Untuk halaman eksterior Wizard97, templat kotak dialog adalah unit dialog 317x193. Ini mengisi semua wizard, kecuali untuk keterangan dan pita di bagian bawah yang berisi tombol Kembali, Berikutnya, dan Batal . Sisi kiri templat, yang dicadangkan untuk bitmap "marka air", tidak boleh berisi kontrol apa pun. Marka air ditentukan dalam struktur PROPSHEETHEADER wizard dan ditambahkan ke halaman secara otomatis. Anda harus mengizinkan ruang untuk itu saat merancang templat sumber daya.

Saat Anda membuat bitmap marka air, perlu diingat bahwa kotak dialog dapat meningkat ukurannya jika, misalnya, pengguna memilih font sistem besar. Bahasa yang berbeda juga cenderung memiliki metrik font yang berbeda. Ketika halaman tumbuh, area yang dicadangkan untuk marka air menjadi lebih besar secara proporsional. Namun, Anda tidak dapat mengubah bitmap marka air, atau bitmap yang direntangkan untuk mengisi area yang lebih besar. Sebaliknya, bitmap dibiarkan dalam ukuran aslinya di bagian kiri atas area yang dipesan. Bagian dari area cadangan yang lebih besar yang tidak tercakup oleh marka air secara otomatis diisi dengan warna piksel kiri atas bitmap.

Jika Anda harus memiliki bitmap marka air berukuran berbeda untuk metrik font yang berbeda, dua solusi yang mungkin adalah:

  • Dapatkan metrik font sebelum membuat wizard, dan tentukan bitmap marka air berukuran tepat.
  • Jangan tentukan bitmap marka air saat Anda membuat wizard. Wizard97 akan membiarkan area marka air kosong. Kemudian gambar bitmap berukuran tepat pada area yang dicadangkan untuk marka air.

Anda dapat menempatkan kontrol di area di sebelah kanan marka air seperti yang Anda lakukan untuk kotak dialog biasa. Warna latar belakang area ini ditentukan oleh sistem, dan tidak memerlukan tindakan pada bagian Anda. Anda biasanya menempatkan dua kontrol statis di area ini. Yang atas memegang judul dan menggunakan font tebal besar (12 poin Verdana Bold untuk Wizard97). Yang lain, yang untuk teks penjelasan, menggunakan font kotak dialog standar.

Perbedaan utama antara halaman pengenalan dan penyelesaian adalah tombol wizard dan teks dalam kontrol statis. Halaman pengenalan biasanya memiliki tombol Berikutnya dan Kembali , dengan hanya tombol Berikutnya yang diaktifkan. Halaman penyelesaian mengaktifkan tombol Kembali , dan tombol Berikutnya digantikan oleh tombol Selesai .

Catatan

Di Panduan Aero, tombol Kembali digantikan oleh tombol panah di bilah keterangan.

 

Anda bisa mengubah teks pada tombol Selesai dengan mengirim pesan PSM_SETFINISHTEXT panduan. Secara default, tombol Selesai tidak menyertakan akselerator keyboard. Untuk menentukan akselerator keyboard, sertakan ampersand dalam string teks yang Anda teruskan ke PSM_SETFINISHTEXT. Misalnya, "&Finish" mendefinisikan 'F' sebagai akselerator keyboard.

Templat Kotak Dialog Halaman Interior

Halaman interior memiliki penampilan yang agak berbeda dari halaman eksterior. Ilustrasi berikut menunjukkan contoh halaman interior Wizard97, dengan bitmap header tempat penampung.

screen shot of a wizard page with title and subtitle text and a graphic at the top, text in the middle, and buttons on the bottom

Area header di bagian atas halaman ditangani oleh lembar properti, sehingga tidak disertakan dalam templat. Konten header ditentukan dalam struktur PROPSHEETPAGE halaman dan struktur PROPSHEETHEADER wizard. Karena halaman interior harus pas antara header dan tombol, templat kotak dialog Wizard97 adalah unit dialog 317x143, agak lebih kecil dari templat untuk halaman eksterior.

Ilustrasi berikut ini memperlihatkan Panduan Aero yang dibuat dari templat yang sama.

screen shot that differs from the previous one by having a title area at the top, and only next and cancel buttons at the bottom

Tentukan Halaman Wizard

Setelah Anda membuat templat kotak dialog dan sumber daya terkait seperti bitmap dan tabel string, Anda dapat membuat halaman lembar properti. Prosedur ini mirip dengan yang untuk lembar properti standar. Pertama, isi anggota struktur PROPSHEETPAGE yang sesuai. (Beberapa anggota khusus untuk wizard.) Kemudian panggil fungsi CreatePropertySheetPage untuk membuat handel HPROPSHEETPAGE halaman.

Bendera terkait wizard berikut dapat diatur dalam anggota dwFlags dari struktur PROPSHEETPAGE .

Bendera Deskripsi
PSP_HIDEHEADER Atur bendera ini untuk halaman eksterior di Wizard97. Header tidak ditampilkan, dan marka air dapat ditampilkan.
PSP_USEHEADERTITLE Atur bendera ini untuk halaman interior untuk meletakkan judul di area header di Wizard97, atau di bagian atas area klien dalam Wizard Aero.
PSP_USEHEADERSUBTITLE Atur bendera ini untuk halaman interior untuk meletakkan subtitel di area header di Wizard97.

 

Jika Anda telah mengatur PSP_USEHEADERTITLE atau PSP_USEHEADERSUBTITLE, tetapkan judul dan teks subtitel ke anggota pszHeaderTitle dan pszHeaderSubtitle . Saat Anda menetapkan string teks kepada anggota struktur PROPSHEETPAGE dan PROPSHEETHEADER, Anda dapat menetapkan penunjuk string atau menggunakan makro MAKEINTRESOURCE untuk menetapkan nilai dari sumber daya string. Sumber daya string dimuat dari modul yang ditentukan dalam anggota hInstance dari struktur PROPSHEETHEADER wizard.

Saat Anda memanggil CreatePropertySheetPage untuk membuat halaman, tetapkan hasilnya ke elemen array handel HPROPSHEETPAGE. Array ini digunakan saat membuat lembar properti. Indeks array dari handel halaman menentukan urutan default tempatnya ditampilkan. Setelah membuat handel HPROPSHEETPAGE halaman, Anda dapat menggunakan kembali struktur PROPSHEETPAGE yang sama untuk membuat halaman berikutnya dengan menetapkan nilai baru ke anggota yang relevan.

Cara alternatif untuk membuat halaman adalah dengan menggunakan struktur PROPSHEETPAGE terpisah untuk setiap halaman, dan membuat array struktur. Array ini digunakan alih-alih array handel HPROPSHEETPAGE saat membuat lembar properti. Menggunakan struktur PROPSHEETPAGE terpisah menghilangkan kebutuhan untuk memanggil CreatePropertySheetPage tetapi menggunakan lebih banyak memori. Jika tidak, tidak ada perbedaan yang signifikan antara kedua pendekatan tersebut.

Contoh berikut mendefinisikan halaman Wizard97 interior dengan menetapkan nilai ke struktur PROPSHEETPAGE. Dalam contoh ini, templat judul, subtitel, dan kotak dialog halaman semuanya diidentifikasi oleh ID sumber dayanya. Fungsi CreatePropertySheetPage kemudian dipanggil untuk membuat handel HPROPSHEETPAGE halaman. Karena akan menjadi halaman kedua yang muncul, handel ditetapkan ke array handel, ahpsp, dengan indeks 1.

// g_hInstance is the global HINSTANCE of the application.
// IntPage1DlgProc is the dialog procedure for this page.
// ahpsp is an array of HPROPSHEETPAGE handles.

PROPSHEETPAGE psp = { sizeof(psp) };

psp.hInstance         = g_hInstance;
psp.dwFlags           = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
psp.lParam            = (LPARAM) &wizdata;
psp.pszHeaderTitle    = MAKEINTRESOURCE(IDS_TITLE1);
psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SUBTITLE1);
psp.pszTemplate       = MAKEINTRESOURCE(IDD_INTERIOR1);
psp.pfnDlgProc        = IntPage1DlgProc;

ahpsp[1] = CreatePropertySheetPage(&psp);

Data Halaman Kustom

Saat membuat halaman, Anda dapat menetapkan data kustom ke halaman tersebut dengan menggunakan anggota lParam dari struktur PROPSHEETPAGE , biasanya dengan menetapkannya penunjuk ke struktur yang ditentukan pengguna.

Saat halaman pertama kali dipilih, prosedur kotak dialognya menerima pesan WM_INITDIALOG. Nilai lParam pesan menunjuk ke salinan struktur PROPSHEETPAGE halaman, tempat Anda dapat mengambil data kustom. Anda kemudian dapat menyimpan data ini untuk digunakan dalam pesan berikutnya dengan menggunakan SetWindowLongPtr dengan GWL_USERDATA sebagai parameter indeks. Beberapa halaman dapat memiliki penunjuk ke data yang sama, dan setiap perubahan pada data yang dibuat oleh satu halaman tersedia untuk halaman lain dalam prosedur dialognya.

Tentukan Lembar Properti Wizard

Seperti halnya lembar properti biasa, Anda menentukan lembar properti wizard dengan mengisi anggota struktur PROPSHEETHEADER. Struktur ini memungkinkan Anda menentukan halaman yang membentuk wizard dan urutan default tempat halaman ditampilkan, bersama dengan beberapa parameter terkait. Anda kemudian meluncurkan wizard dengan memanggil fungsi PropertySheet.

Dalam gaya Wizard97, anggota pszCaption dari struktur PROPSHEETHEADER diabaikan. Sebagai gantinya, wizard menampilkan keterangan yang ditentukan dalam templat kotak dialog halaman saat ini. Jika templat tidak memiliki keterangan, keterangan dari halaman sebelumnya ditampilkan. Dengan demikian, untuk menampilkan keterangan yang sama di semua halaman, tentukan keterangan dalam templat untuk halaman pengantar.

Dalam gaya Aero Wizard, keterangan kotak dialog diambil dari pszCaption.

Jika Anda telah membuat array handel HPROPSHEETPAGE untuk halaman Anda, tetapkan array ke anggota phpage . Jika Anda telah membuat array struktur PROPSHEETPAGE, tetapkan array ke anggota ppsp dan atur bendera PSH_PROPSHEETPAGE di anggota dwFlags.

Contoh berikut menetapkan nilai ke psh, struktur PROPSHEETHEADER, dan memanggil fungsi PropertySheet untuk meluncurkan wizard. Wizard gaya Wizard97 memiliki grafik marka air dan header, yang ditentukan oleh ID sumber dayanya. Array ahpsp berisi semua handel HPROPSHEETPAGE dan menentukan urutan default di mana mereka ditampilkan.

// g_hInstance is the global HINSTANCE of the application.
// ahpsp is an array of HPROPSHEETPAGE handles.

PROPSHEETHEADER psh = { sizeof(psh) };

psh.hInstance      = g_hInstance;
psh.hwndParent     = NULL;
psh.phpage         = ahpsp;
psh.dwFlags        = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
psh.pszbmHeader    = MAKEINTRESOURCE(IDB_BANNER);
psh.nStartPage     = 0;
psh.nPages         = 4;

PropertySheet(&psh);

Prosedur Kotak Dialog

Setiap halaman wizard memerlukan prosedur kotak dialog untuk memproses pesan Windows, terutama pemberitahuan dari kontrol dan wizardnya. Tiga pesan yang harus dapat ditangani hampir semua wizard adalah WM_INITDIALOG, WM_DESTROY, dan WM_NOTIFY.

Pesan WM_NOTIFY diterima sebelum halaman ditampilkan dan ketika salah satu tombol wizard diklik. Parameter lParam pesan adalah penunjuk ke struktur header NMHDR . ID pemberitahuan terkandung dalam anggota kode struktur. Empat pemberitahuan yang perlu ditangani sebagian besar wizard adalah sebagai berikut.

Kode Deskripsi
PSN_SETACTIVE Dikirim sebelum halaman ditampilkan.
PSN_WIZBACK Dikirim saat tombol Kembali diklik.
PSN_WIZNEXT Dikirim saat tombol Berikutnya diklik.
PSN_WIZFINISH Dikirim saat tombol Selesai diklik.

 

Menangani WM_INITDIALOG dan WM_DESTROY

Saat halaman akan ditampilkan untuk pertama kalinya, prosedur kotak dialognya menerima pesan WM_INITDIALOG. Menangani pesan ini memungkinkan wizard untuk melakukan tugas inisialisasi yang diperlukan, seperti menyimpan data kustom atau mengatur font.

Saat lembar properti dihancurkan, Anda menerima pesan WM_DESTROY. Wisaya secara otomatis dihancurkan oleh sistem, tetapi menangani pesan ini memungkinkan Anda melakukan pembersihan yang diperlukan.

Menangani PSN_SETACTIVE

Kode pemberitahuan PSN_SETACTIVE dikirim setiap kali halaman akan dibuat terlihat. Pertama kali halaman dikunjungi, PSN_SETACTIVE mengikuti pesan WM_INITDIALOG. Jika halaman kemudian ditinjau kembali, halaman hanya menerima pemberitahuan PSN_SETACTIVE. Pemberitahuan ini biasanya ditangani untuk menginisialisasi data untuk halaman dan mengaktifkan tombol yang sesuai.

Secara default, wizard menampilkan tombol Kembali, Berikutnya, dan Batal , dengan semua tombol diaktifkan. Untuk menonaktifkan tombol atau menampilkan Selesai alih-alih Berikutnya, Anda harus mengirim pesan PSM_SETWIZBUTTONS. Setelah pesan ini dikirim, status tombol dipertahankan hingga dimodifikasi oleh pesan PSM_SETWIZBUTTONS lain, meskipun halaman baru dipilih. Biasanya, semua handler PSN_SETACTIVE mengirim pesan ini untuk memastikan bahwa setiap halaman memiliki status tombol yang benar.

Anda dapat mengubah status tombol dengan pesan ini kapan saja. Misalnya, Anda mungkin ingin tombol Berikutnya dinonaktifkan awalnya. Setelah pengguna memasukkan semua informasi yang diperlukan, Anda dapat mengirim pesan PSM_SETWIZBUTTONS lain untuk mengaktifkan tombol Berikutnya dan membiarkan pengguna melanjutkan ke halaman berikutnya.

Fragmen kode berikut menggunakan makro PropSheet_SetWizButtons untuk mengaktifkan tombol Kembali dan Berikutnya pada halaman interior sebelum ditampilkan.

case WM_NOTIFY :
    {
        LPNMHDR pnmh = (LPNMHDR)lParam;
        
        switch(pnmh->code)
        {
        
        ...
        
        case PSN_SETACTIVE :
        
            ...
            
            // This is an interior page.
            PropSheet_SetWizButtons(hwnd, PSWIZB_NEXT | PSWIZB_BACK);
            
            ...
        }
    ...
    
    }

Menangani PSN_WIZNEXT, PSNWIZBACK, dan PSN_WIZFINISH

Saat tombol Berikutnya atau Kembali diklik, Anda menerima kode pemberitahuan PSN_WIZNEXT atau PSN_WIZBACK. Secara default, wizard secara otomatis masuk ke halaman berikutnya atau sebelumnya dalam urutan yang ditentukan saat lembar properti dibuat. Alasan umum untuk menangani pemberitahuan ini adalah untuk mencegah pengguna beralih halaman, atau untuk mengambil alih urutan halaman default.

Untuk mencegah pengguna beralih halaman, tangani pemberitahuan tombol, panggil fungsi SetWindowLong dengan nilai DWL_MSGRESULT diatur ke -1, dan kembalikan TRUE. Misalnya:

case PSN_WIZNEXT :

        ...
        
        // Do not go to the next page yet.
        SetWindowLong(hwnd, DWL_MSGRESULT, -1);
        
        return TRUE;
        
        ...

Untuk mengambil alih urutan standar dan masuk ke halaman tertentu, panggil SetWindowLong dengan nilai DWL_MSGRESULT diatur ke ID sumber daya kotak dialog halaman, dan kembalikan TRUE. Misalnya:

case PSN_WIZNEXT :

        ...
        
        // Go straight to the completion page.
        SetWindowLong(hwnd, DWL_MSGRESULT, IDD_FINISH);
        
        return TRUE;
        
        ...

Saat tombol Selesai atau Batal diklik, Anda masing-masing menerima kode pemberitahuan PSN_WIZFINISH atau PSN_RESET . Ketika salah satu tombol ini diklik, wizard secara otomatis dihancurkan oleh sistem. Namun, Anda dapat menangani pemberitahuan ini jika Anda perlu melakukan tugas pembersihan sebelum wizard dihancurkan. Untuk mencegah wizard dihancurkan saat Anda menerima pemberitahuan PSN_WIZFINISH, panggil SetWindowLong dengan nilai DWL_MSGRESULT diatur ke TRUE, dan kembalikan TRUE. Misalnya:

case PSN_WIZFINISH :

        ...
        
        // Not finished yet.
        SetWindowLong(hwnd, DWL_MSGRESULT, TRUE);
        
        return TRUE;
        
        ...

Panduan Kompatibel Mundur

Bagian sebelumnya mengasumsikan bahwa Anda menerapkan wizard untuk sistem dengan kontrol umum versi 5 atau yang lebih baru.

Jika Anda menulis wizard untuk sistem dengan versi kontrol umum yang lebih lama, banyak fitur yang dibahas di bagian sebelumnya tidak akan tersedia. Sejumlah anggota struktur PROPSHEETHEADER dan PROPSHEETPAGE yang digunakan oleh gaya Wizard97 hanya didukung oleh kontrol umum versi 5 dan yang lebih baru. Namun, masih dimungkinkan untuk menerapkan wizard kompatibel mundur dengan tampilan yang mirip dengan gaya Wizard97. Untuk melakukannya, Anda harus secara eksplisit menerapkan hal berikut:

  • Tambahkan grafik marka air ke templat kotak dialog untuk halaman pengenalan dan penyelesaian Anda.
  • Buat semua templat Anda berukuran sama. Tidak ada area header terpisah yang ditentukan sistem untuk halaman interior.
  • Buat area header halaman interior secara eksplisit pada templat Anda.
  • Jangan gunakan grafik header karena mungkin bertentangan dengan judul atau subjudul jika ukuran wizard berubah.

Untuk diskusi lebih lanjut tentang wizard yang kompatibel dengan mundur, lihat Panduan Kompatibel Mundur 97.

Keterangan

Untuk diskusi lengkap tentang masalah desain untuk Wizard97, lihat Spesifikasi Wizard97, di tempat lain di Windows SDK. Dokumen ini memiliki panduan untuk hal-hal seperti dimensi untuk kotak dialog, dimensi dan warna bitmap, dan penempatan kontrol.

Menggunakan Lembar Properti

Demo kontrol umum Windows (CppWindowsCommonControls)