MFC实现文件打开和保存功能实现

在大多数软件中,都有“打开”和“保存”这两个功能,以“记事本为打开功能”为例,其打开对话画框的界面如下:


其保存对画框,与打开对话框界面基本一样,下面也给程序增加这样的对话框,我们可以使用MFC提供的CFileDialog类来完成;


CFileDialg类


CFileDialog类封装了Windows常用的文件对话框。常用的文件对话框提供了一种简单的与Windows标准相一致的文件打开和文件存盘对话框功能,该类的派生层次如下:

                                    

                                                         图1 CFileDialog类的派生层次

从上图中,可以看出这个类也是对话框的类,显示对话框可以使用DoModal函数来完成;


要使用CFileDialog,需要先用CFileDialog构造函数构造一个对象,其构造函数如下:

CFileDialog(BOOL bOpenFileDialog,
            LPCTSTR lpszDefExt = NULL,
            LPCTSTR lpszFileName = NULL,
            DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
            LPCTSTR lpszFilter = NULL,
            CWnd* pParentWnd = NULL
           );
参数:

bOpenFileDialg 

       如果为TRUE, 则创建文件打开对话框;如果为FALSE,则构造一个File Save As(另存为)对话框。  
lpszDefExt 

       缺省文件扩展名,如果用户在文件名编辑框中不包含扩展名,则lpszDefExt定义的扩展名自动加到文件名后。如果为NULL,则不添加扩展名。  
lpszFileName 

        初始显示于文件名编辑框中的文件名,如果为NULL,则不显示初始文件名。  
dwFlags 

          一个或多个标志的组合,使你可定制对话框。如果你改变m_ofn.Flags结构成员,在改变中用OR操作保持缺省行为完整。  
lpszFilter

         一列字符串对,指定可以应用到文件的过滤器。如果指定过滤器,仅被选择的文件显示于文件列表框中
pParentWnd 

          指向文件对话框对象的父窗口或拥有者窗口。  

 其中lpszFilter是个很重要的一个参数,想要完成文件过滤显示功能,需要对这个参数进行赋值;

其格式说明如下:

双字符串的第一个字符串描述过滤器,第二个串表明使用的文件扩展名,多重扩展可用“;”来指定。字符串由两个“|”字符结尾;

如果lpszFilter不是以默认构造形式赋值,而是通过m_ofn.lpszFilter形式赋值,我们需要将过滤器字符串中的“|”替换成”“;

形如:

char szFilter[] =
"Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|*.xlc; *.xls|All Files (*.*)|*.*||";
TCHAR szFilters[] = 
    "C++ source file(*.h;*,hpp;*.cpp)*.h;*.hpp;*.cpp"
    "Text File(*.txt)*.txt"
    "All Typle(*.*)*.*" 
    "Lua source file(*.lua)*.lua"
    ""; 

如果想对对话框作更多定制,我们可通过成员数据m_ofn对对话框进行更多赋值,该参数是Windows OPENFILENAME结构,更多信息参加msdn介绍:

typedef struct tagOFN { 
  DWORD         lStructSize; 
  HWND          hwndOwner; 
  HINSTANCE     hInstance; 
  LPCTSTR       lpstrFilter; //过滤器字符串
  LPTSTR        lpstrCustomFilter; 
  DWORD         nMaxCustFilter; 
  DWORD         nFilterIndex; 
  LPTSTR        lpstrFile;  //文件名字
  DWORD         nMaxFile; 
  LPTSTR        lpstrFileTitle; 
  DWORD         nMaxFileTitle; 
  LPCTSTR       lpstrInitialDir; 
  LPCTSTR       lpstrTitle; //文件对话框名字
  DWORD         Flags; 
  WORD          nFileOffset; 
  WORD          nFileExtension; 
  LPCTSTR       lpstrDefExt; //默认文件扩展名
 ...
} OPENFILENAME, *LPOPENFILENAME;

实例


我们在CFile文件操作示例博文基础上修改其中的OnWriteFile和OnReadFile函数,可以完成对话框的保持和打开功能,具体代码如下:

OnReadFile函数实现:

