Diese Applikationsschrift beschreibt die Verwendung der CWnd::PostNcDestroy -Memberfunktion. Verwenden Sie diese Funktion, wenn Sie wünschen kundenspezifische Zuordnung von CWnd-abgeleiteten Objekten.
Dieser Hinweis erklärt auch einige der Gründe für die Kardinalspflicht:
Verwenden Sie DestroyWindow um ein C++ Windows-Objekt zu zerstören, nicht auf "Löschen".
Dies ist wichtig. Wenn Sie die folgenden Richtlinien befolgen, haben Sie einige Bereinigung Probleme (z. B. vergessen zu löschen/C++ Speicher frei, vergessen zu Systemressourcen wie HWNDs freigeben oder Freigeben von Objekten zu viele Male).
Das Problem
Windows Objekte (von von CWndabgeleiteten Klassen) stehen für ein C++-Objekt (in der Anwendung Heap reserviert) und ein HWND (vom Fenster-Manager in System-Ressourcen reserviert). Da gibt es mehrere Möglichkeiten, um ein Window-Objekt zu zerstören, müssen wir bieten eine Reihe von Regeln, die verhindern, dass Systemressource oder Anwendung Speicherverluste und, die Objekte und verhindern Windows-Handles zerstört mehr als einmal.
Das ist mehr als eine Speicher-Management-Problem. Das Vorhandensein eines Windows-Fensters Benutzeroberfläche wirkt: ein Fenster gezeichnet auf dem Bildschirm; Sobald es zerstört wird gibt es auch Auswirkungen auf die Systemressourcen. C++ Speicherverlust in den Adressbereich einer Anwendung ist nicht so schlimm wie Systemressourcen undicht.
Windows zu zerstören
Die beiden zulässigen Möglichkeiten, ein Windows-Objekt zu zerstören sind:
Der erste Fall ist bei weitem die häufigste. Dies gilt auch dann, wenn DestroyWindow nicht direkt vom Code aufgerufen wird. Das ist der Fall, wenn der Benutzer direkt ein Frame-Fenster schließt (das Standardverhalten WM_CLOSE ist DestroyWindowaufrufen), und wenn ein übergeordnetes Fenster zerstört wird, ruft Windows DestroyWindow für alle Kinder.
Der zweite Fall, die Verwendung des delete -Operators auf Windows-Objekte, sollte sehr selten und nur in den Fällen, die unten aufgeführten.
Automatische Bereinigung mit CWnd::PostNcDestroy
Wenn ein Windows-Fenster zu zerstören, ist die letzte Windows-Nachricht an das Fenster gesendet WM_NCDESTROY. Der CWnd -Standardhandler für diese Nachricht (CWnd::OnNcDestroy) wird das HWND aus der C++-Objekt, und rufen, dass der virtuellen Funktion PostNcDestroytrennen. Einige Klassen überschreiben diese Funktion um das C++-Objekt löschen.
Die Standardimplementierung der CWnd::PostNcDestroy nichts was geeignet für Window-Objekte auf dem Stapelrahmen zugeordnet oder in andere Objekte eingebettet ist. Dies ist nicht geeignet für Window-Objekte, die sich auf dem Heap (nicht in anderen C++-Objekt eingebettet) vergeben werden sollen.
Die Klassen, die von sich selbst auf dem Heap reserviert werden sollen die Memberfunktion PostNcDestroy ausführen ein "delete this" überschreiben. Diese Anweisung gibt C++ die C++-Objekt zugeordneten Arbeitsspeicher frei. Obwohl der Standard CWnd Destruktor DestroyWindow ruft Wenn M_hWnd ungleich NULL ist, führt dies nicht zu Endlosschleife da das Handle während der Bereinigung Phase getrennt und NULL sein wird.
Hinweis&Nbsp;CWnd::PostNcDestroy wird normalerweise aufgerufen, nachdem die Windows WM_NCDESTROY Nachricht verarbeitet wird, als Teil der Fenster Zerstörung, und das HWND als auch die C++-Fensterobjekt sind nicht mehr angebracht. CWnd::PostNcDestroy wird auch bei der Umsetzung der meisten Erstellen Aufrufe aufgerufen, wenn der Fehler auftritt (siehe unten für automatische Bereinigung Regeln).
Automatische Bereinigung Klassen
Die folgenden Klassen sind nicht für Auto-Cleanup entwickelt. Sie werden normalerweise in anderen C++-Objekt oder auf dem Stapel eingebettet.:
Die folgenden Klassen sind für Auto-Cleanup konzipiert. Sie sind normalerweise von selbst auf dem Heap reserviert:
Wenn Sie, diese Regeln zu brechen möchten, müssen Sie die PostNcDestroy Member-Funktion in der abgeleiteten Klasse überschreiben. Um Auto-Cleanup zu Ihrer Klasse hinzufügen, rufen Sie einfach Ihre Basisklasse, und führen Sie dann eine löschen diese. Um Auto-Cleanup aus Ihrer Klasse zu entfernen, rufen Sie CWnd::PostNcDestroy direkt anstelle des betreffenden PostNcDestroy in Ihrer direkten Basisklasse.
Die häufigste Verwendung der oben genannten ist ein nicht modales Dialogfeld, das zugeordnet werden kann auf dem Heap erstellen.
When to Call 'löschen'
Empfohlen, ein Windows-Objekt zu zerstören ist DestroyWindow, entweder die C++-Memberfunktion oder globalen aufrufen :: DestroyWindow API.
Rufen Sie nicht die globale :: DestroyWindow API zu eine untergeordneten MDI-Fenster verwenden Sie stattdessen die virtuelle Memberfunktion CWnd::DestroyWindow.
Für C++-Fensterobjekten, die Auto-Cleanup ausführen nicht, mithilfe von DestroyWindow statt Löschen vermeidet Probleme mit DestroyWindow aufrufen, der CWnd:: ~ CWnd Destruktor wo die VTBL ist nicht auf die korrekt abgeleitete Klasse. Dies kann zu geringfügige Fehler führen, so dass Sie mit die Diagnose (Debug) Version von MFC warnen
Warnung: Aufruf von DestroyWindow in CWnd:: ~ CWnd
&Nbsp; OnDestroy oder PostNcDestroy in abgeleiteten Klasse wird nicht aufgerufen werden
In der C++-Windows-Objekte, die Auto-Cleanup ausführen, müssen Sie die DestroyWindowaufrufen. Wenn Sie Operator Löschen direkt verwenden, benachrichtigt die MFC-Diagnose-Speicherreservierungsfunktion Sie, dass Sie zweimal (der erste Aufruf Löschen ) sowie den indirekten Aufrufdelete this"in der Auto-Cleanup-Implementierung von PostNcDestroySpeicherfreigabe sind.
Nach dem Aufruf von DestroyWindow auf einem nicht-Auto-Cleanup-Objekt, das C++-Objekt werden immer noch herum, aber M_hWnd wird NULL sein. Nach dem Aufruf von DestroyWindow auf ein Auto-Cleanup-Objekt, werden das C++-Objekt, gegangen durch die C++-Delete-Operator in der Auto-Cleanup-Implementierung der PostNcDestroy befreit..
Technische Hinweise von &Nummer |nbsp; Technische Hinweise nach Kategorie