[PATCH 3/8] comdlg32: Support some events in the item dialog.
David Hedberg
david.hedberg at gmail.com
Tue May 24 14:09:48 CDT 2011
TODO: Add some real tests (with a thread that does _Close if nothing happens?)
---
dlls/comdlg32/itemdlg.c | 94 ++++++++++++++++++++++++++++++++++++++++-
dlls/comdlg32/tests/itemdlg.c | 49 ++++++++++++++++++----
2 files changed, 134 insertions(+), 9 deletions(-)
diff --git a/dlls/comdlg32/itemdlg.c b/dlls/comdlg32/itemdlg.c
index 69d9661..dc447c2 100644
--- a/dlls/comdlg32/itemdlg.c
+++ b/dlls/comdlg32/itemdlg.c
@@ -93,6 +93,73 @@ typedef struct FileDialogImpl {
} FileDialogImpl;
/**************************************************************************
+ * Event wrappers.
+ */
+static HRESULT events_OnFileOk(FileDialogImpl *This)
+{
+ events_client *cursor;
+ HRESULT hr = S_OK;
+ TRACE("%p\n", This);
+
+ LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
+ {
+ TRACE("Notifying %p\n", cursor);
+ hr = IFileDialogEvents_OnFileOk(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface);
+ if(FAILED(hr) && hr != E_NOTIMPL)
+ break;
+ }
+
+ if(hr == E_NOTIMPL)
+ hr = S_OK;
+
+ return hr;
+}
+
+static HRESULT events_OnFolderChanging(FileDialogImpl *This, IShellItem *folder)
+{
+ events_client *cursor;
+ HRESULT hr = S_OK;
+ TRACE("%p (%p)\n", This, folder);
+
+ LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
+ {
+ TRACE("Notifying %p\n", cursor);
+ hr = IFileDialogEvents_OnFolderChanging(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface, folder);
+ if(FAILED(hr) && hr != E_NOTIMPL)
+ break;
+ }
+
+ if(hr == E_NOTIMPL)
+ hr = S_OK;
+
+ return hr;
+}
+
+static void events_OnFolderChange(FileDialogImpl *This)
+{
+ events_client *cursor;
+ TRACE("%p\n", This);
+
+ LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
+ {
+ TRACE("Notifying %p\n", cursor);
+ IFileDialogEvents_OnFolderChange(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface);
+ }
+}
+
+static void events_OnSelectionChange(FileDialogImpl *This)
+{
+ events_client *cursor;
+ TRACE("%p\n", This);
+
+ LIST_FOR_EACH_ENTRY(cursor, &This->events_clients, events_client, entry)
+ {
+ TRACE("Notifying %p\n", cursor);
+ IFileDialogEvents_OnSelectionChange(cursor->pfde, (IFileDialog*)&This->IFileDialog2_iface);
+ }
+}
+
+/**************************************************************************
* Helper functions.
*/
static UINT get_file_name(FileDialogImpl *This, LPWSTR *str)
@@ -280,6 +347,9 @@ static HRESULT on_default_action(FileDialogImpl *This)
break;
case ONOPEN_OPEN:
+ if(events_OnFileOk(This) != S_OK)
+ break;
+
hr = SHGetDesktopFolder(&psf_desktop);
if(SUCCEEDED(hr))
{
@@ -288,7 +358,6 @@ static HRESULT on_default_action(FileDialogImpl *This)
hr = SHCreateShellItemArray(NULL, psf_desktop, file_count, (PCUITEMID_CHILD_ARRAY)pidla,
&This->psia_results);
-
if(SUCCEEDED(hr))
ret = S_OK;
@@ -1818,7 +1887,25 @@ static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrow
PCIDLIST_ABSOLUTE pidlFolder)
{
FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
+ IShellItem *psi;
+ HRESULT hr;
TRACE("%p (%p)\n", This, pidlFolder);
+
+ hr = SHCreateItemFromIDList(pidlFolder, &IID_IShellItem, (void**)&psi);
+ if(SUCCEEDED(hr))
+ {
+ hr = events_OnFolderChanging(This, psi);
+ IShellItem_Release(psi);
+
+ /* The ExplorerBrowser treats S_FALSE as S_OK, we don't. */
+ if(hr == S_FALSE)
+ hr = E_FAIL;
+
+ return hr;
+ }
+ else
+ ERR("Failed to convert pidl (%p) to a shellitem.\n", pidlFolder);
+
return S_OK;
}
@@ -1847,6 +1934,8 @@ static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBro
This->psi_folder = NULL;
}
+ events_OnFolderChange(This);
+
return S_OK;
}
@@ -1993,7 +2082,10 @@ static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
hr = SHCreateShellItemArrayFromDataObject(new_selection, &IID_IShellItemArray,
(void**)&This->psia_selection);
if(SUCCEEDED(hr))
+ {
fill_filename_from_selection(This);
+ events_OnSelectionChange(This);
+ }
IDataObject_Release(new_selection);
}
diff --git a/dlls/comdlg32/tests/itemdlg.c b/dlls/comdlg32/tests/itemdlg.c
index 4dafa9b..fcd0e50 100644
--- a/dlls/comdlg32/tests/itemdlg.c
+++ b/dlls/comdlg32/tests/itemdlg.c
@@ -44,6 +44,10 @@ static void init_function_pointers(void)
typedef struct {
IFileDialogEvents IFileDialogEvents_iface;
LONG ref;
+ LONG QueryInterface;
+ LONG OnFileOk, OnFolderChanging, OnFolderChange;
+ LONG OnSelectionChange, OnShareViolation, OnTypeChange;
+ LONG OnOverwrite;
} IFileDialogEventsImpl;
static inline IFileDialogEventsImpl *impl_from_IFileDialogEvents(IFileDialogEvents *iface)
@@ -77,7 +81,8 @@ static ULONG WINAPI IFileDialogEvents_fnRelease(IFileDialogEvents *iface)
static HRESULT WINAPI IFileDialogEvents_fnOnFileOk(IFileDialogEvents *iface, IFileDialog *pfd)
{
- ok(0, "Unexpectedly called.\n");
+ IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
+ This->OnFileOk++;
return S_OK;
}
@@ -85,19 +90,22 @@ static HRESULT WINAPI IFileDialogEvents_fnOnFolderChanging(IFileDialogEvents *if
IFileDialog *pfd,
IShellItem *psiFolder)
{
- ok(0, "Unexpectedly called.\n");
+ IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
+ This->OnFolderChanging++;
return S_OK;
}
static HRESULT WINAPI IFileDialogEvents_fnOnFolderChange(IFileDialogEvents *iface, IFileDialog *pfd)
{
- ok(0, "Unexpectedly called.\n");
+ IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
+ This->OnFolderChange++;
return S_OK;
}
static HRESULT WINAPI IFileDialogEvents_fnOnSelectionChange(IFileDialogEvents *iface, IFileDialog *pfd)
{
- ok(0, "Unexpectedly called.\n");
+ IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
+ This->OnSelectionChange++;
return S_OK;
}
@@ -106,13 +114,15 @@ static HRESULT WINAPI IFileDialogEvents_fnOnShareViolation(IFileDialogEvents *if
IShellItem *psi,
FDE_SHAREVIOLATION_RESPONSE *pResponse)
{
- ok(0, "Unexpectedly called.\n");
+ IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
+ This->OnShareViolation++;
return S_OK;
}
static HRESULT WINAPI IFileDialogEvents_fnOnTypeChange(IFileDialogEvents *iface, IFileDialog *pfd)
{
- ok(0, "Unexpectedly called.\n");
+ IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
+ This->OnTypeChange++;
return S_OK;
}
@@ -121,7 +131,8 @@ static HRESULT WINAPI IFileDialogEvents_fnOnOverwrite(IFileDialogEvents *iface,
IShellItem *psi,
FDE_OVERWRITE_RESPONSE *pResponse)
{
- ok(0, "Unexpectedly called.\n");
+ IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
+ This->OnOverwrite++;
return S_OK;
}
@@ -142,7 +153,7 @@ static IFileDialogEvents *IFileDialogEvents_Constructor(void)
{
IFileDialogEventsImpl *This;
- This = HeapAlloc(GetProcessHeap(), 0, sizeof(IFileDialogEventsImpl));
+ This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IFileDialogEventsImpl));
This->IFileDialogEvents_iface.lpVtbl = &vt_IFileDialogEvents;
This->ref = 1;
@@ -745,6 +756,21 @@ static void test_basics(void)
ok(!ref, "Got refcount %d, should have been released.\n", ref);
}
+void ensure_zero_events_(const char *file, int line, IFileDialogEventsImpl *impl)
+{
+ ok_(file, line)(!impl->OnFileOk, "OnFileOk: %d\n", impl->OnFileOk);
+ ok_(file, line)(!impl->OnFolderChanging, "OnFolderChanging: %d\n", impl->OnFolderChanging);
+ ok_(file, line)(!impl->OnFolderChange, "OnFolderChange: %d\n", impl->OnFolderChange);
+ ok_(file, line)(!impl->OnSelectionChange, "OnSelectionChange: %d\n", impl->OnSelectionChange);
+ ok_(file, line)(!impl->OnShareViolation, "OnShareViolation: %d\n", impl->OnShareViolation);
+ ok_(file, line)(!impl->OnTypeChange, "OnTypeChange: %d\n", impl->OnTypeChange);
+ ok_(file, line)(!impl->OnOverwrite, "OnOverwrite: %d\n", impl->OnOverwrite);
+ impl->OnFileOk = impl->OnFolderChanging = impl->OnFolderChange = 0;
+ impl->OnSelectionChange = impl->OnShareViolation = impl->OnTypeChange = 0;
+ impl->OnOverwrite = 0;
+}
+#define ensure_zero_events(impl) ensure_zero_events_(__FILE__, __LINE__, impl)
+
static void test_advise_helper(IFileDialog *pfd)
{
IFileDialogEventsImpl *pfdeimpl;
@@ -763,6 +789,7 @@ static void test_advise_helper(IFileDialog *pfd)
hr = IFileDialog_Advise(pfd, NULL, &cookie[0]);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
+ ensure_zero_events(pfdeimpl);
hr = IFileDialog_Unadvise(pfd, 0);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
@@ -772,33 +799,39 @@ static void test_advise_helper(IFileDialog *pfd)
ok(cookie[i] == i+1, "Got cookie: %d\n", cookie[i]);
}
ok(pfdeimpl->ref == 10+1, "got ref %d\n", pfdeimpl->ref);
+ ensure_zero_events(pfdeimpl);
for(i = 3; i < 7; i++) {
hr = IFileDialog_Unadvise(pfd, cookie[i]);
ok(hr == S_OK, "got 0x%08x\n", hr);
}
ok(pfdeimpl->ref == 6+1, "got ref %d\n", pfdeimpl->ref);
+ ensure_zero_events(pfdeimpl);
for(i = 0; i < 3; i++) {
hr = IFileDialog_Unadvise(pfd, cookie[i]);
ok(hr == S_OK, "got 0x%08x\n", hr);
}
ok(pfdeimpl->ref == 3+1, "got ref %d\n", pfdeimpl->ref);
+ ensure_zero_events(pfdeimpl);
for(i = 7; i < 10; i++) {
hr = IFileDialog_Unadvise(pfd, cookie[i]);
ok(hr == S_OK, "got 0x%08x\n", hr);
}
ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
+ ensure_zero_events(pfdeimpl);
hr = IFileDialog_Unadvise(pfd, cookie[9]+1);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
+ ensure_zero_events(pfdeimpl);
hr = IFileDialog_Advise(pfd, pfde, &cookie[0]);
ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine ok(cookie[0] == 1, "got cookie: %d\n", cookie[0]);
ok(pfdeimpl->ref == 1+1, "got ref %d\n", pfdeimpl->ref);
+ ensure_zero_events(pfdeimpl);
hr = IFileDialog_Unadvise(pfd, cookie[0]);
--
1.7.5.rc3
More information about the wine-patches
mailing list