TN017: Niszczenie obiektów okien

Uwaga ta opisuje funkcję Państwa CWnd::PostNcDestroy . Użyj tej funkcji, jeśli chcesz dostosowanych alokacji CWnd-pochodnych obiektów.

Uwaga ta również wyjaśnia przyczyny dla reguły, kardynał:

Zniszczenie obiektu C++ Windows, użyj DestroyWindow nie "usuwanie".

Jest to ważne. Jeśli wykonasz poniższe wytyczne, będzie miał kilka problemów oczyszczanie (takich jak włączaniu do usuwania/zwalnia pamięć C++, włączaniu do wolnych zasobów systemowych, takich jak HWNDs lub zwalnianie obiektów zbyt wiele razy).

Problem

Obiekty systemu Windows (obiekty klasy pochodzące od CWnd) reprezentują zarówno obiekt C++ (przydzielone w aplikacji sterty), jak i HWND (przydzielone zasoby systemowe przez menedżera okien). Ponieważ zniszczenie obiektu okna na wiele sposobów, oferujemy zestaw reguł, aby zapobiec zasobu systemu lub przecieki pamięci aplikacji i że zapobiegania obiektów i uchwyty Windows z zniszczeniu więcej niż raz.

Jest to więcej niż problem zarządzania pamięci. Obecność okien systemu Windows ma wpływ interfejsu użytkownika: okno rysowane na ekranie; po jest niszczony jest również wpływ na zasoby systemu. Przecieki pamięci C++ w przestrzeni adresowej aplikacji nie jest równie złe, jak przecieki zasobów systemowych.

Niszczenie systemu Windows

Są dwa sposoby dozwolone do zniszczenia obiektu Windows:

Pierwszy przypadek jest zdecydowanie najbardziej typowych. Ten przypadek dotyczy nawet wtedy, gdy DestroyWindow nie nazywa się bezpośrednio w kodzie. Jest w przypadku, gdy użytkownik zamyka bezpośrednio w oknie ramki ( Polecenie WM_CLOSE zostało domyślne jest wywołanie DestroyWindow), a kiedy niszczony jest okno nadrzędne, Windows wymaga DestroyWindow dla wszystkich dzieci.

Drugim przypadku użycia operatora Usuwanie obiektów systemu Windows, należy bardzo rzadko i tylko w przypadkach przedstawione poniżej.

Oczyszczanie automatyczne z CWnd::PostNcDestroy

Przy niszczeniu okno systemu Windows, ostatni komunikat systemu Windows wysyłane do okna jest WM_NCDESTROY. CWnd domyślną obsługę wiadomości (CWnd::OnNcDestroy) będzie odłączyć HWND z obiektu C++ i wywołują wirtualnego funkcji PostNcDestroy. Niektóre klasy zastępują funkcja ta służy do usuwania obiektu C++.

Domyślna implementacja CWnd::PostNcDestroy nie działają, który jest właściwe dla obiektów okno przydzielone ramki stosu lub osadzone w innych obiektów. Ta nie jest odpowiednia dla obiektów okien, które mają być przydzielone przez siebie na stercie (nie osadzone w innym obiekcie C++).

Tych klas, które są zaprojektowane do przyznawany przez siebie na stercie przesłonić funkcję Państwa PostNcDestroy do wykonywania "Usuń to". Ta instrukcja zwolni wszelkich pamięci C++ skojarzone z obiektem C++. Mimo że destruktor CWnd domyślne wywołuje DestroyWindow , jeżeli m_hWnd jest NIEZEROWA, nie doprowadzi do nieskończonej rekursji ponieważ dojście zostanie odłączone i NULL podczas fazy oczyszczania.

Uwaganbsp;CWnd::Post&NcDestroy zwykle nosi nazwę po Windows WM_NCDESTROY wiadomość jest przetwarzana jako część okna zniszczenia, i HWND i obiekt window C++ są już podłączone. CWnd::PostNcDestroy również zostanie wywołana w realizacji większości Tworzenie rozmowy, jeśli wystąpi awaria (patrz poniżej zasady Oczyszczanie automatyczne).

Automatyczne oczyszczanie klas

Poniższe klasy nie są przeznaczone do automatycznego oczyszczania. Zwykle są osadzone w innym obiekcie C++ lub na stosie:

Poniższe klasy są zaprojektowane do automatycznego oczyszczania. One są standardowo przydzielane przez siebie na stercie:

Jeśli chcesz przerwać któregokolwiek z tych zasad, należy zastąpić funkcję Państwa PostNcDestroy , w klasie pochodnej. Aby dodać auto oczyszczania do klasy, zadzwoń do klasy podstawowej, a następnie wykonaj usunąć. Aby usunąć auto oczyszczanie z klasy, wywołanie CWnd::PostNcDestroy bezpośrednio zamiast członka PostNcDestroy w bezpośrednim klasy podstawowej.

Najczęstszym zastosowaniem powyższego jest utworzenie niemodalny okno dialogowe, która może być alokowana na stercie.

Gdy do wywołania „Usuń"

Zalecany sposób zniszczenie obiektu Windows jest wywołanie DestroyWindow, albo funkcji składowej C++ lub globalnym :: DestroyWindow API.

Nie wywołuj globalnym :: DestroyWindow API do zniszczenia okno potomne MDI, należy użyć funkcji wirtualnych Państwa CWnd::DestroyWindow.

Dla obiektów C++ okna, które nie wykonują auto oczyszczanie, przy użyciu DestroyWindow zamiast usuwania pozwala uniknąć problemów mających wywołać DestroyWindow w CWnd:: ~ CWnd destruktor, gdy VTBL nie wskazuje się poprawnie pochodną klasy. Może to prowadzić do błędów subtelne tak wersji diagnostyczne (debugowanie) MFC będzie ostrzegać o

Ostrzeżenie: wywołanie DestroyWindow w CWnd:: ~ CWnd
 nbsp; OnDestroy lub Post&NcDestroy w klasie pochodnej nie zostanie wywołany

W przypadku dóbr C++ Windows, wykonywać oczyszczanie automatyczne musi wywołać DestroyWindow. Użycie operatora, Usuń bezpośrednio, przydzielania diagnostyki pamięci usługi MFC zostanie wyświetlony alert że są zwalniania pamięci, dwukrotnie (pierwsze wywołanie usunięcia ), jak i pośrednich wywołanie "usunąć" w wykonaniu auto oczyszczanie PostNcDestroy.

Po wywołaniu DestroyWindow w obiekcie Oczyszczanie automatyczne, obiekt C++ nadal będzie się wokół, ale m_hWnd będzie mieć wartość NULL. Po wywołaniu DestroyWindow obiektu auto oczyszczanie, obiekt C++ będzie gone, zwolnione przez operatora delete C++ w realizacji auto oczyszczanie PostNcDestroy..

Uwagi techniczne przez liczbę |nbsp; Uwagi techniczne według kategorii

Index