[PATCH 3/6] shell32: Implement IExplorerBrowser::BrowseToIDList and IShellBrowser::BrowseToObject. (resend)

David Hedberg david.hedberg at gmail.com
Tue Aug 24 03:56:21 CDT 2010


---
 dlls/shell32/ebrowser.c       |  220 +++++++++++++++++++++++++++++++++-
 dlls/shell32/tests/ebrowser.c |  266 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 482 insertions(+), 4 deletions(-)

diff --git a/dlls/shell32/ebrowser.c b/dlls/shell32/ebrowser.c
index 3e56ce0..daf5d4a 100644
--- a/dlls/shell32/ebrowser.c
+++ b/dlls/shell32/ebrowser.c
@@ -33,6 +33,7 @@
 #include "debughlp.h"
 
 #include "shell32_main.h"
+#include "pidl.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
@@ -59,6 +60,7 @@ typedef struct _ExplorerBrowserImpl {
 
     IShellView *psv;
     RECT sv_rc;
+    LPITEMIDLIST current_pidl;
 } ExplorerBrowserImpl;
 
 /**************************************************************************
@@ -78,6 +80,65 @@ static void events_unadvise_all(ExplorerBrowserImpl *This)
     }
 }
 
+static HRESULT events_NavigationPending(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
+{
+    event_client *cursor;
+    HRESULT hres = S_OK;
+
+    TRACE("%p\n", This);
+
+    LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
+    {
+        TRACE("Notifying %p\n", cursor);
+        hres = IExplorerBrowserEvents_OnNavigationPending(cursor->pebe, pidl);
+
+        /* If this failed for any reason, the browsing is supposed to be aborted. */
+        if(FAILED(hres))
+            break;
+    }
+
+    return hres;
+}
+
+static void events_NavigationComplete(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
+{
+    event_client *cursor;
+
+    TRACE("%p\n", This);
+
+    LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
+    {
+        TRACE("Notifying %p\n", cursor);
+        IExplorerBrowserEvents_OnNavigationComplete(cursor->pebe, pidl);
+    }
+}
+
+static void events_NavigationFailed(ExplorerBrowserImpl *This, PCIDLIST_ABSOLUTE pidl)
+{
+    event_client *cursor;
+
+    TRACE("%p\n", This);
+
+    LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
+    {
+        TRACE("Notifying %p\n", cursor);
+        IExplorerBrowserEvents_OnNavigationFailed(cursor->pebe, pidl);
+    }
+}
+
+static void events_ViewCreated(ExplorerBrowserImpl *This, IShellView *psv)
+{
+    event_client *cursor;
+
+    TRACE("%p\n", This);
+
+    LIST_FOR_EACH_ENTRY(cursor, &This->event_clients, event_client, entry)
+    {
+        TRACE("Notifying %p\n", cursor);
+        IExplorerBrowserEvents_OnViewCreated(cursor->pebe, psv);
+    }
+}
+
 /**************************************************************************
  * Helper functions
  */
@@ -116,6 +177,55 @@ static HRESULT change_viewmode(ExplorerBrowserImpl *This, UINT viewmode)
     return hr;
 }
 
+static HRESULT create_new_shellview(ExplorerBrowserImpl *This, IShellItem *psi)
+{
+    IShellBrowser *psb = (IShellBrowser*)&This->lpsbVtbl;
+    IShellFolder *psf;
+    IShellView *psv;
+    HWND hwnd_new;
+    HRESULT hr;
+
+    TRACE("%p, %p\n", This, psi);
+
+    hr = IShellItem_BindToHandler(psi, NULL, &BHID_SFObject, &IID_IShellFolder, (void**)&psf);
+    if(SUCCEEDED(hr))
+    {
+        hr = IShellFolder_CreateViewObject(psf, This->hwnd_main, &IID_IShellView, (void**)&psv);
+        if(SUCCEEDED(hr))
+        {
+            if(This->hwnd_sv)
+            {
+                IShellView_DestroyViewWindow(This->psv);
+                This->hwnd_sv = NULL;
+            }
+
+            hr = IShellView_CreateViewWindow(psv, This->psv, &This->fs, psb, &This->sv_rc, &hwnd_new);
+            if(SUCCEEDED(hr))
+            {
+                /* Replace the old shellview */
+                if(This->psv) IShellView_Release(This->psv);
+
+                This->psv = psv;
+                This->hwnd_sv = hwnd_new;
+                events_ViewCreated(This, psv);
+            }
+            else
+            {
+                ERR("CreateViewWindow failed (0x%x)\n", hr);
+                IShellView_Release(psv);
+            }
+        }
+        else
+            ERR("CreateViewObject failed (0x%x)\n", hr);
+
+        IShellFolder_Release(psf);
+    }
+    else
+        ERR("SI::BindToHandler failed (0x%x)\n", hr);
+
+    return hr;
+}
+
 /**************************************************************************
  * Main window related functions.
  */
