首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何“正确关闭MFC无模式对话框并修复资源泄漏”

如何“正确关闭MFC无模式对话框并修复资源泄漏”
EN

Stack Overflow用户
提问于 2019-06-07 05:27:34
回答 1查看 2.2K关注 0票数 0

我创建了一个MFC应用程序,它包含一个Base Dialog (来自CDialog类)、一个Setting Dialog (来自CBaseDlgApp Dialog (也来自CBaseDlg) )。然后,我创建了一个名为CScrMng (也称为屏幕管理器)的类,它包含ShowDialog()函数(用于CreateShow这些对话框)。

基本思想是ScrMng将管理我所有的无模型对话框,每当我想打开一个对话框时,我只需要在BaseDlg.cpp中使用CScrMng::ShowDialog(),对话框就会显示出来。

这种方法导致资源到处泄漏。我已经做了一些关于覆盖PostNcDestroy()的研究,但是我不清楚该在哪里调用它。

我应该使用什么功能来正确地关闭这些非模式对话框?

我想从Setting Dialog中打开Base Dialog,然后当我点击Cancel按钮时,它应该将我返回到Base Dialog屏幕,这样我就可以打开另一个对话框了。

现在我正在使用EndDialog()。我知道这是错误的,但打电话给DestroyWindow()会立即退出程序,这不是我想要的。

源代码

MFCApplication.cpp

代码语言:javascript
运行
复制
#include...

BEGIN_MESSAGE_MAP(CMFCApp, CWinApp)
    ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()

CMFCApp::CMFCApp()
{
     // support Restart Manager
     m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
}

CMFCApp theApp;

BOOL CMFCApp::InitInstance()
{
    ...
    CWinApp::InitInstance();

    CShellManager *pShellManager = new CShellManager;

    CScrMng::GetInstance()->ShowDialog(IDD_MAINDLG);

    SetRegistryKey(_T("Local Applications"));

    if (pShellManager != NULL)
    {
        delete pShellManager;
    }
    return TRUE;
}

CScrMng.cpp

代码语言:javascript
运行
复制
#include...

CScrMng* CScrMng::m_pInstance = NULL;
CScrMng* CScrMng::GetInstance(){
     if (m_pInstance == NULL)
    m_pInstance = new CScrMng();
    return m_pInstance;
}

CScrMng::CScrMng(){}

void CScrMng::ShowDialog(int ID)
{
    CMainDlg* m_pDlg = NULL;
    switch (ID)
    {
    case IDD_MAINDLG:
        m_pDlg = new CMainDlg();
        theApp.m_pMainWnd = m_pDlg;
        m_pDlg->Create(IDD_MAINDLG);
        m_pDlg->ShowWindow(SW_SHOW);
        m_pDlg->UpdateWindow();
        break;

    case ...
        break;

    case IDD_SETTINGDLG:
        m_pDlg = new CSettingDlg();
        m_pDlg->Create(ID,NULL);
        m_pDlg->ShowWindow(SW_SHOW);
        m_pDlg->UpdateWindow();
        break;
    }

CMainDlg.cpp

代码语言:javascript
运行
复制
#include...

CMainDlg::CMainDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CMainDlg::IDD, pParent) {m_hIcon = AfxGetApp()-> LoadIcon(IDR_MAINFRAME);}

void CMainDlg::DoDataExchange(CDataExchange* pDX) {...}

void CMainDlg::PostNcDestroy() //Added these
{
    CDialog::PostNcDestroy();
    delete this;
}

BEGIN_MESSAGE_MAP(CMainDlg, CDialog)
...
END_MESSAGE_MAP()

BOOL CMainDlg::OnInitDialog() {
    CDialog::OnInitDialog();
    SetIcon(m_hIcon, FALSE);        
    return TRUE; 
}

void CMainDlg::OnPaint() {...}

void CMainDlg::OnBnClickedOpenAppdlg()
{
    CScrMng::GetInstance()->ShowDialog(IDD_APPDLG);
}

void CMainDlg::OnBnClickedOpenSettingdlg()
{
    CScrMng::GetInstance()->ShowDialog(IDD_SETTINGDLG);
}

void CMainDlg::OnBnClickedExit() 
{
     DestroyWindow(); //replaced CDialog::OnCancel() with this.
}

更新:在更改SettingDlg.cpp中的代码之后,我遇到了一个Debug Assertion Failed!问题:

代码语言:javascript
运行
复制
void CWnd::MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint)
{
    ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL)); //Breakpoint triggered

    if (m_pCtrlSite == NULL)
        ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint);
    else
        m_pCtrlSite->MoveWindow(x, y, nWidth, nHeight);
}

下面是我在.cpp文件中更改的内容: SettingDlg.cpp

代码语言:javascript
运行
复制
void CSettingDlg::PostNcDestroy()
{
    CMainDlg::PostNcDestroy();
}

void CSettingDlg::OnBnClickedSettingcancel()
{
    DestroyWindow(); //Using destroyWindow rather than EndDialog();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-07 13:09:11

关闭和删除一个非模式对话框。

正确的方法是:重写无模型对话框的PostNcDestroy、OnOk()和OnCancel()

代码语言:javascript
运行
复制
void CBaseDlg::PostNcDestroy()
{
    CDialog::PostNcDestroy();
    delete this;
}

代码语言:javascript
运行
复制
void CBaseDlg::OnOk()
{
   if(!UpdateData(TRUE))
       return;
    DestroyWindow();
}

代码语言:javascript
运行
复制
void CBaseDlg::OnCancel()
{
    DestroyWindow();
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56488430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档