/*
 * ExplorerBrowser Control implementation.
 *
 * Copyright 2010 David Hedberg
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "winerror.h"
#include "windef.h"
#include "winbase.h"

#include "wine/list.h"
#include "wine/debug.h"
#include "debughlp.h"

#include "shell32_main.h"
#include "pidl.h"

WINE_DEFAULT_DEBUG_CHANNEL(shell);

#define SPLITTER_WIDTH 2
#define NP_MIN_WIDTH 60
#define SV_MIN_WIDTH 150

typedef struct _event_client {
    struct list entry;
    IExplorerBrowserEvents *pebe;
    DWORD cookie;
} event_client;

typedef struct _travellog_entry {
    struct list entry;
    LPITEMIDLIST pidl;
} travellog_entry;

typedef struct _ExplorerBrowserImpl {
    IExplorerBrowser  IExplorerBrowser_iface;
    IShellBrowser     IShellBrowser_iface;
    ICommDlgBrowser3  ICommDlgBrowser3_iface;
    IObjectWithSite   IObjectWithSite_iface;
    INameSpaceTreeControlEvents INameSpaceTreeControlEvents_iface;
    IInputObject      IInputObject_iface;
    LONG ref;
    BOOL destroyed;

    HWND hwnd_main;
    HWND hwnd_sv;

    RECT splitter_rc;
    struct {
        INameSpaceTreeControl2 *pnstc2;
        HWND hwnd_splitter, hwnd_nstc;
        DWORD nstc_cookie;
        UINT width;
        BOOL show;
        RECT rc;
    } navpane;

    EXPLORER_BROWSER_OPTIONS eb_options;
    FOLDERSETTINGS fs;

    struct list event_clients;
    DWORD events_next_cookie;
    struct list travellog;
    travellog_entry *travellog_cursor;
    int travellog_count;

    IShellView *psv;
    RECT sv_rc;
    LPITEMIDLIST current_pidl;

    IUnknown *punk_site;
    ICommDlgBrowser *pcdb_site;
    ICommDlgBrowser2 *pcdb2_site;
    ICommDlgBrowser3 *pcdb3_site;
    IExplorerPaneVisibility *pepv_site;
} ExplorerBrowserImpl;

static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc);

/**************************************************************************
 * 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);
    }
}

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);
    }
}

/**************************************************************************
 * Travellog functions.
 */
static void travellog_remove_entry(ExplorerBrowserImpl *This, travellog_entry *entry)
{
    TRACE("Removing %p\n", entry);

    list_remove(&entry->entry);
    HeapFree(GetProcessHeap(), 0, entry);
    This->travellog_count--;
}

static void travellog_remove_all_entries(ExplorerBrowserImpl *This)
{
    travellog_entry *cursor, *cursor2;
    TRACE("%p\n", This);

    LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
        travellog_remove_entry(This, cursor);

    This->travellog_cursor = NULL;
}

static void travellog_add_entry(ExplorerBrowserImpl *This, LPITEMIDLIST pidl)
{
    travellog_entry *new, *cursor, *cursor2;
    TRACE("%p (old count %d)\n", pidl, This->travellog_count);

    /* Replace the old tail, if any, with the new entry */
    if(This->travellog_cursor)
    {
        LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, &This->travellog, travellog_entry, entry)
        {
            if(cursor == This->travellog_cursor)
                break;
            travellog_remove_entry(This, cursor);
        }
    }

    /* Create and add the new entry */
    new = HeapAlloc(GetProcessHeap(), 0, sizeof(travellog_entry));
    new->pidl = ILClone(pidl);
    list_add_tail(&This->travellog, &new->entry);
    This->travellog_cursor = new;
    This->travellog_count++;

    /* Remove the first few entries if the size limit is reached. */
    if(This->travellog_count > 200)
    {
        UINT i = 0;
        LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
        {
            if(i++ > 10)
                break;
            travellog_remove_entry(This, cursor);
        }
    }
}

static LPCITEMIDLIST travellog_go_back(ExplorerBrowserImpl *This)
{
    travellog_entry *prev;
    TRACE("%p, %p\n", This, This->travellog_cursor);

    if(!This->travellog_cursor)
        return NULL;

    prev = LIST_ENTRY(list_prev(&This->travellog, &This->travellog_cursor->entry),
                      travellog_entry, entry);
    if(!prev)
        return NULL;

    This->travellog_cursor = prev;
    return prev->pidl;
}

static LPCITEMIDLIST travellog_go_forward(ExplorerBrowserImpl *This)
{
    travellog_entry *next;
    TRACE("%p, %p\n", This, This->travellog_cursor);

    if(!This->travellog_cursor)
        return NULL;

    next = LIST_ENTRY(list_next(&This->travellog, &This->travellog_cursor->entry),
                      travellog_entry, entry);
    if(!next)
        return NULL;

    This->travellog_cursor = next;
    return next->pidl;
}

/**************************************************************************
 * Helper functions
 */
static void update_layout(ExplorerBrowserImpl *This)
{
    RECT rc;
    INT navpane_width_actual;
    INT shellview_width_actual;
    TRACE("%p (navpane: %d, EBO_SHOWFRAMES: %d)\n",
          This, This->navpane.show, This->eb_options & EBO_SHOWFRAMES);

    GetClientRect(This->hwnd_main, &rc);

    if((This->eb_options & EBO_SHOWFRAMES) && This->navpane.show)
        navpane_width_actual = This->navpane.width;
    else
        navpane_width_actual = 0;

    shellview_width_actual = rc.right - navpane_width_actual;
    if(shellview_width_actual < SV_MIN_WIDTH && navpane_width_actual)
    {
        INT missing_width = SV_MIN_WIDTH - shellview_width_actual;
        if(missing_width < (navpane_width_actual - NP_MIN_WIDTH))
        {
            /* Shrink the navpane */
            navpane_width_actual -= missing_width;
            shellview_width_actual += missing_width;
        }
        else
        {
            /* Hide the navpane */
            shellview_width_actual += navpane_width_actual;
            navpane_width_actual = 0;
        }
    }

    /**************************************************************
     *  Calculate rectangles for the panes. All rectangles contain
     *  the position of the panes relative to hwnd_main.
     */

    if(navpane_width_actual)
    {
        This->navpane.rc.left = This->navpane.rc.top = 0;
        This->navpane.rc.right = navpane_width_actual;
        This->navpane.rc.bottom = rc.bottom;

        if(!This->navpane.hwnd_splitter)
            initialize_navpane(This, This->hwnd_main, &This->navpane.rc);
    }
    else
        ZeroMemory(&This->navpane.rc, sizeof(RECT));

    This->sv_rc.left   = navpane_width_actual;
    This->sv_rc.top    = 0;
    This->sv_rc.right  = This->sv_rc.left + shellview_width_actual;
    This->sv_rc.bottom = rc.bottom;
}

