Dialog beenden



  • Tach zusammen,

    ich möchte per Knopfdruck auf meinem Hauptfenster (MDI) alle meine Dialoge beenden. Ich zeige meine Dialog mit ShowWindow an und nicht mit DoModal.

    Ich habe es mit DestroyWindow versucht, aber damit bringe ich mein Programm zum Abstürz.

    Danke im Voraus!
    CChris



  • Hallo.

    Wenn Du Deine Fenster anzeigst hast Du doch bestimmt einen Zeiger auf die Klasse. Lösche doch diesen Zeiger. Danach sollte sich das Fenster schließen, ohne Absturz.
    Weiß aber nicht ob das hilft.
    Oli_1977



  • Bei nonmodal Dialog z.B. so:

    m_pDlg->DestroyWindow();
    


  • Halli Hallo,

    So hab ich mir das auch gedacht, aber leider bekomm ich eine Fehlermeldung (Assert) wenn ich m_pDlg->DestroyWindow(); ausführe

    Lösche doch diesen Zeiger.

    Meinst du mit delete? Wenn ja, dann muss das doch einen Haken haben, weil sonst würde es ja kein DestroyWindow, OnClose, OnCancel oder so geben, oder?

    Grüße



  • Ein Assert bei diesem Aufruf, wieso ?
    Ich vermute der Zeiger ist nicht mehr gültig ?

    Gruß
    Marcus



  • Hi,

    ich mache das so:

    if(m_pDlg != NULL && m_pDlg.GetSafeHwnd() != NULL)
    m_pDlg->DestroyWindow();

    das sollte eigentlich ausschließen dass der Zeiger ungültig ist.

    Danke!
    Viele Grüße



  • Hallo,

    Deine Abfrage muß nicht zuschlagen.
    Wenn Du den Zeiger irgend wo löscht und nicht auf NULL setzt, schlägt Deine Abfrage eventuell nicht zu.

    Oli_1977



  • Warum so umständlich?

    if(m_pDlg) 
    m_pDlg->DestroyWindow();
    


  • Also, ~CWnd ruft DestroyWindow sowieso automatisch auf, falls es noch im Besitz eines Fensters ist. Hast du also ein CWnd* p; kannst du getrost delete p; benutzen und kannst dir sicher sein, dass das Fenster auch zerstört wird. Einen Test, ob p != 0 ist, kannst du dir auch sparen, da delete 0 in C++ erlaubt ist und keinen Effekt hat.
    Create und Destroy existieren, da über die Lebenszeit des Objekts nicht ständig ein Fenster mit diesem verbunden sein muss. Du kannst sozusagen auch schon existierende Fenster mit einem neuen CWnd-Objekt "wrappen" beispielsweise um damit komfortabler arbeiten zu können. Außerdem ist das ganz wichtig, wenn man die CWnd's gerne in Klassen abspeichert anstatt immer mit Zeigern hantieren zu müssen. Nicht immer möchte man auch sofort ein Fenster erstellen, wenn ein Objekt der Klasse erstellt wird.
    Außerdem kann man sich GetSafeHwnd() sparen wenn man vorher schon getestet hat, ob der this-Zeiger 0 ist oder nicht.

    Viele Grüße,
    Michael



  • Servus,

    das nenn ich mal ne ausführliche Antwort 👍!

    Ich glaube ich weiss woran das Problem liegt. Ich verwende eine DLL, diese DLL exportiert genau eine Funktion:

    ShowGui()
    {
    if(NULL == m_pMainDlg)
    {
      m_pMainDlg = new CMainDlg(NULL, m_pHardwareManager);
      m_pMainWnd = m_pMainDlg;
      m_pMainDlg->Create();
      m_pMainDlg->ShowWindow(SW_SHOW);
    }
    else
      m_pMainDlg->SetActiveWindow();
    }
    

    Ich vermute wenn ich in einer Exe diese Funktion aufrufe, dann wird das Fenster in einem neuen Thread gesterartet und ich kann nicht DestroyWindow() aus einem anderen Thread aus aufrufen. Ist aber wie gesagt nur eine Vermutung.

    Des Weiteren bin ich mir über folgende Zuweisung nicht ganz im Klaren, ich habe sie einfach aus dem vom Assi erzeugten Code übernommen

    m_pMainWnd = m_pMainDlg;
    

    (Meine DLL funktioniert auch ohne diese Zuweisung prima)

    Viele Grüße :xmas1: :xmas2:



  • Meist hilft es auch einfach, mal den Debugger "während" des Absturzes um Hilfe zu bitten. Hilft natürlich nur, wenn man die Professional-Version mit Source für MFC da hat, falls der Fehler in den entsprechenden Klassen auftritt.

    Viele Grüße,
    Michael


  • Mod

    1. Für die Funtkion der MFC ist

    m_pMainWnd = m_pMainDlg;
    

    jedoch wichtig. Es ist das AfxGetMainWnd was in einigen Positionen benötigt wird.
    Die Frage ist: Was soll dieser Code in einem Stück MDI Code?
    2. Ein CDialog hat keinen Autodestruktor (OnPostNcDestroy), der beim Zersötrn des Dialoges auch den Dialog freigibt! Wenn Du den Dialog mit new anlegst, dann wird der Speicher beim Schließen des Dialoges nicht freigegeben.



  • Guten Abend!

    Gut zu wissen -> m_pMainDlg!

    Vielleicht habe ich mich etwas blöd ausgedrückt, also diese Dialoge stecken in einer DLL und ich möchte sie momentan in einem MDI anzeigen. Da der Nutzen dieser Dialoge aber auch für andere Anwendungen interessant sein könnte möchte ich die Dialoge in einer DLL bereit stellen.

    Wichtig ist jedoch dass ich auch eine Funktion hab die mir die Fenster auch wieder schließt, falls der Benutzer das nicht tut aber die Hauptanwendung beendet.

    Die Dialoge werden mit der genannten ShowGui()-Funktion angezeigt. Ich möchte den Dialog nur irgendwie schließen. DestroyWindow() wird in OnCancel vorgenommmen und delete in OnPosNcDestroy(). Aber egal wie ich es anstelle stürzt mein Proggie immer ab wenn ich versuche den Dialog zu schließen.

    Ich hab auch schon versucht eine WM_DESTROY Message an das Fenster zu schicken, aber immer das Gleiche 👎.

    Hilfe Hilfe 😕

    Schönes WE!



  • Hi!

    Hat niemand einen Tipp für mich?

    CChris :xmas1:


  • Mod

    Was ist das für eine DLL? Standard, extension DLL?
    Warm eine DLL?
    Was ist das für eine EXE?
    Soll die DLL eigenstöändig laufen oder läuft dieimmer im Paket und der gleichen Version wie die EXE?

    Rufst Du auch DestroyWindow aus der DLL heraus aus?
    Was sagt der Stack Trace wenn es kracht?



  • Hallo,

    Was ist das für eine DLL? Standard, extension DLL?

    Eine reguläre MFC-DLL

    Warm eine DLL?

    Weil es später einmal ein Teil einer großen Anwendung werden soll

    Was ist das für eine EXE?

    Momentan eine Mfc-Dialogbasierende Anwendung -> später aber eine beliebige exe (mit graphischer oberfläche)

    Ich habe das Problem gelöst, ich habe AFX_MANAGE_STATE(AfxGetStaticModuleState()); in der Close-Methode vergessen.

    Aber jetzt kracht es immer noch wenn ich die ESC-Taste im Dialog drücke. Wenn ich die Anwendung normal schließe klappt alles einwandfrei... was passiert denn wenn ich die Esc-Taste in meinem Dialog drücke??

    Danke
    CChris :xmas2:


  • Mod

    Bei einem nicht modalen Dialog gar nichts!



  • Also ich hatte mir ja nen Nicht-Modalen Dialog immmer so vorgestellt wie ein normales Fenster, außer dass da halt eine erweiterte Fensterprozedur implementiert ist, die Kinderfenster verwaltet. Warum sollte man den nicht wie ein ganz normales Fenster auch zumachen können? Oo



  • Bei einem nicht modalen Dialog gar nichts!

    ... so hab ich mir das auch vorgestellt, aber leider reagiert meine Anwendung trozdem auf die ESC-Taste.

    Darum wollte ich ja wissen, was im CDialog passiert wenn man auf die ESC-Taste drückt, also was alles aufgerufen wird.

    Also ich hatte mir ja nen Nicht-Modalen Dialog immmer so vorgestellt wie ein normales Fenster, außer dass da halt eine erweiterte Fensterprozedur implementiert ist, die Kinderfenster verwaltet. Warum sollte man den nicht wie ein ganz normales Fenster auch zumachen können? Oo

    Sorry, aber ich versteh nicht ganz wie du das meinst 😕

    Danke



  • Also für mich sieht das gerade echt so aus, als hättest du irgendein anderes Problem, doktorst da jetzt irgendwie rum und traust dich nicht, mal zu schauen was der Debugger so sagt.



  • Hallo,

    witzig... wieso soll ich mich nicht trauen zu schuaen was der debugger sagt 😃 ?

    Der Debugger hängt sich an folgender Stelle auf und durch die Methoden hindurch zu debuggen is nicht, weil ich irgendwann die Meldung bekomme dass der Quellcode nicht verfügbar ist:

    void CWnd::AssertValid() const
    {
    ...
    ASSERT(::IsWindow(m_hWnd));
    ...
    }

    Deshalb habe ich auch nicht die möglichkeit zu schauen welche Methoden aufgerufen werden wenn ich ESC-Taste drücke.

    Ich verwende IsDialog-Message um Definierte Taste wie z. B. ESC, Pfeil-Tasten oder Tab an mein Dialog weiter zuleiten.

    Viele Grüße!


Anmelden zum Antworten