CFileDialog的用法

CFileDialog是MFC(Microsoft Foundation Classes)提供的文件对话框类之一,在Windows应用程序中经常用于打开、保存和选择文件等任务。本文将详细介绍CFileDialog的使用方法,包括CFileDialog类的概述、用法和案例说明。

一、CFileDialog类概述

CFileDialog是Windows API中的一个类,是MFC对Windows API的封装,可以在MFC应用程序中使用。CFileDialog类提供了打开、保存、选择文件等功能,主要有以下特性:

1.支持打开文件、保存文件、选择文件夹等功能;

2.支持设置文件过滤器,如显示特定类型的文件;

3.支持设置默认文件名、标题等参数;

4.支持多选、读取多个文件名等功能。

基本语法如下:

```C++

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

```

下面逐一介绍各个参数:

1. bOpenFileDialog:打开文件对话框标志。如果为TRUE,表示打开文件对话框;如果为FALSE则表示保存文件对话框。

2. lpszDefExt:默认扩展名,例如“.txt”。

3. lpszFileName:默认的文件名称。

4. dwFlags:文件对话框标记。这个参数是DWORD类型,详见下表:

|OFN_ENABLEHOOK|启用钩子功能,可以通过钩子函数处理消息。|

| --- | --- |

|OFN_ENABLETEMPLATE|启用自定义模板文件|

|OFN_ENABLETEMPLATEHANDLE|启用HINSTANCE句柄指定的已加载的模板资源。|

|OFN_EXPLORER|适用于Windows Explorer风格。|

|OFN_EXTENSIONDIFFERENT|允许选择文件夹和扩展名不同。|

|OFN_FILEMUSTEXIST|表示如果用户输入的文件名不存在,将提示错误。|

|OFN_HIDEREADONLY|文件只读标志,表示不显示只读的文件。|

|OFN_LONGNAMES|欲使用长文件名(即使在Windows 95/98下),必须使其为TRUE。|

|OFN_NOCHANGEDIR|用户选择文件后,是否自动转到当前目录下。|

|OFN_NODEREFERENCELINKS|不存在的文件名项不是快捷方式|

|OFN_NOLONGNAMES|不改变用户控制面板文件显示设置。|

|OFN_NONETWORKBUTTON|是否显示网络按钮。|

|OFN_NOREADONLYRETURN|文件已存在同时是只读属性时,不允许用户改写文件。|

|OFN_NOTESTFILECREATE|指定的文件名不允许测试创建,当指定OFN_OVERWRITEPROMPT时,避免询问用户是否重新创建。|

|OFN_NOVALIDATE|不允许名称空,即输入不允许为空格。|

|OFN_OVERWRITEPROMPT|文件已存在时提示覆盖文件。|

|OFN_PATHMUSTEXIST|表示如果用户输入的文件路径不存在,会提示错误。|

|OFN_READONLY|文件只读标志,如果文件已经存在,则会将其设为只读。|

|OFN_SHAREAWARE|如果允许文档共享,则为TRUE。|

|OFN_SHOWHELP|是否显示帮助按钮。|

5. lpszFilter:文件类型过滤器,例如"文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||"。这个参数可以指定需要显示的文件类型。lpszFilter的格式是:

```C++

"文件类型1(*.扩展名1)|*.扩展名1|文件类型2(*.扩展名2)|*.扩展名2|……|文件类型n(*.扩展名n)|*.扩展名n||"

```

可以将lpszFilter指定为NULL,表示显示所有文件。

6. pParentWnd:文件对话框所属的窗口指针。

二、CFileDialog类的使用方法

1. 打开文件对话框

在打开文件对话框时,通常需要设置相应的参数,以满足实际需求。例如,设置文件过滤器、默认路径、默认文件名等。

```C++

CFileDialog dlg(TRUE,NULL,NULL,OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST,_T("所有文件(*.*)|*.*||"),NULL);

```

上面的代码中,第一个参数为TRUE,表示打开文件对话框,第二个参数为NULL,表示没有默认扩展名,第三个参数为NULL,表示没有默认文件名,第四个参数为OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST,这个参数表示用户输入的文件名和路径必须存在,否则会提示错误;第五个参数为所有文件。最后一个参数为NULL,表示文件对话框的父窗口为NULL。

使用DoModal函数显示对话框,并获得用户的选择信息。

```C++

if (dlg.DoModal() == IDOK)

{

CString strPathName = dlg.GetPathName();

......

}

```

