Windows Programmierung: Dialogboxen |
Im Ressource-Editor erhält sowohl die Dialogbox als auch jedes Kontrollelement des Dialogs eine Kennung (SHORT), über die sie identifizierbar ist. Wie bei einem Fenster gibt es eine Fensterfunktion, die das Verhalten des Fensters festlegt. Eine Dialogfensterfunktion unterscheidet sich in einigen Details von der normalen Fensterfunktion. So lautet die Initialisierungsnachricht WM_INITDIALOG statt WM_CREATE. Das Ende der Dialogbox erfolgt durch den Aufruf von EndDialog. Dabei wird der zweite Parameter der von EndDialog der aufrufenden Funktion zurückgegeben.
// Modul fuer die Erzeugung einer Dialogbox ABOUT // (C) Arnold Willemer #include |
Der Start der Dialogbox erfolgt durch den Aufruf der Funktion DialogBox oder einer ihrer Verwandten. Durch die Parameter wird festgelegt, welche Ressource-ID und welche Dialogfensterfunktion herangezogen wird. Das Programm erhält erst dann wieder die Kontrolle, wenn die Dialogfensterfunktion EndDialog aufruft und mit dieser Funktion auch den Rückgabewert von DialogBox bestimmt.
Die Funktion DialogBoxParam verhält sich wie DialogBox. Sie erlaubt aber einen LONG als Parameter, der an die Dialogbox weitergereicht wird. Da man darüber auch einen Zeiger übergeben kann, sind beliebige Daten zu übermitteln.
if (DialogBoxParam(GlobalInstance, MAKEINTRESOURCE(DIA_FELD), (HWND)hWnd, FeldDlgFkt, (LPARAM)ZeilenIndex)==IDOK) { |
In der Fensterfunktion wird er beim Eintreten der Message WM_INITDIALOG einfach aus dem lParam gelesen. Hierin befindet sich der übergebene Wert.
BOOL CALLBACK FeldDlgFkt(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static long ZeilenIndex; switch (message) { case WM_INITDIALOG: ZeilenIndex = (long) lParam; |
Da bei jedem Ereignis die Funktion erneut gestartet wird, muss sich die Dialogbox die übermittelten Daten merken. Da man globale Variablen vermeiden will, muss man mit lokalen Fensterdaten arbeiten.
{ tData *myData; myData = (tData *) GetWindowLong(hWnd, GWL_USERDATA); switch (message) { case WM_INITDIALOG: myData = (tData *)lParam; SetWindowLong(hWnd, GWL_USERDATA, (LONG)myData); ... |
Hier werden Daten im WM_INITDIALOG als Parameter übernommen (siehe oben) und
gleich in die lokalen Fensterdaten geschoben (SetWindowLong).
Bei jedem Ereignis werden diese
lokalen Daten wieder neu geladen (GetWindowLong). Dadurch können mehrere
Fenster gleichzeitig existieren, die mit eigenen, unabhängigen Daten
arbeiten.
In bestimmten Situationen ist dieses Verhalten unerwünscht.
Ein Beispiel ist ein Fortschrittsanzeiger, der nur Sinn macht, wenn im Hintergrund
das Programm weiterläuft. Das gleiche gilt für alle Abbruch-Dialoge.
Eine nicht-modale Dialogbox wird nicht mit DialogBox, sondern durch den
Aufruf CreateDialog und ein anschließendes ShowWindow
erzeugt. Die Parameter für CreateDialog entsprechen denen von
DialogBox. Auch die Fensterfunktion ist weitgehend identisch.
Lediglich das Ende der Dialogbox wird durch DestroyWindow statt mit
EndDialog eingeleitet.
Das Programm läuft nach der Erzeugung ungehindert weiter.
Im Beispiel wird eine Dialogbox erzeugt, die Fehlermeldungen in einer Liste
darstellen soll.
Nicht-modale Dialogboxen
Eine normale Dialogbox wird durch den Aufruf von DialogBox gestartet.
Das Programm bleibt an dieser Stelle stehen und wartet auf das Schließen
der Dialogbox. Der Anwender kann nicht weiterarbeiten, bis der Dialog beendet
ist. Dieses Verhalten nennt man modal.
HWND hWndDlg = 0; BOOL CALLBACK DlgFkt_ErrorList(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: DestroyWindow(hDlg); hWndDlg = 0; return TRUE; } } return FALSE; } HWND DiaErrorList(HWND hWnd) { hWndDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_ERRORLIST), hWnd, DlgFkt_ErrorList); ShowWindow(hWndDlg, SW_SHOW); return hWndDlg; } void Print2List(char *str) { if (hWndDlg) { SendMessage(GetDlgItem(hWndDlg, IDC_LIST), LB_ADDSTRING, 0, (LPARAM)str); } else { Print2File(str); } } |
Homepage - Windows-API-Programmierung | (C) Copyright 1999, 2000, 2005 Arnold Willemer |