Цієї записці описується використання функції членів CWnd::PostNcDestroy . Ця функція використовується, якщо ви бажаєте налаштувати розподіл CWnd-отриманих об'єктів.
Ця Примітка також пояснює деякі з причин для кардинала правила:
Щоб знищити об'єкт Windows c + +, використовуйте DestroyWindow не "Видалити".
Це дуже важливо. Якщо ви будете дотримуватися принципів нижче, ви будете мати кілька очищення проблеми (наприклад, забувши видалити безкоштовні C++ пам'яті, забуваючи в системі вільного ресурси як HWNDs або звільнення об'єктів дуже багато разів).
Проблема
Windows об'єктів (об'єктів класів, отриманих від CWnd) представляють на C++ об'єкт (виділяються в програми купи) і в HWND (виділений у системних ресурсів віконний менеджер). Оскільки існує кілька способів, щоб знищити об'єкт вікна, ми повинні забезпечити набір правил, які запобігти системних ресурсів або витоку пам'яті застосування і що запобігти об'єктів і ручками Windows від більше ніж один раз.
Це більше, ніж проблеми управління пам'яттю. Наявність у вікні Windows має вплив інтерфейс користувача: вікно на екрані; Після того, як знищити є вплив на системні ресурси. Витік C++ пам'яті вашого застосування адресного простору це не так погано, як витік системних ресурсів.
Знищення 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++. Хоча за промовчанням CWnd деструктор закликає DestroyWindow , якщо m_hWnd не NULL, це не призведе до нескінченна рекурсія оскільки ручка буде окремо і NULL на етапі очищення.
Приміткаnbsp;CWnd::Post&NcDestroy , як правило, називається після Windows WM_NCDESTROY повідомлення буде оброблено, як частину знищення вікна, і HWND та C++ вікно об'єкт більше не підключено. CWnd::PostNcDestroy буде також називатися у здійсненні більшість дзвінків Створити разі виникнення проблеми (див. нижче для автоматичного очищення правила).
Автоматичне очищення класи
Наступні класи не призначені для автоматичного очищення. Вони зазвичай вбудовано в інший об'єкт C++ або у стеку:
Наступні класи призначені для автоматичного очищення. Вони зазвичай виділяється самі по собі в купі:
Якщо ви хочете, щоб порушити будь-який з цих правил, потрібно змінити PostNcDestroy функції члена в похідних класів. Додати ваш клас Авто очищення, просто зателефонуйте базового класу і потім зробити, це видалити. Щоб видалити автоматичного очищення з вашого класу, зателефонуйте CWnd::PostNcDestroy безпосередньо замість того, ваша пряма базового класу, член PostNcDestroy.
Найбільш поширене використання вище є створення немодальною діалогового вікна, які можуть бути виділені в купі.
Для виклику 'вилучити'
Рекомендований спосіб знищити об'єкт Windows, називати DestroyWindow, або функція-член C++ або глобальної :: DestroyWindow API.
Не назвав глобальної :: DestroyWindow API знищити з вікна MDI дитини, слід використовувати функцію віртуальний член CWnd::DestroyWindow.
Для C++ вікно об'єктів, які не виконувати автоматичного очищення, за допомогою DestroyWindow , замість того, щоб Видалити уникає проблем того, щоб викликати DestroyWindow на CWnd:: ~ CWnd деструктор, де в VTBL не вказують на правильно похідних класів. Це може призвести до тонких помилок, тому діагностики (debug) Версія MFC попередить вас з
Попередження: виклик DestroyWindow в CWnd:: ~ CWnd
nbsp; OnDestroy або Post&NcDestroy в похідних класів не можна назвати
У випадку з Windows c + + об'єктів, які виконують автоматичне очищення ви повинні викликати DestroyWindow. Якщо використовується оператор Видалити безпосередньо, MFC діагностики пам'яті розподільника попередить вас що є звільнення пам'яті два рази (перший дзвінок Видалити ), а також непрямий викликВидалити це"Авто очищення реалізації з PostNcDestroy.
Після того, як виклик DestroyWindow на об'єкт без автоматичного очищення, C++ об'єкт буде навколо, але m_hWnd буде NULL. Після виклику DestroyWindow для автоматичного очищення об'єкта, об'єкт C++ зникне, звільнений C++ видалити оператора у здійсненні Авто очищення PostNcDestroy..
Технічні примітки за номером |nbsp; Технічні примітки за категоріями