DoModal函数的返回值为用户选择的操作类型,如果用户单击确定按钮,则返回IDOK;如果用户单击取消按钮,则返回IDCANCEL。

GetPathName函数可以获得用户选择的文件的完整路径。

2. 保存文件对话框

在保存文件对话框时,需要设置文件过滤器、默认路径、默认文件名等。与打开文件对话框相比,不同之处在于第一个参数为FALSE,表示该文件对话框是用于保存文件的。

```C++

CFileDialog dlg(FALSE,_T(".txt"),NULL,OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY,_T("文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||"));

```

第一个参数为FALSE,表示保存文件对话框,第二个参数为”.txt”,表示默认扩展名为.txt,第三个参数为NULL,表示默认文件名为空,第四个参数为OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY,这个参数表示如果文件已经存在,则会提示用户询问是否覆盖原有文件,同时文件只读属性不可见;第五个参数为文件过滤器。

如果用户单击确定按钮,则可以通过GetPathName函数获取用户选择的文件的完整路径。

```C++

if (dlg.DoModal() == IDOK)

{

CString strPathName = dlg.GetPathName();

......

}

```

3. 选择文件夹对话框

如果需要在程序中选择文件夹,可以使用SHBrowseForFolder函数和BROWSEINFO结构体,但这种方法较为复杂。更简单的方法是使用CFileDialog,通过指定文件过滤器,可以选择文件夹。例如:

```C++

CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("文件夹(*. )| "),NULL);

```

其中,文件过滤器为“文件夹(*.)| ”,表示只显示文件夹,文件名后缀为空。

4. 设置文件过滤器

文件过滤器用于在文件对话框中显示需要的文件类型。文件对话框会根据文件过滤器列出可供选择的文件类型。文件过滤器由双竖线(||)标识结尾,每个文件类型由一个描述字符串和一个过滤字符串组成。描述字符串用于说明该文件类型,过滤字符串用于指定文件后缀名。多个文件类型之间可以用“|”分隔,例如:

```C++

TCHAR szFilter[]= _T("图像文件(*.bmp;*.jpg)|*.bmp;*.jpg|文本文件(*.txt)|*.txt|所有文件等(*.*) |*.*||");

```

这个文件过滤器,首先会显示所有.bmp和.jpg格式的图像文件,然后会显示所有.txt格式的文本文件,最后将显示所有文件。

5. 设置默认文件名和默认扩展名

使用CFileDialog,可以对文件对话框的打开和保存功能进行扩展,设置默认的文件名和扩展名。例如,可以在打开文件对话框中设置默认文件名和扩展名“*.txt”等。

```C++

CFileDialog dlg(TRUE,_T("txt"),_T("test"),OFN_FILEMUSTEXIST,_T("文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||"));

```

第二个参数“.txt”是默认扩展名,第三个参数“test”是默认文件名。

6. 设置多选、读取多个文件名

使用CFileDialog,可以设置允许用户多选和读取多个文件名,例如:

```C++

CFileDialog dlg(TRUE,_T(""),_T(""),OFN_ALLOWMULTISELECT |OFN_EXPLORER,_T("所有文件(*.*)|*.*||"));

```

其中,第四个参数OFN_ALLOWMULTISELECT 表示允许用户选择多个文件;OFN_EXPLORER 适用于Windows Explorer风格的对话框。

在用户点击打开按钮后,可以遍历用户选择的所有文件名,组成完整的路径。

```C++

CString strFileName = dlg.GetFileName();//获取用户选择的文件名,不包括路径

CString strFilePath = dlg.GetPathName();//获取用户选择的文件路径,不包括文件名

POSITION pos = dlg.GetStartPosition(); //获取第一个选择项的位置

while (pos != NULL)

{

CString strPath = dlg.GetNextPathName(pos); //从当前位置取第一个选择项

}

```

GetNextPathName函数可以依次返回用户选择的每一个文件的完整路径。

三、CFileDialog的案例说明

下面通过一个基于MFC的简单文件读取软件来更好地说明CFileDialog的用法。

1. 构建基本界面

首先在资源管理器中新建一个Dialog资源,命名为IDD_DIALOG_MAIN,布局如图所示,添加一个按钮和一个列表框。

