void MyDlg::OnDestroy() 
{
CDialog::OnDestroy();
delete this;
}Warning: calling DestroyWindow in CDialog::~CDialog --
OnDestroy or PostNcDestroy in derived class will not be called.
如果用下面的代码就没有警告:
void MyDlg::PostNcDestroy() 
{
  delete this;
}请各位讲讲其中的道理。

解决方案 »

  1.   

    你都CDialog::OnDestroy();还delete this, 从逻辑上说不通啊。
      

  2.   

    对于modeless对话框,delete this;放在析构函数里面最好
    MyDlg::~MyDlg() 
    {
      delete this;
    }
      

  3.   

    OnDestroy 的时候, destroywindow函数还没有调用, 你delete this, 就会调用基类cdialog的析构函数, 这个函数发现窗口没销毁, 就会调用destroywindow, 并给一个上面那样的警告, 说子类(MyDlg)中的PostNcDestroy不会被调用.PostNcDestroy是一个窗口类可能被调用的最后一个函数, 如果在PostNcDestroy中delete this, 这时窗口已经销毁. delete this调用基类cdialog的析构函数, 这个函数发现窗口已经销毁, 就不会调用destroywindow, 也就没有警告了.
      

  4.   

    这条警告是下面这个函数引起的:
    CDialog::~CDialog()
    {
    if (m_hWnd != NULL)
    {
    TRACE0("Warning: calling DestroyWindow in CDialog::~CDialog --\n");
    TRACE0("\tOnDestroy or PostNcDestroy in derived class will not be called.\n");
    DestroyWindow();
    }
    }
    他的意思是,如果对话框对象没有通过正常渠道结束,那么他的OnDestroy等函数将没有机会调用。
    比如 CMyDialog* pDlg = new CMyDialog;
     pDlg ->Create(***);
     pDlg ->ShowWindow(***);
     delete pDlg; 就可能引起上面情况的发生,因为析构函数将被调用,OnDestroy等将得不到清除资源的机会。
    那在哪里清楚堆上分配的资源,调用delete呢?一般是在CDialog::PostNcDestroy函数中:
    void MyDlg::PostNcDestroy() 
    {
      delete this;
    }
    这样,保证对话框自己清除在堆上new出来的资源,而不是我们在对话框外面清除,这样避免资源得不到回收。一般,引起对话框关闭的操作从点关闭按钮开始,WM_SYSCOMMAND -> WM_CLOSE -> WM_DESTROY -> WM_NCDESTROY ... 最后PostNcDestroy中delete this;
      

  5.   

    如果对话框不在堆上创建,则要去掉
    void MyDlg::PostNcDestroy() 
    {
      delete this;
    }
    否则会出现违规操作。比如在全局MyDlg dlg;对象。
      

  6.   

    你已经delete完了,必然已经调用了析构函数,完了接着调用destroywindow,你已经析构完了,便会出现警告信息!