static void size_panes(ExplorerBrowserImpl *This)
{
    MoveWindow(This->navpane.hwnd_splitter,
               This->navpane.rc.right - SPLITTER_WIDTH, This->navpane.rc.top,
               SPLITTER_WIDTH, This->navpane.rc.bottom - This->navpane.rc.top,
               TRUE);

    MoveWindow(This->hwnd_sv,
               This->sv_rc.left, This->sv_rc.top,
               This->sv_rc.right - This->sv_rc.left, This->sv_rc.bottom - This->sv_rc.top,
               TRUE);
}

static HRESULT change_viewmode(ExplorerBrowserImpl *This, UINT viewmode)
{
    IFolderView *pfv;
    HRESULT hr;

    if(!This->psv)
        return E_FAIL;

    hr = IShellView_QueryInterface(This->psv, &IID_IFolderView, (void*)&pfv);
    if(SUCCEEDED(hr))
    {
        hr = IFolderView_SetCurrentViewMode(pfv, This->fs.ViewMode);
        IFolderView_Release(pfv);
    }

    return hr;
}

static HRESULT create_new_shellview(ExplorerBrowserImpl *This, IShellItem *psi)
{
    IShellBrowser *psb = &This->IShellBrowser_iface;
    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;
}

static void get_interfaces_from_site(ExplorerBrowserImpl *This)
{
    IServiceProvider *psp;
    HRESULT hr;

    /* Calling this with This->punk_site set to NULL should properly
     * release any previously fetched interfaces.
     */

    if(This->pcdb_site)
    {
        IUnknown_Release(This->pcdb_site);
        if(This->pcdb2_site) IUnknown_Release(This->pcdb2_site);
        if(This->pcdb3_site) IUnknown_Release(This->pcdb3_site);

        This->pcdb_site = NULL;
        This->pcdb2_site = NULL;
        This->pcdb3_site = NULL;
    }

    if(This->pepv_site)
    {
        IExplorerPaneVisibility_Release(This->pepv_site);
        This->pepv_site = NULL;
    }

    if(!This->punk_site)
        return;

    hr = IUnknown_QueryInterface(This->punk_site, &IID_IServiceProvider, (void**)&psp);
    if(FAILED(hr))
    {
        ERR("Failed to get IServiceProvider from site.\n");
        return;
    }

    /* ICommDlgBrowser */
    IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser,
                                  (void**)&This->pcdb_site);
    IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser2,
                                  (void**)&This->pcdb2_site);
    IServiceProvider_QueryService(psp, &SID_SExplorerBrowserFrame, &IID_ICommDlgBrowser3,
                                  (void**)&This->pcdb3_site);

    /* IExplorerPaneVisibility */
    IServiceProvider_QueryService(psp, &SID_ExplorerPaneVisibility, &IID_IExplorerPaneVisibility,
                                  (void**)&This->pepv_site);

    IServiceProvider_Release(psp);
}

/**************************************************************************
 * General pane functionality.
 */
static void update_panestate(ExplorerBrowserImpl *This)
{
    EXPLORERPANESTATE eps = EPS_DONTCARE;
    BOOL show_navpane;
    TRACE("%p\n", This);

    if(!This->pepv_site) return;

    IExplorerPaneVisibility_GetPaneState(This->pepv_site, (REFEXPLORERPANE) &EP_NavPane, &eps);
    if( !(eps & EPS_DEFAULT_OFF) )
        show_navpane = TRUE;
    else
        show_navpane = FALSE;

    if(This->navpane.show != show_navpane)
    {
        update_layout(This);
        size_panes(This);
    }

    This->navpane.show = show_navpane;
}

static void splitter_draw(HWND hwnd, RECT *rc)
{
    HDC hdc = GetDC(hwnd);
    InvertRect(hdc, rc);
    ReleaseDC(hwnd, hdc);
}

/**************************************************************************
 * The Navigation Pane.
 */
static LRESULT navpane_splitter_beginresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
{
    TRACE("\n");

    SetCapture(hwnd);

    CopyRect(&This->splitter_rc, &This->navpane.rc);
    This->splitter_rc.left = This->splitter_rc.right - SPLITTER_WIDTH;

    splitter_draw(GetParent(hwnd), &This->splitter_rc);

    return TRUE;
}

static LRESULT navpane_splitter_resizing(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
{
    int new_width, dx;
    RECT rc;

    if(GetCapture() != hwnd) return FALSE;

    dx = (SHORT)LOWORD(lParam);
    TRACE("%d.\n", dx);

    CopyRect(&rc, &This->navpane.rc);

    new_width = This->navpane.width + dx;
    if(new_width > NP_MIN_WIDTH && This->sv_rc.right - new_width > SV_MIN_WIDTH)
    {
        rc.right = new_width;
        rc.left = rc.right - SPLITTER_WIDTH;
        splitter_draw(GetParent(hwnd), &This->splitter_rc);
        splitter_draw(GetParent(hwnd), &rc);
        CopyRect(&This->splitter_rc, &rc);
    }

    return TRUE;
}

static LRESULT navpane_splitter_endresize(ExplorerBrowserImpl *This, HWND hwnd, LPARAM lParam)
{
    int new_width, dx;

    if(GetCapture() != hwnd) return FALSE;

    dx = (SHORT)LOWORD(lParam);
    TRACE("%d.\n", dx);

    splitter_draw(GetParent(hwnd), &This->splitter_rc);

    new_width = This->navpane.width + dx;
    if(new_width < NP_MIN_WIDTH)
        new_width = NP_MIN_WIDTH;
    else if(This->sv_rc.right - new_width < SV_MIN_WIDTH)
        new_width = This->sv_rc.right - SV_MIN_WIDTH;

    This->navpane.width = new_width;

    update_layout(This);
    size_panes(This);

    ReleaseCapture();

    return TRUE;
}

static LRESULT navpane_on_wm_create(HWND hwnd, CREATESTRUCTW *crs)
{
    ExplorerBrowserImpl *This = crs->lpCreateParams;
    INameSpaceTreeControl2 *pnstc2;
    DWORD style;
    HRESULT hr;

    TRACE("%p\n", This);
    SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
    This->navpane.hwnd_splitter = hwnd;

    hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
                          &IID_INameSpaceTreeControl2, (void**)&pnstc2);

    if(SUCCEEDED(hr))
    {
        style = NSTCS_HASEXPANDOS | NSTCS_ROOTHASEXPANDO | NSTCS_SHOWSELECTIONALWAYS;
        hr = INameSpaceTreeControl2_Initialize(pnstc2, GetParent(hwnd), NULL, style);
        if(SUCCEEDED(hr))
        {
            INameSpaceTreeControlEvents *pnstce;
            IShellFolder *psfdesktop;
            IShellItem *psi;
            IOleWindow *pow;
            LPITEMIDLIST pidl;
            DWORD cookie, style2 = NSTCS2_DISPLAYPADDING;

            hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFF, style2);
            if(FAILED(hr))
                ERR("SetControlStyle2 failed (0x%08x)\n", hr);

            hr = INameSpaceTreeControl2_QueryInterface(pnstc2, &IID_IOleWindow, (void**)&pow);
            if(SUCCEEDED(hr))
            {
                IOleWindow_GetWindow(pow, &This->navpane.hwnd_nstc);
                IOleWindow_Release(pow);
            }
            else
                ERR("QueryInterface(IOleWindow) failed (0x%08x)\n", hr);

            pnstce = &This->INameSpaceTreeControlEvents_iface;
            hr = INameSpaceTreeControl2_TreeAdvise(pnstc2, (IUnknown*)pnstce, &cookie);
            if(FAILED(hr))
                ERR("TreeAdvise failed. (0x%08x).\n", hr);

            /*
             * Add the default roots
             */

            /* TODO: This should be FOLDERID_Links */
            hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
            if(SUCCEEDED(hr))
            {
                hr = SHCreateShellItem(NULL, NULL, pidl, &psi);
                if(SUCCEEDED(hr))
                {
                    hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_NONFOLDERS, NSTCRS_VISIBLE, NULL);
                    IShellItem_Release(psi);
                }
                ILFree(pidl);
            }

            SHGetDesktopFolder(&psfdesktop);
            hr = SHGetItemFromObject((IUnknown*)psfdesktop, &IID_IShellItem, (void**)&psi);
            IShellFolder_Release(psfdesktop);
            if(SUCCEEDED(hr))
            {
                hr = INameSpaceTreeControl2_AppendRoot(pnstc2, psi, SHCONTF_FOLDERS, NSTCRS_EXPANDED, NULL);
                IShellItem_Release(psi);
            }

            /* TODO:
             * We should advertise IID_INameSpaceTreeControl to the site of the
             * host through its IProfferService interface, if any.
             */

            This->navpane.pnstc2 = pnstc2;
            This->navpane.nstc_cookie = cookie;

            return TRUE;
        }
    }

    This->navpane.pnstc2 = NULL;
    ERR("Failed (0x%08x)\n", hr);

    return FALSE;
}

