下面的代碼封裝了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;
}
歡迎拍磚。