David Hedberg : comdlg32: Implement opening files with the item dialog.

Alexandre Julliard julliard at winehq.org
Fri Apr 1 09:41:06 CDT 2011


Module: wine
Branch: master
Commit: f2231f8419a80c3a9653252028658ea6c9040a91
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f2231f8419a80c3a9653252028658ea6c9040a91

Author: David Hedberg <david.hedberg at gmail.com>
Date:   Fri Apr  1 05:52:32 2011 +0200

comdlg32: Implement opening files with the item dialog.

---

 dlls/comdlg32/cdlg.h    |    1 +
 dlls/comdlg32/cdlg32.c  |    3 +-
 dlls/comdlg32/itemdlg.c |  119 ++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 120 insertions(+), 3 deletions(-)

diff --git a/dlls/comdlg32/cdlg.h b/dlls/comdlg32/cdlg.h
index 00ec357..e1b341c 100644
--- a/dlls/comdlg32/cdlg.h
+++ b/dlls/comdlg32/cdlg.h
@@ -192,6 +192,7 @@ extern UINT (WINAPI *COMDLG32_PIDL_ILGetSize)(LPCITEMIDLIST);
 extern LPVOID (WINAPI *COMDLG32_SHAlloc)(DWORD);
 extern DWORD (WINAPI *COMDLG32_SHFree)(LPVOID);
 extern BOOL (WINAPI *COMDLG32_SHGetFolderPathW)(HWND,int,HANDLE,DWORD,LPWSTR);
+extern LPITEMIDLIST (WINAPI *COMDLG32_SHSimpleIDListFromPathAW)(LPCVOID);
 
 #define ONOPEN_BROWSE 1
 #define ONOPEN_OPEN   2
diff --git a/dlls/comdlg32/cdlg32.c b/dlls/comdlg32/cdlg32.c
index 4f6b98a..ad44bbb 100644
--- a/dlls/comdlg32/cdlg32.c
+++ b/dlls/comdlg32/cdlg32.c
@@ -57,6 +57,7 @@ UINT (WINAPI *COMDLG32_PIDL_ILGetSize)(LPCITEMIDLIST);
 LPVOID (WINAPI *COMDLG32_SHAlloc)(DWORD);
 DWORD (WINAPI *COMDLG32_SHFree)(LPVOID);
 BOOL (WINAPI *COMDLG32_SHGetFolderPathW)(HWND,int,HANDLE,DWORD,LPWSTR);
+LPITEMIDLIST (WINAPI *COMDLG32_SHSimpleIDListFromPathAW)(LPCVOID);
 
 /***********************************************************************
  *	DllMain  (COMDLG32.init)
@@ -96,7 +97,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
 		GPA(COMDLG32_PIDL_ILGetSize, SHELL32_hInstance, (LPCSTR)152L);
 
 		/* SHELL */
-
+		GPA(COMDLG32_SHSimpleIDListFromPathAW, SHELL32_hInstance, (LPCSTR)162);
 		GPA(COMDLG32_SHAlloc, SHELL32_hInstance, (LPCSTR)196L);
 		GPA(COMDLG32_SHFree, SHELL32_hInstance, (LPCSTR)195L);
 
diff --git a/dlls/comdlg32/itemdlg.c b/dlls/comdlg32/itemdlg.c
index caa2454..35910c3 100644
--- a/dlls/comdlg32/itemdlg.c
+++ b/dlls/comdlg32/itemdlg.c
@@ -199,6 +199,113 @@ static void fill_filename_from_selection(FileDialogImpl *This)
     return;
 }
 