static LRESULT navpane_on_wm_size_move(ExplorerBrowserImpl *This)
{
    UINT height, width;
    TRACE("%p\n", This);

    width = This->navpane.rc.right - This->navpane.rc.left - SPLITTER_WIDTH;
    height = This->navpane.rc.bottom - This->navpane.rc.top;

    MoveWindow(This->navpane.hwnd_nstc,
               This->navpane.rc.left, This->navpane.rc.top,
               width, height,
               TRUE);

    return FALSE;
}

static LRESULT navpane_on_wm_destroy(ExplorerBrowserImpl *This)
{
    INameSpaceTreeControl_TreeUnadvise(This->navpane.pnstc2, This->navpane.nstc_cookie);
    INameSpaceTreeControl_Release(This->navpane.pnstc2);
    This->navpane.pnstc2 = NULL;
    return TRUE;
}

static LRESULT CALLBACK navpane_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
    ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);

    switch(uMessage) {
    case WM_CREATE:           return navpane_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
    case WM_MOVE:             /* Fall through */
    case WM_SIZE:             return navpane_on_wm_size_move(This);
    case WM_DESTROY:          return navpane_on_wm_destroy(This);
    case WM_LBUTTONDOWN:      return navpane_splitter_beginresize(This, hWnd, lParam);
    case WM_MOUSEMOVE:        return navpane_splitter_resizing(This, hWnd, lParam);
    case WM_LBUTTONUP:        return navpane_splitter_endresize(This, hWnd, lParam);
    default:
        return DefWindowProcW(hWnd, uMessage, wParam, lParam);
    }
    return 0;
}

static void initialize_navpane(ExplorerBrowserImpl *This, HWND hwnd_parent, RECT *rc)
{
    WNDCLASSW wc;
    HWND splitter;
    static const WCHAR navpane_classname[] = {'e','b','_','n','a','v','p','a','n','e',0};

    if( !GetClassInfoW(shell32_hInstance, navpane_classname, &wc) )
    {
        wc.style            = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc      = navpane_wndproc;
        wc.cbClsExtra       = 0;
        wc.cbWndExtra       = 0;
        wc.hInstance        = shell32_hInstance;
        wc.hIcon            = 0;
        wc.hCursor          = LoadCursorW(0, (LPWSTR)IDC_SIZEWE);
        wc.hbrBackground    = (HBRUSH)(COLOR_HIGHLIGHT + 1);
        wc.lpszMenuName     = NULL;
        wc.lpszClassName    = navpane_classname;

        if (!RegisterClassW(&wc)) return;
    }

    splitter = CreateWindowExW(0, navpane_classname, NULL,
                               WS_CHILD | WS_TABSTOP | WS_VISIBLE,
                               rc->right - SPLITTER_WIDTH, rc->top,
                               SPLITTER_WIDTH, rc->bottom - rc->top,
                               hwnd_parent, 0, shell32_hInstance, This);
    if(!splitter)
        ERR("Failed to create navpane : %d.\n", GetLastError());
}

/**************************************************************************
 * Main window related functions.
 */
static LRESULT main_on_wm_create(HWND hWnd, CREATESTRUCTW *crs)
{
    ExplorerBrowserImpl *This = crs->lpCreateParams;
    TRACE("%p\n", This);

    SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LPARAM)This);
    This->hwnd_main = hWnd;

    return TRUE;
}

static LRESULT main_on_wm_size(ExplorerBrowserImpl *This)
{
    update_layout(This);
    size_panes(This);

    return TRUE;
}

static LRESULT CALLBACK main_wndproc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
    ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);

    switch(uMessage)
    {
    case WM_CREATE:           return main_on_wm_create(hWnd, (CREATESTRUCTW*)lParam);
    case WM_SIZE:             return main_on_wm_size(This);
    default:                  return DefWindowProcW(hWnd, uMessage, wParam, lParam);
    }

    return 0;
}

/**************************************************************************
 * IExplorerBrowser Implementation
 */

static inline ExplorerBrowserImpl *impl_from_IExplorerBrowser(IExplorerBrowser *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IExplorerBrowser_iface);
}

