创建非模式窗体

我们从下列代码着手,讨论一下创建非模式窗体时应该注意的问题:

// 创建非模式窗体代码,可以在主菜单的Click事件中

CDepartmentDlg* dpt = new CDepartmentDlg(this);
dpt->Create(IDD_DIALOG_DEPARTMENT,this);
dpt->ShowWindow(SW_SHOW);

 

// CDepartmentDlg窗体确认按钮的代码
void CDepartmentDlg::OnBnClickedOk()
{
 // TODO: 在此添加控件通知处理程序代码
 OnOK();
}

 

习惯于C#或者VB等编码的程序员,对于上述代码来说,可能并没有感觉到有什么不对,那么请你在CDepartmentDlg类中增加Destory消息处理函数,如下:

void CDepartmentDlg::OnDestroy()
{
 CDialog::OnDestroy();
}

然后在CDialog::OnDestroy();语句处增加断点,然后运行应用程序,通过菜单打开CDepartmentDlg窗体,然后关闭该窗体,你会发现系统并没有触发Destroy事件。然后你试着关闭应用程序,此时,系统会调用OnDestroy事件处理函数。就此,可以得出一个结论,当一个窗体关闭的时候,系统是不会主动销毁该对象的,需要等到应用程序关闭的时候。这样,就会产生内存泄露。

 

为了解决这个问题,有两种方式处理:

1、在关闭窗体的代码中调用DestroyWindow函数,然后在Destroy消息处理函数中加入销毁当前对象的代码。

2、在关闭窗体的代码中发出Destroy当前窗体的消息,由主窗体销毁该窗体对象。

 

下面我们针对这两种方法做一个介绍:

方法一

// CDepartmentDlg窗体确认按钮的代码
void CDepartmentDlg::OnBnClickedOk()
{
 // TODO: 在此添加控件通知处理程序代码
 OnOK();

 DestroyWindow();
}

 

void CDepartmentDlg::OnDestroy()
{
 CDialog::OnDestroy();

 delete this;   // 销毁当前对象
}

 

方法二

// 在CDepartmentDlg.h中增加如下两个定义

#define WM_DELETE_DLG (WM_USER+1)

 

private:
 CWnd* m_pParent;

 

// 将CDepartmentDlg的构造函数改为:

CDepartmentDlg(CWnd* pParent = NULL);

 

// 在将CDepartmentDlg的构造函数实现中增加下面的代码:

m_pParent = pParent;

 

// CDepartmentDlg窗体确认按钮的代码
void CDepartmentDlg::OnBnClickedOk()
{
 // TODO: 在此添加控件通知处理程序代码
 OnOK();

 DestroyWindow();
}

 

void CDepartmentDlg::OnDestroy()
{
 CDialog::OnDestroy();

 m_pParent->PostMessage(WM_DELETE_DLG,(WPARAM)this,0);   // 发出销毁当前对象的消息

}

 

// 在MainFrame.h中增加如下WM_DELETE_DLG消息处理函数的定义:

afx_msg LONG OnDeleteDialog(WPARAM wP,LPARAM lP);

 

// 在MainFrame.cpp中增加如下建立消息处理映射代码:

ON_MESSAGE(WM_DELETE_DLG,OnDeleteDialog);

 

// MainFrame类的WM_DELETE_DLG消息处理函数

LONG CMainFrame::OnDeleteDialog(WPARAM wp,LPARAM lp)
{
    delete (CDialog*)wp;    // 销毁对象

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值