MFC启动过程1. 首先说一下MFC程序的启动过程.每个MFC程序都有一个全局的应用程序类的对象, 在面向对象程度非常好的MFC程序中, 应该只有这一个全局的对象.MFC应用程序启动时, 首先创建这个应用程序对象, 比如对象名为theApp, 这时将调用这个对象的构造函数来初始化theApp.然后由应用程序框架调用MFC提供的AfxWinMain主函数. 在这个主函数中, 首先获得应用程序对象theApp的指针, 然后通过这个指针调用程序程序对象的有关函数, 来完成程序的初始化和启动工作, 最后调用Run函数, 进入消息循环. 主要代码如下: [cpp] view plaincopy
与普通的WIN32 SDK应用程序相比, 入口函数换成AfxWinMain, 初始化和启动工作主要交给应用程序类处理. 另外, 创建管理窗口由窗口类负责, 创建创建一个窗口只需要几行便可实现, 完全不用像WIN32 SDK那样用大量代码去注册窗口类, 而且由于消息映像机制的引进, 不用再去写麻烦的回调函数和SWITCH-CASE语句. 当然, MFC的强大远远不只这些, 比如能够方便的实现文档/视图结构和序列化就是它最强大的一个功能之一.
2. 再看一个最简单的MFC程序的代码. 这个程序包含一个.H文件和一个.CPP文件, 代码如下:
[cpp] view plaincopy
在上面的代码中可以看到一个最简单的MFC应用程序的组成和结构: 我做了格式上的修改,原址:http://blog.csdn.net/haonan9122/article/details/5747495
单文档MFC程序的启动详细过程
1、定义和构造全局应用程序对象,CSDITestApp theApp;//这个对象用来唯一标示应用程序,相当于SDK中的应用程序句柄hInstance
2、调用WinMain函数:这是编译链接的时候从外部链接进来的,确切的函数为tWinMain(AfxWinMain)
//设置成员对象CWinApp::m_pDocManager的静态变量CDocManager::bStaticInit为FALSE
3、调用CWinApp::OnFileNew()的过程 //虚函数,可重载//该过程要构造Document, FrameWnd和View类对象,并创建MainFrame和View窗口。实际上OnFileNew函数并不是直接调用的,而是通过CCmdTarget::OnCmdMsg发送一个ID_FILE_NEW来调用的 3.1 调用CDocManager::OnFileNew()函数 3.1.1 获取CDocTemplate* pTemplate对象指针 //在2.1.3.2.1中加入的,如果是MDI程序,会调出对话框,询问使用哪一个DocTemplate 3.1.2 调用CSingleDocTemplate::OpenDocumentFile(NULL);//虚函数,CDocTemplate基类中为纯虚函数,所以调用子类的函数 3.1.2.1 调用CDocTemplate::CreateNewDocument(); 3.1.2.1.1 调用CRuntimeClass::CreateObject()创建并构造一个CSDITestDoc的对象 //CRuntimeClass的含义请看《深入浅出MFC》 3.1.2.1.2 调用CSingleDocTemplate::AddDocument() 3.1.2.1.2.1 调用基类CDocTemplate::AddDocument(),将CSDITestDoc对象的成员m_pDocTemplate设为当前模板this指针。 3.1.2.1.2.2 设置CSingleDocTemplate::m_pOnlyDoc = pDocument; //单文档只能有一个 3.1.2.2 调用CDocTemplate::CreateNewFrame(pDocument, NULL) 3.1.2.2.1调用CRunTimeClass::CreateObject()创建并构造一个CMainFrame的对象 3.1.2.2.2 调用CFrameWnd::LoadFrame(m_nIDResource, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, …) //该函数将完成注册窗口类结构wndclass,创建主窗口,创建view窗口,创建工具条状态条等任务,后面细讲 3.1.2.3 调用CSDITestDoc::OnNewDocument() //虚函数,子类已重载,加入一些初始化代码 3.1.2.4 调用CDocTemplate::InitialUpdateFrame() 3.1.2.4.1 调用CFrameWnd::InitialUpdateFrame() 3.1.2.4.1.1 设置ActiveView //SetActiveView 3.1.2.4.1.2 SendMessageToDescendants(WM_INITIALUPDATE,…) 3.1.2.4.1.3 pView->OnActiveFrame(WA_INACTIVE, this) 3.1.2.4.1.4 ActivateFrame() 3.1.2.4.1.5 pDoc->UpdateFrameCounts 3.1.2.4.1.6 OnUpdateFrameTitle(TRUE)
4. 调用CFrameWnd::LoadFrame(m_nIDResource, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, …)的过程 //虚函数,可重载4.1 调用AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG),即AfxEndDeferRegisterClass构造窗口类,并注册 4.1.1 设置wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; 4.1.2 调用_AfxRegisterWithIcon注册窗口类 4.1.2.1 调用AfxRegisterClass() //如果窗口类没有注册,则调用API函数::RegisterClass()注册窗口类 //第一次注册 4.2 调用GetIconWndClass()函数 4.2.1 调用CMainFrame::PreCreateWindow(cs) //虚函数,子类已经重载 4.2.1.1 又会调用AfxEndDeferRegisterClass注册窗口类,但此时的窗口类已经在4.1.2.1注册了,所以PreCreateWindow函数的主要功能是更新cs结构。 4.2.2 调用AfxRegisterWndClass注册窗口类 //第二次注册 4.3 调用CFrameWnd::Create() 4.3.1 调用CWnd::CreateEx 4.3.1.1 构造cs 4.3.1.2 再次调用PreCreateWindow(cs) //同样也不会注册窗口类,只是修改cs 4.3.1.3 调用API函数::CreateWindowEx创建主窗口,同时发送WM_CREATE消息 4.3.1.3.1 调用CMainFrame::OnCreate()函数响应消息 //虚函数,子类已经重载。后面详细讲述 5. 调用CMainFrame::OnCreate()函数5.1 调用基类CFrameWnd::OnCreate()函数 5.1.1 调用CFrameWnd::OnCreateHelper函数 5.1.1.1 调用CWnd::OnCreate()函数 //调用缺省的窗口过程函数,详细过程略 5.1.1.2 调用CFrameWnd::OnCreateClient函数 5.1.1.2.1 调用CFrameWnd::CreateView函数 5.1.1.2.1.1 调用CRunTimeClass::CreateObject()创建CSDITestView类对象 //调用CView::CView()构造函数 m_pDocument = NULL; 5.1.1.2.1.2 调用CView::Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0,0,0,0), this, nID, pContext) // AFX_WS_DEFAULT_VIEW =WS_CHILD | WS_VISIBLE | WS_BORDER 5.1.1.2.1.2.1 调用CWnd::Create() //此函数只能创建WS_CHILD的窗口,如果是POPUP,需要用CreateEx函数 5.1.1.2.1.2.1.1 调用CWnd::CreateEx() //与4.3.1类似 //在CView::OnCreate函数中,有一个CSDITestDoc::AddView(this),该函数一方面将pView加入到CDocument的成员m_viewList中,另一方面将pView的m_pDocument指向pDocument 5.1.1.3 调用RecalcLayout函数5.2 调用CToolBar和CStatusBar创建工具条和状态条 //省略 我做了格式更改,原址:http://blogguan.blog.sohu.com/67507744.html |
|
来自: qingfengyunjie > 《vc》