/****************************************************************
*函数名称: 打开对话框
*功    能:
*作    者:Jin
*日    期:2017年2月5日
****************************************************************/
void CFileView::OnReadFile()
{
    // TODO: 在此添加命令处理程序代码
    char szFilters[] = 
        "C++ source file(*.h;*,hpp;*.cpp)*.h;*.hpp;*.cpp"
        "Text File(*.txt)*.txt"
        "All Typle(*.*)*.*" 
        "Lua source file(*.lua)*.lua"
        "";

    CFileDialog OpenDlg(TRUE);
    OpenDlg.m_ofn.lpstrTitle = "Open File";
    OpenDlg.m_ofn.lpstrFilter = szFilters;

    if (IDOK == OpenDlg.DoModal())
    {
        CFile File;
        CFileException e;
        //构造文件,同时增加异常处理
        if(!File.Open(OpenDlg.GetPathName(), CFile::modeRead,&e))
        {
            CString strErr;
            strErr.Format(_T("File could not be opened %d
"), e.m_cause);
            MessageBox(strErr);
        }
        //创建指定大小的Buffer
        DWORD  dwFileLenth = (DWORD)File.GetLength();
        //初始化buffer, 增加一个/0空间
        char *pBuf = new char[dwFileLenth + 1];
        memset(pBuf, 0, dwFileLenth + 1);

        if (pBuf != NULL)
        {
            //读取文件内容
            File.Read(pBuf,dwFileLenth);
            File.Close();
            //显示文件内容
            MessageBox(pBuf);
            //删除bufer,避免内存泄漏
            delete[] pBuf;
            pBuf = NULL;
        }
    }

}

OnWriteFile函数实现:

/****************************************************************
*函数名称:保存对话框
*功    能:
*作    者:Jin
*日    期:2017年2月5日
****************************************************************/
void CFileView::OnWriteFile()
{
    //格式:过滤器描述符(显示作用)+  + 文件扩展名称(过滤作用)
    //多个扩展名称之间用(;)分隔,两个过滤字符串之间以分隔
    //最后的过滤器需要以两个结尾
    char szFilters[] = 
        "C++ source file(*.h;*,hpp;*.cpp)*.h;*.hpp;*.cpp"
        "Text File(*.txt)*.txt"
        "All Typle(*.*)*.*" 
        "Lua source file(*.lua)*.lua"
        ""; 
    //当过滤器或者默认构造参数赋值较少情况下,
    //使用构造函数修改对话框初始状态可能更好,这过滤器较多
    CFileDialog FileDlg(FALSE, "txt", _T("Test")); 
    FileDlg.m_ofn.lpstrTitle = "Save File";
    FileDlg.m_ofn.lpstrFilter = szFilters;

    //通过以下两个参数修改对话框初始状态,程序奔溃,使用默认构造形式正常
    //环境:VS2008编译器+Wind7系统
    //FileDlg.m_ofn.lpstrDefExt = "txt";
    //FileDlg.m_ofn.lpstrFile = "test";

    if (IDOK == FileDlg.DoModal())
    {
        CFile File(FileDlg.GetPathName(),CFile::modeCreate|CFile::modeReadWrite);
        
        char szBufData[100] = {"hello word!"};
        //写入文件内容,不包含/0
        File.Write(szBufData, strlen(szBufData));
        //立即写入,不缓冲
        File.Flush();
        //文件操作结束关闭
        File.Close();
    }
}

保存文件:

      

打开文件:

            


成员函数


CFileDialog类的成员

数据成员

m_ofn Windows OPENFILENAME结构,提供对基本文件对话框参数的访问

构造函数
CFileDialog 构造一个CFileDialog对象操作
DoModal 显示对话框并使用户可以进行选择
GetPathName 返回选定文件的完整路径
GetFileName 返回选定文件的文件名
GetFileExt 返回选定文件的扩展文件名
GetFileTitle 返回选定文件的标题
GetNextPathName 返回下一个选定文件的完整路径
GetReadOnlyPref 返回选定文件的只读状态
GetStartPosition 返回文件名列表的第一个元素位置

可覆盖的函数
OnShareViolation 发生共享冲突时调用
OnFileNameOK 确认键入对话框中的文件名
OnLBSelChangedNotify 当列表框选择改变时调用
OnInitDone 处理WM_NOTIFY CDN_INITDONE消息
OnFileNameChange 处理WM_NOTIFY CDN_SELCHANGE消息
OnFolderChange 处理WM_NOTIFY CDN_FOLDERCHANGE消息
OnTypeChange 处理WM_NOTIFY CDN_TYPECHANGE消息 


原文地址:https://www.cnblogs.com/jinxiang1224/p/8468337.html