2012.10.20 周六

来源:互联网 发布:mac系统信息查看 编辑:程序博客网 时间:2024/04/29 18:53

MFC框架分析

以单文档为例:

CProjectApp继承自CWinApp。

CMainFrame继承自CFrameWnd,CFrameWnd继承自CWnd。

第一步:首先构造应用程序对象theApp。

CProjectApp类实现文件中定义了一个全局对象 : CProjectApp theApp; 对于全局对象而言,操作系统首先构造全局对象(分配空间),然后才进入 main() 或WinMain()。该对象theApp是程序中唯一全局对象,所以可以代表该应用程序。

CWinApp定义在 \Microsoft Visual Studio 10.0\VC\atlmfc\src\mfc\appcore.cpp中,构造函数为CWinApp::CWinApp(LPCTSTR lpszAppName)【在afxwin.h头文件中】,而我们的应用程序CProjectApp类的构造函数没有传递参数,是因为CWinApp构造函数的参数缺省:CWinApp(LPCTSTR lpszAppName = NULL);

在父类CWinApp的构造函数中有this指针的使用 : pThreadState->m_pCurrentWinThread = this,那么,根据继承性原理,this 指针指向的对象为我们应用程序 CProjectApp theApp 对象。

构造完全局对象后开始进入WinMain函数,WInMain在哪?

在安装路径下的 \Microsoft Visual Studio 10.0\VC\atlmfc\src\mfc\appmodul.cpp代码中extern了_tWinMain()函数,_tWinMain在 \Microsoft Visual Studio 10.0\VC\include\tchar.h中定义 :#define _tWinMain WinMain,因此,

第二步:程序进入_tWinMain函数,_tWinMain即WinMain

_tWinMain()函数中直接调用了AfxWinMain()函数。

AfxWinMain()函数在WinMain.cpp中:int AFXAPI AfxWinMain(参数)。以Afx开头的函数是Application Framework应用程序框架模型函数,相当于全局函数,引入头文件后即可调用。AfxWinMain函数中获得了应用程序两个重要指针:CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();//
CWinApp类继承自CWinThread类,这两个指针是一致的。

AfxWinMain函数中pThread->InitInstance()实际调用CProjectApp类的InitInstance() 完成建立(选择)窗口类、注册窗口类、创建窗口、显示窗口和更新窗口等过程,pThread->Run() 建立消息循环。

InitInstance函数中:

AfxEndDeferRegisterClass()完成窗口类的建立和注册窗口类。【系统已经建立CWnd类,从它派生的类都是窗口类,如CFrameWnd和CView】,其中窗口类建立和注册会调用CMainFrame::PreCreateWindow函数,所以可以在我们的窗口类之修改窗口类结构体的值。

CMainFrame的LoadFrame函数中调用了Create方法完成窗口的建立,具备能够保存在CProjectApp::m_pMainWnd中。

第三步:窗口的现实和更新

CProjectApp::InitInstance函数中:

m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
//此时MainFrame窗口已经建立,句柄保存在m_pMainWnd

第四步:消息循环

CProjectApp::InitInstance函数完成后,返回AfxWinMain函数,调用pThread->Run() 进入消息循环。


主框架类、视图类和文档类的有机组织:

CProjectApp::InitInstance函数中,new一个单文档模板类,将新程序的主框架类、视图类和文档类关联在一起,然后添加到文档模板中。

CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CCgLSCDemoDoc),
RUNTIME_CLASS(CMainFrame),       // 主 SDI 框架窗口
RUNTIME_CLASS(CCgLSCDemoView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);





原创粉丝点击