现在的位置: 首页 > 综合 > 正文

非模态对话框的释放

2013年01月05日 ⁄ 综合 ⁄ 共 1949字 ⁄ 字号 评论关闭

原创作者已经找不到了。。。

非模态对话框相对模态对话框的创建和释放都相对繁琐点。研究一下非模态对话框的释放问题:

From MSDN:

Modal dialog boxes are normally created on the stack frame and destroyed when the function that created them ends. The dialog object’s destructor is called when the object goes out of scope.

Modeless dialog boxes are normally created and owned by a parent view or frame window — the application’s main frame window or a document frame window. The default  OnClose handler
calls DestroyWindow,  which destroys the dialog-box window. If the dialog box stands alone, with no pointers to it or other special ownership
semantics, you should override PostNcDestroy to destroy the C++ dialog object. You should also override OnCancel and
call DestroyWindow from within it. If not, Don’t call the base class CDialog::OnCancel, because it calls EndDialog, which will make the dialog box invisible but will not destroy it.

You should override PostNcDestroy for modeless dialog boxes in order to delete this, since modeless dialog boxes are usually allocated with new. Modal dialog boxes are usually constructed on the frame and do not need PostNcDestroy cleanup.

挖掘E文:

1、非模态对话框是在堆中产生,必须要释放;模态对话框在栈中,过了作用域会自动释放

2、此时用IDOK,IDCANCEL关闭窗体时,应对OnOK,OnCancel重写,CDialog::OnOK();CDialog::OnCancel();应被替换为CDialog::DestroyWindow()。因为前者是会条用CDialog::EndDialog, 其是为模态对话框而设计,非模态调用它只能隐藏窗体而不会释放。

     void CTestDlg::OnOK() 
    {
     / / TODO: Add extra validation here 
     CDialog::DestroyWindow();             // Here!
    }

3、如果对话框为游离状态(指父窗体或其他窗体没有掌控指向该对话框的指针),就需要重载PostNcDestroy

     void CTestDlg::PostNcDestroy() 
     {
          CDialog::PostNcDestroy();            //据说此函数在基类什么都没做
          delete this;                                        //在此释放窗体内存块                                          
      }

    当然父窗体有该模态对话框的指针CDlg*  pDlg,在适当的时候delete pDlg即可

4、上面的E为提到:OnClose 默认会调用 DestroyWindow,追踪了一下,没调呀!通过右上角的X按钮关闭对话框时不就内存泄露了。只好自己调了。

    void CTestDlg::OnClose() 
    {    CDialog::OnClose();
         DestroyWindow();
    }

总之:先DestroyWindow, 然后delete

<后面引用.....>
用PostNCDestory将windows内核对象销毁,调用delete把对话框的c++对象销毁。       
第一步后,该对象的m_hWnd句柄成员应该置为0.      
对于一个mfc的对话框对象,它实际上分为两部分,一部分是系统内核对象,用句柄标识,一部分是用于包装这个句柄的c++对

抱歉!评论已关闭.