From 586c3f2b4678c7e576c9459cc5aba9f72a327561 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 11 Jun 2014 08:03:37 +0400 Subject: [PATCH] explorerframe: Query for more notification callbacks. --- dlls/explorerframe/nstc.c | 87 +++++++++++++++++++-------------- dlls/explorerframe/tests/nstc.c | 32 ++++-------- 2 files changed, 59 insertions(+), 60 deletions(-) diff --git a/dlls/explorerframe/nstc.c b/dlls/explorerframe/nstc.c index 4d977ecf7bc..04f4ec8f05f 100644 --- a/dlls/explorerframe/nstc.c +++ b/dlls/explorerframe/nstc.c @@ -60,7 +60,9 @@ typedef struct { NSTCSTYLE2 style2; struct list roots; - INameSpaceTreeControlEvents *pnstce; + INameSpaceTreeControlCustomDraw *customdraw; + INameSpaceTreeControlDropHandler *dragdrop; + INameSpaceTreeControlEvents *events; } NSTC2Impl; static const DWORD unsupported_styles = @@ -92,10 +94,10 @@ static HRESULT events_OnGetDefaultIconIndex(NSTC2Impl *This, IShellItem *psi, { HRESULT ret; LONG refcount; - if(!This->pnstce) return E_NOTIMPL; + if(!This->events) return E_NOTIMPL; refcount = IShellItem_AddRef(psi); - ret = INameSpaceTreeControlEvents_OnGetDefaultIconIndex(This->pnstce, psi, piDefaultIcon, piOpenIcon); + ret = INameSpaceTreeControlEvents_OnGetDefaultIconIndex(This->events, psi, piDefaultIcon, piOpenIcon); if(IShellItem_Release(psi) < refcount - 1) ERR("ShellItem was released by client - please file a bug.\n"); return ret; @@ -105,10 +107,10 @@ static HRESULT events_OnItemAdded(NSTC2Impl *This, IShellItem *psi, BOOL fIsRoot { HRESULT ret; LONG refcount; - if(!This->pnstce) return S_OK; + if(!This->events) return S_OK; refcount = IShellItem_AddRef(psi); - ret = INameSpaceTreeControlEvents_OnItemAdded(This->pnstce, psi, fIsRoot); + ret = INameSpaceTreeControlEvents_OnItemAdded(This->events, psi, fIsRoot); if(IShellItem_Release(psi) < refcount - 1) ERR("ShellItem was released by client - please file a bug.\n"); return ret; @@ -118,10 +120,10 @@ static HRESULT events_OnItemDeleted(NSTC2Impl *This, IShellItem *psi, BOOL fIsRo { HRESULT ret; LONG refcount; - if(!This->pnstce) return S_OK; + if(!This->events) return S_OK; refcount = IShellItem_AddRef(psi); - ret = INameSpaceTreeControlEvents_OnItemDeleted(This->pnstce, psi, fIsRoot); + ret = INameSpaceTreeControlEvents_OnItemDeleted(This->events, psi, fIsRoot); if(IShellItem_Release(psi) < refcount - 1) ERR("ShellItem was released by client - please file a bug.\n"); return ret; @@ -131,10 +133,10 @@ static HRESULT events_OnBeforeExpand(NSTC2Impl *This, IShellItem *psi) { HRESULT ret; LONG refcount; - if(!This->pnstce) return S_OK; + if(!This->events) return S_OK; refcount = IShellItem_AddRef(psi); - ret = INameSpaceTreeControlEvents_OnBeforeExpand(This->pnstce, psi); + ret = INameSpaceTreeControlEvents_OnBeforeExpand(This->events, psi); if(IShellItem_Release(psi) < refcount - 1) ERR("ShellItem was released by client - please file a bug.\n"); return ret; @@ -144,10 +146,10 @@ static HRESULT events_OnAfterExpand(NSTC2Impl *This, IShellItem *psi) { HRESULT ret; LONG refcount; - if(!This->pnstce) return S_OK; + if(!This->events) return S_OK; refcount = IShellItem_AddRef(psi); - ret = INameSpaceTreeControlEvents_OnAfterExpand(This->pnstce, psi); + ret = INameSpaceTreeControlEvents_OnAfterExpand(This->events, psi); if(IShellItem_Release(psi) < refcount - 1) ERR("ShellItem was released by client - please file a bug.\n"); return ret; @@ -158,10 +160,10 @@ static HRESULT events_OnItemClick(NSTC2Impl *This, IShellItem *psi, { HRESULT ret; LONG refcount; - if(!This->pnstce) return S_OK; + if(!This->events) return S_OK; refcount = IShellItem_AddRef(psi); - ret = INameSpaceTreeControlEvents_OnItemClick(This->pnstce, psi, nstceHitTest, nstceClickType); + ret = INameSpaceTreeControlEvents_OnItemClick(This->events, psi, nstceHitTest, nstceClickType); if(IShellItem_Release(psi) < refcount - 1) ERR("ShellItem was released by client - please file a bug.\n"); return ret; @@ -169,16 +171,16 @@ static HRESULT events_OnItemClick(NSTC2Impl *This, IShellItem *psi, static HRESULT events_OnSelectionChanged(NSTC2Impl *This, IShellItemArray *psia) { - if(!This->pnstce) return S_OK; + if(!This->events) return S_OK; - return INameSpaceTreeControlEvents_OnSelectionChanged(This->pnstce, psia); + return INameSpaceTreeControlEvents_OnSelectionChanged(This->events, psia); } static HRESULT events_OnKeyboardInput(NSTC2Impl *This, UINT uMsg, WPARAM wParam, LPARAM lParam) { - if(!This->pnstce) return S_OK; + if(!This->events) return S_OK; - return INameSpaceTreeControlEvents_OnKeyboardInput(This->pnstce, uMsg, wParam, lParam); + return INameSpaceTreeControlEvents_OnKeyboardInput(This->events, uMsg, wParam, lParam); } /************************************************************************* @@ -926,42 +928,53 @@ static HRESULT WINAPI NSTC2_fnInitialize(INameSpaceTreeControl2* iface, return S_OK; } -static HRESULT WINAPI NSTC2_fnTreeAdvise(INameSpaceTreeControl2* iface, - IUnknown *punk, - DWORD *pdwCookie) +static HRESULT WINAPI NSTC2_fnTreeAdvise(INameSpaceTreeControl2* iface, IUnknown *handler, DWORD *cookie) { NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface); - HRESULT hr; - TRACE("%p (%p, %p)\n", This, punk, pdwCookie); - *pdwCookie = 0; + TRACE("%p (%p, %p)\n", This, handler, cookie); + + *cookie = 0; /* Only one client supported */ - if(This->pnstce) + if (This->events || This->customdraw || This->dragdrop) return E_FAIL; - hr = IUnknown_QueryInterface(punk, &IID_INameSpaceTreeControlEvents,(void**)&This->pnstce); - if(SUCCEEDED(hr)) - { - *pdwCookie = 1; - return hr; - } + /* FIXME: request INameSpaceTreeAccessible too */ + IUnknown_QueryInterface(handler, &IID_INameSpaceTreeControlEvents, (void**)&This->events); + IUnknown_QueryInterface(handler, &IID_INameSpaceTreeControlCustomDraw, (void**)&This->customdraw); + IUnknown_QueryInterface(handler, &IID_INameSpaceTreeControlDropHandler, (void**)&This->dragdrop); - return E_FAIL; + if (This->events || This->customdraw || This->dragdrop) + *cookie = 1; + + return *cookie ? S_OK : E_FAIL; } -static HRESULT WINAPI NSTC2_fnTreeUnadvise(INameSpaceTreeControl2* iface, - DWORD dwCookie) +static HRESULT WINAPI NSTC2_fnTreeUnadvise(INameSpaceTreeControl2* iface, DWORD cookie) { NSTC2Impl *This = impl_from_INameSpaceTreeControl2(iface); - TRACE("%p (%x)\n", This, dwCookie); + + TRACE("%p (%x)\n", This, cookie); /* The cookie is ignored. */ - if(This->pnstce) + if (This->events) { - INameSpaceTreeControlEvents_Release(This->pnstce); - This->pnstce = NULL; + INameSpaceTreeControlEvents_Release(This->events); + This->events = NULL; + } + + if (This->customdraw) + { + INameSpaceTreeControlCustomDraw_Release(This->customdraw); + This->customdraw = NULL; + } + + if (This->dragdrop) + { + INameSpaceTreeControlDropHandler_Release(This->dragdrop); + This->dragdrop = NULL; } return S_OK; diff --git a/dlls/explorerframe/tests/nstc.c b/dlls/explorerframe/tests/nstc.c index 94ca06c144e..6eefa934857 100644 --- a/dlls/explorerframe/tests/nstc.c +++ b/dlls/explorerframe/tests/nstc.c @@ -91,7 +91,7 @@ static HRESULT WINAPI NSTCEvents_fnQueryInterface( if(This->qi_enable_events && IsEqualIID(riid, &IID_INameSpaceTreeControlEvents)) { - IUnknown_AddRef(iface); + INameSpaceTreeControlEvents_AddRef(iface); *ppvObject = iface; return S_OK; } @@ -1819,37 +1819,27 @@ static void test_events(void) /* First, respond with E_NOINTERFACE to all QI's */ pnstceimpl->qi_enable_events = FALSE; pnstceimpl->qi_called_count = 0; - cookie1 = 0xDEADBEEF; + cookie1 = 1; hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie1); ok(hr == E_FAIL, "Got (0x%08x)\n", hr); ok(cookie1 == 0, "cookie now (0x%08x)\n", cookie1); - todo_wine - { - ok(pnstceimpl->qi_called_count == 7 || pnstceimpl->qi_called_count == 4 /* Vista */, - "QueryInterface called %d times.\n", - pnstceimpl->qi_called_count); - } + ok(pnstceimpl->qi_called_count > 1, "got %d\n", pnstceimpl->qi_called_count); ok(pnstceimpl->ref == 1, "refcount was %d\n", pnstceimpl->ref); /* Accept query for IID_INameSpaceTreeControlEvents */ pnstceimpl->qi_enable_events = TRUE; pnstceimpl->qi_called_count = 0; - cookie1 = 0xDEADBEEF; + cookie1 = 0; hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie1); ok(hr == S_OK, "Got (0x%08x)\n", hr); ok(cookie1 == 1, "cookie now (0x%08x)\n", cookie1); - todo_wine - { - ok(pnstceimpl->qi_called_count == 7 || pnstceimpl->qi_called_count == 4 /* Vista */, - "QueryInterface called %d times.\n", - pnstceimpl->qi_called_count); - } + ok(pnstceimpl->qi_called_count > 1, "got %d\n", pnstceimpl->qi_called_count); ok(pnstceimpl->ref == 2, "refcount was %d\n", pnstceimpl->ref); /* A second time, query interface will not be called at all. */ pnstceimpl->qi_enable_events = TRUE; pnstceimpl->qi_called_count = 0; - cookie2 = 0xDEADBEEF; + cookie2 = 1; hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce, &cookie2); ok(hr == E_FAIL, "Got (0x%08x)\n", hr); ok(cookie2 == 0, "cookie now (0x%08x)\n", cookie2); @@ -1860,7 +1850,7 @@ static void test_events(void) /* Using another "instance" does not help. */ pnstceimpl2->qi_enable_events = TRUE; pnstceimpl2->qi_called_count = 0; - cookie2 = 0xDEADBEEF; + cookie2 = 1; hr = INameSpaceTreeControl_TreeAdvise(pnstc, (IUnknown*)pnstce2, &cookie2); ok(hr == E_FAIL, "Got (0x%08x)\n", hr); ok(cookie2 == 0, "cookie now (0x%08x)\n", cookie2); @@ -1893,12 +1883,8 @@ static void test_events(void) ok(hr == S_OK, "Got (0x%08x)\n", hr); ok(cookie2 == 1, "Cookie is %d\n", cookie2); ok(cookie1 == cookie2, "Old cookie differs from old cookie.\n"); - todo_wine - { - ok(pnstceimpl->qi_called_count == 7 || pnstceimpl->qi_called_count == 4 /* Vista */, - "QueryInterface called %d times.\n", - pnstceimpl->qi_called_count); - } + /* several kinds of callbacks are queried for */ + ok(pnstceimpl->qi_called_count > 1, "got %d\n", pnstceimpl->qi_called_count); ok(pnstceimpl->ref == 2, "refcount was %d\n", pnstceimpl->ref); /* Initialize the control */