Windows编程与MFC # 3 基于对话框的应用程序(1)

Windows编程与MFC # 3 基于对话框的应用程序(1)_第1张图片

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

对话框是Windows系统的一种特殊的窗口,用于应用程序和用户之间进行信息交互,其作用非常重要。
控件是嵌入在对话框或其它父窗口中的一种特殊子窗口。
Visual Studio提供了大量控件用于数据输入与显示。
Windows编程与MFC # 3 基于对话框的应用程序(1)_第2张图片
Windows编程与MFC # 3 基于对话框的应用程序(1)_第3张图片
在Resource View的资源树中双击某个ID,可在中间区域内显示相应的资源界面。双击IDD_ADDITION_DIALOG时,中间区域就会显示Addition对话框模板。
在Addition对话框模板上点右键,然后在右键菜单中选择Properties,则在右侧面板中会显示对话框的属性列表。

Windows编程与MFC # 3 基于对话框的应用程序(1)_第4张图片
Style:对话框类型。
有三种类型:Overlapped(重叠窗口)、Popup(弹出式窗口)和Child(子窗口)。
弹出式窗口比较常见。我们使用默认的Popup类型。

为对话框添加控件

创建对话框资源需要创建对话框模板、修改对话框属性、为对话框添加各种控件等步骤。
实现乘法计算有几个必要的部分:两个操作数和结果。两个操作数需要输入,运算结果需要输出显示。
那么这几个部分都需要相应的控件来输入或显示。
Windows编程与MFC # 3 基于对话框的应用程序(1)_第5张图片
Windows编程与MFC # 3 基于对话框的应用程序(1)_第6张图片
Windows编程与MFC # 3 基于对话框的应用程序(1)_第7张图片
Windows编程与MFC # 3 基于对话框的应用程序(1)_第8张图片
Windows编程与MFC # 3 基于对话框的应用程序(1)_第9张图片
Windows编程与MFC # 3 基于对话框的应用程序(1)_第10张图片
Windows编程与MFC # 3 基于对话框的应用程序(1)_第11张图片
Windows编程与MFC # 3 基于对话框的应用程序(1)_第12张图片
Windows编程与MFC # 3 基于对话框的应用程序(1)_第13张图片
为控件添加变量

1.在编辑框IDC_OPERAND1_EDIT上点右键,在右键菜单中选择“Add Variable”。弹出添加成员变量的向导对话框。
2.我们想为其添加值变量而不是控件变量,所以对话框中“Category”下的组合框中选择Value。
3.“Variable type”下的组合框此时默认选中的是“CString”,CString是字符串类,显然不能进行加法运算。我们可以选择double、float、int等。这里我们选择double,即编辑框关联一个double类型的变量。
4.在“Variable name”中写入自定义的变量名。 为其取名m_dOperand1。

参照此方法,再分别为加数的编辑框IDC_OPERAND2_EDIT添加double型变量m_dOperand2、运算结果的编辑框IDC_RESULT_EDIT添加double型变量m_dResult。
注意,类的成员变量名一般以m_打头,以标识它是一个成员变量。

在程序运行界面中,用户往往会改变控件的属性,比如输入一个数值。
控件的属性改变后MFC会相应修改控件关联变量的值。
这种同步的改变是通过MFC为对话框类自动生成的成员函数DoDataExchange()来实现的,这也叫做对话框的数据交换和检验机制。
MFC为了使控件与关联变量能够绑定,提供了对话框数据交换(Dialog Data Exchange,DDX)和对话框数据验证有效性(Dialog Data Verify,DDV)机制。

为三个编辑框添加了变量以后,在AdditionDlg.cpp中CAdditionDlg的DoDataExchange()函数的函数体中多了三条DDX_Text调用语句。

void CAdditionDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_OPERAND1_EDIT, m_dOperand1);
DDX_Text(pDX, IDC_OPERAND2_EDIT, m_dOperand2);
DDX_Text(pDX, IDC_RESULT_EDIT, m_dResult);
}

如果我们在程序运行界面中输入被加数,则通过CAddition的DoDataExchange()函数可以将输入的值保存到m_dResult变量中。
反之如果程序运行中修改了变量m_dResult的值,则通过CAddition的DoDataExchange()函数也可以将新的变量值显示到运算结果的编辑框中。

