深入浅出MFC笔记.docx

上传人:小飞机 文档编号:3635010 上传时间:2023-03-14 格式:DOCX 页数:37 大小:52.71KB
返回 下载 相关 举报
深入浅出MFC笔记.docx_第1页
第1页 / 共37页
深入浅出MFC笔记.docx_第2页
第2页 / 共37页
深入浅出MFC笔记.docx_第3页
第3页 / 共37页
深入浅出MFC笔记.docx_第4页
第4页 / 共37页
深入浅出MFC笔记.docx_第5页
第5页 / 共37页
亲,该文档总共37页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《深入浅出MFC笔记.docx》由会员分享,可在线阅读,更多相关《深入浅出MFC笔记.docx(37页珍藏版)》请在三一办公上搜索。

1、深入浅出MFC笔记深入浅出MFC笔记 用AppWizard产生一个MDI工程T,AppWizard创建了一系列文件,构成了一个应用程序框架。这些文件分四类:头文件,实现文件(.cpp),资源文件(.rc),模块定义文件(.def),等。 构成应用程序的对象 图1-1解释了该应用程序的结构,箭头表示信息流向。 从CWinApp、CDocument、CView、CMDIFrameWnd、CMDIChildWnd类对应地派生出CTApp、CTDoc、CTView、CMainFrame、CChildFrame五个类,这五个类的实例分别是应用程序对象、文档对象、视对象、主框架窗口对象和文档边框窗口对象。

2、主框架窗口包含了视窗口、工具条和状态栏。 表1-1 AppWizard所生成的头文件 头文件 stdafx.h 用途 标准AFX头文件 resource.h 定义了各种资源ID t.h #include resource.h 定义了从CWinApp派生的应用程序对象CTApp childfrm.h 定义了从CMDIChildWnd派生的文档框架窗口对象CTChildFrame mainfrm.h 定义了从CMDIFrameWnd派生的框架窗口对象CMainFrame tdoc.h tview.h 定义了从CDocument派生的文档对象CTDoc 定义了从CView派生的视图对象CTView

3、1 表1-2 AppWizard所生成的实现文件 实现文件 stdafx.cpp 所包含的头文件 #include stdafx.h 实现的内容和功能 用来产生预编译的类型信息。 定义CTApp的实现,并定义CTApp类型的全局变量theApp。 t.cpp # include stdafx.h # include t.h # include MainFrm.h # include childfrm.h #include tdoc.h #include tview.h childfrm.cpp #inlcude stdafx.h #include t.h #include “childfrm.

4、h” 实现了类CChildFrame childfrm.cpp #inlcude stdafx.h #include t.h #include childfrm.h 实现了类CMainFrame tdoc.cpp # include stdafx.h # include t.h # include tdoc.h 实现了类CTDoc tview.cpp # include stdafx.h # include t.h # include tdoc.h # include tview.h 实现了类CTview 2 从表1-2中的包含关系一栏可以看出:CTApp 的实现用到所有的用户定义对象,包含了

5、他们的定义;CView 的实现用到CTdoc;其他对象的实现只涉及自己的定义; 构成应用程序的对象之间的关系 图1-2所示的类都是从CObject类派生出来的;所有处理消息的类都是从CCmdTarget类派生的。如果是多文档应用程序,文档模板使用CMultiDocTemplae,主框架窗口从CMdiFarmeWnd派生,它包含工具条、状态栏和文档框架窗口。文档框架窗口从CMdiChildWnd派生,文档框架窗口包含视,视从CView或其派生类派生。 表2-1 MFC Object和Windows Object的对应关系 描述 Windows柄 HWND HDC 句MFC Object 窗口 设

6、备上下文 菜单 笔 CWnd and CWnd-derived classes CDC and CDC-derived classes HMENU HPEN CMenu CGdiObject类,CPen和CPen-derived classes CGdiObject类,CBrush和CBrush-derived classes CGdiObject类,CFont和CFont-derived 3 刷子 HBRUSH 字体 HFONT classes 位图 HBITMAP CGdiObject类,CBitmap和CBitmap-derived classes CGdiObject类,CPalett