@@ -277,6 +387,9 @@ static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
 
     events_unadvise_all(This);
 
+    ILFree(This->current_pidl);
+    This->current_pidl = NULL;
+
     DestroyWindow(This->hwnd_main);
     This->destroyed = TRUE;
 
@@ -407,14 +520,113 @@ static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
     return S_OK;
 }
 
+static const UINT unsupported_browse_flags =
+    SBSP_NAVIGATEBACK | SBSP_NAVIGATEFORWARD | SBSP_NEWBROWSER |
+    EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
 static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
                                                         PCUIDLIST_RELATIVE pidl,
                                                         UINT uFlags)
 {
     ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
-    FIXME("stub, %p (%p, 0x%x)\n", This, pidl, uFlags);
+    LPITEMIDLIST absolute_pidl = NULL;
+    HRESULT hr;
+    TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);
 
-    return E_NOTIMPL;
+    if(!This->hwnd_main)
+        return E_FAIL;
+
+    if(This->destroyed)
+        return HRESULT_FROM_WIN32(ERROR_BUSY);
+
+    if(This->current_pidl && (This->eb_options & EBO_NAVIGATEONCE))
+        return E_FAIL;
+
+    if(uFlags & SBSP_EXPLOREMODE)
+        return E_INVALIDARG;
+
+    if(uFlags & unsupported_browse_flags)
+        FIXME("Argument 0x%x contains unsupported flags.\n", uFlags);
+
+    if(uFlags & SBSP_PARENT)
+    {
+        if(This->current_pidl)
+        {
+            if(_ILIsPidlSimple(This->current_pidl))
+            {
+                absolute_pidl = _ILCreateDesktop();
+            }
+            else
+            {
+                absolute_pidl = ILClone(This->current_pidl);
+                ILRemoveLastID(absolute_pidl);
+            }
+        }
+        if(!absolute_pidl)
+        {
+            ERR("Failed to get parent pidl.\n");
+            return E_FAIL;
+        }
+
+    }
+    else if(uFlags & SBSP_RELATIVE)
+    {
+        /* SBSP_RELATIVE has precedence over SBSP_ABSOLUTE */
+        TRACE("SBSP_RELATIVE\n");
+        if(This->current_pidl)
+        {
+            absolute_pidl = ILCombine(This->current_pidl, pidl);
+        }
+        if(!absolute_pidl)
+        {
+            ERR("Failed to get absolute pidl.\n");
+            return E_FAIL;
+        }
+    }
+    else
+    {
+        TRACE("SBSP_ABSOLUTE\n");
+        absolute_pidl = ILClone(pidl);
+        if(!absolute_pidl && !This->current_pidl)
+            return E_INVALIDARG;
+        else if(!absolute_pidl)
+            return S_OK;
+    }
+
+    /* TODO: Asynchronous browsing. Return S_OK here and finish in
+     * another thread. */
+
+    hr = events_NavigationPending(This, absolute_pidl);
+    if(FAILED(hr))
+    {
+        TRACE("Browsing aborted.\n");
+        ILFree(absolute_pidl);
+        return E_FAIL;
+    }
+
+    /* Only browse if the new pidl differs from the old */
+    if(!ILIsEqual(This->current_pidl, absolute_pidl))
+    {
+        IShellItem *psi;
+        hr = SHCreateItemFromIDList(absolute_pidl, &IID_IShellItem, (void**)&psi);
+        if(SUCCEEDED(hr))
+        {
+            hr = create_new_shellview(This, psi);
+            if(FAILED(hr))
+            {
+                events_NavigationFailed(This, absolute_pidl);
+                ILFree(absolute_pidl);
+                IShellItem_Release(psi);
+                return E_FAIL;
+            }
+            IShellItem_Release(psi);
+        }
+    }
+
+    events_NavigationComplete(This, absolute_pidl);
+    ILFree(This->current_pidl);
+    This->current_pidl = absolute_pidl;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
@@ -594,9 +806,9 @@ static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
                                                    LPCITEMIDLIST pidl, UINT wFlags)
 {
     ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
-    FIXME("stub, %p\n", This);
+    TRACE("%p (%p, %x)\n", This, pidl, wFlags);
 
-    return E_NOTIMPL;
+    return IExplorerBrowser_fnBrowseToIDList((IExplorerBrowser*)This, pidl, wFlags);
 }
 
 static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
