关于MFC单文档文件OnFileOpen的调用过程

//由于MFC中,SendMessage发出一个打开或保存命令时,首先接受到这个命令的框架是
//CWinApp 这个基类的应用程序,可以调用相应的程序来查看有相应的命令函数
如下:
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
afx_msg void OnFileNew();
afx_msg void OnFileOpen();
可知相应程序首先调用的是CWinApp::OnFileNew()函数完成相应的文件打开对话框的实现,
通过查看相应的程序代码,可知相应的代码如下:




void CWinApp::OnFileOpen()
{
ASSERT(m_pDocManager!=NULL);
m_pDocManager->OnFileOpen();
}
可知在CWinApp类中有CDocManager *m_pDocManager指针调用了该函数OnFileOpen,
调用相印的OnFileOpen函数




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);//这个是哪个WinAPP ,
// if returns NULL, the user has already been alerted
}
//可知调用CDocManager函数中的DoPromptFileName函数,如下图


BOOL CDocManager::DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate)
{
CFileDialog dlgFile(bOpenFileDialog);


CString title;
VERIFY(title.LoadString(nIDSTitle));


dlgFile.m_ofn.Flags |= lFlags;


CString strFilter;
CString strDefault;
if (pTemplate != NULL)
{
ASSERT_VALID(pTemplate);
_AfxAppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate, &strDefault);
}
else
{
// do for all doc template
POSITION pos = m_templateList.GetHeadPosition();
BOOL bFirst = TRUE;
while (pos != NULL)
{
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);
_AfxAppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate,
bFirst ? &strDefault : NULL);
bFirst = FALSE;
}
}


// append the "*.*" all files filter
CString allFilter;
VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));
strFilter += allFilter;
strFilter += (TCHAR)'\0';   // next string please
strFilter += _T("*.*");
strFilter += (TCHAR)'\0';   // last string
dlgFile.m_ofn.nMaxCustFilter++;


dlgFile.m_ofn.lpstrFilter = strFilter;
dlgFile.m_ofn.lpstrTitle = title;
dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);


int nResult = dlgFile.DoModal();
fileName.ReleaseBuffer();
return nResult == IDOK;
}
调用完成后,用AfxGetApp()函数获得该CWInApp类的指针,获得相应的类的对象。
并通过该指针获得CWinApp对象的OpenDocumentFile函数,如下函数可视
CDocument *CWinApp::OpenDocumentFile(LPCTSTR lpszFileName)
{
ASSERT(m_pDocManager != NULL);
return m_pDocManager->OpenDocumentFile(lpszFileName);//返回
}
并且函数完成后,重新调用CDocManager中的OpenDocumentFile函数,OpenDocumentFile函数如下
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);
}
,由于我们知道该文档是单文档文件,因此最终获得的CDocument的指针式CSingleDocTemplate的
OpenDocumentFile函数如下:
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;
}
并最终通过相应的Serialize函数调用CGDIDoc中的Serialize函数,实现相应数据的序列化。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MFC 应用程序中,您可以通过添加一个文档类和一个视图类来实现文件的打开和读取。在这种情况下,您可以使用 MFC 框架中的 OnOpenDocument() 函数来打开和读取文件。以下是实现此功能的步骤: 1. 创建一个文档类。可以通过添加一个类来创建文档类,并选择 "CDocument" 作为基类。 2. 在文档类的头文件中添加以下代码,以声明 OnOpenDocument() 函数: ``` class CMyDoc : public CDocument { DECLARE_DYNCREATE(CMyDoc) public: virtual BOOL OnOpenDocument(LPCTSTR lpszPathName); }; ``` 3. 在文档类的源文件中添加以下代码,以实现 OnOpenDocument() 函数: ``` BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; // 在此处添加您的文件读取代码 return TRUE; } ``` 4. 在文档类的源文件中,添加您的文件读取代码。您可以使用 CStdioFile 或 CFile 类来读取文件内容。 5. 创建一个视图类。可以通过添加一个类来创建视图类,并选择 "CView" 作为基类。 6. 在视图类的头文件中添加以下代码,以声明 OnDraw() 函数: ``` class CMyView : public CView { DECLARE_DYNCREATE(CMyView) public: virtual void OnDraw(CDC* pDC); }; ``` 7. 在视图类的源文件中添加以下代码,以实现 OnDraw() 函数: ``` void CMyView::OnDraw(CDC* pDC) { // 在此处添加您的绘制代码 } ``` 8. 在您的 MFC 应用程序中打开资源视图,并双击 "MainFrm"。 9. 在 "MainFrm" 的头文件中添加以下代码,以声明 OnFileOpen() 函数: ``` class CMainFrame : public CFrameWnd { DECLARE_DYNAMIC(CMainFrame) public: afx_msg void OnFileOpen(); }; ``` 10. 在 "MainFrm" 的源文件中添加以下代码,以实现 OnFileOpen() 函数: ``` void CMainFrame::OnFileOpen() { CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, _T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||"), NULL); if (dlg.DoModal() == IDOK) { CString strPath = dlg.GetPathName(); AfxGetApp()->OpenDocumentFile(strPath); } } ``` 11. 在您的 MFC 应用程序中打开资源视图,并双击 "IDD_MAIN_DIALOG"。 12. 将一个按钮控件添加到 "IDD_MAIN_DIALOG" 对话框中。您可以使用工具栏中的按钮工具来添加此控件。 13. 双击该按钮,以添加一个响应函数。例如,如果您想要对一个名为 "IDC_BUTTON_OPEN" 的按钮进行操作,则可以双击该按钮并添加一个响应函数 OnBnClickedButtonOpen()。 14. 在响应函数中添加以下代码: ``` void CMyDialog::OnBnClickedButtonOpen() { CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd(); pFrame->OnFileOpen(); } ``` 现在,当用户击您的应用程序中的 "打开" 按钮时,将弹出一个对话框,用户可以选择要打开的文件。一旦用户选择一个文件,OnOpenDocument() 函数将被调用,并且可以使用该函数读取文件内容。需要注意的是,您需要根据您的应用程序的实际需求来修改以上代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值