MFC编程基础教程

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第1章基于对话框的Windows应用程序
1.简介Windows编程的两种方法,即Windows API编程和MFC编程。

2.基于对话框的应用程序的创建过程:
•建立基于对话框的MFC 应用程序框架;
•放置控件;
•设置控件属性;
•为控件连接变量,即为控件命名;
•添加并且编写消息处理函数。

3.常用基本控件:
•静态文本框:主要用来显示文本信息,不能接受用户输入
•命令按钮:是最常见的、应用最广泛的一种控件。

在程序执行期间,当单击某个命令按钮后就会执行相应的消息处理函数。

•编辑框:是一个文本编辑区域,用户可以在该区域输入、编辑和显示正文内容。

•框架:将一组相关的控件框起来,达到标识一组控件的作用。

•单选按钮:用户在一组单选按钮中最多只能选择一项。

当某一项被选定后,其他选项自动变成未选状态。

•复选框:列出了可供选择的项,用户可根据需要选择其中的一项或多项,各选项之间的状态互不相关。

•列表框:通过显示多个选项,供用户选择,达到与用户对话的目的。

•组合框:组合了编辑框和列表框的特性而形成的一种控件。

在列表框中列出可供用户选择的项,当用户选定某项后,该项内容自动装入编辑框中。

•滚动条:通常附在对话框上用来协助观察数据或确定位置,也可以用来作为数据输入的工具。

1.1 Windows编程基础
Windows 应用程序的主要特点是:
•具有标准的图形用户界面。

•具有与硬件无关的特性。

•采用“消息传递,事件驱动”的运行机制。

用Visual C++ 编写Windows 应用程序主要有两种方法:一是使用Windows 提供的应用程序接口(Application Programming Interface ,API )函数;二是使用Microsoft 提供的微软基础类(Microsoft Foundation Class ,MFC )。

1.1.1 Windows API编程
从本质上来说,API 是Windows 系统支持的函数定义、参数定义和消息格式的集合,共有上千个标准的API 函数可供应用程序调用。

调用Windows API 函数的方法与调用C 语言库函数的方法基本相同。

下面通过一个简单的实例来说明Windows API 编程是如何调用API 函数的。

…………………………………………………………
# include "windows.h"
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MessageBox ( NULL," 这是一个简单的Windows 应用程序!","API 函数调用示例",MB_OK );
return 0;
}
…………………………………………………………
这是一个简单的Windows 应用程序。

Windows 应用程序的主函数是WinMain() ,不是main() 函数。

函数体中调用了Windows API 函数MessageBox() ,弹出如图所示的对话框。

在直接使用API 函数进行Windows 编程时,程序员不仅需要熟记一大堆常用的API 函数,而且还要对Windows 操作系统有深入的了解,编写大量的代码。

用这种方式即使是开发一个很简单的应用程序也需要大量的工作,直接用API 函数进行编程是需要极大的耐心和丰富的编程经验的。

1.1.2 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 )向导创建的:
(1)基于对话框的应用程序:这类程序适合于文档较少而交互操作较多的应用场合,如Windows 自带的计算器程序。

(2)单文档界面(SDI )应用程序:这类程序一次只能打开一个文档,如Windows 自带的Notepad 程序。

(3)多文档界面(MDI )应用程序:这类程序可以同时打开多个文档并进行处理,处理的过程中很容易地进行切换,如Microsoft Word 。

1.2 基于对话框的Windows应用程序
对话框是一种特殊类型的窗口,绝大多数Windows程序都通过对话框与用户进行交互。

在Visual C++中,对话框既可以单独组成一个简单的应用程序,又可以成为文档/视图结构程序的资源。

1.2.1 简单应用程序实例
创建对话框程序的步骤:
(1)建立基于对话框的MFC 应用程序框架;
(2)放置控件;
(3)设置控件属性;
(4)为控件连接变量,即为控件命名;
(5)添加并且编写消息处理函数。

【例1.1】编写一个如图所示的应用程序。

若单击“复制”按钮,则把上面的编辑框中的内容复制到下面的编辑框中;若单击“结束”按钮,则退出程序的运行。

程序的创建过程:
(1)建立基于对话框的MFC 应用程序框架。

