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

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

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

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


CFileDialg类


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

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

                                                         图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形式赋值,我们需要将过滤器字符串中的“|”替换成”\0“;

形如:

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)\0*.h;*.hpp;*.cpp\0"\
    "Text File(*.txt)\0*.txt\0"\
    "All Typle(*.*)\0*.*\0" \
    "Lua source file(*.lua)\0*.lua\0"\
    "\0"; 

如果想对对话框作更多定制,我们可通过成员数据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)\0*.h;*.hpp;*.cpp\0"\
        "Text File(*.txt)\0*.txt\0"\
        "All Typle(*.*)\0*.*\0" \
        "Lua source file(*.lua)\0*.lua\0"\
        "\0";

    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\n"), 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()
{
    //格式:过滤器描述符(显示作用)+ \0 + 文件扩展名称(过滤作用)
    //多个扩展名称之间用(;)分隔,两个过滤字符串之间以\0分隔
    //最后的过滤器需要以两个\0\0结尾
    char szFilters[] = 
        "C++ source file(*.h;*,hpp;*.cpp)\0*.h;*.hpp;*.cpp\0"\
        "Text File(*.txt)\0*.txt\0"\
        "All Typle(*.*)\0*.*\0" \
        "Lua source file(*.lua)\0*.lua\0"\
        "\0"; 
    //当过滤器或者默认构造参数赋值较少情况下,
    //使用构造函数修改对话框初始状态可能更好,这过滤器较多
    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();
    }
}

保存文件:

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

打开文件:

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

成员函数

CFileDialog类的成员

数据成员

m_ofnWindows 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消息 
    原文作者:Jimmy1224
    原文地址: https://blog.csdn.net/xiao3404/article/details/54882541
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