Zeiger auf Dialog löschen
-
Hallo
So habe mir nun mal etwas selber geholfen. Habe nun
SendMessage(m_pdlgTest->m_hWnd,WM_DESTROY,NULL,NULL);
gesendet.
Und im Dialog habe ich in OnDestroy das Objekt mit delete this gelöscht.
So nun meine Frage! Ist das so in Ordnung? Und was ist besser zu senden WM_DESTROY oder WM_CLOSE wo liegt der Unterschied?
-
Man darf kein WM_DESTROY an ein Fenster senden. WM_DESTROY ist eine Benachrichtigung und keine Aktion.
Du darfst WM_CLOSE senden.Lies doch einfach die MSDN.
-
Lies doch einfach die MSDN.
Das habe ich getan. Aber ich kann nirgends lesen wo steht dass man kein WM_DESTROY an ein Fenster senden darf.
-
Du darfst WM_CLOSE senden.
WM_CLOSE wird aber gesendet wenn ich den Dialog schliesse. Sprich wenn ich meinen Dialog auch nur ausblende wird dann die Funktion onClose aufgerufen. Und dort datf ich auf keinen Fall den Zeiger löschen.
-
Push!
-
Ein WM_CLOSE zerstört den Dialog, aber es zerstört nihct das Objekt. delete tis wird nur für Frame Windows, Views, Toolbars, Tipps etc. verwendet.
Deine Frage war doch wie man den Dialog schließt!
-
Sorry bin jetzt erst wieder dazu gekommen.
Deine Frage war doch wie man den Dialog schließt!
Nein. Ich will den Dialog nicht schliessen sondern löschen.
Also er wurde ja mit Create angelegt und muss nun wieder mit Destroy beendet werden.
Da dachte ich einfach ich sende WM_DESTROY und fange diese Nachricht ab und darin mache ich delete this.
Was ist daran nun falsch oder wie geht es besser bzw. richtig?
-
push
-
Wenn ein Fenster/Dialog mit CreateWindow/CreateDialog angelegt wurde muss er mit DestroyWindow zerstört werden.
Aber es bleibt dabei, dass man DestroyWndow nicht aus einem anderen Thread ausführen kann.
Aber Du hast doch schon ale Antworten bekommen. Sende dem Fenster selbst eine eigene Nachricht oder gib dem Thread ein Signal, dass er das Fenster zerstört.
-
Ich darf DestroyWindow nicht ausführen von einem anderen Thread, das habe ich gelesen. Aber nirgends steht dass ich WM_DESTROY nicht senden darf.
...gib dem Thread ein Signal
Und wie, ich weiß es halt nicht.
-
sasse schrieb:
Und wie, ich weiß es halt nicht.
Setze ein Flag, das abgeprüft wird...
Wenn Du nicht weißt wie das geht, dann lerne erst einmal etwas von den Grundzügen des Programmierens!
Fröhliche Weihnachten! :xmas1:
-
Ich erzeuge ja aber gar kein Thread. Dies geschiet ja durch eine andere Applikation.
Ich erzeuge in InitInstance meinen Dialog und in ExitInstance soll er wieder gelöscht werden. ExitInstance wird nun aber von einem anderen Thread aufgerufen. Also wo soll ich da bitte ein Flag setzen.
Und wieso darf ich WM_DESTROY nicht senden?
-
Es ist schon seltsam. Man versucht hier sein Problem zu klären. Dann erhält man Tipps, was auch echt toll ist. Nur das Problem ist wenn einem diese Tipps nicht helfen und man versucht das Problem genauer zu erläutern. Und erklärt wieso einem die Tipps nichts bringen. Schüttelt man unverständlicherweise den Kopf und das wars dann.
Ich versuche hier nochmals mein Problem genau zu definieren.Also ich habe eine DLL die von einer fremden Applikation geladen wird. In InitInstance werden mehrere Dialoge mit new und Create angelegt. Nun sollte ja bei ExitInstance diese Dialoge wieder zerstört und gelsöcht werden. Also mit DestroyWindow und mit delete. Nun allerdings wird von der fremden Applikation allerdings ein anderer Thread dazu verwendet um die DLL zu entladen. Das sehe ich daran dass ich im Debugger den aktuellen Thread kontrolliere.
Wenn ich nun einfach m_myDlg1->DestroyWindow() aufrufe erhalte ich einen Fehler weil DestroyWindow nicht von einem anderen Thread aufgerufen werden darf, als der der ihn erzeugt hat. Sprich ich muss nun eine Nachricht senden die den Dialog zerstört. Und dort drin kann ich dann auch delete this aufrufen.
Aber nun weiß ich halt nicht was ich da genau senden soll und wie das ganze dann abfangen.
Also bitte kann mir da keiner eine genaue Auskunft geben.
-
Wenn eine fremde EXE Deine DLL aus mehreren Threads verwendet, dann ist die MFC bestimmt nicht das Tool der Wahl, denn MFC Objekte sind threadafin, d.h. sie dürfen nur von dem Thread aus verwendet werden, der das Objekt/Fenster erzeugt hat.
- Wenn das aufrufende Programm ein Stück .NET Software ist, dann ist es sehr wahrscheinlich, dass der Garbage Collector aus einem anderen Thread Objekt abräumt.
- Wenn Dir also geraten wird aus enem Thread an ein Fenster eine Nachricht zu senden, dann mach dies doch einfach (SendMessage)
- Eine eigene Nachricht definieren geht ja auch (WM_APP+n)
- Einen Handler für die Nachricht in Deinen Dialog einbauen geht auch (ON_MESSAGE).Mit den Angaben, die ich Dir gemacht habe, hättest Du all dies ohne Probleme in Google nachschlagen können.
Wenn die fremde Software DLLs lädtmuss es ja wohl auch eine Doku dazu geben, oder geht es hier wieder um Hooks etc.?
-
Hallo nochmal
Einen Handler für die Nachricht in Deinen Dialog einbauen geht auch (ON_MESSAGE).
Ja aber was mach ich den in der Funktion dann? DestroyWindow aufrufen oder was?
-
sasse schrieb:
Hallo nochmal
Einen Handler für die Nachricht in Deinen Dialog einbauen geht auch (ON_MESSAGE).
Ja aber was mach ich den in der Funktion dann? DestroyWindow aufrufen oder was?
Ja sicher! Was sonst?
Dann bist Du doch im selben Thread! Durch SendMessage erfolgt (wenn notwendig) ein Threadwechsel.
-
Ok werde ich versuchen. Aber jetzt habe ich Urlaub :xmas1:
Also Danke mal.
-
So Urlaub vorbei. Habe das ganze nun getestet. Es funktioniert allerdings nur teilweise. Ich rufe SendMessage für 4 Dialoge auf. Bei 2en kommt die Nachricht aber nur an. Gibt es dafür eine Erklärung.
-
Hm merkwürdig, wenn es bei 2 Dialogen funktioniert. - Hast du denn nähere Informationen dazu?
-
Ich rufe hintereinander Sendmessage auf für alle 4 Dialoge
SendMessage(m_pmydlg1->m_hWnd,WM_APPWICI,NULL,NULL); SendMessage(m_pmydlg2->m_hWnd,WM_APPWICI,NULL,NULL); SendMessage(m_pmydlg3->m_hWnd,WM_APPWICI,NULL,NULL); SendMessage(m_pmydlg4->m_hWnd,WM_APPWICI,NULL,NULL);
folgendes in jeder MessageMap der jeweiligen Klassen
ON_MESSAGE(WM_APPWICI,&CMyDlg1::MyDestroyWindow)
Funktion sieht dann wie folgt aus
LRESULT CRuntimeInfoDlg::MyDestroyWindow(WPARAM wparam, LPARAM lparam) { DestroyWindow(); delete this; return (LRESULT)0; }
Und noch was wenn DestroyWindow vom ersten Dialog aufgerufen wird. Wird DestroyWindow auch in allen weiteren Dialogen ausgeführt. Also vor SendMessage des jeweiligen Dialoges.