低版本MFC没有提供选择文件夹的类,到了高版本并且是Vista系统以上才有了选择文件夹对话框的专用的类:CFolderPickerDialog
。下面的程序对这个问题做了简单的封装,可以直接调用得到选择的文件夹或文件夹列表。先看效果,再看代码。
低版本的选择文件夹对话框:
高版本的选择文件夹对话框:
代码:
//SelectPath.h
#pragma once
#include <vector>
std::vector<CString> select_path_dlg(HWND hwnOwner=0, bool multSel=false);
bool os_higher_than_xp();
CString select_path_dlg_xp(HWND hwnOwner);
//SelectPath.cpp
#include "stdafx.h"
#include "SelectPath.h"
bool os_higher_than_xp()
{
bool ans = false;
OSVERSIONINFO osinfo;
osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osinfo);
if(osinfo.dwPlatformId == 2 && osinfo.dwMajorVersion >= 6)
ans = true;
return true;
}
CString select_path_dlg_xp(HWND hwnOwner)
{
CString ans;
BROWSEINFO bi = {0};
memset(&bi, 0, sizeof(bi));
bi.hwndOwner = hwnOwner;
bi.lpszTitle = _T("选择文件夹");
bi.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX ;
LPITEMIDLIST pl = SHBrowseForFolder(&bi);
if (!pl)
return ans;
TCHAR path[MAX_PATH];
SHGetPathFromIDList(pl, path);
ans = path;
IMalloc * imalloc = 0;
if (SUCCEEDED(SHGetMalloc(&imalloc))) {
imalloc->Free(pl);
imalloc->Release();
}
return ans;
}
std::vector<CString>select_path_dlg(HWND hwnOwner/*=0*/, bool multSel/*=false*/)
{
std::vector<CString> ans;
if (os_higher_than_xp()) {
#if _MSC_VER >= 1600
CWnd * pWnd = hwnOwner? CWnd::FromHandle(hwnOwner) : NULL;
if (multSel) {
CFolderPickerDialog dlg(NULL, OFN_FILEMUSTEXIST|OFN_ALLOWMULTISELECT|OFN_ENABLESIZING, pWnd);
if (dlg.DoModal() == IDOK) {
POSITION pos = dlg.GetStartPosition();
while (pos) {
ans.push_back(dlg.GetNextPathName(pos));
}
}
} else {
CFolderPickerDialog dlg(NULL, OFN_FILEMUSTEXIST|OFN_ENABLESIZING, pWnd);
if (dlg.DoModal() == IDOK) {
ans.push_back(dlg.GetPathName());
}
}
#else
ans.push_back(select_path_dlg_xp(hwnOwner));
#endif
} else {
ans.push_back(select_path_dlg_xp(hwnOwner));
}
return ans;
}
测试程序:
//TestDlg.cpp
std::vector<CString> pl = select_path_dlg(GetSafeHwnd(), true);
简单的解释:
1. 程序首先判断是否xp以上系统,如果是xp系统只能用老式的对话框。如果是vista及以上系统则可以有新式对话框,这一点还得看是用什么VS编译本程序,VS2010以下是编译不出新式对话框的。
2. VS2010及以上的VS可以用 CFolderPickerDialog
创建新式的选择文件夹的对话框,并且支持多选。