+static HRESULT on_default_action(FileDialogImpl *This)
+{
+    IShellFolder *psf_parent, *psf_desktop;
+    LPITEMIDLIST *pidla;
+    LPITEMIDLIST current_folder;
+    LPWSTR fn_iter, files, tmp_files;
+    UINT file_count = 0, len, i;
+    int open_action;
+    HRESULT hr, ret = E_FAIL;
+
+    len = get_file_name(This, &tmp_files);
+    if(len)
+    {
+        UINT size_used;
+        file_count = COMDLG32_SplitFileNames(tmp_files, len, &files, &size_used);
+    }
+    if(!file_count) return E_FAIL;
+
+    hr = SHGetIDListFromObject((IUnknown*)This->psi_folder, &current_folder);
+    if(FAILED(hr))
+    {
+        ERR("Failed to get pidl for current directory.\n");
+        return hr;
+    }
+
+    TRACE("Acting on %d file(s).\n", file_count);
+
+    pidla = HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST) * file_count);
+    open_action = ONOPEN_OPEN;
+    fn_iter = files;
+
+    for(i = 0; i < file_count && open_action == ONOPEN_OPEN; i++)
+    {
+        WCHAR canon_filename[MAX_PATH];
+        psf_parent = NULL;
+
+        COMDLG32_GetCanonicalPath(current_folder, fn_iter, canon_filename);
+
+        if( (This->options & FOS_NOVALIDATE) &&
+            !(This->options & FOS_FILEMUSTEXIST) )
+            open_action = ONOPEN_OPEN;
+        else
+            open_action = ONOPEN_BROWSE;
+
+        open_action = FILEDLG95_ValidatePathAction(canon_filename, &psf_parent, This->dlg_hwnd,
+                                                   This->options, (This->dlg_type == ITEMDLG_TYPE_SAVE),
+                                                   open_action);
+
+        pidla[i] = COMDLG32_SHSimpleIDListFromPathAW(canon_filename);
+
+        if(psf_parent && !(open_action == ONOPEN_BROWSE))
+            IShellItem_Release(psf_parent);
+
+        fn_iter += (WCHAR)lstrlenW(fn_iter) + 1;
+    }
+
+    HeapFree(GetProcessHeap(), 0, files);
+    ILFree(current_folder);
+
+    if((This->options & FOS_PICKFOLDERS) && open_action == ONOPEN_BROWSE)
+        open_action = ONOPEN_OPEN; /* FIXME: Multiple folders? */
+
+    switch(open_action)
+    {
+    case ONOPEN_SEARCH:
+        FIXME("Filtering not implemented.\n");
+        break;
+
+    case ONOPEN_BROWSE:
+        hr = IExplorerBrowser_BrowseToObject(This->peb, (IUnknown*)psf_parent, SBSP_DEFBROWSER);
+        if(FAILED(hr))
+            ERR("Failed to browse to directory: %08x\n", hr);
+
+        IShellItem_Release(psf_parent);
+        break;
+
+    case ONOPEN_OPEN:
+        hr = SHGetDesktopFolder(&psf_desktop);
+        if(SUCCEEDED(hr))
+        {
+            if(This->psia_results)
+                IShellItemArray_Release(This->psia_results);
+
+            hr = SHCreateShellItemArray(NULL, psf_desktop, file_count, (PCUITEMID_CHILD_ARRAY)pidla,
+                                        &This->psia_results);
+
+            if(SUCCEEDED(hr))
+                ret = S_OK;
+
+            IShellFolder_Release(psf_desktop);
+        }
+        break;
+
+    default:
+        ERR("Failed.\n");
+        break;
+    }
+
+    /* Clean up */
+    for(i = 0; i < file_count; i++)
+        ILFree(pidla[i]);
+    HeapFree(GetProcessHeap(), 0, pidla);
+
+    /* Success closes the dialog */
+    return ret;
+}
+
 /**************************************************************************
  * Window related functions.
  */
@@ -527,7 +634,8 @@ static LRESULT on_idok(FileDialogImpl *This)
 {
     TRACE("%p\n", This);
 
-    EndDialog(This->dlg_hwnd, S_OK);
+    if(SUCCEEDED(on_default_action(This)))
+        EndDialog(This->dlg_hwnd, S_OK);
 
     return FALSE;
 }
@@ -1766,7 +1874,14 @@ static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *ifac
                                                           IShellView *shv)
 {
     FileDialogImpl *This = impl_from_ICommDlgBrowser3(iface);
-    FIXME("Stub: %p (%p)\n", This, shv);
+    HRESULT hr;
+    TRACE("%p (%p)\n", This, shv);
+
+    hr = on_default_action(This);
+
+    if(SUCCEEDED(hr))
+        EndDialog(This->dlg_hwnd, S_OK);
+
     return S_OK;
 }
 




More information about the wine-cvs mailing list