![filedialog1](https://img-blog.csdn.net/20180309101617539?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhlbmc4MjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/50)

代码如下:

```C++

BOOL CSimpleFileReaderDlg::OnInitDialog()

{

CDialogEx::OnInitDialog();

//......

m_ListBoxFileList.SubclassDlgItem(IDC_LIST_FILES, this); //将该dialog中的List Box控件绑定一个CListBox对象m_ListBoxFileList

m_ListBoxFileList.ResetContent();//初始化List Box控件

return TRUE;

}

```

2. 点击按钮,打开文件对话框

在按钮的OnBnClicked事件中,使用CFileDialog打开文件对话框:

```C++

void CSimpleFileReaderDlg::OnBnClickedButtonOpenfile()

{

// 在打开文件对话框时使用默认参数

CFileDialog dlgOpen(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("所有文件(*.*)|*.*||"), this);

if (dlgOpen.DoModal() == IDOK)

{

CString strPathName = dlgOpen.GetPathName();

// 打开文件

CFile file;

if (!file.Open(strPathName, CFile::modeRead))

{

// 读取文件失败

AfxMessageBox(_T("读取文件失败!"), MB_OK | MB_ICONERROR);

return;

}

// 显示文件内容

ShowFileContentRaw(&file, m_ListBoxFileList);//在List Box控件中显示文件内容

file.Close();

}

}

```

这里的Open对话框使用了默认参数,用户可以浏览计算机上的所有文件,也可以使用“文件类型”下拉列表来快速筛选文件。在用户打开文件后,程序通过ShowFileContentRaw在ListBox显示文件内容。这个函数的代码如下:

```C++

void CSimpleFileReaderDlg::ShowFileContentRaw(CFile* pFile, CListBox& listBox)

{

ASSERT(pFile != NULL);

ASSERT(listBox.GetSafeHwnd() != NULL);

// 获取文件长度

ULONGLONG nLength = pFile->GetLength();

if (nLength == 0 || nLength >= INT_MAX)

{

return;

}

// 读取文件内容

BYTE *pBuffer = NULL;

try {

pBuffer = new BYTE[nLength + 1];

pFile->Read(pBuffer, nLength);

pBuffer[nLength] = 0;

}

catch (...) {

AfxMessageBox(_T("内存分配失败!"), MB_ICONERROR | MB_OK);

return;

}

//....

}

```

ShowFileContentRaw读取文件内容,并将内容在List Box控件中显示。

3. 点击按钮,保存文件

在按钮的OnBnClicked事件中,使用CFileDialog打开“另存为”对话框,将List Box中的内容保存至指定路径:

```C++

void CSimpleFileReaderDlg::OnBnClickedButtonSaveas()

{

CFileDialog dlgSave(FALSE, NULL, NULL, OFN_OVERWRITEPROMPT, _T("文本文件(*.txt)|*.txt||"), this);

if (dlgSave.DoModal() == IDOK)

{

CString strPathName = dlgSave.GetPathName();

// 保存文件

CFile fileOut;

if (!fileOut.Open(strPathName, CFile::modeCreate | CFile::modeWrite))

{

// 保存文件失败

AfxMessageBox(_T("保存文件失败!"), MB_OK | MB_ICONERROR);

return;

}

SaveToFileRaw(&fileOut, m_ListBoxFileList);//将List Box中的内容存储到文件中

fileOut.Close();

AfxMessageBox(_T("保存文件成功!"), MB_OK | MB_ICONINFORMATION);

}

}

```

其中,文件保存的格式为TXT文件,CFile::modeCreate 和 CFile::modeWrite 表示如果文件存在,则先删除源文件内容,再写入新数据。

SaveToFileRaw函数可以将ListBox的内容保存到文件中,代码如下:

```C++

void CSimpleFileReaderDlg::SaveToFileRaw(CFile* pFile, CListBox& listBox)

{

int itemCount = listBox.GetCount();

CString lineBuffer;

for (int i = 0; i < itemCount; ++i)

{

listBox.GetText(i, lineBuffer);

lineBuffer.AppendChar(0x0a);

pFile->Write((LPCTSTR)lineBuffer, lineBuffer.GetLength() * sizeof(TCHAR));

lineBuffer.Empty();

}

}

```

这个函数首先获取ListBox的行数,然后依次读取每一行内容,写入文件,并在行末添加0x0a(换行)。

通过上面的代码实现了一个简单的文件读取程序,在软件中使用了CFileDialog的打开和保存文件对话框,可以方便地选择文件和保存文件。

壹涵网络我们是一家专注于网站建设、企业营销、网站关键词排名、AI内容生成、新媒体营销和短视频营销等业务的公司。我们拥有一支优秀的团队,专门致力于为客户提供优质的服务。

我们致力于为客户提供一站式的互联网营销服务,帮助客户在激烈的市场竞争中获得更大的优势和发展机会!

点赞(104) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部