MFC选择目录

上一篇《MFC选择目录》写的有点太简单,而且界面也不好。今天重写一遍。少啰嗦,先看东西。

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;
}

欢迎拍砖。

posted @ 2018-08-24 17:01  探索者软件  阅读(690)  评论(0编辑  收藏  举报