2011年3月16日 星期三

知識更新 MFC Modeless Dialog 生成與結束

Windows的dialog有二種模式,model與modeless。所謂的model模式指的是當dialog產生時,該應用程式的訊息會被鎖住,直到dialog結束。而modeless dialog則較像是程式中的floating panel一樣可和應用程式一同運作,能做出較複雜的功能。

如果要產生一個modeless dialog

我所會的舊知識(這是MS VC 1.5時代學到的)

1. 建立一個新的CModeless::Create(CWnd* pParent)函式。
2. 呼叫端中必需記錄該dialog object。
3. 呼叫端必需有closedialog函式。
4. 要產生modeless dialog時必需透過new、Create、與ShowWindow三個步驟。
5. 當對話盒要關閉時,需使用呼叫端的closedialog函式而非自行解構。
6. 當程式要結束時,必需檢查dialog object是否已解構,否則必需呼叫closedialog函式以避免memory leakage的發生。

今天的新知識(可參考VC Sample : Modeless)

1. 建立一個新的CModeless::Create(CWnd* pParent)函式。
2. 呼叫端中不必有記錄該dialog object。
3. 呼叫端不必有closedialog函式。
4. 要產生modeless dialog時必需透過new與Create ShowWindow 個步驟。
5. 當對話盒要關閉時,透過WM_NCDESTROY訊息自行解構。
6. 當程式要結束時,必需檢查dialog object是否已解構,否則必需呼叫closedialog函式以避免memory leakage的發生。

以前在呼叫Create之後必需再呼叫ShowWindow(SW_SHOW)對話盒才可視,但可在resouce中將對話盒Visible屬性設為True即可在Create後直接出現,省去了呼叫ShowWindow的動作。

以前要在呼叫端記錄dialog object是為了在程式結束時能順利解構,但透過接收WM_NCDESTROY訊息可正確得知視窗需解構的時間點,是否要儲存dialog object就不再是必需。

VC的Modeless sample在收到WM_NCDESTROY後馬上就執行delete this,對自己進行解構。
void CModeless::OnNcDestroy()
{
    delete this;
}

但CDialog::OnNcDestroy會釋放dialog中的controller元件的資源,若未先呼叫可能會有memory leakage的疑慮。我加入了這段
void CModeless::OnNcDestroy()
{
    CDialog::OnNcDestroy();
    delete this;
}

沒有留言:

張貼留言