Vincent Povirk : comdlg32: Implement overwrite check in item dialog.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Aug 17 09:01:11 CDT 2015


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

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Thu Aug 13 15:57:02 2015 -0500

comdlg32: Implement overwrite check in item dialog.

---

 dlls/comdlg32/itemdlg.c       | 83 +++++++++++++++++++++++++++++++++++++++++++
 dlls/comdlg32/tests/itemdlg.c |  2 +-
 2 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/dlls/comdlg32/itemdlg.c b/dlls/comdlg32/itemdlg.c
index d1a52cd..3150485 100644
--- a/dlls/comdlg32/itemdlg.c
+++ b/dlls/comdlg32/itemdlg.c
@@ -213,6 +213,47 @@ static void events_OnTypeChange(FileDialogImpl *This)
     }
 }
 
+static HRESULT events_OnOverwrite(FileDialogImpl *This, IShellItem *shellitem)
+{
+    events_client *cursor;
+    HRESULT hr = S_OK;
+    FDE_OVERWRITE_RESPONSE response = FDEOR_DEFAULT;
+    TRACE("%p %p\n", This, shellitem);
+
+    LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
+    {
+        TRACE("Notifying %p\n", cursor);
+        hr = IFileDialogEvents_OnOverwrite(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface, shellitem, &response);
+        TRACE("<-- hr=%x response=%u\n", hr, response);
+        if(FAILED(hr) && hr != E_NOTIMPL)
+            break;
+    }
+
+    if(hr == E_NOTIMPL)
+        hr = S_OK;
+
+    if(SUCCEEDED(hr))
+    {
+        if (response == FDEOR_DEFAULT)
+        {
+            WCHAR buf[100];
+            int answer;
+
+            LoadStringW(COMDLG32_hInstance, IDS_OVERWRITEFILE, buf, 100);
+            answer = MessageBoxW(This->dlg_hwnd, buf, This->custom_title,
+                       MB_YESNO | MB_ICONEXCLAMATION);
+            if (answer == IDNO || answer == IDCANCEL)
+            {
+                hr = E_FAIL;
+            }
+        }
+        else if (response == FDEOR_REFUSE)
+            hr = E_FAIL;
+    }
+
+    return hr;
+}
+
 static inline HRESULT get_cctrl_event(IFileDialogEvents *pfde, IFileDialogControlEvents **pfdce)
 {
     return IFileDialogEvents_QueryInterface(pfde, &IID_IFileDialogControlEvents, (void**)pfdce);
@@ -423,6 +464,28 @@ static LPWSTR get_first_ext_from_spec(LPWSTR buf, LPCWSTR spec)
     return ext;
 }
 
+static BOOL shell_item_exists(IShellItem* shellitem)
+{
+    LPWSTR filename;
+    HRESULT hr;
+    BOOL result;
+
+    hr = IShellItem_GetDisplayName(shellitem, SIGDN_FILESYSPATH, &filename);
+    if (SUCCEEDED(hr))
+    {
+        /* FIXME: Implement SFGAO_VALIDATE in Wine and use it instead. */
+        result = (GetFileAttributesW(filename) != INVALID_FILE_ATTRIBUTES);
+        CoTaskMemFree(filename);
+    }
+    else
+    {
+        SFGAOF attributes;
+        result = SUCCEEDED(IShellItem_GetAttributes(shellitem, SFGAO_VALIDATE, &attributes));
+    }
+
+    return result;
+}
+
 static HRESULT on_default_action(FileDialogImpl *This)
 {
     IShellFolder *psf_parent, *psf_desktop;
@@ -589,6 +652,26 @@ static HRESULT on_default_action(FileDialogImpl *This)
                 }
             }
 
+            if((This->options & FOS_OVERWRITEPROMPT) && This->dlg_type == ITEMDLG_TYPE_SAVE)
+            {
+                IShellItem *shellitem;
+
+                for (i=0; SUCCEEDED(hr) && i<file_count; i++)
+                {
+                    hr = IShellItemArray_GetItemAt(This->psia_results, i, &shellitem);
+                    if (SUCCEEDED(hr))
+                    {
+                        if (shell_item_exists(shellitem))
+                            hr = events_OnOverwrite(This, shellitem);
+
+                        IShellItem_Release(shellitem);
+                    }
+                }
+
+                if (FAILED(hr))
+                    break;
+            }
+
             if(events_OnFileOk(This) == S_OK)
                 ret = S_OK;
         }
diff --git a/dlls/comdlg32/tests/itemdlg.c b/dlls/comdlg32/tests/itemdlg.c
index b7238bb..6ea3481 100644
--- a/dlls/comdlg32/tests/itemdlg.c
+++ b/dlls/comdlg32/tests/itemdlg.c
@@ -2370,7 +2370,7 @@ static void test_overwrite(void)
     hr = IFileDialog_Show(fd, NULL);
     ok(hr == S_OK, "Show failed: Got 0x%08x\n", hr);
 
-    todo_wine ok(pfdeimpl->OnOverwrite == 1, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
+    ok(pfdeimpl->OnOverwrite == 1, "got %u overwrite events\n", pfdeimpl->OnOverwrite);
     ok(pfdeimpl->OnFileOk == 1, "got %u ok events\n", pfdeimpl->OnFileOk);
 
     hr = IFileDialog_GetFileName(fd, &filename);




More information about the wine-cvs mailing list