(搬运)mfc非模态对话框关闭避免内存泄露

以下是一段在CView类里调用非模态对话框的实例

void CYourView::OnOpenDlg(void)

{

/*假设IDD_TEST_DLG为已经定义的对话框资源的ID号*/

CTestDlg *dlg=new CTestDlg;

dlg->Create(IDD_TEST_DLG,NULL);

dlg->ShowWindow(SW_SHOW);

/*不要调用 delete dlg;*/

}

在上面的代码中我们新生成了一个对话框对象,而且在退出函数时并没有销毁该对象。因为如果此时销毁该对象(对象被销毁时窗口同时被销毁),而此时对话框还在显示就会出现错误。那么这就提出了一个问题:什么时候销毁该对象。我时常使用的方法有两个:

在对话框退出时销毁自己:在对话框中重载OnOK与OnCancel在函数中调用父类的同名函数,然后调用DestroyWindow()强制销毁窗口,在对话框中映射WM_DESTROY消息,在消息处理函数中调用delete this;强行删除自身对象。相关代码如下:

void CTestDlg1::OnOK()

{

CDialog::OnOK();

DestroyWindow();

}

void CTestDlg1::OnCancel()

{

CDialog::OnCancel();

DestroyWindow();

}

void CTestDlg1::OnDestroy()

{

CDialog::OnDestroy();

AfxMessageBox("call delete this");

delete this;

}

这种方法的要点是在窗口被销毁的时候,删除自身对象。所以你可以在任何时候调用DestroyWindow()以达到彻底销毁自身对象的作用。(DestroyWindow()的调用会引起OnDestroy()的调用)

通过向父亲窗口发送消息,要求其他窗口对其进行销毁:首先需要定义一个消息用于进行通知,然后在对话框中映射WM_DESTROY消息,在消息处理函数中调用消息发送函数通知其他窗口。在接收消息的窗口中利用ON_MESSAGE映射处理消息的函数,并在消息处理函数中删除对话框对象。相关代码如下:

/*更改对话框的有关文件*/

CTestDlg2::CTestDlg2(CWnd* pParent /*=NULL*/)

: CDialog(CTestDlg2::IDD, pParent)

{/*m_pParent为一成员变量,用于保存通知窗口的指针,所以该指针不能是一个临时指针*/

ASSERT(pParent);

m_pParent=pParent;

//{{AFX_DATA_INIT(CTestDlg2)

// NOTE: the ClassWizard will add member initialization here

//}}AFX_DATA_INIT

}

void CTestDlg2::OnOK()

{

CDialog::OnOK();

DestroyWindow();

}

void CTestDlg2::OnCancel()

{

CDialog::OnCancel();

DestroyWindow();

}

void CTestDlg2::OnDestroy()

{

CDialog::OnDestroy();

/*向其他窗口发送消息,将自身指针作为一个参数发送*/

m_pParent->PostMessage(WM_DELETE_DLG,(WPARAM)this);

}

/*在消息接收窗口中添加消息映射*/

/*在头文件中添加函数定义*/

afx_msg LONG OnDelDlgMsg(WPARAM wP,LPARAM lP);

/*添加消息映射代码*/

ON_MESSAGE(WM_DELETE_DLG,OnDelDlgMsg)

END_MESSAGE_MAP()

/*实现消息处理函数*/

LONG CMy53_s1View::OnDelDlgMsg(WPARAM wP,LPARAM lP)

{

delete (CTestDlg2*)wP;

return 0;

}

/*创建对话框*/

void CMy53_s1View::OnTest2()

{

CTestDlg2 *dlg=new CTestDlg2(this);

dlg->Create(IDD_TEST_DLG_2);

dlg->ShowWindow(SW_SHOW);

}

在这种方法中我们利用消息来进行通知,在Window系统中利用消息进行通知和传递数据的用法是很多的。

同样无模式对话框的另一个作用还可以用来在用户在对话框中的输入改变时可以及时的反映到其他窗口。下面的代码演示了在对话框中输入一段文字,然后将其更新到视图的显示区域中,这同样也是利用了消息进行通知和数据传递。

/*在对话框中取出数据,并向其他窗口发送消息和数据,将数据指针作为一个参数发送*/

void CTestDlg2::OnCommBtn()

{

char szOut[30];

GetDlgItemText(IDC_OUT,szOut,30);

m_pParent->SendMessage(WM_DLG_NOTIFY,(WPARAM)szOut);

}

/*在消息接收窗口中*/

/*映射消息处理函数*/

ON_MESSAGE(WM_DLG_NOTIFY,OnDlgNotifyMsg)

/*在视图中绘制出字符串 m_szOut*/

void CMy53_s1View::OnDraw(CDC* pDC)

{

CMy53_s1Doc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

pDC->TextOut(0,0,"Display String");

pDC->TextOut(0,20,m_szOut);

}

/*处理通知消息,保存信息并更新显示*/

LONG CMy53_s1View::OnDlgNotifyMsg(WPARAM wP,LPARAM lP)

{

m_szOut=(char*)wP;

Invalidate();

return 0;

}

此外这种用法利用消息传递数据的方法对有模式对话框和其他的窗口间通信也一样有效

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值