7、eCPalette-derived classes 和调色板 HPALETTE 区域 HRGN CGdiObject类,CRgn和CRgn-derived classes CimageListclasses 和CimageList-derived 图像列表 HimageLIST 套接字 SOCKET CSocket,CAsynSocket及其派生类 表2-1中的OBJECT分以下几类: 1. 2. 3. 4. 5. 6. Windows对象, 设备上下文对象, GDI对象, 菜单, 图像列表, 网络套接字接口 MFC窗口类CWnd 窗口创建函数: 主要讨论函数Create和CreateEx。它

8、们封装了Win32窗口创建函数:CreateWindowEx。 Create的原型如下: BOOL CWnd:Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) Create是一个虚拟函数,用来创建子窗口。CWnd的基类可以覆盖该函数,例如边框窗口类等覆盖了该函数以实现边框窗口的创建,视类则使用它来创建视窗口。 4 Create调用了成员函数CreateEx。CWnd

9、:CreateEx的原型如下: BOOL CWnd:CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam) CreateEx有11个参数,它将调用:CreateWindowEx完成窗口的创建,这11个参数对应地传递给:CreateWindowEx。参数指定了窗口扩展风格、“窗口类”、窗口名、窗口大小

10、和位置、父窗口句柄、窗口菜单和窗口创建参数。 2)窗口销毁函数 例如: DestroyWindow函数 销毁窗口 PostNcDestroy( ),销毁窗口后调用,虚拟函数 3)用于设定、获取、改变窗口属性的函数,例如: SetWindowText(CString tiltle) 设置窗口标题 GetWindowText 得到窗口标题 SetIcon(HICON hIcon, BOOL bBigIcon);设置窗口像标 GetIcon( BOOL bBigIcon ) ;得到窗口像标 GetDlgItem( int nID);得到窗口类指定ID的控制子窗口 GetDC; 得到窗口的设备上下文

11、SetMenu(CMenu *pMenu); 设置窗口菜单 GetMenu;得到窗口菜单 4)用于完成窗口动作的函数 5 用于更新窗口,滚动窗口,等等。一部分成员函数设计成或可重载(Overloaded)函数,或虚拟(Overridden)函数,或MFC消息处理函数。这些函数或者实现了一部分功能,或者仅仅是一个空函数。如: 有关消息发送的函数: SendMessage( UINT message,WPARAM wParam = 0, LPARAM lParam = 0 ); 给窗口发送发送消息,立即调用方式 PostMessage( UINT message,WPARAM wParam = 0

12、, LPARAM lParam = 0 ); 给窗口发送消息,放进消息队列 有关改变窗口状态的函数 MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE ); 移动窗口到指定位置 ShowWindow(BOOL );显示窗口,使之可见或不可见 . 实现MFC消息处理机制的函数: virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam ); 窗口过程,虚拟函数 virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam )

13、;处理命令消息 消息处理函数: OnCreate( LPCREATESTRUCT lpCreateStruct );MFC窗口消息处理函数,窗口创建时由MFC框架调用 OnClose;MFC窗口消息处理函数,窗口创建时由MFC框架调用 其他功能的函数 6 CWnd的导出类是类型更具体、功能更完善的窗口类,它们继承了CWnd的属性和方法,并提供了新的成员函数。 在MFC下创建一个窗口对象 MFC下创建一个窗口对象分两步,首先创建MFC窗口对象,然后创建对应的Windows窗口。在内存使用上,MFC窗口对象可以在栈或者堆(使用new创建)中创建。具体表述如下: 创建MFC窗口对象。通过定义一个CW

