Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Nota
Pustaka Microsoft Foundation Classes (MFC) terus didukung. Namun, kami tidak lagi menambahkan fitur atau memperbarui dokumentasi.
Catatan ini menjelaskan penggunaan CWnd::PostNcDestroy metode . Gunakan metode ini jika Anda ingin melakukan alokasi objek turunan CWnd yang disesuaikan. Catatan ini juga menjelaskan mengapa Anda harus menggunakan CWnd::DestroyWindow untuk menghancurkan objek C++ Windows alih-alih delete operator.
Jika Anda mengikuti panduan dalam artikel ini, Anda akan memiliki sedikit masalah pembersihan. Masalah ini dapat disebabkan oleh masalah seperti lupa menghapus/membebaskan memori C++, lupa untuk membebaskan sumber daya sistem seperti HWNDs, atau membebaskan objek terlalu banyak kali.
Masalahnya
Setiap objek windows (objek kelas yang berasal dari CWnd) mewakili objek C++ dan HWND. Objek C++ dialokasikan dalam timbunan aplikasi dan HWNDdialokasikan dalam sumber daya sistem oleh manajer jendela. Karena ada beberapa cara untuk menghancurkan objek jendela, kita harus menyediakan seperangkat aturan yang mencegah kebocoran sumber daya sistem atau memori. Aturan ini juga harus mencegah objek dan handel Windows dihancurkan lebih dari satu kali.
Menghancurkan jendela
Berikut ini adalah dua cara yang diizinkan untuk menghancurkan objek Windows:
Memanggil
CWnd::DestroyWindowatau Windows APIDestroyWindow.Menghapus secara eksplisit dengan
deleteoperator.
Kasus pertama sejauh ini adalah yang paling umum. Kasus ini berlaku bahkan jika kode Anda tidak memanggil DestroyWindow secara langsung. Ketika pengguna langsung menutup jendela bingkai, tindakan ini menghasilkan pesan WM_CLOSE, dan respons default terhadap pesan ini adalah memanggil DestroyWindow. Ketika jendela induk dihancurkan, Windows memanggil DestroyWindow untuk semua anaknya.
Kasus kedua, penggunaan delete operator pada objek Windows, harus jarang terjadi. Berikut ini adalah beberapa kasus di mana penggunaan delete adalah pilihan yang benar.
Pembersihan otomatis dengan CWnd::PostNcDestroy
Ketika sistem menghancurkan jendela Windows, pesan Windows terakhir yang dikirim ke jendela adalah WM_NCDESTROY. Handler default CWnd untuk pesan tersebut adalah CWnd::OnNcDestroy.
OnNcDestroy akan melepaskan HWND dari objek C++ dan memanggil fungsi PostNcDestroyvirtual . Beberapa kelas mengambil alih fungsi ini untuk menghapus objek C++.
Implementasi default CWnd::PostNcDestroy tidak melakukan apa pun, yang sesuai untuk objek jendela yang dialokasikan pada kerangka tumpukan atau disematkan dalam objek lain. Perilaku ini tidak sesuai untuk objek jendela yang dirancang untuk alokasi pada timbunan tanpa objek lain. Dengan kata lain, tidak sesuai untuk objek jendela yang tidak disematkan di objek C++ lainnya.
Kelas yang dirancang hanya untuk dialokasikan pada heap menimpa metode PostNcDestroy untuk melakukan delete this;. Pernyataan ini akan membebaskan memori apa pun yang terkait dengan objek C++. Meskipun destruktor default CWnd memanggil DestroyWindow jika m_hWnd tidak NULL, panggilan ini tidak menyebabkan rekursi tak terbatas karena handle akan dilepaskan dan NULL selama fase pembersihan.
Nota
Sistem biasanya memanggil CWnd::PostNcDestroy setelah memproses pesan Windows WM_NCDESTROY dan HWND dan objek jendela C++ tidak lagi tersambung. Sistem juga akan memanggil CWnd::PostNcDestroy dalam implementasi sebagian besar CWnd::Create panggilan jika kegagalan terjadi. Aturan pembersihan otomatis dijelaskan nanti dalam artikel ini.
Kelas pembersihan otomatis
Kelas-kelas berikut ini tidak dirancang untuk pembersihan otomatis. Mereka biasanya disematkan di objek C++ lain atau pada tumpukan:
Semua kontrol Windows standar (
CStatic, ,CEditCListBox, dan sebagainya).Setiap jendela anak berasal langsung dari
CWnd(misalnya, kontrol kustom).Jendela pemisah (
CSplitterWnd).Bilah kontrol default (kelas yang berasal dari
CControlBar, lihat Catatan Teknis 31 untuk mengaktifkan penghapusan otomatis untuk objek bilah kontrol).Dialog (
CDialog) yang dirancang untuk dialog modal pada bingkai tumpukan.Semua dialog standar kecuali
CFindReplaceDialog.Dialog default yang dibuat oleh ClassWizard.
Kelas berikut dirancang untuk pembersihan otomatis. Mereka biasanya dialokasikan sendiri di timbunan:
Jendela bingkai utama (diturunkan secara langsung atau tidak langsung dari
CFrameWnd).Lihat jendela (diturunkan secara langsung atau tidak langsung dari
CView).
Jika Anda ingin mengecualikan aturan ini, Anda harus mengesampingkan metode PostNcDestroy di kelas turunan Anda. Untuk menambahkan pembersihan otomatis ke kelas Anda, panggil kelas dasar Anda lalu lakukan delete this;. Untuk menghapus pembersihan otomatis dari kelas Anda, panggil CWnd::PostNcDestroy secara langsung alih-alih metode PostNcDestroy dari kelas dasar langsung Anda.
Penggunaan paling umum untuk mengubah perilaku pembersihan otomatis adalah membuat dialog tidak berpola yang dapat dialokasikan pada memori heap.
Kapan harus memanggil delete
Kami menyarankan agar Anda memanggil DestroyWindow untuk menghancurkan objek Windows, baik metode C++ atau API global DestroyWindow .
Jangan panggil API global DestroyWindow untuk menghancurkan jendela MDI Child. Anda harus menggunakan metode CWnd::DestroyWindow virtual sebagai gantinya.
Untuk objek C++ Window yang tidak melakukan pembersihan otomatis, menggunakan delete operator dapat menyebabkan kebocoran memori saat Anda mencoba memanggil DestroyWindow di CWnd::~CWnd destruktor jika VTBL tidak menunjuk ke kelas turunan yang benar. Kebocoran terjadi karena sistem tidak dapat menemukan metode penghancurkan yang sesuai untuk dipanggil. Menggunakan DestroyWindow alih-alih delete menghindari masalah ini. Karena kesalahan ini bisa halus, mengkompilasi dalam mode debug akan menghasilkan peringatan berikut jika Anda berisiko.
Warning: calling DestroyWindow in CWnd::~CWnd
OnDestroy or PostNcDestroy in derived class will not be called
Untuk objek C++ Windows yang melakukan pembersihan otomatis, Anda harus memanggil DestroyWindow. Jika Anda menggunakan delete operator secara langsung, alokator memori diagnostik MFC akan memberi tahu Anda bahwa Anda membebaskan memori dua kali. Dua kejadian tersebut adalah panggilan eksplisit pertama Anda dan panggilan tidak langsung ke delete this; dalam implementasi pembersihan otomatis PostNcDestroy.
Setelah Anda memanggil DestroyWindow pada objek non-pembersihan otomatis, objek C++ akan tetap ada, tetapi m_hWnd akan NULL. Setelah Anda memanggil DestroyWindow pada objek pembersihan otomatis, objek C++ akan hilang, dibebaskan oleh operator penghapusan C++ dalam implementasi pembersihan otomatis PostNcDestroy.
Lihat juga
Catatan teknis menurut angka
Catatan teknis menurut kategori