VisualC++MFC编程实例.PDF
本书通过85个实例全面讲述了应用MFC进行Visual C++编程的思想。每个实例均以编写一个应用程序要走的步骤编写。全书共分四部分进行介绍,第一部分是基础知识,第二部分讲述用户界面的实例,第三部分讲述MFC内部处理方面的实例,第四部分讲述打包实例。全书基本上面向实例进行阐述,讲解透彻、易于掌握。本书既可作为初学者和大专院校师生的自学参考书,也可作为计算机软件开发人员的技术参考书。 目 录第一部分 基础知识第1章 窗口 21.1 窗口和API环境 21.1.1 三种类型窗口 21.1.2 客户区和非客户区 31.2 窗口和MFC环境 41.3 China-pub.coM第l章窗口3下载重叠窗囗弹出窗囗子窗口洋意:在的蕞基「汪薏:在卺的蕞基最基本的4本的窗体中,系统本的窗体中,系统窗体不进行任何绘制。不进行任何绘制。窗口都是客户区窗口都是客户区典型的外观AE薏:蘧鄱是客芦。字窗口通常自己进行绘制ENH图碳E比h了共同的设置总子窗口不能有子菜单图1-2窗口风格可以用来区分三种不同类型的窗口不是一个窗口显示在子窗口中属于主窗口的子窗囗并由子窗口绘制属于桌面的重叠窗口,也称为主窗口YeH Insee Fs属于主窗口的弹出窗口属于弹出窗口的子窗口,它位于弹出窗口之中图1-3由重叠窗口、弹出窗口和子窗口组成的窗口应用程序1.12客户区和非客户区每个窗口都有由系统绘制的“非客户区”和由应用程序绘制的“客户区”。系统可以绘制图1-4显示的其中一个或者全部特征,当然也可以把所有的特征留给你去绘制。任务栏最小化按钮应用程序图标最大化按钮FE Example菜单条file Edit view关闭按钮M系统菜单(单击应用程Maximize客户区垂直滚动条序图标时,显示虚线框)Close AIt+F4水平滚动条图1-4窗口的非客户区可以由系统选择绘制每个窗口代表内存中的一个窗口对象,并由该窗口对象告诉 Windows操作系统将窗口绘制在何处,以及在对鼠标单击、键盘按下(假设该窗口拥有输入焦点)和时钟终止等事件作出响第一部分基础知识China-pub.com下载应时应调用什么应用程序。窗口对象自身是窗口类的一个实例,它不是 Visual o++的类,而是存在于Ⅴ isual o艹+之外,并早于Ⅴ isual o++的 Microsoft windows所属的类。然而,就像C++的类一样,窗口类为每个基于它创建的窗口定义了若干特征,如背景色和往何处发送消息等(见图1-5窗口对象窗口类indow Nam窗口Window StyleClass InstanceXY PositionClass NameWindow processClass Nar①使用 Register Class(函数创建窗口类②窗口对象由 Create Window()③窗口管理器保持一个窗口对函数创建,作为它的变量传象列表,并告诉每个对象在输窗口类屏幕上绘制自己图1-5 Microsoft windows所属的窗口类创建的窗口对象Windows操作系统提供了一个扩展的应用程序接口(API),可以用来创建和维护这些窗囗对象。调用 Create Window()函数可以创建一个窗口对象;调用 Set Window Long()函数可以改变由窗口类定义的特征;调用 Move window()函数可以移动窗口;调用 Destroy window()可以退出窗口。如此说来,MFC又能做些什么呢?1.2窗口和MFC环境MFC窗囗是C++和 WindOws api调用的综合。事实上,MFC窗口提供了许多(但不是全部) WindOws api的C++封装,从而减轻了编写 Windows应用程序时一些乏味的工作,并提供了一些新的服务MFC窗口不对窗口对象迸行直接控制,而在API环境中却是可以的。如果不能在API环境中实现某项功能,那么肯定也不能在MFC环境中实现。举例来说,MFC库的CWnd可以创建一个窗口,但它只是过去在AP环境中使用的AP调用的封装。微软已经把在MFC库中创建和维护一个窗口的逻辑作为真正的C++封装和控制。然而,这种方法虽使得MFC库万能,但却是不方便的,并导致了严重的冗余和更多的错误。创建MFC窗口是复杂的,首先,创建类CWnd的一个实例,然后调用类CWnd的一个成员函数,该成员函数调用AP中的 Creat window()函数。返回的窗口句柄(这只是指向窗口对象的非直接指针)保存在类CWnd的成员变量 m hwnd中。注意因为窗口在內存中创建,而內存经常发生变化,窗口地址可能是经常变化的。因此,窗口句柄并非直接指向窗口对象,而是指向跟踪窗口对象地址的另-个指针。销毁窗口同样也是复杂的,必须确保销毁了该窗口对象,以及封装该窗口对象的CWnd实例。虽然CWnd对象知道窗口对象,但是窗口对象并不知道CWnd对象(见图1-6)。第章窗口5下载窗口对象窗口类CWnd类对象Window InstancehWnd窗口HWND m hwndWindow StyleHWND CreateParentChild ListMindowClass Name②然后,在堆栈上Class Style①首先,用 AfxRegister Class9或堆中创建一个Menu or d函数创建一个窗口类CWnd类对象④: Create Window⑤窗口管理器告知③调用CWn的成员函数再次创建窗口每个窗口对象在Create(0,该函数自身窗口句柄保存到屏幕上绘制自己调用图1-4中看到的CWnd中Create Window(函数图1-6应用两个对象创建MFC窗口尽管窗口应用程序的用户界面可以由几十个、甚至几百个窗口构成,但是大多数窗口还是由不到十个的窗口类创建的。即使在应用程序中有一千个窗口,每个窗口也只能是三种基本类型之一:重叠窗口、弹出窗口或子窗口1.3怎样应用MFC创建一个窗口可以用MFC的CWnd类创建一个窗口CWnd wndBOOL b=wnd Create EX(EXStyle, ClassName, WindowName, Style, X, y, Width, Height, Parent, Menu,Param)第一行代码创建了一个CWnd类的对象,第二行通过调用 Windows api函数 Create WindowEx()创建了真正的窗口。HWND hwnd=: Create Window EX(EXStyle, ClassName, WindowName, Style, x, y, Width, Height, Parent,Instance, Param)因为CWnd类只是封装了用于创建窗口的 WindOws api函数 Create Windowex(),因此从本质上讲,创建窗口所必须的参数在AP环境和MFC环境中是相同的■参数 Style和 ExStyle决定窗口的“外观″和类型(重叠、弹出、子窗口)。参数 ClassName决定在创建窗口时使用的窗口类。参数 Window name决定窗口标题内容(如果窗口标题有内容)。■参数x,y, Width和 Height决定窗口的位置和大小。■参数 Parent指向拥有该窗口的窗口指针(如果有这样的窗口)。■参数Menu指向内存中的一个对象,作为它的菜单使用—除非创建一个子窗口,如果是这样的话,那么该参数是帮助父窗口识别子窗口的 INumber■参数 Instance识别该窗口属于哪个应用程序,以便发送到该窗口的消息能被发送到正确的应用程序的消息队列中。CWnd类填入 Instance参数。■参数 Param是在创建窗口时由窗口类使用的指针,该指针是指向附加信息的非强制性结构的指针。返回的hwnd参数是指向创建的窗口对象的指针,但在未创建任何窗口时,该参数返回值为NULL。窗口句柄自动地保存在CWnd类的 m hWnd成员变量中,这在前面的图1-6中可以看到。6第一部分基础知识China-pub.com下载现在既然已了解了有关创建窗口的基本知识,那么让我们进一步来看看填写这些参数的规则。规则1.窗口名称参数该参数是一个零结尾的文本串,用该串指明在窗口标题栏中显示的内容。如果窗口没有标题栏,该参数可以为零(0)然而,某些通用控件也使用该参数。例如,按钮控件把该参数的內容放在按钮的表面。在创建窗口标题栏后,可以用类CWnd的成员函数 Set window text()来改变窗口标题栏的名称。2.风格和扩展风格参数这两个是32位的参数,用来指定创建什么类型的窗口。可以选择多种类型,如下面的例子所示WS CHILDWS VISIBLE窗口风格参数的作用包括■用于创建三种基本窗口类型的风格,用 WM CHILD创建一个子窗口;用 WM POPUP创建一个弹出窗口。WM OVERLAPPED创建一个重叠窗口。如果不为窗口指定任何一种风格,那么窗口风格默认为 WM OVERLAPPED。■用以增添窗口的非客户区特色的风格。例如,可以用 WS VSCROLL为窗口添加一个垂直滚动条,如图1-7所示其他非客户区窗口风格。WS CAPTION WS_ MINIMIZEBOXWS SYSMENUWS MAXIMIZEBOX若在 Create Window()中定义Emp如果选取了最小化或最大化按了菜单条,则菜单条出现,File edit view钮则关闭按钮出现它不是一个子窗口WS VSCROLL(使窗口可VS DISABLEWS HSCROLL(禁止窗口输入)图1-7非客户窗口风格用来增添窗口的特色■由毎个通用控件定义的风格。例如, BS FLAT按钮风格告诉按钮控件绘制-个二维按■用来使窗口可视、可操作和/或初始最大化的风格。■用来标识控件组起始控件的风格,或者当用户敲击Tab键控制焦点在窗口中变化时,用来指示哪个控件有资格获得输入焦点的风格。想了解更多的有关窗口风格的例子,请参阅附录A。在创建窗口以后,可以用CWnd的成员函数 Modify Style()和 Modify styleEx()改变窗口风格。某些风格可能要求重画窗口,这时,可以给 Modify Style()函数添加第三个参数,自动激发类CWnd的成员函数 Set window pose()做重画窗囗工作CMa°dcc0l第章窗口7「下载CWnd wndwnd Modify style(O,WS BORDER,SWP NOZORDER)事实上,给 Modify style(或 Modify stylee(添加任何第三个参数,都需要添加下面的Setwindowpos()选项: SWP NOZORDER、 SWP NOMOVE、 SWP NOACTIVATE和SWP SHOW。注意有时候,甚至一个重画的窗口可能与新风格不相容,尤其对通用控件窗口来说更是这样。因为单个窗口决定重画窗口时使用什么风格。在这种情况下,唯一的办法是在事先存储已有窗口的风格和其他参数后,销毁和重建该窗口。3.X和Y位置参数这是两个32位的参数,用于以像素为单位指定窗口的位置。创建重叠窗口和弹出窗口时Ⅹ和Y是相对于桌面窗口左上角的位置。而创建子窗口时,X和Y是相对于父窗口客户区的左上角位置。如果把X和Y参数都设置为 CW USEDEFAULT,那么系统将自动为窗口选定一位置。系统层叠排列这些新窗口(见图1-8)第一窗口下一个窗口第三个窗口图1-8 CW USEDEFAULT允许系统自动设定窗口位置然而,如果X和Y参数都设置为 CW USEDEFAULT,那么子窗口在创建的时候,总被创建在(0,0)的位置创建窗口以后,可以用类CWnd的成员函数 Move window()移动窗口4.宽度和高度参数这是两个32位的参数,用于以像素为单位指定窗口的大小。如果将参数 Width和 Height都设置为 CW USEDEFAULT,则系统将根据桌面窗口的大小,自动选定窗口的大小。然而,对于一个子窗口来说,系统将创建一个长和宽均为0的窗口。如果窗口的风格是 WS MINIMIZE或 WS MAXIMIZE,那么系统将忽视用户为Wdth和 Height设置的任何值。创建窗口以后,可以用类CWnd的成员函数 Move Window()重新设置窗口的大小5. Z-Order当几个窗口占据屏幕上同一区域时,z-Orde决定哪个窗口显示在哪个窗口之上。ZOrder(Z顺序)中的Z来源于坐标Ⅹ-¥-Z轴的Z轴,其中Z轴垂直屏幕,并由屏幕指向外面。当窗口最初被创建或选中时,则窗口将出现在z- Order的顶层。然而,该窗口永远不可能出现在个最顶层窗口的上面,除非该窗口也是最顶层的窗口。“最顶层”窗口用 WS EX TOPMOST窗口风格创建,并显示在所有非最顶层窗口的上面,而与该窗口是不是当前选中的窗口无关。创建窗口后,可以用CWnd的成员函数 Set Window poso改变窗口的Z顺序。6.父窗口或物主窗口参数该参数是指向类Cwnd对象的指针,根据创建的窗口类型标识是父窗口还是物主窗口第一部分基础知识ChinapUb CoM下载(Owner)如果创建的是一个子窗口,那么用该参数来标识它的父窗口(该子窗口所放置的并为之所截断的窗口)。该值不能为NULL。子窗口只能出现在它的父窗口里面,当父窗口被销毁时它们也被销毁,并且当父窗口被隐藏或最小化时它们也被隐藏。如果创建的是重叠窗口或弹出窗口,用该参数来标识物主窗口。如果该值为NULL,则桌面窗口成为物主窗口。从属窗口总是显示在它们的主窗口上面,并且随着物主窗口的销毁而被销毁;物主窗口最小化时,则从属窗口被隐藏;但当物主窗口被隐藏时,从属窗口并不被隐藏。个子窗口可能是另一个子窗口的父窗口,但绝不可能是一个物主窗口。如果试图使个子窗口成为一个物主窗口,那么系统只能使那个子窗口的最顶层窗口作为物主窗口。图1-9是这些关系的概述。②子窗口对象被创建,并显示在父窗口中WindowParent/wnerWindowObject①重叠或弹出窗口对Owned象被创建,并显示ndow在屏幕上③弹出或重叠窗口对象被创建,并显示在父窗口中图1-9物主、父、子窗口的层次关系可以用CWnd的成员函数 Setowner()改变已有窗口的物主窗囗,用CWnd的成员函数Setparent()改变父窗囗。7.菜单或控件ID参数该参数用来标识菜单(Menu)句柄或控件( Control)ID,这要依赖于创建的窗口是子窗口重叠窗口,还是弹出窗口。■如果创建的是一个子窗口,用该参数标识控件Ⅰ,控件⑩通常用来帮助父窗口识别子窗口。因为该参数寻求一个 HMENU变量,因此,需要用 HMENU类型重载变量定义控件ID。例如,如果子窗口的控件⑩是102,应该用如下方法定义它(HMENU)102如果创建的是一个重叠窗口或弹出窗口,用该参数定义窗口的菜单。若该值为NULL,则菜单默认为在该窗口的窗口类中定义的任何菜单;如果窗口类也没有指定的菜单,则该窗口在创建时没有菜单。可以用下面的方法为该参数加载一个菜单HMENU hMenu=: LoadMenu(Afx GetlnstanceHandle (), MAKEINTRESOURCE (XX)CAMa°eol第l章窗口下载这里的xx是应用程序资源里面的菜单ID( Menu id)。可以用CWnd的 SetDlg CtrlID()改变已有子窗口的ID。用类CWnd的成员函数 Setmenu()改变一个重叠窗口或弹出窗口的菜单。8.实例前面已提到,CWnd类将填入该参数。CWnd通过调用 Afx GetInstancehandle()获得该实例( nstance)。一个应用程序的实例从本质上标识了哪个程序在内存里。 Afx GetInstancehandle()是由MFC库提供的静态函数9参数该32位参数( Parameter)是可选的。它通常是指向一个结构或者类对象的指针,而该结构或者类对象是创建某种类型的窗口时需要提供的。例如,当用 MDICLIENT窗口类创建窗口时,需要该参数提供一个 CLIENTCREATESTRUCT结构的指针。10.类名参数类名( Class name)参数是一个零结尾字符串,当创建一个窗囗时,用来标识使用那个窗囗类。关于窗口类和窗口处理,将在本章后面的内容中详细讨论。该参数不能为NULL,在创建个非常一般的MFC窗口时,使用 AfxRegisterWndClass(0)填入该参数。1.4怎样使用MFC销毁一个窗口如前面所提到的一样,删除一个MFC窗口可能有些烦琐,必须按下面的顺序删除两个对象pWnd->Destroy Window(); //destroys Window Objectdelete pWnd;/destroys Cwnd object也可以只删除CWnd对象,因为 Destroy Window()是从CWnd的析构函数中调用的,但不提倡使用这种方法。销毁一个窗口而不先调用 Destroy Window()函数,将使某些析构消息不能被任何从Cwnd派生的类处理。你几乎不需自己销毁一个窗口,用户或系统通常会做这项工作。如果需要在销毁窗口的同时销毁CWnd对象,则应该在CWnd的派生类中添加下面的重载函数CYourWnd: PostNcDestroy()delete thiPostNcDestroy()是销毁窗口前调用的最后一个成员函数。但是,几乎不需对该函数进行重载,因为Cwnd和派生类一般是嵌在另一个类中或建立在堆栈中的。1.4.1捆绑到一个已有的窗口如果一个窗口是用 WindOws api在应用程序建立之前或外面创建的,并且需要把它封装到CWnd类中,可以用下面的语句实现:CWnd wndwnd Attach(hwnd)这里的hwnd是已有窗口的句柄。 Attach()只是把CWnd的成员变量 m hWnd赋给hwnd。也可以使用 CWnd: FromHandle(hwnd),它查看是否有CWnd对象已经封装了该窗口句柄并返回该CWnd对象的指针。如果不存在这样的Cwnd对象,将创建一个临时对象。如果是临10第一部分基础知识CAina-pubcoM下载时对象,则不要使用该指针,因为在应用程序空闲的时候,该指针指向的对象将被删除。1.42窗口类前面已提及,一个窗口类不是一个C++类,而是早于并存在于C++之外的窗口专有的类窗口类的作用就像一个模板,可以由此创建其他窗口,并可共享某些特征,包括下面所示的特征:类风格包括能给予窗口的一些微小的特征。类图标如果窗口有图标,用它来指定在窗口的左上角处所画的图标类菜单如果窗口有菜单,用它来指定窗口中显示的菜单。类光标当光标通过窗口的客户区时,用它来指定显示哪种鼠标形状。背景色定义用什么颜色来擦除窗口的背景色。窗口的客户区将显示该颜色。窗口进程定义处理任何发送到该窗口的消息时应该调用的函数。定义窗口进程可能是窗口类唯一最重要的前提。14.3窗口进程窗口与环境的交互是通过发送和接收消息来实现的。如果系统要求窗口自己进行绘制,系统给它发送一个 WM PAINT消息;如果系统要求窗口销毁自己,则发送一个WM DESTROY消息。这些消息都由窗口的窗口进程处理,该窗口进程的地址在窗口类中定义。对于发送到由相同的窗口类创建的窗口的消息,系统采用完全相同的窗口进程进行处理。相同的窗口进程是怎样跟踪所有的窗口的呢?它是怎么知道窗口A画在(10,34),而窗口B画在(56,21)呢?所有这些工作的完成只需使用窗口的窗口对象例如,所有用按钮窗口类创建的窗口,都使用相同的按钮窗口进程。如果一个WM PAINT消息发送到其中任何一个窗口,则按钮窗口进程根据每个窗口的窗口对象指定的大小、位置和风格画出确切的按钮(见图1-10)窗口对象③" BUTTON"的窗口进程搜索窗口对象,以查明绘制什么类型的按钮,如果风格是Check box",则绘制一个复选框BUTTON"s父窗口区①用“ BUTTON"窗Find whab口类创建的窗口WndProc=Drection厂 Match caseBUTTON"S④如果风格是“Push⑤窗口进程也搜索窗口对象以②通过发送一个 WM PAINT消Button”,则窗口进查明在哪里绘制这些控件窗息到窗口进程,窗口管理器程绘制一个按钮告诉每个窗口绘制自己图1-10按钮窗口进程使用窗口对象指定对哪个窗口进行操纵
用户评论
谢谢博主!
简单看看还行
不是原版,垃圾
还行 就是图比较少