diff --git a/dlls/shell32/tests/ebrowser.c b/dlls/shell32/tests/ebrowser.c
index 2d90d06..788d644 100644
--- a/dlls/shell32/tests/ebrowser.c
+++ b/dlls/shell32/tests/ebrowser.c
@@ -28,6 +28,18 @@
 
 static HWND hwnd;
 
+static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
+static HRESULT (WINAPI *pSHParseDisplayName)(LPCWSTR,IBindCtx*,LPITEMIDLIST*,SFGAOF,SFGAOF*);
+
+static void init_function_pointers(void)
+{
+    HMODULE hmod;
+
+    hmod = GetModuleHandleA("shell32.dll");
+    pSHCreateShellItem = (void*)GetProcAddress(hmod, "SHCreateShellItem");
+    pSHParseDisplayName = (void*)GetProcAddress(hmod, "SHParseDisplayName");
+}
+
 /*********************************************************************
  * Some simple helpers
  */
@@ -44,6 +56,17 @@ static HRESULT ebrowser_initialize(IExplorerBrowser *peb)
     return IExplorerBrowser_Initialize(peb, hwnd, &rc, NULL);
 }
 
+/* Process some messages */
+static void process_msgs(void)
+{
+    MSG msg;
+    while(PeekMessage( &msg, NULL, 0, 0, PM_REMOVE))
+    {
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
+    }
+}
+
 /*********************************************************************
  * IExplorerBrowserEvents implementation
  */
@@ -532,6 +555,247 @@ static void test_Advise(void)
     ok(!ref, "Got %d", ref);
 }
 