static HRESULT WINAPI IExplorerBrowser_fnQueryInterface(IExplorerBrowser *iface,
                                                        REFIID riid, void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);

    *ppvObject = NULL;
    if(IsEqualIID(riid, &IID_IExplorerBrowser) ||
       IsEqualIID(riid, &IID_IUnknown))
    {
        *ppvObject = This;
    }
    else if(IsEqualIID(riid, &IID_IShellBrowser))
    {
        *ppvObject = &This->IShellBrowser_iface;
    }
    else if(IsEqualIID(riid, &IID_ICommDlgBrowser) ||
            IsEqualIID(riid, &IID_ICommDlgBrowser2) ||
            IsEqualIID(riid, &IID_ICommDlgBrowser3))
    {
        *ppvObject = &This->ICommDlgBrowser3_iface;
    }
    else if(IsEqualIID(riid, &IID_IObjectWithSite))
    {
        *ppvObject = &This->IObjectWithSite_iface;
    }
    else if(IsEqualIID(riid, &IID_IInputObject))
    {
        *ppvObject = &This->IInputObject_iface;
    }

    if(*ppvObject)
    {
        IUnknown_AddRef((IUnknown*)*ppvObject);
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI IExplorerBrowser_fnAddRef(IExplorerBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    LONG ref = InterlockedIncrement(&This->ref);
    TRACE("%p - ref %d\n", This, ref);

    return ref;
}

static ULONG WINAPI IExplorerBrowser_fnRelease(IExplorerBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    LONG ref = InterlockedDecrement(&This->ref);
    TRACE("%p - ref %d\n", This, ref);

    if(!ref)
    {
        TRACE("Freeing.\n");

        if(!This->destroyed)
            IExplorerBrowser_Destroy(iface);

        IObjectWithSite_SetSite(&This->IObjectWithSite_iface, NULL);

        HeapFree(GetProcessHeap(), 0, This);
        return 0;
    }

    return ref;
}

static HRESULT WINAPI IExplorerBrowser_fnInitialize(IExplorerBrowser *iface,
                                                    HWND hwndParent, const RECT *prc,
                                                    const FOLDERSETTINGS *pfs)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    WNDCLASSW wc;
    LONG style;
    static const WCHAR EB_CLASS_NAME[] =
        {'E','x','p','l','o','r','e','r','B','r','o','w','s','e','r','C','o','n','t','r','o','l',0};

    TRACE("%p (%p, %p, %p)\n", This, hwndParent, prc, pfs);

    if(This->hwnd_main)
        return E_UNEXPECTED;

    if(!hwndParent)
        return E_INVALIDARG;

    if( !GetClassInfoW(shell32_hInstance, EB_CLASS_NAME, &wc) )
    {
        wc.style            = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc      = main_wndproc;
        wc.cbClsExtra       = 0;
        wc.cbWndExtra       = 0;
        wc.hInstance        = shell32_hInstance;
        wc.hIcon            = 0;
        wc.hCursor          = LoadCursorW(0, (LPWSTR)IDC_ARROW);
        wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1);
        wc.lpszMenuName     = NULL;
        wc.lpszClassName    = EB_CLASS_NAME;

        if (!RegisterClassW(&wc)) return E_FAIL;
    }

    style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER;
    This->hwnd_main = CreateWindowExW(WS_EX_CONTROLPARENT, EB_CLASS_NAME, NULL, style,
                                      prc->left, prc->top,
                                      prc->right - prc->left, prc->bottom - prc->top,
                                      hwndParent, 0, shell32_hInstance, This);

    if(!This->hwnd_main)
    {
        ERR("Failed to create the window.\n");
        return E_FAIL;
    }

    This->fs.ViewMode = pfs ? pfs->ViewMode : FVM_DETAILS;
    This->fs.fFlags = pfs ? (pfs->fFlags | FWF_NOCLIENTEDGE) : FWF_NOCLIENTEDGE;

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p\n", This);

    if(This->psv)
    {
        IShellView_DestroyViewWindow(This->psv);
        IShellView_Release(This->psv);
        This->psv = NULL;
        This->hwnd_sv = NULL;
    }

    events_unadvise_all(This);
    travellog_remove_all_entries(This);

    ILFree(This->current_pidl);
    This->current_pidl = NULL;

    DestroyWindow(This->hwnd_main);
    This->destroyed = TRUE;

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnSetRect(IExplorerBrowser *iface,
                                                 HDWP *phdwp, RECT rcBrowser)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p (%p, %s)\n", This, phdwp, wine_dbgstr_rect(&rcBrowser));

    if(phdwp && *phdwp)
    {
        *phdwp = DeferWindowPos(*phdwp, This->hwnd_main, NULL, rcBrowser.left, rcBrowser.top,
                                rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top,
                                SWP_NOZORDER | SWP_NOACTIVATE);
        if(!*phdwp)
            return E_FAIL;
    }
    else
    {
        MoveWindow(This->hwnd_main, rcBrowser.left, rcBrowser.top,
                   rcBrowser.right - rcBrowser.left, rcBrowser.bottom - rcBrowser.top, TRUE);
    }

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnSetPropertyBag(IExplorerBrowser *iface,
                                                        LPCWSTR pszPropertyBag)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    FIXME("stub, %p (%s)\n", This, debugstr_w(pszPropertyBag));

    if(!pszPropertyBag)
        return E_INVALIDARG;

    /* FIXME: This method is currently useless as we don't save any
     * settings anywhere, but at least one application breaks if we
     * return E_NOTIMPL.
     */

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnSetEmptyText(IExplorerBrowser *iface,
                                                      LPCWSTR pszEmptyText)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    FIXME("stub, %p (%s)\n", This, debugstr_w(pszEmptyText));

    return E_NOTIMPL;
}

static HRESULT WINAPI IExplorerBrowser_fnSetFolderSettings(IExplorerBrowser *iface,
                                                           const FOLDERSETTINGS *pfs)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p (%p)\n", This, pfs);

    if(!pfs)
        return E_INVALIDARG;

    This->fs.ViewMode = pfs->ViewMode;
    This->fs.fFlags = pfs->fFlags | FWF_NOCLIENTEDGE;

    /* Change the settings of the current view, if any. */
    return change_viewmode(This, This->fs.ViewMode);
}

