【MFC】学习笔记:模态、非模态对话框的创建与弹出过程

01、文章目录

文章目录

      • 01、文章目录
      • 02、MFC两种基础对话框
      • 03、模态对话框的弹出方式
      • 04、模态对话框建立与弹出全过程
      • 05、非模态对话框创建与弹出全过程
      • 06、总结

02、MFC两种基础对话框

MFC中或者说Windows系统中,对话框主要分为两种:模态对话框和非模态对话框。
今天就浅谈两种对话框的创建流程与弹出流程。
看了这篇文章之后,想必创建两种对话框是完全没有问题的。

  1. 模态对话框
    模态对话框是这样的对话框,当它弹出后,本应用程序其他窗口将不再接受用户输入,只有该对话框响应用户输入,在对它进行相应操作退出后,其他窗口才能继续与用户交互。
  2. 非模态对话框
    非模态对话框则是,它弹出后,本程序其他窗口仍能响应用户输入。非模态对话框一般用来显示提示信息等。

说通俗点就是,当对话框点开之后,我们能不能操作其他对话框,就是区分的条件。
如果能,则是非模态对话框,即证明焦点不固定在当前打开对话框。
如果不能,则是模态对话框,即证明焦点固定在了当前打开对话框。

03、模态对话框的弹出方式

这里我贴上我以前的一片博客,上面有创建步骤,但是当初搞太快,发现有一张图片是放错了,但是关系不大,按照步骤来,你们同样可以做出一样的效果。
https://blog.csdn.net/m0_43458204/article/details/106389789

既然是聊弹出方式,因为当时我们并没有操作他,而是直接MFC自动生成的,所以这里贴上MFC的弹出过程源码,一起来看看。

当我们创建一个基于对话框的项目时,会自动生成一个某某莫APP类,这个名字是你们自己命名的。
我们进入这个类的.cpp中,找到InitInstance()函数。
查找函数的方式:下拉框式查找函数。

步骤如下:
1.点击工具,然后点击最后一个选项。
2.进入选项之后点击文本编辑器,下拉到最后,点击所有语言,选择常规,旁边有一个导航栏,勾选中即可。
3.退出设置界面,代码区域header部分就会有一行三选项的下拉框,在最后一个找InitInstance()函数即可。如果没有选项,则调整前面两个下拉框,选择定位在全局还是其他位置。

InitInstance()函数C++代码如下:

CAdditionDlg dlg;        // 定义对话框类CAdditionDlg的对象dlg   
m_pMainWnd = &dlg;       // 将dlg设为主窗口   
INT_PTR nResponse = dlg.DoModal();   // 弹出对话框dlg,并将DoModal函数的返回值(退出时点击按钮的ID)赋值给nResponse   
if (nResponse == IDOK)               // 判断返回值是否为OK按钮(其ID为IDOK,我已经将它删除)   
{   
    // TODO: Place code here to handle when the dialog is   
    //  dismissed with OK   
}   
else if (nResponse == IDCANCEL)      // 判断返回值是否为Cancel按钮(其ID为IDCANCEL,我将它的Caption改为了“退出”)   
{   
    // TODO: Place code here to handle when the dialog is   
    //  dismissed with Cancel   
}  

弹出对话框比较关键的一个函数,就是对话框类的DoModal()函数。CDialog::DoModal()函数的原型为:

virtual INT_PTR DoModal(); 

返回值:整数值,指定了传递给CDialog::EndDialog(该函数用于关闭对话框)的nResult参数值。如果函数不能创建对话框,则返回-1;如果出现其它错误,则返回IDABORT。

调用了它对话框就会弹出,返回值是退出对话框时所点的按钮的ID,比如,我们点了“退出”按钮,那么DoModal返回值为IDCANCEL。

这里为了能让各位看见整个过程,我重新建一个对话框。

