北风网mfc系列第五讲 mfc体系结构_第1页
北风网mfc系列第五讲 mfc体系结构_第2页
北风网mfc系列第五讲 mfc体系结构_第3页
北风网mfc系列第五讲 mfc体系结构_第4页
北风网mfc系列第五讲 mfc体系结构_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

北风网MFC系列教程·第五讲MFC体系结构深入理解MicrosoftFoundationClasses的分层架构与核心机制LECTURE05课程回顾与学习路线本讲是MFC系列课程的知识枢纽,将前四讲零散的编程基础整合为体系化的框架认知,为后续深入开发奠定架构思维基础。前置知识积累前四讲覆盖了MFC发展历史、开发环境配置、Windows消息机制与基本类封装,为理解体系结构提供了必要的前置知识。掌握这些基础内容,是进入框架深层学习的必经之路。本讲核心目标本讲从宏观视角拆解MFC框架的分层架构、核心类关系与运行机制,帮助学员建立完整的框架级认知。通过系统梳理,将零散知识点串联成有机整体。后续深入方向后续课程将在本讲架构基础上深入讲解消息映射、文档/视图、动态创建等具体机制的实现细节。理解本讲内容,是掌握高级开发技巧的重要前提。Contents目录MFC体系结构全貌:从核心对象模型到应用程序生命周期的五大模块纵览。01MFC概述与开发定位02MFC核心对象模型03文档/视图架构体系04消息映射与命令路由05应用程序生命周期CHAPTER01MFC概述与开发定位理解微软基础类库的本质定位与核心价值DefinitionMFC的定义与双重身份MFC既是封装Win32API的C++类库,也是提供工程骨架的应用程序框架,通过浅层封装在开发效率与运行性能之间取得平衡。C++类库封装大部分WindowsAPI函数,将C风格的SDK接口转化为面向对象的类成员函数,降低调用复杂度。Win32API应用程序框架新建工程自动生成消息循环、窗口注册等基础代码骨架,使开发者聚焦业务逻辑而非底层重复编码。自动骨架浅层封装策略保留接近原生SDK的执行效率,通用性与性能之间的损失极小,适合企业级Windows桌面应用开发。近原生性能ARCHITECTURECOMPARISONMFC与Win32SDK开发对比MFC通过面向对象封装大幅降低Windows开发复杂度,将SDK中数百行的窗口创建代码压缩为几行类实例化,是开发效率的关键跃升。TRADITIONALWin32SDK编程◆需手动注册窗口类、编写消息循环和WndProc回调函数,创建一个基础窗口通常需要100行以上代码◆资源管理依赖手动分配与释放,句柄泄露风险高,调试难度大且代码可维护性较差◆缺乏面向对象抽象,代码复用率低,大型项目架构难以扩展和维护100+行代码/基础窗口⚠️MODERNMFC框架编程✓CWnd类封装窗口创建与销毁,开发者只需派生并重写虚函数,基础窗口创建代码量降至10行以内✓内置文档/视图架构、消息映射、动态创建等高级机制,提供完整的工程骨架与自动化代码生成✓RAII自动资源管理,智能指针与容器类降低内存泄漏风险,显著提升代码健壮性≤10行代码/基础窗口🚀ENCODINGEVOLUTIONMFC版本演进与编码模式MFC经历了从多字节到Unicode的编码范式转换,开发者需根据VS版本选择正确的编码策略,_T宏是实现编码兼容的核心工具。VC++6.0时代默认使用多字节编码(MBCS),处理中文等非ASCII字符时容易出现乱码和缓冲区溢出问题MBCSVisualStudio2010起默认切换为Unicode编码,所有字符串以宽字符存储,从根本上解决了国际化兼容问题VS2010MFC提供_T宏实现编码自动适配:多字节环境展开为普通字符串,Unicode环境展开为L前缀宽字符字符串_T()跨版本迁移时需注意CString与std::string的互转,以及第三方库的编码接口是否支持Unicode输入MIGRATEApplicationTypesMFC支持的三类应用程序MFC通过统一的文档模板机制支持SDI、MDI和对话框三种界面类型,不同类型共享底层框架但呈现不同的用户交互模式。单文档界面(SDI)一次仅打开一个文档,如Windows记事本,适用于轻量级单任务场景使用CFrameWnd作为主框架窗口,文档模板关联单一文档类与视图类框架自动处理窗口创建、消息循环和文档序列化,开发者只需关注业务逻辑CFrameWnd多文档界面(MDI)支持同时打开多个文档子窗口,如早期Office套件,适用于复杂多任务场景使用CMDIFrameWnd主框架加CMDIChildWnd子框架,每个子窗口独立管理文档与视图支持窗口平铺、层叠等布局管理,菜单和工具栏可随活动子窗口动态切换CMDIFrameWnd对话框应用程序以CDialog为主窗口,无传统文档/视图结构,适用于工具类和配置类应用仅使用MFC框架的部分功能,如控件绑定和数据交换(DDX/DDV)机制通过资源编辑器可视化设计界面,控件与变量自动关联,简化数据验证流程DDX/DDVCHAPTER02MFC核心对象模型从CObject根类到完整类层次的面向对象封装体系MFCArchitectureCObject:MFC类层次的根类CObject作为MFC的根类提供运行时类信息、动态创建、序列化和诊断调试四大基础设施,是整个框架面向对象能力的基石。运行时类信息通过CRuntimeClass结构体记录类名、对象大小和继承链,支持类型判断和类信息查询IsKindOf()动态创建机制DYNCREATE宏对使对象可通过类名在运行时实例化,为文档模板的自动对象管理提供支撑DYNCREATE序列化支持Serialize()虚函数配合CArchive实现统一的文件读写接口,派生类重写即可获得持久化能力Serialize()诊断与调试Dump()输出对象状态,AssertValid()验证完整性,DEBUG_NEW宏追踪内存分配并检测泄漏Dump()ARCHITECTUREOVERVIEWMFC类层次结构总览MFC类层次以CObject为根,通过CCmdTarget、CWnd、CWinThread等关键节点构建出覆盖应用程序、窗口、文档、视图的完整面向对象体系。CCMDTARGET命令处理核心基类所有能接收和处理WM_COMMAND消息的类均派生自它,包括窗口类和文档类WM_COMMANDCWND窗口类型全覆盖CFrameWnd(框架窗口)、CView(视图)、CDialog(对话框)及CButton/CEdit等控件类CFrameWnd·CView·CDialogCWINTHREAD线程生命周期管理CWinApp作为应用对象控制全局初始化,用户界面线程支持多线程窗口管理CWinAppCDOCUMENT数据管理独立体系专注于数据存储与管理,通过文档模板与视图和框架窗口建立松耦合关联Doc-View松耦合MFCARCHITECTURE·CORECONCEPTSMFC对象与Windows对象的关系MFC对象是C++层面的类实例,Windows对象是操作系统层面的内部数据结构,两者通过句柄映射建立关联但生命周期不完全同步。MFC对象(C++层)是C++类的实例(如CWnd派生类对象),由程序通过构造函数创建,随析构函数调用而消亡。属于高层抽象,封装了Windows对象的功能并提供成员函数接口,使用者无需直接操作句柄。C++类实例Windows对象(系统层)是Windows操作系统的内部数据结构实例,由系统创建并分配资源,通过句柄(HANDLE)唯一标识。可被程序主动销毁,也可由用户操作触发销毁,生命周期独立于对应的MFC对象。HANDLE句柄映射与同步机制MFC对象通过m_hWnd等成员变量保存Windows对象句柄,建立一对一映射关系。创建分两步:先构造MFC对象(此时句柄为空),再调用Create成员函数创建Windows对象并填充句柄。m_hWnd映射MFCArchitecture运行时类信息与动态创建机制DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏对为MFC类注入运行时类型识别能力,DYNCREATE宏对在此基础上增加运行时动态实例化支持。运行时类型信息载体CRuntimeClass结构体记录类名、对象大小、基类指针和CreateObject函数指针,构成运行时类型信息的完整载体。CRuntimeClass运行时类型判断IsKindOf()沿基类CRuntimeClass链向上遍历,实现类似Javainstanceof的运行时类型判断功能。IsKindOf()工厂模式动态实例化DECLARE_DYNCREATE宏在类声明中添加CreateObject()静态方法和GetRuntimeClass()方法,支持工厂模式实例化。DYNCREATE文档模板自动创建文档模板通过CRuntimeClass指针自动创建文档、视图和框架对象,无需在代码中硬编码具体的类名。DocTemplateMFCArchitecture·Serialization序列化(Serialization)机制MFC通过CObject::Serialize()虚函数与CArchive归档对象构建了统一的对象持久化体系,支持嵌套对象的递归序列化与版本控制。01Serialize()虚函数配合CArchive对象实现读写统一接口,IsStoring()区分存储/加载模式,<<和>>操作符提供流式语法IsStoring()02DECLARE_SERIAL/IMPLEMENT_SERIAL宏对注册类的版本号和序列化函数指针,使CArchive能通过CRuntimeClass自动调度序列化CRuntimeClass03嵌套对象支持递归序列化:父类Serialize中调用基类Serialize,再处理自身成员,保证完整对象图的保存与恢复Recursive04CArchive内部维护对象引用表,自动处理指针去重,避免循环引用导致的无限递归和重复写入DedupChapter03文档/视图架构体系数据管理与界面显示的分离式架构设计Architecture文档/视图架构的核心思想文档/视图架构将数据管理与界面显示彻底分离,本质是MVC模式的Windows桌面实现,支持一文档多视图的灵活数据呈现方式。01文档(CDocument)专职数据存储与管理负责读取和写入持久化存储,提供数据接口供视图访问,不关心数据如何呈现02视图(CView)专职数据显示与交互附加到文档并关联框架窗口,从文档获取数据显示,将用户编辑操作回传给文档03一文档多视图支持同一份数据可同时以表格、图表、文本等不同视图呈现,文档通过UpdateAllViews()同步通知所有视图刷新04架构松耦合优势修改显示方式不影响数据逻辑,修改数据结构不影响界面代码,显著降低大型应用的维护复杂度COREARCHITECTURECDocument类:数据管理的核心CDocument通过Serialize()实现数据持久化,通过UpdateAllViews()驱动视图同步更新,是文档/视图架构中数据流的起点和控制中枢。Serialize()重写实现数据读写持久化配合CArchive完成文件保存与加载,是文档持久化的唯一入口。通过重载该函数,开发者可自定义数据序列化格式,支持二进制或文本存储模式。关键调用:CArchive»数据成员»文件流OnNewDocument()/OnOpenDocument()初始化处理文档初始化流程:新建时设置默认数据状态,打开时触发反序列化流程。框架自动调用,开发者可重写以添加自定义初始化逻辑。执行顺序:构造→OnNewDocument/OnOpenDocument→数据就绪DeleteContents()数据清理清理在文档关闭或重建前清理旧数据,防止内存泄漏。每次文档生命周期重置的必经环节,确保资源正确释放,为下一次文档复用做准备。触发场景:关闭文档、新建覆盖、异常恢复UpdateAllViews()视图同步同步通知所有关联视图刷新显示。pSender排除发起修改的视图避免重复更新,lHint和pHint传递增量更新线索,实现高效局部刷新。参数说明:pSender=修改源视图,lHint=更新类型,pHint=自定义数据MFCVIEWARCHITECTURECView类:数据呈现与交互CView通过OnDraw()完成数据可视化,通过OnUpdate()响应文档变更通知,通过GetDocument()建立数据访问通道,是用户与数据交互的桥梁。OnDraw(CDC*pDC)视图的核心绘制入口。框架在WM_PAINT消息触发时调用,开发者在此使用CDC完成所有图形和文字渲染。WM_PAINT·CDCOnUpdate()响应文档变更通知。根据lHint决定全量重绘还是局部更新,优化刷新性能。LPARAMlHintGetDocument()返回关联文档指针。视图通过此方法访问文档数据,保证数据访问路径单一且可控。DOCACCESS派生类扩展能力CScrollView支持大文档滚动、CEditView提供文本编辑、CFormView支持对话框式布局。3SUBCLASSESMFCDocument/ViewArchitecture文档模板:连接文档、视图与框架文档模板(CDocTemplate)通过CRuntimeClass指针在运行时动态创建并关联文档、视图和框架窗口,是文档/视图架构的粘合剂与调度中心。SDI与MDI模板CSingleDocTemplate用于SDI应用,CMultiDocTemplate用于MDI应用,两者均通过构造函数接收文档、框架、视图三个CRuntimeClass指针,实现运行时动态对象创建CRuntimeClass×3注册到应用程序AddDocTemplate()将模板注册到CWinApp对象,框架据此自动管理文档的新建、打开、保存和关闭全流程,实现文档生命周期统一管理CWinApp字符串资源维护文档模板维护字符串资源(IDR_XXX),包含文档类型名、文件扩展名、过滤器等信息,驱动文件对话框显示和系统注册表配置IDR_XXX多文档类型支持支持同一应用注册多个文档模板,实现一个程序管理多种文档类型(如同时支持文本文件和图片文件),扩展应用功能边界1App→NTypesMFCArchitectureCFrameWnd:视图的容器与外壳CFrameWnd作为视图的承载容器管理菜单栏、工具栏和状态栏等界面元素,同时承担命令消息路由的核心调度职责。非客户区元素管理框架窗口管理菜单栏、工具栏(CToolBar)、状态栏(CStatusBar)和停靠面板,将客户区完整交付给视图使用。支持动态工具栏停靠与浮动,提供灵活的界面布局能力。CToolBarSDI与MDI窗口体系SDI应用使用CFrameWnd作为主窗口,MDI应用使用CMDIFrameWnd主窗口搭配CMDIChildWnd子窗口管理多文档。两种架构共享统一的视图嵌入机制。SDI/MDI视图创建机制OnCreateClient()虚函数在框架创建时调用,负责创建视图对象并将其嵌入框架的客户区。开发者可重写此函数实现自定义视图布局,如拆分窗口或多视图组合。OnCreateClient命令消息路由命令路由起始于框架窗口:接收WM_COMMAND后按视图→文档→框架→应用的顺序分发,实现消息的智能传递。未处理命令最终由框架默认处理或丢弃。WM_COMMANDDATAFLOW文档/视图的完整数据流从用户操作到数据持久化,文档/视图架构通过"视图捕获→文档存储→广播通知→视图重绘"的闭环实现数据与界面的自动同步。01用户操作捕获视图通过消息处理函数(如OnLButtonDown)接收鼠标/键盘事件,解析用户意图View02数据写入文档视图调用GetDocument()获取文档指针,通过文档成员函数修改数据,保证修改入口统一Document03变更广播通知文档调用UpdateAllViews()向所有关联视图发送更新通知,附带变更类型提示参数Broadcast04视图重绘呈现OnUpdate()触发Invalidate(),框架发出WM_PAINT,OnDraw()从文档读取最新数据完成重绘RedrawCHAPTER04消息映射与命令路由Windows消息驱动模型在MFC面向对象体系中的实现机制MessageDrivenWindows消息驱动机制基础Windows通过消息队列和WndProc回调实现事件驱动,MFC在此基础上用消息映射表取代switch-case,将消息处理转化为面向对象的成员函数调用。Windows事件驱动模型用户操作和系统事件产生消息(MSG结构体),经消息队列由GetMessage/DispatchMessage分发到目标窗口的WndProcMSGSDK编程的消息处理在WndProc中通过switch-case分派数百种消息,代码冗长且维护困难,每增加一个消息需修改核心分发逻辑switch-caseMFC的封装策略用消息映射表(MessageMap)替代switch-case,将消息与处理函数的对应关系声明在类定义中,实现模块化与面向对象化MessageMap消息分类标准窗口消息(WM_XXX)、命令消息(WM_COMMAND)、控件通知消息(WM_NOTIFY),不同类型有不同的路由规则WM_XXXMESSAGEMAPMACROSMFC消息映射宏体系MFC通过DECLARE_MESSAGE_MAP/BEGIN_MESSAGE_MAP/END_MESSAGE_MAP宏对构建静态消息映射表,将消息ID与成员函数指针在编译期完成绑定。声明层宏DECLARE_MESSAGE_MAP()在类声明中添加消息映射表的静态成员变量和运行时查找函数声明DECLARE定义层宏BEGIN_MESSAGE_MAP与END_MESSAGE_MAP在实现文件中定义映射表数组,记录基类指针以支持链式查找BEGIN/END映射宏ON_WM_PAINT()映射固定签名处理函数,ON_COMMAND将命令消息绑定到自定义函数ON_COMMAND运行时查找映射表编译为AFX_MSGMAP_ENTRY静态数组,框架遍历当前类和所有基类查找匹配处理函数AFX_MSGMAPMFCArchitecture消息映射的查找与分发流程MFC通过全局AfxWndProc接收消息,经窗口句柄映射到CWnd对象,再沿类继承链逐级查找消息映射表,实现消息的面向对象分发。01AfxWndProc全局入口接收所有Windows消息,通过窗口句柄在句柄映射表中找到对应的CWnd对象指针,完成全局到面向对象的桥接。02WindowProc消息匹配CWnd::WindowProc()调用OnWndMsg()处理标准消息,遍历当前类的AFX_MSGMAP_ENTRY数组查找匹配项。03链式继承查找当前类未找到处理函数时,通过基类CRuntimeClass指针向上逐级查找,直到CCmdTarget根类或DefWindowProc。04消息反射机制控件通知消息先发送给父窗口,父窗口可选择反射回控件自身处理,支持自包含控件的封装与解耦。CommandRoutingWM_COMMAND命令路由机制命令消息按"框架→视图→文档→框架→应用"的固定顺序路由,各层次均可截获处理,实现了命令处理的职责分离与灵活分发。01命令路由起点:CFrameWnd::OnCommand()接收WM_COMMAND消息后,首先转发给当前活动视图的OnCmdMsg()函数02视图优先处理:CView在自身消息映射表中查找命令处理函数,找到则执行并返回TRUE,未找到则转发给关联的CDocument03文档次优先处理:CDocument在自身映射表中查找,处理后返回或放弃;未处理的命令回到框架窗口自身查找04应用层兜底:框架窗口仍未处理的命令最终到达CWinApp,适合放置全局命令如"关于"对话框、退出程序等命令路由流程CFrameWnd::OnCommand转发OnCmdMsgCView::OnCmdMsg查找消息映射→处理或继续未处理则转发CDocument::OnCmdMsg查找消息映射→处理或放弃回退到框架CWinApp(全局兜底)"关于"对话框·退出程序MFCCommandRoutingUPDATE_COMMAND_UI命令更新机制MFC在菜单弹出前自动发送UPDATE_COMMAND_UI消息,通过CCmdUI对象动态控制菜单项和工具栏按钮的启用、禁用和选中状态。01逐项发送更新通知菜单弹出前框架逐项发送CN_UPDATE_COMMAND_UI通知,每个菜单项和工具栏按钮均有机会在显示前更新自身状态。该机制确保用户界面始终反映当前程序状态,避免显示过时或无效的命令选项。02CCmdUI核心控制方法CCmdUI对象提供Enable()、SetCheck()、SetText()方法,分别控制命令的启用/禁用、勾选状态和显示文本。这些方法封装了底层WindowsAPI调用,为开发者提供简洁统一的接口。03命令路由路径传递更新消息沿命令路由路径传递:视图→文档→框架→应用,各层次均可根据当前状态设置命令的可用性。这种分层设计使得不同组件能够独立管理与其相关的命令状态。04无处理函数自动禁用如果整条路由路径上都没有对应的UPDATE_COMMAND_UI处理函数,框架自动灰化该菜单项。这一默认行为防止用户执行未实现或不适用的命令,提升界面友好性。CHAPTER05应用程序生命周期从CWinApp启动到消息循环再到程序退出的完整运行流程MFCArchitectureCWinApp:应用程序对象与全局入口CWinApp是MFC程序的全局入口和生命周期管理者,每个应用有且仅有一个CWinApp派生对象,负责初始化、消息循环和退出清理。全局唯一实例CWinApp派生对象在WinMain执行前构造,通过theApp全局变量和AfxGetApp()函数提供全局访问点theAppInitInstance()重写此函数完成文档模板注册、主窗口创建和显示,返回FALSE则终止程序启动初始化入口Run()调用GetMessage/TranslateMessage/DispatchMessage持续处理消息,是程序持续运行的核心引擎消息循环ExitInstance()在消息循环结束后调用,释放全局资源、保存用户配置,完成程序优雅退出退出清理STARTUPSEQUENCEMFC程序启动流程详解MFC启动依次经历全局构造、WinMain、AfxWinInit等六阶段,任一环节失败即触发退出清理。全局对象构造theApp对象在C运行时启动代码中构造,早于WinMain执行,确保应用对象在框架初始化前已就绪01AfxWinInit框架内核注册MFC窗口类、初始化模块状态和线程局部存储,为后续窗口创建提供运行环境02InitInstance实例初始化创建文档模板、注册窗口类、创建并显示主窗口,是开发者介入启动流程的主要入口03Run消息泵PumpMessage()循环调用GetMessage与DispatchMessage,PreTranslateMessage()提供消息预处理拦截点04MFCInternals消息循环与空闲处理机制CWinApp::Run()通过PumpMessage()持续从消息队列取消息并分发,空闲时调用OnIdle()执行后台任务,构成程序运行的心脏。PumpMessage()核心循环GetMessage()取消息→TranslateMessage()转换键盘消息→DispatchMessage()分发到目标窗口的WndProc,构成消息处理的标准三步管线。GetMessage→DispatchMessageWM_QUIT终止信号GetMessage()收到WM_QUIT时返回0,PumpMessage()返回FALSE,Run()退出消息循环进入退出流程,程序开始销毁与清理。WM_QUIT→ReturnFALSEOnIdle()空闲处理消息队列空时框架调用OnIdle(lCount),lCount递增标识空闲轮次,适合执行延迟计算、UI状态更新和低优先级后台任务。lCount递增轮次PreTranslateMessage()钩子在消息分发前拦截处理MSG*pMsg,常用于对话框的快捷键响应和模式消息过滤,是消息管线中最早的截获点。MSG*pMsg预处理EXITLIFECYCLEMFC程序退出流程MFC程序退出经历WM_QUIT信号→消息循环终止→文档保存检查→ExitInstance清理→对象析构的有序流程,确保数据安全与资源释放。01退出触发用户关闭主窗口产生WM_CLOSE,经DestroyWindow()后发出WM_QUIT;或程序直接调用AfxPostQuitMessage()注入退出信号。WM_QUIT02文档保存检查框架关闭前调用CDocument::SaveModified()检查修改标记,有未保存修改时弹出确认对话框。SaveModified()03应用级清理在Run()返回后调用ExitInstance(),释放全局资源、保存窗口位置和用户偏好设置。ExitInstance()04对象销毁顺序视图→文档→框架窗口→文档模板→应用对象,严格的逆序销毁保证资源依赖关系的正确解除。逆序销毁ArchitectureOverviewMFC体系结构全景总结MFC体系结构由应用对象、文档模板、文档/视图/框架三件套、消息映射和命令路由五大模块协同构成,形成完整的Windows桌面应用框架。架构核心三件套文档/视图/框架:CDocument管理数据生命周期,CView负责数据可视化与用户交互,CFrameWnd提供界面容器与命令分发。动态创建机制:文档模板(CDocTemplate)自动实例化并关联三者,实现松耦合的模块化架构。Doc/View/Frame消息与命令体系消息映射:将Windows消息绑定到C++成员函数

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论