第三讲 MFC框架程序剖析_第1页
第三讲 MFC框架程序剖析_第2页
第三讲 MFC框架程序剖析_第3页
第三讲 MFC框架程序剖析_第4页
第三讲 MFC框架程序剖析_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

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

文档简介

2020/5/27,第三讲MFC框架程序剖析,2020/5/27,2,MFC框架程序剖析,内容安排,什么是MFC框架程序?MFC的程序框架剖析(运行脉络)MFC框架程序仿真,2020/5/27,3,MFC框架程序剖析,什么是MFC框架程序?,MFC框架程序是利用MFCAppWizard生成的Windows应用程序。,MFCAppWizard是一个辅助我们生成源代码的向导工具,它可以帮助我们自动生成基于MFC框架的源代码。该向导的每一个步骤中,我们都可以根据需要来选择各种特性,从而实现定制应用程序。,实践:利用MFCAppWizard创建一个基于MFC的“单文档界面(SDI)”应用程序。,2020/5/27,4,MFC框架程序剖析,MFC单文档界面程序初探,头文件类定义、类成员函数声明stdafx.h、test.h、MainFrm.h、testDoc.h、testView.h、Resource.h,源文件类函数实现stdafx.cpp、test.cpp、MainFrm.cpp、testDoc.cpp、testView.cpp、test.rc,资源文件图标、菜单项、鼠标形状等资源test.ico、test.rc2、testDoc.ico、toolbar.bmp,2020/5/27,5,MFC框架程序剖析,MFC单文档界面程序初探(续),stdafx.h、stdafx.cpp,stdafx.h中包含了使用MFC的常备头文件,包括:afxwin.h每一个WindowsMFC程序都必须载入它,它以及它载入的文件申明了所有的MFC类。afxext.h凡使用工具栏、状态栏的程序必须载入这个文件。afxdisp.h凡使用通用对话框的MFC的程序需载入该文件。afxdtctl.h支持IE4的常用控件。afxcmn.h凡使用Windows9x新增的通用型控件的MFC程序需载入此文件。,2020/5/27,6,MFC框架程序剖析,MFC单文档界面程序初探(续),test.h、test.cpp,管理和维护主应用程序类CTestApp(由CWinApp继承而来),每一个MFC程序有且仅有一个主应用程序类对象theApp,它代表一个程序本体。,MainFrm.h、MainFrm.cpp,管理和维护主框架类CMainFrame(由CWnd继承而来),主框架是应用程序的主体窗口,其他的窗口(如视类窗口、工具条、状态条)都依附于主框架窗口(覆盖在它上面)。,2020/5/27,7,MFC框架程序剖析,MFC单文档界面程序初探(续),testView.h、testView.cpp,管理和维护视图类CTestView(由CWnd继承而来),负责显示的部分。,testDoc.h、testDoc.cpp,文档类CTestDoc(由CDocumet继承而来),负责显示数据的后台管理和维护。,2020/5/27,8,MFC框架程序剖析,内容安排,什么是MFC框架程序?MFC框架程序剖析(运行脉络)MFC框架程序仿真,2020/5/27,9,MFC框架程序剖析,WindowsAPI程序回顾,2020/5/27,10,MFC框架程序剖析,问题的提出,与WindowsAPI程序相比,MFC程序无执行路径、无条理、不知如何处理消息,有点“见林不见树”的味道:问题一:看不到WinMain,因此不知道程序从哪里开始执行。问题二:看不到RegisterClass和CreateWindow,那么窗口是如何做出来的呢?问题三:看不到消息循环(GetMessage/DispathMessage),那么程序如何推动?问题四:看不到窗口过程WindowProcedure,那么窗口消息响应如何执行?,本节的目的就是要铲除这些疑惑,把上述看不到的东西给挖出来。,2020/5/27,11,MFC框架程序剖析,MFC中的全局对象theApp,初始化CTestAPP对象,应用程序内存获得配置调用基类CWinApp构造函数(在MFC源码目录的文件中AppCore.cpp),用于程序运行时的一些初始化工作。注意:由于theApp是个全局对象,所以CWinApp构造函数会在入口函数WinMain之前运行。,2020/5/27,12,MFC框架程序剖析,MFC中的WinMain函数,文件AppModul.cpp中能找到WinMain入口函数:externCintWINAPI_tWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow)/callshared/exportedWinMainreturnAfxWinMain(hInstance,hPrevInstance,lpCmdLine,nCmdShow);,至此,问题一得以解决!(找到WinMain),2020/5/27,13,MFC框架程序剖析,AfxWinMain函数,AfxWinMain的定义在WinMain.cpp中intAFXAPIAfxWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow).CWinThread*pThread=AfxGetThread();CWinApp*pApp=AfxGetApp();/Appglobalinitializations(rare)if(pApp!=NULL/消息循环,2020/5/27,14,MFC框架程序剖析,CTestApp:InitInstance()函数,BOOLCTestApp:InitInstance()/Test.cpp中if(!ProcessShellCommand(cmdInfo)/new一个CMainFrame对象returnFALSE;m_pMainWnd-ShowWindow(SW_SHOW);/显示主框架窗口m_pMainWnd-UpdateWindow();/更新主框架窗口returnTRUE;,注:ProcessShellCommand(cmdInfo)会new一个主框类对象,从而调用主框类函数CFrameWnd:LoadFrame(),2020/5/27,15,MFC框架程序剖析,CFrameWnd:LoadFrame函数,CFrameWnd:LoadFrame的定义在WinFrm.cpp中BOOLCFrameWnd:LoadFrame(UINTnIDResource,DWORDdwDefaultStyle,CWnd*pParentWnd,CCreateContext*pContext)VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG);if(!Create(lpszClass,lpszTitle,dwDefaultStyle,rectDefault,pParentWnd,MAKEINTRESOURCE(nIDResource),0L,pContext)returnFALSE;/willselfdestructonfailurenormally,2020/5/27,16,MFC框架程序剖析,LoadFrame函数(续),CFrameWnd:LoadFrame中的AfxDeferRegisterClass函数会调用API函数:RegisterClass()来注册主框架窗口。,至此,问题二的窗口类注册问题得以解决!(找到RegisterClass),CFrameWnd:LoadFrame中的Create函数会调用基类的窗口创建函数CWnd:CreateEx()。,2020/5/27,17,MFC框架程序剖析,CWnd:CreateEx,CWnd:CreateEx的定义在WinCore.cpp中在CreateEx函数内部:首先会调用PreCreateWindow(cs)函数,给设计人员一个更改窗口风格的机会。然后调用API函数:CreateWindowEx创建窗口,至此,问题二的窗口类创建问题得以解决!(找到CreateWindowEx),2020/5/27,18,MFC框架程序剖析,CWinThread:Run,CWinThread:Run()的定义在ThrdCore.cpp中intCWinThread:Run()do/pumpmessage,butquitonWM_QUITif(!PumpMessage()returnExitInstance();.ASSERT(FALSE);/notreachable,2020/5/27,19,MFC框架程序剖析,PumpMessage(),PumpMessage()的定义在ThrdCore.cpp中BOOLCWinThread:PumpMessage()if(m_msgCur.message!=WM_KICKIDLE,至此,问题三的消息循环问题得以解决,2020/5/27,20,MFC框架程序剖析,消息映射,Windows程序靠消息的流动而维护生命。在WindowsAPI程序当中,消息的处理方法是在窗口函数中借助一个大大的switch/case比较操作,判别消息,再执行对应的处理代码。在MFC中,为了让大大的switch/case比较操作简化,也让程序代码更模块化一些,MFC采用了一种“MessageMapping”(消息映射表)的做法,把消息和其处理程序关联起来。,2020/5/27,21,MFC框架程序剖析,MessageMapping的基本原理,首先定义一个MSGMAP_ENTRY结构,structMSGMAP_ENTRYUNITnMessage;LONG(*pfn)(HWND,UNIT,WPARAM,LPARAM);,注意:pfn是一个函数指针,而该指针所指的函数处理nMessage消息。这正是面向对象观念中把“数据”和“处理数据的方法”封装起来的一种具体实现。,2020/5/27,22,MFC框架程序剖析,MessageMapping的基本原理(续),接下来,组织一个MSGMAP_RNTRY结构的数组_messageEntries,把程序终欲处理的若干消息以及消息处理函数的关联性建立起来:,structMSGMAP_ENTRY_messageEntries=WM_CREATE,OnCreate,WM_PAINT,OnPaint,WM_SIZE,OnSize,WM_COMMAND,OnCommandWM_CLOSE,OnColse;,消息,消息处理函数,2020/5/27,23,MFC框架程序剖析,MessageMapping的基本原理(续),于是窗口函数可以这么写:,LRESULTCALLBACKMyWndProc(HWNDhwnd,UINTuMsg,WPARAMwParam,LPARAMlParam)for(inti=0;isizeof(_messageEntries);i+)if(message=_messageEntriesi.nMessage)return(*_messageEntriesi.pfn)(hwnd,nMsg,wParam,lParam),这么一来,窗口过程函数WndProc永远不必改变,每当有新的要处理的消息,只要在_messageEntries数组中加上新的数组元素,并针对新消息写新的处理函数就OK了。,2020/5/27,24,MFC框架程序剖析,MFC框架程序中是如何实现消息映射操作的呢?,举例:在MFC框架程序中为视类增加一个鼠标左键按下消息。在源文件中会增加三处代码:(1)消息响应函数原型(作为类成员函数,在类h头文件中声明)(2)消息映射宏(CPP源文件)(3)消息响应函数定义(在类CPP源文件实现该消息响应函数),在MFC框架程序中,消息映射通过消息映射宏来实现消息映射的操作。,2020/5/27,25,MFC框架程序剖析,消息映射宏,BEGIN_MESSAGE_MAP(CTestView,CView)/AFX_MSG_MAP(CTestView)ON_WM_LBUTTONDOWN()/AFX_MSG_MAP/StandardprintingcommandsEND_MESSAGE_MAP(),其中BEGIN_MESSAGE_MAP和END_MESSAGE_MAP这两个宏之间定义了CTestView类的消息映射表,即前面所讲的_messageEntries数组;而ON_WM_LBUTTONDOWN()这个宏的作用是在_messageEntries数组中添加一个消息映射元素,把WM_LBUTTONDOWN消息与OnLButtonDown函数关联起来。通过这种机制,一旦有消息产生,程序就会调用相应的消息响应函数来进行处理。,2020/5/27,26,MFC框架程序剖析,内容安排,什么是MFC框架程序?MFC框架程序剖析(运行脉络)MFC框架程序仿真,2020/5/27,27,MFC框架程序剖析,MFC框架程序仿真,为什么要仿真?MFC太过庞大,我们必须撇开枝节,把重点凸现出来,才容易领略到MFC框架程序的设计方式,从而将来使用起来得心应手。如何仿真?采用控制台Console程序方式,这样可以把程序结构的负荷降到最低。仿真的最高原则是

温馨提示

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

最新文档

评论

0/150

提交评论