①选择“文件| 新建”命令;
②在“工程”选项卡中,选定“MFC AppWizard(exe) ”,输入工程名称,选择“确定”。

③选定“D 基本对话”,即创建基于对话框的应用程序,选择“完成”。

(2)放置控件
•删除原有的控件。

•放置所需的控件:两个编辑框和两个命令按钮。

方法是:先单击控件工具栏上的控件图标选择所需的控件,然后在对话框设计界面上按住鼠标左键拖拉出所需要的大小后释放。

(3)设置控件属性
选定控件,在其快捷菜单中选择“属性”命令,在弹出如图所示的对话框中进行设置。

上面编辑框的属性设置为:
•选定“Multiline ”复选框,编辑框中可以输入多行文本。

•选定“Vertical scroll ”和“Auto Vscroll ”,编辑框将有垂直滚动条。

•选定“Want return ”。

下面编辑框属性的设置与上面编辑框基本一样,只是可以不选定“Want return ”。

从图中可以看到编辑框的ID 为IDC_EDIT1 ,这是该控件的标识。

任何一个控件都有一个ID ,某些函数需要通过ID 对控件进行操作。

(4)连接变量
为控件连接变量就是为控件起一个名称。

每一个控件都是一个对象,调用MFC 类库中的函数都是通过对象来实现的。

为IDC_EDIT1 连接变量m_e1 的步骤为:
①在IDC_EDIT1 编辑框的快捷菜单中选“建立类向导”,弹出“MFC ClassWiard ”对话框。

②在“Member Variables ”中,选定“IDC_EDIT1 ”,再选择“Add Variable ”命令。

③在“Add Member Variable ”对话框中输入以下的数据:
Member Variable name (内存变量名):m_e1 ;
Category (类别):Control ;
Variable type (类型):Cedit
用同样的方法再为IDC_EDIT2 连接一个变量m_e2 。

(5)添加并且编写消息处理函数。

本例要求单击“复制”按钮后上面编辑框中的内容复制到下面的编辑框中。

也就是说,在程序运行时,在“复制”按钮上发生单击事件后,Windows 向对话框发出了一个BN_CLICKED 消息,CTESTDlg 类应有一个处理该消息的函数。

添加和编写这个消息处理函数的过程是:
①双击“复制”按钮,弹出的“Add Member Function ”对话框,输入函数名(缺省函数名为OnButton1 ),选择“确定”按钮后,添加了一个空函数。

另一个方法是在“MFC ClassWiard ”对话框“Message Maps ”选项卡中,选定IDC_BUTTON1 和BN_CLICKED 消息,然后选择“Add Function ”按钮即可。

添加的空函数如下:
void CTESTDlg::OnButton1()
{
// TODO: Add your control notification handler code here
}
②为void CTESTDlg::OnButton1() 添加代码
void CTESTDlg::OnButton1()
{
// TODO: Add your control notification handler code here
m_e1.SetSel(0,-1); // 选定编辑框m_e1 中的所有内容
m_e1.Copy(); //把编辑框m_e1 中选定的内容复制到剪贴板
m_e2.SetSel(0,-1); // 选定编辑框m_e2 中的所有内容
m_e2.Paste(); // 将剪贴板中内容粘贴到编辑框m_e2 中,替换所有选定的内容
}
用同样的方法为“结束”按钮添加、编写如下的消息处理函数:
void CTESTDlg::OnButton2()
{
// TODO: Add your control notification handler code here
CDialog::OnOK(); // 退出对话框程序
}
1.2.2 对话框应用程序框架
用AppWizard 创建基于对话框的应用程序框架(假定工程名为TEST )后,项目工作区上增加了一个“ResourceView ”选项卡,中间是对话框设计界面,右边是控件工具栏。

1.ResourceView
在Visual C++ 中,与用户进行交互的对话框界面被认为是一种资源。

展开“Dialog ”,可以看到有一个ID 为IDD_TEST_DIALOG 的资源,对应中间的对话框设计界面。

不管在何时,只要双击对话框资源的ID ,对话框设计界面就会显示在中间。

2.ClassView
在ClassView 中,如图所示,可以看到生成了3 个类:CAboutDlg 、CTESTApp 和CTESTDlg 。