DDX机制将对话框资源中的控件和对话框类的一个成员变量之间建立关联,使成员变量和控件之间的数据交换更加容易。
DDV机制用于在返回成员变量之前自动校验数据的长度和范围,并发出相应的警告信息。

DDX函数是一个全局函数,其函数声明如下:
void AFXAPI DDX_type(CDataExchange *pDX,int CtrlID,VariableType& m_data);
如:
DDX_Text(pDX, IDC_OPERAND1, m_dOperand1);
表示m_dOperand1是一个Value值类别的成员变量,用于与IDC_OPERAND1文本编辑框控件实现数据交换。

DDV函数也是全局函数,有两种重载形式,分别用于校验字符串数据和数值数据。
void AFXAPI DDV_MaxChars(CDataExchange *pDX,CString const& m_data ,int nChars);

void AFXAPI DDV_MinMaxVariableType(CDataExchange *pDX, VariableType m_data, VariableType minVal, VariableType MaxVal);

其中VariableType是成员变量的数据类型,m_data是成员变量,nChars是字符串数据的最大长度,minVal和maxVal分别是数值数据的最小值和最大值。


DDV_MinMaxDouble(pDX, m_dOperand1, 0., 100.);
表示double类型成员变量m_dOperand1的最小值和最大值分别是0.0和100.0。
如果用户输入的数值超过这个范围,DDV就显示信息对话框,提示用户有效的输入范围。
另外程序如果已经指定文本编辑框控件与double类型变量关联,那么当用户输入的不是数值,DDV也会提出提示。

Windows编程与MFC # 3 基于对话框的应用程序(1)_第14张图片
上两个信息对话框并不是用户在输入数据后立即弹出,而是在调用DoDataExchange()函数时才会出现的。但MFC程序中一般不直接调用DoDataExchange()函数,而是通过UpdateData()函数间接调用。

可以通过UpdateData()函数的参数控制数据在控件和关联变量之间的传递方向:
当调用UpdateData(TRUE)时,程序通过调用DoDataExchange()函数将数据从控件传递到关联变量。
当调用UpdateData(FALSE)时,程序通过调用DoDataExchange()函数将数据从关联变量传递到控件,实现了控件在刷新后重新获取关联变量的值。

BOOL UpdateData(BOOL bSaveAndValidate = TRUE);
参数:bSaveAndValidate用于指示数据传输的方向,TRUE表示从控件传给变量,FALSE表示从变量传给数据。默认值是TRUE,即从控件传给变量。
返回值:CDialogEx::UpdateData()函数的返回值表示操作是否成功,成功则返回TRUE,否则返回FALSE。

在对话框初始化时或关联变量数据发生变化时需要调用UpdateData(FALSE)函数,以使控件正确显示数据内容;如果要获取用户在控件中的输入信息时,需要调用UpdateData(TRUE)。

DDX和DDV不仅适用于文本编辑框,还适用于单选按钮、复选按钮、组合框等控件,MFC为它们提供了对应的DDX和DDV函数。

编辑框(Edit Control)是一种很常用的控件,可以在编辑框中输入并编辑文本。
编辑框发生某些事件时会向父窗口发送通知消息。在对话框模板中的编辑框上点右键,选择“Add Event Handler”,为编辑框添加消息处理函数时,可以在“Message type”列表中看到这些消息。
下面简单介绍编辑框的部分通知消息。

EN_CHANGE:编辑框的内容被用户改变了,与EN_UPDATE 不同,该消息是在编辑框显示的正文被刷新后才发出的。
EN_ERRSPACE:编辑框控件无法申请足够的动态内存来满足需要。
EN_HSCROLL:用户在水平滚动条上单击鼠标。
EN_KILLFOCUS:编辑框失去输入焦点。
EN_MAXTEXT:输入的字符超过了规定的最大字符数。在没有ES_AUTOHSCROLL 或 ES_AUTOVSCROLL: 的编辑框中,当正文超出了编辑框的边框时也会发出该消息。
EN_SETFOCUS:编辑框获得输入焦点。
EN_UPDATE:在编辑框准备显示改变了的正文时发送该消息。
EN_VSCROLL: 用户在垂直滚动条上单击鼠标。

Windows编程与MFC # 3 基于对话框的应用程序(1)_第15张图片

Windows编程与MFC # 3 基于对话框的应用程序(1)_第16张图片
Windows编程与MFC # 3 基于对话框的应用程序(1)_第17张图片