14、nd或其派生类的实例变量或者动态创建一个MFC窗口的实例,前者在栈空间创建一个MFC窗口对象,后者在堆空间创建一个MFC窗口对象。 调用相应的窗口创建函数,创建Windows窗口对象。 例如:在前面提到的AppWizard产生的源码中,有CMainFrame类。它有两个成员变量定义如下: CToolBar m_wndToolBar; CStatusBar m_wndStatusBar; 当创建CMainFrame类对象时,上面两个MFC Object也被构造。 CMainFrame还有一个成员函数 OnCreate之后,发送消息WM_CREATE; 窗口的窗口过程在窗口显示之前收到这两个消息。

15、 如果是子窗口,在发送了上述两个消息之后,还给父窗口发送WM_PARENATNOTIFY消息。其他类或风格的窗口可能发送更多的消息,具体参见SDK开发文档 在MFC下窗口的销毁 窗口对象使用完毕,应该销毁。在MFC下,一个窗口对象的销毁包括HWND窗口对象的销毁和MFC窗口对象的销毁。一般情况下,MFC编程框架自动地处理了这些。 对CFrameWnd和CView的派生类 这些窗口的关闭导致销毁窗口的函数DestroyWindow被调用。销毁Windows窗口时,MFC框架调用的最后一个成员函数是OnNcDestroy函数,该函数负责Windows清理工作,并在最后调用虚拟成员函数PostNcD

16、estroy。CFrameWnd和CView的PostNcDestroy调用delete this删除自身这个MFC窗口对象。 所以,对这些窗口,如前所述,应在堆中分配,而且,不要对这些对象使用delete操作。 8 对Windows Control窗口 在它们的析构函数中,将调用DestroyWidnow来销毁窗口。如果在栈中分配这样的窗口对象,则在超出作用范围的时候,随着析构函数的调用,MFC窗口对象和它的Windows window对象都被销毁。如果在堆中分配,则显式调用delete操作符,导致析构函数的调用和窗口的销毁。 所以,这种类型的窗口应尽可能在栈中分配,避免用额外的代码来销毁窗

17、口。如前所述的CMainFrame的成员变量m_wndStatusBar和m_wndToolBar就是这样的例子。 对于程序员直接从CWnd派生的窗口 程序员可以在派生类中实现上述两种机制之一,然后,在相应的规范下使用。 设备描述表 设备描述表概述: 当一个应用程序使用GDI函数时,必须先装入特定的设备驱动程序,然后为绘制窗口准备设备描述表,比如指定线的宽度和颜色、刷子的样式和颜色、字体、剪裁区域等等。不像其他Win32结构,设备描述表不能被直接访问,只能通过系列Win32函数来间接地操作。 如同Windows“窗口类”一样,设备描述表也是一种Windows数据结构,用来描述绘制窗口所需要的信

18、息。它定义了一个坐标映射模式、一组GDI图形对象及其属性。这些GDI对象包括用于画线的笔,绘图、填图的刷子,位图,调色板,剪裁区域,及路径(Path)。 表2-2列出了设备描述表的结构和各项缺省值,表2-3列出了设备描述表的类型,表2-4显示设备描述表的类型。 表2-2 设备描述表的结构 属性 Background color 缺省值 Background color setting from Windows Control Panel (typically, white) Background mode OPAQUE Bitmap Brush Brush origin None WHITE_

19、BRUSH (0,0) 9 Clipping region Entire window or client area with the update region clipped, as appropriate. Child and pop-up windows in the client area may also be clipped Palette DEFAULT_PALETTE Current pen (0,0) position Device origin Upper left corner of the window or the client area Drawing mode

20、R2_COPYPEN Font SYSTEM_FONT (SYSTEM_FIXED_FONT for applications written to run with Windows versions 3.0 and earlier) Intercharacter 0 spacing Mapping mode MM_TEXT Pen BLACK_PEN Polygon-fill ALTERNATE mode Stretch mode BLACKONWHITE Text color Text color setting from Control Panel (typically, black)

