1深入浅出MFC笔记用AppWizard产生一个MDI工程T(无OLE等支持),AppWizard创建了一系列文件,构成了一个应用程序框架。这些文件分四类:头文件(.h),实现文件(.cpp),资源文件(.rc),模块定义文件(.def),等。构成应用程序的对象图1-1解释了该应用程序的结构,箭头表示信息流向。从CWinApp、CDocument、CView、CMDIFrameWnd、CMDIChildWnd类对应地派生出CTApp、CTDoc、CTView、CMainFrame、CChildFrame五个类,这五个类的实例分别是应用程序对象、文档对象、视对象、主框架窗口对象和文档边框窗口对象。主框架窗口包含了视窗口、工具条和状态栏。表1-1AppWizard所生成的头文件头文件用途stdafx.h标准AFX头文件resource.h定义了各种资源IDt.h#includeresource.h定义了从CWinApp派生的应用程序对象CTAppchildfrm.h定义了从CMDIChildWnd派生的文档框架窗口对象CTChildFramemainfrm.h定义了从CMDIFrameWnd派生的框架窗口对象CMainFrametdoc.h定义了从CDocument派生的文档对象CTDoctview.h定义了从CView派生的视图对象CTView2表1-2AppWizard所生成的实现文件实现文件所包含的头文件实现的内容和功能stdafx.cpp#includestdafx.h用来产生预编译的类型信息。t.cpp#includestdafx.h#includet.h#includeMainFrm.h#includechildfrm.h#includetdoc.h#includetview.h定义CTApp的实现,并定义CTApp类型的全局变量theApp。childfrm.cpp#inlcudestdafx.h#includet.h#include“childfrm.h”实现了类CChildFramechildfrm.cpp#inlcudestdafx.h#includet.h#includechildfrm.h实现了类CMainFrametdoc.cpp#includestdafx.h#includet.h#includetdoc.h实现了类CTDoctview.cpp#includestdafx.h#includet.h#includetdoc.h#includetview.h实现了类CTview3从表1-2中的包含关系一栏可以看出:CTApp的实现用到所有的用户定义对象,包含了他们的定义;CView的实现用到CTdoc;其他对象的实现只涉及自己的定义;构成应用程序的对象之间的关系图1-2所示的类都是从CObject类派生出来的;所有处理消息的类都是从CCmdTarget类派生的。如果是多文档应用程序,文档模板使用CMultiDocTemplae,主框架窗口从CMdiFarmeWnd派生,它包含工具条、状态栏和文档框架窗口。文档框架窗口从CMdiChildWnd派生,文档框架窗口包含视,视从CView或其派生类派生。表2-1MFCObject和WindowsObject的对应关系描述Windows句柄MFCObject窗口HWNDCWndandCWnd-derivedclasses设备上下文HDCCDCandCDC-derivedclasses菜单HMENUCMenu笔HPENCGdiObject类,CPen和CPen-derivedclasses刷子HBRUSHCGdiObject类,CBrush和CBrush-derivedclasses字体HFONTCGdiObject类,CFont和CFont-derived4classes位图HBITMAPCGdiObject类,CBitmap和CBitmap-derivedclasses调色板HPALETTECGdiObject类,CPalette和CPalette-derivedclasses区域HRGNCGdiObject类,CRgn和CRgn-derivedclasses图像列表HimageLISTCimageList和CimageList-derivedclasses套接字SOCKETCSocket,CAsynSocket及其派生类表2-1中的OBJECT分以下几类:1.Windows对象,2.设备上下文对象,3.GDI对象(BITMAP,BRUSH,FONT,PALETTE,PEN,RGN),4.菜单,5.图像列表,6.网络套接字接口MFC窗口类CWnd(1)窗口创建函数:主要讨论函数Create和CreateEx。它们封装了Win32窗口创建函数::CreateWindowEx。Create的原型如下:BOOLCWnd::Create(LPCTSTRlpszClassName,LPCTSTRlpszWindowName,DWORDdwStyle,constRECT&rect,CWnd*pParentWnd,UINTnID,CCreateContext*pContext)Create是一个虚拟函数,用来创建子窗口(不能创建桌面窗口和POPUP窗口)。CWnd的基类可以覆盖该函数,例如边框窗口类等覆盖了该函数以实现边框窗口的创建,视类则使用它来创建视窗口。5Create调用了成员函数CreateEx。CWnd::CreateEx的原型如下:BOOLCWnd::CreateEx(DWORDdwExStyle,LPCTSTRlpszClassName,LPCTSTRlpszWindowName,DWORDdwStyle,intx,inty,intnWidth,intnHeight,HWNDhWndParent,HMENUnIDorHMenu,LPVOIDlpParam)CreateEx有11个参数,它将调用::CreateWindowEx完成窗口的创建,这11个参数对应地传递给::CreateWindowEx。参数指定了窗口扩展风格、“窗口类”、窗口名、窗口大小和位置、父窗口句柄、窗口菜单和窗口创建参数。2)窗口销毁函数例如:DestroyWindow函数销毁窗口PostNcDestroy(),销毁窗口后调用,虚拟函数3)用于设定、获取、改变窗口属性的函数,例如:SetWindowText(CStringtiltle)设置窗口标题GetWindowText()得到窗口标题SetIcon(HICONhIcon,BOOLbBigIcon);设置窗口像标GetIcon(BOOLbBigIcon);得到窗口像标GetDlgItem(intnID);得到窗口类指定ID的控制子窗口GetDC();得到窗口的设备上下文SetMenu(CMenu*pMenu);设置窗口菜单GetMenu();得到窗口菜单…4)用于完成窗口动作的函数6用于更新窗口,滚动窗口,等等。一部分成员函数设计成或可重载(Overloaded)函数,或虚拟(Overridden)函数,或MFC消息处理函数。这些函数或者实现了一部分功能,或者仅仅是一个空函数。如:有关消息发送的函数:SendMessage(UINTmessage,WPARAMwParam=0,LPARAMlParam=0);给窗口发送发送消息,立即调用方式PostMessage((UINTmessage,WPARAMwParam=0,LPARAMlParam=0);给窗口发送消息,放进消息队列…有关改变窗口状态的函数MoveWindow(LPCRECTlpRect,BOOLbRepaint=TRUE);移动窗口到指定位置ShowWindow(BOOL);显示窗口,使之可见或不可见….实现MFC消息处理机制的函数:virtualLRESULTWindowProc(UINTmessage,WPARAMwParam,LPARAMlParam);窗口过程,虚拟函数virtualBOOLOnCommand(WPARAMwParam,LPARAMlParam);处理命令消息…消息处理函数:OnCreate(LPCREATESTRUCTlpCreateStruct);MFC窗口消息处理函数,窗口创建时由MFC框架调用OnClose();MFC窗口消息处理函数,窗口创建时由MFC框架调用…其他功能的函数7CWnd的导出类是类型更具体、功能更完善的窗口类,它们继承了CWnd的属性和方法,并提供了新的成员函数(消息处理函数、虚拟函数、等等)。在MFC下创建一个窗口对象MFC下创建一个窗口对象分两步,首先创建MFC窗口对象,然后创建对应的Windows窗口。在内存使用上,MFC窗口对象可以在栈或者堆(使用new创建)中创建。具体表述如下:创建MFC窗口对象。通过定义一个CWnd或其派生类的实例变量或者动态创建一个MFC窗口的实例,前者在栈空间创建一个MFC窗口对象,后者在堆空间创建一个MFC窗口对象。调用相应的窗口创建函数,创建Windows窗口对象。例如:在前面提到的AppWizard产生的源码中,有CMainFrame(派生于CMDIFrame(SDI)或者CMDIFrameWnd(MDI))类。它有两个成员变量定义如下:CToolBarm_wndToolBar;CStatusBarm_wndStatusBar;当创建CMainFrame类对象时,上面两个MFCObject也被构造。CMainFrame还有一个成员函数OnCreate(LPCREATESTRUCTlpCreateStruct),它的实现包含如下一段代码,调用CToolBar和CStatusBar的成员函数Create来创建上述两个MFC对象对应的工具栏HWND窗口和状态栏HWND窗口:intCMainFrame::OnCreate(LPCREATESTRUCTlpCreateStruct){…if(!m_wndToolBar.Create(this)||!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)){TRACE0(Failedtocreatetoolbar\n);return-1;//failtocreate8}if(!m_wndStatusBar.Create(this)||!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT))){TRACE0(Failedtocreatestatusbar\n);return-1;//failtocreate}…}在Windows窗口的创建过程中,将发送一些消息,如:在创建了窗口的非客户区(Nonclientarea)之后,发送消息WM_NCCREATE;在创建了窗口的客户区(clientarea)之后,发送消息WM_CREATE;窗口的窗口过程在窗口显示之前收到这两个消息。如果是子窗口,在发送了上述两个消息之后,还给父窗口发送WM_PARENATNOTIFY消息。其他类或风格的窗口可能发送更多的消息,具体参见SDK开发文档在MFC下窗口的销毁窗口对象使用完毕,应该销毁。在MFC下,一个窗口对象的销毁包括HWND窗口对象的销毁和MFC窗口对象的销毁。一般情况下,MFC编程框架自动地处理了这些。(1)对CFrameWnd和CView的派生类这些窗口的关闭导致销毁窗口的函数DestroyWindow被调用。销毁Windows窗口时,MFC框架调用的最后一个成员函数是OnNcDestroy函数,该函数负责Windows清理工作,并在最后调用虚拟成员函数PostNcDestroy。CFrameWnd和CView的PostNcDestroy调用deletethis删除自身这个MFC窗口对象。所以,对这些窗口,如前所述,应在堆(Heap)中分配,而且,不要对这些对象使用delete操作。9(2)对WindowsControl窗