资源描述:
《MFC应用程序框架类分析》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、即便是基于MFC的应用程序,建立窗口类也是会遵循如下的过程:设计窗口类->注册窗口类->生成窗口->显示窗口->更新窗口->消息循环->消息路由到窗口过程函数处理。下面就剖析一下在MFC中是如何完成上述过程的。(1)每个应用程序都有且仅有一个应用类的全局变量theApp,全局变量先于WinMain函数进行处理。(2)WinMain函数体在APPMODUL.CPP文件中,定义如下:extern"C"intWINAPI_tWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstan
2、ce,LPTSTRlpCmdLine,intnCmdShow){//callshared/exportedWinMainreturnAfxWinMain(hInstance,hPrevInstance,lpCmdLine,nCmdShow);}其中#define_tWinMain WinMain(3)AfxWinMain函数体在WINMAIN.CPP文件中,里面有如下两句话:CWinThread*pThread=AfxGetThread();CWinApp*pApp=AfxGetApp();其实这里得到的这两
3、个指针都是指向全局的对象theApp的;接下来有函数调用pThread->InitInstance(),根据多态性,会调用CXXXApp类中的InitInstance()函数。该函数很重要,在对该函数的调用中就会完成:设计窗口类->注册窗口类->生成窗口->显示窗口->更新窗口。接下来,该函数中会继续调用pThread->Run(),这就完成了:消息循环->消息路由到窗口过程函数处理。(4)进入CXXXApp::InitInstance()函数体中,对于单文档应用程序,调用ProcessShellCommand
4、(cmdInfo),通过调用该函数就会完成:设计窗口类->注册窗口类->生成窗口。再接下来就会调用m_pMainWnd->ShowWindow(SW_SHOW);m_pMainWnd->UpdateWindow();这就完成了:显示窗口->更新窗口。(5)在函数CWinApp::ProcessShellCommand(CCommandLineInfo&rCmdInfo)中会进入到如下的case分支:caseCCommandLineInfo::FileNew: if(!AfxGetApp()->OnCmdMsg
5、(ID_FILE_NEW,0,NULL,NULL))(6)进入函数CCmdTarget::OnCmdMsg(UINTnID,intnCode,void*pExtra,AFX_CMDHANDLERINFO*pHandlerInfo),调用_AfxDispatchCmdMsg(this,nID,nCode, lpEntry->pfn,pExtra,lpEntry->nSig,pHandlerInfo);(7)进入函数AFXAPI_AfxDispatchCmdMsg(CCmdTarget*pTarget,UIN
6、TnID,intnCode,AFX_PMSGpfn,void*pExtra,UINTnSig,AFX_CMDHANDLERINFO*pHandlerInfo),调用caseAfxSig_vv: //normalcommandorcontrolnotification ASSERT(CN_COMMAND==0); //CN_COMMANDsameasBN_CLICKED ASSERT(pExtra==NULL); (pTarget->*mmf.pfn_COMMAND)();(8)进入CWinA
7、pp::OnFileNew(),调用m_pDocManager->OnFileNew();这个函数很特殊,它本身是个消息响应函数,当我们点击ID为ID_FILE_NEW的菜单时,会产生一个命令消息,由于命令消息可以被CCmdTarget类及其派生类来捕获,而CWinApp是从CCmdTarget派生出来的,因此可以捕获这个消息。当应用程序创建完成并成功显示后,当我们点击文件菜单下的新建菜单项时,就会首先进入这个函数,然后再依次执行下去,最后就会执行到pDocument->OnNewDocument()中,往往我
8、们会对这个函数不解,不知道它为什么会响应ID_FILE_NEW的命令消息,至此真相大白了。顺便说一句,为什么程序在刚启动的时候,我们并没有点击菜单项,为什么会自动的产生这个消息呢?这是因为在CXXXXApp::InitInstance()函数中有“CCommandLineInfocmdInfo;”这个类的构造函数是这样的:CCommandLineInfo::CCommandLineIn