comdlg32: Implement Advise/Unadvise for the Item Dialog.

This commit is contained in:
David Hedberg 2011-03-29 21:13:23 +02:00 committed by Alexandre Julliard
parent b5a1c89f6a
commit ac2063a418
2 changed files with 251 additions and 4 deletions

View File

@ -35,6 +35,7 @@
#include "cdlg.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
@ -43,6 +44,12 @@ enum ITEMDLG_TYPE {
ITEMDLG_TYPE_SAVE
};
typedef struct {
struct list entry;
IFileDialogEvents *pfde;
DWORD cookie;
} events_client;
typedef struct FileDialogImpl {
IFileDialog2 IFileDialog2_iface;
union {
@ -57,6 +64,9 @@ typedef struct FileDialogImpl {
UINT filterspec_count;
UINT filetypeindex;
struct list events_clients;
DWORD events_next_cookie;
IShellItemArray *psia_selection;
IShellItemArray *psia_results;
IShellItem *psi_defaultfolder;
@ -209,15 +219,48 @@ static HRESULT WINAPI IFileDialog2_fnGetFileTypeIndex(IFileDialog2 *iface, UINT
static HRESULT WINAPI IFileDialog2_fnAdvise(IFileDialog2 *iface, IFileDialogEvents *pfde, DWORD *pdwCookie)
{
FileDialogImpl *This = impl_from_IFileDialog2(iface);
FIXME("stub - %p (%p, %p)\n", This, pfde, pdwCookie);
return E_NOTIMPL;
events_client *client;
TRACE("%p (%p, %p)\n", This, pfde, pdwCookie);
if(!pfde || !pdwCookie)
return E_INVALIDARG;
client = HeapAlloc(GetProcessHeap(), 0, sizeof(events_client));
client->pfde = pfde;
client->cookie = ++This->events_next_cookie;
IFileDialogEvents_AddRef(pfde);
*pdwCookie = client->cookie;
list_add_tail(&This->events_clients, &client->entry);
return S_OK;
}
static HRESULT WINAPI IFileDialog2_fnUnadvise(IFileDialog2 *iface, DWORD dwCookie)
{
FileDialogImpl *This = impl_from_IFileDialog2(iface);
FIXME("stub - %p (%d)\n", This, dwCookie);
return E_NOTIMPL;
events_client *client, *found = NULL;
TRACE("%p (%d)\n", This, dwCookie);
LIST_FOR_EACH_ENTRY(client, &This->events_clients, events_client, entry)
{
if(client->cookie == dwCookie)
{
found = client;
break;
}
}
if(found)
{
list_remove(&found->entry);
IFileDialogEvents_Release(found->pfde);
HeapFree(GetProcessHeap(), 0, found);
return S_OK;
}
return E_INVALIDARG;
}
static HRESULT WINAPI IFileDialog2_fnSetOptions(IFileDialog2 *iface, FILEOPENDIALOGOPTIONS fos)
@ -997,6 +1040,9 @@ static HRESULT FileDialog_constructor(IUnknown *pUnkOuter, REFIID riid, void **p
fdimpl->psia_selection = fdimpl->psia_results = NULL;
fdimpl->psi_setfolder = fdimpl->psi_folder = NULL;
list_init(&fdimpl->events_clients);
fdimpl->events_next_cookie = 0;
/* FIXME: The default folder setting should be restored for the
* application if it was previously set. */
SHGetDesktopFolder(&psf);

View File

@ -20,6 +20,7 @@
*/
#define COBJMACROS
#define CONST_VTABLE
#include "shlobj.h"
#include "wine/test.h"
@ -37,6 +38,117 @@ static void init_function_pointers(void)
#undef MAKEFUNC
}
/**************************************************************************
* IFileDialogEvents implementation
*/
typedef struct {
IFileDialogEvents IFileDialogEvents_iface;
LONG ref;
} IFileDialogEventsImpl;
static inline IFileDialogEventsImpl *impl_from_IFileDialogEvents(IFileDialogEvents *iface)
{
return CONTAINING_RECORD(iface, IFileDialogEventsImpl, IFileDialogEvents_iface);
}
static HRESULT WINAPI IFileDialogEvents_fnQueryInterface(IFileDialogEvents *iface, REFIID riid, void **ppv)
{
/* Not called. */
ok(0, "Unexpectedly called.\n");
return E_NOINTERFACE;
}
static ULONG WINAPI IFileDialogEvents_fnAddRef(IFileDialogEvents *iface)
{
IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI IFileDialogEvents_fnRelease(IFileDialogEvents *iface)
{
IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
LONG ref = InterlockedDecrement(&This->ref);
if(!ref)
HeapFree(GetProcessHeap(), 0, This);
return ref;
}
static HRESULT WINAPI IFileDialogEvents_fnOnFileOk(IFileDialogEvents *iface, IFileDialog *pfd)
{
ok(0, "Unexpectedly called.\n");
return S_OK;
}
static HRESULT WINAPI IFileDialogEvents_fnOnFolderChanging(IFileDialogEvents *iface,
IFileDialog *pfd,
IShellItem *psiFolder)
{
ok(0, "Unexpectedly called.\n");
return S_OK;
}
static HRESULT WINAPI IFileDialogEvents_fnOnFolderChange(IFileDialogEvents *iface, IFileDialog *pfd)
{
ok(0, "Unexpectedly called.\n");
return S_OK;
}
static HRESULT WINAPI IFileDialogEvents_fnOnSelectionChange(IFileDialogEvents *iface, IFileDialog *pfd)
{
ok(0, "Unexpectedly called.\n");
return S_OK;
}
static HRESULT WINAPI IFileDialogEvents_fnOnShareViolation(IFileDialogEvents *iface,
IFileDialog *pfd,
IShellItem *psi,
FDE_SHAREVIOLATION_RESPONSE *pResponse)
{
ok(0, "Unexpectedly called.\n");
return S_OK;
}
static HRESULT WINAPI IFileDialogEvents_fnOnTypeChange(IFileDialogEvents *iface, IFileDialog *pfd)
{
ok(0, "Unexpectedly called.\n");
return S_OK;
}
static HRESULT WINAPI IFileDialogEvents_fnOnOverwrite(IFileDialogEvents *iface,
IFileDialog *pfd,
IShellItem *psi,
FDE_OVERWRITE_RESPONSE *pResponse)
{
ok(0, "Unexpectedly called.\n");
return S_OK;
}
static const IFileDialogEventsVtbl vt_IFileDialogEvents = {
IFileDialogEvents_fnQueryInterface,
IFileDialogEvents_fnAddRef,
IFileDialogEvents_fnRelease,
IFileDialogEvents_fnOnFileOk,
IFileDialogEvents_fnOnFolderChanging,
IFileDialogEvents_fnOnFolderChange,
IFileDialogEvents_fnOnSelectionChange,
IFileDialogEvents_fnOnShareViolation,
IFileDialogEvents_fnOnTypeChange,
IFileDialogEvents_fnOnOverwrite
};
static IFileDialogEvents *IFileDialogEvents_Constructor(void)
{
IFileDialogEventsImpl *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(IFileDialogEventsImpl));
This->IFileDialogEvents_iface.lpVtbl = &vt_IFileDialogEvents;
This->ref = 1;
return &This->IFileDialogEvents_iface;
}
static BOOL test_instantiation(void)
{
IFileDialog *pfd;
@ -635,6 +747,94 @@ static void test_basics(void)
IFileSaveDialog_Release(pfsd);
}
static void test_advise_helper(IFileDialog *pfd)
{
IFileDialogEventsImpl *pfdeimpl;
IFileDialogEvents *pfde;
DWORD cookie[10];
UINT i;
HRESULT hr;
pfde = IFileDialogEvents_Constructor();
pfdeimpl = impl_from_IFileDialogEvents(pfde);
hr = IFileDialog_Advise(pfd, NULL, NULL);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
hr = IFileDialog_Advise(pfd, pfde, NULL);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
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);
hr = IFileDialog_Unadvise(pfd, 0);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
for(i = 0; i < 10; i++) {
hr = IFileDialog_Advise(pfd, pfde, &cookie[i]);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(cookie[i] == i+1, "Got cookie: %d\n", cookie[i]);
}
ok(pfdeimpl->ref == 10+1, "got ref %d\n", pfdeimpl->ref);
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);
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);
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);
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);
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);
hr = IFileDialog_Unadvise(pfd, cookie[0]);
if(0)
{
/* Unadvising already unadvised cookies crashes on
Windows 7. */
IFileDialog_Unadvise(pfd, cookie[0]);
}
IFileDialogEvents_Release(pfde);
}
static void test_advise(void)
{
IFileDialog *pfd;
HRESULT hr;
trace("Testing FileOpenDialog (advise)\n");
hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
&IID_IFileDialog, (void**)&pfd);
ok(hr == S_OK, "got 0x%08x.\n", hr);
test_advise_helper(pfd);
IFileDialog_Release(pfd);
trace("Testing FileSaveDialog (advise)\n");
hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
&IID_IFileDialog, (void**)&pfd);
ok(hr == S_OK, "got 0x%08x.\n", hr);
test_advise_helper(pfd);
IFileDialog_Release(pfd);
}
START_TEST(itemdlg)
{
OleInitialize(NULL);
@ -643,6 +843,7 @@ START_TEST(itemdlg)
if(test_instantiation())
{
test_basics();
test_advise();
}
else
skip("Skipping all Item Dialog tests.\n");