对话框
一种用户界面,主要功能是输出信息和接收用户操作。每个对话框都包含一些控件,对话框依靠这些控件与用户进行交互。
1. 对话框概述
对话框分为两种:一种是模式(Model)对话框,另一种是非模式(Modeless)对话框。两者主要区别:当模式对话框出现时,调用该对话框的父窗口会无效;而非模式对话框出现时,调用该对话框的父窗口功能不受影响。另两种对话框的生成方式不同。
对话框最基本的要素就是对话框模板,从对话框的尺寸到对话框包含的控件以及分布情况。对话框模板定义了对话框一般的属性。Windows根据对话框模板来创建并显示对话框。
1)模式对话框
当模式对话框被打开始后,用户只能与该对话框进行交互,而且其他用户界面对象无法接收输入消息。
创建一个模式对话框:
A. 首先创建一个对话框模板,描述对话框及其包含的控件。
B. 为该对话框创建一个派生于CDialog类的子类,封装该对话框模板及其对话框的所有操作。
C. 调用DoModal函数建立并显示模式对话框,同时也使得所有用户对应用程序的操作在该对话框外无效。函数DoModal被调用之后,只有当用户通过操作直接或者间接关闭对话框后,函数DoMedal才返回。
2)非模式对话框
非模式对话框和模式对话框最大的不同在于,当费模式对话框处于激活状态时,还允许用户在用户程序的其他地方工进行操作,而模式对话框处于激活状态后,则不允许对主窗口进行任何操作。而导致这个区别的主要原因是在对话框的创造和删除过程中:
A. 建立和显示模式对话框需要调用对话框类的函数DoMedal,而非模式对话框的建立和显示则要调用对话框类的函数Create。函数Create不会启动新的消息循环,非模式对话框与应用程序共用一个消息循环,所以非模式对话框不会垄断用户的输入操作。
B. 模式对话框的清除是通过函数DoModal返回过程中立即调用EndDialog完成的,而非模式对话框的清除必须调用函数DestroyWindow。因为函数DestroyWindow是直接删除窗口的方法,而函数EndDialog对于非模式对话框,只能让对话框不看见,而不能彻底清除对话框
C. 模式对话对象通常是在栈上创建,而非模式对话框对象需要通过new在堆中动态创建。
D. 模式对话框对象的析构在关闭对话框时自动完成,而非模式对话框对象的析构需要在关闭对话框时调用函数CWnd::PostNcDestroy,并包含代码delete this。
2. 类CDialog
类CDialog既支持模式对话框,也支持非模式对话框,类CDialog的继承关系:
CObject
|---CCmdTarget
|---CWnd
|---CDialog
类CDialog的常用方法:
BOOL Create(LPCTSTR lpszTemplate, CWnd *pParentWnd = NULL);
BOOL Create(UINT nIDTemplate, CWnd *pParentWnd = NULL);
参数lpszTemplate/nIDTemplate和对话框模板的唯一对应的字符串或者资源ID,参数pParentWnd是指向该对话框父窗口的指针,如果pParentWnd = NULL,则对话框的父窗口为应用程序的主窗口。
virtual int DoModal()
针对模式对话框,实现对话框的建立和显示功能
void NextDlgCtrl()const;
void PrevDlgCtrl()contr;
void GotoDlgCtrl(CWnd *pWndCtrl);
用于对话框控件之间的切换操作,与使用键盘Tab键及方向键操作对话框控件的功能基本一致
virtual BOOL OnInitDialog();
消息WM_INITDIALOG的响应函数,初始化对话框及其控件。返回值通知系统如何处置输入焦点,如果函数放回TRUE,则Windows将输入焦点指派给制表键控制次序中的第一个控件;如果输入焦点指派给了其他任何控件,则函数返回FALSE
类CDialog的派生类
CDialog
|---CCommonDialog----------CFileDialog
|---COlePropertyPage |---CPrintDialog
|---CPropertyPage |---CColorDialog
|---User Dialog Boxes |---Others
3. 对话框数据存储机制
要实现对对话框控件中的数据进行存取,需要在对话框类里定义成员变量,并建立控件与类成员变量的联系。在此基础上,在由函数CWnd::UpdateData实现对话框控件与对话框成员变量之间的数据交互。
BOOL UpdateData(BOOL bSaveAndValidate = TRUE);
函数UpdateData在对话框打开和关闭时个执行一次。也可以在需要时手动更新数据,进行数据交互。
virtual void DoDataExchange(CDataExchange *pDX);
参数pDX是指向数据交互类CDataExchange的对象,类CDataExchange没有基类。函数DoDataExchange的功能是数据转换与数据有效范围检查,但他不能直接被使用,而必须由函数UpdateData调用。
数据转换(DDX, Dialog Data Exchange)和数据校验(DDV, Dialog Data Validation)是对话框数据存取机制的核心。函数DoDataExchange中包含了许多以DDX_开头的数据转换函数和以DDV_开头的数据校验函数,比如:
void CListComboScroll::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_pName); // 建立了编辑框控件显示内容和成员变量之间的联系
DDX_Control(pDX, IDC_COMBO2, m_cbYear); // 建立了组合框控件和组合框成员变量的联系
DDX_Control(pDX, IDC_LIST3, m_lbSalary); // 建立了列表框控件和列表框成员变量的联系
}
DDV是对话框校验机制,它允许应用程序在清除对话框之前校验输入对话框控件的数据
void CColorUserDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
// 建立成员变量m_nGreen,m_nRed和m_nBlue和控件的联系
DDX_Text(pDX, IDC_EDIT3, m_nGreen);
DDX_Text(pDX, IDC_EDIT1, m_nRed);
DDX_Text(pDX, IDC_EDIT2, m_nBlue);
// 给出m_nGreen,m_nRed和m_nBlue成员变量的输入范围
DDV_MinMaxInt(pDX, m_nGreen, 0, 255);
DDV_MinMaxInt(pDX, m_nRed, 0, 255);
DDV_MinMaxInt(pDX, m_nBlue, 0, 255);
}
4. 对话框控件
控件是Windows图形用户界面的主要组成部分之一,用户通过操作控件完成与应用程序之间的交互,作为一个具体的对象控件具有属性,事件和方法的三重性。
Visual C++提供了控件工具条和样式工具条,能够很方便控件创建和调整布局:
控件工具条
样式工具条