static HRESULT WINAPI IExplorerBrowser_fnAdvise(IExplorerBrowser *iface,
                                                IExplorerBrowserEvents *psbe,
                                                DWORD *pdwCookie)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    event_client *client;
    TRACE("%p (%p, %p)\n", This, psbe, pdwCookie);

    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 = impl_from_IExplorerBrowser(iface);
    event_client *client;
    TRACE("%p (0x%x)\n", This, dwCookie);

    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,
                                                    EXPLORER_BROWSER_OPTIONS dwFlag)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    static const EXPLORER_BROWSER_OPTIONS unsupported_options =
        EBO_ALWAYSNAVIGATE | EBO_NOWRAPPERWINDOW | EBO_HTMLSHAREPOINTVIEW;

    TRACE("%p (0x%x)\n", This, dwFlag);

    if(dwFlag & unsupported_options)
        FIXME("Flags 0x%08x contains unsupported options.\n", dwFlag);

    This->eb_options = dwFlag;

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
                                                    EXPLORER_BROWSER_OPTIONS *pdwFlag)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p (%p)\n", This, pdwFlag);

    *pdwFlag = This->eb_options;

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
                                                        PCUIDLIST_RELATIVE pidl,
                                                        UINT uFlags)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    LPITEMIDLIST absolute_pidl = NULL;
    HRESULT hr;
    static const UINT unsupported_browse_flags =
        SBSP_NEWBROWSER | EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
    TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);

    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_NAVIGATEBACK)
    {
        TRACE("SBSP_NAVIGATEBACK\n");
        absolute_pidl = ILClone(travellog_go_back(This));
        if(!absolute_pidl && !This->current_pidl)
            return E_FAIL;
        else if(!absolute_pidl)
            return S_OK;

    }
    else if(uFlags & SBSP_NAVIGATEFORWARD)
    {
        TRACE("SBSP_NAVIGATEFORWARD\n");
        absolute_pidl = ILClone(travellog_go_forward(This));
        if(!absolute_pidl && !This->current_pidl)
            return E_FAIL;
        else if(!absolute_pidl)
            return S_OK;

    }
    else 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;
    }

    get_interfaces_from_site(This);
    update_panestate(This);

    /* 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;
            }

            /* Add to travellog */
            if( !(This->eb_options & EBO_NOTRAVELLOG) &&
                !(uFlags & (SBSP_NAVIGATEFORWARD|SBSP_NAVIGATEBACK)) )
            {
                travellog_add_entry(This, absolute_pidl);
            }

            IShellItem_Release(psi);
        }
    }

    events_NavigationComplete(This, absolute_pidl);
    ILFree(This->current_pidl);
    This->current_pidl = absolute_pidl;

    /* Expand the NameSpaceTree to the current location. */
    if(This->navpane.show && This->navpane.pnstc2)
    {
        IShellItem *psi;
        hr = SHCreateItemFromIDList(This->current_pidl, &IID_IShellItem, (void**)&psi);
        if(SUCCEEDED(hr))
        {
            INameSpaceTreeControl_EnsureItemVisible(This->navpane.pnstc2, psi);
            IShellItem_Release(psi);
        }
    }

    return S_OK;
}

static HRESULT WINAPI IExplorerBrowser_fnBrowseToObject(IExplorerBrowser *iface,
                                                        IUnknown *punk, UINT uFlags)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    LPITEMIDLIST pidl;
    HRESULT hr;
    TRACE("%p (%p, 0x%x)\n", This, punk, uFlags);

    if(!punk)
        return IExplorerBrowser_fnBrowseToIDList(iface, NULL, uFlags);

    hr = SHGetIDListFromObject(punk, &pidl);
    if(SUCCEEDED(hr))
    {
        hr = IExplorerBrowser_BrowseToIDList(iface, pidl, uFlags);
        ILFree(pidl);
    }

    return hr;
}

static HRESULT WINAPI IExplorerBrowser_fnFillFromObject(IExplorerBrowser *iface,
                                                        IUnknown *punk,
                                                        EXPLORER_BROWSER_FILL_FLAGS dwFlags)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    FIXME("stub, %p (%p, 0x%x)\n", This, punk, dwFlags);

    return E_NOTIMPL;
}

static HRESULT WINAPI IExplorerBrowser_fnRemoveAll(IExplorerBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    FIXME("stub, %p\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI IExplorerBrowser_fnGetCurrentView(IExplorerBrowser *iface,
                                                        REFIID riid, void **ppv)
{
    ExplorerBrowserImpl *This = impl_from_IExplorerBrowser(iface);
    TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppv);

    if(!This->psv)
        return E_FAIL;

    return IShellView_QueryInterface(This->psv, riid, ppv);
}

static const IExplorerBrowserVtbl vt_IExplorerBrowser =
{
    IExplorerBrowser_fnQueryInterface,
    IExplorerBrowser_fnAddRef,
    IExplorerBrowser_fnRelease,
    IExplorerBrowser_fnInitialize,
    IExplorerBrowser_fnDestroy,
    IExplorerBrowser_fnSetRect,
    IExplorerBrowser_fnSetPropertyBag,
    IExplorerBrowser_fnSetEmptyText,
    IExplorerBrowser_fnSetFolderSettings,
    IExplorerBrowser_fnAdvise,
    IExplorerBrowser_fnUnadvise,
    IExplorerBrowser_fnSetOptions,
    IExplorerBrowser_fnGetOptions,
    IExplorerBrowser_fnBrowseToIDList,
    IExplorerBrowser_fnBrowseToObject,
    IExplorerBrowser_fnFillFromObject,
    IExplorerBrowser_fnRemoveAll,
    IExplorerBrowser_fnGetCurrentView
};

/**************************************************************************
 * IShellBrowser Implementation
 */

static inline ExplorerBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IShellBrowser_iface);
}

static HRESULT WINAPI IShellBrowser_fnQueryInterface(IShellBrowser *iface,
                                                     REFIID riid, void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p\n", This);
    return IUnknown_QueryInterface((IUnknown*) This, riid, ppvObject);
}

static ULONG WINAPI IShellBrowser_fnAddRef(IShellBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p\n", This);
    return IUnknown_AddRef((IUnknown*) This);
}

static ULONG WINAPI IShellBrowser_fnRelease(IShellBrowser *iface)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p\n", This);
    return IUnknown_Release((IUnknown*) This);
}

static HRESULT WINAPI IShellBrowser_fnGetWindow(IShellBrowser *iface, HWND *phwnd)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p)\n", This, phwnd);

    if(!This->hwnd_main)
        return E_FAIL;

    *phwnd = This->hwnd_main;
    return S_OK;
}

static HRESULT WINAPI IShellBrowser_fnContextSensitiveHelp(IShellBrowser *iface,
                                                           BOOL fEnterMode)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%d)\n", This, fEnterMode);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnInsertMenusSB(IShellBrowser *iface,
                                                    HMENU hmenuShared,
                                                    LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p, %p)\n", This, hmenuShared, lpMenuWidths);

    /* Not implemented. */
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnSetMenuSB(IShellBrowser *iface,
                                                HMENU hmenuShared,
                                                HOLEMENU holemenuReserved,
                                                HWND hwndActiveObject)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p, %p, %p)\n", This, hmenuShared, holemenuReserved, hwndActiveObject);

    /* Not implemented. */
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnRemoveMenusSB(IShellBrowser *iface,
                                                    HMENU hmenuShared)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p)\n", This, hmenuShared);

    /* Not implemented. */
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnSetStatusTextSB(IShellBrowser *iface,
                                                      LPCOLESTR pszStatusText)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%s)\n", This, debugstr_w(pszStatusText));

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnEnableModelessSB(IShellBrowser *iface,
                                                       BOOL fEnable)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%d)\n", This, fEnable);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnTranslateAcceleratorSB(IShellBrowser *iface,
                                                             MSG *pmsg, WORD wID)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%p, 0x%x)\n", This, pmsg, wID);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnBrowseObject(IShellBrowser *iface,
                                                   LPCITEMIDLIST pidl, UINT wFlags)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p, %x)\n", This, pidl, wFlags);

    return IExplorerBrowser_fnBrowseToIDList((IExplorerBrowser*)This, pidl, wFlags);
}

