MFC界面编程基础(10):基于对话框的MFC应用程序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17017545/article/details/85088036
上一篇:MFC界面编程基础(09):菜单(二) 下一篇:MFC界面编程基础(11):静态文本框、命令按钮和编辑框

MFC编程

MFC 是 Visual C++ 的核心。虽然在 Windows 应用程序中可以直接调用 API 函数,但是一般不经常直接调用,而是从 MFC 类创建对象并调用属于这些对象的成员函数。MFC 是 Microsoft 公司提供的用来编写 Windows 应用程序的 C++ 类库,MFC 大约有 200 多个类,可以分成两种:一是 Cobject 类的派生类,它们以层次结构的形式组织起来,几乎每个子层次结构都与一个具体的 Windows 实体对应;二是非 Cobject 派生类,这些都是独立的类,如表示点的 CPoint 类,表示矩形的 CRect 类。

在 Visual C++ 中,可以创建以下 3 类典型的 Windows 应用程序,它们都是通过 MFC AppWizard(exe) (以下简称 AppWizard )向导创建的:

  • 基于对话框的应用程序:这类程序适合于文档较少而交互操作较多的应用场合,如 Windows 自带的计算器程序。
  • 单文档界面( SDI )应用程序:这类程序一次只能打开一个文档,如 Windows 自带的 Notepad 程序。
  • 多文档界面( MDI )应用程序:这类程序可以同时打开多个文档并进行处理,处理的过程中很容易地进行切换,如 Microsoft Word 。

基于对话框的MFC应用程序

有两种对话框: 模态对话框(Modal)和非模态对话框

  • 模态对话框
    当其显示时,程序会暂停执行,直到关闭这个模态对话框之后,才能执行程序中的其他任务。我们平时遇到的对话框都是模态对话框。
    模态对话框的创建
    实现模态对话框的创建需要调用CDialog类的成员函数 DoModel(),该函数的功能就是创建并显示一个对话框。
//弹出模态对话框,有阻塞(效果是弹出对话框后会停留在这个界面)
CTestDlg dlg;
dlg.DoModel();	//显示模态对话框
  • 非模态对话框
    当非模态对话框显示时,运行转而执行程序中 的其他任务,而不用关闭这个对话框。典型的就是Windows记事本中提供的查找对话框,打开该对话框后仍可以与其他用户界面对象进行交互,一遍查找,一遍修改文章,这样就大大方便了使用。
    非模态对话框的创建
    如果要创建非模态对话框在需要使用CDialog的Create成员函数。
BOOL Create(LPCSTR lpszTemplateName, CWnd* pParentWnd = NULL);
BOOL Create(UNIT nIDTemplate, CWnd* pParentWnd = NULL);

返回值:
如果对话框创建和初始化成功,则返回非零值,否则为0。
参数:
lpszTemplateName 对话框模板的名称。
nIDTemplate 对话框资源的ID。
pParentWnd 指向含有对话框的父窗口对象的指针。如果为NULL,对话框对象的父窗口设置为应用的主窗口。
利用Create函数创建非模态对话框时,还需要调用ShowWindow函数将这个对话框显示出来。

//弹出非模态对话框,无阻塞(效果是弹出对话框后会立马关闭,一闪而过的样子)
CTestDlg dlg;
dlg.Create(IDD_DIALOG1, this);//创建
dlg.ShowWindow(SW_SHOW);		//显示 
//ShowWindow() 函数在  CWnd:ShowWindow() 中,因为CTestDlg 属于CDialog 类,CDialog 的父类就是CWnd (类的层次结构图中可查找到)

执行程序发现仍然没有弹出测试对话框,问题就出在创建的非模态对话框是一个局部对象,函数结束后,对话框的生命周期也就结束了。在创建非模态对话框时不能将其定义为局部对象。有两种解决方法:

  • 1.把对话框对象定义为类的成员变量,主要按照以下两个操作步骤:

    ①:在主对话框的 .h 文件中添加成员变量,同时将事件处理程序中的 CTestDlg dlg; 注释掉;

#include“TestDlg .h”
……
private:
	CTestDlg dlg;

若只是这样,当第一次点击按钮时会弹出非模态对话框,也不会闪退,而当你关闭这个非模态对话框后再次点击按钮,程序会崩溃,原因是 dlg.Create(IDD_DIALOG1, this); 执行了两次,所以需要进行第②步操作
  ②:将创建窗口的函数移到主对话框的初始化函数OnInitDialog中,同时将事件处理程序中的dlg.Create(IDD_DIALOG1, this); 注释掉,确保窗口只创建一次,因为创建多次会崩溃,最后实际上就是当每次点击按钮,事件处理程序中只负责显示窗口就OK了;

