說起來挺簡單的,一個對話框關閉時要依次調用該類的DestroyWindow-OnDestroy-PostNcDestroy,根據關閉的方法不同,在這些函數之前會調用OnOK、OnCancle或者OnClose。
這里要說的是,模態對話框的消息循環要到調用了PostNcDestroy之后才真正的結束,即ContinueModal循環在這里才結束,然后類的析構函數將被調用,這個對話框才真正的被銷毀了。
如果一個模態對話框還有一個模態的子對話框,那就更要注意了。如果子對話框還在顯示的時候,父對話框由於某種原因關閉了(如從其他線程接收到了WM_CLOSE消息),父對話框在執行完OnClose函數后會等到,直到子對話框銷毀了,才會繼續執行自己的如第一段所說的關閉過程。
今天遇到的問題就是父對話框中保存子對話框的指針,為了讓主對話框在關閉的時候先關閉所有的子窗口,在父對話框的OnClose里調用了delete pDlgChld,結果程序直接崩潰。后來改成先給子對話框發一個WM_CLOSE消息再delete,還是崩潰,又試了發WM_DESTROY、調子對話框的DestroyWindows,都不行。 看了上面的說明這里應該很清楚了,程序處理完這些消息后子對話框還在繼續它的ModalLoop,這時候要delete對象肯定就會導致崩潰了。
解決辦法其實很簡單,把對子對話框指針的delete移到OnClose之后的任意一個函數中,這樣就不會導致崩潰。因為父對話框在執行完OnClose后會等待直到它的子對話框結束,執行到OnClose之后的函數里時子對話框的生命期已經結束了,這時刪除指針就不會有任何問題。
其實我們最好不要改變MFC對這套機制的處理,這樣對資源的管理也是最合理的。