zoukankan      html  css  js  c++  java
  • 单文档/视图

    引文《MFC深入浅出》李进久

    如前一节所述,程序从 InitInstance 开始。在 SDI 应用程序的APP::InitInstance()里,至少有以下语句:

    第一部分,创建文档模板对象并把它添加到应用程序的模板链表

    CSingleDocTemplate* pDocTemplate; 
    pDocTemplate = new CSingleDocTemplate( 
      IDR_MAINFRAME, 
      RUNTIME_CLASS(CTDoc), 
      RUNTIME_CLASS(CMainFrame), // main SDI frame window 
      RUNTIME_CLASS(CTView)); 
    AddDocTemplate(pDocTemplate); 

    CSingleDocTemplate调用构造函数,源码如下:

    void CWinApp::AddDocTemplate(CDocTemplate* pTemplate)
    {
        if (m_pDocManager == NULL)
            m_pDocManager = new CDocManager;
        m_pDocManager->AddDocTemplate(pTemplate);
    }

    作用两个:

    • 生成一个CDocManager对象,其中m_pDocManagerCWinApp::m_pDocManager
    • 接着调用CDocManager的成员函数CDocManager::AddDocTemplate(),实际是转手了一次

    接着跟踪CDocManager的成员函数AddDocTemplate,源码截选如下:

    void CDocManager::AddDocTemplate(CDocTemplate* pTemplate)
    {
    ...............
            ASSERT_VALID(pTemplate);
            ASSERT(m_templateList.Find(pTemplate, NULL) == NULL);// must not be in list
            pTemplate->LoadTemplate();
            m_templateList.AddTail(pTemplate);//将文档模板指针加入到自己的CDocManager::CPtrList类型的链表中...
        }
    }

    第二部分,动态创建文档、视图、边框窗口等 MFC 对象和对应的 Windows 对象

    //Parse command line for standard shell commands, DDE, file open 

    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo); 
    // Dispatch commands specified on the command line 
    if (!ProcessShellCommand(cmdInfo)) 
    return FALSE; 

    第三部分,返回 TRUE,WinMain 下一步调用 Run 开始消息循环
    //否则,终止程序
    return TRUE;
    对于第二部分,又可以分解成许多步骤。
    下面将解释每一步。

    第一部分:文档模板的创建

    第一步是创建文档模板。
    文档模板的作用是动态创建其他 MFC 对象,它保存了要动态创建类的动态创建信息和该文档类型的资源 ID。这些信息保存在文档模板的成员变量里:

    • m_nIDResource(资源 ID)
    • m_pDocClass( 文 档 类 动 态 创 建 信 息 ) 
    • m_pFrameClass( 边 框 窗 口 类 动 态 创 建 信 息 ) 
    • m_pViewClass(视类动态创建信息)

    资源 ID 包括菜单、像标、快捷键、字符串资源的 ID,它们都使用同一个 ID 值,如IDR_MAINFRAME。其中,字符串资源描述了文档类型,由七个被“ ”分隔的子字符串组成,各 个 子 串 可 以 通 过 CDocTemplate 的 成 员 函 数 GetDocString(CString& rString, enum DocStringIndex index)来获取。DocStringIndex 是 CDocTemplate 类定义的枚举变量以区分七个子串,描述如下(英文是枚举变量名称)。

    • WindowTitle 应用程序窗口的标题。仅仅对 SDI 程序指定。
    • DocName 用来构造缺省文档名的字符串。当用 File 菜单的菜单项 new 创建新文档时,缺省文档名由该字符串加一个数字构成。如果空,使用“unitled”。
    • FileNewName 文档类型的名称,在打开 File New 对话框时显示。
    • FilterName 匹配过滤字符串,在 File Open 对话框用来过滤要显示的文件。如果不指定,File Open 对话框的文件类型(file style)不可访问。
    • FilterExt 该类型文档的扩展名。如果不指定,则不可访问对话框的文件类型(File Style)。
    • RegFileTypeId 文档类型在 Windows 注册库中的存储标识。
    • RegFileTypeName 文档类型在 Windows 注册库中的类型名称。

    文档模板被应用程序对象创建和管理。应用程序类 CWinApp 有一个 CDocManager 类型的成员变量m_pDocManager,通过该变量来管理应用程序的文档模板列表,把一些相关的操作委派给 CDocManager 对象处理。 CDocManager 使用 CPtrList 类型的m_templateList 变量来存储文档模板,并提供了操作文档模板列表的系列函数。 从语句 pDocTemplate = new CSingleDocTemplate(…)可以看出应用程序对象创建模板时传递一个资源 ID 和三个类的动态创建信息给它:
    IDR_MAINFRAME,//资源 ID
    RUNTIME_CLASS(CTDoc),//文档类动态创建信息
    RUNTIME_CLASS(CMainFrame),//边框窗口类动态创建信息
    RUNTIME_CLASS(CTView),//视类动态创建信息
    文档模板对象接收这些信息并把它们保存到对应的成员变量里头。然后 AddDocTemplate 实
    际调用 m_pDocManager->AddDocTemplate,把创建的模板对象加入到文档模板管理器的模
    板列表中,也就是应用程序对象的文档模板列表中。

    结果:

    • 生成文档模板对象
    • 初始化一些成员变量

    第二部分:文件的创建或者打开

    第二步是创建或者打开文件。对于SDI程序,MFC对象的动态创建过程是在创建或者打开文件中发生的。但是为什么没有看到文件操作相关的语句呢?
    重点参考笔记《CCommandLineInfo类》

    这一部分主要是命令行解析的操作,比如:命令类型是FILENEW时,调用的函数就是标准命令ID_FILE_NEW对应的处理函数OnFileNew;命令类型是FILEOPEN时调用的函数是OpenDocumentFile,标准命令ID_FILE_OPEN的处理函数OnFileOpen的工作实际上就是由OpenDocumentFile完成的。函数FileNew、OpenDocumentFile导致了窗口、文档的创建。

    这一部分只解析命令,并根据结果来调用相关的函数。

    继续跟踪,假如是OnFileNew,调用的是APP::OnFileNew,别忘了现在这些都是在APP对象内的操作。查看源码CWinApp::OnFileNew的调用

    void CWinApp::OnFileNew()
    {
        if (m_pDocManager != NULL)
            m_pDocManager->OnFileNew(); //调用m_pDocManager的..
    }

    可知,实际上调用的是m_pDocManager所指向的OnFileNew()函数。

  • 相关阅读:
    SPI masterslave驱动框架分析
    linux内存分配方法总结
    C#图片适应PictureBox大小显示
    .NET下的AO对象的安全释放
    .net C# PropertyGrid 显示下拉列表
    Oracle事务细节问题
    C#中Remoting的IPC通信之Winform与Windows服务通信错误问题及解决
    windows服务的安装与卸载
    windows环境下Oracle数据库冷备份和恢复全过程
    OGR连接数据源读取矢量数据图层(C#)
  • 原文地址:https://www.cnblogs.com/tinaluo/p/7835732.html
Copyright © 2011-2022 走看看