CDocument aufräumen und Messagebox ausgeben können
-
@hustbaer sagte in CDocument aufräumen und Messagebox ausgeben können:
- Du solltest in deiner
CMyWindow::OnClose
Funktion dieMessageBox
anzeigen bevor du dieOnClose
Funktion der Basisklasse aufrufst.
Die Routinen, die ich für das Aufräumen brauche, kommen aus einer MFC-Erweiterungs-DLL. Das Problem scheint zu sein, dass zum Zeitpunkt des Aufrufs die DLL schon entladen ist und es deshalb knallt.
Wieso sollte in
WM_CLOSE
des top-level Fensters schon etwas entladen sein? Verstehe ich nicht.Das erste ist klar und das zweite verstehe ich auch nicht. Folgendes hab ich jetzt und es wird nicht angesprungen:
BEGIN_MESSAGE_MAP(CMFCApplication12View, CFormView) ON_WM_CONTEXTMENU() ON_WM_RBUTTONUP() ON_WM_CLOSE() END_MESSAGE_MAP() void CMFCApplication12View::OnClose() { // TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein, und/oder benutzen Sie den Standard. AfxMessageBox(_T("Test")); CFormView::OnClose(); }
Wenn ich einen Breakpoint in die OnClose setzte wird das nicht angesprungen. Hingegen:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx) ON_WM_CREATE() ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook) ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook) ON_COMMAND(ID_VIEW_CAPTION_BAR, &CMainFrame::OnViewCaptionBar) ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTION_BAR, &CMainFrame::OnUpdateViewCaptionBar) ON_COMMAND(ID_TOOLS_OPTIONS, &CMainFrame::OnOptions) ON_WM_CLOSE() END_MESSAGE_MAP() void CMainFrame::OnClose() { // TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein, und/oder benutzen Sie den Standard. AfxMessageBox(_T("Test")); CFrameWndEx::OnClose(); }
funktioniert.
- Du solltest in deiner
-
Dass es in der View nicht geht ist klar, da die View kein
WM_CLOSE
bekommt. DieWM_CLOSE
Message teilt dem top-level Fenster mit dass jemand es bitte gerne schliessen möchte. z.B. wenn man auf den "X" Button klickt oder Alt-F4 drückt. Das Fenster muss dieser Bitte nicht nachkommen. Wenn es der Bitte nachkommen möchte, dann zerstört es sich imWM_CLOSE
Handler selbst indem esDestroyWindow
aufruft. Im MFC Framework wird das gemacht indem man dieOnClose
Funktion der Basisklasse aufruft, also z.B.CFrameWndEx::OnClose()
. Duch denDestroyWindow
Aufruf werden dann auch alle Child-Fenster mit zerstört.Daher würde es auch keinen Sinn machen
WM_CLOSE
an ein Child-Fenster zu schicken. Die Entscheidung trifft immer das top-level Fenster, das Child-Fenster hat da nix mitzureden.
-
@hustbaer
Vielen Dank, so direkt war mir das nicht klar. Dachte immer das der Weg über die View zum Mainframe geht. Aber noch mal ne Frage zur Messagebox. Was wird mindestens benötigt um die anzuzeigen? Wenn das View-Objekt nicht existiert müsste es ja noch gehen. Wie sieht es da mit Mainframe und Anwendungsobjekt aus?
-
@AndyDD
Es wird eigentlich überhaupt nichts benötigt, zumindest nicht beiMessageBox
aus der WINAPI. Was derAfxMessageBox
Aufruf genau braucht kann ich nur vermuten, vielleicht wird da das Parent-Fensterhandle über das Hauptfenster der Anwendung geholt. Wenn das dann schon zerstört wurde (also das komplette Objekt, nicht nur die Windows-Resourcen), dann geht einCWnd->GetSafeHwnd()
Aufruf natürlich in die Hose.
Im Grunde kann einAfxMessageBox
Aufruf nicht wesentlich viel mehr machen als einMessageBox
Aufruf. Wenn das so ein Timing Problem und man nicht genau feststellen kann, welches Objekt wann noch lebt, dann istMessageBox
mit 0 als Parent vielleicht eine Lösung.
-
Ich bin bei meiner Aussage auch von der Standard-WinAPI Funktion MessageBox ausgegangen und nicht einer speziellen Funktion.
-
@Th69
Jau, hab ich auch grad gesehen, dass du das schon vor 2 Tagen vorgeschlagen hast. Ist offensichtlich auch am TE vorbeigegangen.
-
Ich habe sowohl
MessageBox
mit NULL undAfxMessageBox
probiert im Destructor der Dokumentenklasse aufzurufen. Bei letzterem kommt zumindest noch ein Warnton, bei ersterm passiert gar nichts. Ich hab das schon hinbekommen Messageboxen beim Programmstart anzuzeigen, ohne das ein Fenster sichtbar war. Jedoch heißt das ja nicht, dass davon nicht schon eine Instanz existieren kann.
-
Ich weiss nicht ob es in allen Situationen möglich ist eine Message-Box anzuzeigen. Mag sein dass es da ein paar Sonderfälle gibt wo es nicht geht. Kann auch sein dass es vom OS aus ginge aber die MFC es nicht in allen Situationen verkraftet.
Das Anzeigen einer Message-Box führt ja dazu dass alle möglichen Messages "gesendet" werden (beim Erzeugen/Anzeigen des Message-Box Fensters) und danach wird eine Message-Schleife für das Message-Box Fenster ausgeführt. Dabei wird vermutlich auch das gerade aktive Fenster eine Message bekommen, nämlich z.B. dass es jetzt nicht mehr aktiv ist. Was passiert wenn z.B. gerade eine
WM_DESTROY
Handler für dieses Fenster "aktiv" ist (also wenn manMessageBox
aus demWM_DESTROY
heraus aufruft), weiss ich nicht. Jetzt nur als ein Beispiel wo ich mir vorstellen könnte dass es evtl. Probleme gibt. Hab's aber nicht ausprobiert, kann auch gut sein dass es in dem beschriebenen Fall eh funktioniert.
-
Wenn noch eine WM_QUIT Message in der Queue ist, beendet sich die MessageBox automagisch.
PostQuitMessage(0); MessageBox(NULL, TEXT("Text"), TEXT("Titel"), MB_OK); // Wird nicht angezeigt
-
@servus_ sagte in CDocument aufräumen und Messagebox ausgeben können:
Wenn noch eine WM_QUIT Message in der Queue ist, beendet sich die MessageBox automagisch.
PostQuitMessage(0); MessageBox(NULL, TEXT("Text"), TEXT("Titel"), MB_OK); // Wird nicht angezeigt
Ich glaub sowas wird wohl der Grund sein. Wie gesagt ich habe das jetzt in CMainFrame::OnDestroy() platziert und da funktioniert es zumindest so, wie ich es brauche.