21、Viewport extent (1,1) Viewport origin (0,0) Window extent (1,1) Window origin (0,0) 表2-3 设备描述表的分类 Display 显示设备描述表,提供对视频显示设备上的绘制操作10 的支持 Printer 打印设备描述表,提供对打印机、绘图仪设备上的绘制操作的支持 内存设备描述表,提供对位图操作的支持 Memory Information 信息设备描述表,提供对操作设备信息获取的支持 表2-4 显示设备描述表的分类 名称 Class Device Contexts Common Device Contexts P

22、rivate Device Contexts 使用设备描述表的步骤 要使用设备描述表,一般有如下步骤: 获取或者创建设备描述表; 必要的话,改变设备描述表的属性; 使用设备描述表完成绘制操作; 释放或删除设备描述表。 特点 提供对Win16的向后兼容 功能 在Windows系统的高速缓冲区,数量有限 Applicaion获取设备描述表时,Windows用缺省值初始化该设备描述表,Application使用它完成绘制操作,然后释放 多次使用过程中,每次设备描述表属性的任何修改或变化都会被保存,以支持快速绘制 没有数量限制,用完不需释放一次获取,多次使用 Common设备描述表通过:GetDC,:

23、GetDCEx,:BeginPaint来获得一个设备描述表,用毕,用:ReleaseDC或:EndPaint释放设备描述表; Printer设备描述表通过:CreateDC创建设备描述表,用:DeleteDC删除设备描述表。 11 Memory设备描述表通过:CreateCompatibleDC创建设备描述表,用:DeleteDC删除。 Information设备描述表通过:CreateIC创建设备描述表,用:DeleteDC删除。 改变设备描述表属性的途径 要改变设备描述表的属性,可通过以下途径: 用:SelectObject选入新的除调色板以外的GDI Object到设备描述表中; 对于调

24、色板,使用:SelectPalette函数选入逻辑调色板,并使用:RealizePalette把逻辑调色板的入口映射到物理调色板中。 用其他API函数改变其他属性,如:SetMapMode改变映射模式。 设备描述表在MFC中的实现 MFC提供了CDC类作为设备描述表类的基类,它封装了Windows的HDC设备描述表对象和相关函数。 1.CDC类有两个成员变量:m_hDC,m_hAttribDC,它们都是Windows设备描述表句柄。CDC的成员函数作输出操作时,使用m_Hdc;要获取设备描述表的属性时,使用m_hAttribDC。 2.在创建一个CDC类实例时,缺省的m_hDC等于m_hAtt

25、ribDC。如果需要的话,程序员可以分别指定它们。例如,MFC框架实现CMetaFileDC类时,就是如此:CMetaFileDC从物理设备上读取设备信息,输出则送到元文件上,所以m_hDC和m_hAttribDC是不同的,各司其责。还有一个类似的例子:打印预览的实现,一个代表打印机模拟输出,一个代表屏幕显示。 3.CDC封装:SelectObject(HDC hdc,HGDIOBJECT hgdiobject)函数时,采用了重载技术,即它针对不同的GDI对象,提供了名同而参数不同的成员函数: SelectObject(CPen *pen)用于选入笔; SelectObject(CBitmap

26、* pBitmap)用于选入位图; SelectObject(CRgn *pRgn)用于选入剪裁区域; SelectObject(CBrush *pBrush)用于选入刷子; SelectObject(CFont *pFont)用于选入字体; 至于调色板,使用SelectPalette(CPalette *pPalette,BOOL bForceBackground )选入调色板到设备描述表,使用RealizePalletter实现逻辑调色板到物理调色板的映射。 12 从CDC 派生出四个功能更具体的设备描述表类。层次如图2-3所示。 CCientDC 代表窗口客户区的设备描述表。其构造函数C

27、ClientDC(CWnd *pWin)通过:GetDC获取指定窗口的客户区的设备描述表HDC,并且使用成员函数Attach把它和CClientDC对象捆绑在一起;其析构函数使用成员函数Detach把设备描述表句柄HDC分离出来,并调用:ReleaseDC释放设备描述表HDC。 CPaintDC 仅仅用于响应WM_PAINT消息时绘制窗口,因为它的构造函数调用了:BeginPaint获取设备描述表HDC,并且使用成员函数Attach把它和CPaintDC对象捆绑在一起;析构函数使用成员函数Detach把设备描述表句柄HDC分离出来,并调用:EndPaint释放设备描述表HDC,而:BeginP

