您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 企业财务 > 浅析MFC程序基本运行机制
浅析MFC程序基本运行机制或许我不该写这篇文章;或许你会不屑的看了看标题,然后华丽的WS之;又或许你会在看完之后,在这篇文章的末尾的写上“打倒KC,打倒MFC,打倒M$”,然后签上自己伟大的名字。但是这都丝毫不会影响包括我在内的所有想了解MFC的Coder对于MFC研究。或许,有好几个问题曾连续地在你的脑海里浮现:MFC很容易学么?是的,很容易。但是前提是你首先得理解他的源代码,并且看懂背后的故事。MFC很复杂么?是的,以MFC4.X来说,仅是一个单独的源文件都有超过120000行的代码,这还不算头文件和.H扩展文件。MFC很强大么?是的,它不仅能让你更加了解Windows系统的运行机理,还能让你从传统SDK的束缚中解脱出来。MFC很恶心么?是的,它会时常让你感到,不是你在控制MFC,而是MFC在控制你MFC很完美么?没有完美的思想,也没有完美的程序。从产生人类文明至今,尚未出现真正称得上“完美”的东西。因为我们在进步,在革命。……常言道:知己知彼,百战不殆。如果你真的决定使用MFC,那么你就应该好好的研究它的内部运行机制。这不是关键性的,但是是必要性的。而这篇文章,就向大家展示了MFC程序的基本运行机制。1.温故知新在研究MFC的基本运行机制之前,先让我们来回忆一下使用C++/SDK写WindowsGUI程序的顺序:调用WinMain入口函数→注册窗口类→窗口实例化→建立消息循环→处理消息可以说,几乎每个WindowsGUI程序的建立和运行,都要经过上面的几个步骤,MFC程序也不例外。但是由于MFC是以C++为基础,所以它势必会使用OOP思想进行架构。而这一切,都会导致我们研究MFC的方式会和C++/SDK有那么一点区别。我们在下面会以MFC的Class为中心进行研究,而非Windows窗体的线性行为。这意味着我们得忍受在几个类中跳来跳去。是的,你可能会感到身体不适,我同样有这种感觉,我从小就恨透了goto……那么,就让我们先来看看使用MFC改如何创建一个简单的窗体,然后在逐步抽丝剥茧,剖析MFC程序的基本运行机理。/****************************************************Project:MFCAppUser**File:MFCAppUser.cpp**Edition:NULL**Coder:KingsamChen[MDSAGroup]**LastModify:2008-8-9**************************************************/#includeafxwin.h//必备的头文件,这个头文件间接包含了windows.hclassCMFCApp:publicCWinApp//继承CWinApp{public:virtualBOOLInitInstance();//虚函数//这个函数必须重写};classCMFCAppWindow:publicCFrameWnd{public:CMFCAppWindow()//在构造函数里创建窗体~{Create(NULL,KC'sWindows);//除前两个参数外,其他参数均有初始值}//下面是消息映射的东东afx_msgvoidOnLButtonDblClk(UINTnFlags,CPointpoint);//左键双击的消息声明afx_msgvoidOnPaint();//WM_PAINT消息声明DECLARE_MESSAGE_MAP()//消息映射宏};//MS叫做消息映射表BEGIN_MESSAGE_MAP(CMFCAppWindow,CFrameWnd)ON_WM_LBUTTONDBLCLK()ON_WM_PAINT()END_MESSAGE_MAP()//对应的消息处理,类似SDK窗体里面的回调函数处理过程voidCMFCAppWindow::OnLButtonDblClk(UINTnFlags,CPointpoint){MessageBox(KCisaFucker,NULL,MB_OK);}voidCMFCAppWindow::OnPaint(){CPaintDCPaint(this);Paint.TextOut(0,0,ThisisasampleforMFC);}//重写InitInstance虚函数BOOLCMFCApp::InitInstance(){m_pMainWnd=newCMFCAppWindow();m_pMainWnd-ShowWindow(m_nCmdShow);m_pMainWnd-UpdateWindow();returnTRUE;}CMFCApptheApp;//唯一的应用程序对象将这段代码编译运行后(注意将编译方式调整为“使用静态的MFC库”),可以看到运行了一个窗体,双击窗体会弹出一个MessageBox。这里的代码要比使用C++/SDK要简单明了的多,但是我们没有发现熟悉的WinMain,也没有窗口注册创建等等的部分。显然,这些都被MFC隐藏了。2.CWinApp—应用程序类就像标题所说的,CWinApp的作用是用来产生MFC应用程序对象。每个MFC程序都要求存在一个派生自CWinApp的子类作为应用程序的类,并且需要我们通过这个子类,改写某些虚函数。可见CWinApp的重要性,显然,CWinApp是一个很大的类,他得完成很多工作。以下是MFC7.1的CWinApp的定义源代码的超精简版本(完整版在AFXWIN.H中):classCWinApp:publicCWinThread{DECLARE_DYNAMIC(CWinApp)public://Constructor/*explicit*/CWinApp(LPCTSTRlpszAppName=NULL);//appnamedefaultstoEXEname//Attributes//Startupargs(donotchange)//Thismodule'shInstance.HINSTANCEm_hInstance;//Pointertothecommand-line.LPTSTRm_lpCmdLine;//Initialstateoftheapplication'swindow;normally,//thisisanargumenttoShowWindow().intm_nCmdShow;//Runningargs(canbechangedinInitInstance)//Human-redablenameoftheapplication.Normallysetin//constructororretreivedfromAFX_IDS_APP_TITLE.LPCTSTRm_pszAppName;//Nameofregistrykeyforthisapplication.See//SetRegistryKey()memberfunction.LPCTSTRm_pszRegistryKey;//PointertoCDocManagerusedtomanagedocumenttemplates//forthisapplicationinstance.CDocManager*m_pDocManager;//SupportforShift+F1helpmode.//TRUEifwe'reinSHIFT+F1mode.BOOLm_bHelpMode;public://setinconstructortooverridedefault//Executablename(nospaces).LPCTSTRm_pszExeName;//Defaultbasedonthismodule'spath.LPCTSTRm_pszHelpFilePath;//Defaultbasedonthisapplication'sname.LPCTSTRm_pszProfileName;//Overridables//HooksforyourinitializationcodevirtualBOOLInitApplication();public://publicforimplementationaccessCCommandLineInfo*m_pCmdInfo;//overridesforimplementationvirtualBOOLInitInstance();virtualintExitInstance();//returnappexitcodevirtualintRun();virtualBOOLOnIdle(LONGlCount);//returnTRUEifmoreidleprocessingvirtualLRESULTProcessWndProcException(CException*e,constMSG*pMsg);virtualHINSTANCELoadAppLangResourceDLL();public:virtual~CWinApp();#ifdef_DEBUGvirtualvoidAssertValid()const;virtualvoidDump(CDumpContext&dc)const;#endif//helpersforregistrationHKEYGetSectionKey(LPCTSTRlpszSection);HKEYGetAppRegistryKey();protected://{{AFX_MSG(CWinApp)afx_msgvoidOnAppExit();afx_msgvoidOnUpdateRecentFileMenu(CCmdUI*pCmdUI);afx_msgBOOLOnOpenRecentFile(UINTnID);//}}AFX_MSGDECLARE_MESSAGE_MAP()public://SystemPolicySettingsvirtualBOOLLoadSysPolicies();//OverridetoloadpoliciesotherthanthesystempoliciesthatMFCloads.BOOLGetSysPolicyValue(DWORDdwPolicyID,BOOL*pbValue);//returnsthepolicy'ssettingintheoutparameterprotected:DWORDm_dwPolicies;//blockforstoringbooleansystempolicies};CWinApp中全是成员函数和成员变量(废话--!),我们重点来看看几个重要的函数和变量:lCWinApp中保存了一些传递给WinMain()的命令行参数,这些参数包括当前实例的句柄(m_hInstance)、前一个实例的句柄(m_hPrevInstance)、命令行参数(m_lpCmdLine)以及控制窗口显示的标志(m_nCmdShow)。lCWinApp在m_pszAppName中保存了应用程序名字的拷贝。lCWinApp中保存了指向可执行文件名字的指针(m_pszExeName)、指向应用程序帮助文件路径的指针(m_pszHelpFilePath)以及指向其应用程序配置文件名字的指针(m_pszProfileName)。lCWinApp还是用了一个叫做CCommandLineInfo的Class来保存命令行参数。CCommandLineInfo在一个地方保存了所有标准参数,他是一个很小却很实用的Class。他在你需要得到的命令行参数的时候很有用。我们这里粗略的浏览下他的定义源代码(同样在AFXWIN.H中):classCCommandLineInfo:publicCObject{public://SetsdefaultvaluesCCommandLineInfo();//plainchar*versiononUNICODEforsource-codebackwardscompatibilityvirtualvoid
本文标题:浅析MFC程序基本运行机制
链接地址:https://www.777doc.com/doc-4050456 .html