หมายเหตุนี้อธิบายการใช้งานฟังก์ชันสมาชิกCWnd::PostNcDestroy ใช้ฟังก์ชันนี้ถ้าคุณต้องการปันส่วนแบบกำหนดเองของCWnd-มาวัตถุ?
หมายเหตุนี้ยังอธิบายถึงบางประการสำหรับกฎเชิงการนับ:
ทำลายวัตถุ Windows c ++ ใช้ DestroyWindow ไม่ "ลบ"?
นี่คือสิ่งสำคัญ ถ้าคุณทำตามคำแนะนำด้านล่างนี้ คุณจะมีปัญหาน้อยของการล้างข้อมูล (เช่นว่าจะลืมลบ/ฟรี c ++หน่วยความจำ ลืมไปฟรีทรัพยากรระบบเช่นHWNDs หรือเพิ่มวัตถุหลายครั้ง)?
ปัญหา
Windows วัตถุ (วัตถุของคลาสที่ได้รับจากCWnd) เป็นตัวแทนทั้งวัตถุ c ++ (ปันส่วนในกองของโปรแกรมประยุกต์) และการ HWND (ปันส่วนในระบบทรัพยากร โดยตัวจัดการหน้าต่าง) เนื่องจากมีหลายวิธีที่จะทำลายวัตถุในหน้าต่าง เราต้องมีชุดของกฎที่ป้องกันไม่ให้ทรัพยากรระบบ หรือโปรแกรมประยุกต์ที่หน่วยความจำรั่วไหล และที่ป้องกันวัตถุและจับ Windows ถูกทำลายมากกว่าหนึ่งครั้ง?
นี่คือปัญหาการจัดการหน่วยความจำมากกว่า การแสดงตนของหน้าต่าง Windows มีผลกระทบต่อผู้ใช้อินเทอร์เฟซ: หน้าต่างที่วาดบนหน้าจอ เมื่อมันถูกทำลาย ยังมีผลต่อทรัพยากรของระบบ Leaking c ++หน่วยความจำในพื้นที่แอพลิเคชันของคุณไม่ใช่ไม่ดีเป็น leaking ทรัพยากรระบบ?
เท่า Windows
วิธีการได้รับอนุญาตที่สองเพื่อทำลายวัตถุ Windows ได้:
กรณีแรกทีเดียวพบบ่อยที่สุดได้ กรณีนี้นำไปใช้ได้แม้ว่าDestroyWindowไม่ได้ถูกเรียก โดยใช้รหัสของคุณโดยตรง เป็นกรณีเมื่อผู้ใช้ปิดหน้าต่างเฟรม ( WM_CLOSEลักษณะเริ่มต้นเป็นการ เรียกDestroyWindow) โดยตรง และเมื่อหน้าต่างหลักถูกทำลาย Windows เรียกDestroyWindowสำหรับเด็ก ๆ?
กรณีที่สอง การใช้ตัวดำเนินลบวัตถุ Windows ควรหายากมาก และเฉพาะในกรณีอธิบายไว้ด้านล่าง?
การล้างข้อมูลโดยอัตโนมัติ ด้วย CWnd::PostNcDestroy
เมื่อเท่าหน้าต่าง Windows, Windows ข้อความสุดท้ายที่ส่งไปยังหน้าต่างเป็นWM_NCDESTROY ตัวจัดการCWndเริ่มต้นสำหรับข้อความ (CWnd::OnNcDestroy) จะแยกHWNDจาก c ++วัตถุและเรียกเสมือนฟังก์ชันPostNcDestroy บางชั้นแทนที่ฟังก์ชันนี้เพื่อลบวัตถุ c ++?
เริ่มต้นใช้งานการCWnd::PostNcDestroyไม่ทำสิ่งใด ๆ ที่เหมาะสมสำหรับหน้าต่างวัตถุบนเฟรมกองการปันส่วน หรือฝังตัวอยู่ในวัตถุอื่น ๆ นี้ไม่เหมาะสมสำหรับวัตถุในหน้าต่างที่ถูกออกแบบมาเพื่อการปันส่วน ด้วยตัวมันเองบนกอง (ไม่ฝังตัวในวัตถุอื่น c ++)?
เรียนเหล่านั้นที่ถูกออกแบบมาเพื่อการปันส่วน ด้วยตัวมันเองบนกอง แทนฟังก์ชันสมาชิกPostNcDestroyทำการ "ลบนี้" คำชี้แจงนี้จะฟรีหน่วยความจำ c ++ใด ๆ เกี่ยวข้องกับวัตถุ c ++ แม้ว่า destructor CWndเริ่มต้นการเรียกDestroyWindowถ้าm_hWndไม่ใช่ NULL นี้ไม่ได้นำไปสอบถามซ้ำอนันต์เนื่องจากหมายเลขอ้างอิงจะแยก และค่า NULL ในระหว่างขั้นตอนการล้างข้อมูล?
หมายเหตุnbspCWnd::PostNcDestroyโดยปกติเรียกว่าหลังจาก Windows WM_NCDESTROYข้อความมีการประมวล ผล เป็นส่วนหนึ่งของหน้าต่างทำลาย และไม่แนบHWNDและ c ++หน้าต่างวัตถุ CWnd::PostNcDestroyจะยังถูกเรียกในการใช้งานส่วนใหญ่สร้างสายหากเกิดความล้มเหลวเกิดขึ้น (ดูด้านล่างสำหรับกฎการล้างข้อมูลโดยอัตโนมัติ)(&N)?
เรียนการล้างข้อมูลโดยอัตโนมัติ
คลาสที่ดังต่อไปนี้ไม่ได้ถูกออกแบบมาสำหรับ auto-ล้าง โดยปกติแล้วฝัง ในวัตถุอื่น c ++ หรือกองซ้อน:
การเรียนต่อไปนี้ถูกออกแบบมาสำหรับล้างข้อมูลโดยอัตโนมัติ พวกเขามักถูกปันส่วน ด้วยตัวมันเองบนกอง:
ถ้าคุณต้องการแบ่งให้กฎเหล่านี้ คุณต้องแทนฟังก์ชันสมาชิกPostNcDestroyในชั้นเรียนของคุณได้รับ การเพิ่มอัตโนมัติล้างข้อมูลของคลาส เพียงโทรคลาสพื้นฐานของคุณ และทำการลบนี้ การเอาออกอัตโนมัติล้างจากของคลาส โทรCWnd::PostNcDestroyแทนโดยตรงของสมาชิกPostNcDestroyในคลาสพื้นฐานของคุณโดยตรง?
การใช้งานทั่วไปด้านบนเป็นการ สร้างกล่องโต้ตอบสร้างที่สามารถปันส่วนบนกอง?
เมื่อการเรียก 'ลบ'
วิธีแนะนำไปทำลายวัตถุ Windows จะเรียกDestroyWindow, c ++สมาชิกฟังก์ชันหรือโลก:: DestroyWindow API?
ไม่เรียกโลก:: DestroyWindow API ทำลายหน้าต่างมีลูก MDI ใช้ฟังก์ชันเสมือนสมาชิกCWnd::DestroyWindowแทน?
สำหรับหน้าต่าง c ++วัตถุที่ไม่ดำเนินการล้างข้อมูลบนอัตโนมัติ การใช้DestroyWindowแทนที่จะลบเลี่ยงปัญหาจะต้องเรียกDestroyWindowในการCWnd:: ~ CWnd destructor ที่ VTBL ที่ไม่ได้วิ่งไปเรียนได้รับมาอย่างถูกต้อง นี้สามารถนำไปบักสีสันเพื่อวินิจฉัย (ตรวจแก้จุดบกพร่อง) รุ่นของ MFC จะแจ้งเตือนคุณด้วย
คำเตือน: การเรียก DestroyWindow ใน CWnd:: ~ CWnd
nbsp OnDestroy หรือ PostNcDestroy ในชั้นเรียนที่ได้รับจะไม่ถูกเรียก(&N)
ในกรณีของวัตถุ Windows c ++ที่ดำเนินการโดยอัตโนมัติล้าง คุณต้องเรียกDestroyWindow ถ้าคุณใช้ตัวดำเนินลบโดยตรง การจัดสรรหน่วยความจำที่วินิจฉัย MFC จะแจ้งเตือนคุณว่า คุณกำลังเพิ่มหน่วยความจำสองครั้ง (สายแรกลบ) รวมทั้งการเรียกทางอ้อมการ "ลบนี้" ในการใช้งาน auto-ล้างข้อมูลของPostNcDestroy?
หลังจากโทรDestroyWindowบนวัตถุไม่ใช่-auto-ล้าง วัตถุ c ++จะยังคงมีรอบ แต่m_hWndจะเป็น NULL หลังจากโทรDestroyWindowบนวัตถุอัตโนมัติล้าง วัตถุ c ++จะหมดไป รอด ด้วยตัวดำเนินการลบ c ++ในการใช้งาน auto-ล้างข้อมูลของPostNcDestroy..
หมายเหตุด้านเทคนิคตามหมายเลข|nbsp หมายเหตุด้านเทคนิคตามประเภท(&N)