28、aint和:EndPaint仅仅在响应WM_PAINT时使用。 CMetaFileDC 用于生成元文件。 CWindowDC 代表整个窗口区(包括非客户区)的设备描述表。其构造函数CWindowDC(CWnd *pWin)通过:GetWindowDC获取指定窗口的客户区的设备描述表HDC,并使用Attach把它和CWindowDC对象捆绑在一起;其析构函数使用Detach把设备描述表HDC分离出来,调用:ReleaseDC释放设备描述表HDC。 MFC设备描述表类的使用 1. 使用CPaintDC、CClientDC、CWindowDC的方法 首先,定义一个这些类的实例变量,通常在栈中定义。然

29、后,使用它。 例如,MFC中CView对WM_PAINT消息的实现方法如下: void CView:OnPaint 13 / standard paint routine CPaintDC dc(this); OnPrepareDC(&dc); OnDraw(&dc); 在栈中定义了CPaintDC类型的变量dc,随着构造函数的调用获取了设备描述表;设备描述表使用完毕,超出其有效范围就被自动地清除,随着析构函数的调用,其获取的设备描述表被释放。 如果希望在堆中创建,例如 CPaintDC *pDC; pDC = new CPaintDC(this) 则在使用完毕时,用delete删除pDC:

30、delete pDC; 1. 使用CPaintDC、CClientDC、CWindowDC的方法 首先,定义一个这些类的实例变量,通常在栈中定义。然后,使用它。 例如,MFC中CView对WM_PAINT消息的实现方法如下: void CView:OnPaint / standard paint routine CPaintDC dc(this); OnPrepareDC(&dc); OnDraw(&dc); 14 在栈中定义了CPaintDC类型的变量dc,随着构造函数的调用获取了设备描述表;设备描述表使用完毕,超出其有效范围就被自动地清除,随着析构函数的调用,其获取的设备描述表被释放。 如

31、果希望在堆中创建,例如 CPaintDC *pDC; pDC = new CPaintDC(this) 则在使用完毕时,用delete删除pDC: delete pDC; 2. 直接使用CDC 需要注意的是:在生成CDC对象的时候,并不像它的派生类那样,在构造函数里获取相应的Windows设备描述表。最好不要使用:GetDC等函数来获取一个设备描述表,而是创建一个设备描述表。其构造函数如下: CDC:CDC m_hDC = NULL; m_hAttribDC = NULL; m_bPrinting = FALSE; 其析构函数如下: CDC:CDC if (m_hDC != NULL) :De

32、leteDC(Detach); 在CDC析构函数中,如果设备描述表句柄不空,则调用DeleteDC删除它。这是直接使用CDC时最好创建Windows设备描述表的理由。如果设备描述表不是创建15 的,则应该在析构函数被调用前分离出设备描述表句柄并用:RealeaseDC释放它,释放后m_hDC为空,则在析构函数调用时不会执行:DeleteDC。当然,不用担心CDC的派生类的析构函数调用CDC的析构函数,因为CDC:CDC不是虚拟析构函数。 直接使用CDC的例子是内存设备上下文,例如: CDC dcMem; /声明一个CDC对象 dcMem.CreateCompatibleDC(&dc); /创建

33、设备描述表 pbmOld = dcMem.SelectObject(&m_bmBall);/更改设备描述表属性 /作一些绘制操作 dcMem.SelectObject(pbmOld);/恢复设备描述表的属性 dcMem.DeleteDC; /可以不调用,而让析构函数去删除设备描述表 GDI对象: 在讨论设备描述表时,已经多次涉及到GDI对象。这里,需强调一下:GDI对象要选入Windows 设备描述表后才能使用;用毕,要恢复设备描述表的原GDI对象,并删除该GDI对象。 一般按如下步骤使用GDI对象: Create or get a GDI OBJECT hNewGdi; hOldGdi =

