Permalink
Browse files

Merge pull request #247 from adobe/bchin/open-folder-using-IFileDialog

Update "File > Open Folder..." dialog with Windows' Open File dialog in pick folders mode.
  • Loading branch information...
2 parents f791fb9 + 0716515 commit 40ce20c43a116b6f6c2515d71460485aa52e368f @redmunds redmunds committed May 26, 2013
Showing with 61 additions and 23 deletions.
  1. +61 −23 appshell/appshell_extensions_win.cpp
@@ -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>
@@ -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;

0 comments on commit 40ce20c

Please sign in to comment.