comdlg32: Support some events in the item dialog.

This commit is contained in:
David Hedberg 2011-05-24 21:09:48 +02:00 committed by Alexandre Julliard
parent 77cc26878c
commit 1597dec048
2 changed files with 134 additions and 9 deletions

View File

@ -92,6 +92,73 @@ typedef struct FileDialogImpl {
LPWSTR custom_filenamelabel; LPWSTR custom_filenamelabel;
} 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. * Helper functions.
*/ */
@ -280,6 +347,9 @@ static HRESULT on_default_action(FileDialogImpl *This)
break; break;
case ONOPEN_OPEN: case ONOPEN_OPEN:
if(events_OnFileOk(This) != S_OK)
break;
hr = SHGetDesktopFolder(&psf_desktop); hr = SHGetDesktopFolder(&psf_desktop);
if(SUCCEEDED(hr)) 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, hr = SHCreateShellItemArray(NULL, psf_desktop, file_count, (PCUITEMID_CHILD_ARRAY)pidla,
&This->psia_results); &This->psia_results);
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
ret = S_OK; ret = S_OK;
@ -1818,7 +1887,25 @@ static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrow
PCIDLIST_ABSOLUTE pidlFolder) PCIDLIST_ABSOLUTE pidlFolder)
{ {
FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface); FileDialogImpl *This = impl_from_IExplorerBrowserEvents(iface);
IShellItem *psi;
HRESULT hr;
TRACE("%p (%p)\n", This, pidlFolder); 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; return S_OK;
} }
@ -1847,6 +1934,8 @@ static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBro
This->psi_folder = NULL; This->psi_folder = NULL;
} }
events_OnFolderChange(This);
return S_OK; return S_OK;
} }
@ -1993,7 +2082,10 @@ static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
hr = SHCreateShellItemArrayFromDataObject(new_selection, &IID_IShellItemArray, hr = SHCreateShellItemArrayFromDataObject(new_selection, &IID_IShellItemArray,
(void**)&This->psia_selection); (void**)&This->psia_selection);
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{
fill_filename_from_selection(This); fill_filename_from_selection(This);
events_OnSelectionChange(This);
}
IDataObject_Release(new_selection); IDataObject_Release(new_selection);
} }

View File

