/*
以下是编译命令:
g++ .\test.cpp -std=c++11 -DUNICODE
*/
#include <windows.h>
#include <ShlObj.h>
#include <iostream>
#include <string>
static wchar_t STATIC_BFFM_SETSELECTION[MAX_PATH] = L"C:\\Program Files (x86)\\";
static int CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM )
{
if(uMsg == BFFM_SELCHANGED){
wchar_t path[MAX_PATH];
const bool ok = SHGetPathFromIDList(reinterpret_cast<PIDLIST_ABSOLUTE>(lParam), path) && path[0];
SendMessage(hwnd, BFFM_ENABLEOK, ok ? 1 : 0, 1);
}else if(uMsg == BFFM_INITIALIZED){
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(STATIC_BFFM_SETSELECTION));
}
return 0;
}
static std::string GetExistingDirectory(std::string selectedFile = std::string())
{
if(!selectedFile.empty()){
const char* pCStrKey = selectedFile.c_str();
int cSize = static_cast<int>(selectedFile.size()) + 1, pSize = MultiByteToWideChar(CP_OEMCP, 0, pCStrKey, cSize, nullptr, 0);
MultiByteToWideChar(CP_OEMCP, 0, pCStrKey, cSize, STATIC_BFFM_SETSELECTION, pSize);
}
BROWSEINFO bi;
wchar_t initPath[MAX_PATH];
initPath[0] = 0;
bi.hwndOwner = nullptr;
bi.pidlRoot = nullptr;
bi.lpszTitle = nullptr;
bi.pszDisplayName = initPath;
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
bi.lpfn = xpFileDialogGetExistingDirCallbackProc;
bi.lParam = LPARAM(0);
if (PIDLIST_ABSOLUTE pItemIDList = SHBrowseForFolder(&bi)) {
wchar_t path[MAX_PATH];
path[0] = 0;
if (SHGetPathFromIDList(pItemIDList, path) && path[0]){
int pSize = WideCharToMultiByte(CP_OEMCP, 0, path, static_cast<int>(wcslen(path)), nullptr, 0, nullptr, nullptr);
selectedFile.resize(static_cast<unsigned long long>(pSize));
WideCharToMultiByte(CP_OEMCP, 0, path, static_cast<int>(wcslen(path)), const_cast<char*>(selectedFile.c_str()), pSize, nullptr, nullptr);
}
IMalloc *pMalloc;
if (SHGetMalloc(&pMalloc) == NOERROR) {
pMalloc->Free(pItemIDList);
pMalloc->Release();
}
}
if(!selectedFile.empty()) { selectedFile.push_back('\\'); }
return selectedFile;
}
int main()
{
std::string path = GetExistingDirectory();
std::cout << GetExistingDirectory(path) << std::endl;
return 0;
}
WINDOWS系统 纯C++代码 打开文件目录选择框获取目录
最新推荐文章于 2023-08-09 10:45:30 发布