zoukankan      html  css  js  c++  java
  • 文档打开时,MFC内部的执行流程

    多文档框架中,"建立空文档失败"的问题的分析!

    环境是  使用CWinApp中使用AddDocTemplate添加了多套CChildFrame/Doc/View模板!

    这类问题的出现主要在

    第一步:

    BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo);

    函数的关键内容:
    BOOL bResult = TRUE;
    switch (rCmdInfo.m_nShellCommand)
    {
    case CCommandLineInfo::FileNew: // 新建
    if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))   //响应CWinApp的ID_FILE_NEW消息处理函数,即CWinApp::OnFileNew();
    OnFileNew();
    if (m_pMainWnd == NULL)
    bResult = FALSE;
    break;
    case CCommandLineInfo::FileOpen:
    if (!OpenDocumentFile(rCmdInfo.m_strFileName))
    bResult = FALSE;
    break;
    通过上面的内容我们可以看出:如果没有对ID_FILE_NEW做映射的话出现问题就在OnFileNew();

    第二步:

    void CWinApp::OnFileNew()
    {
     if (m_pDocManager != NULL)
      m_pDocManager->OnFileNew();
    }


    CWinApp对OnFileNew的默认实现是调用m_pDocManager->OnFileNew(); //调用的事CDocMamager::OnFileNew()

    我们继续解析CDocManager,它究竟干了些什么?
    (首先说明一下CDocManager它主要的功能是帮助CWinApp是管理文档模板链表和注册文件类型.)


    第三步:

    void CDocManager::OnFileNew()

    {
    //如果模板列表为空的话
    if (m_templateList.IsEmpty())
    {
    TRACE0("Error: no document templates registered with CWinApp.\n");
    AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);  //报错并返回.这里不会报建立新文档出错。
    return;
    }

    CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();
    if (m_templateList.GetCount() > 1)
    {
    // more than one document template to choose from
    // bring up dialog prompting user
    CNewTypeDlg dlg(&m_templateList); //有多个模板时,会显示一个选择对话框
    int nID = dlg.DoModal();
    if (nID == IDOK)
    pTemplate = dlg.m_pSelectedTemplate;
    else
    return;     // none - cancel operation
    }

    ASSERT(pTemplate != NULL);
    ASSERT_KINDOF(CDocTemplate, pTemplate);

    pTemplate->OpenDocumentFile(NULL);

    }

    通过上面的代码我们可以看出,CWinApp的OnFileNew和OnFileOpen分别调用CDocManager的虚拟函数OnFileNew

    和OnFileOpen。而在CDocManager里面。通过模板链表选择不同的模板来调用文档模板的OpenDocumentFile();  //最重要,应用程序不同调用的函数不同
    如果传入参数NULL表示新建文件。

    第四步:
    下面我们来看看CDocTemplate::OpenDocumentFile()它是一个最关键的函数。因为他是虚拟函数,我们考虑
    CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther)
    {
     if (pDoc != NULL)
      ASSERT_VALID(pDoc);
     // create a frame wired to the specified document

     ASSERT(m_nIDResource != 0); // must have a resource ID to load from
     CCreateContext context;
     context.m_pCurrentFrame = pOther;
     context.m_pCurrentDoc = pDoc;
     context.m_pNewViewClass = m_pViewClass;
     context.m_pNewDocTemplate = this;

     if (m_pFrameClass == NULL)
     {
      TRACE(traceAppMsg, 0, "Error: you must override CDocTemplate::CreateNewFrame.\n");
      ASSERT(FALSE);
      return NULL;
     }
     CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject(); 
     if (pFrame == NULL)
     {
      TRACE(traceAppMsg, 0, "Warning: Dynamic create of frame %hs failed.\n",
       m_pFrameClass->m_lpszClassName);
      return NULL;
     }
     ASSERT_KINDOF(CFrameWnd, pFrame);

     if (context.m_pNewViewClass == NULL)
      TRACE(traceAppMsg, 0, "Warning: creating frame with no default view.\n");

     // create new from resource
     if (!pFrame->LoadFrame(m_nIDResource,
       WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,   // default frame styles
       NULL, &context))
     {
      TRACE(traceAppMsg, 0, "Warning: CDocTemplate couldn't create a frame.\n");
      // frame will be deleted in PostNcDestroy cleanup
      return NULL;
     }

     // it worked !
     return pFrame;
    }

    通过观察上面的代码我们很容易的看出 有两个可能出错的原因:1、CreateObject返回值为空; 2、LoadFrame 返回为空

    ============================
    注意:
     CreateObject返回为空,可能的原因是m_pFrameClass定义的CFrameWnd对象没有申明动态创建性能(DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE)


     

  • 相关阅读:
    涂抹mysql笔记-安装mysql
    使用Oracle DBLink进行数据库之间对象的访问操作
    mysqldump备份与恢复笔记
    linux6下源码安装mysql5.6
    虚拟机克隆之后,网卡名称从eth0变成eth1之后的解决办法
    linux添加zabbix service并开机自动启动
    理解Linux系统负荷load average
    oracle体系结构理解
    C#中Abstract和Virtual[转载]
    WPF后台写ControlTemplate总结
  • 原文地址:https://www.cnblogs.com/xuxu8511/p/3119044.html
Copyright © 2011-2022 走看看