一个APP可以有多个文档模板,一个文档模板可以有多个文档(Document),一个Document可以有多个View。在程序。要在程序中添加新的文档模板可以如下所示:
CSingleDocTemplate*pDocTemplate;
pDocTemplate = newCSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CmfcArchiveDoc),
RUNTIME_CLASS(CMainFrame), // 主 SDI 框架窗口
RUNTIME_CLASS(CmfcArchiveView));
if(!pDocTemplate)
returnFALSE;
AddDocTemplate(pDocTemplate);
CSingleDocTemplate* pDocNew;
pDocNew = newCSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CmfcArchiveDoc),
RUNTIME_CLASS(CMainFrame), // 主 SDI 框架窗口
RUNTIME_CLASS(CmfcArchiveView));
if (pDocNew == NULL)
returnFALSE;
AddDocTemplate(pDocNew);
1 程序启动
在程序初始化或者点击菜单新建的时候都会调用OnNewDocument函数。具体流程如下所示:
<1>CWinApp::OnFileNew()//appdlg.cpp
void CWinApp::OnFileNew()
{
if(m_pDocManager != NULL)
m_pDocManager->OnFileNew();
}
<2>CDocManager::OnFileNew() //docmgr.cpp
void CDocManager::OnFileNew()
{
if(m_templateList.IsEmpty())
{
TRACE(traceAppMsg, 0, "Error: no document templates registered withCWinApp.\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
CNewTypeDlgdlg(&m_templateList);
INT_PTR 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);
//if returns NULL, the user has already been alerted
}
从这个函数可以看到首次运行程序的时候吧,程序会从成员变量m_templateList这里获取程序的模板中的列表,并且弹出对话框供user选择使用哪一个模板
最后在pTemplate->OpenDocumentFile(NULL)调用OpenDocumentFlle函数,因为这个文档模板是单文档的 ,所以pTemplate是CSingleTemplate类型的。
<3> CSingleDocTemplate::OpenDocumentFile(LPCTSTRlpszPathName, BOOL bMakeVisible)
CDocument*CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName, BOOL bMakeVisible)
{
returnOpenDocumentFile(lpszPathName, TRUE, bMakeVisible);
}
<4> CSingleDocTemplate::OpenDocumentFile(LPCTSTRlpszPathName, BOOL bAddToMRU, BOOL bMakeVisible)
这个函数时主要的函数
CDocument*CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName, BOOL bAddToMRU, BOOLbMakeVisible)
{
CDocument* pDocument = NULL;
CFrameWnd* pFrame = NULL;
BOOL bCreated = FALSE; // => docand frame created
BOOL bWasModified = FALSE;
if(m_pOnlyDoc != NULL)
{
//already have a document - reinit it
pDocument = m_pOnlyDoc;
if(!pDocument->SaveModified())
{