OnFileNew()/OnFileOpen()的MFC代码跟踪简析
来源:互联网 发布:声雨竹羽绒服淘宝 编辑:程序博客网 时间:2024/05/03 04:43
对OnFileNew()/OnFileOpen()的MFC代码跟踪简析,简析可能也谈不上了,为了快速的理解MFC的实现思路以及文档视图架构的应用,在学习的过程当中我也没有进行学习理解的注解。不过细细阅读整个的实现流程,相信你我都能理解掌握MFC的整体思路。以后有机会再进行注解吧。
A) OnFileNew()执行过程分析
1. void CWinApp::OnFileNew()
{
if (m_pDocManager != NULL)
m_pDocManager->OnFileNew();
}
注释:MFC对ID_FILE_NEW菜单的响应函数,系统默认操作.
2. 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);
// if returns NULL, the user has already been alerted
}
注:如果跳过此函数而手动操作直接进入pTemplate->OpenDocumentFile(),那么文档模版列表选择对话框也就不会出现了.
3.1 CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
BOOL bMakeVisible)
// if lpszPathName == NULL => create new file of this type
{
CDocument* pDocument = NULL;
CFrameWnd* pFrame = NULL;
BOOL bCreated = FALSE; // => doc and frame created
BOOL bWasModified = FALSE;
if (m_pOnlyDoc != NULL)
{
// already have a document - reinit it
pDocument = m_pOnlyDoc;
if (!pDocument->SaveModified())
return NULL; // leave the original one
pFrame = (CFrameWnd*)AfxGetMainWnd();
ASSERT(pFrame != NULL);
ASSERT_KINDOF(CFrameWnd, pFrame);
ASSERT_VALID(pFrame);
}
else
{
// create a new document
pDocument = CreateNewDocument();
ASSERT(pFrame == NULL); // will be created below
bCreated = TRUE;
}
if (pDocument == NULL)
{
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
return NULL;
}
ASSERT(pDocument == m_pOnlyDoc);
if (pFrame == NULL)
{
ASSERT(bCreated);
// create frame - set as main document frame
BOOL bAutoDelete = pDocument->m_bAutoDelete;
pDocument->m_bAutoDelete = FALSE;
// don't destroy if something goes wrong
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;
}
}
if (lpszPathName == NULL)
{
// create a new document
SetDefaultTitle(pDocument);
// avoid creating temporary compound file when starting up invisible
if (!bMakeVisible)
pDocument->m_bEmbedded = TRUE;
if (!pDocument->OnNewDocument())
{
// user has been alerted to what failed in OnNewDocument
TRACE(traceAppMsg, 0, "CDocument::OnNewDocument returned FALSE./n");
if (bCreated)
pFrame->DestroyWindow(); // will destroy document
return NULL;
}
}
else
{
CWaitCursor wait;
// open an existing document
bWasModified = pDocument->IsModified();
pDocument->SetModifiedFlag(FALSE); // not dirty for open
if (!pDocument->OnOpenDocument(lpszPathName))
{
// user has been alerted to what failed in OnOpenDocument
TRACE(traceAppMsg, 0, "CDocument::OnOpenDocument returned FALSE./n");
if (bCreated)
{
pFrame->DestroyWindow(); // will destroy document
}
else if (!pDocument->IsModified())
{
// original document is untouched
pDocument->SetModifiedFlag(bWasModified);
}
else
{
// we corrupted the original document
SetDefaultTitle(pDocument);
if (!pDocument->OnNewDocument())
{
TRACE(traceAppMsg, 0, "Error: OnNewDocument failed after trying "
"to open a document - trying to continue./n");
// assume we can continue
}
}
return NULL; // open failed
}
pDocument->SetPathName(lpszPathName);
}
CWinThread* pThread = AfxGetThread();
ASSERT(pThread);
if (bCreated && pThread->m_pMainWnd == NULL)
{
// set as main frame (InitialUpdateFrame will show the window)
pThread->m_pMainWnd = pFrame;
}
InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
return pDocument;
}
3.1.1 BOOL CDocument::SaveModified()
{
if (!IsModified())
return TRUE; // ok to continue
// get name/title of document
CString name;
if (m_strPathName.IsEmpty())
{
// get name based on caption
name = m_strTitle;
if (name.IsEmpty())
ENSURE(name.LoadString(AFX_IDS_UNTITLED));
}
else
{
// get name based on file title of path name
name = m_strPathName;
AfxGetFileTitle(m_strPathName, name.GetBuffer(_MAX_PATH), _MAX_PATH);
name.ReleaseBuffer();
}
CString prompt;
AfxFormatString1(prompt, AFX_IDP_ASK_TO_SAVE, name);
switch (AfxMessageBox(prompt, MB_YESNOCANCEL, AFX_IDP_ASK_TO_SAVE))
{
case IDCANCEL:
return FALSE; // don't continue
case IDYES:
// If so, either Save or Update, as appropriate
if (!DoFileSave())
return FALSE; // don't continue
break;
case IDNO:
// If not saving changes, revert the document
break;
default:
ASSERT(FALSE);
break;
}
return TRUE; // keep going
}
3.1.2 BOOL CDocument::DoFileSave()
{
DWORD dwAttrib = GetFileAttributes(m_strPathName);
if (dwAttrib & FILE_ATTRIBUTE_READONLY)
{
// we do not have read-write access or the file does not (now) exist
if (!DoSave(NULL))
{
TRACE(traceAppMsg, 0, "Warning: File save with new name failed./n");
return FALSE;
}
}
else
{
if (!DoSave(m_strPathName))
{
TRACE(traceAppMsg, 0, "Warning: File save failed./n");
return FALSE;
}
}
return TRUE;
}
3.1.3 BOOL CDocument::DoSave(LPCTSTR lpszPathName, BOOL bReplace)
// Save the document data to a file
// lpszPathName = path name where to save document file
// if lpszPathName is NULL then the user will be prompted (SaveAs)
// note: lpszPathName can be different than 'm_strPathName'
// if 'bReplace' is TRUE will change file name if successful (SaveAs)
// if 'bReplace' is FALSE will not change path name (SaveCopyAs)
{
CString newName = lpszPathName;
if (newName.IsEmpty())
{
CDocTemplate* pTemplate = GetDocTemplate();
ASSERT(pTemplate != NULL);
newName = m_strPathName;
if (bReplace && newName.IsEmpty())
{
newName = m_strTitle;
// check for dubious filename
int iBad = newName.FindOneOf(_T(":///"));
if (iBad != -1)
newName.ReleaseBuffer(iBad);
// append the default suffix if there is one
CString strExt;
if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&
!strExt.IsEmpty())
{
ASSERT(strExt[0] == '.');
int iStart = 0;
newName += strExt.Tokenize(_T(";"), iStart);
}
}
if (!AfxGetApp()->DoPromptFileName(newName,
bReplace ? AFX_IDS_SAVEFILE : AFX_IDS_SAVEFILECOPY,
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, FALSE, pTemplate))
return FALSE; // don't even attempt to save
}
CWaitCursor wait;
if (!OnSaveDocument(newName))
{
if (lpszPathName == NULL)
{
// be sure to delete the file
TRY
{
CFile::Remove(newName);
}
CATCH_ALL(e)
{
TRACE(traceAppMsg, 0, "Warning: failed to delete file after failed SaveAs./n");
DELETE_EXCEPTION(e);
}
END_CATCH_ALL
}
return FALSE;
}
// reset the title and change the document name
if (bReplace)
SetPathName(newName);
return TRUE; // success
}
3.1.4 BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName)
{
ENSURE(lpszPathName);
CFileException fe;
CFile* pFile = NULL;
pFile = GetFile(lpszPathName, CFile::modeCreate |
CFile::modeReadWrite | CFile::shareExclusive, &fe);
if (pFile == NULL)
{
ReportSaveLoadException(lpszPathName, &fe,
TRUE, AFX_IDP_INVALID_FILENAME);
return FALSE;
}
CArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete);
saveArchive.m_pDocument = this;
saveArchive.m_bForceFlat = FALSE;
TRY
{
CWaitCursor wait;
Serialize(saveArchive); // save me
saveArchive.Close();
ReleaseFile(pFile, FALSE);
}
CATCH_ALL(e)
{
ReleaseFile(pFile, TRUE);
TRY
{
ReportSaveLoadException(lpszPathName, e,
TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);
}
END_TRY
DELETE_EXCEPTION(e);
return FALSE;
}
END_CATCH_ALL
SetModifiedFlag(FALSE); // back to unmodified
return TRUE; // success
}
3.2 CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,BOOL bMakeVisible)
{
CDocument* pDocument = CreateNewDocument();
if (pDocument == NULL)
{
TRACE0("CDocTemplate::CreateNewDocument returned NULL./n");
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
return NULL;
}
ASSERT_VALID(pDocument);
BOOL bAutoDelete = pDocument->m_bAutoDelete;
pDocument->m_bAutoDelete = FALSE; // don't destroy if something goes wrong
CFrameWnd* 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;
}
ASSERT_VALID(pFrame);
if (lpszPathName == NULL)
{
// create a new document - with default document name
SetDefaultTitle(pDocument);
// avoid creating temporary compound file when starting up invisible
if (!bMakeVisible)
pDocument->m_bEmbedded = TRUE;
if (!pDocument->OnNewDocument())
{
// user has be alerted to what failed in OnNewDocument
TRACE0("CDocument::OnNewDocument returned FALSE./n");
pFrame->DestroyWindow();
return NULL;
}
// it worked, now bump untitled count
m_nUntitledCount++;
}
else
{
// open an existing document
CWaitCursor wait;
if (!pDocument->OnOpenDocument(lpszPathName))
{
// user has be alerted to what failed in OnOpenDocument
TRACE0("CDocument::OnOpenDocument returned FALSE./n");
pFrame->DestroyWindow();
return NULL;
}
pDocument->SetPathName(lpszPathName);
}
InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
return pDocument;
}
4. CDocument* CDocTemplate::CreateNewDocument()
{
// default implementation constructs one from CRuntimeClass
if (m_pDocClass == NULL)
{
TRACE0("Error: you must override CDocTemplate::CreateNewDocument./n");
ASSERT(FALSE);
return NULL;
}
CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject();
if (pDocument == NULL)
{
TRACE1("Warning: Dynamic create of document type %hs failed./n",
m_pDocClass->m_lpszClassName);
return NULL;
}
ASSERT_KINDOF(CDocument, pDocument);
AddDocument(pDocument);
return pDocument;
}
5. 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)
{
TRACE0("Error: you must override CDocTemplate::CreateNewFrame./n");
ASSERT(FALSE);
return NULL;
}
CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
if (pFrame == NULL)
{
TRACE1("Warning: Dynamic create of frame %hs failed./n",
m_pFrameClass->m_lpszClassName);
return NULL;
}
ASSERT_KINDOF(CFrameWnd, pFrame);
if (context.m_pNewViewClass == NULL)
TRACE0("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))
{
TRACE0("Warning: CDocTemplate couldn't create a frame./n");
// frame will be deleted in PostNcDestroy cleanup
return NULL;
}
// it worked !
return pFrame;
}
6. BOOL CDocument::OnNewDocument()
{
if (IsModified())
TRACE0("Warning: OnNewDocument replaces an unsaved document./n");
DeleteContents();
m_strPathName.Empty(); // no path name yet
SetModifiedFlag(FALSE); // make clean
return TRUE;
}
7. BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)
{
if (IsModified())
TRACE0("Warning: OnOpenDocument replaces an unsaved document./n");
CFileException fe;
CFile* pFile = GetFile(lpszPathName,
CFile::modeRead|CFile::shareDenyWrite, &fe);
if (pFile == NULL)
{
ReportSaveLoadException(lpszPathName, &fe,
FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
return FALSE;
}
DeleteContents();
SetModifiedFlag(); // dirty during de-serialize
CArchive loadArchive(pFile, CArchive::load | CArchive::bNoFlushOnDelete);
loadArchive.m_pDocument = this;
loadArchive.m_bForceFlat = FALSE;
TRY
{
CWaitCursor wait;
if (pFile->GetLength() != 0)
Serialize(loadArchive); // load me
loadArchive.Close();
ReleaseFile(pFile, FALSE);
}
CATCH_ALL(e)
{
ReleaseFile(pFile, TRUE);
DeleteContents(); // remove failed contents
TRY
{
ReportSaveLoadException(lpszPathName, e,
FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
}
END_TRY
DELETE_EXCEPTION(e);
return FALSE;
}
END_CATCH_ALL
SetModifiedFlag(FALSE); // start off with unmodified
return TRUE;
}
8. BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)
{
// only do this once
ASSERT_VALID_IDR(nIDResource);
ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource);
m_nIDHelp = nIDResource; // ID for help context (+HID_BASE_RESOURCE)
CString strFullString;
if (strFullString.LoadString(nIDResource))
AfxExtractSubString(m_strTitle, strFullString, 0); // first sub-string
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
// attempt to create the window
LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource);
LPCTSTR lpszTitle = m_strTitle;
if (!Create(lpszClass, lpszTitle, dwDefaultStyle, rectDefault,
pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext))
{
return FALSE; // will self destruct on failure normally
}
// save the default menu handle
ASSERT(m_hWnd != NULL);
m_hMenuDefault = ::GetMenu(m_hWnd);
// load accelerator resource
LoadAccelTable(MAKEINTRESOURCE(nIDResource));
if (pContext == NULL) // send initial update
SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
return TRUE;
}
9. void DocTemplate::InitialUpdateFrame(CFrameWnd* pFrame, CDocument* pDoc,BOOL bMakeVisible)
{
// just delagate to implementation in CFrameWnd
pFrame->InitialUpdateFrame(pDoc, bMakeVisible);
}
10. void CFrameWnd::InitialUpdateFrame(CDocument* pDoc, BOOL bMakeVisible)
{
// if the frame does not have an active view, set to first pane
CView* pView = NULL;
if (GetActiveView() == NULL)
{
CWnd* pWnd = GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
if (pWnd != NULL && pWnd->IsKindOf(RUNTIME_CLASS(CView)))
{
pView = (CView*)pWnd;
SetActiveView(pView, FALSE);
}
}
if (bMakeVisible)
{
// send initial update to all views (and other controls) in the frame
SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
// give view a chance to save the focus (CFormView needs this)
if (pView != NULL)
pView->OnActivateFrame(WA_INACTIVE, this);
// finally, activate the frame
// (send the default show command unless the main desktop window)
int nCmdShow = -1; // default
CWinApp* pApp = AfxGetApp();
if (pApp != NULL && pApp->m_pMainWnd == this)
{
nCmdShow = pApp->m_nCmdShow; // use the parameter from WinMain
pApp->m_nCmdShow = -1; // set to default after first time
}
ActivateFrame(nCmdShow);
if (pView != NULL)
pView->OnActivateView(TRUE, pView, pView);
}
// update frame counts and frame title (may already have been visible)
if (pDoc != NULL)
pDoc->UpdateFrameCounts();
OnUpdateFrameTitle(TRUE);
}
B) OnFileOpen()执行过程分析
11. void CWinApp::OnFileOpen()
{
ASSERT(m_pDocManager != NULL);
m_pDocManager->OnFileOpen();
}
12. void CDocManager::OnFileOpen()
{
// prompt the user (with all document templates)
CString newName;
if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,
OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
return; // open cancelled
AfxGetApp()->OpenDocumentFile(newName);
// if returns NULL, the user has already been alerted
}
13. CDocument* CWinApp::OpenDocumentFile(LPCTSTR lpszFileName)
{
ASSERT(m_pDocManager != NULL);
return m_pDocManager->OpenDocumentFile(lpszFileName);
}
14. CDocument* CDocManager::OpenDocumentFile(LPCTSTR lpszFileName)
{
// find the highest confidence
POSITION pos = m_templateList.GetHeadPosition();
CDocTemplate::Confidence bestMatch = CDocTemplate::noAttempt;
CDocTemplate* pBestTemplate = NULL;
CDocument* pOpenDocument = NULL;
TCHAR szPath[_MAX_PATH];
ASSERT(lstrlen(lpszFileName) < _countof(szPath));
TCHAR szTemp[_MAX_PATH];
if (lpszFileName[0] == '/"')
++lpszFileName;
lstrcpyn(szTemp, lpszFileName, _MAX_PATH);
LPTSTR lpszLast = _tcsrchr(szTemp, '/"');
if (lpszLast != NULL)
*lpszLast = 0;
AfxFullPath(szPath, szTemp);
TCHAR szLinkName[_MAX_PATH];
if (AfxResolveShortcut(AfxGetMainWnd(), szPath, szLinkName, _MAX_PATH))
lstrcpy(szPath, szLinkName);
while (pos != NULL)
{
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);
ASSERT_KINDOF(CDocTemplate, pTemplate);
CDocTemplate::Confidence match;
ASSERT(pOpenDocument == NULL);
match = pTemplate->MatchDocType(szPath, pOpenDocument);
if (match > bestMatch)
{
bestMatch = match;
pBestTemplate = pTemplate;
}
if (match == CDocTemplate::yesAlreadyOpen)
break; // stop here
}
if (pOpenDocument != NULL)
{
POSITION pos = pOpenDocument->GetFirstViewPosition();
if (pos != NULL)
{
CView* pView = pOpenDocument->GetNextView(pos); // get first one
ASSERT_VALID(pView);
CFrameWnd* pFrame = pView->GetParentFrame();
if (pFrame != NULL)
pFrame->ActivateFrame();
else
TRACE0("Error: Can not find a frame for document to activate./n");
CFrameWnd* pAppFrame;
if (pFrame != (pAppFrame = (CFrameWnd*)AfxGetApp()->m_pMainWnd))
{
ASSERT_KINDOF(CFrameWnd, pAppFrame);
pAppFrame->ActivateFrame();
}
}
else
{
TRACE0("Error: Can not find a view for document to activate./n");
}
return pOpenDocument;
}
if (pBestTemplate == NULL)
{
AfxMessageBox(AFX_IDP_FAILED_TO_OPEN_DOC);
return NULL;
}
return pBestTemplate->OpenDocumentFile(szPath);
}
15. CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,BOOL bMakeVisible)
{
CDocument* pDocument = CreateNewDocument();
if (pDocument == NULL)
{
TRACE0("CDocTemplate::CreateNewDocument returned NULL./n");
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
return NULL;
}
ASSERT_VALID(pDocument);
BOOL bAutoDelete = pDocument->m_bAutoDelete;
pDocument->m_bAutoDelete = FALSE; // don't destroy if something goes wrong
CFrameWnd* 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;
}
ASSERT_VALID(pFrame);
if (lpszPathName == NULL)
{
// create a new document - with default document name
SetDefaultTitle(pDocument);
// avoid creating temporary compound file when starting up invisible
if (!bMakeVisible)
pDocument->m_bEmbedded = TRUE;
if (!pDocument->OnNewDocument())
{
// user has be alerted to what failed in OnNewDocument
TRACE0("CDocument::OnNewDocument returned FALSE./n");
pFrame->DestroyWindow();
return NULL;
}
// it worked, now bump untitled count
m_nUntitledCount++;
}
else
{
// open an existing document
CWaitCursor wait;
if (!pDocument->OnOpenDocument(lpszPathName))
{
// user has be alerted to what failed in OnOpenDocument
TRACE0("CDocument::OnOpenDocument returned FALSE./n");
pFrame->DestroyWindow();
return NULL;
}
pDocument->SetPathName(lpszPathName);
}
InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
return pDocument;
}
16. CDocument* CDocTemplate::CreateNewDocument()
{
// default implementation constructs one from CRuntimeClass
if (m_pDocClass == NULL)
{
TRACE0("Error: you must override CDocTemplate::CreateNewDocument./n");
ASSERT(FALSE);
return NULL;
}
CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject();
if (pDocument == NULL)
{
TRACE1("Warning: Dynamic create of document type %hs failed./n",
m_pDocClass->m_lpszClassName);
return NULL;
}
ASSERT_KINDOF(CDocument, pDocument);
AddDocument(pDocument);
return pDocument;
}
17. 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)
{
TRACE0("Error: you must override CDocTemplate::CreateNewFrame./n");
ASSERT(FALSE);
return NULL;
}
CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
if (pFrame == NULL)
{
TRACE1("Warning: Dynamic create of frame %hs failed./n",
m_pFrameClass->m_lpszClassName);
return NULL;
}
ASSERT_KINDOF(CFrameWnd, pFrame);
if (context.m_pNewViewClass == NULL)
TRACE0("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))
{
TRACE0("Warning: CDocTemplate couldn't create a frame./n");
// frame will be deleted in PostNcDestroy cleanup
return NULL;
}
// it worked !
return pFrame;
}
18. BOOL CDocument::OnNewDocument()
{
if (IsModified())
TRACE0("Warning: OnNewDocument replaces an unsaved document./n");
DeleteContents();
m_strPathName.Empty(); // no path name yet
SetModifiedFlag(FALSE); // make clean
return TRUE;
}
19. BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)
{
if (IsModified())
TRACE0("Warning: OnOpenDocument replaces an unsaved document./n");
CFileException fe;
CFile* pFile = GetFile(lpszPathName,
CFile::modeRead|CFile::shareDenyWrite, &fe);
if (pFile == NULL)
{
ReportSaveLoadException(lpszPathName, &fe,
FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
return FALSE;
}
DeleteContents();
SetModifiedFlag(); // dirty during de-serialize
CArchive loadArchive(pFile, CArchive::load | CArchive::bNoFlushOnDelete);
loadArchive.m_pDocument = this;
loadArchive.m_bForceFlat = FALSE;
TRY
{
CWaitCursor wait;
if (pFile->GetLength() != 0)
Serialize(loadArchive); // load me
loadArchive.Close();
ReleaseFile(pFile, FALSE);
}
CATCH_ALL(e)
{
ReleaseFile(pFile, TRUE);
DeleteContents(); // remove failed contents
TRY
{
ReportSaveLoadException(lpszPathName, e,
FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
}
END_TRY
DELETE_EXCEPTION(e);
return FALSE;
}
END_CATCH_ALL
SetModifiedFlag(FALSE); // start off with unmodified
return TRUE;
}
20. void DocTemplate::InitialUpdateFrame(CFrameWnd* pFrame, CDocument* pDoc,BOOL bMakeVisible)
{
// just delagate to implementation in CFrameWnd
pFrame->InitialUpdateFrame(pDoc, bMakeVisible);
}
21. void CFrameWnd::InitialUpdateFrame(CDocument* pDoc, BOOL bMakeVisible)
{
// if the frame does not have an active view, set to first pane
CView* pView = NULL;
if (GetActiveView() == NULL)
{
CWnd* pWnd = GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
if (pWnd != NULL && pWnd->IsKindOf(RUNTIME_CLASS(CView)))
{
pView = (CView*)pWnd;
SetActiveView(pView, FALSE);
}
}
if (bMakeVisible)
{
// send initial update to all views (and other controls) in the frame
SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
// give view a chance to save the focus (CFormView needs this)
if (pView != NULL)
pView->OnActivateFrame(WA_INACTIVE, this);
// finally, activate the frame
// (send the default show command unless the main desktop window)
int nCmdShow = -1; // default
CWinApp* pApp = AfxGetApp();
if (pApp != NULL && pApp->m_pMainWnd == this)
{
nCmdShow = pApp->m_nCmdShow; // use the parameter from WinMain
pApp->m_nCmdShow = -1; // set to default after first time
}
ActivateFrame(nCmdShow);
if (pView != NULL)
pView->OnActivateView(TRUE, pView, pView);
}
// update frame counts and frame title (may already have been visible)
if (pDoc != NULL)
pDoc->UpdateFrameCounts();
OnUpdateFrameTitle(TRUE);
}
- OnFileNew()/OnFileOpen()的MFC代码跟踪简析
- MFC OnFileNew OnFileOpen过程分析代码
- MFC OnFileNew OnFileOpen过程分析代码
- MFC OnFileNew OnFileOpen过程分析代码(以记录MFC学习点滴)
- OnFileNew()的定制
- 关于OnFileNew()的定制
- MFC之代码跟踪
- MFC学习笔记:怎样尽可能的跟踪和查看MFC中函数的代码
- 关于MFC中如何调用CWinApp::OnFileNew()和OnFileClose()
- 跟踪代码的方法
- 关于MFC中Winmain函数的跟踪
- 基于MFC对话框的摄像头跟踪
- 深入跟踪MFC程序的执行流程
- 深入跟踪MFC程序的执行流程
- 深入跟踪MFC程序的执行流程
- 关于MFC中main函数的跟踪
- 深入跟踪MFC程序的执行流程
- 简单的跟踪示例代码
- 哪本书是对程序员最有影响、每个程序员都该阅读的书?
- [sql server] 问题总结7- union-- union all--with as 实例
- django foreignkey 中的 self 递归用法
- 打开rar文件
- Driver: 跟设备驱动相关的一些知识点
- OnFileNew()/OnFileOpen()的MFC代码跟踪简析
- 「邮槽」单向进程间通信——Console程序设计
- [sql server] 问题总结8- 中间变量
- 在ASP.Net2.0中使用UrlRewritingNet实现链接重写
- swt布局
- VC用ADO连接oracle的方法
- Java web学习笔记——总
- Java web学习笔记——入门2011/3/5
- 技术影响的力量