Windows编程时,常用到打开文件(夹)对话框,选择文件或者多个文件的功能。Windows提供了好几种方式,现在做个总结,也好方便以后的使用。
常用的方式有三种:
1.1 使用OPENFILENAME这个结构体和GetOpenFileName()函数
这种方式在于能够可以实现单选文件或者多选文件的功能。多选时,只需按照字符串的拼接格式进行split即可。
打开单文件的代码:
char szFilePath[1024] = {0}; // 所选择的文件最终的路径
OPENFILENAME ofn= {0};
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = m_hWnd;
ofn.lpstrFilter = "txt文件(*.txt)\0";//要选择的文件后缀
ofn.lpstrInitialDir = "./";//默认的文件路径
ofn.lpstrFile = szFilePath;//存放文件的缓冲区
ofn.nMaxFile = sizeof(szFilePath)/sizeof(*szFilePath);
ofn.nFilterIndex = 0;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER ; //标志如果是多选要加上OFN_ALLOWMULTISELECT
if (!GetOpenFileName(&ofn))
{
return ;
}
if (strcmp(szFilePath, "") == 0)
{
// 检验是否获取成功
return ;
}
效果图:
1.2 使用SHBrowseForFolder调用
此种功能,是产生文件浏览的特效。可以选择文件或者文件夹。
选择文件代码示例:
char szFilePath[1024] = {0}; // 所选择的文件最终的路径
BROWSEINFO bi;
ZeroMemory(&bi,sizeof(BROWSEINFO));
bi.hwndOwner = NULL;
bi.pszDisplayName = szFilePath;
bi.lpszTitle = ("从下面选择文件或文件夹:");
bi.ulFlags = BIF_BROWSEINCLUDEFILES;
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
if (NULL == idl)
{
return;
}
SHGetPathFromIDList(idl,szFilePath);
if (strcmp(szFilePath, "") == 0)
{
// 检验是否获取成功
return ;
}
效果图:
1.3 使用系统的CFileDialog
CFileDialog是系统提供的打开和保存文件对话框类。可以弹出打开文件对话框,也可以弹出保存文件对话框。功能相比比较丰富。
在介绍如何使用之前,着重介绍其构造函数的定义。这是关键。
1.3.1 构造函数 CFileDialog()
CFileDialog::CFileDialog(
BOOL bOpenFileDialog,
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL );
参数意义如下:
- bOpenFileDialog 为TRUE则显示打开对话框,为FALSE则显示保存对话文件对话框。
- lpszDefExt 指定默认的文件扩展名。
- lpszFileName 指定默认的文件名。
- dwFlags 指明一些特定风格。
- lpszFilter 是最重要的一个参数,它指明可供选择的文件类型和相应的扩展名。
参数格式如:
"Worksheet Files (*.xls)|*.xls;*.xlsx|text Files (*.txt)|*.txt|All Files (*.*)|*.*||";
文件类型说明和扩展名间用 | 分隔,同种类型文件的扩展名间可以用 ; 分割,每种文件类型间用 | 分隔,末尾用 || 指明。
- pParentWnd 指明父窗口该函数未指明选择文件对话框的默认选择路径,一般情况是当前路径。
1.3.2 选择打开文件对话框的使用
一般情况下,通过构造函数构造一个CFileDialog类对象,通过doModel函数来弹出相应的对话框,用户在对话框中选中文件,点击确定,即可获取到该文件的路径。保存文件对话框类似。
打开文件对话框示例代码:
char szFilePath[1024] = {'\0'};
CString filter("文本文档(*.txt)|*.txt|All Files (*.*)|*.*||");
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,filter);
if(dlg.DoModal()==IDOK)
{
strcpy(szFilePath, dlg.GetPathName().GetBuffer(0)) ;
}
else
{
return ;
}
if (strcmp(szFilePath, "") == 0)
{
return ;
}
效果图: