Aracılığıyla paylaş


TN017: Window nesnelerinden yok

Bu not açıklar CWnd::PostNcDestroy yöntemi.Özelleştirilmiş ayrılması yapmak istiyorsanız bu yöntemi kullanın CWnd-türetilen nesneler.Bu not da neden kullanmanız gerektiğini açıklar CWnd::DestroyWindow yerine C++ Windows nesneyi yıkmak için delete işleci.

Bu konudaki yönergeleri izleyin, birkaç temizleme sorunlara sahip olacaktır.Sil/unutulması gibi sistem kaynakları boşaltmak C++ bellek boşaltmak unutulması gibi sorunlardan bu sorunların neden HWNDs veya nesneleri birden çok kez boşaltma.

Sorunu

Windows her nesnenin (bir sınıfın nesnesini elde edilen CWnd) hem bir C++ nesnesi gösterir ve bir HWND.C++ nesneleri, uygulamanın öbeğe ayrılır ve HWNDs, sistem kaynaklarında Pencere Yöneticisi tarafından ayrılır.Bir window nesnesi yıkmak için çeşitli yollar nedeniyle sistem engelleyen kurallar kümesi sağlamanız gerekir kaynak veya bellek sızıntıları.Bu kurallar ayrıca nesneleri ve Windows işleme birden çok kez yok engellemelisiniz.

Windows yok

Windows nesneyi yıkmak için izin verilen iki yolları şunlardır:

  • Arayan CWnd::DestroyWindow veya Windows API DestroyWindow.

  • İle açıkça silme delete işleci.

İlk durum yanı sıra yaygın olarak kullanılır.Kodunuzu çağrılmayan bile bu durum geçerlidir DestroyWindow doğrudan.Kullanıcı doğrudan çerçeve penceresi kapandığında, bu eylemi oluşturur WM_CLOSE iletisi bu ileti için varsayılan yanıt ise çağırmak için DestroyWindow. bir üst pencere bozulduğunda Windows çağıran DestroyWindow tüm çocuklar için.

İkinci durumda, kullanımını delete operator Windows nesnelerinde nadir olmalıdır.Bazı durumlarda kullanarak burada aşağıdaki öğeler delete doğru bir seçimdir.

CWnd::PostNcDestroy ile otomatik temizleme

Windows pencere sistem kaynaklarýný penceresi gönderilen son Windows ileti olur WM_NCDESTROY.Varsayılan CWnd bu ileti işleyicisi CWnd::OnNcDestroy.OnNcDestroyAyır HWND C++ nesnesi ve sanal işlev çağrısı PostNcDestroy.Bazı sınıflar C++ nesneyi silmek için bu işlevi geçersiz kılar.

Varsayılan uygulama olarak CWnd::PostNcDestroy , yığın çerçevesi üzerinde ayrılan veya diğer nesneleri katıştırılmış pencere nesneler için uygun olduğu yapmaz.Bu olmadan diğer nesnelerin yığın tahsis edilecek tasarlanmış penceresindeki nesneler için uygun değildir.Diğer bir deyişle, diğer C++ nesneleri gömülü pencere nesneler için uygun değil.

Geçersiz kılma öbek üzerinde tek başına ayrılması için tasarlanmış bu sınıfların PostNcDestroy yöntemi gerçekleştirmek için bir delete this.Bu ifade, C++ nesnesi ile ilişkilendirilmiş bellekleri kazandıracaktır.Rağmen varsayılan CWnd yıkıcı çağrıları DestroyWindow , m_hWnd olan çıkarılmış ve boş tutamaç temizleme aşamasında olacağı için null olmayan, bu sonsuz özyinelemeye neden değil.

[!NOT]

Genellikle sistem çağrıları CWnd::PostNcDestroy Windows işledikten sonra WM_NCDESTROY ileti ve HWND ve C++ window nesnesi artık bağlı.Sistem ayrıca çağrı CWnd::PostNcDestroy uygulamasında en CWnd::Create hatası oluşursa çağırır.Otomatik temizleme kuralları, bu konunun ilerisinde açıklanmıştır.

