zoukankan      html  css  js  c++  java
  • 【MFC】打开文件的流程

    打开文件的步骤如下:

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

     我们程序中经常需要定制的操作如下:

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

    2. 定制文件显示的行为

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

    1. CWinApp::OnFileOpen

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

    下面是CWinApp::OnFileOpen的源码:

    1 void CWinApp::OnFileOpen()

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

    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 

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

  • 相关阅读:
    手机蓝牙各类服务对应的UUID
    Android数据传递的四种方法
    PS延迟显示的解决方法
    字符串分离函数
    利用cmd命令创建wifi热点
    我的毕业设计——无线控制平台
    只需简单一步,android自带的示例程序 BluetoothChat 变蓝牙串口助手
    volatile 关键字
    PC蓝牙开发笔记
    Jquery与CSS中的大于符号
  • 原文地址:https://www.cnblogs.com/hdtianfu/p/2357724.html
Copyright © 2011-2022 走看看