FundamentalsofComputers暨南大学珠海学院《Windows编程》制作:刘晓翔2020/5/19第三讲MFC框架程序剖析FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/192MFC框架程序剖析内容安排什么是MFC框架程序?MFC的程序框架剖析(运行脉络)MFC框架程序仿真FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/193MFC框架程序剖析什么是MFC框架程序?MFC框架程序是利用MFCAppWizard生成的Windows应用程序。MFCAppWizard是一个辅助我们生成源代码的向导工具,它可以帮助我们自动生成基于MFC框架的源代码。该向导的每一个步骤中,我们都可以根据需要来选择各种特性,从而实现定制应用程序。实践:利用MFCAppWizard创建一个基于MFC的“单文档界面(SDI)”应用程序。FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/194MFC框架程序剖析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.bmpFundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/195MFC框架程序剖析MFC单文档界面程序初探(续)stdafx.h、stdafx.cppstdafx.h中包含了使用MFC的常备头文件,包括:afxwin.h——每一个WindowsMFC程序都必须载入它,它以及它载入的文件申明了所有的MFC类。afxext.h——凡使用工具栏、状态栏的程序必须载入这个文件。afxdisp.h——凡使用通用对话框的MFC的程序需载入该文件。afxdtctl.h——支持IE4的常用控件。afxcmn.h——凡使用Windows9x新增的通用型控件的MFC程序需载入此文件。FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/196MFC框架程序剖析MFC单文档界面程序初探(续)test.h、test.cpp管理和维护主应用程序类CTestApp(由CWinApp继承而来),每一个MFC程序有且仅有一个主应用程序类对象theApp,它代表一个程序本体。MainFrm.h、MainFrm.cpp管理和维护主框架类CMainFrame(由CWnd继承而来),主框架是应用程序的主体窗口,其他的窗口(如视类窗口、工具条、状态条)都依附于主框架窗口(覆盖在它上面)。FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/197MFC框架程序剖析MFC单文档界面程序初探(续)testView.h、testView.cpp管理和维护视图类CTestView(由CWnd继承而来),负责显示的部分。testDoc.h、testDoc.cpp文档类CTestDoc(由CDocumet继承而来),负责显示数据的后台管理和维护。FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/198MFC框架程序剖析内容安排什么是MFC框架程序?MFC框架程序剖析(运行脉络)MFC框架程序仿真FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/199MFC框架程序剖析WindowsAPI程序回顾程序入口WinMain设计注册窗口类RegisterClass创建窗口CreateWindow显示/更新窗口ShowWindow消息循环GetMessage窗口过程WindowProcFundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/1910MFC框架程序剖析问题的提出与WindowsAPI程序相比,MFC程序无执行路径、无条理、不知如何处理消息,有点“见林不见树”的味道:问题一:看不到WinMain,因此不知道程序从哪里开始执行。问题二:看不到RegisterClass和CreateWindow,那么窗口是如何做出来的呢?问题三:看不到消息循环(GetMessage/DispathMessage),那么程序如何推动?问题四:看不到窗口过程WindowProcedure,那么窗口消息响应如何执行?本节的目的就是要铲除这些疑惑,把上述看不到的东西给挖出来。FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/1911MFC框架程序剖析①MFC中的全局对象theApp初始化CTestAPP对象,应用程序内存获得配置调用基类CWinApp构造函数(在MFC源码目录的文件中AppCore.cpp),用于程序运行时的一些初始化工作。注意:由于theApp是个全局对象,所以CWinApp构造函数会在入口函数WinMain之前运行。FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/1912MFC框架程序剖析②MFC中的WinMain函数文件AppModul.cpp中能找到WinMain入口函数:externCintWINAPI_tWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow){//callshared/exportedWinMainreturnAfxWinMain(hInstance,hPrevInstance,lpCmdLine,nCmdShow);}至此,问题一得以解决!(找到WinMain)FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/1913MFC框架程序剖析AfxWinMain函数AfxWinMain的定义在WinMain.cpp中intAFXAPIAfxWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow){…..CWinThread*pThread=AfxGetThread();CWinApp*pApp=AfxGetApp();//Appglobalinitializations(rare)if(pApp!=NULL&&!pApp-InitApplication())gotoInitFailure;//Performspecificinitializationsif(!pThread-InitInstance())//CWinApp的虚函数,实际执行的是CTestApp中的InitInstance()函数。窗口对象就在这个函数内部产生。{……}nReturnCode=pThread-Run();//消息循环……}FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/1914MFC框架程序剖析③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()FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/1915MFC框架程序剖析④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}……}FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/1916MFC框架程序剖析LoadFrame函数(续)CFrameWnd::LoadFrame中的AfxDeferRegisterClass函数会调用API函数::RegisterClass()来注册主框架窗口。至此,问题二的窗口类注册问题得以解决!(找到RegisterClass)CFrameWnd::LoadFrame中的Create函数会调用基类的窗口创建函数CWnd::CreateEx()。FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/1917MFC框架程序剖析⑤CWnd::CreateExCWnd::CreateEx的定义在WinCore.cpp中在CreateEx函数内部:首先会调用PreCreateWindow(cs)函数,给设计人员一个更改窗口风格的机会。然后调用API函数::CreateWindowEx创建窗口至此,问题二的窗口类创建问题得以解决!(找到CreateWindowEx)FundamentalsofComputers制作:刘晓翔JINANUniversity暨南大学珠海学院《Windows编程》2020/5/1918MFC框架程序剖析⑥CWinThread::RunCWinThread::Run()的定义在ThrdCore.cpp中intCWinThread::Run(){……do{//pumpmessage,butquitonWM_QUITif(!PumpMessage())returnExitInstance();}……..ASSERT(FALSE);//notreachable}FundamentalsofComputers制作:刘晓翔J