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内容生成、新媒体营销和短视频营销等业务的公司。我们拥有一支优秀的团队,专门致力于为客户提供优质的服务。
我们致力于为客户提供一站式的互联网营销服务,帮助客户在激烈的市场竞争中获得更大的优势和发展机会!
发表评论 取消回复