Beenden der Anwendung

Zurück Zum Inhaltsverzeichnis Weiter

Hatte das vorherige Beispiel noch den 'kleinen' Fehler, dass beim Schließen des Fensters die Anwendung nicht beendet wurde, so werden wir dies jetzt korrigieren.

Nach dem das Fenster geschlossen wurde, sendet WINDOWS eine WM_DESTROY Nachricht an die Fensterprozedur des Fenster. Die Zusatzinformationen zur Nachricht haben folgende Bedeutung:

WM_DESTROY Nachricht

WPARAM wParam keine Bedeutung
LPARAM lParam keine Bedeutung

Beim Eintreffen dieser Nachricht muss nun irgendwie erreicht werden, dass die Nachrichtenschleife in der Funktion WinMain(...) verlassen und damit das Programm beendet wird. Wie Sie sich bestimmt noch erinnern, holt die Nachrichtenschleife mit 'while ( GetMessage(...) )' die Nachrichten aus der Nachrichtenschlange. Und GetMessage(...) liefert als Returnwert den Wert 0 wenn eine WM_QUIT Nachricht ausgelesen wurde. Um nun eine WM_QUIT Nachricht in die Nachrichtenschlange abzulegen wird die Funktion PostQuitMessage(...) aufgerufen.

Öffnen Sie nun zunächst das Ausgangsprojekt  02EPOMFC\WndPraxis im Programmverzeichnis zum Kurs. Anschließend erweitern Sie die Fensterprozedur um die Verarbeitung der WM_DESTROY Nachricht so, dass beim Eintreffen dieser Nachricht das Programm korrekt beendet wird.

Übersetzen und starten Sie das Beispiel dann. Wenn Sie alles richtig gemacht haben sollte beim Schließen des Fensters auch die Anwendung beendet werden. Sie können dies nachprüfen, in dem Sie nach dem Beenden den berühmten Dreifingergriff ausführen. In dem darauf eingeblendeten Dialog sollte die Anwendung Wndpraxis nicht mehr aufgeführt sein.

Lösung zur WM_DESTROY Nachricht

// Die Fensterprozedur!
// --------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        // Beim Eintreffen von WM_DESTROY, Anwendung beenden
        PostQuitMessage(0);
        return 0L;
    }
    // Nicht bearbeitete Nachrichten an WINDOWS uebergeben
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

Nach dem Schließen des Fensters wird die Funktion PostQuitMessage(...) ausgeführt was wiederum dazu führt, dass die Nachrichtenschleife verlassen und damit die Anwendung korrekt beendet wird.

Ende der Lösung

Erweitern wir das Beispiel noch um eine zusätzliche Funktionalität. In vielen Fällen ist es erforderlich, noch vor dem Schließen des Fenster einige Aktionen durchzuführen. Denken Sie z.B. an einen Editor der vor dem Schließen des Fensters nachfragen muss, ob die geänderten Daten gesichert werden sollen. Um dies zu erreichen wird die Nachricht WM_CLOSE innerhalb der Fensterprozedur verarbeitet.  Die Zusatzinformationen zur Nachricht haben folgende Bedeutung:

WM_CLOSE Nachricht

WPARAM wParam keine Bedeutung
LPARAM lParam keine Bedeutung

WINDOWS versendet diese Nachricht bevor das Fenster geschlossen wird. Die Standard-Fensterprozedur ruft als Reaktion auf diese Nachricht die Funktion DestroyWindow(...) auf.

Wenn diese Nachricht in der Fensterprozedur verarbeitet wird und das Fenster soll geschlossen werden, so muss die Anwendung die Funktion DestroyWindow(...) selbst aufrufen. Soll dagegen der Schließvorgang abgebrochen werden, so ist keine weitere Aktion notwendig.
Fügen Sie jetzt ihrem Beispiel eine Abfrage hinzu die vom Anwender nach dem Einleiten des Schließvorgangs zusätzlich nochmals abfragt, ob das Fensters auch tatsächlich geschlossen werden soll. Wird diese Abfrage bejaht, so ist das Fenster zu schließen und damit auch die Anwendung zu beenden. Wird die Abfrage dagegen verneint so soll das Fenster selbstverständlich weiterhin geöffnet bleiben.

Übersetzen und starten Sie das Beispiel dann.

Lösung zur WM_CLOSE Nachricht

// Die Fensterprozedur!
// --------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    // Nachrichten auswerten.
    switch (uMsg)
    {
    case WM_DESTROY:
        ....
    case WM_CLOSE:
        {
             // Abfrage, ob Anwendung beendet werden soll
             int nRetVal = MessageBox(hWnd,
                            "Soll die Anwendung beendet werden?",
                            "WM_CLOSE", MB_YESNO);
             // Falls ja, Fenster zerstoeren
             if ( nRetVal == IDYES)
                 DestroyWindow(hWnd);
            return 0L;
        }
    }
    // Nicht bearbeitete Nachrichten an WINDOWS uebergeben
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

Wenn das Fenster nun geschlossen werden soll empfängt die Anwendung eine WM_CLOSE Nachricht. Als Reaktion darauf wird eine Messagebox eingeblendet in der nochmals nachgefragt wird, ob die Anwendung auch tatsächlich beendet werden soll. Wird dies verneint (Returncode von MessageBox(...) ist ungleich 'IDYES'), so wird die Fensterprozedur sofort verlassen und das Fenster wird nicht geschlossen. Wird die Frage aber bejaht, so wird daraufhin die Funktion DestroyWindow(...) aufgerufen und damit die Anwendung indirekt, nach Bearbeitung der WM_DESTROY, beendet.

Ende der Lösung

Wie reagiert Ihre Anwendung, wenn Sie im WM_DESTROY Zweig den Aufruf von PostQuitMessage(...) entfernen?

Im nächsten Schritt werden wir uns mit dem prinzipiellen Darstellen von Fensterinhalten befassen.

Zurück Zum Inhaltsverzeichnis Weiter


Copyright © 2004

Senden Sie Emails mit Fragen oder Kommentaren zu dieser Website an: mailto:info@cpp-tutor.de
 Wolfgang Schröder, Lerchenweg 23, D-72805 Lichtenstein. Tel: +49 7129 6470