第5章MFC编程基础.docx
- 文档编号:29394511
- 上传时间:2023-07-23
- 格式:DOCX
- 页数:42
- 大小:905.22KB
第5章MFC编程基础.docx
《第5章MFC编程基础.docx》由会员分享,可在线阅读,更多相关《第5章MFC编程基础.docx(42页珍藏版)》请在冰豆网上搜索。
第5章MFC编程基础
第5章MFC编程基础
教学提示:
在VisualC++集成开发环境下,利用Microsoft的基础类库MFC(Microsoft
FoundationClass),可以开发出功能强大的Windows应用程序。
VisualC++提供的应用程序
生成向导AppWizard等工具创建应用程序框架,便于快速掌握和学习程序设计方法。
教学目标:
通过对关于Windows图形下的窗口、消息机制、事件等基本概念的学习,
同时掌握VisualC++开发工具的基本原理、开发环境及一般的使用方法,逐步提高实践操
作和独立编程的能力。
5.1Windows编程基础
MicrosoftWindows是一个应用于个人计算机上的图形化用户界面的操作系统,它为
应用程序提供了一个由窗口和菜单结构构成的多任务环境。
Windows的程序设计语言,包
括VisualC++、VisualBasic、Java等,都被称为“面向对象(ObjectOriented)”的程序设计
语言。
在Windows编程中“对象(Object)”是指Windows的规范部件,包括各种窗口、菜
单、按钮、对话框及程序模块等。
MFC提供了开发Windows程序的类框架结构。
VisualC++的集成开发环境会自动生成
许多代码,而且可以在继承某些类的基础上开发出符合实际需要的类。
当然,由于MFC
庞大而且复杂,所以在学习中会有一些难度。
开始学习MFC类框架之前,有必要先来了解一些Windows的编程概念。
5.1.1Windows操作系统的技术特点
在Windows版本系列中,其下列技术特点是始终坚持并不断发展的。
1.标准的用户接口
在所有的Windows技术特点中,标准的图形接口是用户最熟悉的,也是最受欢迎的。
所有的Windows程序都具有相似的外观和相同的标准控件,使用户不需要长期的学习就
可使用新开发的软件。
随着Windows的进化,用户界面也在不断地丰富,越来越方便
用户。
2.多任务
支持多任务是Windows的另一成功之处,用户可以在操作系统下同时运行多个应用程
序,可以随时在屏幕上移动窗口、改变其大小、在窗口间切换,还可以在窗口间交换信息。
在多任务操作系统出现之前,应用程序独占计算机的全部资源,其中包括输入输出设备、
内存和显示器设备甚至CPU本身,但在Windows系统中,这些资源是共享的。
3.优秀的内存管理
用过DOS的用户一定记得640KB的常规内存。
在DOS环境下,如果要编制一个大于
640KB的应用程序,程序员就要优化内存,甚至自己编写内存管理程序。
但在Windows
下,内存是重要的共享资源。
对于如此重要的资源,则是由Windows自己管理的。
Windows
通过在内存中移动代码和数据,收集碎块,构成大的自由内存块。
此外,Windows还有许
多技术共享内存,例如用动态链接库。
对于用户来说,内存是平坦的(FlatMemory)。
因此,
用户不必像在DOS下编程时那样考虑段的问题,只需提出内存分配要求,其他交给
Windows操作系统,即可得到答复。
4.设备独立性
Windows提供的另一个主要功能是应用程序对硬件设备的独立性。
随着电子技术、计
算机技术的发展,硬件设备的发展速度越来越快,应用程序必须面向不断变化的众多硬件
设备。
在非Windows应用程序中必须包括预计使用的所有设备的驱动程序,其中最主要的
是显示设备和打印设备,这极大地影响了软件的开发效率。
Windows在这方面解放了程序
设计人员,在Windows下,显示器、打印机、键盘以及鼠标的驱动程序只需安装一次就可
以支持各个应用程序。
软件开发人员可以使用Windows提供的通用接口,这就消除了程序
设计中大量的重复劳动。
以上是Windows的主要技术特点,此外Windows还有许多其他的技术,如网络功能、
多媒体功能以及功能丰富的用户管理工具等。
可以说Windows充分利用了PC的资源,同
时也赋予了PC强大的活力。
5.1.2事件驱动模式
Windows的程序设计方法是事件驱动的。
事件驱动程序设计是一种全新的程序设计方
法。
它不是由事件的顺序来控制,而是由事件的发生来控制,而这种事件的发生是随机的、
不确定的,并没有预定的顺序,这样就允许程序的用户用各种合理的顺序来安排程序的流
程。
对于需要用户交互的应用程序来说,事件驱动的程序设计有着过程驱动方法无法替代
的优点。
它是一种面向用户的程序设计方法,它在程序设计过程中除了完成所需功能之外,
更多地考虑了用户可能的各种输入,并针对性地设计相应的处理程序。
它是一种“被动”
式程序设计方法。
程序开始运行时,处于等待用户输入事件状态,然后取得事件并做出相
应反应,处理完毕又返回并处于等待事件状态。
所谓事件,简言之,就是对操作系统而言所发生的“事情”。
这种“事情”可以由系
统产生,也可以由用户或者硬件设备产生。
最常见的是鼠标事件,包括鼠标移动,鼠标左
右键的单击、双击,鼠标位于窗口的位置等。
针对鼠标的不同事件,可以通过相应的处理
程序来响应,如图5.1所示。
图5.1事件驱动程序模型
5.1.3消息处理机制
Windows操作系统将包含用户输入在内的各种事件,以消息的形式发送到目标,目标系
统再根据消息的具体内容进行相应的处理。
一般来讲,只有窗口才可以接收消息。
例如,当
用户在窗口中移动鼠标时,窗口将得到一个WM_MOUSEMOVE消息。
对这个消息的处理
并不需要用户来干预,它几乎全部传递给操作系统来进行处理,由操作系统在新位置上重绘
鼠标。
当用户单击某个命令按钮时,窗口将得到一个鼠标按钮的WM_LBUTTONDOWN的
消息,此时用户需要在这个按钮中添加代码对这个消息进行处理。
事件驱动围绕消息的产生与处理展开,一条消息是关于发生事件的消息。
MFC类中是
以消息来实现窗口间的相互通信。
共有三种类型的消息:
标准的窗口(Window)消息、命令
(Command)消息和控件通知(ControlNotification)消息,并且这些消息既可以发送(sent),也
可以寄送(post)。
1.标准的窗口消息
标准的窗口消息分为三类:
(1)键盘消息:
和键盘的某个键的动作相关。
(2)鼠标消息:
涉及鼠标的单击、双击、拖动等动作。
(3)窗口消息:
创建、绘制、移动和销毁窗口等动作。
所有标准窗口消息都是以WM_为前缀的,如关于鼠标消息WM_LBUTTONDOWN、
WM_LBUTTONUP、WM_MOUSEMOVE分别表示按下鼠标左键、释放鼠标左键、鼠标移
动所生成的消息。
2.控件消息
在VisualC++中,控件消息是指控件或其他子窗口发送WM_COMMAND消息或控件
类所发送的消息。
发送控件消息的控件在VisualC++中使用唯一的ID号来进行标识,使用
控件消息来操纵。
3.命令消息
命令消息是指菜单项、工具栏按钮、加速键等用户界面对象发送的WM_COMMAND
消息。
它和控件消息的区别在于:
控件消息只能由特定控件向Windows系统传送,而命令
消息是由用户界面对象发送的,它可以被更多的对象处理。
发送消息时,直接调用窗口的窗口进程。
通信是即时的,直到窗口进程为调用函数返
回一个结果后,应用程序才能继续。
寄送消息时,把消息发送到拥有那个窗口的应用程序
消息队列中。
一有空闲,应用程序就搜索消息队列,并在消息队列中处理消息,即从队列
中删除它们,并将它们发送到既定窗口。
通信将可能延迟,直到目标应用程序获得处理消
息的时间。
调用函数发送消息后即返回,但结果只是表示消息寄送成功与否,而不是被调
用窗口进程的结果,如图5.2所示。
图5.2发送消息和寄送消息
鼠标和键盘消息通常是寄送的,而所有其他消息通常都是发送的。
在消息队列中,寄
送的消息接受特殊的鼠标和键盘处理。
通常,应该尽量发送一个消息,除非想把动作延迟
到所有鼠标和键盘消息被处理之后。
5.1.4窗口
1.窗口的概念
窗口是屏幕上的一个矩形区域,应用程序在该区域中显示数据并等待鼠标点击。
Windows应用系统的用户界面可以包含许多窗口,每个窗口都有不同的特点,但都是互相
联系的,如图5.3所示。
图5.3Windows应用程序用户界面包括的窗口
这么多窗口中,基本类型只有三种:
重叠窗口(建立应用程序的主窗口)、弹出窗口(对
话框或消息框)和子窗口(控件窗口)。
在它们之间并没有太多内在的差异,但是使用不同的
窗口风格,它们的外观是不同的。
重叠窗口通常用于建立应用程序主窗口。
事实上,有时也叫做“主”窗口或者“框架”
窗口。
2.应用程序接口(API)
每个窗口代表内存中的一个窗口对象,并由该窗口对象告诉Windows操作系统将窗口
绘制在何处,以及在对鼠标单击、键盘按下(假设该窗口拥有输入焦点)和时钟终止等事件
作出响应时应调用什么应用程序。
窗口对象自身是窗口类的一个实例,它不是VisualC++
的类,而是存在于VisualC++之外,并早于VisualC++的MicrosoftWindows所属的类。
然
而,就像C++的类一样,窗口类为每个基于它创建的窗口定义了若干特征,如背景色和往
何处发送消息等。
Windows操作系统提供了一个扩展的应用程序接口(API),可以用来创建和维护这些
窗口对象。
调用CreateWindow()函数可以创建一个窗口对象;调用SetWindowLong()
函数可以改变由窗口类定义的特征;调用MoveWindow()函数可以移动窗口;调用
DestroyWindow()可以退出窗口。
如此说来,MFC又能做些什么呢?
MFC窗口是C++和WindowsAPI调用的综合。
事实上,MFC窗口提供了许多(但不是
全部)WindowsAPI的C++封装,从而减轻了编写Windows应用程序时一些乏味的工作,
并提供了一些新的服务。
MFC窗口不对窗口对象进行直接控制,而在API环境中却是可以的。
如果不能在API
环境中实现某项功能,那么肯定也不能在MFC环境中实现。
举例来说,MFC库的CWnd
可以创建一个窗口,但它只是过去在API环境中使用的API调用的封装。
5.2MFC基础
5.2.1MFC概述
1.MFC的发展历史
1992年4月,第一个MFC(MicrosoftFoundationClass)版本即MFC1.0,伴随着Microsoft
C/C++5.0版一起发布。
当时的MFC1.0中主要包括两种类型的类:
一种是用于应用程序
中非图形部分的类和用于应用程序的图形用户界面(GraphicsDeviceInterface,GDI)功能的
Windows相关类。
1993年2月,MFC2.0伴随着VisualC++1.0版一起发布。
扩展后的核心功能在原有
的基础上又增添了一些新的构造类,这些构造类有助于组织和构造应用程序,以及对
Windows应用程序中部分界面元素的高层抽象,这些高层抽象有助于程序员优化界面,使
得应用程序更易操作。
1993年12月,MFC与VisualC++1.5一起发布。
这一版本的MFC添加了与数据库进
行链接的ODBC(OpenDataBaseConnection,开放数据库互联)数据库类,ODBC数据库类
允许应用程序访问具有ODBC驱动程序的数据库中的数据。
程序员可以通过ODBC对某
些数据源进行存取,并且这一版本的MFC还全面支持OLE的众多性能,不过这一版本的
MFC是基于16位的应用程序而开发的。
1994年9月,MFC3.0作为VisualC++2.0的一部分公开发布,这个版本的MFC增添
了对开发32位应用程序的支持,具有丰富的用户界面风格,以及对Win32API和OLEControl扩展的更多支持。
MFC3.0将MFC的影响扩展到大多数基于Win32应用程序的核心底层结构。
随后的两个版本中又添加了对Windows公共控件和Sockets等的支持。
1995年10月推出的MFC4.0中包括了在Windows95和WindowsNT操作系统中大
多数新的Windows公共控件,它能进一步支持OLE(ObjectLinkingandEmbedding,对象链
接和嵌入)的扩展功能,开发人员可以建立、使用并且可以和其他开发人员共享OLE控件。
MFC4.0除了继续扩大对ODBC的支持外,还提供了一种新的DAO(DataAccessObject,
数据存取对象)类。
通过DAO类,程序员可以直接存取MicrosoftJet数据库引擎,它是一
种同MicrosoftAccessforWindows96和MicrosoftVisualBasic中的引擎完全相同的引擎。
DAO类包含了Jet数据库引擎的OLECOM接口,开发人员不必亲自编写SQL程序就可以
实现对数据库的操作。
当使用DAO类时,程序员可以有计划地访问和操纵数据库内的数
据,并管理数据库、数据库对象及数据库结构。
MFC中引进了线程同步对象的概念,为了
管理线程的同步操作,MFC提供了一个新的基类——CSyncObject,以及代表公用同步技
术的几个派生对象。
MFC提供了对Windows的MAPI(MessageApplicationProgramming
Interface,消息应用程序接口)的支持,通过MFC的这一扩展,程序员可以很容易地开发出
用于建立、处理、转送以及存储邮件消息的应用程序。
MFC进一步增强了对Windows
Sockets的支持,通过MFC可以较容易地实现在Windows操作系统环境下的网络通信程序。
从MFC4.21版本到今天的MFC5.0版本,增强了对数据库应用程序的支持和对网络
协议的强有力支持以及其他新的功能。
新的MFC类CHtmlView使用户可以在MFC应用
程序中承载动态HTML;可以使用ODBC类和高性能的ODBC驱动程序来访问和操纵数
据库中的数据;可以通过数据访问对象(DAO)类;通过编程语言来访问和操纵数据库中的
数据并管理数据库、数据库对象与结构。
2.MFC的概念
若要建立一个Windows应用程序,最好是从设计用户界面开始。
首先,要确定用户怎样使用该程序并根据需要设置相应的用户界面对象。
Windows用
户界面有一些标准的控制,如按钮、菜单、滚动条和列表等,这对Windows用户来说已经
是很熟悉了。
需要注意的是,作为程序员必须选择一组控制并决定如何把它们安排到屏幕
上。
传统上,需要在纸上做一下用户界面的草图,直到对各元素感到满意为止。
这对于一
些比较小的项目以及一些大项目的早期原型阶段是可以的。
下一步,是要实现代码。
为任何Windows平台建立应用程序时,程序员都有两种选择:
C或C++。
使用C,程序员是在Windows应用程序界面(API)的水平上编写代码。
该界面由
几百个C函数组成。
Microsoft也提供了C++库,它位于任何WindowsAPI之上,能够使
程序员的工作更容易。
它就是MFC,该库的主要优点是效率高。
MFC是建立在C++的基
础上,MFC借助ApplicationWizard使开发者脱离了那些每次都必写基本代码的繁琐;借
助ClassWizard和消息映射使开发者摆脱了定义消息处理时那种混乱和冗长的代码段。
利
用C++的封装性,开发者可以更容易理解和操作各种窗口对象;利用C++的派生性,开发
者可以减少开发自定义窗口的时间,并创造出可重用的代码;利用虚拟性,可以在必要时
更好地控制窗口的活动。
因此,MFC是很值得推荐的开发Windows应用程序的方法。
当使用MFC时,我们所编写的代码是用来建立必要的用户界面控制并定制其外观的。
同时还要编写用来响应用户、操作这些控制的代码。
例如,上一节鼠标左右键单击的例子,
一旦应用程序正确地响应了所有允许的控制,它的任务也就完成了。
3.MFC的优势
作为微软基础数据库类,MFC向程序员提供了一种通过类的层次结构组织在一起的应
用程序框架。
几个高层的类提供一般的功能,而底层的类则实现更为具体的行为。
程序员
也可以从基类派生出自定义的类,从而创建既具有一般功能又具有特殊性质和用途的对象,
例如窗口、按钮等。
这种框架及层次结构一方面减少了不必要的重复编程工作,一方面又
充分保证了程序的可扩展性。
复杂的WindowsAPI函数被合理地封装在MFC的类和对象中,相关的部分被组合在
一起。
这样,程序员不必再记忆大量的API函数调用及其相应的数据结构,只需要将对应
的类实例化,并简单地调用几个成员函数即可。
例如,应用程序主窗口的创建过程,需要
经历窗口类的定义、注册、调用CreateWindow函数创建窗口、调用ShowWindow函数显
示窗口等一系列复杂的操作,而使用MFC达到同样的目的却十分简单。
CMyAppmyApp;
BOOLCmyApp:
:
InitInstance()
{m_pMainWnd=newCMainWindow;
m_pMainWnd->ShowWindow(m_nCmdshow);
m_pMainWnd->UpdateWindow();
}
CMainWindow:
:
CMainWindow()
{
Create(NULL,"MFC应用程序");
}
这样的代码最终要被转换成上述的一系列复杂操作,但实现细节却被隐藏起来了。
除了简洁和可扩展外,MFC还为应用程序提供了非常丰富的特性,主要有:
多文档界面(MDI)。
文档/视图体系结构。
ODBC及Jet数据库支持。
InternetTCP/IP协议编程支持。
多线程支持。
ActiveX控件编程支持。
Windows9X/WindowsNT常用控件支持。
其中的文档视图模式适合于绝大多数应用程序。
在该模式中,存放数据的是文档类的
对象,而负责显示数据的是试图类的对象。
文档和视图分离,使程序更易于维护,譬如仅
需要修改试图类就可以改变数据的显示方式或使同样的数据以不同的方式显示。
5.2.2MFC应用程序框架
MFC中的各种类结合起来构成了一个应用程序框架,它的目的就是让程序员在此基础
上来建立Windows下的应用程序,这是一种相对SDK来说更为简单的方法。
因为总体上,
MFC框架定义了应用程序的轮廓,并提供了用户接口的标准实现方法,程序员所要做的就
是通过预定义的接口把具体应用程序特有的东西填入这个轮廓。
MicrosoftVisualC++提供了相应的工具来完成这个工作:
ApplicationWizard可以用来
生成初步的框架文件(代码和资源等);资源编辑器用于帮助直观地设计用户接口;Class
Wizard用来协助添加代码到框架文件;编译则通过类库实现了应用程序特定的逻辑。
MFC
ApplicationWizard生成的应用程序必须包括如下一些要素:
1.WinMain()函数
Windows要求应用程序必须有一个WinMain()函数。
但程序中看不到WinMain(),因
为它隐藏在应用程序框架中。
启动应用程序时,Windows调用应用程序框架内置的
WinMain()函数。
2.应用程序类
也称CMyHelloApp。
该类的每一个对象代表一个应用程序。
程序中默认定义一个全局
CMyHelloApp对象,即theAPP。
CWinApp基类决定theAPP的大多数行为。
3.成员函数CMyHelloApp:
:
InitInstance()
当WinMain()函数找到应用程序对象时,它调用虚成员函数InitInstance()及其构造,显
示应用程序的主框架窗口。
4.CMainFrame类
代表应用程序的主框架窗口。
当构造函数调用基类CFrameWnd的成员函数Create()
时,Windows创建实际窗口结构,应用程序框架把它链接到C++对象。
函数ShowWindows()
和UpdateWindow()也是基类的成员函数,必须调用它们来显示窗口。
5.2.3程序运行过程
如图5.4所示,当运行用户应用程序时,程序中的框架首先获得控制权,然后依次执
行下列功能:
(1)初始化工作。
(2)构造应用程序唯一应用类的对象。
构造应用类对象时,要调用其构造函数。
(3)调用WinMain()函数。
(4)从WinMain()函数返回,删除应用程序的唯一应用类对象。
(5)终止应用程序,退出并返回。
图5.4应用程序的运行过程
5.2.4创建一个简单的MFC应用程序
1.创建工程
(1)启动VisualC++6.0。
选择File|New命令。
此时弹出如图5.5所示的New对话框。
(2)在New对话框中,选择Projects标签中的MFCAppWizard(exe)类型,在Projectname
文本框中输入工程名称:
Hello。
单击OK按钮,进入下一步。
图5.5新建工程对话框
(3)此时,VisualC++将显示如图5.6所示的MFCAppWizard-Step1对话框。
在此对
话框中有以下几个选项。
Singledocument:
表示单文档界面,主窗口中只能容纳一个文档。
Multipledocuments:
表示多文档界面,窗口同时容纳多个文档。
Dialogbased:
表示生成基于对话框的应用程序。
本例中,选择Singledocument单文档应用程序。
图5.6MFCAppWizard-Step1:
设置应用程序类型
(4)单击Next按钮,VisualC++显示MFCAppWizard–step2of6对话框,如图5.5所
示。
在此对话框中决定所要生成的应用程序是否需要数据库的支持,以及数据库支持的级
别。
关于数据库支持的选项如下。
None:
不包含任何数据库支持。
Headerfilesonly:
包括最低限度的数据库支持。
Databaseviewwithoutfilesupport:
要支持数据库时不使用文件支持。
Databaseviewwithfilesupport:
要支持数据库时使用文件支持。
应用程序框架包含数据库头文件和链接库,从CFormView中派生出自己的视图类,菜
单中可以包含一个记录菜单,此时可以用类CRecordset来更新数据库记录或选择程序是否
支持文档的串行化。
图5.5MFCAppWizard-Step2:
设置数据库支持模式
当前,选择默认的None选项。
然后继续单击Next按钮,进入APPWizard的下一步。
(5)第3步显示MFCAppWizard–step3of6对话框,如图5.6所示。
在此对话框中可
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MFC 编程 基础