VC编程中经常需要弹出选择文件夹对话框供用户选择目标文件夹
-----------------------------------------------------------------------------------------------------------------------------------
一种是用MFC提供的CFileDiglog类
(vs2010环境)
#include "stdafx.h"
#include <Windows.h>
#include "BaseFunc.h"
using namespace std;
using namespace BaseFunc;
unsigned BaseFunc::selFile( string &strFile,const string &strExt,bool bOpen )
{
string strDir = "D:\\Downloads";//这里通过strFile解析目录,CFileDialog会自动记住
string filename = "hi.txt"; //通过strFile解析文件名
string filter = strExt + "文件 (*." + strExt + ")|*." + strExt + "||";
string ext = "." + strExt;
CFileDialog dlg(bOpen,ext.c_str(),filename.c_str(),OFN_READONLY|OFN_OVERWRITEPROMPT,filter.c_str(),NULL);
dlg.GetOFN().lpstrInitialDir = strFile.c_str();// 默认目录
if (dlg.DoModal())
{
strFile = dlg.GetPathName();
return IDOK;
}
return IDCANCEL;
}
-----------------------------------------------------------------------------------------------------------------------------------
另一种是通过SHBrowseForFolder函数,可以通过回调函数设置标题及路径
基本实现的源码如下
- void CTestDlg::OnBtnTest()
- {
- // TODO: Add your control notification handler code here
- TCHAR pszPath[MAX_PATH];
- BROWSEINFO bi;
- bi.hwndOwner = this->GetSafeHwnd();
- bi.pidlRoot = NULL;
- bi.pszDisplayName = NULL;
- bi.lpszTitle = TEXT("请选择文件夹");
- bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
- bi.lpfn = NULL;
- bi.lParam = 0;
- bi.iImage = 0;
- LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
- if (pidl == NULL)
- {
- return;
- }
- if (SHGetPathFromIDList(pidl, pszPath))
- {
- AfxMessageBox(pszPath);
- }
- }
这一般均能够满足要求,但有时还是需要在此基础上增强一些功能。
比如在弹出选择文件夹对话框时选中默认的文件夹,或在STATUSTEXT区域显示一些信息等等。这需要在BrowseCallbackProc回调函数中实现。具体实现的源码如下:
(具体BrowseCallBackFun回调函数的用法请参照MSDN)
- //选择文件夹对话框回调函数
- int CALLBACK BrowseCallBackFun(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
- {
- switch(uMsg)
- {
- case BFFM_INITIALIZED: //选择文件夹对话框初始化
- //设置默认路径为lpData即'D:\'
- ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
- //在STATUSTEXT区域显示当前路径
- ::SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, lpData);
- //设置选择文件夹对话框的标题
- ::SetWindowText(hwnd, TEXT("请先设置个工作目录"));
- break;
- case BFFM_SELCHANGED: //选择文件夹变更时
- {
- TCHAR pszPath[MAX_PATH];
- //获取当前选择路径
- SHGetPathFromIDList((LPCITEMIDLIST)lParam, pszPath);
- //在STATUSTEXT区域显示当前路径
- ::SendMessage(hwnd, BFFM_SETSTATUSTEXT, TRUE, (LPARAM)pszPath);
- }
- break;
- }
- return 0;
- }
- void CTestDlg::OnBtnTest()
- {
- // TODO: Add your control notification handler code here
- TCHAR pszPath[MAX_PATH];
- BROWSEINFO bi;
- bi.hwndOwner = this->GetSafeHwnd();
- bi.pidlRoot = NULL;
- bi.pszDisplayName = NULL;
- bi.lpszTitle = TEXT("请选择文件夹");
- bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
- bi.lpfn = BrowseCallBackFun; //回调函数
- bi.lParam = (LPARAM)TEXT("D:\\"); //传给回调函数的参数,设置默认路径
- bi.iImage = 0;
- LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
- if (pidl == NULL)
- {
- return;
- }
- if (SHGetPathFromIDList(pidl, pszPath))
- {
- AfxMessageBox(pszPath);
- }
- }
附图片:
当然也可以设置选择文件对话框的其他样式,比如使其具有新增文件夹的功能,可如下实现
bi.ulFlags = BIF_USENEWUI
附图:(改图来源于www.VCKBASE.com,本人电脑上安装的是VC6,不支持BIF_USENEWUI,请在VC2003+上尝试)
具体请参照MSDN
定义
结构
成员变量
------------------------------------------------------
若要建立可以新建文件夹的对话框:
在CPP开头加上:
#define BIF_NEWDIALOGSTYLE 0x40
#define BIF_USENEWUI (BIF_NEWDIALOGSTYLE|BIF_EDITBOX)
在风格中多加上 BIF_USENEWUI
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT |BIF_USENEWUI;