Dialoge erzeugen und zur Laufzeit wieder ordentlich den Speicher leeren
-
Hallo @all,
ich habe anscheinend einen Denkfehler, wie man mit verschiedenen Dialogen zur Laufzeit arbeitet und wie man diese wieder vollständig aus dem Speicher entfernt. Hier mal mein Konstrukt:
Ich habe ein Hauptprogramm in der ein Platzhalter (normales Static-Control) für verschiedene Unterdialoge / Klassen herhalten soll.
Im Header des Hauptprogramms habe ich die Zugriffe auf die folgenden Klassen unter
protected:definiert:
CKlasse01Dialog Dlg01; CKlasse02Dialog Dlg02; CKlasse03Dialog Dlg03;Das forciert ja, dass der Konstruktor aufgerufen wird.
Wenn man nun im Hauptprogramm auf die jeweiligen Buttons klickt, wird die folgende Funktion aufgerufen um den jeweiligen Unterdialog anzuzeigen:
///////////////////////////////////////////////////////////////////////////// // Zeigt den entsprechenden Dialog an und versteckt den derzeit aktiven Dialog void CHauptklasseDlg::DialogAnzeigen(int Nr) { CRect Rechteck; GetDlgItem(IDC_SHEET)->GetWindowRect(Rechteck); ScreenToClient(&Rechteck); // Den derzeit aktiven Dialog verstecken if ( AktuellerDialog == 1 && Nr != 1 ) { Dlg01.DestroyWindow(); } else if ( AktuellerDialog == 2 && Nr != 2 ) { Dlg02.DestroyWindow(); } else if ( AktuellerDialog == 3 && Nr != 3 ) { Dlg03.DestroyWindow(); } // Den entsprechenden Dialog anzeigen if ( Nr == 1 && AktuellerDialog != 1 ) { Dlg01.Create(CKlasse01Dialog::IDD, this); Dlg01.SetWindowPos(NULL, Rechteck.left, Rechteck.top, Rechteck.Width(), Rechteck.Height(), SWP_SHOWWINDOW); AktuellerDialog = 1; } else if ( Nr == 2 && AktuellerDialog != 2 ) { Dlg02.Create(CKlasse02Dialog::IDD, this); Dlg02.SetWindowPos(NULL, Rechteck.left, Rechteck.top, Rechteck.Width(), Rechteck.Height(), SWP_SHOWWINDOW); AktuellerDialog = 2; } else if ( Nr == 3 && AktuellerDialog != 3 ) { Dlg02.Create(CKlasse03Dialog::IDD, this); Dlg02.SetWindowPos(NULL, Rechteck.left, Rechteck.top, Rechteck.Width(), Rechteck.Height(), SWP_SHOWWINDOW); AktuellerDialog = 3; } }Nun sind mir dabei aber die folgenden Phänomene aufgefallen:
Wenn man bestimmte Variablen die in einer untergeordneten Klasse auf neue Werte gesetzt wurden beim erneuten Aufruf anspricht, beinhalten diese den zuvor gesetzten Wert. Das heißt, das DestroyWindow scheint nicht zu funktionieren, obwohl es aufgerufen wird!
Wenn ich mein Programm beende (mit ::PostQuitMessage(0); exit(0) etc.), kommt es mitunter vor, dass es abstürzt.
Wie geht man richtig vor?

-
Erstmal: DestroyWindow() zerstört nur das angezeigte Dialogfenster, aber nicht das dahinterliegende Objekt - das wird erst vom DTor vernichtet, wenn dein Programm beendet wird.
Zweitens: Ich weiß zwar nicht, was genau du vorhast, aber schau dir mal CPropertySheet an

-
Hi CStoll,
danke für die schnelle Reaktion!
Mit PropertyPages hab ich es zunächst versucht, dann schien mir dieses Konstrukt aber einfacher umzusetzen, zumal ich die dahinterliegenden Dialoge wieder in den "Urzustand" befördern möchte.
Gibt es keine Möglichkeit das dahinterliegende Objekt, wie du so schön schreibst, vorher komplett zu zerstören?Hat man eine andere Möglichkeit, ohne mit den PropertyPages arbeiten zu müssen, um weiter mein Konstrukt nutzen zu können ohne irgendwelche Fehler zu produzieren?

-
Du könntest Zeiger verwenden, die du bei jedem Wechsel des Dialogs wieder freigibst (wenn alle verwendeten Dialoge von der selben Basisklasse abgeleitet sind, reicht da sogar einer aus). Oder (ist vermutlich besser) du setzt alle relevanten Membervariablen des Fensters manuell auf ihren Startwert zurück, wenn er reinkarniert werden soll (die OnInitDialog()-Methode dürfte dafür geeignet sein).
-
Hmm...das mit den Membervariablen in der OnInit-Section bzw. eine spezielle Funktion zum Leeren der Variablen hab ich bereits proaktiv gemacht.

Mal ganz grundsätzlich, kann ich mein Konstrukt in der Form beibehalten, sprich mit dem Create und Destroy zur Laufzeit, ohne dass es mal zu Speicherüberläufen oder Ähnlichen kommt?
