MFC程序产生、启动全讲解

1、Applicate Object产生,内存于是获得配置,初值也设立,也即调用了CWinApp的构造函数
2、CWinApp --> AfxWinMain,它先执行 AfxWinInit --> AfxInitThread 。把消息队列尽量加大到 96
3、AfxWinMain 执行 InitApplication ,这个函数为CWinApp的虚函数,通常不需要改写,主要为MFC内部管理作一些设置
ps.以前的InitApplication是注册窗口类的场所!!
4、AfxWinMain 执行 InitInstance,这也是CWinApp的一个虚函数,通常是要改写的
5、InitInstance new 一个 CSingleDocTemplate 或者CMultiDocTemplate 对象,规划 Document、View、DocumentFrame三者之间的关系
6、InitInstance  调用AddDocTemplate,主要为了处理 IDR_MAINFRAME
ps.如果是MDI的情况,这之后首先需要调用:

 程序代码
    CMainFrame* pMainFrame = new CMainFrame;
    if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
        return FALSE;
    m_pMainWnd = pMainFrame;
这样创建主窗口,后面的步骤中创建的是子窗口的过程。
7、InitInstance  调用 ParseCommandLine
ParseCommandLine作用:分析命令行参数,如果没有命令行参数 ,ParseCommandLine 就假定用户想新建一个文档,于是设置一个FileNew命令
8、InitInstance  调用 ProcessShellCommand 处理 FileNew命令,将调用 CWinApp::OnFileNew
9、CWinApp::OnFileNew --> CDocManager::OnFileNew --> CWinApp::OpenDocumentFile(NULL) --> CDocManager::OpenDocumentFile(NULL) --> CSingleDocTemplate::OpenDocumentFile(NULL) 或者 CMultiDocTemplate::OpenDocumentFile(NULL)
ps.这里传入的参数是NULL,如果是打开一个已经存在的文件时,传入的就是文件的路径名
10、CSingleDocTemplate::OpenDocumentFile
10-1、【Document】CreateNewDocument(); 动态创建Document对象 (类型信息根据本身程序原先的窗口)

 程序代码
CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject();
此时创建的是自定义的一个CDocument子类,例如 “CTestDoc”
10-2、【Frame】CreateNewFrame();  这个函数先动态创建Frame对象,然后调用LoadFrame
ps. 前者只是建立一个类型空的数据结构,后者LoadFrame才是创建窗口的地方。

 程序代码
CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
pFrame->LoadFrame(m_nIDResource,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // default frame styles
NULL, &context)
此时创建的一个自定义的一个CFrameWnd子类,一般自动名为“CMainFrame”

另外Frame主窗口创建具体过程:

 引用内容
LoadFrame --> Create
    (1) CFrameWnd::Create
                   A、::LoadMenu 创建菜单对象结构,并且返回菜单对象句柄
             B、CWnd::CreateEx
    (2) CWnd::CreateEx
                   A、CFrameWnd::PreCreateWindow  注册窗口类的地方,以前在InitApplication
                   B、AfxHookWindowCreate
                         hook窗口处理函数交由全局函数AfxWndProc处理
                 具体操作见《深入浅出MFC》P418 米诺斯托与西休斯
             C、调用Win32 API ::CreateWindowEx创建窗口 (这里需要传入前面的菜单句柄)

11、此时 CreateWindowEx 产生消息 WM_Create,于是调用 CMainFrame::OnCreate,这个函数将创建工具栏和状态栏!!
12、【View】View什么时候生成?当窗口产生时会有一个WM_Create消息。此时:
WM_Create --> CFrameWnd::OnCreate --> CFrameWnd::OnCreateHelper --> CFrameWnd::OnCreateClient --> CFrameWnd::CreateView

 程序代码
CWnd* pView = (CWnd*)pContext->m_pNewViewClass->CreateObject();
pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0,0,0,0), this, nID, pContext))

13、创建完“三口组”,又回到 CSingleDocTemplate::OpenDocumentFile 。
此时调用 OnNewDocument,子类若重载了,就调用子类的 CTestDoc::OnNewDocument
14、如果子类没有重载,那么就调用基类的OnNewDocument ,基类的OnNewDocument 会调用DeleteContents,这个函数的作用:
当从磁盘文件中载入文件,首先需要将现有文档对象的内容清除掉,这就交由DeleteContents处理

15、CSingleDocTemplate::OpenDocumentFile 接着调用 CDocTemplate::InitialUpdateFrame --> CFrameWnd::InitialUpdateFrame
16、CFrameWnd::InitialUpdateFrame 中 bMakeVisible=true,所以
SendMessageToDescendants(WM_INITIALUpdate, 0, 0, TRUE, TRUE);
17、消息 WM_INITIALUpdate 导致 自定义的CView子类的 重载的 OnInitialUpdate 的调用。假设为:
CTestView::OnInitialUpdate
ps.没有重载当然调用CView的 OnInitialUpdate。

 引用内容
ps.构造函数所做的工作越少,程序失败的机会就越小,所以在一些初始的函数中加入变量初始化工作才是最佳选择:例如在 CDocument::OnNewDocument、CView::OnInitialUpdate 等地方!!
在例如,进行窗口特性的控制最好放在 PreCreateWindow 函数中~~
18、此时导致 CTestView::OnUpdate 的调用
19、回到 CFrameWnd::InitialUpdateFrame 。它将调用 CFrameWnd::ActivateFrame虚成员函数,如果冲在了(一般都是),将调用 CMainFrame::ActivateFrame.
作用是 激活具有菜单、视图窗口和工具栏的主框架窗口。
但是此时窗口还没有显示,在这里可以定义窗口激活的方式,例如设置全屏激活等等...

 程序代码
nCmdShow = SW_MAXIMIZE;
CFrameWnd::ActivateFrame(nCmdShow);
20、回到调用ShowWindow显示主窗口
21、UpdateWindow 发出 WM_PAINT 消息

调用 CFrameWnd::ActivateFrame虚成员函数,显示具有菜单、视图窗口和工具栏的主框架窗口。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值