shell32: Implement IExplorerBrowser::Advise and IExplorerBrowser::Unadvise.

This commit is contained in:
David Hedberg 2010-08-24 10:56:19 +02:00 committed by Alexandre Julliard
parent 2ca5513a62
commit b88c3e2ecb
2 changed files with 212 additions and 4 deletions

View File

@ -28,6 +28,7 @@
#include "windef.h"
#include "winbase.h"
#include "wine/list.h"
#include "wine/debug.h"
#include "debughlp.h"
@ -35,6 +36,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
typedef struct _event_client {
struct list entry;
IExplorerBrowserEvents *pebe;
DWORD cookie;
} event_client;
typedef struct _ExplorerBrowserImpl {
const IExplorerBrowserVtbl *lpVtbl;
const IShellBrowserVtbl *lpsbVtbl;
@ -47,10 +54,30 @@ typedef struct _ExplorerBrowserImpl {
EXPLORER_BROWSER_OPTIONS eb_options;
FOLDERSETTINGS fs;
struct list event_clients;
DWORD events_next_cookie;
IShellView *psv;
RECT sv_rc;
} ExplorerBrowserImpl;
/**************************************************************************
* Event functions.
*/
static void events_unadvise_all(ExplorerBrowserImpl *This)
{
event_client *client, *curs;
TRACE("%p\n", This);
LIST_FOR_EACH_ENTRY_SAFE(client, curs, &This->event_clients, event_client, entry)
{
TRACE("Removing %p\n", client);
list_remove(&client->entry);
IExplorerBrowserEvents_Release(client->pebe);
HeapFree(GetProcessHeap(), 0, client);
}
}
/**************************************************************************
* Helper functions
*/
@ -248,6 +275,8 @@ static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
This->hwnd_sv = NULL;
}
events_unadvise_all(This);
DestroyWindow(This->hwnd_main);
This->destroyed = TRUE;
@ -314,18 +343,40 @@ static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
DWORD *pdwCookie)
{
ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
FIXME("stub, %p (%p, %p)\n", This, psbe, pdwCookie);
event_client *client;
TRACE("%p (%p, %p)\n", This, psbe, pdwCookie);
return E_NOTIMPL;
client = HeapAlloc(GetProcessHeap(), 0, sizeof(event_client));
client->pebe = psbe;
client->cookie = ++This->events_next_cookie;
IExplorerBrowserEvents_AddRef(psbe);
*pdwCookie = client->cookie;
list_add_tail(&This->event_clients, &client->entry);
return S_OK;
}
static HRESULT WINAPI IExplorerBrowser_fnUnadvise(IExplorerBrowser *iface,
DWORD dwCookie)
{
ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
FIXME("stub, %p (0x%x)\n", This, dwCookie);
event_client *client;
TRACE("%p (0x%x)\n", This, dwCookie);
return E_NOTIMPL;
LIST_FOR_EACH_ENTRY(client, &This->event_clients, event_client, entry)
{
if(client->cookie == dwCookie)
{
list_remove(&client->entry);
IExplorerBrowserEvents_Release(client->pebe);
HeapFree(GetProcessHeap(), 0, client);
return S_OK;
}
}
return E_INVALIDARG;
}
static HRESULT WINAPI IExplorerBrowser_fnSetOptions(IExplorerBrowser *iface,
@ -652,6 +703,8 @@ HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, voi
eb->lpVtbl = &vt_IExplorerBrowser;
eb->lpsbVtbl = &vt_IShellBrowser;
list_init(&eb->event_clients);
ret = IExplorerBrowser_QueryInterface((IExplorerBrowser*)eb, riid, ppv);
IExplorerBrowser_Release((IExplorerBrowser*)eb);

View File

@ -44,6 +44,77 @@ static HRESULT ebrowser_initialize(IExplorerBrowser *peb)
return IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
}
/*********************************************************************
* IExplorerBrowserEvents implementation
*/
typedef struct {
const IExplorerBrowserEventsVtbl *lpVtbl;
LONG ref;
UINT pending, created, completed, failed;
} IExplorerBrowserEventsImpl;
static IExplorerBrowserEventsImpl ebev;
static HRESULT WINAPI IExplorerBrowserEvents_fnQueryInterface(IExplorerBrowserEvents *iface,
REFIID riid, void **ppvObj)
{
ok(0, "Never called.\n");
return E_NOINTERFACE;
}
static ULONG WINAPI IExplorerBrowserEvents_fnAddRef(IExplorerBrowserEvents *iface)
{
IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI IExplorerBrowserEvents_fnRelease(IExplorerBrowserEvents *iface)
{
IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
return InterlockedDecrement(&This->ref);
}
static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationPending(IExplorerBrowserEvents *iface,
PCIDLIST_ABSOLUTE pidlFolder)
{
IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
This->pending++;
return S_OK;
}
static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationComplete(IExplorerBrowserEvents *iface,
PCIDLIST_ABSOLUTE pidlFolder)
{
IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
This->completed++;
return S_OK;
}
static HRESULT WINAPI IExplorerBrowserEvents_fnOnNavigationFailed(IExplorerBrowserEvents *iface,
PCIDLIST_ABSOLUTE pidlFolder)
{
IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
This->failed++;
return S_OK;
}
static HRESULT WINAPI IExplorerBrowserEvents_fnOnViewCreated(IExplorerBrowserEvents *iface,
IShellView *psv)
{
IExplorerBrowserEventsImpl *This = (IExplorerBrowserEventsImpl*)iface;
This->created++;
return S_OK;
}
static const IExplorerBrowserEventsVtbl ebevents =
{
IExplorerBrowserEvents_fnQueryInterface,
IExplorerBrowserEvents_fnAddRef,
IExplorerBrowserEvents_fnRelease,
IExplorerBrowserEvents_fnOnNavigationPending,
IExplorerBrowserEvents_fnOnViewCreated,
IExplorerBrowserEvents_fnOnNavigationComplete,
IExplorerBrowserEvents_fnOnNavigationFailed
};
static void test_QueryInterface(void)
{
IExplorerBrowser *peb;
@ -378,6 +449,89 @@ static void test_basics(void)
ok(lres == 0, "Got %d\n", lres);
}
static void test_Advise(void)
{
IExplorerBrowser *peb;
IExplorerBrowserEvents *pebe;
DWORD cookies[10];
HRESULT hr;
UINT i, ref;
/* Set up our IExplorerBrowserEvents implementation */
ebev.lpVtbl = &ebevents;
pebe = (IExplorerBrowserEvents*) &ebev;
ebrowser_instantiate(&peb);
if(0)
{
/* Crashes on Windows 7 */
IExplorerBrowser_Advise(peb, pebe, NULL);
IExplorerBrowser_Advise(peb, NULL, &cookies[0]);
}
/* Using Unadvise with a cookie that has yet to be given out
* results in E_INVALIDARG */
hr = IExplorerBrowser_Unadvise(peb, 11);
ok(hr == E_INVALIDARG, "got (0x%08x)\n", hr);
/* Add some before initialization */
for(i = 0; i < 5; i++)
{
hr = IExplorerBrowser_Advise(peb, pebe, &cookies[i]);
ok(hr == S_OK, "got (0x%08x)\n", hr);
}
ebrowser_initialize(peb);
/* Add some after initialization */
for(i = 5; i < 10; i++)
{
hr = IExplorerBrowser_Advise(peb, pebe, &cookies[i]);
ok(hr == S_OK, "got (0x%08x)\n", hr);
}
ok(ebev.ref == 10, "Got %d\n", ebev.ref);
/* Remove a bunch somewhere in the middle */
for(i = 4; i < 8; i++)
{
hr = IExplorerBrowser_Unadvise(peb, cookies[i]);
ok(hr == S_OK, "got (0x%08x)\n", hr);
}
if(0)
{
/* Using unadvise with a previously unadvised cookie results
* in a crash. */
hr = IExplorerBrowser_Unadvise(peb, cookies[5]);
}
/* Remove the rest. */
for(i = 0; i < 10; i++)
{
if(i<4||i>7)
{
hr = IExplorerBrowser_Unadvise(peb, cookies[i]);
ok(hr == S_OK, "%d: got (0x%08x)\n", i, hr);
}
}
ok(ebev.ref == 0, "Got %d\n", ebev.ref);
/* ::Destroy implies ::Unadvise. */
hr = IExplorerBrowser_Advise(peb, pebe, &cookies[0]);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(ebev.ref == 1, "Got %d\n", ebev.ref);
hr = IExplorerBrowser_Destroy(peb);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(ebev.ref == 0, "Got %d\n", ebev.ref);
ref = IExplorerBrowser_Release(peb);
ok(!ref, "Got %d", ref);
}
static BOOL test_instantiate_control(void)
{
IExplorerBrowser *peb;
@ -424,6 +578,7 @@ START_TEST(ebrowser)
test_SB_misc();
test_initialization();
test_basics();
test_Advise();
DestroyWindow(hwnd);
OleUninitialize();