04、模态对话框建立与弹出全过程

  1. 根据https://blog.csdn.net/m0_43458204/article/details/106389789中所讲的方法,在Resource View中的“Dialog”上点右键选择“Insert Dialog”,创建一个新的对话框模板,修改其ID为IDD_TIP_DIALOG,Caption改为“提示”,然后参考“为对话框添加控件”中所讲,在对话框模板上添加一个静态文本框(static text),Caption改为“您确定要进行加法计算吗?”,接下来修改OK按钮的Caption为“确定”,Cancel按钮的Caption为“取消”,最后调整各个控件的位置和对话框的大小。最终的对话框模板如下图:【MFC】学习笔记:模态、非模态对话框的创建与弹出过程_第1张图片
  2. 在对话框模板上点右键选择“Add Class…”,弹出添加类的对话框,设置“Class name”为CTipDlg,点“OK”。在Solution Explorer中可以看到生成了CTipDlg类的头文件TipDlg.h和源文件TipDlg.cpp。
  3. 我们要在点“计算”按钮之后弹出此提示对话框,那么就要在“计算”按钮的消息处理函数OnBnClickedAddButton()中访问提示对话框类,所以为了访问CTipDlg类,在AdditionDlg.cpp中包含CTipDlg的头文件:#include “TipDlg.h”。(双击按钮即可添加消息响应函数)在
  4. 修改OnBnClickedAddButton()的函数体,在所有代码前,构造CTipDlg类的对象tipDlg,并通过语句tipDlg.DoModal();弹出对话框,最后判断DoModal()函数的返回值是IDOK还是IDCANCEL来确定是否继续进行计算。OnBnClickedAddButton()函数修改后如下:
void CAdditionDlg::OnBnClickedAddButton()   
{   
    // TODO: Add your control notification handler code here   
    INT_PTR nRes;             // 用于保存DoModal函数的返回值   
  
    CTipDlg tipDlg;           // 构造对话框类CTipDlg的实例   
    nRes = tipDlg.DoModal();  // 弹出对话框   
    if (IDCANCEL == nRes)     // 判断对话框退出后返回值是否为IDCANCEL,如果是则return,否则继续向下执行   
        return;   
  
    // 将各控件中的数据保存到相应的变量   
    UpdateData(TRUE);   
  
    // 将被加数和加数的加和赋值给m_editSum   
    m_editSum = m_editSummand + m_editAddend;   
  
    // 根据各变量的值更新相应的控件。和的编辑框会显示m_editSum的值   
    UpdateData(FALSE);   
}  
  1. 测试。编译运行程序后,在对话框上输入被加数和加数,点“计算”,弹出提示对话框询问是否进行计算,如果选择“确定”,则提示对话框退出,并在主对话框上显示被加数和加数的和,而如果选择“取消”,则提示对话框也会退出,但主对话框显示的和不变,即没有进行加法计算。

05、非模态对话框创建与弹出全过程

实际上,模态对话框和非模态对话框在创建对话框资源和生成对话框类上是没有区别的,所以上一讲中创建的IDD_TIP_DIALOG对话框资源和CTipDlg类都不需要修改。

需要修改的是,对话框类实例的创建和显示,也就是之前在CAdditionDlg::OnBnClickedAddButton()函数体中添加的对话框显示代码。下面是具体步骤:

  1. 在AdditionDlg.h中包含CTipDlg头文件并定义CTipDlg类型的指针成员变量。详细操作方法是,在AdditionDlg.cpp中删除之前添加的#include “TipDlg.h”,而在AdditionDlg.h中添加#include “TipDlg.h”,这是因为我们需要在AdditionDlg.h中定义CTipDlg类型的指针变量,所以要先包含它的头文件;然后在AdditionDlg.h中为CAdditionDlg类添加private成员变量CTipDlg *m_pTipDlg;。
  2. 在CAdditionDlg类的构造函数中初始化成员变量m_pTipDlg。如果cpp文件中函数太多,我们可以在Class View上半个视图中找到CAdditionDlg类,再在下半个视图中找到其构造函数双击,中间客户区域即可马上切到构造函数的实现处。在构造函数体中添加m_pTipDlg = NULL;,这是个好习惯,在任何指针变量使用前都初始化,可以避免因误访问重要内存地址而破坏此地址的数据。(指针真可怕,使用必须初始化)
  3. 将上一讲中添加的模态对话框显示代码注释或删除掉,添加非模态对话框的创建和显示代码。VC++中注释单行代码使用“//”,注释多行代码可以在需注释的代码开始处添加“/”,结束处添加“/”。修改后的CAdditionDlg::OnBnClickedAddButton()函数如下:

