Child-Dialog sauber schließen
-
Habe nachdem vorher geklärten Problem mit dem Vorder-/Hintergrund jetzt das Problem, das es zwar funktioniert, ich aber nicht weiss, wie ich das Fenster "sauber" beende.
void CLineAnalyzerDlg::OnButtonClickedConfigLeft() { if (m_pConfig == NULL) { m_pConfig = new CConfig(); m_pConfig->Create(IDD_CONFIG, GetDesktopWindow()); m_pConfig->ShowWindow(SW_SHOW); } else m_pConfig->SetActiveWindow(); }
m_pConfig wird im Konstruktor mit NULL gefüllt und in der Headerdatei mit
CConfig* m_pConfig;
deklariert. Ich wollte mit der if-Schleife verhindern, dass das Fenster mehrmals zu öffnen ist, was ja auch nicht logisch wäre. Jetzt habe ich den Effekt, das wenn ich das Fenster einmal zugemacht habe, es nicht mehr aufgeht, weil der Pointer nicht gelöscht wurde, er das Fenster aber auch nicht mehr findet. Da hat auch
void CConfig::PostNcDestroy() { delete this; }
nicht geholfen, die Routine wird garnicht aufgerufen. Das Dialogfenster wir nur per X rechts oben geschlossen, nicht per Button. Wie kann ich den Pointer sauber löschen?
-
das problem ist ja, dass der Parentdialog mitbekommen muss, wenn du den configdialog schliesst. dann muss im parentdialog ein:
if (m_pConfig) { delete m_pConfig; m_pConfig = NULL; }
gemacht werden. Aber wie der parentdialog das schließen mitbekommt habe ich jetzt keine idee.
Vielleicht über irgendein flag, aber das geht bestimmt auch anders.
Ich nehme mal an, dass der Configdialog ein nicht-modaler dialog ist
-
Horst2 schrieb:
Aber wie der parentdialog das schließen mitbekommt habe ich jetzt keine idee.
Das wollte ich wissen, ja.
Horst2 schrieb:
Ich nehme mal an, dass der Configdialog ein nicht-modaler dialog ist
Ja, ist er.
-
du könntest dem parentdialog auch eine message sende, wenn sich der clientdialog beendet
-
Also die Stelle, an der ich die Message schicken müsste, habe ich gefunden, aber wie schickt man "manuell" Messages?
BEGIN_MESSAGE_MAP(CConfig, CDialog) ON_WM_CLOSE() END_MESSAGE_MAP() ... void CConfig::OnClose() { // Hier müsste die Nachricht geschickt werden }
-
genau.
Du musst dir eine eigene Message definieren.
#define MM_CONFIG_CLOSED (WM_USER + 1)
Dann brauchst du eine Methode um auf die Message zu reagieren
void CParentDlg::OnConfigClosed(UINT wparam, LONG lparam) { }
und du musst die message in deine messagemap einfügen
ON_MESSAGE(MM_CONFIG_CLOSED, OnConfigClosed)
natürlich die Funktion im header des parentdlg auch deklarieren.
gesendet wird die Message mit SendMessage() oder PostMessage()
-
So wird das Config-Fenster geschlossen:
void CConfig::OnClose() { ::AfxMessageBox("Jetzt wird das Fenster geschlossen."); }
So nicht, Config-Fenster bleibt offen:
void CConfig::OnClose() { PostMessage(MM_CONFIG_CLOSED,0,0); }
-
So, ich schreibe mal, wie ich es gelöst habe, aber bitte nicht laut schreien, hat teilweise so ein bisschen "Hornbach"-Flair... mit Hammer und Nagel!
afx_msg LRESULT OnConfigClosed(WPARAM, LPARAM);
UINT WM_CONFIG_CLOSED = RegisterWindowMessage("WINDOWCLOSED"); ... BEGIN_MESSAGE_MAP(CLineAnalyzerDlg, CDialog) ... //}}AFX_MSG_MAP ON_REGISTERED_MESSAGE(WM_CONFIG_CLOSED, OnConfigClosed) ... END_MESSAGE_MAP() ... LRESULT CLineAnalyzerDlg::OnConfigClosed(WPARAM wParam, LPARAM lParam) { if (m_pConfig) { delete m_pConfig; m_pConfig = NULL; } return (LRESULT)0; }
void CConfig::OnClose() { CWnd* WHandle = FindWindow(NULL, "LineAnalyzer"); UINT WM_CONFIG_CLOSED = RegisterWindowMessage("WINDOWCLOSED"); WHandle->PostMessage(WM_CONFIG_CLOSED,0,0); }
Verbesserungs- und Optimierungsvorschläge sind herzlich willkommen, dass ist halt leider doch nur Quick&Dirty.
-
Gib doch dem Konstruktor von dem CConfig einen Zeiger auf den aufrufenden Dialog mit. Den kannst du dann verwenden, das ist wohl besser als FindWindow.
-
Danke estartu_de!
Stimmt, hätte ich mal selbst drauf kommen sollen...
if (m_pConfig == NULL) { m_pConfig = new CConfig(this); // im Standardkostruktor das =NULL rausgenommen m_pConfig->Create(IDD_CONFIG, GetDesktopWindow()); ... }
CConfig::CConfig(CWnd* pParent /*=NULL*/) : CDialog(CConfig::IDD, pParent) { m_pParent = pParent; // ist in .h als CWnd* m_pParent deklariert } ... void CConfig::OnClose() { UINT WM_CONFIG_CLOSED = RegisterWindowMessage("WINDOWCLOSED"); m_pParent->PostMessage(WM_CONFIG_CLOSED,0,0); }
Weitere Verbesserungen?