C++ MFC打开文件的流程

打开文件的步骤以下:框架

弹出打开文件对话框 -> 获取选择的文件,并将文件显示在视图中。 函数

 咱们程序中常常须要定制的操做以下:spa

1. 定制弹出的文件对话框,例如须要修改打开文件的类型或扩展名code

2. 定制文件显示的行为blog

3. 定制文件打开后的行为文档

 

1. CWinApp::OnFileOpen源码

它是ID_FILE_OPEN消息的处理函数,在内部调用CDocManager::OnFileOpen。it

下面是CWinApp::OnFileOpen的源码:io

1 void CWinApp::OnFileOpen()

2 {
3     ENSURE(m_pDocManager != NULL);
4     m_pDocManager->OnFileOpen();  //CDocManager m_pDocManager; 
5 }class

CDocManager::OnFileOpen的主要做用是弹出文件选择对话框,它的源码以下:

复制代码
 1 void CDocManager::OnFileOpen()

 2 {
 3     // prompt the user (with all document templates)
 4     CString newName;
 5     if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,
 6       OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
 7     return; // open cancelled
 8 
 9     AfxGetApp()->OpenDocumentFile(newName);
10     // if returns NULL, the user has already been alerted
11 }

复制代码

CDocManager::DoPromptFileName的做用就是弹出文件选择对话框。

写到这里咱们已经能够解决第一个问题了---定制文件打开对话框。咱们能够选择两种方式:

第一种:重写CWinApp::OnFileOpen

 示例以下:

 

复制代码
1 CYourApp::OnFileOpen()
2 {
3     CString newName;
4     // 1. 在这里弹出本身的打开文件对话框
5     // 2. 直接调用OpenDocumentFile(newName)
6     OpenDocumentFile(newName);
7 }
复制代码

 

 这种方式的缺点是,若是要定制保存文件对话框,还得重写其余的某个函数,如CDocument::DoSave。

第二种: 重写CDocManager::DoPromptFileName

这种方式会同时改变打开文件对话框和保存文件对话框,由于打开和保存时的对话框都是经过此函数弹出的。 

这种方式须要两步:

1. 自定义一个CDocManager的子类,例如,CYourDocManager,在其中重写DoPromptFileName方法

2.  在CYourApp::InitInstance函数中找到AddDocTemplate,并在它的前面加上这样一行:m_pDocManager  = new CYourDocManager;

     由于在AddDocTemplate中先判断m_pDocManager是否为Null,若为Null则建立一个。咱们在它前边将m_pDocManager实例化,

     这样以后就会调用咱们定制的DoPromptFileName函数了。

 

 2. CWinApp::OpenDocumentFile 

 在获取要打开文件的路径后框架调用了这个函数,并在这个函数中完成了读取文件数据并显示的操做。

经过跟踪MFC的源码,咱们会发现真正打开文件是在CDocument::OnOpenDocument中进行的,

CDocument::OnOpenDocument的默认行为是先调用DeleteContents成员函数来确保文档空白,而后调用Serialize函数读取文件数据。

所以若是你的程序有打开文件的需求,则必须在你的文档类中重写Serialize函数。 

 

上文中,咱们已经解决了前两个定制的需求,如今来解决第三个,若是咱们在打开文档后须要进行某些操做,如初始化, 咱们能够对三个函数进行重写:

1. CDocument::OnOpenDocument

    在Document中咱们能够获取它关联的View,若是打开文档后须要对View进行某些初始化或者其余的一些初始化,则能够重写这个函数,示例以下:

复制代码
1 BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName)

2 {
3    if (!CDocument::OnOpenDocument(lpszPathName))
4       return FALSE;
5    // 进行初始化 

6    return TRUE;
7 }

复制代码

也能够对下面两个函数进行重写以进行某些初始化 

2. CWinApp::OpenDocumentFile

默认行为:CDocManager::OpenDocumentFile -->CDocument::OnOpenDocument

也就是说它最终还要调用CDocument::OnOpenDocument。 其中,CDocManager::OpenDocumentFile真正建立了Document。

3. CWinApp::OnFileOpen 

 具体将初始化的代码放在哪里,没有一个统一的标准,对于本人来讲,在哪里初始化方便,便把初始化代码放在哪里。

相关文章
相关标签/搜索