非模態對話方塊的建立和銷燬過程
一個非模態的MFC 視窗的銷燬過程:
假設自己通過new建立了一個視窗物件pWnd,然後pWnd->Create。則銷燬視窗的呼叫次序:
1. 手工呼叫pWnd->DestroyWindow(); // 一般在對話方塊類中的OnCancle函式中postMessage(WM_DESTORY)或者直接呼叫
2. DestroyWindow會發送WM_DESTROY;
3. WM_DESTROY對應的訊息處理函式是OnDestroy();
4. DestroyWindow會發送WM_NCDESTROY;
5. WM_NCDESTROY
6. OnNcDestroy最後會呼叫PostNcDestroy;
7. PostNcDestroy經常被使用者過載以提供釋放記憶體操作。例如可以使用delete this;
通過這種方式,視窗物件對應的視窗和視窗物件本身都被釋放了。
對於非模態視窗,必須過載OnCancel函式,在函式中呼叫DestroyWindows()方法,且不能呼叫基類的函式。因為基類函式中呼叫的是EndDialog()方法。(因為EndDialog是關閉模態對話方塊時呼叫的)而OnClose()也會呼叫OnCancel()方法。另外想通過OnOK
所以對於非模態視窗,其關閉過程為:
OnClose()->OnCancel()->DestroyWindow()->OnDestroy()->OnNcDestroy()->PostNcDestroy()->僅表示時間先後而已
而OnNcDestroy()最後又呼叫了PostNcDestroy()
對於DoModal出來的視窗,可以使用預設的OnOk()和OnCancel()來處理。其基類方法中會呼叫EndDialog()方法。
最後注意一個問題,通常我們建立一個非模態視窗時,可能會這樣寫
{
CDialog * pWnd = new CMyDialog();
pWnd->Create(……);
pWnd->ShowWindow(SW_SHOW);
}
一般是在一個模組或者一個函式中建立視窗,但是卻無法知道什麼時候關閉視窗。而pWnd也只是作為一個區域性變數。那麼如何對它進行析構呢?
通常這樣是過載虛擬函式PostNcDestroy()來實現
void CMyDialog::PostNcDestroy()
{
CDialog::PostNcDestroy();
delete this;
}
為什麼把對話方塊類的delete this放在PostNcDestroy中而不是OnNcDestroy?
這是因為OnNcDestroy只被已建立的視窗呼叫。如果建立視窗失敗(如PreCreateWindow),則沒有窗口出來發送