static HRESULT WINAPI IShellBrowser_fnGetViewStateStream(IShellBrowser *iface,
                                                         DWORD grfMode,
                                                         IStream **ppStrm)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (0x%x, %p)\n", This, grfMode, ppStrm);

    *ppStrm = NULL;
    return E_FAIL;
}

static HRESULT WINAPI IShellBrowser_fnGetControlWindow(IShellBrowser *iface,
                                                       UINT id, HWND *phwnd)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%d, %p)\n", This, id, phwnd);

    /* Not implemented. */
    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnSendControlMsg(IShellBrowser *iface,
                                                     UINT id, UINT uMsg,
                                                     WPARAM wParam, LPARAM lParam,
                                                     LRESULT *pret)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%d, %d, %lx, %lx, %p)\n", This, id, uMsg, wParam, lParam, pret);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnQueryActiveShellView(IShellBrowser *iface,
                                                           IShellView **ppshv)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    TRACE("%p (%p)\n", This, ppshv);

    if(!This->psv)
        return E_FAIL;

    *ppshv = This->psv;
    IShellView_AddRef(This->psv);

    return S_OK;
}

static HRESULT WINAPI IShellBrowser_fnOnViewWindowActive(IShellBrowser *iface,
                                                         IShellView *pshv)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%p)\n", This, pshv);

    return E_NOTIMPL;
}

static HRESULT WINAPI IShellBrowser_fnSetToolbarItems(IShellBrowser *iface,
                                                      LPTBBUTTONSB lpButtons,
                                                      UINT nButtons, UINT uFlags)
{
    ExplorerBrowserImpl *This = impl_from_IShellBrowser(iface);
    FIXME("stub, %p (%p, %d, 0x%x)\n", This, lpButtons, nButtons, uFlags);

    return E_NOTIMPL;
}

static const IShellBrowserVtbl vt_IShellBrowser = {
    IShellBrowser_fnQueryInterface,
    IShellBrowser_fnAddRef,
    IShellBrowser_fnRelease,
    IShellBrowser_fnGetWindow,
    IShellBrowser_fnContextSensitiveHelp,
    IShellBrowser_fnInsertMenusSB,
    IShellBrowser_fnSetMenuSB,
    IShellBrowser_fnRemoveMenusSB,
    IShellBrowser_fnSetStatusTextSB,
    IShellBrowser_fnEnableModelessSB,
    IShellBrowser_fnTranslateAcceleratorSB,
    IShellBrowser_fnBrowseObject,
    IShellBrowser_fnGetViewStateStream,
    IShellBrowser_fnGetControlWindow,
    IShellBrowser_fnSendControlMsg,
    IShellBrowser_fnQueryActiveShellView,
    IShellBrowser_fnOnViewWindowActive,
    IShellBrowser_fnSetToolbarItems
};

/**************************************************************************
 * ICommDlgBrowser3 Implementation
 */

static inline ExplorerBrowserImpl *impl_from_ICommDlgBrowser3(ICommDlgBrowser3 *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, ICommDlgBrowser3_iface);
}

static HRESULT WINAPI ICommDlgBrowser3_fnQueryInterface(ICommDlgBrowser3 *iface,
                                                        REFIID riid,
                                                        void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p\n", This);
    return IUnknown_QueryInterface((IUnknown*) This, riid, ppvObject);
}

static ULONG WINAPI ICommDlgBrowser3_fnAddRef(ICommDlgBrowser3 *iface)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p\n", This);
    return IUnknown_AddRef((IUnknown*) This);
}

static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p\n", This);
    return IUnknown_Release((IUnknown*) This);
}

static HRESULT WINAPI ICommDlgBrowser3_fnOnDefaultCommand(ICommDlgBrowser3 *iface,
                                                          IShellView *shv)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    IDataObject *pdo;
    HRESULT hr;
    HRESULT ret = S_FALSE;

    TRACE("%p (%p)\n", This, shv);

    hr = IShellView_GetItemObject(shv, SVGIO_SELECTION, &IID_IDataObject, (void**)&pdo);
    if(SUCCEEDED(hr))
    {
        FORMATETC fmt;
        STGMEDIUM medium;

        fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
        fmt.ptd = NULL;
        fmt.dwAspect = DVASPECT_CONTENT;
        fmt.lindex = -1;
        fmt.tymed = TYMED_HGLOBAL;

        hr = IDataObject_GetData(pdo, &fmt ,&medium);
        IDataObject_Release(pdo);
        if(SUCCEEDED(hr))
        {
            LPIDA pida = GlobalLock(medium.u.hGlobal);
            LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);

            /* Handle folders by browsing to them. */
            if(_ILIsFolder(pidl_child) || _ILIsDrive(pidl_child) || _ILIsSpecialFolder(pidl_child))
            {
                IExplorerBrowser_BrowseToIDList((IExplorerBrowser*)This, pidl_child, SBSP_RELATIVE);
                ret = S_OK;
            }
            GlobalUnlock(medium.u.hGlobal);
            GlobalFree(medium.u.hGlobal);
        }
        else
            ERR("Failed to get data from IDataObject.\n");
    } else
        ERR("Failed to get IDataObject.\n");

    /* If we didn't handle the default command, check if we have a
     * client that does */
    if(ret == S_FALSE && This->pcdb_site)
        return ICommDlgBrowser_OnDefaultCommand(This->pcdb_site, shv);

    return ret;
}
static HRESULT WINAPI ICommDlgBrowser3_fnOnStateChange(ICommDlgBrowser3 *iface,
                                                       IShellView *shv, ULONG uChange)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p, %d)\n", This, shv, uChange);

    if(This->pcdb_site)
        return ICommDlgBrowser_OnStateChange(This->pcdb_site, shv, uChange);

    return E_NOTIMPL;
}
static HRESULT WINAPI ICommDlgBrowser3_fnIncludeObject(ICommDlgBrowser3 *iface,
                                                       IShellView *pshv, LPCITEMIDLIST pidl)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p, %p)\n", This, pshv, pidl);

    if(This->pcdb_site)
        return ICommDlgBrowser_IncludeObject(This->pcdb_site, pshv, pidl);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnNotify(ICommDlgBrowser3 *iface,
                                                IShellView *pshv,
                                                DWORD dwNotifyType)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p, 0x%x)\n", This, pshv, dwNotifyType);

    if(This->pcdb2_site)
        return ICommDlgBrowser2_Notify(This->pcdb2_site, pshv, dwNotifyType);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnGetDefaultMenuText(ICommDlgBrowser3 *iface,
                                                            IShellView *pshv,
                                                            LPWSTR pszText, int cchMax)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p, %s, %d)\n", This, pshv, debugstr_w(pszText), cchMax);

    if(This->pcdb2_site)
        return ICommDlgBrowser2_GetDefaultMenuText(This->pcdb2_site, pshv, pszText, cchMax);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnGetViewFlags(ICommDlgBrowser3 *iface,
                                                      DWORD *pdwFlags)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p)\n", This, pdwFlags);

    if(This->pcdb2_site)
        return ICommDlgBrowser2_GetViewFlags(This->pcdb2_site, pdwFlags);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnOnColumnClicked(ICommDlgBrowser3 *iface,
                                                         IShellView *pshv, int iColumn)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p, %d)\n", This, pshv, iColumn);

    if(This->pcdb3_site)
        return ICommDlgBrowser3_OnColumnClicked(This->pcdb3_site, pshv, iColumn);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnGetCurrentFilter(ICommDlgBrowser3 *iface,
                                                          LPWSTR pszFileSpec,
                                                          int cchFileSpec)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%s, %d)\n", This, debugstr_w(pszFileSpec), cchFileSpec);

    if(This->pcdb3_site)
        return ICommDlgBrowser3_GetCurrentFilter(This->pcdb3_site, pszFileSpec, cchFileSpec);

    return S_OK;
}