C++代码如下:

void CAdditionDlg::OnBnClickedAddButton()   
{   
    // TODO: Add your control notification handler code here   
    /*INT_PTR nRes;             // 用于保存DoModal函数的返回值  
 
    CTipDlg tipDlg;           // 构造对话框类CTipDlg的实例  
    nRes = tipDlg.DoModal();  // 弹出对话框  
    if (IDCANCEL == nRes)     // 判断对话框退出后返回值是否为IDCANCEL,如果是则return,否则继续向下执行  
        return;*/  
  
    // 如果指针变量m_pTipDlg的值为NULL,则对话框还未创建,需要动态创建   
    if (NULL == m_pTipDlg)   
    {   
        // 创建非模态对话框实例   
        m_pTipDlg = new CTipDlg();   
        m_pTipDlg->Create(IDD_TIP_DIALOG, this);   
    }   
    // 显示非模态对话框   
    m_pTipDlg->ShowWindow(SW_SHOW);   
  
    // 将各控件中的数据保存到相应的变量   
    UpdateData(TRUE);   
  
    // 将被加数和加数的加和赋值给m_editSum   
    m_editSum = m_editSummand + m_editAddend;   
  
    // 根据各变量的值更新相应的控件。和的编辑框会显示m_editSum的值   
    UpdateData(FALSE);   
}  
  1. 因为此非模态对话框实例是动态创建的,所以需要手动删除此动态对象来销毁对话框。我们在CAdditionDlg类的析构函数中添加删除代码,但是MFC并没有自动给出析构函数,这时需要我们手动添加,在对话框对象析构时就会调用我们自定义的析构函数了。在AdditionDlg.h文件中为CAdditionDlg添加析构函数声明:~CAdditionDlg();,然后在AdditionDlg.cpp文件中添加析构函数的实现,函数体如下:
CAdditionDlg::~CAdditionDlg()   
{   
    // 如果非模态对话框已经创建则删除它   
    if (NULL != m_pTipDlg)   
    {   
        // 删除非模态对话框对象   
        delete m_pTipDlg;   
    }   
}  

这样,非模态对话框创建和显示的代码就添加修改完了。让我们运行下看看效果吧。

在加法计算器对话框上输入被加数和加数,然后点“计算”按钮,依然像上节一样弹出了提示对话框,但是先不要关闭它,你可以拖动它后面的加法计算器对话框试试,我们发现加法计算器对话框竟然可以拖动了,而且“和”编辑框里已经显示了运算结果,这表明提示对话框显示以后还没有关闭,OnBnClickedAddButton() 就继续向下执行了,不仅如此,加法计算器的每个编辑框还都可以响应输入。

这只是一个简单的例子,非模态对话框的用处有很多,以后大家在软件开发中会用到。

06、总结

通过上述的两个例子即概念,想必各位对模态与非模态对话框也有了一定的了解,至少简单的创建,判断是No problem。
这就是暂时对模态对话框与非模态对话框的全部介绍了,如果有什么疑问,可以再评论区或者私信里问我,我看见就会为大家解决。

版权声明:转载请注明出处,谢谢!

你可能感兴趣的:(MFC,MFC入门编程)