Skip to content
This repository has been archived by the owner on Sep 2, 2021. It is now read-only.

Commit

Permalink
Merge pull request #247 from adobe/bchin/open-folder-using-IFileDialog
Browse files Browse the repository at this point in the history
Update "File > Open Folder..." dialog with Windows' Open File dialog in pick folders mode.
  • Loading branch information
redmunds committed May 26, 2013
2 parents f791fb9 + 0716515 commit 40ce20c
Showing 1 changed file with 61 additions and 23 deletions.
84 changes: 61 additions & 23 deletions appshell/appshell_extensions_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include <ShellAPI.h>
#include <ShlObj.h>
#include <Shlwapi.h>
#include <Shobjidl.h>
#include <atlbase.h>
#include <stdio.h>
#include <sys/stat.h>

Expand Down Expand Up @@ -429,33 +431,69 @@ int32 ShowOpenDialog(bool allowMultipleSelection,
}
*/

// SHBrowseForFolder can handle Windows path only, not Unix path.
// Windows common file dialogs can handle Windows path only, not Unix path.
// ofn.lpstrInitialDir also needs Windows path on XP and not Unix path.
ConvertToNativePath(initialDirectory);

if (chooseDirectory) {
BROWSEINFO bi = {0};
bi.hwndOwner = GetActiveWindow();
bi.lpszTitle = title.c_str();
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
bi.lpfn = SetInitialPathCallback;
bi.lParam = (LPARAM)initialDirectory.c_str();

LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
if (pidl != 0) {
if (SHGetPathFromIDList(pidl, szFile)) {
// Add directory path to the result
ExtensionString pathName(szFile);
ConvertToUnixPath(pathName);
selectedFiles->SetString(0, pathName);
}
IMalloc* pMalloc = NULL;
SHGetMalloc(&pMalloc);
if (pMalloc) {
pMalloc->Free(pidl);
pMalloc->Release();
}
}
// check current OS version
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osvi) && (osvi.dwMajorVersion >= 6)) {
// for Vista or later, use the MSDN-preferred implementation of the Open File dialog in pick folders mode
IFileDialog *pfd;
if (SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd)))) {
// configure the dialog to Select Folders only
DWORD dwOptions;
if (SUCCEEDED(pfd->GetOptions(&dwOptions))) {
pfd->SetOptions(dwOptions | FOS_PICKFOLDERS | FOS_DONTADDTORECENT);
CComPtr<IShellItem> shellItem;
if (SUCCEEDED(SHCreateItemFromParsingName(initialDirectory.c_str(), 0, IID_IShellItem, reinterpret_cast<void**>(&shellItem))))
pfd->SetFolder(shellItem);
if (SUCCEEDED(pfd->Show(NULL))) {
IShellItem *psi;
if (SUCCEEDED(pfd->GetResult(&psi))) {
LPWSTR lpwszName = NULL;
if(SUCCEEDED(psi->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, (LPWSTR*)&lpwszName))) {
// Add directory path to the result
std::wstring wstrName(lpwszName);
ExtensionString pathName(wstrName);
ConvertToUnixPath(pathName);
selectedFiles->SetString(0, pathName);
::CoTaskMemFree(lpwszName);
}
psi->Release();
}
}
}
pfd->Release();
}
} else {
// for XP, use the old-styled SHBrowseForFolder() implementation
BROWSEINFO bi = {0};
bi.hwndOwner = GetActiveWindow();
bi.lpszTitle = title.c_str();
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
bi.lpfn = SetInitialPathCallback;
bi.lParam = (LPARAM)initialDirectory.c_str();

LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
if (pidl != 0) {
if (SHGetPathFromIDList(pidl, szFile)) {
// Add directory path to the result
ExtensionString pathName(szFile);
ConvertToUnixPath(pathName);
selectedFiles->SetString(0, pathName);
}
IMalloc* pMalloc = NULL;
SHGetMalloc(&pMalloc);
if (pMalloc) {
pMalloc->Free(pidl);
pMalloc->Release();
}
}
}
} else {
OPENFILENAME ofn;

Expand Down

0 comments on commit 40ce20c

Please sign in to comment.