上次提了这个问题,我描述的不清楚,重新描述一下:
我有一个基于对话框的程序,程序起来后点击一个按钮创建一个无模式对话框A
{
    m_pDlgModeless = new CModelessDlg();
    m_pDlgModeless->Create(IDD_MODALESS, this);
    m_pDlgModeless->ShowWindow(SW_SHOW);    SetTimer(1, 30000, NULL);
}30秒后销毁该对话框
{
    if (m_pDlgModeless != NULL && IsWindow(m_pDlgModeless->m_hWnd))
    {
        m_pDlgModeless->DestroyWindow();
        m_pDlgModeless = NULL;
    }
}A上有一个按钮,点击后弹出一个模态对话框B。所以有可能B存在时A被销毁了。
我通过把B对象做成A的成员变量,并重载A的DestroyWindow()函数,在DestroyWindow中这样销毁B窗口
{
    if(::IsWindow(m_modalDlg.m_hWnd))
        m_modalDlg.EndDialog(IDCANCEL);
}
可是这样也不行。这中情况该如何处理?

解决方案 »

  1.   

    将模态对话框B的设置设置成非模态对话框A的子窗口试试设置
    b为a的子窗口
      

  2.   

       对于父对话框,如果子模态对话框不关闭,父模态对话框无法执行操作,
    所以不能DestroyWindow(),自然也就不能执行你重载后的操作了。
    所以应该先结束子对话框,再调用父对话框的DestroyWindow()//如下
    30秒后销毁该对话框 

        if (m_pDlgModeless != NULL && IsWindow(m_pDlgModeless->m_hWnd)) 
        {
            if(HWND hwnd=::FindWindow( ,"B对话框title")) //利用findwindow
            {
              sendmessage(hwnd,WM_CLOSE, , );//利用消息函数
            } 
            m_pdlgmodeless->destroy();
        } 
    }也可以把m_modeDlg声明为全局的。然后直接调用destroywindow(); 
      

  3.   

    把这段
    if(::IsWindow(m_modalDlg.m_hWnd)) 
            m_modalDlg.EndDialog(IDCANCEL); 
    换成
    if (m_modalDlg!= NULL && IsWindow(m_modalDlg->m_hWnd)) 

        m_modalDlg->DestroyWindow(); 
        m_modalDlg= NULL; 
    }把m_modalDlg.DoModal();换成
    m_modalDlg= new CModalDlg();
    m_modalDlg->Create(IDD_DIALOG1, this); 
    m_modalDlg->ShowWindow(SW_SHOW);
    EnableWindow(false);
    GetParent()->EnableWindow(false);
    m_modalDlg->EnableWindow(true);在我这,代码是测试通过的,可以的,你试试看
      

  4.   

    少了一句,OnTimer里面应该再加上一句
    if (m_modalDlg!= NULL && IsWindow(m_modalDlg->m_hWnd)) 

        m_modalDlg->DestroyWindow(); 
        m_modalDlg= NULL; 
        EnableWindow(true);
    }
      

  5.   

    设置成A的子窗口不行。
    B窗口该成非模态的是可以,但是我程序里B只能是模态的。
    如果我在A上弹出一个MessageBox就没有问题,我想要的就是类似这样的窗口。
      

  6.   

    B窗口该成非模态的是可以,但是我程序里B只能是模态的。
    ----------------------------------
    m_modalDlg= new CModalDlg();
    m_modalDlg->Create(IDD_DIALOG1, this); 
    m_modalDlg->ShowWindow(SW_SHOW);
    EnableWindow(false);
    GetParent()->EnableWindow(false);
    m_modalDlg->EnableWindow(true);
    这段代码就是产生模态的B窗口阿vc的DoModal的实现代码就是这样的,因此这产生的对话框和DoModal产生的一样
    你试试看吧
      

  7.   

    EnableWindow(false);
    GetParent()->EnableWindow(false);
    m_modalDlg->EnableWindow(true);这三句是实现模态的关键代码
      

  8.   

    LZ的代码看起来没什么问题,只是没有KillTimer。具体怎么不行?
      

  9.   

    回10楼,你可以试一下,当A被关闭时,出现一个
    First-chance exception in PopupWindow.exe (MFC42D.DLL): 0xC0000005: Access Violation.
    程序停在
    if (!ContinueModal())
        goto ExitModal;
      

  10.   

    其一:time 要及时kill,因此应该有一个timer id 的变量
    其二:m_modalDlg不一定非的每次重新创建,因为一个普通的dlg占不了太多的内存,当然如果考虑gdi资源是另外一回事
    m_modalDlg.ShowWindow(SW_HIDE);
    delete m_modalDlg;
    m_modalDlg = NULL;
      

  11.   

    给你一个建议,
    非模态对话框A,如果需要在运行一段时间自动退出的话,建议由A自己实现,而不是由调用者实现。
    譬如你可以在A::OnInitDialog时SetTimer,然后在OnTimer中DestoryWindow.而不是由A的ParentWindow来SetTimer.
      

  12.   

    回12楼,对比了一下你的代码,我知道问题在哪了。我的代码会出错是因为在非模态对话框销毁时,在PostNcDestroy中调用了delete this.如果不删除这个new出来的非模态对话框又会有内存泄漏,我试过在其他地方delete 它也不行。
      

  13.   

    原因是B是A类中的成员,在delete A的时候,B也被delete了,如果把B定义为指针变量就没问题了。