Otomatik temizleme sınıfları

Aşağıdaki sınıflar, otomatik temizleme için tasarlanmamıştır.Diğer C++ nesneleri veya yığın gömülü genellikle:

  • Tüm standart Windows denetimleri (CStatic, CEdit, CListBox, vb.).

  • Herhangi bir alt pencereleri doğrudan türetilen CWnd (örneğin, özel denetimleri).

  • Splitter pencereleri (CSplitterWnd).

  • Varsayılan Denetim çubuklarından (türetilmiş sınıfları CControlBar, bakın Teknik Not 31 denetim çubuğu nesneleri otomatik Sil etkinleştirilmesi için).

  • İletişim kutuları (CDialog) kalıcı iletişim kutularının yığını çerçeve için tasarlanmıştır.

  • Standart iletişim kutuları dışında CFindReplaceDialog.

  • ClassWizard tarafından oluşturulan varsayılan iletişim kutuları.

Aşağıdaki sınıflar, otomatik temizleme için tasarlanmıştır.Bunlar genellikle kendiliğinden öbek üzerinde ayrılır:

  • Windows ana çerçeve (doğrudan veya dolaylı olarak türetilen CFrameWnd).

  • Windows görüntüleme (doğrudan veya dolaylı olarak türetilen CView).

Bu kurallar kesmek isterseniz kılmalısınız PostNcDestroy yönteminde, türetilmiş bir sınıf.Otomatik temizleme sınıfı eklemek için sınıfınızın temel arama ve sonra bunu bir delete this.Otomatik temizleme kendi sınıfından kaldırma çağrısı CWnd::PostNcDestroy yerine doğrudan PostNcDestroy , doğrudan temel sınıf yöntemi.

Otomatik temizleme davranışı değiştirmenin en yaygın kullanımı, tahsis edilecek kalıcı olmayan bir iletişim öbek üzerinde oluşturmaktır.

Zaman aramayı silme

Sizi aramak öneririz DestroyWindow C++ yöntemi veya genel bir Windows nesneyi yıkmak için DestroyWindow API.

Genel arama DestroyWindow API bir MDI alt penceresi yok.Sanal bir yöntem kullanması gereken CWnd::DestroyWindow yerine.

C++ penceresi, gerçekleştirme otomatik temizleme nesneleri için delete operator neden olabilecek bir bellek sızıntısı çağırmaya çalıştığınızda DestroyWindow , CWnd::~CWnd vtbl için doğru türetilmiş bir sınıf işaret etmiyorsa yıkıcı.Bu yöntemi çağırmak için uygun bozmak sistemi bulamadığından oluşur.Kullanarak DestroyWindow yerine delete bu sorunları önler.Bu ince bir hata olması nedeniyle risk altındadır debug modda derleme aşağıdaki uyarı oluşturur.

Warning: calling DestroyWindow in CWnd::~CWnd
   OnDestroy or PostNcDestroy in derived class will not be called

Otomatik temizleme gerçekleştirmek C++ Windows nesneleri durumunda çağırması gerekir DestroyWindow.Kullanırsanız, delete operatör doğrudan, mfc Bellek Tanılama ayırıcısı verecektir, iki kez bellek boşaltma.İki oluşum ilk açık aramanız ve dolaylı çağrısı olan delete this 'nde otomatik temizleme PostNcDestroy.

Sonra arama DestroyWindow otomatik temizleme nesnesinde C++ nesnesi, geçici olmaya devam eder, ancak m_hWnd null olur.Sonra arama DestroyWindow nesneyi otomatik temizleme C++ nesne otomatik temizleme uygulamasında C++ delete operatörü tarafından serbest gitmiş, olur PostNcDestroy.

Ayrıca bkz.

Diğer Kaynaklar

Teknik notlar numarasına göre

Kategoriye göre teknik notlar