(1)CAboutDlg :对应生成的版本信息对话框。

(2)CTESTDlg :对话框类,从Cdialog 继承过来的,在程序运行时看到的对话框就是它的一个具体对象。

(3)CTESTApp :应用程序类,从CWinApp 继承过来,封装了初始化、运行、终止该程序的代码。

3.对话框设计界面
对话框设计界面是进行对话框设计的地方,可以将各种控件放置在这里。

4.控件工具栏
控件工具栏上有26 个控件图标,可以通过这些图标在对话框上设计出所需的控件。

1.3 静态文本框、命令按钮和编辑框
静态文本框、命令按钮和编辑框是Windows应用程序中最基本的控件。

静态文本框是CStatic类的对象,命令按钮是CButton类的对象,编辑框是CEdit类的对象。

这三个类都是从CWnd类直接派生来的,具有CWnd类的全部功能。

1.3.1 静态文本框
静态文本框是最简单的控件。

它主要用来显示文本信息,不能接受用户输入,一般不需要连接变量,也不需要处理消息。

静态文本框的重要属性有:
(1)ID :所有静态文本框的缺省ID 都是IDC_STA TIC ,一般不需要重新设置。

(2)标题:需要显示的文本信息是在这里设置的。

(3)边框:边框属性在Styles 选项卡中,决定是否带有边框。

1.3.2 命令按钮
命令按钮是最常见的、应用最广泛的一种控件。

在程序执行期间,当单击某个命令按钮后就会执行相应的消息处理函数。

命令按钮的主要属性是标题属性,该属性用来设置在命令按钮上显示的文本。

命令按钮一般不需要连接变量。

命令按钮能处理的消息是BN_CLICKED 。

1.3.3 编辑框
1. 属性设置
编辑框的属性主要在Styles 选项卡中设置。

重要属性有:
(1)Multiline :定义该编辑框为多行文本框。

(2)Number :限定输入的字符只能是数字字符。

(3)Border :为控件创建边界。

(4)Read-only :编辑框成为只读的,禁止用户编辑。

2. 成员函数
编辑框常用的成员函数见表。

此外编辑框还可以使用CWnd 类的成员函数。

CWnd 类的重要成员函数有:
(1)获取编辑中的内容
形式 1 :void GetWindowText( CString& rString ) const;
说明:将编辑框中的内容复制到CString 类对象rString 中。

示例:将编辑框m_e 中的内容复制到CString 类对象ch 中。

CString ch;
m_e.GetWindowText(ch);
形式 2 :int GetWindowText( LPTSTR lpszStringBuf, int nMaxCount ) const;
说明:将编辑框中的内容复制到lpszStringBuf 中,最多复制nMaxCount 个字符。

lpszStringBuf 是字符数组或字符指针。

示例:将编辑框m_e 中的内容复制到字符数组ch 中。

char ch[80];
m_e.GetWindowText(ch,80);
(2)设置编辑框中的内容
形式:void SetWindowText( LPCTSTR lpszString );
说明:将lpszString 中的内容替换编辑框中原有内容,lpszString 是字符数组或字符指针。

示例:设置编辑框中的内容为“abcdefg ”
char ch[20]="abcdefg";
m_e.SetWindowText(ch);
3. 连接变量
编辑框在连接变量时,除了要指定变量名之外,还要确定变量类别。

变量类别有两个可选择:一是Control,意味着该变量作控件使用,对应的变量类型只能是Cedit,可以使用该控件类的成员函数;二是Value,意味着该变量当作C/C++中普通的变量使用,对应的变量类型有CString、int、double等,可以使用这些数据类型的函数,但是不能使用控件的成员函数。

若一个编辑框连接了一个Value类别的变量,则该变量就表示这个编辑框,编辑框中显示的内容就是变量的值。

但是,改变了编辑框的内容并不会自动更新对应的变量的值,同样,改变了变量的值也不会自动刷新编辑框的内容。

若要保持一致,需要使用UpdateData()函数更新,如图所示。

若编辑框的内容改变了,则应使用语句UpdateData(TRUE);更新对应的变量的值;若变量的值改变了,则应使用语句UpdateData(FALSE);刷新编辑框的内容。

