Klasa CDialog jest podstawową klasą wykorzystywaną do wyświetlania
okienek dialogowych na ekranie. Wyróżniamy dwa rodzaje okien dialogowych:
okna modalne i niemodalne. Okno modalne blokuje okno, z którego
zostało uruchomione i musi zostać zamknięte przez użytkownika,
aby umożliwić dalszą pracę aplikacji. Okna
niemodalne umożliwiają swobodne przechodzenie między zadaniami
bez konieczności ich zamykania.
Obiekt klasy CDialog jest w rzeczywistości kombinacją dwóch obiektów:
- szablonu okna dialogowego, utworzonego zwykle przy użyciu narzędzia
do projektowania, a przechowywanego najczęściej w zasobach aplikacji
- skojarzonej z nim klasy dziedziczącej po CDialog
Najczęściej tworzenie okna dialogowego rozpoczynamy od zaprojektowania
jego wyglądu i umieszczenia go w odpowiednim skrypcie zasobów. Następnym
krokiem jest powiązanie go z odpowiednią klasą dziedziczącą po klasie
CDialog. Czynności te doskonale wspomagają istniejące narzędzia, np.
ClassWizard z pakietu MS Visual C++.
Okno dialogowe, tak jak każde inne okno, otrzymuje od systemu komunikaty.
Szczególną cechą okien dialogowych jest to, iż najczęściej programistę
interesują komunikaty wysyłane przez kontrolki (przyciski, listy, pola wyboru)
umieszczone w oknie dialogowym. Z tymi bowiem kontrolkami najczęściej
wiążą się określone działania użytkownika, na które program powinien
reagować. ClassWizard (i inne podobne narzędzia) umożliwiają przejrzenie listy
komunikatów wysyłanych przez poszczególne kontrolki i wybranie tych,
których obsługa jest konieczna w programie. Następnie ClassWizard
dodaje odpowiednie wpisy do mapy komunikatów oraz generuje nagłówki
procedur obsługujących zdarzenia. Zadaniem programisty jest jedynie
wypełnienie wygenerowanych procedur odpowiednim kodem.
Jeśli nie dysponujemy narzędziem w rodzaju ClassWizarda odpowiednie
wpisy można wykonać ręcznie.
Automatyczna wymiana danych
W niemal wszystkich oknach dialogowych (pomijając najprostsze) zachodzi
konieczność przechowania informacji wyświetlanych w oknie, czy też
wprowadzanych przez użytkownika. Zalecanym rozwiązaniem jest
utworzenie pól składowych w klasie dziedziczącej po CDialog, przechowujących wszystkie
potrzebne informacje. ClassWizard automatyzuje tę czynność, pomagając
utworzyć odpowiednie pola dla każdej z kontrolek okna dialogowego. ClassWizard
automatycznie proponuje utworzenie pola odpowiedniego typu, wraz z
ewentualnym określeniem dopuszczalnego zakresu wprowadzanych danych.
Kolejnym udogodnieniem (wspomaganym oczywiście przez ClassWizarda) jest
możliwość automatycznej wymiany danych między utworzonymi wcześniej
polami składowymi, a kontrolkami w okienku dialogowym. Mając np. kontrolkę
typu CEdit oraz pole składowe m_EditString typu
CString możemy zapewnić
automatyczną wymianę tekstu pomiędzy kontrolką na ekranie a naszym polem składowym.
ClassWizard utworzy automatycznie mapę danych, za pomocą której nasza kontrolka
zostanie przy otwarciu okienka automatycznie zainicjowana zawartością
pola m_EditString, a po zamknięciu okna dialogowego
(naciśnięciu klawisza OK) dane przepłyną automatycznie w drugą stronę,
tzn. edytowany przez użytkownika ciąg znaków znajdzie się w polu
m_EditString.
Metodą odpowiedzialną za odpowiednie powiązanie kontrolek okna dialogowego
z odpowiadającymi im polami składowymi klasy jest metoda DoDataExchange().
Na szczęście właściwą postać tej metody w klasach dziedziczących po CDialog
generuje automatycznie ClassWizard.
Metoda DoDataExchange() wywoływana jest automatycznie, można jednak wymusić
jej wykonanie poprzez użycie metody UpdateData(). Metoda ta realizuje
"przepływ" informacji między kontrolkami na ekranie a polami składowymi klasy.
Jej parametr wywołania informuje o kierunku tego przepływu. W ten prosty sposób
można więc wymusić auktualnienie danych w razie takiej konieczności.
Środowisko wywołuje metodę UpdateData() w dwóch zasadniczych momentach:
- podczas aktywacji okna dialogowego wykonywana jest automatycznie
metoda OnInitDialog(), która z kolei wywołuje UpdateData()
w celu zainicjowania kontrolek
- po naciśnięciu przez użytkownika przycisku OK, czyli w momencie
zamknięcia okna dialogowego
Należy zauważyć, iż po naciśnięciu przycisku Anuluj dane nie są przesyłane.
Tworzenie okna dialogowego
Utworzenie modalnego okna dialogowego jest czynnością prostą. Składają się na nią
dwie czynności:
- utworzenie obiektu klasy dziedziczącej po CDialog i wywołanie konstruktora
- wywołanie metody DoModal(), która automatycznie wyświetli
okno dialogowe na ekranie i "zamrozi" wywołujący ją proces do czasu zamknięcia
okna przez użytkownika.
Z punktu widzenia programisty rzeczą istotną jest wynik zwracany przez
metodę DoModal(). Informuje on o tym, czy okno dialogowe
zostało zamknięte za pomocą przycisku OK, czy też Anuluj.
Możliwe jest również automatyczne zamknięcie modalnego okna dialogowego
za pomocą metody EndDialog().
Aby utworzyć niemodalne okno dialogowe należy w konstruktorze klasy
dziedziczącej po klasie CDialog użyć metody Create(). Jeśli
schemat okna w skrypcie zasobów ma ustawiony parametr WS_VISIBLE, okno
pojawi się automatycznie. Jeśli nie, trzeba użyć metody ShowWindow().
Niemodalne okna dialogowe wymagają od programisty nieco więcej uwagi.
Należy bowiem zagwarantować prawidłowe usunięcie okna w odpowiednim
czasie. Najczęściej wykonuje się to pokrywając domyślną metodę
OnCancel() i umieszczając w niej wywołanie metody DestroyWindow().
Nie należy wywoływać w tym przypadku dziedziczonej metody
CDialog::OnCancel(), ponieważ ona automatycznie wywołuje
metodę EndDialog() stosowaną przy oknach modalnych. Należy również
pamiętać o dealokacji pamięci zajmowanej przez obiekt klasy okna.
Możliwe jest utworzenie szablonu okna dialogowego w pamięci, za pomocą
struktury DLGTEMPLATE. Okno takie obsługuje się przy użyciu metod
CreateIndirect() i InitModalIndirect(). Szczegółowe
informacje znajdują się w dokumentacji Win32 SDK.
Brak
Konstruowanie
| Metody | Opis |
|---|---|
| CDialog | Tworzy obiekt typu CDialog. |
| Metody | Opis |
|---|---|
| Create | Inicjuje obiekt CDialog. Tworzy niemodalne okno dialogowe i łączy je z obiektem CDialog. |
| CreateIndirect | Tworzy niemodalne okno dialogowe wykorzystując szablon utworzony w pamięci (zamiast skryptu zasobów). |
| InitModalIndirect | Tworzy niemodalne okno dialogowe wykorzystując
szablon utworzony w pamięci (zamiast skryptu zasobów). Parametry są przetrzymywane
do momentu wywołania metody DoModal(). |
| Metody | Opis |
|---|---|
| DoModal | Uruchamia obsługę modalnego okna dialogowego.
Powrót z wywołania funkcji następuje po zamknięciu okna (przyciskiem
OK lub Anuluj). Zwraca stałą IDxxxx określającą sposób zamknięcia okna. |
| MapDialogRect | Wykonuje konwersję rozmiarów prostokąta wyrażonych w jednostkach okna dialogowego na jednostki ekranowe. |
| NextDlgCtrl | Przesuwa ognisko do następnej kontrolki w oknie dialogowym (reakcja na przycisk Tab). |
| PrevDlgCtrl | Przesuwa ognisko do poprzedniej kontrolki w oknie dialogowym (reakcja na przycisk Shift-Tab). |
| GotoDlgCtrl | Przesuwa ognisko do kontrolki podanej jako parametr. |
| SetDefID | Ustawia tzw. przycisk domyślny. Po wywołaniu przycisk o identyfikatorze podanym jako parametr staje się przyciskiem domyślnym. |
| GetDefID | Zwraca identyfikator przycisku domyślnego lub 0 jeśli przycisk nie ma identyfikatora. |
| SetHelpID | Ustawia numer kontekstu w pliku pomocy aplikacji związany z danym oknem. |
| EndDialog | Zamyka modalne okno dialogowe. |
| Metody | Opis |
|---|---|
| OnInitDialog | Pokrywana w celu przeprowadzenia specyficznej dla danego okna inicjalizacji. Wywoływana tylko raz, w momencie inicjalizacji okna. |
| OnSetFont | Pokrywana w celu ustawienia czcionki,
jaką będzie wyświetlany tekst w oknie dialogowym. Czcionka ta jest używana
jako domyślna dla wszystkich kontrolek znajdujących się w oknie. Wskazówka: aby ustawić czcionkę dla danej kontrolki użyj metody SetFont() klasy CWnd
dla tej kontrolki. |
| OnOK | Pokrywana w celu przeprowadzenia odpowiedniej
akcji po naciśnięciu klawisza OK. Domyślnie traktuje okno jako
modalne, zamyka je, a metoda DoModal() zwraca wynik
IDOK. |
| OnCancel | Pokrywana w celu przeprowadzenia odpowiedniej
akcji po naciśnięciu klawisza Anuluj lub przycisku Esc. Domyślnie
traktuje okno jako modalne, zamyka je, a metoda
DoModal() zwraca wynik IDCANCEL. |