34、:SelectObject(hdc, hNewGdi) :SelectObject(hdc, hOldGdi) :DeleteObject(hNewGdi) 先创建或得到一个GDI对象,然后把它选入设备描述表并保存它原来的GDI对象;用毕恢复设备描述表原来的GDI对象并删除新创建的GDI对象。 需要指出的是,如果hNewGdi是一个Stock GDI对象,可以不删除。通过 HGDIOBJ GetStockObject( int fnObject / type of stock object 16 ); 来获取Stock GDI对象。 MFC GDI对象: CGdiObject的构造函数仅仅让m

35、_hObject为空。如果m_hObject不空,其析构函数将删除对应的Windows GDI对象。MFC GDI对象和Windows GDI对象的关系如图2-5所示。 使用MFC GDI类的使用: 首先创建GDI对象,可分一步或两步创建。一步创建就是构造MFC对象和Windows GDI对象一步完成;两步创建则先构造MFC对象,接着创建Windows GDI对象。然后,把新创建的GDI对象选进设备描述表,取代原GDI对象并保存。最后,恢复原GDI对象。例如: void CMyView:OnDraw(CDC *pDC) CPen penBlack; /构造MFC CPen对象 if (penB

36、lack.CreatePen(PS_SOLID, RGB(0, 0, 0) CPen *pOldPen = pDC-SelectObject(&penBlack); /选进设备表,保存原笔 pDC-SelectObject(pOldPen); /恢复原笔 else 17 和在SDK下有一点不同的是:这里没有DeleteObject。因为执行完OnDraw后,栈中的penBlack被销毁,它的析构函数被调用,导致DeleteObject的调用。 还有一点要说明: pDC-SelectObject(&penBlack)返回了一个CPen *指针,也就是说,它根据原来PEN的句柄创建了一个MFC C

37、Pen对象。这个对象是否需要删除呢?不必要,因为它是一个临时对象,MFC框架会自动地删除它。当然,在本函数执行完毕把控制权返回给主消息循环之前,该对象是有效的。 关于临时对象及MFC处理它们的内部机制,将在后续章节详细讨论。 至此,Windows编程的核心概念:窗口、GDI界面已经陈述清楚,特别揭示了MFC对这些概念的封装机制,并简明讲述了与这些Windows Object对应的MFC类的使用方法。还有其他Windows概念,可以参见SDK开发文档。在MFC的实现上,基本上仅仅是对和这些概念相关的Win32函数的封装。如果明白了MFC的窗口、GDI界面的封装机制,其他就不难了。 18 3. C

38、Object类 CObject是大多数MFC类的根类或基类。CObject类有很多有用的特性:对运行时类信息的支持,对动态创建的支持,对串行化的支持,对象诊断输出,等等。MFC从CObject派生出许多类,具备其中的一个或者多个特性。程序员也可以从CObject类派生出自己的类,利用CObject类的这些特性。 本章将讨论MFC如何设计CObject类的这些特性。首先,考察CObject类的定义,分析其结构和方法对CObject特性的支持。然后,讨论CObject特性及其实现机制。 1. CObject的结构 以下是CObject类的定义: class CObject public: /与动态

39、创建相关的函数 virtual CRuntimeClass* GetRuntimeClass const; 析构函数 virtual CObject; / virtual destructors are necessary /与构造函数相关的内存分配函数,可以用于DEBUG下输出诊断信息 void* PASCAL operator new(size_t nSize); void* PASCAL operator new(size_t, void* p); void PASCAL operator delete(void* p); #if defined(_DEBUG) & !defined(_

40、AFX_NO_DEBUG_CRT) void* PASCAL operator new(size_t nSize, LPCSTR lpszFileName, int nLine); #endif 19 /缺省情况下,复制构造函数和赋值构造函数是不可用的 /如果程序员通过传值或者赋值来传递对象,将得到一个编译错误 protected: /缺省构造函数 CObject; private: /复制构造函数,私有 CObject(const CObject& objectSrc); / no implementation /赋值构造函数,私有 void operator=(const CObject&

41、 objectSrc); / no implementation / Attributes public: /与运行时类信息、串行化相关的函数 BOOL IsSerializable const; BOOL IsKindOf(const CRuntimeClass* pClass) const; / Overridables virtual void Serialize(CArchive& ar); / 诊断函数 virtual void AssertValid const; virtual void Dump(CDumpContext& dc) const; / Implementation