4. 消息处理函数
在编辑框能处理的消息中是最重要的是EN_CHANGE ,这是编辑框中的文本被修改后发出的消息。

【例1.2】输入一元二次方程ax2 +bx+c=0 的系数a 、b 、c ,计算并输出两个根x1 、x2 ,如图所示。

求方程的根
对话框上有5个静态文本框、5个编辑框和2个命令按钮。

编辑框按表连接变量,其余控件不需要连接变量。

为了要计算b2 -4ac 的平方根,需要使用sqrt() 函数,因此在TESTDlg.cpp 文件的开始添加了文件包含命令:
#include "math.h" // "计算"按钮的函数
…………………………………………………………
void CTESTDlg::OnCalc()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
double a=m_a;
double b=m_b;
double c=m_c;
m_x1=(-b+sqrt(b*b-4*a*c))/(2*a);
m_x2=(-b-sqrt(b*b-4*a*c))/(2*a);
UpdateData(FALSE);
}
// “结束”按钮的函数
…………………………………………………………
void CTESTDlg::OnOk()
{
// TODO: Add your control notification handler code here
CDialog::OnOK(); //OnOK();
}
…………………………………………………………
【例1.3】字符串转换程序
转换规则为:大写字母转换成小写;
将小写字母转换成大写;
换行符和回车符不变;
其余字符转换为“*”
要求:每输入一个字符立即转换
第1个编辑框连接变量m_e1 (Control )
属性选定:Multiline
Vertical scroll
Auto VScroll(在多行控件中,当用户在最后一行按下ENTER键时自动向上滚动文本) Want return(使多行编辑器接收回车键,表示换行。

如果不指定,按回车键会选择缺省的命令按钮,这往往会导致对话框的关闭)
第2个编辑框连接变量m_e2 (Control )
属性选定:Multiline
Vertical scroll
Auto VScroll
Read-only
对第1个编辑框添加EN_CHANGE 消息处理函数
void CTESTDlg::OnChangeEdit1()
{
// TODO: Add your control notification handler code here
char s[80];
m_e1.GetWindowText(s,80);
for(int i=0;s[i]!='\0';i++)
if (s[i]>='A' && s[i]<='Z')
s[i]=s[i]+'a'-'A';
else
if(s[i]>='a' && s[i]<='z')
s[i]=s[i]+'A'-'a';
else
if (s[i]=='\n' || s[i]=='\r')
s[i]=s[i];
else
s[i]='*';
m_e2.SetWindowText(s);
}
1.4 框架、单选按钮和复选框
框架、单选按钮和复选框都是对话框的常见控件。

框架与静态文本框一样是CStatic类的对象,单选按钮和复选框与命令按钮一样都是CButton类的对象。

1.4.1 框架
当对话框上控件较多时,可以使用框架将一组相关的控件框起来,达到标识一组控件的作用。

框架不需要连接变量,也不需要处理消息。

框架的重要属性有:
(1)ID :所有框架的缺省ID 都是IDC_STATIC ,不需要重新设置。

(2)标题:该属性决定框架上的标题文本。

1.4.2 单选按钮
1. 设计要求
同一组中的按钮必须一个接一个地放进对话框中,中间不能插入其他控件,并且一个组的第一个按扭要选中“Group”属性,表示一组控件的开始。

2. 重要属性
(1)ID :每个命令按钮都有一个缺省ID ,如IDC_RADIO1 ,可以重新设置。

(2)标题:该属性值就是单选按钮右边显示的文本标题。

(3)Group :一组中第一个按钮选中该属性,表示它是一组的开始。

3. 消息
单选按钮能处理的消息是BN_CLICKED。

4. 重要函数
(1)设定单选按钮选中状态
初始时,可使用Windows API 函数CheckRadioButton() 设定一组单选按钮中选中的按钮。

形式:void CheckRadioButton(int nIDFirstButton, int nIDLastButton, int nIDCheckButton);
说明:
①nIDFirstButton 是一组中第一个单选按钮的ID ;
②nIDLastButton 是一组中最后一个单选按钮的ID ;
③nIDCheckButton 为初始时设置为选中的那个单选按钮的ID 。