static HRESULT WINAPI ICommDlgBrowser3_fnOnPreviewCreated(ICommDlgBrowser3 *iface,
                                                          IShellView *pshv)
{
    ExplorerBrowserImpl *This = impl_from_ICommDlgBrowser3(iface);
    TRACE("%p (%p)\n", This, pshv);

    if(This->pcdb3_site)
        return ICommDlgBrowser3_OnPreviewCreated(This->pcdb3_site, pshv);

    return S_OK;
}

static const ICommDlgBrowser3Vtbl vt_ICommDlgBrowser3 = {
    ICommDlgBrowser3_fnQueryInterface,
    ICommDlgBrowser3_fnAddRef,
    ICommDlgBrowser3_fnRelease,
    ICommDlgBrowser3_fnOnDefaultCommand,
    ICommDlgBrowser3_fnOnStateChange,
    ICommDlgBrowser3_fnIncludeObject,
    ICommDlgBrowser3_fnNotify,
    ICommDlgBrowser3_fnGetDefaultMenuText,
    ICommDlgBrowser3_fnGetViewFlags,
    ICommDlgBrowser3_fnOnColumnClicked,
    ICommDlgBrowser3_fnGetCurrentFilter,
    ICommDlgBrowser3_fnOnPreviewCreated
};

/**************************************************************************
 * IObjectWithSite Implementation
 */

static inline ExplorerBrowserImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IObjectWithSite_iface);
}

static HRESULT WINAPI IObjectWithSite_fnQueryInterface(IObjectWithSite *iface,
                                                       REFIID riid, void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
    TRACE("%p\n", This);
    return IUnknown_QueryInterface((IUnknown*)This, riid, ppvObject);
}

static ULONG WINAPI IObjectWithSite_fnAddRef(IObjectWithSite *iface)
{
    ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
    TRACE("%p\n", This);
    return IUnknown_AddRef((IUnknown*)This);
}

static ULONG WINAPI IObjectWithSite_fnRelease(IObjectWithSite *iface)
{
    ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
    TRACE("%p\n", This);
    return IUnknown_Release((IUnknown*)This);
}

static HRESULT WINAPI IObjectWithSite_fnSetSite(IObjectWithSite *iface, IUnknown *punk_site)
{
    ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
    TRACE("%p (%p)\n", This, punk_site);

    if(This->punk_site)
    {
        IUnknown_Release(This->punk_site);
        This->punk_site = NULL;
        get_interfaces_from_site(This);
    }

    This->punk_site = punk_site;

    if(This->punk_site)
        IUnknown_AddRef(This->punk_site);

    return S_OK;
}

static HRESULT WINAPI IObjectWithSite_fnGetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
{
    ExplorerBrowserImpl *This = impl_from_IObjectWithSite(iface);
    TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvSite);

    if(!This->punk_site)
        return E_FAIL;

    return IUnknown_QueryInterface(This->punk_site, riid, ppvSite);
}

static const IObjectWithSiteVtbl vt_IObjectWithSite = {
    IObjectWithSite_fnQueryInterface,
    IObjectWithSite_fnAddRef,
    IObjectWithSite_fnRelease,
    IObjectWithSite_fnSetSite,
    IObjectWithSite_fnGetSite
};

/**************************************************************************
 * INameSpaceTreeControlEvents Implementation
 */
static inline ExplorerBrowserImpl *impl_from_INameSpaceTreeControlEvents(INameSpaceTreeControlEvents *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, INameSpaceTreeControlEvents_iface);
}

static HRESULT WINAPI NSTCEvents_fnQueryInterface(INameSpaceTreeControlEvents *iface,
                                                  REFIID riid, void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%s, %p)\n", This, shdebugstr_guid(riid), ppvObject);

    *ppvObject = NULL;
    if(IsEqualIID(riid, &IID_INameSpaceTreeControlEvents) ||
       IsEqualIID(riid, &IID_IUnknown))
    {
        *ppvObject = iface;
    }

    if(*ppvObject)
    {
        IUnknown_AddRef((IUnknown*)*ppvObject);
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI NSTCEvents_fnAddRef(INameSpaceTreeControlEvents *iface)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p\n", This);
    return IUnknown_AddRef((IUnknown*)This);
}

static ULONG WINAPI NSTCEvents_fnRelease(INameSpaceTreeControlEvents *iface)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p\n", This);
    return IUnknown_Release((IUnknown*)This);
}

static HRESULT WINAPI NSTCEvents_fnOnItemClick(INameSpaceTreeControlEvents *iface,
                                               IShellItem *psi,
                                               NSTCEHITTEST nstceHitTest,
                                               NSTCECLICKTYPE nstceClickType)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstceHitTest, nstceClickType);
    return S_OK;
}

static HRESULT WINAPI NSTCEvents_fnOnPropertyItemCommit(INameSpaceTreeControlEvents *iface,
                                                        IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnItemStateChanging(INameSpaceTreeControlEvents *iface,
                                                       IShellItem *psi,
                                                       NSTCITEMSTATE nstcisMask,
                                                       NSTCITEMSTATE nstcisState)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnItemStateChanged(INameSpaceTreeControlEvents *iface,
                                                      IShellItem *psi,
                                                      NSTCITEMSTATE nstcisMask,
                                                      NSTCITEMSTATE nstcisState)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, 0x%x, 0x%x)\n", This, psi, nstcisMask, nstcisState);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnSelectionChanged(INameSpaceTreeControlEvents *iface,
                                                      IShellItemArray *psiaSelection)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    IShellItem *psi;
    HRESULT hr;
    TRACE("%p (%p)\n", This, psiaSelection);

    hr = IShellItemArray_GetItemAt(psiaSelection, 0, &psi);
    if(SUCCEEDED(hr))
    {
        hr = IExplorerBrowser_BrowseToObject((IExplorerBrowser*)This,
                                             (IUnknown*)psi, SBSP_DEFBROWSER);
        IShellItem_Release(psi);
    }

    return hr;
}

