如何检测无模型CDialog是否已被关闭?

问题描述 投票:4回答:4

我按照这个问题做了一个无模版的对话框,请问如何检测无模版的CDialog是否已经关闭?如何显示一个无模式的CDialog?

我在VS2008中使用MFCC++。比起MFC和C++,我对C#和.net更精通。

我在我的窗体中有一个启动对话框的菜单项。对话框只能有一个实例被打开。对话框显示良好。我可以通过点击角落里的X来关闭它,当我关闭主窗体时,它就会关闭。我遇到的问题是,在我点击X关闭对话框后,对话框无法再次打开。我知道这是因为指针从来没有设置回NULL。

我在我的表单的头文件里有这个部分。

CChildDialog *m_pDialog;

我在表单的构造函数里有这部分。

m_pDialog = NULL;

当点击一个菜单项时,我在菜单项的方法中有这段代码(我从另一个SO答案中修改了它,因为我只想打开一个对话框的实例)。

if(m_pDialog == NULL)
{
    // Invoking the Dialog
    m_pDialog = new CChildDialog();
    BOOL ret = m_pDialog->Create(IDD_CHILDDIALOG, this);

    if (!ret)   //Create failed.
    {
        AfxMessageBox(_T("Error creating Dialog"));
    }    

    m_pDialog->ShowWindow(SW_SHOW);
}

现在我知道我需要执行这部分并将指针设置为NULL,但我不知道该把它放在哪里。

// Delete the dialog once done
delete m_pDialog;
m_pDialog = NULL;

我需要继续监视对话框是否被处理了吗?对话框关闭时,是否有事件触发到父窗体?

c++ visual-studio-2008 mfc dialog
4个回答
4
投票

如果你想在用X关闭窗口后回收窗口的内容,你必须在你的对话框中处理WM_CLOSE消息。

void CChildDialog::OnClose()
{
    ShowWindow(SW_HIDE);
}

然后在打开窗口的代码中处理

if(m_pDialog == NULL)
{
    // Invoking the Dialog
    m_pDialog = new CChildDialog();
    BOOL ret = m_pDialog->Create(IDD_CHILDDIALOG, this);

    if (!ret)   //Create failed.
    {
        AfxMessageBox(_T("Error creating Dialog"));
    }    
}

m_pDialog->ShowWindow(SW_SHOW); //moved outside the if(m_pDialog == NULL)

希望能帮到你


3
投票

如果你想删除无模型对话框,那就直接删除。

如果你想在用户关闭无模型对话框时删除该对话框的对象,你可以看一下 WM_PARENTNOTIFY. 如果一个子窗口被破坏,而该子窗口没有扩展的窗口样式。WS_EX_NOPARENTNOTIFY 设置,那么windows就会发送一个 WM_PARENTNOTIFYwParam=WM_DESTROY 到父窗口。你应该在父窗口中实现一个该消息的处理程序,并检查是否是无模型对话框被破坏。


1
投票

我已经起草好了这个问题,并准备把它发布出来,但后来我有了一个想法,最后解决了自己的问题。所以对于其他有问题的人来说,如果检测到无模型对话框的关闭,我是这样做的。

void Form1::MenuItemMethod()
{
    if(m_pDialog == NULL)
    {
        // Invoking the Dialog
        m_pDialog = new CChildDialog();
        BOOL ret = m_pDialog->Create(IDD_CHILDDIALOG, this);

        if (!ret)   //Create failed.
        {
            AfxMessageBox(_T("Error creating Dialog"));
        }    

        m_pDialog->ShowWindow(SW_SHOW);
    }
    else
    {
        // cannot check if visible at the beginning of method because
        // pointer could be NULL and will throw an exception

        if(m_pDialog->IsWindowVisible())
        {
            return;
        }

        m_pDialog->DestroyWindow();
        m_pDialog = NULL;
        MenuItemMethod();
    }
}

我只是在再次点击窗体的菜单项后,检查无模型对话框是否可见。如果可见,就不要做任何事情。如果不可见,则销毁现有的不可见对话框,将指针设置为NULL,然后再次递归调用该方法。由于指针现在是NULL,所以应该会正常地重新创建对话框,然后返回正常操作。


0
投票

你必须删除内存中的 PostNcDestroy 这样

void CChildDialog ::PostNcDestroy() 
{   
    CDialog::PostNcDestroy();
    GetParent()->PostMessage(WM_WIN_CLOSED,0,0);
    delete this;
}

并向父窗口发送一个用户定义的消息,说明您的窗口已经关闭。在父窗口中添加一个消息处理程序,用于处理 WM_WIN_CLOSED 喜欢

LRESULT CMainDialog::OnMyMethod(WPARAM wParam, LPARAM lParam)
{
    m_pDialog = NULL; 
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.