(2)判定单选按钮是否被选定
形式:UINT IsDlgButtonChecked( int nIDButton ) const;
说明:如果ID 为nIDButton 的按钮被选定,则该函数的返回值为true ,否则为false 。

【例 1.4】设计一个如图所示的程序。

当单击“确定”后,用AfxMessageBox 函数显示一个如图所示的消息框。

(1)界面设计
首先创建一个对话框程序框架,然后放置各控件,进行属性设置,将编辑框连接到Cstring 类型的m_e 变量,其余控件不需要连接变量。

将“男”和“教授”对应的单选钮的Group属性勾上。

(2)初始化
单选按钮的初始化工作在对话框的初始化函数实现。

BOOL CTESTDlg::OnInitDialog()
{

CheckRadioButton(IDC_RADIO1, IDC_RADIO2, IDC_RADIO1);
CheckRadioButton(IDC_RADIO3, IDC_RADIO5, IDC_RADIO3);

};
(3)消息处理函数
void CTESTDlg::OnButton1()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
CString s;
s+=m_e;
if(IsDlgButtonChecked(IDC_RADIO1))
s+=" 男";
else
s+= " 女";
if(IsDlgButtonChecked(IDC_RADIO3))
s +=" 教授";
else if(IsDlgButtonChecked(IDC_RADIO4))
s+= " 副教授";
else
s+= " 讲师";
AfxMessageBox(s);
}
1.4.3 复选框
1. 重要属性
(1)ID :每个复选框都有一个缺省ID ,如IDC_CHECK1 ,可以重新设置。

(2)标题:该属性值决定了复选框右边显示的文本标题。

2. 连接变量
复选框通常被连接到Value类别BOOL类型的变量。

3. 消息
复选框能处理BN_CLICKED 消息。

【例5】设计一个如图所示的程序。

当单击“确定”后,在右边的编辑框中显示有关信息。

复选框应用示例
4. 界面设计
首先创建一个对话框程序框架,然后放置各控件,进行属性设计,各编辑框和复选框按表连接变量,其余控件不需要连接变量。

5. 消息处理函数
void CTESTDlg::OnButton1()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
CString s;
s=m_e1;
s+= " 爱好:";
if (m_c1) s+=" 旅游";
if (m_c2) s+= "运动";
if (m_c3) s+= " 音乐";
m_e2=s;
UpdateData(FALSE);
}
1.5 列表框和组合框
列表框是CListBox类的对象,组合框是CComboBox的对象。

1.5.1 列表框
1. 属性设置
列表框的属性在如图所示的属性窗口中设置。

重要的属性有:
(1)Selection
该属性决定用户的选择方式,缺省值为Single 。

属性值有:
Single ──单项选择
Multiple ──多项选择,但是忽略Ctrl 和Alt 键。

Extended ──允许使用Ctrl 和Alt 进行多项选择
None ──禁止选择
(2)Sort
当该属性被选定后,列表框中的选项按字母顺序排列。

2. 常用成员函数
(1)添加项目
格式:int AddString( LPCTSTR lpszItem );
例如:语句m_l. AddString(" 陈蓉") ;把“陈蓉”添加到了列表框m_l 中。

(2)删除项目
格式:int DeleteString( UINT nIndex );
说明:nIndex 表示被删除项目在列表框中的位置,对于第一个选项,nIndex 应为0 。

例如:语句m_l. DeleteString (4) ;删除列表框中的第 5 个项目。

(3)获取当前被选定的项目的序号
格式:int GetCurSel( ) const;
例如:语句int I=m_l.GetCurSel(); 将使I 获得m_l 列表框中当前选定的项目的序号。

(4)获取列表框中指定的项目
格式 1 :int GetText( int nIndex, LPTSTR lpszBuffer ) const;
格式 2 :void GetText( int nIndex, CString& rString ) const;
说明:将列表框中第nIndex 个选项的文本送到lpszBuffer 或rString 中。

例如:假定有说明语句char s1[20]; CString s2; ,则语句m_l. GetText(4, s1); 和m_l. GetText(4, rString); 把第5 项内容分别送到s1 和s2 中。

【例1. 6】编写一个能对列表框进行项目添加、修改和删除操作的应用程序,如图所示。

