Jak tworzyć kreatory
Kreator jest typem arkusza właściwości, który zapewnia prosty i skuteczny sposób prowadzenia użytkowników przez procedurę.
Czarodzieje są jednym z kluczy do uproszczenia doświadczenia użytkownika. Umożliwiają one wykonanie złożonej operacji, takiej jak konfiguracja aplikacji, i podzielenie jej na serię prostych kroków. W każdym momencie procesu możesz podać wyjaśnienie, co jest potrzebne, i wyświetlić kontrolki, które umożliwiają użytkownikowi wprowadzanie zaznaczeń i wprowadzanie tekstu.
Kreator jest w rzeczywistości typem arkusza właściwości. Arkusz właściwości jest zasadniczo kontenerem kolekcji stron , gdzie każda strona jest osobnym oknom dialogowym. Podczas gdy zwykłe arkusze właściwości umożliwiają użytkownikowi dostęp do dowolnej strony w dowolnym momencie, kreatory prezentują strony w sekwencji. Zamiast kart przyciski są używane do przechodzenia do przodu i do tyłu. Kolejność wyświetlania stron jest kontrolowana przez aplikację i może być modyfikowana na podstawie danych wejściowych użytkownika.
Istnieją dwa główne style kreatora: starszy styl Wizard97 i styl Aero wprowadzony w systemie Windows Vista. Aby uzyskać ilustracje, zobacz About Property Sheets. Trzeci styl, korzystając jedynie z flagi PSH_WIZARD lub PSH_WIZARD_LITE, prezentuje prostą sekwencję kart właściwości bez nagłówków ani znaków wodnych.
Notatka
Znak wodny w kontekście kreatorów to mapa bitowa wyświetlana na lewym marginesie niektórych stron.
W większości tego dokumentu przyjęto założenie, że implementujesz kreatora dla systemu z w wersji 5.80 lub nowszej wspólnych kontrolek. Jeśli spróbujesz użyć stylu Wizard97 z wcześniejszymi wersjami wspólnych kontrolek, aplikacja może zostać skompilowana, ale nie będzie wyświetlana prawidłowo. Aby dowiedzieć się, jak stworzyć kreatora kompatybilnego z interfejsem Kreatora97 na starszych systemach, zobacz sekcję Kreatory zgodne wstecznie w dalszej części tego tematu.
Co musisz wiedzieć
Technologie
Warunki wstępne
- C/C++
- Programowanie interfejsu użytkownika systemu Windows
Instrukcje
Implementacja kreatora
Implementacja kreatora jest podobna do implementacji zwykłego arkusza właściwości. Na najbardziej podstawowym poziomie jest to kwestia ustawienia jednej z następujących flag lub kombinacji flag w PROPSHEETHEADER struktury definiującej arkusz właściwości.
Flaga | Styl |
---|---|
PSH_WIZARD | Prosty kreator bez nagłówków ani map bitowych. |
PSH_WIZARD_LITE | Podobnie jak PSH_WIZARD, z niewielkimi różnicami w wyglądzie; na przykład rozdzielacz powyżej przycisków jest ustawiony na pełną szerokość okna. |
PSH_WIZARD97 | Asystent Wizard97 z opcjonalnymi nagłówkami, mapami bitowymi nagłówków i znakami wodnymi. |
PSH_WIZARD | PSH_AEROWIZARD | Kreator Aero Aero Wizards nie używają znaków wodnych ani bitmap nagłówków. Wymagają one modelu mieszkania jednowątkowego (STA). |
Podstawowa procedura implementowania kreatora jest następująca:
- Utwórz szablon okna dialogowego dla każdej strony.
- Zdefiniuj strony poprzez utworzenie struktury PROPSHEETPAGE dla każdej strony. Ta struktura definiuje stronę i zawiera wskaźniki do szablonu okna dialogowego oraz wszelkich map bitowych lub innych zasobów.
- PrzekażstrukturęPROPSHEETPAGE utworzoną w poprzednim kroku do funkcji CreatePropertySheetPage, aby utworzyć dojście HPROPSHEETPAGE strony.
- Zdefiniuj asystenta, tworząc dla niego strukturę PROPSHEETHEADER.
- Przekaż strukturę PROPSHEETHEADER do funkcjiPropertySheet, aby wyświetlić kreatora.
- Zaimplementuj procedury okna dialogowego dla każdej strony w celu obsługi komunikatów powiadomień z kontrolek strony i przycisków kreatora oraz przetwarzania innych komunikatów systemu Windows.
Tworzenie szablonów okien dialogowych
Istnieją dwa podstawowe typy strony kreatora: zewnętrzne i wewnętrzne. Strony zewnętrzne to wprowadzenie (zapraszamy) i strony ukończenia. Wszystkie inne są stronami wewnętrznymi.
szablony strony zewnętrznej
Podstawowy układ stron wprowadzenia i uzupełniania jest identyczny. Na poniższej ilustracji pokazano przykładową stronę powitalną Wizard97 z symbolem zastępczym.
W przypadku stron zewnętrznych Wizard97 szablon okna dialogowego to 317x193 jednostki okien dialogowych. Wypełnia on wszystkie elementy kreatora, z wyjątkiem podpisu i paska w dolnej części, który zawiera Back, Nexti Przycisk Anuluj. Lewa strona szablonu, która jest zarezerwowana dla mapy bitowej "znak wodny", nie powinna zawierać żadnych kontrolek. Znak wodny jest określony w strukturze PROPSHEETHEADER kreatora i jest dodawany automatycznie do strony. Należy uwzględnić miejsce na to, projektując szablon zasobu.
Podczas tworzenia mapy bitowej znaku wodnego należy pamiętać, że okno dialogowe może zwiększyć rozmiar, jeśli na przykład użytkownik wybierze dużą czcionkę systemową. Różne języki mają również różne metryki czcionek. Kiedy zwiększa się rozmiar strony, obszar zarezerwowany dla znaku wodnego staje się proporcjonalnie większy. Nie można jednak zmienić mapy bitowej znaku wodnego ani nie jest ona rozciągana w celu wypełnienia większego obszaru. Zamiast tego mapa bitowa pozostaje w oryginalnym rozmiarze w lewej górnej części obszaru zarezerwowanego. Część większego zarezerwowanego obszaru, który nie jest objęty znakiem wodnym, jest automatycznie wypełniona kolorem lewego górnego piksela mapy bitowej.
Jeśli potrzebujesz różnych map bitowych dla różnych metryk czcionek, dostępne są dwa możliwe rozwiązania:
- Pobierz metryki czcionek przed utworzeniem kreatora i określ mapę bitową o odpowiednim rozmiarze.
- Nie należy określać bitmapy znaku wodnego podczas tworzenia kreatora. Kreator97 pozostawi pusty obszar znaku wodnego. Następnie narysuj odpowiedniej wielkości bitmapę w obszarze przeznaczonym na znak wodny.
Kontrolki można umieścić w obszarze po prawej stronie znaku wodnego, tak jak w przypadku zwykłego okna dialogowego. Kolor tła tego obszaru jest określany przez system i nie wymaga żadnej akcji ze swojej strony. Zazwyczaj w tym obszarze umieszczasz dwie statyczne kontrolki. Górna część zawiera tytuł i używa dużej pogrubionej czcionki (12 punktów Verdana Bold dla Wizard97). Drugi, który jest przeznaczony do objaśnienia tekstu, używa standardowej czcionki okna dialogowego.
Główną różnicą między stronami wprowadzenia i uzupełniania są przyciski kreatora i tekst w kontrolkach statycznych. Strony wprowadzające zwykle mają przycisk Dalej i Wstecz, z aktywnym tylko przyciskiem Dalej. Strony uzupełniania mają włączony przycisk Wstecz, a zamiast przycisku Dalej pojawia się przycisk Zakończ.
Nota
W kreatorach Aero, przycisk Wstecz jest zastępowany przyciskiem strzałki na pasku tytułu.
Możesz zmodyfikować tekst na przycisku Zakończ , wysyłając kreatorowi wiadomość PSM_SETFINISHTEXT. Domyślnie przycisk Zakończ nie zawiera akceleratora klawiatury. Aby zdefiniować akcelerator klawiatury, dołącz znak ampersand w ciągu tekstowym przekazywanym do PSM_SETFINISHTEXT. Na przykład "&Finish" definiuje "F" jako akcelerator klawiatury.
szablony okien dialogowych strony wewnętrznej
Strony wewnętrzne mają nieco inny wygląd niż strony zewnętrzne. Poniższa ilustracja przedstawia przykładową stronę wewnętrzną Wizard97 z zastępczym obrazem nagłówka.
Obszar nagłówka w górnej części strony jest obsługiwany przez arkusz właściwości, więc nie jest uwzględniony w szablonie. Zawartość nagłówka jest określona w strukturze strony PROPSHEETPAGE oraz w strukturze kreatora PROPSHEETHEADER. Ponieważ strona wewnętrzna musi mieścić się między nagłówkiem a przyciskami, szablon okna dialogowego Wizard97 to 317x143 jednostki okna dialogowego, nieco mniejsze niż szablon dla stron zewnętrznych.
Na poniższej ilustracji przedstawiono Kreatora Aero, który został utworzony na podstawie tegoż samego szablonu.
Definiowanie stron kreatora
Po utworzeniu szablonów okien dialogowych i powiązanych zasobów, takich jak mapy bitowe i tabele ciągów, można utworzyć strony arkusza właściwości. Procedura jest podobna do procedury dla standardowych arkuszy właściwości. Najpierw wypełnij odpowiednie elementy członkowskie struktury PROPSHEETPAGE. (Niektóre elementy członkowskie są specyficzne dla kreatorów.) Następnie wywołaj funkcję CreatePropertySheetPage, aby utworzyć dojście HPROPSHEETPAGE strony.
Następujące flagi związane z kreatorem można ustawić w dwFlags członku PROPSHEETPAGE struktury.
Flaga | Opis |
---|---|
PSP_HIDEHEADER | Ustaw tę flagę dla stron zewnętrznych w Kreator 97. Nagłówek nie jest wyświetlany i można wyświetlić znak wodny. |
PSP_USEHEADERTITLE | Ustaw tę flagę dla stron wewnętrznych, aby umieścić tytuł w obszarze nagłówka w Kreatorze97 lub w górnej części obszaru klienta w Kreatorze Aero. |
PSP_USEHEADERSUBTITLE | Ustaw tę flagę dla stron wewnętrznych, aby umieścić podtytuł w obszarze nagłówka w Wizard97. |
Jeśli ustawiono PSP_USEHEADERTITLE lub PSP_USEHEADERSUBTITLE, przypisz tekst tytułu i podtytułu do członków pszHeaderTitle i pszHeaderSubtitle, odpowiednio. Po przypisaniu ciągów tekstowych do elementów członkowskich PROPSHEETPAGE i struktur PROPSHEETHEADER można przypisać wskaźnik ciągu lub użyć makra MAKEINTRESOURCE, aby przypisać wartość z zasobu ciągu. Zasób ciągu jest ładowany z modułu określonego w hInstance elementu członkowskiego PROPSHEETHEADER kreatora struktury.
Po wywołaniu CreatePropertySheetPage w celu utworzenia strony, przypisz wynik do elementu tablicy uchwytów HPROPSHEETPAGE. Ta tablica jest używana podczas tworzenia arkusza właściwości. Indeks tablicy uchwytu strony określa domyślną kolejność wyświetlania. Po utworzeniu dojścia HPROPSHEETPAGE strony można ponownie użyć tej samej struktury PROPSHEETPAGE, aby utworzyć następną stronę, przypisując nowe wartości odpowiednim elementom.
Alternatywnym sposobem tworzenia stron jest użycie oddzielnych PROPSHEETPAGE struktur dla każdej strony i utworzenie tablicy struktur. Ta tablica jest używana zamiast tablicy uchwytów HPROPSHEETPAGE podczas tworzenia tabeli właściwości. Użycie oddzielnych struktur PROPSHEETPAGE eliminuje konieczność wywoływania createPropertySheetPage, ale używa więcej pamięci. W przeciwnym razie nie ma znaczącej różnicy między dwoma podejściami.
Na poniższym przykładzie zdefiniowano stronę wewnętrzną Kreatora97, przypisując wartości do struktury PROPSHEETPAGE. W tym przykładzie szablon tytułu, podtytułu i okna dialogowego strony są identyfikowane przez identyfikatory zasobów. Funkcja CreatePropertySheetPage jest następnie wywoływana w celu utworzenia dojścia HPROPSHEETPAGE strony. Ponieważ zostanie wyświetlona druga strona, uchwyt zostanie przypisany do tablicy uchwytów, ahpsp, z indeksem 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);
Niestandardowe dane strony
Podczas tworzenia strony można przypisać do niej dane niestandardowe, używając elementu członkowskiego lParam struktury PROPSHEETPAGE, często poprzez przypisanie wskaźnika do struktury zdefiniowanej przez użytkownika.
Po pierwszym wybraniu strony jej procedura okna dialogowego odbiera komunikat WM_INITDIALOG. Wartość lParam komunikatu wskazuje kopię struktury PROPSHEETPAGE strony, z której można pobrać dane niestandardowe. Następnie można przechowywać te dane do użycia w kolejnych komunikatach przy użyciu SetWindowLongPtr z GWL_USERDATA jako parametr indeksu. Wiele stron może mieć wskaźnik do tych samych danych, a każda zmiana danych wprowadzonych przez jedną stronę jest dostępna dla innych stron w ich procedurach dialogowych.
Zdefiniuj arkusz właściwości Kreatora
Podobnie jak w przypadku zwykłych arkuszy właściwości, należy zdefiniować arkusz właściwości kreatora, wypełniając człony struktury PROPSHEETHEADER. Ta struktura umożliwia określenie stron tworzących kreatora i kolejność domyślną, w której są wyświetlane, wraz z kilkoma powiązanymi parametrami. Następnie uruchom kreatora, wywołując funkcję PropertySheet.
W stylu Wizard97 element pszCaption członka PROPSHEETHEADER jest ignorowany. Zamiast tego kreator wyświetla nagłówek określony w szablonie okna dialogowego bieżącej strony. Jeśli szablon nie ma podpisu, zostanie wyświetlony podpis z poprzedniej strony. W związku z tym, aby wyświetlić ten sam podpis na wszystkich stronach, określ podpis w szablonie strony wprowadzającej.
W stylu Kreatora Aero tytuł okna dialogowego jest pobierany z pszCaption.
Jeśli utworzono tablicę uchwytów HPROPSHEETPAGE dla stron, przypisz tablicę do członka phpage. Jeśli zamiast tego utworzono tablicę struktur PROPSHEETPAGE, przypisz tablicę do elementu ppsp i ustaw flagę PSH_PROPSHEETPAGE w elemencie dwFlags.
Poniższy przykład przypisuje wartości do psh, struktury PROPSHEETHEADER i wywołuje funkcję PropertySheet, aby uruchomić kreatora. Kreator w stylu Wizard97 ma zarówno grafikę znaku wodnego, jak i nagłówka określoną przez identyfikatory zasobów. Tablica ahpsp zawiera wszystkie dojścia HPROPSHEETPAGE i definiuje kolejność domyślną, w której są wyświetlane.
// 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);
Procedura okna dialogowego
Każda strona kreatora wymaga procedury okna dialogowego do przetwarzania komunikatów systemu Windows, w szczególności powiadomień z kontrolek i kreatora. Trzy komunikaty, które prawie wszystkie asystenci muszą być w stanie obsłużyć, to WM_INITDIALOG, WM_DESTROYi WM_NOTIFY.
Komunikat WM_NOTIFY jest odbierany przed wyświetleniem strony i kliknięciem dowolnego przycisku kreatora. Parametr lParam komunikatu jest wskaźnikiem na strukturę nagłówka NMHDR. Identyfikator powiadomienia jest zawarty w członku kodu struktury. Cztery powiadomienia, które większość kreatorów musi obsługiwać, są następujące.
Kod | Opis |
---|---|
PSN_SETACTIVE | Wysłane przed wyświetleniem strony. |
PSN_WIZBACK | Wysłane po kliknięciu przycisku wstecz. |
PSN_WIZNEXT | Wysłane po kliknięciu na przycisk Dalej. |
PSN_WIZFINISH | Wysłane po kliknięciu przycisku Zakończ. |
Obsługa WM_INITDIALOG i WM_DESTROY
Gdy strona zostanie wyświetlona po raz pierwszy, jej procedura okna dialogowego odbiera komunikat WM_INITDIALOG. Obsługa tego komunikatu umożliwia kreatorowi wykonywanie wszelkich niezbędnych zadań inicjalizacyjnych, takich jak przechowywanie niestandardowych danych lub ustawianie czcionek.
Gdy arkusz właściwości zostanie zniszczony, zostanie wyświetlony komunikat WM_DESTROY. Kreator jest automatycznie niszczony przez system, ale obsługa tego komunikatu umożliwia wykonanie wszelkich niezbędnych czynności oczyszczania.
Obsługa PSN_SETACTIVE
Kod powiadomienia PSN_SETACTIVE jest wysyłany za każdym razem, gdy strona zostanie wyświetlona. Przy pierwszym odwiedzeniu strony PSN_SETACTIVE następuje komunikat WM_INITDIALOG. Jeśli strona zostanie następnie ponownie wyświetlona, otrzyma tylko powiadomienie PSN_SETACTIVE. Powiadomienie to jest zazwyczaj używane do zainicjowania danych dla strony i włączenia odpowiednich przycisków.
Domyślnie kreator wyświetla przyciski Wstecz, Daleji Anuluj, z wszystkimi przyciskami aktywnymi. Aby wyłączyć przycisk lub wyświetlić Zakończ zamiast Dalej, musisz wysłać komunikat PSM_SETWIZBUTTONS. Po wysłaniu tej wiadomości stan przycisków zostanie zachowany do momentu jego zmodyfikowania przez inny komunikat PSM_SETWIZBUTTONS, nawet jeśli zostanie wybrana nowa strona. Zazwyczaj wszystkie programy obsługi PSN_SETACTIVE wysyłają ten komunikat, aby upewnić się, że każda strona ma prawidłowy stan przycisku.
Stan przycisku można zmienić za pomocą tej wiadomości w dowolnym momencie. Na przykład możesz chcieć, aby przycisk Dalej był początkowo wyłączony. Po wprowadzeniu wszystkich niezbędnych informacji przez użytkownika możesz wysłać inny komunikat PSM_SETWIZBUTTONS, aby włączyć przycisk Dalej i pozwolić użytkownikowi przejść do następnej strony.
Poniższy fragment kodu używa makra PropSheet_SetWizButtons, aby włączyć przyciski Wstecz i Dalej na stronie wewnętrznej przed jej wyświetleniem.
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);
...
}
...
}
Obsługa PSN_WIZNEXT, PSNWIZBACK i PSN_WIZFINISH
Po kliknięciu przycisku Next lub Back zostanie wyświetlony kod powiadomienia PSN_WIZNEXT lub PSN_WIZBACK. Domyślnie kreator automatycznie przechodzi do następnej lub poprzedniej strony w kolejności zdefiniowanej podczas tworzenia arkusza właściwości. Typowym powodem obsługi tych powiadomień jest uniemożliwienie użytkownikowi przełączania stron lub zastąpienie domyślnej kolejności stron.
Aby uniemożliwić użytkownikowi przełączanie stron, obsłuż powiadomienie przycisku, wywołaj funkcję SetWindowLong z wartością DWL_MSGRESULT ustawioną na –1 i zwróć true. Na przykład:
case PSN_WIZNEXT :
...
// Do not go to the next page yet.
SetWindowLong(hwnd, DWL_MSGRESULT, -1);
return TRUE;
...
Aby zastąpić zamówienie standardowe i przejść do określonej strony, wywołaj SetWindowLong z wartością DWL_MSGRESULT ustawioną na identyfikator zasobu okna dialogowego strony i zwróć TRUE. Na przykład:
case PSN_WIZNEXT :
...
// Go straight to the completion page.
SetWindowLong(hwnd, DWL_MSGRESULT, IDD_FINISH);
return TRUE;
...
Po kliknięciu przycisku Zakończ lub Anuluj otrzymasz odpowiednio kod powiadomienia PSN_WIZFINISH lub PSN_RESET. Po kliknięciu jednego z tych przycisków kreator zostanie automatycznie zniszczony przez system. Możesz zarządzać tymi powiadomieniami, jeśli musisz wykonać zadania oczyszczania przed zniszczeniem kreatora. Aby zapobiec niszczeniu kreatora po otrzymaniu powiadomienia PSN_WIZFINISH, wywołaj SetWindowLong z wartością DWL_MSGRESULT ustawioną na wartość TRUEi zwróć TRUE. Na przykład:
case PSN_WIZFINISH :
...
// Not finished yet.
SetWindowLong(hwnd, DWL_MSGRESULT, TRUE);
return TRUE;
...
Asystenci zgodni z wcześniejszymi wersjami
W poprzedniej sekcji założono, że implementujesz kreatora dla systemu z w wersji 5 lub nowszej wspólnych kontrolek.
Jeśli piszesz kreatora dla systemów ze starszymi wersjami wspólnych kontrolek, wiele funkcji omówionych w poprzedniej sekcji nie będzie dostępnych. Wiele członków struktur PROPSHEETHEADER oraz PROPSHEETPAGE używanych przez styl Wizard97 jest obsługiwanych tylko przez typowe kontrolki wersji 5 lub nowszej. Jednak nadal można zaimplementować zgodny z poprzednimi wersjami kreatora z wyglądem podobnym do stylu Wizard97. W tym celu należy jawnie zaimplementować następujące elementy:
- Dodaj grafikę znaku wodnego do szablonu okna dialogowego dla stron wprowadzenia i uzupełniania.
- Ustaw wszystkie szablony na ten sam rozmiar. Nie ma oddzielnego obszaru nagłówka zdefiniowanego przez system dla stron wewnętrznych.
- Utwórz jawnie obszar nagłówka strony wewnętrznej w szablonach.
- Nie używaj grafiki w nagłówku, ponieważ może kolidować z tytułem lub podtytułem, jeśli asystent zmieni rozmiar.
Aby uzyskać więcej informacji na temat kreatorów zgodnych z poprzednimi wersjami, zobacz Kreator Zgodny z Poprzednimi Wersjami 97.
Uwagi
Aby uzyskać pełne omówienie kwestii projektowych dotyczących Kreatora97, zobacz #Specyfikację Kreatora97 #w innym miejscu pakietu Windows SDK. Ten dokument zawiera wytyczne dotyczące takich elementów jak wymiary okien dialogowych, wymiarów mapy bitowej i kolorów oraz umieszczania kontrolek.
Tematy pokrewne