MFC,EndDialog,重复创建对话框会导致意外行为

时间:2013-01-18 01:35:03

标签: c++ windows winapi mfc dialog

我需要根据其大小动态调整对话框窗口。为此,我采用了以下技术:

  1. 我加载它并从CDialog :: OnInitDialog()处理程序获取它的大小。

  2. 如果尺寸太大,我通过调用CDialog :: EndDialog来结束对话

  3. 然后更新全局变量并使用大小调整再次重新启动对话框派生类。

  4. 在第二次传递中会发生一些API开始奇怪的行为。例如,MessageBox没有显示(因此所有ASSERT宏都停止工作),并且一些SetWindowText API使应用程序崩溃。知道为什么吗?

    以下是代码片段:

    #define SPECIAL_VALUE -1
    //From CWinApp-derived class
    BOOL CWinAppDerivedClass::InitInstance()
    {
        //...
    
        for(;;)
        {
            CDialogDerivedClass dlg(&nGlobalCounter);
            m_pMainWnd = &dlg;
            if(dlg.DoModal() != SPECIAL_VALUE)
                break;
        }
    
        //...
    }
    

    然后从对话框类本身开始:

    //From CDialogDerivedClass
    BOOL CDialogDerivedClass::OnInitDialog()
    {
        //The following API shows message box only on the 1st pass, why?
        ::MessageBox(NULL, L"1", L"2", MB_OK);
    
        //...
    
        if(checkedDialogSizeIndicatesReload)
        {
            this->EndDialog(SPECIAL_VALUE);
            return FALSE;
        }
    
        //Continue loading dialog as usual
        ...
    }
    

    编辑:我偶然发现,如果我注释掉下面一行,它似乎有效。知道为什么吗?

    //m_pMainWnd = &dlg;
    

2 个答案:

答案 0 :(得分:1)

InitDialog是屏幕上出现对话窗口之前处理的最后一条消息 - 您可以检测并调整大小,而不是那种时髦的全局变量。

if(checkedDialogSizeIndicatesReload)
    {
    // look up SetWindowPos - 
    // I am nt sure if there is another parameter or not that is optional
    int x,y,cx,cy;
    WINDOWPLACEMENT wp;
    GetWindowPlacement(&wp);
    // calc new size here
    SetWindowPos(this,x,y,cx,cy);
    }

// window appears when the message handler returns

答案 1 :(得分:1)

变量dlg还不是您设置m_pMainWnd的地方的窗口(仅在OnInitInstance返回TRUE后才会显示该对话框);以下代码应该有效:

for(;;)
{
    CDialogDerivedClass dlg(&nGlobalCounter);
//  m_pMainWnd = &dlg;
    if(dlg.DoModal() != SPECIAL_VALUE)
        break;
}
m_pMainWnd = &dlg;