“添加”按钮的功能是将文本框中的内容添加到列表框,“删除”按钮的功能是删除列表框中选定的选项。

如果要修改列表框,则首先选定选项,然后单击“修改”按钮,所选的选项显示在文本框中,当在文本框中修改完之后再单击“修改确定”按钮更新列表框。

列表框应用示例
(1)界面设计
首先创建一个对话框应用程序框架,然后放置按钮。

列表框和命令按钮按表连接变量,其余控件不需要连接变量。

(2)初始化
列表框的选项在对话框的初始化函数中用AddString 函数添加。

BOOL CTESTDlg::OnInitDialog()
{

// TODO: Add extra initialization here
m_l.AddString(" 大学计算机基础");
m_l.AddString("C/C++ 程序设计");
m_l.AddString("VB 程序设计");
m_l.AddString(" 软件技术基础");

}
(3)消息处理函数
…………………………………………………………
void CTESTDlg::OnButton1() // 选择“添加”后执行的函数
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_l.AddString(m_e);
m_e="";
UpdateData(FALSE);
}
…………………………………………………………
void CTESTDlg::OnButton2() // 选择“删除”后执行的函数
{
// TODO: Add your control notification handler code here
int n=m_l.GetCurSel();
m_l.DeleteString(n);
}
…………………………………………………………
void CTESTDlg::OnButton3() // 选择“修改”后执行的函数
{
// 将选定的项目送编辑框供修改
// TODO: Add your control notification handler code here
CString s;
int n=m_l.GetCurSel();
m_l.GetText(n,s);
m_e=s;
UpdateData(FALSE);
}
…………………………………………………………
void CTESTDlg::OnButton4() // 选择“确定修改”后执行的函数
{
// 将修改后的项目送回列表框中,替换原项目,实现修改。

// TODO: Add your control notification handler code here
UpdateData(TRUE);
int n=m_l.GetCurSel();
m_l.DeleteString(n);
m_l.InsertString(n,m_e);
m_e="";
UpdateData(FALSE);
}
…………………………………………………………
1.5.2 组合框
1. 属性设置
(1)类(Type )
该属性用于指定组合框的类型,共有三个选择:Simple 、Dropdown 和Droplist ,默认值为Dropdown 。

(2)键入列表框项(Enter listbox items )
在列表框的属性窗口“Data ”选项卡中有一个键入列表框项,这是在设计阶段输入选项的地方,如图所示。

每当输入一项后按Ctrl+Enter 键才能输入下一项。

(注意在设计ComboBox时,点下向下箭头,然后将控件下边向下拉,之后才输入数据,这样才能显示出ComboBox的下拉的项。

或者,在新建该控件时往下拖放足够大的区域)
组合框属性窗口Data选项卡
2. 常用成员函数
编辑框和列表框的成员函数几乎都可以用于组合框,但是列表框的成员函数GetText() 在组合框中的是GetLBText() 。

形式 1 :int GetLBText( int nIndex, LPTSTR lpszText ) const;
形式 2 :void GetLBText( int nIndex, CString& rString ) const;
说明:使用GetLBText 函数可以将组合框中的第nIndex 个项目的文本送入lpszText 或rString 中。

3. 组合框发出的消息
(1)CBN_SELECTCHANGE :组合框的列表框中的选项改变时发送。

(2)CBN_EDITCHANGE :组合框的编辑框中文本改变时发出。

【例1.7】设计一个如图所示的对话框。

如果单击“确定”按钮,则用MessageBox 显示如图所示的信息框。

(1)首先创建一个对话框程序框架,然后放置各控件,进行属性设置,组合框的选项在设计阶段直接输入,按表连接变量,其余控件不需要连接变量。

(2)消息处理函数
void CTESTDlg::OnButton1()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
CString s;
s=" 品牌:";
s=s+m_c;
s=s+"\n";
s=s+" 数量:";
s=s+m_e;
MessageBox(s);
}
1.6 滚动条
滚动条是CScrollBar 类的对象,是Windows 应用程序中一个很重要的控件,通常附在对话框上用来协助观察数据或确定位置,也可以用来作为数据输入的工具。

滚动条有水平和垂直两种。