BOOL XXXXX:OnInitDialog()
{
	……
	//TODO:在此添加额外的初始化代码
	dlg.Create(IDD_DIALOG1, this);//创建
}
  • 2.将对话框对象定义为指针,在堆上分配内存

如果选择在堆上分配内存,关闭对话框时就需要释放堆内存,释放的方式有两种:

  • 将指针定义为对话框所属的类的成员变量(比如视类),在指针所属的类的析构函数中释放
  • 在对话框类中重载PostNcDestroy虚函数,释放this指针指向的内存。
void MyDialog::PostNcDestroy()
{
	// TODO:  在此添加专用代码和/或调用基类
	delete this;
	CDialogEx::PostNcDestroy();
}

创建基于对话框的 MFC 应用程序框架

程序的创建过程:

  • 选择“文件 | 新建 | 项目”菜单;
  • 在“新建项目”对话框中,选择“ MFC 应用程序 ”,输入工程名称,选择“确定”。

在这里插入图片描述

  • 选择“ 基于对话框”,即创建基于对话框的应用程序,选择“完成”。
    在这里插入图片描述

对话框应用程序框架

用 AppWizard 创建基于对话框的应用程序框架(假定工程名为 Dialog )后,项目工作区上增加了一个“ 资源视图 ”选项卡。
在这里插入图片描述

  • 资源视图
    在 MFC中,与用户进行交互的对话框界面被认为是一种资源。展开“ Dialog ”,可以看到有一个 ID 为 IDD_ DIALOG _DIALOG(中间部分(DIALOG)与项目名称相同) 的资源,对应中间的对话框设计界面。不管在何时,只要双击对话框资源的 ID ,对话框设计界面就会显示在中间。
    在MFC中对资源的操作通常都是通过一个与资源相关的类来完成的。
  • 类视图
    在类视图中,可以看到生成了3 个类: CAboutDlg 、 CDialogApp 和 CDialogDlg 。
    在这里插入图片描述
  • CAboutDlg:对应生成的版本信息对话框。
  • CDialogApp:对话框类,从 Cdialog 继承过来的,在程序运行时看到的对话框就是它的一个具体对象。
  • CDialogDlg:应用程序类,从 CWinApp 继承过来,封装了初始化、运行、终止该程序的代码。
    ※ DoDataExchange函数,该函数主要完成对话框数据的交换和校验。
    ※ OnInitDialog函数:相当于对对话框进行初始化处理
    调用这个成员函数是对WM_INITDIALOG消息作出的反应。这条消息是在对话框即将显示之前,在Create,CreateIndirect或DoModal调用期间发出的。
  • 对话框设计界面
    对话框设计界面是进行对话框设计的地方,可以将各种控件放置在这里。
    在这里插入图片描述
  • 控件工具栏
    我们可以根据实际需求,在开发过程中选择不同的控件,实现不同的功能。
    在这里插入图片描述

注1:当点击一个按钮需要弹出一个另外一个对话框,通常分以下几个步骤:
①:在资源视图中的Dialog中添加一个新的对话框(即你点击按钮需要显示的这个对话框)
②:在生成的新对话框中右键->添加类(类名自定义),将其对应到一个类中,然后会生成对应的 .h /.cpp 文件
③:在按钮的时间处理程序中使用这个类,并通过这个类创建一个对象,然后操作对象让对话框显示出来(模态的或者非模态的)

注2:给按钮添加点击事件的处理程序的常用三种方法:
①:点击按钮右键属性->控制事件(闪电图标)->BN_CLICKED(单次点击)->下拉列表出现字样然后点击进入编辑
②:点击按钮右键属性->添加事件处理程序->点击进入编辑消息类型等等
③:双击此按钮,直接创建一个事件处理程序

注3:在MFC中一个类的名称通常以一个大写的C开头,但是在别的文件中引用这个头文件的时候不用带C
例如:类名 CDlgExec ,只需 #include “DlgExec.h”

上一篇:MFC界面编程基础(09):菜单(二) 下一篇:MFC界面编程基础(11):静态文本框、命令按钮和编辑框

猜你喜欢

转载自blog.csdn.net/qq_17017545/article/details/85088036
今日推荐