实战经验:MFC非模态对话框的使用
在MFC编程中,我们经常会使用到模态对话框,模态对话框的一个典型特征是当对话框弹出后,其父窗口将不接受任何UI响应,直到关闭当前的模态对话框后才能继续。然而,非模态对话框就没有这个限制,今天我们就来讲讲如何在MFC中使用非模态对话框。
1) 在VS的资源管理器中新建一个对话框资源。
2) 为这个对话框新建对话框类,这里将对话框类命名为CTestDlg。
3) 对话框资源及对话框类创建好之后,需要在父窗口类中定义一个指向对话框对象的指针。例如,我们的对话框类名为CTestDlg,那么我们就需要在父窗口类中定义一个CTestDlg指针。
#include "CTestDlg.h" private: CTestDlg * m_pTestDlg;
4) 在父窗口类的构造函数中初始化m_pTestDlg为空。
5) 创建并显示非模态对话框。
// 首先检查指针是否为空,若为空,表示对话框还未创建,所以需要申请内存并创建对象。 if (m_pTestDlg == NULL) { m_pTestDlg = new CTestDlg(this); m_pTestDlg->Create(IDD_DIALOG_TEST, this); } // 对话框的初始大小可以在这里指定 int nDlgWidth = 400; int nDlgHeight = 200; CRect rcClient; GetClientRect(&rcClient); // 对话框居中 m_pTestDlg->MoveWindow((rcClient.Width() - nDlgWidth) / 2, (rcClient.Height() - nDlgHeight) / 2, nDlgWidth, nDlgHeight, TRUE); // 对话框显示 m_pTestDlg->ShowWindow(SW_SHOW);
6) 对话框关闭并销毁
对话框的关闭:
可以使用DestroyWindow函数实现。
void CTestDlg::OnOK() { DestroyWindow(); }
对话框的销毁:
由于对话框是动态在堆内存上创建的,当我们不再使用到这个对话框后,我们需要手动销毁对话框并释放内存,否则会造成内存泄漏。方法如下:重写CTestDlg的PostNcDestroy虚函数,其函数实现为delete this,也即在非模态对话框窗口销毁之后,自动释放对话框对象的内存。
void CTestDlg::PostNcDestroy() { delete this; }
7) OnOK和OnCancel的处理
当用户在对话框上点击OK按钮或者敲击回车,系统会自动调用OnOK虚函数。当用户在对话框上点击Cancel按钮或者敲击ECS,系统会自动调用OnCancel虚函数,如果我们需要在这些事件发生时做一些自定义处理,则可以重写这两个虚函数。
void CTestDlg::OnOK() { // 自定义处理代码 } void CTestDlg::OnCancel() { // 自定义处理代码 }
8) WM_SIZE消息处理
当对话框上有子控件时,我们需要映射对话框的WM_SIZE消息并编写子控件的自适应代码。
void CTestDlg::OnSize(UINT nType, int cx, int cy) { // 子控件自适应代码 }
9) 客户区拖动
当我们希望用户通过拖动对话框的客户区来改变对话框的位置时,可以重写OnNcHitTest方法。
LRESULT CTestDlg::OnNcHitTest(CPoint point) { CRect rc; GetClientRect(&rc); ClientToScreen(&rc); return rc.PtInRect(point) ? HTCAPTION : __super::OnNcHitTest(point); }
至此,我们讲述了非模态对话框的基本使用方法及注意事项,希望对有需要的朋友有所帮助。
相关推荐
- 绘制菜单符号的技法
- Posted on 12月26日
- 错误信息:Unable to stop the stream: Inappropriate ioctl for device
- Posted on 04月18日
- 动态初始化和用户定义分区的新编译器警告
- Posted on 08月25日
- 调用函数不仅仅只是传递正确的参数类型
- Posted on 06月04日
评论已关闭。