MFC MDI 打开文件的调用过程
来源:互联网 发布:剑灵男灵族捏脸数据 编辑:程序博客网 时间:2024/06/08 05:31
1,
ON_COMMAND(ID_FILE_OPEN, CWinAppEx::OnFileOpen)
2,
void CWinApp::OnFileOpen()
{
ENSURE(m_pDocManager != NULL);
m_pDocManager->OnFileOpen();
}
3,
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
}
3,
CDocument* CWinApp::OpenDocumentFile(LPCTSTR lpszFileName, BOOL bAddToMRU)
{
ENSURE_VALID(m_pDocManager);
return m_pDocManager->OpenDocumentFile(lpszFileName, bAddToMRU);
}
4,
CDocument* CDocManager::OpenDocumentFile(LPCTSTR lpszFileName, BOOL bAddToMRU)
{
if (lpszFileName == NULL)
{
AfxThrowInvalidArgException();
}
// 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;
Checked::tcsncpy_s(szTemp, _countof(szTemp), lpszFileName, _TRUNCATE);
LPTSTR lpszLast = _tcsrchr(szTemp, '\"');
if (lpszLast != NULL)
*lpszLast = 0;
if( AfxFullPath(szPath, szTemp) == FALSE )
{
ASSERT(FALSE);
return NULL; // We won't open the file. MFC requires paths with
// length < _MAX_PATH
}
TCHAR szLinkName[_MAX_PATH];
if (AfxResolveShortcut(AfxGetMainWnd(), szPath, szLinkName, _MAX_PATH))
Checked::tcscpy_s(szPath, _countof(szPath), szLinkName);
while (pos != NULL)
{
//遍历m_templateList中保存的的Doctemplate,逐个和欲打开的文件名称进行匹配
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);
ASSERT_KINDOF(CDocTemplate, pTemplate);
CDocTemplate::Confidence match;
ASSERT(pOpenDocument == NULL);
match = pTemplate->MatchDocType(szPath, pOpenDocument);
//匹配成功或者发现此文件已经打开,前者保存为pBestTemplate,且此时pOpenDocument为NULL
if (match > bestMatch)
{
bestMatch = match;
pBestTemplate = pTemplate;
}
if (match == CDocTemplate::yesAlreadyOpen)
break; // stop here
}
if (pOpenDocument != NULL)
{
POSITION posOpenDoc = pOpenDocument->GetFirstViewPosition();
if (posOpenDoc != NULL)
{
CView* pView = pOpenDocument->GetNextView(posOpenDoc); // get first one
ASSERT_VALID(pView);
CFrameWnd* pFrame = pView->GetParentFrame();
if (pFrame == NULL)
TRACE(traceAppMsg, 0, "Error: Can not find a frame for document to activate.\n");
else
{
pFrame->ActivateFrame();
if (pFrame->GetParent() != NULL)
{
CFrameWnd* pAppFrame;
if (pFrame != (pAppFrame = (CFrameWnd*)AfxGetApp()->m_pMainWnd))
{
ASSERT_KINDOF(CFrameWnd, pAppFrame);
pAppFrame->ActivateFrame();
}
}
}
}
else
TRACE(traceAppMsg, 0, "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;
}
//用匹配的Doctemplate开启Doc,View,Frame组合
return pBestTemplate->OpenDocumentFile(szPath, bAddToMRU, TRUE);
}
CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName, BOOL bAddToMRU, BOOL bMakeVisible)
{
//创建CDocument对象
CDocument* pDocument = CreateNewDocument();
if (pDocument == NULL)
{
TRACE(traceAppMsg, 0, "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
//创建frame和View对象并创建相应的窗口
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
TRACE(traceAppMsg, 0, "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))//Serialize被调用,从文件中读取
{
// user has be alerted to what failed in OnOpenDocument
TRACE(traceAppMsg, 0, "CDocument::OnOpenDocument returned FALSE.\n");
pFrame->DestroyWindow();
return NULL;
}
pDocument->SetPathName(lpszPathName, bAddToMRU);
pDocument->OnDocumentEvent(CDocument::onAfterOpenDocument);
}
设置frame的title
InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
return pDocument;
}
总体可看出在打开一个新文件时,App类,DocManager类,Doctemplate类 的各自职责
同时也将 View doc Frame和Docteplate进行了一些粘合
- MFC MDI 打开文件的调用过程
- MFC 的MDI创建空文档调用过程
- MDI文件如何打开
- MFC MDI OnOpenDocument后自动调用相应的OnDraw
- 激活MDI中已经打开过的文件
- MFC调用打开文件、文件夹对话框
- MFC调用com打开文件预览
- 【MFC】打开文件的流程
- 【MFC】打开文件的流程
- 【MFC】打开文件的流程
- 【MFC】打开文件的流程
- MFC + MDI文件拖拽功能
- mfc 调用绿色版的Foxit Reader / 迷你pdf阅读器.exe的同时打开一个pdf文件
- MFC MDI
- c#判断打开的窗体:MDI和非MDI
- 改变MFC中MDI默认打开方式(ID_FILE_OPEN)
- MFC 程序中调用记事本 NotePad 打开 txt 文件
- 从open系统调用的源码看文件的打开过程
- BZOJ 1996 合唱队
- Mysql安装的几种方式详解
- UVA1121 Subsequence 二分+前缀数组
- java 中的equal和==的区别
- 3步部署shipyard-实验笔记
- MFC MDI 打开文件的调用过程
- hadoop之 Hadoop 2.x HA 、Federation
- 实验三 Linux文件管理
- 欢迎使用CSDN-markdown编辑器
- HTML元素分类、定位简单总结
- 设计模式简析
- hdu1963(完全背包)
- JavaScript对象——属性描述符
- 点分十进制表示的IP地址解析方法