+/* Based on PathAddBackslashW from dlls/shlwapi/path.c */
+static LPWSTR myPathAddBackslashW( LPWSTR lpszPath )
+{
+  size_t iLen;
+
+  if (!lpszPath || (iLen = lstrlenW(lpszPath)) >= MAX_PATH)
+    return NULL;
+
+  if (iLen)
+  {
+    lpszPath += iLen;
+    if (lpszPath[-1] != '\\')
+    {
+      *lpszPath++ = '\\';
+      *lpszPath = '\0';
+    }
+  }
+  return lpszPath;
+}
+
+static void test_browse_pidl_(IExplorerBrowser *peb, IExplorerBrowserEventsImpl *ebev,
+                              LPITEMIDLIST pidl, UINT uFlags,
+                              HRESULT hr_exp, UINT pending, UINT created, UINT failed, UINT completed,
+                              const char *file, int line)
+{
+    HRESULT hr;
+    ebev->completed = ebev->created = ebev->pending = ebev->failed = 0;
+
+    hr = IExplorerBrowser_BrowseToIDList(peb, pidl, uFlags);
+    ok_(file, line) (hr == hr_exp, "BrowseToIDList returned 0x%08x\n", hr);
+    process_msgs();
+
+    ok_(file, line)
+        (ebev->pending == pending && ebev->created == created &&
+         ebev->failed == failed && ebev->completed == completed,
+         "Events occurred: %d, %d, %d, %d\n",
+         ebev->pending, ebev->created, ebev->failed, ebev->completed);
+}
+#define test_browse_pidl(peb, ebev, pidl, uFlags, hr, p, cr, f, co)     \
+    test_browse_pidl_(peb, ebev, pidl, uFlags, hr, p, cr, f, co, __FILE__, __LINE__)
+
+static void test_browse_pidl_sb_(IExplorerBrowser *peb, IExplorerBrowserEventsImpl *ebev,
+                                 LPITEMIDLIST pidl, UINT uFlags,
+                                 HRESULT hr_exp, UINT pending, UINT created, UINT failed, UINT completed,
+                                 const char *file, int line)
+{
+    IShellBrowser *psb;
+    HRESULT hr;
+
+    hr = IExplorerBrowser_QueryInterface(peb, &IID_IShellBrowser, (void**)&psb);
+    ok_(file, line) (hr == S_OK, "QueryInterface returned 0x%08x\n", hr);
+    if(SUCCEEDED(hr))
+    {
+        ebev->completed = ebev->created = ebev->pending = ebev->failed = 0;
+
+        hr = IShellBrowser_BrowseObject(psb, pidl, uFlags);
+        ok_(file, line) (hr == hr_exp, "BrowseObject returned 0x%08x\n", hr);
+        process_msgs();
+
+        ok_(file, line)
+            (ebev->pending == pending && ebev->created == created &&
+             ebev->failed == failed && ebev->completed == completed,
+             "Events occurred: %d, %d, %d, %d\n",
+             ebev->pending, ebev->created, ebev->failed, ebev->completed);
+
+        IShellBrowser_Release(psb);
+    }
+}
+#define test_browse_pidl_sb(peb, ebev, pidl, uFlags, hr, p, cr, f, co)  \
+    test_browse_pidl_sb_(peb, ebev, pidl, uFlags, hr, p, cr, f, co, __FILE__, __LINE__)
+
+static void test_navigation(void)
+{
+    IExplorerBrowser *peb, *peb2;
+    IFolderView *pfv;
+    IShellFolder *psf;
+    LPITEMIDLIST pidl_current, pidl_child;
+    DWORD cookie, cookie2;
+    HRESULT hr;
+    LONG lres;
+    WCHAR current_path[MAX_PATH];
+    WCHAR child_path[MAX_PATH];
+    static const WCHAR testfolderW[] =
+        {'w','i','n','e','t','e','s','t','f','o','l','d','e','r','\0'};
+
+    ok(pSHParseDisplayName != NULL, "pSHParseDisplayName unexpectedly missing.\n");
+    ok(pSHCreateShellItem != NULL, "pSHCreateShellItem unexpectedly missing.\n");
+
+    GetCurrentDirectoryW(MAX_PATH, current_path);
+    if(!lstrlenW(current_path))
+    {
+        skip("Failed to create test-directory.\n");
+        return;
+    }
+
+    lstrcpyW(child_path, current_path);
+    myPathAddBackslashW(child_path);
+    lstrcatW(child_path, testfolderW);
+
+    CreateDirectoryW(child_path, NULL);
+
+    pSHParseDisplayName(current_path, NULL, &pidl_current, 0, NULL);
+    pSHParseDisplayName(child_path, NULL, &pidl_child, 0, NULL);
+
+    ebrowser_instantiate(&peb);
+    ebrowser_initialize(peb);
+
+    ebrowser_instantiate(&peb2);
+    ebrowser_initialize(peb2);
+
+    /* Set up our IExplorerBrowserEvents implementation */
+    ebev.lpVtbl = &ebevents;
+
+    IExplorerBrowser_Advise(peb, (IExplorerBrowserEvents*)&ebev, &cookie);
+    IExplorerBrowser_Advise(peb2, (IExplorerBrowserEvents*)&ebev, &cookie2);
+
+    /* These should all fail */
+    test_browse_pidl(peb, &ebev, 0, SBSP_ABSOLUTE | SBSP_RELATIVE, E_FAIL, 0, 0, 0, 0);
+    test_browse_pidl_sb(peb2, &ebev, 0, SBSP_ABSOLUTE | SBSP_RELATIVE, E_FAIL, 0, 0, 0, 0);
+    test_browse_pidl(peb, &ebev, 0, SBSP_ABSOLUTE, E_INVALIDARG, 0, 0, 0, 0);
+    test_browse_pidl_sb(peb2, &ebev, 0, SBSP_ABSOLUTE, E_INVALIDARG, 0, 0, 0, 0);
+    test_browse_pidl(peb, &ebev, 0, SBSP_RELATIVE, E_FAIL, 0, 0, 0, 0);
+    test_browse_pidl_sb(peb2, &ebev, 0, SBSP_RELATIVE, E_FAIL, 0, 0, 0, 0);
+    test_browse_pidl(peb, &ebev, 0, SBSP_PARENT, E_FAIL, 0, 0, 0, 0);
+    test_browse_pidl_sb(peb2, &ebev, 0, SBSP_PARENT, E_FAIL, 0, 0, 0, 0);
+
+    /* "The first browse is synchronous" */
+    test_browse_pidl(peb, &ebev, pidl_child, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
+    test_browse_pidl_sb(peb2, &ebev, pidl_child, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
+
+    /* Relative navigation */
+    test_browse_pidl(peb, &ebev, pidl_current, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
+    test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
+
+    hr = IExplorerBrowser_GetCurrentView(peb, &IID_IFolderView, (void**)&pfv);
+    ok(hr == S_OK, "Got 0x%08x\n", hr);
+    if(SUCCEEDED(hr))
+    {
+        LPITEMIDLIST pidl_relative;
+
+        hr = IFolderView_GetFolder(pfv, &IID_IShellFolder, (void**)&psf);
+        ok(hr == S_OK, "Got 0x%08x\n", hr);
+        hr = IShellFolder_ParseDisplayName(psf, NULL, NULL, (LPWSTR)testfolderW,
+                                           NULL, &pidl_relative, NULL);
+        ok(hr == S_OK, "Got 0x%08x\n", hr);
+
+        /* Browsing to another location here before using the
+         * pidl_relative would make ExplorerBrowser in Windows 7 show a
+         * not-available dialog. Also, passing a relative pidl without
+         * specifying SBSP_RELATIVE makes it look for the pidl on the
+         * desktop
+         */
+
+        test_browse_pidl(peb, &ebev, pidl_relative, SBSP_RELATIVE, S_OK, 1, 1, 0, 1);
+        test_browse_pidl_sb(peb2, &ebev, pidl_relative, SBSP_RELATIVE, S_OK, 1, 1, 0, 1);
+
+        ILFree(pidl_relative);
+        /* IShellFolder_Release(psf); */
+        IFolderView_Release(pfv);
+    }
+
+    /* misc **/
+    test_browse_pidl(peb, &ebev, NULL, SBSP_ABSOLUTE, S_OK, 0, 0, 0, 0);
+    test_browse_pidl_sb(peb2, &ebev, NULL, SBSP_ABSOLUTE, S_OK, 0, 0, 0, 0);
+    test_browse_pidl(peb, &ebev, NULL, SBSP_DEFBROWSER, S_OK, 0, 0, 0, 0);
+    test_browse_pidl_sb(peb2, &ebev, NULL, SBSP_DEFBROWSER, S_OK, 0, 0, 0, 0);
+    test_browse_pidl(peb, &ebev, pidl_current, SBSP_SAMEBROWSER, S_OK, 1, 1, 0, 1);
+    test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_SAMEBROWSER, S_OK, 1, 1, 0, 1);
+    test_browse_pidl(peb, &ebev, pidl_current, SBSP_SAMEBROWSER, S_OK, 1, 0, 0, 1);
+    test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_SAMEBROWSER, S_OK, 1, 0, 0, 1);
+
+    test_browse_pidl(peb, &ebev, pidl_current, SBSP_EXPLOREMODE, E_INVALIDARG, 0, 0, 0, 0);
+    test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_EXPLOREMODE, E_INVALIDARG, 0, 0, 0, 0);
+    test_browse_pidl(peb, &ebev, pidl_current, SBSP_OPENMODE, S_OK, 1, 0, 0, 1);
+    test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_OPENMODE, S_OK, 1, 0, 0, 1);
+
+    /* SBSP_NEWBROWSER will return E_INVALIDARG, claims MSDN, but in
+     * reality it works as one would expect (Windows 7 only?).
+     */
+    if(0)
+    {
+        IExplorerBrowser_BrowseToIDList(peb, NULL, SBSP_NEWBROWSER);
+    }
+
+    hr = IExplorerBrowser_Unadvise(peb, cookie);
+    ok(hr == S_OK, "Got 0x%08x\n", hr);
+    IExplorerBrowser_Destroy(peb);
+    process_msgs();
+    hr = IExplorerBrowser_Unadvise(peb2, cookie2);
+    ok(hr == S_OK, "Got 0x%08x\n", hr);
+    IExplorerBrowser_Destroy(peb2);
+    process_msgs();
+
+    /* Attempt browsing after destroyed */
+    test_browse_pidl(peb, &ebev, pidl_child, SBSP_ABSOLUTE, HRESULT_FROM_WIN32(ERROR_BUSY), 0, 0, 0, 0);
+    test_browse_pidl_sb(peb2, &ebev, pidl_child, SBSP_ABSOLUTE, HRESULT_FROM_WIN32(ERROR_BUSY), 0, 0, 0, 0);
+
+    lres = IExplorerBrowser_Release(peb);
+    ok(lres == 0, "Got lres %d\n", lres);
+    lres = IExplorerBrowser_Release(peb2);
+    ok(lres == 0, "Got lres %d\n", lres);
+
+    /******************************************/
+    /* Test some options that affect browsing */
+
+    ebrowser_instantiate(&peb);
+    hr = IExplorerBrowser_Advise(peb, (IExplorerBrowserEvents*)&ebev, &cookie);
+    ok(hr == S_OK, "Got 0x%08x\n", hr);
+    hr = IExplorerBrowser_SetOptions(peb, EBO_NAVIGATEONCE);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+    ebrowser_initialize(peb);
+
+    test_browse_pidl(peb, &ebev, pidl_current, 0, S_OK, 1, 1, 0, 1);
+    test_browse_pidl(peb, &ebev, pidl_current, 0, E_FAIL, 0, 0, 0, 0);
+
+    hr = IExplorerBrowser_SetOptions(peb, 0);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+    test_browse_pidl(peb, &ebev, pidl_current, 0, S_OK, 1, 0, 0, 1);
+    test_browse_pidl(peb, &ebev, pidl_current, 0, S_OK, 1, 0, 0, 1);
+
+    /* Difference in behavior lies where? */
+    hr = IExplorerBrowser_SetOptions(peb, EBO_ALWAYSNAVIGATE);
+    ok(hr == S_OK, "got (0x%08x)\n", hr);
+
+    test_browse_pidl(peb, &ebev, pidl_current, 0, S_OK, 1, 0, 0, 1);
+    test_browse_pidl(peb, &ebev, pidl_current, 0, S_OK, 1, 0, 0, 1);
+
+    hr = IExplorerBrowser_Unadvise(peb, cookie);
+    ok(hr == S_OK, "Got 0x%08x\n", hr);
+
+    IExplorerBrowser_Destroy(peb);
+    lres = IExplorerBrowser_Release(peb);
+    ok(lres == 0, "Got lres %d\n", lres);
+
+    /* Cleanup */
+    RemoveDirectoryW(child_path);
+    ILFree(pidl_current);
+    ILFree(pidl_child);
+}
+
 static BOOL test_instantiate_control(void)
 {
     IExplorerBrowser *peb;
@@ -573,12 +837,14 @@ START_TEST(ebrowser)
     }
 
     setup_window();
+    init_function_pointers();
 
     test_QueryInterface();
     test_SB_misc();
     test_initialization();
     test_basics();
     test_Advise();
+    test_navigation();
 
     DestroyWindow(hwnd);
     OleUninitialize();
-- 
1.7.2




More information about the wine-patches mailing list