【例8】建立一个水平滚动条,最小值为0 ,最大值为100 ,单击滚动条两端箭头时滑块移动的增量值为 2 ,单击滚动条中的空白处(滑块与两端箭头之间的区域)时滑块移动的增量值为10 。

另有一个只读的编辑框,显示了滑块当前位置所代表的值。

假定工程名为TEST 。

1 .界面设计
首先创建一个对话框应用程序框架,然后放置水平滚动条、编辑框,按表连接变量,编辑框设置为只读。

2 .初始化
滚动条的初始化就是设置最小值,最大值,以及初始时滑块所代表的值。

滚动条初始化在对话框的初始化函数中完成,涉及两个函数:
(1)设置最大值和最小值
形式:void SetScrollRange(int nMinPos , int nMaxPos , BOOL bRedraw = TRUE);
说明:nMinPos 表示最小值,nMinPos 表示最大值。

当bRedraw 为TRUE 时
重画滚动条。

(2)设置滑块的位置
格式:int SetScrollPos( int nPos , BOOL bRedraw = TRUE );
说明:nPos 表示滑块的位置。

当bRedraw 为TRUE 时重画滚动条。

滚动条初始化代码如下:
BOOL CTESTDlg::OnInitDialog()
{

// TODO: Add extra initialization here
m_s.SetScrollRange(0,100);
m_s.SetScrollPos(50);
m_e=50; // 初始时,编辑框显示50 。

UpdateData(FALSE); // 更新编辑框显示的内容。


};
3 .编写消息处理函数
当用户在滚动条上进行操作时,滚动条接收不到任何消息。

但是对话框却能接收到WM_Hscroll (水平滚动条)或WM_Vscroll (垂直滚动条)消息,也就是说,程序对滚动条的操作只能在OnHScroll() 或OnVScroll() 中编写代码。

滚动条处理WM_Hscroll 消息的函数为:
void CTESTDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
Cdialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
做如图选择,点击“add and Edit”就把OnHScroll函数添加进去。

说明:
①pScrollBar 指向用户正在进行操作的滚动条。

②nPos 表示滑块当前的位置。

③nSBCode 指示用户正在进行的操作,其取值及其意义见表。

程序代码:
…………………………………………………………
void CTestDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{ // TODO: Add your message handler code here and/or call default
if (pScrollBar==&m_s)
{ int iNowPos;
switch(nSBCode)
{ case SB_THUMBTRACK: // 拖动滚动滑块时
m_s.SetScrollPos(nPos);
m_e=nPos;
break;
case SB_LINELEFT : // 单击滚动条向左的箭头
iNowPos=m_s.GetScrollPos(); // 获取滑块当前位置所代表的值
iNowPos=iNowPos-2;
if(iNowPos<0)
iNowPos=0;
m_s.SetScrollPos(iNowPos);
m_e=iNowPos;
break;
case SB_LINERIGHT : // 单击滚动条向右的箭头
iNowPos=m_s.GetScrollPos(); // 获取滑块当前位置所代表的值
iNowPos=iNowPos+2;
if(iNowPos>100)
iNowPos=100;
m_s.SetScrollPos(iNowPos);
m_e=iNowPos;
break;
case SB_PAGELEFT : // 单击滚动条左边的箭头与滑块之间的区域
iNowPos=m_s.GetScrollPos(); // 获取滑块当前位置所代表的值
iNowPos=iNowPos-10;
if(iNowPos<0)
iNowPos=0;
m_s.SetScrollPos(iNowPos);
m_e=iNowPos;
break;
case SB_PAGERIGHT : // 单击滚动条右边的箭头与滑块之间的区域
iNowPos=m_s.GetScrollPos(); // 获取滑块当前位置所代表的值
iNowPos=iNowPos+10;
if(iNowPos>100)
iNowPos=100;
m_s.SetScrollPos(iNowPos);
m_e=iNowPos;
break;
}
}
UpdateData(FALSE);
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
…………………………………………………………
说明:
(1)由于对话框上可能有多个滚动条,因此函数首先需要根据指针pScrollBar 确定事件发生在哪一个滚动条上,方法是使用表达式pScrollBar==&m_s 。

因为,pScrollBar 指向发生事件的滚动条,所以这个表达式为真时,意味着用户对滚动条m_s 进行了操作。

(2)用户对滚动条的操作有 5 种,因此函数中必须以这 5 种情况分别进行处理。

1.7 程序举例
对话框是Windows 应用程序中最常用的一种与用户交互的方式。

用户通过对话框输入数据,程序通过对话框显示执行的情况。

【例 1.9】设计如图所示的对话框。

若选定了“日期”或“时间”复选框,则在对应
的只读编辑框中显示系统当前日期或时间。

分析: CTime 是 MFC 中的一个类,封装了日期和时间。

它有一个静态成员 GetCurrentTime() ,返回系统当前的日期和时间。

实现:
(1)界面设计
首先创建一个对话框程序框架,然后放置各控件,按表进行属性设置和连接变量。

(2)消息处理函数
…………………………………………………………
void CTESTDlg::OnCheck1()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
if(m_k1==TRUE)
{ CTime time=Ctime::GetCurrentTime();
m_e1=time.Format("%Y.%m.%d"); // 构造“ YYYY.MM.DD ”形式的日期字符串
}
else
m_e1="";
UpdateData(FALSE);
}
…………………………………………………………
void CTESTDlg::OnCheck2()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
if(m_k2==TRUE)
{ CTime time=Ctime::GetCurrentTime();
m_e2=time.Format("%I:%M:%S"); // 构造“HH:MM:SS ”形式的时间字符串
}
else
m_e2="";
UpdateData(FALSE);
}
…………………………………………………………
【例1.10】设计如图所示的对话框。

