下面的代码封装了MFC选择目录的函数,适用于高低版本的Windows系统和高低版本的Visual Studio.
少啰嗦,先看东西。
XP系统或低版本VS编译出来的结果:
XP以上的系统并且高版本VS编译出来的结果:
同时支持一次选择多个文件夹。代码的使用也超简单,调用一个函数即可。
Talk is cheap. Show me the code.
//SelectPathDlg.h
#pragma once
#include <vector>
/*
* hwndOwner: 父窗口句柄,multSel: 是否运行选择多个目录
* 使用很简单:
* std::vector<CString> dirs = select_path_dlg(GetSafeHwnd(), false);
*/
std::vector<CString> select_path_dlg(HWND hwndOwner = NULL, bool multSel = false);
bool os_higher_than_xp();
CString select_path_dlg_xp(HWND hwndOwner);
//SelectPathDlg.cpp
#include "stdafx.h"
#include "SelectPathDlg.h"
#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
// Disable warning about strdup being deprecated.
#pragma warning(disable : 4996)
#endif
bool os_higher_than_xp()
{
bool ans = false;
OSVERSIONINFO osInfo;
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osInfo);
if (osInfo.dwPlatformId == 2) {
if (osInfo.dwMajorVersion >= 6)
ans = true;
}
return ans;
}
CString select_path_dlg_xp(HWND hwndOwner)
{
CString ans;
BROWSEINFO bi = { 0 };
memset(&bi, 0, sizeof(bi));
bi.hwndOwner = hwndOwner;
bi.lpszTitle = _T("选择一个文件夹");
bi.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
if (!pidl) {
return ans;
}
TCHAR path[MAX_PATH];
SHGetPathFromIDList(pidl, path);
ans = path;
IMalloc * imalloc = 0;
if (SUCCEEDED(SHGetMalloc(&imalloc))) {
imalloc->Free(pidl);
imalloc->Release();
}
return ans;
}
std::vector<CString> select_path_dlg(HWND hwndOwner /*= NULL*/, bool multSel /*= false*/)
{
std::vector<CString> ans;
if (os_higher_than_xp()) {
#if _MSC_VER >= 1600
CWnd * pWnd = hwndOwner != NULL ? CWnd::FromHandle(hwndOwner) : 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(hwndOwner));
#endif
} else {
ans.push_back(select_path_dlg_xp(hwndOwner));
}
return ans;
}
欢迎拍砖。