/*
 * 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);
    ILFree(entry->pidl);
    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 main_on_cwm_getishellbrowser(ExplorerBrowserImpl *This)
{
    return (LRESULT)&This->IShellBrowser_iface;
}

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);
    case CWM_GETISHELLBROWSER: return main_on_cwm_getishellbrowser(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;
}


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