单击“确定”按钮后,在列表框中显示选择的信息。

(1)界面设计
首先创建一个对话框程序框架,然后放置各控件,按图所示设置属性和连接变量。

其中,m_e2 编辑框设置为只读,组合框和列表框取消排序属性。

(2)初始化
组合框的选项在设计阶段输入,其余控件的初始化在对话框的初始化函数中完成。

BOOL CTESTDlg::OnInitDialog()
{

// TODO: Add extra initialization here
CheckRadioButton(IDC_RADIO1, IDC_RADIO2, IDC_RADIO1);
m_sc.SetScrollRange(0,30);
m_sc.SetScrollPos(10);
m_e2=10;
UpdateData(FALSE);

}
(3)滚动条消息处理函数
请参照滚动条部分自己完成。

为了不影响其它控件,应开始处添加命令:
UpdateData(TRUE);
(4)命令按钮的消息处理函数
…………………………………………………………
void CTESTDlg::OnButton1()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); // 用各控件中的值更新对应的连接变量
m_l.ResetContent(); // 删除列表框中所有的内容
m_l.AddString(m_e1);
if(IsDlgButtonChecked(IDC_RADIO1))
m_l.AddString(" 男");
else
m_l.AddString(" 女");
if (m_c1) m_l.AddString(" 旅游");
if (m_c2) m_l.AddString(" 运动");
if (m_c3) m_l.AddString(" 音乐");
CString s;
s.Format("%d",m_e2); // m_e2 是int 类型,将它转换成字符串
m_l.AddString(s);
m_l.AddString(m_conb);
}
…………………………………………………………
第2章文档/视图结构应用程序
1. 文档/视图结构的思想是将数据的管理与显示分离,其中文档用于管理应用程序的数据,而视图是用户界面,用于显示、打印文档中的数据,并管理与用户的交互。

2. SDI具有文档/视图结构的应用程序框架,该框架包括应用程序类、窗口框架类、文档类和视图类,编程的任务是在文档类和视图类中添加适当的代码。

其中文档类中一个重要的成员函数是OnNewDocument(),用户在此添加代码完成对数据的初始化;而视图类中最重要的成员函数是OnDraw(),通过在该函数中添加代码实现窗口内容的输出。

3. 通过介绍几种SDI结构的典型应用程序来了解其结构及设计方法,典型应用包括:
•利用画笔、画刷等工具及位图处理的方法实现文字和图形的输出。

•利用定时器控件制作动画程序。

•对鼠标和键盘进行编程的基本方法。

•文件、字体、颜色等几种通用对话框的使用方法及自定义对话框的设计、调用方法。

•菜单的设计方法。

相关文档
最新文档