MFC選擇目錄

下面的代碼封裝了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;
}

歡迎拍磚。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章