问题引入:
新建一个mfc单文档程序后,删除了所有的工具栏条目,程序编译通过,但在执行时后提示:“建立空文档失败”,程序退出
问题分析:
由于工具栏资源被删除,所以在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
里面创建工具栏目时候会失败。 但是这和弹出“建立空文档失败”看不出直接联系。为了查出根本原因,这里进行深入调试。
跟踪调试,问题出现在 代码 if (!ProcessShellCommand(cmdInfo)),设计一正常程序深入调试,查找原因。
1、C:/Program Files/Microsoft Visual Studio/VC98/MFC/SRC/APPUI2.CPP文件函数:
BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)
中,定位到代码:
if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL)),该语句处理消息ID_FILE_NEW, 进入步骤2
2、C:/Program Files/Microsoft Visual Studio/VC98/MFC/SRC/DOCMGR.CPP 的void CDocManager::OnFileNew()
函数,发现如果m_templateList列表为空,会导致该问题,如下:
if (m_templateList.IsEmpty())
{
TRACE0("Error: no document templates registered with CWinApp./n");
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
return;
}
继续跟踪至
3、C:/Program Files/Microsoft Visual Studio/VC98/MFC/SRC/DOCSINGL.CPP
的函数:CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName, BOOL bMakeVisible)
该函数里如果CreateNewDocument失败,也会导致该问题,如下:
pDocument = CreateNewDocument();
ASSERT(pFrame == NULL); // will be created below
bCreated = TRUE;
}
if (pDocument == NULL)
{
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
return NULL;
}
跟踪分析,删除工具栏目对CreateNewDocument应该没影响。
另外该函数里如果CreateNewFrame失败,也会导致该问题,如下:
pFrame = CreateNewFrame(pDocument, NULL);
pDocument->m_bAutoDelete = bAutoDelete;
if (pFrame == NULL)
{
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
delete pDocument; // explicit delete on error
return NULL;
}
我们深入跟踪语句: pFrame = CreateNewFrame(pDocument, NULL);进入代码文件
C:/Program Files/Microsoft Visual Studio/VC98/MFC/SRC/DOCTEMPL.CPP 的函数
CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther),在这里,跟踪语句
if (!pFrame->LoadFrame(m_nIDResource,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // default frame styles
NULL, &context))
使我们进入到C:/Program Files/Microsoft Visual Studio/VC98/MFC/SRC/WINFRM.CPP文件的
BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
CWnd* pParentWnd, CCreateContext* pContext) 函数,至此,我们发现该函数的语句
if (!Create(lpszClass, lpszTitle, dwDefaultStyle, rectDefault,
pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext))
{
return FALSE; // will self destruct on failure normally
}
调用了CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct),这里工具栏创建的失败,导致问题的出现