zoukankan      html  css  js  c++  java
  • [转]MFC下关于“建立空文档失败”问题的分析

    这类问题的出现主要在bool CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo);

    函数的关键内容: 
    BOOL bResult = TRUE; 
    switch (rCmdInfo.m_nShellCommand) 

    case CCommandLineInfo::FileNew:  // 新建 
     if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL)) 
      OnFileNew(); 
     if (m_pMainWnd == NULL)


    3&­'  
      bResult = FALSE; 
     break; 
    case CCommandLineInfo::FileOpen: 
     if (!OpenDocumentFile(rCmdInfo.m_strFileName)) 
      bResult = FALSE; 
     break; 
    通过上面的内容我们可以看出:如果没有对ID_FILE_NEW做映射的话出现问题就在OnFileNew(); 
    CWinApp对OnFileNew的默认实现是调用m_pDocManager->OnFileNew();

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

    //如果模板列表为空的话 
    if (m_templateList.IsEmpty()) 
    {


    q  
     TRACE0("Error: no document templates registered with CWinApp. 
    "); 
     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;Mj8F  
     else 
      return;     // none - cancel operation


    w  
    }

    assert(ptemplate != NULL);


    ]kW  
    ASSERT_KINDOF(CDocTemplate, pTemplate);

    ptemplate->opendocumentfile(null);

    通过上面的代码我们可以看出,cwinapp的onfilenew和onfileopen分别调用cdocmanager的虚拟函数onfilenew和onfileopen。而在cdocmanager里面。通过模板链表选择不同的模板来调用文档模板的opendocumentfile(); 
    如果传入参数NULL表示新建文件。

    下面我们来看看cdoctemplate::opendocumentfile()它是一个最关键的函数。因为他是虚拟函数,我们考虑CSingleDocTemplate::OpenDocumentFile的情况。


    4RqL=  
    这个函数里面有一段代码: 
    其中:AFX_IDP_FAILED_TO_CREATE_DOC 就是字符“建立空文档失败”的资源id 
    // create a new document 
    pDocument = CreateNewDocument(); 
    ASSERT(pFrame == NULL);     // will be created below 
    bCreated = TRUE; 
    if (pDocument == NULL)N+  

    AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC); 
    return NULL; 

    ASSERT(pDocument == m_pOnlyDoc);?#Z  
    if (pFrame == NULL) 

    ASSERT(bCreated);

    // create frame - set as main document frame


    @(m`w  
    BOOL bAutoDelete = pDocument->m_bAutoDelete; 
    pDocument->m_bAutoDelete = FALSE; 
    // don’t destroy if something goes wrong 
    pFrame = CreateNewFrame(pDocument, NULL); 
    pDocument->m_bAutoDelete = bAutoDelete;1nD{WwQ  
    if (pFrame == NULL) 

     AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC); 
     delete pDocument;       // explicit delete on error 
     return NULL; 
    }

    通过观察上面的代码我们很容易的看出有两个可能出错的原因:1 CreateNewDocument返回为NULL 2 createnewframe 返回为空。

    先看 CreateNewDocument() 一般来说这个函数很少失败。不过在调试时也不能掉以轻心。


    6GYC
    >'@  
    再看看CreateNewFrame()  里面有一个函数LoadFrame是造成这种“建立新文档失败”错误的源泉所在。 
    只要它返回False就会弹出这样的提示。 
    我们在来看看LoadFrame() 里面调用CFrameWnd::Create()来创建窗口,创建窗口失败返回Fasle。 
    这样问题就变的比较简单了。

    看看create和createex函数的动作就知道怎么回事了。


    [V:!R  
    ****************************************************************S_zS  
    1如果找不到菜单资源返回False 同时也弹出“建立空文档失败” 
    HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, RT_MENU); 
    if ((hMenu = ::LoadMenu(hInst, lpszMenuName)) == NULL) 

     TRACE0("Warning: failed to load menu for CFrameWnd. 
    "); 
     PostNcDestroy();            // perhaps delete the C++ object 
     return FALSE; 

    2重载了PreCreateWindow而且返回False也会导致弹出“建立空文档失败” 
    3在OnCreate 里面返回-1 也会导致弹出“建立空文档失败”。 
    ******************************************************************

    以上就是我分析的出现这样“建立空文档失败”问题的大致原因。也许还有其他的原因。我这里就不一一列举了。

  • 相关阅读:
    逆变电路技术研究!
    GOOGLE日历(管理自己的日常事务!)
    MATLAB使用的几个小问题(随笔记录下,用作以后参考!)
    ASP.NET截取字符串
    ASP.NET以及JS获取URL和IP地址
    Jvascript 做IE功能按钮,打开、另存为。属性、打印、收藏夹等js按钮
    C# winform 动态添加控件 以及 事件
    VS2008简体中文正式版序列号
    js 获取日期
    ASP.NET读取XML某节点所有数据返回DataTable实例
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/8979563.html
Copyright © 2011-2022 走看看