static HRESULT WINAPI NSTCEvents_fnOnKeyboardInput(INameSpaceTreeControlEvents *iface,
                                                   UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%d, 0x%lx, 0x%lx)\n", This, uMsg, wParam, lParam);
    return S_OK;
}

static HRESULT WINAPI NSTCEvents_fnOnBeforeExpand(INameSpaceTreeControlEvents *iface,
                                                  IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnAfterExpand(INameSpaceTreeControlEvents *iface,
                                                 IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnBeginLabelEdit(INameSpaceTreeControlEvents *iface,
                                                    IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnEndLabelEdit(INameSpaceTreeControlEvents *iface,
                                                  IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnGetToolTip(INameSpaceTreeControlEvents *iface,
                                                IShellItem *psi, LPWSTR pszTip, int cchTip)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %p, %d)\n", This, psi, pszTip, cchTip);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnBeforeItemDelete(INameSpaceTreeControlEvents *iface,
                                                      IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnItemAdded(INameSpaceTreeControlEvents *iface,
                                               IShellItem *psi, BOOL fIsRoot)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnItemDeleted(INameSpaceTreeControlEvents *iface,
                                                 IShellItem *psi, BOOL fIsRoot)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %d)\n", This, psi, fIsRoot);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnBeforeContextMenu(INameSpaceTreeControlEvents *iface,
                                                       IShellItem *psi, REFIID riid, void **ppv)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %s, %p)\n", This, psi, shdebugstr_guid(riid), ppv);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnAfterContextMenu(INameSpaceTreeControlEvents *iface,
                                                      IShellItem *psi, IContextMenu *pcmIn,
                                                      REFIID riid, void **ppv)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %p, %s, %p)\n", This, psi, pcmIn, shdebugstr_guid(riid), ppv);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnBeforeStateImageChange(INameSpaceTreeControlEvents *iface,
                                                            IShellItem *psi)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p)\n", This, psi);
    return E_NOTIMPL;
}

static HRESULT WINAPI NSTCEvents_fnOnGetDefaultIconIndex(INameSpaceTreeControlEvents* iface,
                                                         IShellItem *psi,
                                                         int *piDefaultIcon, int *piOpenIcon)
{
    ExplorerBrowserImpl *This = impl_from_INameSpaceTreeControlEvents(iface);
    TRACE("%p (%p, %p, %p)\n", This, psi, piDefaultIcon, piOpenIcon);
    return E_NOTIMPL;
}


const INameSpaceTreeControlEventsVtbl vt_INameSpaceTreeControlEvents =  {
    NSTCEvents_fnQueryInterface,
    NSTCEvents_fnAddRef,
    NSTCEvents_fnRelease,
    NSTCEvents_fnOnItemClick,
    NSTCEvents_fnOnPropertyItemCommit,
    NSTCEvents_fnOnItemStateChanging,
    NSTCEvents_fnOnItemStateChanged,
    NSTCEvents_fnOnSelectionChanged,
    NSTCEvents_fnOnKeyboardInput,
    NSTCEvents_fnOnBeforeExpand,
    NSTCEvents_fnOnAfterExpand,
    NSTCEvents_fnOnBeginLabelEdit,
    NSTCEvents_fnOnEndLabelEdit,
    NSTCEvents_fnOnGetToolTip,
    NSTCEvents_fnOnBeforeItemDelete,
    NSTCEvents_fnOnItemAdded,
    NSTCEvents_fnOnItemDeleted,
    NSTCEvents_fnOnBeforeContextMenu,
    NSTCEvents_fnOnAfterContextMenu,
    NSTCEvents_fnOnBeforeStateImageChange,
    NSTCEvents_fnOnGetDefaultIconIndex
};

/**************************************************************************
 * IInputObject Implementation
 */

static inline ExplorerBrowserImpl *impl_from_IInputObject(IInputObject *iface)
{
    return CONTAINING_RECORD(iface, ExplorerBrowserImpl, IInputObject_iface);
}

static HRESULT WINAPI IInputObject_fnQueryInterface(IInputObject *iface,
                                                    REFIID riid, void **ppvObject)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    TRACE("%p\n", This);
    return IUnknown_QueryInterface((IUnknown*)This, riid, ppvObject);
}

static ULONG WINAPI IInputObject_fnAddRef(IInputObject *iface)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    TRACE("%p\n", This);
    return IUnknown_AddRef((IUnknown*)This);
}

static ULONG WINAPI IInputObject_fnRelease(IInputObject *iface)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    TRACE("%p\n", This);
    return IUnknown_Release((IUnknown*)This);
}

static HRESULT WINAPI IInputObject_fnUIActivateIO(IInputObject *iface, BOOL fActivate, MSG *pMsg)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    FIXME("stub, %p (%d, %p)\n", This, fActivate, pMsg);
    return E_NOTIMPL;
}

static HRESULT WINAPI IInputObject_fnHasFocusIO(IInputObject *iface)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    FIXME("stub, %p\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IInputObject_fnTranslateAcceleratorIO(IInputObject *iface, MSG *pMsg)
{
    ExplorerBrowserImpl *This = impl_from_IInputObject(iface);
    FIXME("stub, %p (%p)\n", This, pMsg);
    return E_NOTIMPL;
}

static IInputObjectVtbl vt_IInputObject = {
    IInputObject_fnQueryInterface,
    IInputObject_fnAddRef,
    IInputObject_fnRelease,
    IInputObject_fnUIActivateIO,
    IInputObject_fnHasFocusIO,
    IInputObject_fnTranslateAcceleratorIO
};

HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
    ExplorerBrowserImpl *eb;
    HRESULT ret;

    TRACE("%p %s %p\n", pUnkOuter, shdebugstr_guid (riid), ppv);

    if(!ppv)
        return E_POINTER;
    if(pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    eb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ExplorerBrowserImpl));
    eb->ref = 1;
    eb->IExplorerBrowser_iface.lpVtbl = &vt_IExplorerBrowser;
    eb->IShellBrowser_iface.lpVtbl    = &vt_IShellBrowser;
    eb->ICommDlgBrowser3_iface.lpVtbl = &vt_ICommDlgBrowser3;
    eb->IObjectWithSite_iface.lpVtbl  = &vt_IObjectWithSite;
    eb->INameSpaceTreeControlEvents_iface.lpVtbl = &vt_INameSpaceTreeControlEvents;
    eb->IInputObject_iface.lpVtbl     = &vt_IInputObject;

    /* Default settings */
    eb->navpane.width = 150;
    eb->navpane.show = TRUE;

    list_init(&eb->event_clients);
    list_init(&eb->travellog);

    ret = IExplorerBrowser_QueryInterface((IExplorerBrowser*)eb, riid, ppv);
    IExplorerBrowser_Release((IExplorerBrowser*)eb);

    TRACE("--(%p)\n", ppv);
    return ret;
}
