加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 VC++的MFC教程

VC++的MFC教程.pdf

VC++的MFC教程

zmh0373
2011-04-29 0人阅读 举报 0 0 暂无简介

简介:本文档为《VC++的MFC教程pdf》,可适用于IT/计算机领域

下载无论读者是否已经读过本系列的书籍或者已经具备了多年的编程经验我们仍将在这一部分回顾一下所需要的基本知识其目的就在于能够使读者更好地理解本书的实例。编写程序常常是一种需要尝试不同方法以达到最终目的的工作。通常情况下了解用MFC来做什么涉及到对个基本概念的理解:WindowsAPI怎样创建窗口MFC如何封装并改进WindowsAPIMFC如何与窗口通信以及MFC是怎样控制绘图任务的。除了这些概念以外本部分还将讨论一下工具栏和状态栏。最后我们将讨论一下MFC如何同非Windows构件进行通信如串行口和Internet站点。本部分包括的章节介绍如下。第章概述本章概述MFC如何封装并改进WindowsAPI。如果读者已经阅读过本系列书籍的前一本将会发现该章是对那些版本基础部分的一些回顾。本书包含这一章是为了保持本书对高层次读者的独立性。第章控件条本章将讨论MFC支持的控件条。标准的控件条包括工具栏、状态栏和伸缩条(Rebar)等。MFC增加了对话条和停靠栏。该章还要探讨MFC如何避免控件条之间以及它们和视之间互相覆盖的技术内幕。第章通信本章讨论应用程序与外部世界的不同通信方式。其中最基础的窗口消息将在第一章中讨论。本章还涉及其他一些通信途径包括局域网、Internet通信、串行和并行端口、DDE、Windows挂钩和管道等。第章概述本章将回顾Windows应用程序的基本知识包括应用程序如何创建窗口、窗口之间如何进行对话以及如何在窗口内绘图。然后将讨论微软基础类库(MFC)以及DeveloperStudio怎样使创建窗口应用程序的工作变得容易起来。Windows基础当Windows操作系统启动应用程序时它首先创建一个程序线程该线程一般只是一个第一部分基础可执行内存的管理模块而这些内存则与系统中其他应用程序分享执行时间。如果这个应用程序要通过显示屏幕与用户交互那么这个程序线程便需要负责创建显示在屏幕上的窗口。程序线程通过调用操作系统的应用程序编程接口(API)来创建这些窗口。实际调用的函数是::CreateWindowEx()这个函数需要下列参数:屏幕位置、窗口大小以及即将创建的窗口的风格。窗口类结构线程创建的多数窗口具有类似的风格(例如按钮)这些类似的风格已经被集成为一个名为窗口类(WindowsClass)的结构。注意这是一个结构而不是一个C类。在创建窗口时必须设定窗口类。也可以使用其他的窗口风格并且分别设定各自的窗口类结构。消息如果用户单击了一个窗口操作系统就会向这个窗口发送一个消息来把这一事件通知给它。每个窗口用自己的窗口处理过程来处理窗口消息举个例子一个按钮的窗口处理过程可能向它的主窗口发送一个消息告诉它需要做什么事情。每个窗口的处理过程还负责在屏幕上绘制属于自己的窗口。操作系统在绘制窗口时会向目标窗口发送WMPAINT消息。所有类似的窗口具备同样的窗口处理过程例如所有的按钮控件使用同样的窗口处理过程因此所有的按钮看起来外表都很类似其行为也类似。这种情况下的窗口处理过程位于操作系统内。它的地址在窗口的窗口类结构内指定。所有的按钮控件都由同样的窗口类创建这个窗口类结构的名字叫做BUTTON。客户区和非客户区窗口处理过程在屏幕上绘制一个窗口时实际上绘制了两个部分:客户区和非客户区。为了绘制非客户区(nonclientarea)窗口处理过程总是调用所有窗口过程都需要调用的相同的操作系统处理过程。该过程接下来还需要绘制框架、菜单条以及标题栏等等多数窗口共同具有的内容。过程所绘制的东西取决于窗口的风格。例如由于按钮的风格被指定为不用绘制其非客户区所以按钮窗口上就不会看见框架和菜单。窗口的客户区(clientarea)总是由窗口自己的窗口处理过程绘制也可能由操作系统来完成这件事例如所有的按钮都由同样的处理过程来绘制或者由创建者自己来绘制图像或列表。重叠窗口、弹出窗口和子窗口除了窗口类以外还有成百上千种窗口风格供用户指定窗口的绘制及其行为。其中有种最重要的风格创建了对应种最基本的窗口类型:重叠窗口、弹出窗口和子窗口。■重叠窗口(overlappedwindow)具有应用程序主窗口的全部特点。它的非客户区包括一个可伸缩的框架、菜单条、标题栏和最小化、最大化按钮。■弹出窗口(popupwindow)具有消息框或者对话框的全部特点。它的非客户区包括一个固定大小的框架和一个标题栏。第第第一部分第基础下载■子窗口(childwindow)具有类似按钮控件的全部特点。它没有非客户区窗口的处理过程负责绘制窗口的每个部分。这些窗口在其行为上表现不同这将在以后讨论。父窗口和宿主窗口由于用户界面可能会由好多个窗口组成所以由程序线程控制它们将是很困难的例如如果用户将一个应用程序最小化那么程序线程应该对那些组成用户界面的所有最小化窗口负责吗?实际上并没有采取直接控制的方式应用程序创建的每个窗口都通过调用::CreateWindowEx()分配了一个控制窗口。如果这个控制窗口被最小化那么所有被其控制的窗口都会由操作系统自动地最小化。如果控制窗口被销毁那么每个被控制窗口也随之被销毁。每个被控窗口也可以作为其他窗口的控制窗口结果最小化或者销毁某些窗口都只影响用户界面的一部分。无论是什么窗口或者位于何处程序员都可以在它内部创建另外的窗口。子窗口的控制窗口叫做父窗口(parentwindow)。父窗口剪切其子窗口也就是子窗口不能在其父窗口以外绘制。当用户与类似按钮的子窗口交互的时候这些子窗口将自动地生成消息并发送到其父窗口。这就使得控件可以在父窗口的窗口处理过程中被集中处理。图构成一个Windows应用程序界面的窗口弹出窗口和重叠窗口的控制窗口叫做宿主窗口(ownerwindow)。与父窗口不同宿主窗口并不限制属于它的窗口。然而当最小化宿主窗口的时候它的所属窗口也将被最小化。但是当宿主窗口隐藏的时候它的所属窗口却仍然显示。请参见图以了解组成Windows应用程序的各种窗口。Windows消息上面提到每个窗口由其自己的窗口处理过程响应来自操作系统或者其他窗口的消息。例如用户用鼠标单击了某个窗口那么操作系统可能就会向这个窗口发送一个消息。如果这是一个标识为LoadFile的按钮窗口那么它的窗口处理过程就可能向应用的主窗口发送一个消息通知加载文件。主窗口处理过程将加载文件并在其客户区显示文件内容来作为响应。接下来讨论消息是如何传送的。第章第概第第述第第下载一个重叠窗口。宿主窗口是桌面也叫主窗口子窗口。文窗口是主窗口弹出窗口。宿主窗口是主窗口子窗口。文窗口是它所在的弹出窗口发送或寄送消息传送消息到窗口有两种方式:发送(send)或者寄送(post)。这两种方式之间的主要差别在于被寄送的消息不必立即处理。被寄送的消息放置于一个先入先出的队列里等待应用程序空闲的时候处理而被发送的消息需要立即处理。实际上发送消息到窗口处理过程和直接调用窗口处理过程两者之间几乎没有任何不同。只是你可以要求操作系统截获所有为达到某个目的而在应用程序中被发送的消息但不能截获对窗口处理过程的直接调用。与用户输入相对应的消息(如鼠标单击和按下一个按键)通常都是以寄送的方式传送以便于这些用户输入可以由运行较缓慢的系统进行缓冲处理。而其余的所有消息都是被发送的。在以上的例子中系统寄送了鼠标单击消息而按钮窗口则向其主窗口发送了LoadFile消息。消息类型有种类型的消息:窗口消息、命令消息和控件通知消息:■窗口消息(Windowmessage)是由操作系统和控制其他窗口的窗口所使用的消息。这一类的消息有Create、Destroy和Move等等。上例中的鼠标单击消息也是一种窗口消息。■命令消息(Commandmessage)是一种特殊的窗口消息它从一个窗口发送到另一个窗口以处理来自用户的请求。在以上例子中从按钮窗口发送到主窗口的消息就是命令消息。■控件通知消息(controlnotification)是最后一种消息类型。它类似命令消息当用户与控件窗口交互时这一类消息就从控件窗口发送到其主窗口。但是这种消息的目的并不在于处理用户命令而是为了让主窗口能够改变控件如加载并显示更多的数据。以上所述的例子中并没有控件通知消息但是假如按钮发送了鼠标单击消息给它的主窗口那么这个消息也可以看作是一个控件通知消息。一个普通的鼠标单击消息可以由主窗口直接处理然后由控件窗口处理。接收消息窗口处理过程看起来与其他函数和方法没有任何不同。消息到来后按照消息类型排序进行处理。其中的参数则由调用函数提供以进一步区分消息。命令消息由wParam中的命令ID分类。DefWindowProc()函数则发送任何程序员都不会去处理的消息给操作系统。所有传送到窗口的消息都将通过这个函数甚至包括绘制窗口非客户区的消息尽管最终它们都将绕过DefWindowProc()函数。一个主窗口的处理过程实例如下:MainWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam){switch(message){caseWMCREATE::::breakcaseWMPAINT::::breakcaseWMCOMMAND:第第第一部分第基础下载switch(id){caseIDCLOADFILE::::break}breakdefault:return(DefWindowProc(hWnd,message,wParam,lParam))}return()}窗口处理函数的子类化上面提到过在窗口类中定义了窗口处理过程的地址。由窗口类所创建的窗口将把它们的消息传递给窗口处理过程。如果程序员使用的是一个由系统提供的窗口类并要增加自己对窗口的特殊处理就需要使用子类化(swbolassing)。将窗口指向自己的窗口处理过程便对窗口进行了子类化这样所有的消息都可以由程序员自己处理了。如果只想处理一个或者两个消息只需简单地将剩余消息传递给初始的窗口处理过程即可。我们注意到采用子类化并没有修改原先的窗口类而是直接对窗口对象进行了修改这个对象保存了一份窗口处理过程地址的拷贝。与此相反超类化(superclassing)则修改了原始的窗口类然后将其应用于创建窗口但由于可以更方便、安全地使用MFC来获得由超类化带来的好处所以这种方法就很少采用了。请参见图了解子类化概念。窗口绘图WindowsAPI为窗口绘图提供了好几种调用函数。它们是点、弧、图形和圆绘图函数以及图形填充和位图绘制等函数。正是因为采用了绘图API所以程序员必须负责传递坐标数值、颜色、宽度和绘图位置而API函数则负责剩余的工作。为了简化对WindowsAPI的图像函数调用一些参数被固化到了一个名为设备环境的可重用对象中。设备环境图像设备环境(DeviceContext)是一个简单的对象它包含了对绘图而言比较共同的属性第章第概第第述第第下载窗口对象指向创建它的窗口类的窗口过程通过设置自己的窗口过程地址来子类化该窗口任何不希望自行处理的消息可以交由初始窗口过程负责处理窗口对象初始窗口过程新窗口过程图窗口处理函数的子类化例如绘图位置、线宽、填充模式的颜色等等。这个对象可以一次设置然后多次重复使用。实际上并不需要自己创建设备环境只要调用几个可能的API函数系统就可以返回已经被预先准备好的设备环境值。例如系统为屏幕创建的设备环境包含屏幕上将用于绘图的颜色以及绘图工具的当前位置程序员则可以在该位置进行绘图并设置颜色。绘图工具设备环境并没有包括绘图所需的全部特征。有几个特征存在于设备环境可以引用的附加图像对象中。这些对象都各自代表了某一特定绘图工具的特征(如:画笔的色彩和宽度、画刷采用的模式等)。这些工具包括绘制直线的画笔用某种模式填充封闭区域的画刷确定文本绘制效果的字体以及确定使用何种颜色的调色板等等。另外的两种绘图工具:位图和区域则显得更抽象一些。位图工具看起来像画刷除了它只能用位图模式填充一个区域。而区域工具则类似于画笔工具但它起的是剪切作用例如可以使用区域工具从一个位图中将“STOP”单词分割出来。映射模式设备环境保持跟踪程序员采用的映射模式。设置映射模式可以指定调用参数中以英寸或者厘米作为度量单位的坐标x和y每个绘图函数则可以自动确定绘制多少像素。可用的映射模式如下表所示。表可用的映射模式模式使用说明MMTEXT这是缺省的映射模式坐标值x和y精确地等于一个屏幕像素或者一个打印机的打印点y的正方向沿屏幕或者打印页向下MMHIENGLISHx和y值为屏幕或者打印页上一英寸的。窗口决定当前屏幕设备应该有多少个像素等于英寸。Y的方向则为沿屏幕或者打印页向上MMLOENGLISHx和y值为设备上一英寸的y向上为正MMHIMETRICx和y值为设备上一毫米的y向上为正MMLOMETRICx和y值为设备上一毫米的y向上为正MMTWIPSx和y值为设备上一英寸的y向上为正。这个模式通常应用于绘制文本一twip等于一个字体点的MMANISOTROPIC程序员通过设置接下来将讨论的窗口和视口以决定x和y代表多少像素MMISOTROPIC同上但x和y代表的像素数必须相等窗口视和视口视MMANISOTROPIC和MMISOTROPIC映射模式允许程序员自定义将坐标x和y换算为像素数的转换比率。这个工作由定义两种叫做视的矩形来完成。首先应该定义一个代表将要绘制的整个区域(例如:)的矩形然后定义一个代表那些最终出现绘图结果的屏幕或打印机上的对等坐标(例如:)的矩形。第一个矩形叫做窗口视第第第一部分第基础下载(WindowView)第二个矩形叫做视口视(ViewportView)。如果在设备环境中定义了这两个矩形并使用上述两种映射模式之一那么使用窗口视坐标的图形将自动地被转换为使用视口视的坐标。除了视口视的坐标之外程序员可以缩小、放大以及颠倒自己的图形而不需要改变其他任何东西。逻辑单位和设备单位使用除MMTEXT以外的绘图模式绘图的时候传递给绘图函数的坐标采用逻辑单位(LogicalUnit)。逻辑单位可以是英寸、厘米或者像素。绘图函数本身则用设备单位绘图。举一个例子直线绘图函数可能使用个像素代表一个英寸的逻辑单位这里的数字就是逻辑单位数值而数字则是设备单位(DeviceUnit)数值。这并不会成为一个问题除非打算让用户能够使用鼠标绘图。鼠标传回给应用程序的任何坐标都是以设备单位计量的数值因此必须使用一些WindowsAPI将这些坐标值转换为逻辑单位数值。绘图函数WindowsAPI具有多个绘图函数举例如下:■画点函数:如SetPixel()。■画线函数:如LineTo()、Arc()、Polyline()。■画图形函数:如Rectangle()、Polygon()、Ellipse()。■填充和图形反转函数:如FillRect()、InvertRect()、FillRgn()。■滚屏函数:ScrollDC()。■文本绘制函数:如TextOut()、DrawText()。■位图和图标绘制函数:如DrawIcon()、BitBlt()。抖动和非抖动颜色所有可用的绘图函数包括从画线到画图形和文本都需要使用颜色。但是除非系统具备足够的显示内存否则颜色将必须利用抖动(Dithered)方式。所谓抖动颜色实际上是一些主要颜色的集合在显示的时候通过几个颜色相互混合以获得某种理想的色彩。对大多数情况抖动颜色已经足够了。然而由于抖动颜色显得比较模糊对图像应用程序而言通常不足以达到要求。图像应用程序不希望线条与其包围的图形颜色相互渗透混合。对图像应用程序可以有以下几种选择方案:■增加更多的显示内存。需要颜色抖动的理由在于虽然屏幕上的每个像素都具有自己的RGB颜色。但一般的系统都没有足够的显示内存来为每个像素存储其RGB值。例如设每个像素为位那么一个×像素的屏幕就需要M字节的显示内存以容纳所有的颜色值。■只用标准颜色绘图。Windows使用的显示卡保证了至少能定义种标准颜色因为它需要使用这些颜色来创建抖动效果。■配置自己的颜色。除了标准颜色以外显示卡还有一些空间可定义多种颜色可以在设备环境调色板内定义这些颜色并只用这些颜色绘图。多数图像应用都采用了这种方法此方法将在实例中得到详细描述。第章第概第第述第第下载设备无关位图每个像素都有自己的RGB颜色每种颜色的数值范围可以为~。一排同样颜色(例如黑色)的像素在屏幕上显示一条直线一个具有不同颜色像素的矩形就可以创建任何图像。将这些像素的色彩数值存到一个文件中就得到了一个位图文件。这个文件的头不仅要指示文件包含了多少颜色值而且还要指出多少颜色值组成一排。如果位图文件中的每个颜色值都包含完整的RGB数值那么由于这个颜色值完全在位图中得到定义这个文件就是一个设备无关位图。如果每个颜色值实际上都是对某个颜色表的字节索引那么在它同时包含了这个颜色表的情况下这个文件仍然是设备无关的。像这样的颜色索引常用于压缩位图的大小。一个位索引只占用位RGB值空间的四分之一。设备无关位图(DeviceIndependentBitmaps)由对颜色表的索引组成这个颜色表在系统的显卡中被定义。这就是在上节的第步为显示非抖动颜色而配置的颜色表如果某个位图指向它的话那么这个颜色表将不能独立于设备之外而存在。元文件除了在屏幕或者打印机上绘图还可以在文件中绘图这样的文件就是元文件(Metafile)。元文件的优点在于:无论绘制的内容是什么它们都将完整地重现。由于元文件可以伸展得到更好的效果而位图进行伸展时会扭曲变形所以元文件优于用位图的形式存储图像。何时绘图看起来这个话题可能有点傻但对一个多任务操作系统而言应用程序之间不得不争夺屏幕上有限的显示空间。哪怕只是在自己的窗口中绘图也不可能想做什么就做什么。通常只是在窗口接收到WMPAINT消息或者WMDRAWITEM消息(针对所属的控件窗口)的时候才绘图。系统仅在窗口被部分遮盖以及由于关闭其他窗口而显现出来的时候才发送这些消息。或者说如果需要重画以显示新的信息系统在这种情况之下将发送这些消息。MFC基础到目前为止我们只讨论了应用程序可以从WindowsAPI中所获得的功能。但API并不是面向对象的。例如使用API不可能在创建一个窗口实例之后再调用其成员函数作用于该窗口。并且不能从窗口类派生出一个可以加入自己所需功能的类比方说不可以增加自己的窗口处理过程。微软基础类库所要做的就是向应用程序提供可以访问WindowsAPI的一种模拟面向对象的访问方式。在功能上每个MFC类都紧密结合一种Windows资源对象(如窗口)而API函数则控制该资源。举个例子MFC的CWnd类创建并控制窗口。而操作系统一创建窗口就会开辟一块叫做Window对象的管理内存然后返回该对象的指针也就是窗口句柄。MFCCWnd类则以成员变量的形式存储这个句柄并且由CWnd的成员函数调用该变量来控制该窗口。例如CWnd的MoveWindow()成员函数调用WindowsAPI::MoveWindow()来移动属于该窗口句柄的窗口。因为MFC是用C写成的所以程序员可以从CWnd类派生自己的类并在其中增加所需功能。第第第一部分第基础下载但是因为这只是面向对象设计的一个模拟所以MFC类对操作系统内部工作的控制能力并不会比任何其他API调用更多。例如如果对窗口打开方式的修改是API的内部功能那么即使使用MFC类来试图改变这一方式也是不可能的。创建和销毁MFC类创建MFC类是一个棘手的问题。对封装了类似窗口系统资源的MFC类来说程序员不仅要创建自己的MFC类的实例还要调用该类的成员函数来创建该系统资源。因此MFC类的创建几乎总是分成两步走:)创建一个类的示例)创建系统资源。注意为什么MFC类不仅仅只是简单地在它们自己的构造函数内创建系统资源呢?这是因为创建系统资源是否成功是不可能预先知道的而类的构造函数又难于访问(它甚至不返回错误状态)利用成员函数来完成这一工作则要容易得多。销毁MFC类也同样棘手。如果类的实例首先被销毁那么它将简单地在其析构函数内销毁资源。然而如果开始就没有资源那么WindowsAPI也就没有办法知道有一个MFC类实例必须被销毁。令人惊奇的是这只是存在于CWnd类和窗口资源之间的问题其他类型的资源并不由用户销毁。但是用户可能通过单击窗口的关闭按钮来关闭窗口在这种情况下不知何故CWnd对象必须知道足够的信息来销毁自己以防止出现内存泄漏。幸运的是当窗口资源被销毁时它会发送一个消息而CWnd对象可以捕获这个消息以用于销毁自身。因为MFC类对象和系统资源是两种不同实体所以可以通过编程的方法将两者分开或者重新组合在一起。例如通过调用Attach()函数可以将一个CWnd类对象附着于一个已经存在的窗口对象上。所有控制系统资源的MFC类都具有Attach()函数和Detach()函数。DeveloperStudio基础为了将MFC类恰当地运用于应用程序DeveloperStudio(开发平台)提供了几种向导(Wizard)工具和编辑器工具:■AppWizard用于生成应用程序所需要的基本类文件。所产生的类都派生于MFC类它们在编译后与MFC库链接以创建应用程序。■ClassWizard用于创建应用程序额外的文件或者为已有的类增加新的成员函数。这些被创建的类可以由MFC派生。■DialogEditor用于创建对话框模板方法是将控件窗口图标拖到一个空白的框架窗口内。被创建的模板作为应用程序的资源存储然后用于在运行时候创建对话框。ClassWizard可以直接从DialogEditor调用以创建一个对话框类该类则负责创建对话框。■ToolbarEditor用于创建工具栏和位图资源而这些资源则又用于创建应用程序的工具栏。■Cursor、Icon和BitmapEditor是简单的图像编辑器用于创建应用所使用的光标、图标和位图资源。■MenuEditor用于创建应用中的菜单条和弹出菜单资源。■StringEditor用于创建字串资源它可以将文本字符串从应用程序中分离出来并且可以很方便地从一种语言转变为另一种语言(例如从英语转变为法语而不是从C到JAVA)。第章第概第第述第第下载■TextEditor用于编辑类文件。Windows和MFC总结以上所述说明了Windows、MFC和DeveloperStudio是如何一起协同工作的。Windows操作系统创建并支持应用程序其中包括窗口的创建。MFC则在C类中封装了这一功能而DeveloperStudio则负责创建这些类。现在来回顾一下MFC提供了哪些类。基本类多数MFC类由下列种基本类派生:CObject、CCmdTarget和CWnd。如上所述CWnd类封装了创建和控制窗口的WindowsAPI它还允许程序员向窗口处理函数中添加自己的消息处理过程。CCmdTarget类则允许没有创建窗口的类也能处理消息但只能是后面要讨论的所谓命令消息。CObject类为每个从它派生的类提供了许多基本功能例如得到类对象的大小将对象存入一个磁盘文件等等。CObject类CObject类本身并没有提供什么重要的功能。该类通过种相互配合的宏(macro)完成实际工作。这些宏使得类在运行时可以从Cobject类派生以获得类的名字和对象大小。创建一个这样的类不必要知道类的名字文档环境存储和接收这种类的实例也不必知道类的名字。下列宏允许类的实例知道它自己的类名字和运行时的类大小:DECLAREDYNAMIC(CYourClass)inthehfileIMPLEMENTDYNAMIC(CYourClass,CYourBaseClass)inthecppfile使用CObject::GetRuntimeClass()函数可以在运行时使用这些宏来获得与类有关的细节。另外几个宏包括以上宏的功能但同时允许类的实例在不知道它的类名字的情况下被创建:DECLAREDYNCREATE(CYourClass)inthehfileIMPLEMENTDYNCREATE(CYourClass,CYourBaseClass)inthecppfile使用CObject::CreateObject()函数可以利用这些宏创建一个类的实例而无需知道它的类名字。另外几个宏包括以上所有宏的功能但同时允许类实例在不知道它的类名字的情况下被存贮:DECLARESERIAL(CYourClass)inthehfileIMPLEMENTSERIAL(CYourClass,CYourBaseClass,schema)inthecppfileCCmdTarget类从CCmdTarget类派生的类可以接收并处理由应用程序的菜单或者工具栏发出的命令消息。CCmdTarget类将在以后的消息机制部分详细讨论。CWnd类如上讨论CWnd类的成员函数封装了负责创建和维护窗口的WindowsAPI。CWnd类派生于CCmdTarget类因此能够接收和处理命令消息。所有其他的控制窗口的MFC类都由该类派生。第第第一部分第基础下载注意本章所使用的下列字母用于指出MFC类从以上的何种基类派生:■O代表派生于CObject。■OC代表派生于CObject和CCmdTarget。■OCW代表派生于CObject、CCmdTarget和CWnd。应用类AppWizard以下列种MFC类为基础为应用程序产生出一些派生类:)CWinApp也就是应用程序的应用类(ApplicationClass)它负责初始化并运行应用程序这就是以上讨论的程序线程。)CFrameWnd也就是应用程序的框架类(FrameClass)它负责显示并跟踪用户命令以及显示应用程序的主窗口。)CDocument应用程序的文档类(DocumentClass)它负责加载和维护文档。文档可以是从草稿到网络设置的任何东西。)CView应用程序的视类(ViewClass)它负责为文档提供一个或者多个视。注意这里使用了应用类、框架类等术语但本书所指的都是以上种基类的派生类。这种类中的哪些类将包括在应用程序中取决于所创建应用程序的类型。■对话框应用程序(DialogApplication)只是简单地拥有作为用户界面的对话框而没有框架、文档或者视类。对话框应用程序仅利用了应用类CWinApp的派生类。对话框则用MFC的CDialog类创建这个类将在以后讨论。■单文档界面应用程序(SDI:SingleDocumentInterfaceApplication)可以一次加载并编辑一个文档它使用以上提到的全部种基类。■多文档界面应用程序(MDI:MultipleDocumentInterfaceApplication)可以一次加载并编辑几个文档它使用以上提到的全部种基类此外还增加了两个CFrameWnd的派生类:CMDIFrameWnd和CMDIChildWnd。文档视CDocument和CView类的派生类负责文档视。MFC应用程序是面向文档的这意味着应用程序负责加载、观察、编辑并存储文档而文档则可能是文本文件、图形图像或者二进制配置文件。文档类的工作是将文档从磁盘加载到它的成员变量。然后创建一个或者多个视类以显示这些成员变量。文档类仅需为文档类对象创建多个视类对象就可以拥有多个视。因为文档类没有关联的窗口所以它并不是从CWnd类派生的而是从CCmdTarget派生的因而可以处理命令消息。CWinApp(OC)应用类是应用程序运行时创建的第一个对象并在应用程序执行的过程中最后一个终止。启动后应用类就负责创建应用程序的其他对象。■针对对话框应用程序应用类用CDialog创建一个对话框。■针对SDI应用程序应用类创建一个或者多个文档模板(参阅以后内容)然后使用该模第章第概第第述第第下载板打开一个空文档。■针对MDI应用程序应用类创建一个或者多个文档模板然后使用该模板在主框架类内打开一个空文档。应用类派生于CWinApp并从AppWizard中得到类似CXxxApp的类名字Xxx就是具体应用的名字。文档模板文档模板定义了在应用程序打开一个文档时框架类、文档类和视类的创建结果。为了生成一个文档模板必须为SDI应用程序创建一个CSingleDocTemplate类或者为MDI应用程序创建一个CMultiDocTemplate类并用个类指针对其初始化:pDocTemplate=newCMultiDocTemplate(IDRAPPTYPE,RUNTIMECLASS(CAppDoc),YourDocumentClassRUNTIMECLASS(CChildFrame),YourFrameClassRUNTIMECLASS(CAppView)YourViewClass)其中的RUNTIMECLASS()宏返回一个指向类的CRuntimeClass结构的指针DECLAREDYNCREATE和IMPLEMENTDYNCREATE宏则将该结构添加到类中。文档模板通过创建以上个类的实例并调用其CRuntimeClass::CreateObject()函数打开文档。线程CWinApp类本身从CwinThread类派生。而CWinThread类则封装了创建和维护系统中具体应用程序线程的WindowsAPI。实际上可以通过创建CWinThread类的另一个实例以在应用程序中实现多任务。读者可以参考实例和实例。CWinApp类代表了应用程序中的执行主线程。CFrameWnd(OCW)框架类是应用程序运行时创建的下一个对象它负责显示并为应用程序引导用户命令。对于SDI应用程序框架类派生于CFrameWnd类AppWizard将自动为它分配一个名字:CMainFrame。对于MDI应用程序框架类则派生于CMDIFrameWnd类AppWizard也为它分配CMainFrame这个名字。同时MDI应用程序还为每个打开的文档创建一个子框架类(ChildFrameClass)。每个子框架类都派生于CMDIChildWndAppWizard自动为子框架类分配名字:CChildFrm。对话框应用程序没有框架类正如上面提到的对话框应用程序由应用类和对话框类组成。CDocument(OC)文档类通常是应用程序创建的下一个类应用程序或者打开一个新文档或者打开一个已经存在的文档。文档类负责将文档加载到其成员变量中并允许视类编辑这些成员变量。文档可以包括从图像文件到可编程控制器设置等任何内容。第第第一部分第基础下载文档类派生于CDocument类AppWizard自动为其分配的名字为CXxxDoc其中Xxx是应用程序的名字。CView(OCW)文档类的实例创建之后紧接着就会创建一个视类的实例。视类负责描述文档类的内容。视类还允许用户编辑文档。分离窗口类CSplitterWnd则允许文档同时具有一个以上的视这些视可以由好几个同样的或者不一样的视类创建。AppWizard允许程序员从下列几个基类派生自己的视类它们是:CTreeView、CEditView、CRichEditView和CListView等等。每一种基类给予应用程序一组不同功能。所有这些类都从CView类派生。无论选择什么基类AppWizard自动为派生类分配的名字为CXxxView其中Xxx是应用的名字。如上所述可以从这种基类创建种类型的MFC应用程序:对话框、SDI和MDI。下面详细介绍一下这些应用程序类型。对话框应用程序对话框应用程序由一个应用类和对话框类组成应用类是由CWinApp派生的对话框则由一个从对话框类派生的类创建。SDI应用程序SDI应用程序由一个派生于CWinApp的应用类、一个派生于CFrameWnd的框架类、一个派生于CDocument的文档类和一个或者一个以上的视类组成这些视类由一种或几种以CView类为基类的视类派生。MDI应用程序MDI应用程序由一个派生于CWinApp的应用类、一个派生于CMDIFrameWnd的框架类、一个或者一个以上派生于CMDIChildWnd的子框架类和多个文档类和视类组成。其中每个子框架类的对应文档派生于CDocument类每个文档对应的一个或者多个视类则派生于CView类。其余用户界面类除了框架类和视类MFC还提供了几种其他的类来支持用户界面:■通用控件类(CommonControlClass)封装了诸如按钮一类的通用控件。■菜单类(MenuClass)是CWnd类为窗口提供的菜单。■对话框类(DialogClass)封装了对话框和通用对话框。■控件条类(ControlBarClass)封装了控件条(工具栏、对话条和状态栏等)。■属性类(PropertyClass)封装了属性表和属性页。通用控件类通用控件类封装了通用控件(如按钮、列表框等)的功能。这些类派生于CWnd类并继承了第章第概第第述第第下载其成员函数如ShowWindow()和MoveWindow()等等。当这些类创建一个窗口时它们中的每一种都将使用一种通用控件窗口类。例如当CButton通用控件类创建一个按钮时它将使用BUTTON窗口类来创建实际的窗口:Creat(T("BUTTON"),lpszCaption,dwStyle,rect,pParentwnd,nID)下表列出了这些通用控件类、它们所创建的控件以及所使用的窗口类。表MFC通用控件类和它们的窗口类MFC类通用控件Windows类CAnimateCtrl(OCW)Animation动画控件SysAnimateCButton(OCW)按钮控件BUTTONCComboBox(OCW)组合框控件COMBOBOXCEdit(OCW)编辑控件EDITCHeaderCtrl(OCW)标头控件SysHeaderCListBox(OCW)列表框控件LISTBOXCListCtrl(OCW)列表控件SysListViewCProgressCtrl(OCW)进度控件msctlsprogressCScrollBar(OCW)滚动条控件SCROLLBARCSliderCtrl(OCW)滑块控件msctlstrackbarCSpinButtonCtrl(OCW)上下按钮控件msctlsupdownCStatic(OCW)静态控件STATICCTreeCtrl(OCW)树型控件SysTreeViewCTabCtrl(OCW)标签控件SysTabControlCDateTimeCtrl(OCW)日期时间获取控件SysDateTimePickCMonthCalCtrl(OCW)日历控件SysMonthCalCHotKeyCtrl(OCW)热键控件msctlshotkeyCToolTipCtrl(OCW)工具提示控件tooltipsclass并不是所有的通用控件类都只是简单地封装一个通用控件窗口类。有种MFC类实际上提供的功能在通用控件内就找不到。表显示了这些类、派生它们的MFC类和它们所提供的支持。表MFC派生类和它们的基类MFC类MFC继承类新增的功能CBitmapButtonCButton对按钮上的位图提供了更好的支持CCheckListBoxCListBox列表框中的复选框CDragListBoxCListBox列表框中的用户可拖动项目菜单类(O)CMenu类封装了创建和维护菜单的WindowsAPI。CMenu有两个成员函数:Attach()和Detach()。这两个函数允许程序员采用类似CWnd类对象包含一个已有窗口的方法包含一个已第第第一部分第基础下载有菜单。对话框类CDialog类封装了创建对话框的WindowsAPI对话框创建时是一种弹出窗口可以向对话框类增加在对话框模板中定义的控件窗口。通用对话框MFC类MFC库还有种通用对话框类它们封装了创建通用对话框的WindowsAPI。通用对话框是预先加入了控件的对话框它们以一些普通请求信息提示用户如要装载和存储的文件名、颜色、字体和打印参数等。它们简化了由程序员自己编写这些对话框的工作而且向用户展示了他们所熟悉的Windows对话框。表显示了通用对话框的功能、提供的WindowsAPI以及封装的MFC通用对话框类。表通用对话框类及其使用通用对话框WindowAPI调用MFC类选择颜色::ChooseColor()CColorDialog打开保存文件::GetOpenFileName()CFileDialog::GetSaveFileName()“查找”或“替换文本”::FindText()CFindReplaceDialog::ReplaceText()选择字体::ChooseFont()CFontDialog打印页面设置::PageSetupDlg()CPageSetupDialog打印::PrintDlg()CPrintDial

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/49

VC++的MFC教程

仅供在线阅读

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利