@ -44,6 +44,10 @@ static void init_function_pointers(void)
typedef struct { typedef struct {
IFileDialogEvents IFileDialogEvents_iface; IFileDialogEvents IFileDialogEvents_iface;
LONG ref; LONG ref;
LONG QueryInterface;
LONG OnFileOk, OnFolderChanging, OnFolderChange;
LONG OnSelectionChange, OnShareViolation, OnTypeChange;
LONG OnOverwrite;
} IFileDialogEventsImpl; } IFileDialogEventsImpl;
static inline IFileDialogEventsImpl *impl_from_IFileDialogEvents(IFileDialogEvents *iface) 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) 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; return S_OK;
} }
@ -85,19 +90,22 @@ static HRESULT WINAPI IFileDialogEvents_fnOnFolderChanging(IFileDialogEvents *if
IFileDialog *pfd, IFileDialog *pfd,
IShellItem *psiFolder) IShellItem *psiFolder)
{ {
ok(0, "Unexpectedly called.\n"); IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
This->OnFolderChanging++;
return S_OK; return S_OK;
} }
static HRESULT WINAPI IFileDialogEvents_fnOnFolderChange(IFileDialogEvents *iface, IFileDialog *pfd) 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; return S_OK;
} }
static HRESULT WINAPI IFileDialogEvents_fnOnSelectionChange(IFileDialogEvents *iface, IFileDialog *pfd) 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; return S_OK;
} }
@ -106,13 +114,15 @@ static HRESULT WINAPI IFileDialogEvents_fnOnShareViolation(IFileDialogEvents *if
IShellItem *psi, IShellItem *psi,
FDE_SHAREVIOLATION_RESPONSE *pResponse) FDE_SHAREVIOLATION_RESPONSE *pResponse)
{ {
ok(0, "Unexpectedly called.\n"); IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
This->OnShareViolation++;
return S_OK; return S_OK;
} }
static HRESULT WINAPI IFileDialogEvents_fnOnTypeChange(IFileDialogEvents *iface, IFileDialog *pfd) 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; return S_OK;
} }
@ -121,7 +131,8 @@ static HRESULT WINAPI IFileDialogEvents_fnOnOverwrite(IFileDialogEvents *iface,
IShellItem *psi, IShellItem *psi,
FDE_OVERWRITE_RESPONSE *pResponse) FDE_OVERWRITE_RESPONSE *pResponse)
{ {
ok(0, "Unexpectedly called.\n"); IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
This->OnOverwrite++;
return S_OK; return S_OK;
} }
@ -142,7 +153,7 @@ static IFileDialogEvents *IFileDialogEvents_Constructor(void)
{ {
IFileDialogEventsImpl *This; IFileDialogEventsImpl *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(IFileDialogEventsImpl)); This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IFileDialogEventsImpl));
This->IFileDialogEvents_iface.lpVtbl = &vt_IFileDialogEvents; This->IFileDialogEvents_iface.lpVtbl = &vt_IFileDialogEvents;
This->ref = 1; This->ref = 1;
@ -745,6 +756,21 @@ static void test_basics(void)
ok(!ref, "Got refcount %d, should have been released.\n", ref); 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) static void test_advise_helper(IFileDialog *pfd)
{ {
IFileDialogEventsImpl *pfdeimpl; IFileDialogEventsImpl *pfdeimpl;
@ -763,6 +789,7 @@ static void test_advise_helper(IFileDialog *pfd)
hr = IFileDialog_Advise(pfd, NULL, &cookie[0]); hr = IFileDialog_Advise(pfd, NULL, &cookie[0]);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref); ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
ensure_zero_events(pfdeimpl);
hr = IFileDialog_Unadvise(pfd, 0); hr = IFileDialog_Unadvise(pfd, 0);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 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(cookie[i] == i+1, "Got cookie: %d\n", cookie[i]);
} }
ok(pfdeimpl->ref == 10+1, "got ref %d\n", pfdeimpl->ref); ok(pfdeimpl->ref == 10+1, "got ref %d\n", pfdeimpl->ref);
ensure_zero_events(pfdeimpl);
for(i = 3; i < 7; i++) { for(i = 3; i < 7; i++) {
hr = IFileDialog_Unadvise(pfd, cookie[i]); hr = IFileDialog_Unadvise(pfd, cookie[i]);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "got 0x%08x\n", hr);
} }
ok(pfdeimpl->ref == 6+1, "got ref %d\n", pfdeimpl->ref); ok(pfdeimpl->ref == 6+1, "got ref %d\n", pfdeimpl->ref);
ensure_zero_events(pfdeimpl);
for(i = 0; i < 3; i++) { for(i = 0; i < 3; i++) {
hr = IFileDialog_Unadvise(pfd, cookie[i]); hr = IFileDialog_Unadvise(pfd, cookie[i]);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "got 0x%08x\n", hr);
} }
ok(pfdeimpl->ref == 3+1, "got ref %d\n", pfdeimpl->ref); ok(pfdeimpl->ref == 3+1, "got ref %d\n", pfdeimpl->ref);
ensure_zero_events(pfdeimpl);
for(i = 7; i < 10; i++) { for(i = 7; i < 10; i++) {
hr = IFileDialog_Unadvise(pfd, cookie[i]); hr = IFileDialog_Unadvise(pfd, cookie[i]);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "got 0x%08x\n", hr);
} }
ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref); ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
ensure_zero_events(pfdeimpl);
hr = IFileDialog_Unadvise(pfd, cookie[9]+1); hr = IFileDialog_Unadvise(pfd, cookie[9]+1);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref); ok(pfdeimpl->ref == 1, "got ref %d\n", pfdeimpl->ref);
ensure_zero_events(pfdeimpl);
hr = IFileDialog_Advise(pfd, pfde, &cookie[0]); hr = IFileDialog_Advise(pfd, pfde, &cookie[0]);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine ok(cookie[0] == 1, "got cookie: %d\n", cookie[0]); todo_wine ok(cookie[0] == 1, "got cookie: %d\n", cookie[0]);
ok(pfdeimpl->ref == 1+1, "got ref %d\n", pfdeimpl->ref); ok(pfdeimpl->ref == 1+1, "got ref %d\n", pfdeimpl->ref);
ensure_zero_events(pfdeimpl);
hr = IFileDialog_Unadvise(pfd, cookie[0]); hr = IFileDialog_Unadvise(pfd, cookie[0]);