42、 public: /与动态创建对象相关的函数 20 static const AFX_DATA CRuntimeClass classCObject; #ifdef _AFXDLL static CRuntimeClass* PASCAL _GetBaseClass; #endif ; 由上可以看出,CObject定义了一个CRuntimeClass类型的静态成员变量: CRuntimeClass classCObject 还定义了几组函数: 构造函数析构函数类, 诊断函数, 与运行时类信息相关的函数, 与串行化相关的函数。 其中,一个静态函数:_GetBaseClass;五个虚拟函数:析构函

43、数、GetRuntimeClass、Serialize、AssertValid、Dump。这些虚拟函数,在CObject的派生类中应该有更具体的实现。必要的话,派生类实现它们时可能要求先调用基类的实现,例如Serialize和Dump就要求这样。 静态成员变量classCObject和相关函数实现了对CObjet特性的支持。 2. CObject类的特性 下面,对三种特性分别描述,并说明程序员在派生类中支持这些特性的方法。 1. 对运行时类信息的支持 该特性用于在运行时确定一个对象是否属于一特定类,或者从一个特定类派生来的。CObject提供IsKindOf函数来实现这个功能。 从CObjec

44、t派生的类要具有这样的特性,需要: 定义该类时,在类说明中使用DECLARE_DYNAMIC宏; 21 在类的实现文件中使用IMPLEMENT_DYNAMIC(CLASSNAME,BASECLASS)宏。 1. 对动态创建的支持 前面提到了动态创建的概念,就是运行时创建指定类的实例。在MFC中大量使用,如前所述框架窗口对象、视对象,还有文档对象都需要由文档模板类(CDocTemplate)对象来动态的创建。 从CObject派生的类要具有动态创建的功能,需要: 定义该类时,在类说明中使用DECLARE_DYNCREATE宏; 定义一个不带参数的构造函数; 在类的实现文件中使用IMPLEMENT

45、_DYNCREATE宏; 使用时先通过宏RUNTIME_CLASS得到类的RunTime信息,然后使用CRuntimeClass的成员函数CreateObject创建一个该类的实例。 例如: CRuntimeClass* pRuntimeClass = RUNTIME_CLASS(CNname) /CName必须有一个缺省构造函数 CObject* pObject = pRuntimeClass-CreateObject; /用IsKindOf检测是否是CName类的实例 Assert( pObject-IsKindOf(RUNTIME_CLASS(CName); 1. 对序列化的支持 “序列

46、化”就是把对象内容存入一个文件或从一个文件中读取对象内容的过程。从CObject派生的类要具有序列化的功能,需要: 定义该类时,在类说明中使用DECLARE_SERIAL宏; 定义一个不带参数的构造函数; 在类的实现文件中使用IMPLEMENT_SERIAL宏; 覆盖Serialize成员函数。 对运行时类信息的支持、动态创建的支持、串行化的支持层,这三种功能的层次依次升高。如果对后面的功能支持,必定对前面的功能支持。支持动态创建的话,必定支持运行时类信息;支持序列化,必定支持前面的两个功能,因为它们的声明和实现都是后者包含前者。 1. 综合示例: 22 定义一个支持串行化的类CPerson: class CPerson : public CObject public: DECLARE_SERIAL( CPerson ) / 缺省构造函数 CPerson; CString m_name; WORD m_number; void Serialize( CArchive& archive

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号