comdlg32: Support some events in the item dialog.
This commit is contained in:
parent
77cc26878c
commit
1597dec048
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue