[PATCH 7/7] comdlg32: Support browsing for folders.

David Hedberg david.hedberg at gmail.com
Wed Jul 30 13:43:26 CDT 2014


Fixes bugs #31008, #32393.
---
 dlls/comdlg32/cdlg.h           |  1 +
 dlls/comdlg32/comdlg32.rc      |  2 ++
 dlls/comdlg32/filedlgbrowser.h |  1 +
 dlls/comdlg32/itemdlg.c        | 46 ++++++++++++++++++++++++++++++++++++++----
 4 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/dlls/comdlg32/cdlg.h b/dlls/comdlg32/cdlg.h
index 954a0b1..c437183 100644
--- a/dlls/comdlg32/cdlg.h
+++ b/dlls/comdlg32/cdlg.h
@@ -176,6 +176,7 @@ typedef struct {
 #define IDS_SAVE         1203
 #define IDS_SAVE_AS      1204
 #define IDS_OPEN_FILE    1205
+#define IDS_SELECT_FOLDER 1206
 
 #define IDS_FAKEDOCTEXT  1300
 
diff --git a/dlls/comdlg32/comdlg32.rc b/dlls/comdlg32/comdlg32.rc
index 32eded5..3118610 100644
--- a/dlls/comdlg32/comdlg32.rc
+++ b/dlls/comdlg32/comdlg32.rc
@@ -36,6 +36,7 @@ STRINGTABLE
     IDS_INVALID_FILENAME    "A filename cannot contain any of the following characters:\n                          / : < > |"
     IDS_PATHNOTEXISTING     "Path does not exist"
     IDS_FILENOTEXISTING     "File does not exist"
+    IDS_INVALID_FOLDERNAME  "The selection contains a non-folder object"
 }
 
 STRINGTABLE
@@ -142,6 +143,7 @@ STRINGTABLE
     IDS_SAVE        "Save"
     IDS_SAVE_AS     "Save As"
     IDS_OPEN_FILE   "Open File"
+    IDS_SELECT_FOLDER "Select Folder"
 }
 
 /*
diff --git a/dlls/comdlg32/filedlgbrowser.h b/dlls/comdlg32/filedlgbrowser.h
index e01c5a0..60f0e7e 100644
--- a/dlls/comdlg32/filedlgbrowser.h
+++ b/dlls/comdlg32/filedlgbrowser.h
@@ -105,6 +105,7 @@ typedef struct
 #define IDS_INVALID_FILENAME		121
 #define IDS_PATHNOTEXISTING		122
 #define IDS_FILENOTEXISTING		123
+#define IDS_INVALID_FOLDERNAME		124
 
 /* File Dialog Tooltips string IDs */
 
diff --git a/dlls/comdlg32/itemdlg.c b/dlls/comdlg32/itemdlg.c
index 21cdf89..17d2c01 100644
--- a/dlls/comdlg32/itemdlg.c
+++ b/dlls/comdlg32/itemdlg.c
@@ -346,8 +346,10 @@ static void fill_filename_from_selection(FileDialogImpl *This)
             UINT attr;
 
             hr = IShellItem_GetAttributes(psi, SFGAO_FOLDER, &attr);
-            if(SUCCEEDED(hr) && (attr & SFGAO_FOLDER))
-                continue; /* FIXME: FOS_PICKFOLDERS */
+            if(SUCCEEDED(hr) &&
+               (( (This->options & FOS_PICKFOLDERS) && !(attr & SFGAO_FOLDER)) ||
+                (!(This->options & FOS_PICKFOLDERS) &&  (attr & SFGAO_FOLDER))))
+                continue;
 
             hr = IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &names[valid_count]);
             if(SUCCEEDED(hr))
@@ -540,14 +542,37 @@ static HRESULT on_default_action(FileDialogImpl *This)
         if(SUCCEEDED(hr))
         {
             if(This->psia_results)
+            {
                 IShellItemArray_Release(This->psia_results);
+                This->psia_results = NULL;
+            }
 
             hr = SHCreateShellItemArray(NULL, psf_desktop, file_count, (PCUITEMID_CHILD_ARRAY)pidla,
                                         &This->psia_results);
 
             IShellFolder_Release(psf_desktop);
 
-            if(SUCCEEDED(hr) && events_OnFileOk(This) == S_OK)
+            if(FAILED(hr))
+                break;
+
+            if(This->options & FOS_PICKFOLDERS)
+            {
+                SFGAOF attributes;
+                hr = IShellItemArray_GetAttributes(This->psia_results, SIATTRIBFLAGS_AND, SFGAO_FOLDER, &attributes);
+                if(hr != S_OK)
+                {
+                    WCHAR buf[64];
+                    LoadStringW(COMDLG32_hInstance, IDS_INVALID_FOLDERNAME, buf, sizeof(buf)/sizeof(WCHAR));
+
+                    MessageBoxW(This->dlg_hwnd, buf, This->custom_title, MB_OK | MB_ICONEXCLAMATION);
+
+                    IShellItemArray_Release(This->psia_results);
+                    This->psia_results = NULL;
+                    break;
+                }
+            }
+
+            if(events_OnFileOk(This) == S_OK)
                 ret = S_OK;
         }
         break;
@@ -1815,6 +1840,13 @@ static HRESULT WINAPI IFileDialog2_fnSetOptions(IFileDialog2 *iface, FILEOPENDIA
     FileDialogImpl *This = impl_from_IFileDialog2(iface);
     TRACE("%p (0x%x)\n", This, fos);
 
+    if( !(This->options & FOS_PICKFOLDERS) && (fos & FOS_PICKFOLDERS) )
+    {
+        WCHAR buf[30];
+        LoadStringW(COMDLG32_hInstance, IDS_SELECT_FOLDER, buf, sizeof(buf)/sizeof(WCHAR));
+        IFileDialog2_SetTitle(iface, buf);
+    }
+
     This->options = fos;
 
     return S_OK;
@@ -2846,7 +2878,7 @@ static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
     ULONG attr;
     TRACE("%p (%p, %p)\n", This, shv, pidl);
 
-    if(!This->filterspec_count)
+    if(!This->filterspec_count && !(This->options & FOS_PICKFOLDERS))
         return S_OK;
 
     hr = SHGetIDListFromObject((IUnknown*)shv, &parent_pidl);
@@ -2870,6 +2902,12 @@ static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
         return S_OK;
     }
 
+    if((This->options & FOS_PICKFOLDERS) && !(attr & (SFGAO_FOLDER | SFGAO_LINK)))
+    {
+        IShellItem_Release(psi);
+        return S_FALSE;
+    }
+
     hr = S_OK;
     if(SUCCEEDED(IShellItem_GetDisplayName(psi, SIGDN_PARENTRELATIVEPARSING, &filename)))
     {
-- 
2.0.1




More information about the wine-patches mailing list