Windows编程与MFC # 3 基于对话框的应用程序(1)_第18张图片
“计算”按钮的ID为IDC_ADD_BUTTON,图中Commands标签下,Object IDs列表中有此ID,因为我们是想实现点击按钮后的消息处理函数,所以在Messages列表中选择BN_CLICKED消息,然后点右上方的Add Handler就可以添加BN_CLICKED消息处理函数OnClickedAddButton

在得到一个空的OnBnClickedAddButton()函数的函数体后,需要在函数体中加入自定义功能代码。
在加法计算器程序中,我们想要“计算”按钮实现的功能是,获取被加数和加数的数值,然后计算它们的和并显示到运算结果的编辑框里。那么,OnBnClickedAddButton()的函数体就应修改为:

void CAdditionDlg::OnClickedAddButton()
{
    // TODO: 在此添加控件通知处理程序代码
    // 将各控件中的数据保存到相应的变量 
    UpdateData(TRUE);
    // 将被加数和加数的加和赋值给m_dResult   
    m_dResult =m_dOperand1+m_dOperand2;
    //根据各变量的值更新相应的控件。和的编辑框会显示   
    //m_dResult的值   
    UpdateData(FALSE);   
}

按钮控件
按钮控件包括命令按钮(Button)、单选按钮(Radio Button)和复选框(Check Box)等。
命令按钮就是前面用到的狭义的按钮控件,用来响应用户的鼠标单击操作,进行相应的处理,它可以显示文本也可以嵌入位图。
按钮控件会向父窗口发送通知消息,最常用的通知消息莫过于BN_CLICKED和BN_DOUBLECLICKED了。
用户在按钮上单击鼠标时会向父窗口发送BN_CLICKED消息,双击鼠标时发送BN_DOUBLECLICKED消息。
Windows编程与MFC # 3 基于对话框的应用程序(1)_第19张图片
HBITMAP SetBitmap(HBITMAP hBitmap);
设置要在按钮中显示的位图。参数hBitmap为位图的句柄。返回值为按钮原来位图的句柄。
HBITMAP GetBitmap( ) const;
获取之前由SetBitmap函数设置的按钮位图的句柄。
void SetButtonStyle(UINT nStyle,BOOL bRedraw = TRUE);
设置按钮的风格。参数nStyle指定按钮的风格,bRedraw指定按钮是否重绘,为TRUE则重绘,否则不重绘,默认为重绘。
UINT GetButtonStyle( ) const;
获取按钮控件的风格。
void SetCheck(int nCheck);
设置按钮的选择状态。参数nCheck为0表示未选中状态,1表示选中状态,2表示不确定状态(仅用于复选框)。
int GetCheck( ) const;
获取按钮的选择状态。返回值的意义同SetCheck函数的nCheck参数。
HCURSOR SetCursor(HCURSOR hCursor);
设置要显示到按钮上的光标图。参数hCursor指定了光标的句柄。返回值为按钮原来光标的句柄。
HCURSOR GetCursor( );
获取之前由SetCursor设置的光标的句柄。

控件上的通知消息
当控件上有事件发生时,它会向父窗口发送通知消息。最常发生的事件就是鼠标单击了,此时控件会向父窗口发送BN_CLICKED消息,实际上也就是给父窗口发送WM_COMMAND消息,在wParam参数中包含有通知消息码(鼠标单击时的通知消息码就是BN_CLICKED)和控件ID,lParam参数中包含了控件的句柄。
MFC消息映射机制中的消息是由三个部分组成:消息值、wParam参数和lParam参数。

控件的消息映射宏的格式:
ON_通知消息码(nID, memberFun)
此消息映射宏应添加到BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间。
nID参数是控件的ID,memberFun参数是消息处理函数名。
例如,
ON_BN_CLICKED(IDC_BUTTON1, &CDlg::OnBnClickedButton1)
消息处理函数声明的语法形式为:
afx_msg void memberFun();
** 设置对话框控件的Tab顺序**
运行加法计算器程序,显示对话框后不进行任何操作,直接按回车,可以看到对话框退出了。这是因为“退出”按钮是Tab顺序为1的控件,也就是第一个接受用户输入的控件。
在主菜单中选择“Format”->“Tab Order”,或者按快捷键Ctrl+D,对话框模板上就会显示各个控件的Tab顺序数字。
Windows编程与MFC # 3 基于对话框的应用程序(1)_第20张图片

你可能感兴趣的:(Windows编程)