• 第五课——对话框


    一、何为对话框

    • 是Windows应用程序中最重要的用户界面元素之一,是与用户交互的重要手段。
    • 是一个特殊类型的窗口,可作为各种控件(具有独特功能的界面元素)的容器,可用于捕捉和处理用户的多个输入信息或数据。

    二、创建对话框

    情形一:直接创建一个基于对话框的应用程序

    情形二:在一个应用程序中添加对话框资源创建对话框类

    • 下面主要讲述第二种情形,其中应用程序以单文档应用程序为例。

    1. 创建步骤

      添加对话框资源 + 创建对话框类

    2. 资源&资源标识

    • Visual C++ 6.0将Windows应用程序中经常用到的菜单、工具栏、对话框、图标等都视为“资源”,并将其单独存放在一个资源文件(第4课有提及)中。
    • 每个资源都有相应的标识符(即ID)来区分,并且可以像变量一样进行赋值。

      常用资源分类:快捷键列表、对话框、图标、菜单、字符串表、工具栏按钮、版本信息

    常用资源的类别 说明
    快捷键列表(Accelerator)

    一系列组合键的集合,被应用程序用来引发一个动作。

    该列表一般与菜单命令相关联,用来代替鼠标操作。

    对话框(Dialog) 含有按钮、列表框、编辑框等各种控件的窗口
    图标(Icon)

    代表应用程序显示在Windows桌面上的位图

    它同时有32x32像素和16x16像素两种规格

    菜单(Menu) 用户通过菜单可以完成应用程序的大部分操作
    字符串表(String Table) 应用程序使用的全局字符串或其他标识符
    工具栏按钮(Toolbar)

    工具栏外观是以一系列具有相同尺寸的位图组成的

    它通常与一些菜单命令项相对应,以提高用户的工作效率

    版本信息(Version) 包含应用程序的版本、用户注册码等相关信息

      除了上述常用资源类别外,还有鼠标指针、HTML等,甚至可以自己添加新的资源类别。

      每一个资源类别下都有一个或多个相关资源,每一个资源均是由标识符来定义的。

      当添加一个新的资源对象时,系统会为其提供默认的标识符名称,如IDD_DIALOG1等。当然,用户可以重命名。

    3. 添加对话框资源

      假设我们为当前应用程序Ex_SDI添加了一个对话框资源,系统为其提供的默认的标识符名称为IDD_DIALOG1。

      使用通用的对话框模板创建的对话框资源,有“确定”和“取消”两个按钮,这两个按钮的标识符分别为IDOK和IDCANCEL。

    4. 创建对话框类

      添加完对话框资源,我们要想在应用程序中使用该对话框,必须先为该对话框模板创建一个用户对话框类:为对话框资源创建一个新类→类名以C字母打头(假设为COneDlg)→一个基于对话框资源模板IDD_DIALOG1的用户对话框类COneDlg就创建好了

    • 注:用户对话框类是从基类CDialog(第三课有提及)派生而来的

      3、4节的结果:为应用程序Ex_SDI添加了一个新对话框资源IDD_DIALOG1,并为之生成了一个对话框类COneDlg。

    三、设计对话框

    1. 控件的添加和布局

    • 控件工具栏+控件布局工具栏
    • 所有静态控件的ID均默认为IDC_STATIC(好像控件那一课将会学到...)

    2. WM_INITDIALOG消息

      定义:在对话框显示之前向父窗口发送的消息

      我们建立了此消息和OnInitDialog函数的关联,即OnInitDialog函数是WM_INITDIALOG消息的映射,因此系统在对话框显示之前就会调用OnInitDialog函数(故常将对话框一些初始化代码添加到OnInitDialog函数中)

      注:Visual C++只会为基于对话框的应用程序添加WM_INITDIALOG消息的映射函数OnInitDialog,并添加了一系列的初始化代码。但在应用程序添加的对话框资源,创建的对话框类并不会自动添加该消息的映射函数,这需要手动操作。

      下面以单文档应用程序Ex_SDI添加的COneDlg对话框为例说明该映射过程:MFC ClassWizard对话框(Message Maps选项卡)→类名选定为COneDlg(Objects IDs选定为COneDlg)→双击Messages列表框中的(要映射的)WM_INITDIALOG消息在CEx_SDIView类中添加该消息的映射函数OnInitDialog→双击消息函数(即OnInitDialog)定位到COneDlg::OnInitDialog函数实现的源代码处

    四、使用对话框

    1. 步骤概述

    1. 先在应用程序中添加该对话框类的包含头文件(在Ex_SDIView.cpp中添加#include "OneDlg.h");
    2. 然后定义该类的对象(COneDlg dlg;);
    3. 通过对象调用类的成员函数DoModal来模式显示,或通过对象指针来创建对话框。

      注:DoModal是CDialog基类虚成员函数,它用来显示和终止模式对话框。

    2. 在程序中使用

    • 方法:将显示对话框的代码添加到命令消息映射函数

      由于单文档应用程序包含菜单的用户界面,因而通常将代码添加到菜单命令消息的映射函数中。

      过程:将项目工作区窗口切换到ResourceView选项卡→双击资源Menu项中的IDR_MAINFRAME(打开菜单编辑器)→完成输入新的菜单项(假设其ID为ID_DLG_FIRST)→MFC ClassWizard对话框(Messaage Maps选项卡)→类名选定为CEx_SDIView(Objects IDs选定为ID_DLG_FIRST)→双击Messages列表框中的(要映射的)COMMAND消息在CEx_SDIView类中添加该消息的映射函数OnDlgFirst(该成员函数是对菜单项ID_DLG_FIRST的映射)→双击消息函数OnDlgFirst定位到CEx_SDIView::OnDlgFirst函数实现的源代码处→添加如下代码→在CEx_SDIView类的实现文件Ex_SDIView.cpp中添加COneDlg类的头文件包含→编译并运行(点击菜单项会显示对话框)

    void CEx_SDIView::OnDlgFirst() 
    {
    	// TODO: Add your command handler code here
    	COneDlg dlg;
    	dlg.DoModal();
    }
    

    3. DoModal和模式对话框

      模式对话框:对话框弹出后,用户必须在对话框中作出相应的操作,在退出对话框之前,对话框所在的应用程序不能继续执行。

      模式对话框中的“确定”和“取消”按钮:单击确定按钮,系统认定用户在对话框中的选择或输入有效,对话框退出;单击取消按钮,对话框中的选择或输入无效,退出对话框,程序恢复原有状态。

      将对话框以模式方式来显示:通过CDialog::DoModal函数来实现

    • DoModal函数:没有形参,但有返回值。单击确定按钮,则DoModal结束并返回默认的IDOK值(IDOK是确定按钮的ID值);单击取消按钮,DoModal结束并返回默认的IDCANCEL值(IDCANCEL是取消按钮的ID值);若有错误,则返回-1。

      即要求获取对话框中用户操作的内容,还要判断DoModal的返回值。

      即使用类似这样的代码:int nRet = dlg.DoModal();

    4. 通用对话框

      从上面的过程可知,使用对话框编辑器和MFC ClassWizard可以创建自己的对话框类

      除此,在Visual C++ 6.0中还提供了一些通用对话框供用户在程序中直接调用

      这些对话框都是Windows标准用户界面对话框,MFC为它们提供了相应的MFC类。MFC对这些通用对话框所构造的类都是从一个公共的基类CCommonDialog派生而来的。下标列出了MFC的通用对话框类:

    对话框 用途
    CColorDialog 颜色对话框,用来选择或创建颜色
    CFileDialog 文件对话框,用来打开或保存一个文件
    CFindReplaceDialog 查找替换对话框,用来查找或替换指定字符串
    CPageSetupDialog 页面设置对话框,用来设置页面参数
    CFontDialog 字体对话框,用来从列出的可用字体中选择一种字体
    CPrintDialog 打印对话框,用来设置打印机的参数及打印文档

      这些对话框的共同特点:都只从用户获取信息,但并不对信息作处理。例如,文件对话框可用来选择一个要打开的文件,但它实际上只是给程序提供了一个文件路径名,用户的程序必须调用相应的成员函数才能打开文件。类似地,字体对话框只是填充一个描述字体的逻辑结构,但它并不创建字体。

      用户可以在程序中直接使用这些通用对话框,例如,可将下面的代码添加在前面Ex_SDI项目CEx_SDIView::OnDlgFirst函数中,运行后点击菜单项会弹出一个文件对话框,选定一个文件并单击“打开”按钮,就会弹出一个消息对话框,显示该文件的全路径名。

    void CEx_SDIView::OnDlgFirst() 
    {
    	// TODO: Add your command handler code here
    	CString filter;
    	filter = "文本文件(*.txt)|*.txt | C++文件(*.h,*.cpp)|*.h;*.cpp ||";
    	CFileDialog dlg (TRUE, NULL, NULL, OFN_HIDEREADONLY, filter);
    	if (dlg.DoModal() == IDOK) {
    		CString str, str1;
    		str = dlg.GetPathName();	//返回选择文件的路径
    		AfxMessageBox(str);
    	}
    }
    • 上述代码中,CString是MFC中的一个类,用来操作字符串

    通用文件对话框类CFileDialog的构造函数的原型如下:

    CFileDialog(BOOL bOpenFileDialog, 
    			LPCTSTR lpszDefExt = NULL, 
    			LPCTSTR lpszFileName = NULL, 
    			DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 
    			LPCTSTR lpszFilter = NULL, 
    			CWnd *pParentWnd = NULL);
    

    参数中:

    • 当bOpenFileDialog为TRUE时,表示文件打开对话框,为FALSE时表示文件保存对话框。
    • lpszDefExt用来指定文件扩展名,若用户在文件名编辑框中没有输入扩展名,则系统在文件名后自动添加lpszDefExt指定的扩展名。
    • lpszFileName用来在文件名编辑框中指定开始出现的文件名,若为NULL时,则不出现。
    • dwFlags用来指定对话框的界面标志,当为OFN_HIDEREADONLY时表示隐藏对话框中的“只读”复选框,当为OFN_OVERWRITEPROMPT时表示文件保存时,若指定的文件有重名,则出现提示对话框。
    • pParentWnd用来指定对话框的父窗口指针
    • lpszFilter参数用来确定出现在文件列表框中的文件类型。它由一对或多对字符串组成,每对字符串中第一个字符串表示过滤器名称,第二个字符串表示文件扩展名,若指定多个扩展名则用“;”分隔,字符串最后用两个“|”结尾。

    函数原型中,LPCTSTR类型(第2课提到的LPCSTR表示const char *)用来表示一个常值字符指针,这里可以将其理解为一个常值字符串类型

    GetPathName是CFileDialog类成员函数,用来获取文件的全路径名。除此,CFileDialog类中还有类似的成员函数:

    //返回在对话框确定的文件名
    CString GetFileName() const;
    //返回在对话框中确定的文件扩展名
    CString GetFileExt() const;
    
    • 强调:当只调用对话框类的成员函数DoModal并返回IDOK后,该对话框类的其他属性成员函数才会有效。

      注:关于其他通用对话框的具体用法在以后的章节中将陆续介绍。

    5. 消息对话框

    定义:是最简单的一类对话框,只是用来显示信息的。

    在Visual C++ 6.0的MFC类库中就提供相应的函数实现这样的功能,使用时,直接在程序中调用它们即可。

    它们的函数原型如下:

    	int AfxMessageBox(LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0);
    	int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK);

    这两个函数都是用来创建和显示消息对话框的,它们和第一课使用到的Win32 API函数MessageBox是不同的,前者是MFC类库中的函数。AfxMessageBox是全程函数,可以用在任何地方。而MessageBox只能在控件、对话框、窗口等一些窗口类中使用。

    这两个函数都返回用户选择按钮的情况,如返回IDOK表示用户单击OK按钮。

    参数lpszText表示在消息对话框中显示的字符串文本;lpszCaption表示消息对话框的标题,为NULL时使用默认标题;nIDHelp表示消息的上下文帮助ID标识符;nType表示消息对话框的图标类型以及所包含的按钮类型,这些类型都是用MFC预先定义的一些标识符来指定的,例如MB_ICONSTOP、MB_YESNOCANCEL等,具体见下图:

    注:图标类型和按钮类型的标识可使用按位或运算符“|”来组合。

    例如,下面是消息对话框的使用示例:

    	int nChoice = MessageBox("你喜欢周帅帅吗?", "爱情问卷", MB_YESNO|MB_ICONQUESTION);
    	if (nChoice == IDYES)
    		AfxMessageBox("QQ914408090
    TEL15195952087");
    
  • 相关阅读:
    RocketMq总结(六) -- 顺序消息
    RocketMq总结(五) -- 消息队列负载均衡和再分配
    RocketMq总结(三) -- 消费者启动 MQClientInstance
    归并排序
    CMS垃圾收集器总结
    桶排序
    快速排序
    ThreadLocal的妙用
    NC_41 找最小的k个数
    RocketMq一条消息存储结构
  • 原文地址:https://www.cnblogs.com/xzxl/p/7931916.html
Copyright © 2020-2023  润新知