Index: dll/win32/browseui/explorerband.h
===================================================================
--- dll/win32/browseui/explorerband.h	(révision 70688)
+++ dll/win32/browseui/explorerband.h	(copie de travail)
@@ -1,8 +1,7 @@
 #pragma once
 
-#if 0
-// Is this a CToolsBand that implements a toolbar?
-class CToolBand :
+class CExplorerBand :
+    public CComCoClass<CExplorerBand, &CLSID_ExplorerBand>,
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IDeskBand,
     public IObjectWithSite,
@@ -9,137 +8,56 @@
     public IInputObject,
     public IPersistStream,
     public IOleCommandTarget,
-    public IServiceProvider
-{
-public:
-    // *** IOleWindow methods ***
-    virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
-    virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
-
-    // *** IDockingWindow methods ***
-    virtual HRESULT STDMETHODCALLTYPE CloseDW(DWORD dwReserved);
-    virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved);
-    virtual HRESULT STDMETHODCALLTYPE ShowDW(BOOL fShow);
-
-    // *** IDeskBand methods ***
-    virtual HRESULT STDMETHODCALLTYPE GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi);
-
-    // *** IObjectWithSite methods ***
-    virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);
-    virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
-
-    // *** IOleCommandTarget methods ***
-    virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText);
-    virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
-
-    // *** IServiceProvider methods ***
-    virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
-
-    // *** IInputObject methods ***
-    virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL fActivate, LPMSG lpMsg);
-    virtual HRESULT STDMETHODCALLTYPE HasFocusIO();
-    virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg);
-
-    // *** IPersist methods ***
-    virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
-
-    // *** IPersistStream methods ***
-    virtual HRESULT STDMETHODCALLTYPE IsDirty();
-    virtual HRESULT STDMETHODCALLTYPE Load(IStream *pStm);
-    virtual HRESULT STDMETHODCALLTYPE Save(IStream *pStm, BOOL fClearDirty);
-    virtual HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize);
-
-    BEGIN_COM_MAP(CToolBand)
-        COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDeskBand)
-        COM_INTERFACE_ENTRY2_IID(IID_IDockingWindow, IDockingWindow, IDeskBand)
-        COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
-        COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
-        COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
-        COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
-        COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
-        COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistStream)
-        COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
-    END_COM_MAP()
-};
-
-class CNSCBand :
-    public CToolBand,
-    public IDeskBand,
-    public IObjectWithSite,
-    public IInputObject,
-    public IPersistStream,
-    public IOleCommandTarget,
     public IServiceProvider,
     public IBandNavigate,
     public IWinEventHandler,
-    public INamespaceProxy
+    public INamespaceProxy,
+    public IDispatch,
+    public CWindowImpl<CExplorerBand, CWindow, CControlWinTraits>
 {
-public:
-    // *** IWinEventHandler methods ***
-    virtual HRESULT STDMETHODCALLTYPE OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult);
-    virtual HRESULT STDMETHODCALLTYPE IsWindowOwner(HWND hWnd);
 
-    // *** IBandNavigate methods ***
-    virtual HRESULT STDMETHODCALLTYPE Select(long paramC);
+private:
+    class NodeInfo
+    {
+    public:
+        LPITEMIDLIST absolutePidl;
+        LPITEMIDLIST relativePidl;
+        BOOL expanded;
+    };
+    CComPtr<IUnknown> pSite;
+    CComPtr<IServiceProvider> pServiceProvider;
+    CComPtr<IOleWindow> pBandOle;
+    CComPtr<IShellFolder> pDesktop;
+    RECT hwndClient;
+    BOOL fVisible;
+    BOOL bNavigating;
+    DWORD dwBandID;
+    HIMAGELIST hImageList;
+    HTREEITEM  hRoot;
+    HTREEITEM  oldSelected;
+    DWORD adviseCookie;
 
-    // *** INamespaceProxy ***
-    virtual HRESULT STDMETHODCALLTYPE GetNavigateTarget(long paramC, long param10, long param14);
-    virtual HRESULT STDMETHODCALLTYPE Invoke(long paramC);
-    virtual HRESULT STDMETHODCALLTYPE OnSelectionChanged(long paramC);
-    virtual HRESULT STDMETHODCALLTYPE RefreshFlags(long paramC, long param10, long param14);
-    virtual HRESULT STDMETHODCALLTYPE CacheItem(long paramC);
+    void InitializeExplorerBand();
+    void DestroyExplorerBand();
+    HRESULT ExecuteCommand(CComPtr<IContextMenu>& menu, UINT nCmd);
 
-    BEGIN_COM_MAP(CNSCBand)
-        COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler)
-        COM_INTERFACE_ENTRY_IID(IID_IBandNavigate, IBandNavigate)
-        COM_INTERFACE_ENTRY_IID(IID_INamespaceProxy, INamespaceProxy)
-#if 0
-        COM_INTERFACE_ENTRY_CHAIN(CToolBand)
-#else
-        COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDeskBand)
-        COM_INTERFACE_ENTRY2_IID(IID_IDockingWindow, IDockingWindow, IDeskBand)
-        COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
-        COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
-        COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
-        COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
-        COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistStream)
-        COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
-#endif
-    END_COM_MAP()
-};
-#endif
+    // *** notifications handling ***
+    void OnTreeItemChanged(LPNMTREEVIEW pnmtv);
+    BOOL OnTreeItemExpanding(LPNMTREEVIEW pnmtv);
+    BOOL OnTreeItemDeleted(LPNMTREEVIEW pnmtv);
 
-class CExplorerBand :
-    public CComCoClass<CExplorerBand, &CLSID_ExplorerBand>,
-#if 0
-    public CNSCBand,
-#else
-    public CComObjectRootEx<CComMultiThreadModelNoCS>,
-#endif
-    public IDeskBand,
-    public IObjectWithSite,
-    public IInputObject,
-    public IPersistStream,
-    public IOleCommandTarget,
-    public IServiceProvider,
-    public IBandNavigate,
-    public IWinEventHandler,
-    public INamespaceProxy
-{
-    CComPtr<IUnknown> m_internalBand;
+    // *** ATL event handlers ***
+    LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
+    LRESULT ContextMenuHack(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
 
-    CComPtr<IDeskBand> m_internalDeskBand;
-    CComPtr<IObjectWithSite> m_internalObjectWithSite;
-    CComPtr<IInputObject> m_internalInputObject;
-    CComPtr<IPersistStream> m_internalPersistStream;
-    CComPtr<IOleCommandTarget> m_internalOleCommandTarget;
-    CComPtr<IServiceProvider> m_internalServiceProvider;
-    CComPtr<IBandNavigate> m_internalBandNavigate;
-    CComPtr<IWinEventHandler> m_internalWinEventHandler;
-    CComPtr<INamespaceProxy> m_internalNamespaceProxy;
-    CComPtr<IDispatch> m_internalDispatch;
+    // *** Helper functions ***
+    BOOL InsertSubitems(HTREEITEM hItem, NodeInfo *pNodeInfo); 
+    BOOL NavigateToPIDL(LPITEMIDLIST dest, HTREEITEM *item, BOOL bExpand, BOOL bInsert, BOOL bSelect);
+    BOOL NavigateToCurrentFolder();
 
-    bool m_OnWinEventShown;
+    // *** Tree item sorting callback ***
+    static int CALLBACK CompareTreeItems(LPARAM p1, LPARAM p2, LPARAM p3);
+
 public:
     CExplorerBand();
     virtual ~CExplorerBand();
@@ -207,7 +125,7 @@
     DECLARE_PROTECT_FINAL_CONSTRUCT()
 
     BEGIN_COM_MAP(CExplorerBand)
-        COM_INTERFACE_ENTRY_IID(IID_IDispatch, IDeskBand)
+        COM_INTERFACE_ENTRY_IID(IID_IDispatch, IDispatch)
         COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler)
         COM_INTERFACE_ENTRY_IID(IID_IBandNavigate, IBandNavigate)
         COM_INTERFACE_ENTRY_IID(IID_INamespaceProxy, INamespaceProxy)
@@ -221,7 +139,14 @@
         COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistStream)
         COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
     END_COM_MAP()
+
+    BEGIN_MSG_MAP(CExplorerBand)
+        MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
+#ifdef __REACTOS__
+        MESSAGE_HANDLER(WM_RBUTTONDOWN, ContextMenuHack)
+#endif
+    END_MSG_MAP()
 };
 
 extern "C"
-HRESULT WINAPI CExplorerBand_Constructor(REFIID riid, LPVOID *ppv);
\ No newline at end of file
+HRESULT WINAPI CExplorerBand_Constructor(REFIID riid, LPVOID *ppv);
Index: dll/win32/browseui/explorerband.cpp
===================================================================
--- dll/win32/browseui/explorerband.cpp	(révision 70688)
+++ dll/win32/browseui/explorerband.cpp	(copie de travail)
@@ -6,258 +6,761 @@
 #define UNIMPLEMENTED DbgPrint("%s is UNIMPLEMENTED!\n", __FUNCTION__)
 #endif
 
+/*
+ * TODO:
+ *  - Implement adding PIDL to a given node (required for second point)
+ *  - Refresh on FS changes
+ *  - Drag'n'drop support
+ *  - Editable labels support (renaming folders)
+ *  - find and fix what cause explorer crashes sometimes
+ *  - Make it 100% compatible with WinXP/2003 (i.e. fully implement DWebBrowserEvents I guess)
+ *  - TESTING
+ */
+
+typedef struct _PIDLDATA
+{
+    BYTE type;
+    BYTE data[1];
+} PIDLDATA, *LPPIDLDATA;
+
+#define PT_GUID 0x1F
+#define PT_SHELLEXT 0x2E
+#define PT_YAGUID 0x70
+
+static BOOL _ILIsSpecialFolder (LPCITEMIDLIST pidl)
+{
+    LPPIDLDATA lpPData = (LPPIDLDATA)&pidl->mkid.abID;
+
+    return (pidl &&
+        ((lpPData && (PT_GUID == lpPData->type || PT_SHELLEXT== lpPData->type ||
+        PT_YAGUID == lpPData->type)) || (pidl && pidl->mkid.cb == 0x00)));
+}
+
+HRESULT GetDisplayName(LPCITEMIDLIST pidlDirectory,TCHAR *szDisplayName,UINT cchMax,DWORD uFlags)
+{
+    IShellFolder *pShellFolder = NULL;
+    LPITEMIDLIST pidlRelative = NULL;
+    STRRET str;
+    HRESULT hr;
+
+    if(pidlDirectory == NULL || szDisplayName == NULL)
+    {
+        return E_FAIL;
+    }
+
+    hr = SHBindToParent(pidlDirectory, IID_PPV_ARG(IShellFolder, &pShellFolder), (LPCITEMIDLIST *)&pidlRelative);
+
+    if(SUCCEEDED(hr))
+    {
+        hr = pShellFolder->GetDisplayNameOf(pidlRelative,uFlags,&str);
+        if(SUCCEEDED(hr))
+        {
+            hr = StrRetToBuf(&str,pidlDirectory,szDisplayName,cchMax);
+        }
+        pShellFolder->Release();
+    }
+    return hr;
+}
+
+static LPARAM TreeView_GetItemData(HWND hwndTreeView, HTREEITEM hItem);
+
+
 extern "C"
 HRESULT WINAPI CExplorerBand_Constructor(REFIID riid, LPVOID *ppv)
 {
+#ifdef __REACTOS__
     return ShellObjectCreator<CExplorerBand>(riid, ppv);
+#else
+    return S_OK;
+#endif
 }
 
 CExplorerBand::CExplorerBand() :
-    m_OnWinEventShown(FALSE)
+    pSite(NULL), fVisible(FALSE), bNavigating(FALSE), dwBandID(0)
 {
-#if 0
-    HRESULT hResult = CoCreateInstance(CLSID_ExplorerBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, &m_internalBand));
-    if (FAILED(hResult))
+}
+
+CExplorerBand::~CExplorerBand()
+{
+}
+
+
+void CExplorerBand::InitializeExplorerBand()
+{
+    // Init the treeview here
+    TV_INSERTSTRUCT                     tvInsert;
+    TV_ITEM*                            tvItem;
+    HRESULT                             hr;
+    LPITEMIDLIST                        pidl;
+    SHFILEINFOW                         shfi;
+    NodeInfo                            *pNodeInfo;
+    CComPtr<IBrowserService>            browserService;
+    
+    tvItem = &tvInsert.item;
+    tvInsert.hParent = 0;
+    tvInsert.hInsertAfter = TVI_LAST;
+    hr = SHGetDesktopFolder(&pDesktop);
+    if(!SUCCEEDED(hr))
     {
-        ERR("Could not create internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
+        ERR("Can't initialize desktop folder !\n");
         return;
     }
-    hResult = m_internalBand->QueryInterface(IID_PPV_ARG(IDeskBand, &m_internalDeskBand));
-    if (FAILED(hResult))
+    pNodeInfo = new NodeInfo;
+    if(!pNodeInfo)
     {
-        ERR("Could not obtain interface IDeskBand from internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
-        m_internalDeskBand = NULL;
+        ERR("Can't allocate memory, aborting.\n");
         return;
     }
-    hResult = m_internalBand->QueryInterface(IID_PPV_ARG(IObjectWithSite, &m_internalObjectWithSite));
-    if (FAILED(hResult))
+    // Initialize display name and our imagelist
+    hr = SHGetFolderLocation(m_hWnd, CSIDL_DESKTOP, NULL, 0, &pidl);
+    hImageList = (HIMAGELIST)SHGetFileInfoW((LPTSTR)pidl, NULL, &shfi, NULL,
+            SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME | SHGFI_SMALLICON);
+
+    // Set up our node
+    tvItem->mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
+    tvItem->cchTextMax = MAX_PATH;
+    tvItem->pszText = shfi.szDisplayName;
+    tvItem->iImage = tvItem->iSelectedImage = shfi.iIcon;
+    tvItem->cChildren = 1;
+
+    // Insert create node data
+    pNodeInfo->absolutePidl = ILClone(pidl);
+    pNodeInfo->relativePidl = ILClone(pidl);
+    pNodeInfo->expanded = FALSE;
+    tvItem->lParam = (LPARAM)pNodeInfo;
+    TreeView_SetImageList(m_hWnd, hImageList, TVSIL_NORMAL);
+
+    // Add root node
+    HTREEITEM hItem = TreeView_InsertItem(m_hWnd, &tvInsert);
+    hRoot = hItem;
+    TreeView_SelectItem(m_hWnd, hItem);
+
+    // Insert child nodes
+    InsertSubitems(hItem, pNodeInfo);
+    TreeView_Expand(m_hWnd, hItem, TVE_EXPAND);
+
+    ILFree(pidl);
+    
+    // Navigate to current folder position
+    NavigateToCurrentFolder();
+
+    // Register browser connection endpoint
+    hr = pServiceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
+
+    hr = AtlAdvise(browserService, reinterpret_cast<IDispatch*>(this), DIID_DWebBrowserEvents, &adviseCookie);
+    if(!SUCCEEDED(hr))
     {
-        ERR("Could not obtain interface IObjectWithSite from internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
-        m_internalDeskBand = NULL;
-        m_internalObjectWithSite = NULL;
-        return;
+        ERR("Can't advise our browser service !\n");
     }
-    hResult = m_internalBand->QueryInterface(IID_PPV_ARG(IInputObject, &m_internalInputObject));
-    if (FAILED(hResult))
+}
+
+void CExplorerBand::DestroyExplorerBand()
+{
+    TRACE("Cleaning up explorer band ...\n");
+    /* Remove all items of the treeview */
+    TreeView_DeleteAllItems(m_hWnd);
+    pDesktop = NULL;
+    hRoot = NULL;
+    TRACE("Cleanup done !\n");
+}
+
+HRESULT CExplorerBand::ExecuteCommand(CComPtr<IContextMenu>& menu, UINT nCmd)
+{
+    CComPtr<IOleWindow>                 pBrowserOleWnd;
+    CMINVOKECOMMANDINFO                 cmi;
+    HWND                                browserWnd;
+    HRESULT                             hr;
+
+    ZeroMemory(&cmi, sizeof(cmi));
+    cmi.cbSize = sizeof(cmi);
+    cmi.lpVerb = MAKEINTRESOURCEA(nCmd);
+
+    // Retrieve OLE window
+    hr = pServiceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IOleWindow, &pBrowserOleWnd));
+    if(!SUCCEEDED(hr))
     {
-        ERR("Could not obtain interface IInputObject from internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
-        m_internalDeskBand = NULL;
-        m_internalObjectWithSite = NULL;
-        m_internalInputObject = NULL;
-        return;
+        ERR("Can't get IOleWindow interface for shell browser\n");
+        return E_FAIL;
     }
-    hResult = m_internalBand->QueryInterface(IID_PPV_ARG(IPersistStream, &m_internalPersistStream));
-    if (FAILED(hResult))
+    hr = pBrowserOleWnd->GetWindow(&browserWnd);
+    if(!SUCCEEDED(hr))
     {
-        ERR("Could not obtain interface IPersistStream from internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
-        m_internalDeskBand = NULL;
-        m_internalObjectWithSite = NULL;
-        m_internalInputObject = NULL;
-        m_internalPersistStream = NULL;
+        ERR("Can't get browser hWnd\n");
+        return E_FAIL;
+    }
+    cmi.hwnd = browserWnd;
+
+    if(GetKeyState(VK_SHIFT) & 0x8000)
+        cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
+
+    if(GetKeyState(VK_CONTROL) & 0x8000)
+        cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
+
+    return menu->InvokeCommand(&cmi);
+}
+
+
+// *** notifications handling ***
+BOOL CExplorerBand::OnTreeItemExpanding(LPNMTREEVIEW pnmtv)
+{
+    NodeInfo                           *pNodeInfo;
+
+    if (pnmtv->action == TVE_COLLAPSE) {
+        if(pnmtv->itemNew.hItem == hRoot)
+        {
+            // Prenvent root from collapsing
+            pnmtv->itemNew.mask |= TVIF_STATE;
+            pnmtv->itemNew.stateMask |= TVIS_EXPANDED;
+            pnmtv->itemNew.state &= ~TVIS_EXPANDED;
+            pnmtv->action = TVE_EXPAND;
+            return TRUE;
+        }
+    }
+    if (pnmtv->action == TVE_EXPAND) {
+        // Grab our directory PIDL
+        pNodeInfo = (NodeInfo*)TreeView_GetItemData(m_hWnd, pnmtv->itemNew.hItem);
+        // We have it, let's try
+        if (pNodeInfo && !pNodeInfo->expanded)
+            if (!InsertSubitems(pnmtv->itemNew.hItem, pNodeInfo)) {
+                // remove subitem "+" since we failed to add subitems
+                TV_ITEM tvItem;
+
+                tvItem.mask = TVIF_CHILDREN;
+                tvItem.hItem = pnmtv->itemNew.hItem;
+                tvItem.cChildren = 0;
+
+                TreeView_SetItem(m_hWnd, &tvItem);
+            }
+    }
+    return FALSE;
+}
+
+BOOL CExplorerBand::OnTreeItemDeleted(LPNMTREEVIEW pnmtv)
+{
+    /* Destroy memory associated to our node */
+    NodeInfo                            *ptr;
+
+    ptr = (NodeInfo*)pnmtv->itemOld.lParam;
+    ILFree(ptr->relativePidl);
+    ILFree(ptr->absolutePidl);
+    delete ptr;
+    return TRUE;
+}
+
+void CExplorerBand::OnTreeItemChanged(LPNMTREEVIEW pnmtv)
+{
+    CComPtr<IShellBrowser>              pBrowserService;
+    HRESULT                             hr;
+    NodeInfo                            *pInfo;
+
+    /* Prevents navigation if selection is initiated inside the band */
+    if(bNavigating)
         return;
-    }
-    hResult = m_internalBand->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &m_internalOleCommandTarget));
-    if (FAILED(hResult))
+
+    hr = pServiceProvider->QueryService(SID_STopLevelBrowser, IID_PPV_ARG(IShellBrowser, &pBrowserService));
+    if(!SUCCEEDED(hr))
     {
-        ERR("Could not obtain interface IOleCommandTarget from internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
-        m_internalDeskBand = NULL;
-        m_internalObjectWithSite = NULL;
-        m_internalInputObject = NULL;
-        m_internalPersistStream = NULL;
-        m_internalOleCommandTarget = NULL;
+        ERR("Can't get IBrowserService !\n");
         return;
     }
-    hResult = m_internalBand->QueryInterface(IID_PPV_ARG(IServiceProvider, &m_internalServiceProvider));
-    if (FAILED(hResult))
+
+    pInfo = (NodeInfo*)TreeView_GetItemData(m_hWnd, pnmtv->itemNew.hItem);
+    hr = pBrowserService->BrowseObject(pInfo->absolutePidl, SBSP_SAMEBROWSER | SBSP_ABSOLUTE | SBSP_ACTIVATE_NOFOCUS);
+    if(!SUCCEEDED(hr))
     {
-        ERR("Could not obtain interface IServiceProvider from internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
-        m_internalDeskBand = NULL;
-        m_internalObjectWithSite = NULL;
-        m_internalInputObject = NULL;
-        m_internalPersistStream = NULL;
-        m_internalOleCommandTarget = NULL;
-        m_internalServiceProvider = NULL;
-        return;
+        ERR("Cannot navigate to specified destination !\n");
     }
-    hResult = m_internalBand->QueryInterface(IID_PPV_ARG(IBandNavigate, &m_internalBandNavigate));
-    if (FAILED(hResult))
+
+    SetFocus();
+    // Expand the node
+    //TreeView_Expand(m_hWnd, pnmtv->itemNew.hItem, TVE_EXPAND);
+}
+
+
+// *** ATL event handlers ***
+LRESULT CExplorerBand::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+    HTREEITEM                           item;
+    NodeInfo                            *info;
+    HMENU                               treeMenu;
+    WORD                                x;
+    WORD                                y;
+    CComPtr<IShellFolder>               pFolder;
+    CComPtr<IContextMenu>               contextMenu;
+    HRESULT                             hr;
+    UINT                                uCommand;
+    LPITEMIDLIST                        pidlChild;
+
+    treeMenu = NULL;
+    item = TreeView_GetSelection(m_hWnd);
+    bHandled = TRUE;
+    if(!item)
     {
-        ERR("Could not obtain interface IBandNavigate from internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
-        m_internalDeskBand = NULL;
-        m_internalObjectWithSite = NULL;
-        m_internalInputObject = NULL;
-        m_internalPersistStream = NULL;
-        m_internalOleCommandTarget = NULL;
-        m_internalServiceProvider = NULL;
-        m_internalBandNavigate = NULL;
-        return;
+        goto Cleanup;
     }
-    hResult = m_internalBand->QueryInterface(IID_PPV_ARG(IWinEventHandler, &m_internalWinEventHandler));
-    if (FAILED(hResult))
+
+    x = LOWORD(lParam);
+    y = HIWORD(lParam);
+    if(x == -1 && y == -1)
     {
-        ERR("Could not obtain interface IWinEventHandler from internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
-        m_internalDeskBand = NULL;
-        m_internalObjectWithSite = NULL;
-        m_internalInputObject = NULL;
-        m_internalPersistStream = NULL;
-        m_internalOleCommandTarget = NULL;
-        m_internalServiceProvider = NULL;
-        m_internalBandNavigate = NULL;
-        m_internalWinEventHandler = NULL;
-        return;
+        // TODO: grab position of tree item and position it correctly
     }
-    hResult = m_internalBand->QueryInterface(IID_PPV_ARG(INamespaceProxy, &m_internalNamespaceProxy));
-    if (FAILED(hResult))
+
+    info = (NodeInfo*)TreeView_GetItemData(m_hWnd, item);
+    if(!info)
     {
-        ERR("Could not obtain interface INamespaceProxy from internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
-        m_internalDeskBand = NULL;
-        m_internalObjectWithSite = NULL;
-        m_internalInputObject = NULL;
-        m_internalPersistStream = NULL;
-        m_internalOleCommandTarget = NULL;
-        m_internalServiceProvider = NULL;
-        m_internalBandNavigate = NULL;
-        m_internalWinEventHandler = NULL;
-        m_internalNamespaceProxy = NULL;
-        return;
+        ERR("No node data, something has gone wrong !\n");
+        goto Cleanup;
     }
-    hResult = m_internalBand->QueryInterface(IID_PPV_ARG(IDispatch, &m_internalDispatch));
-    if (FAILED(hResult))
+    hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pFolder),
+        (LPCITEMIDLIST*)&pidlChild);
+    if(!SUCCEEDED(hr))
     {
-        ERR("Could not obtain interface INamespaceProxy from internal band (hr=%08lx).\n", hResult);
-        m_internalBand = NULL;
-        m_internalDeskBand = NULL;
-        m_internalObjectWithSite = NULL;
-        m_internalInputObject = NULL;
-        m_internalPersistStream = NULL;
-        m_internalOleCommandTarget = NULL;
-        m_internalServiceProvider = NULL;
-        m_internalBandNavigate = NULL;
-        m_internalWinEventHandler = NULL;
-        m_internalNamespaceProxy = NULL;
-        m_internalDispatch = NULL;
-        return;
+        ERR("Can't bind to folder!\n");
+        goto Cleanup;
     }
-#endif
+    hr = pFolder->GetUIObjectOf(m_hWnd, 1, (LPCITEMIDLIST*)&pidlChild, IID_IContextMenu,
+        NULL, reinterpret_cast<void**>(&contextMenu));
+    if(!SUCCEEDED(hr))
+    {
+        ERR("Can't get IContextMenu interface\n");
+        goto Cleanup;
+    }
+    treeMenu = CreatePopupMenu();
+    hr = contextMenu->QueryContextMenu(treeMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST,
+        CMF_EXPLORE);
+    if(!SUCCEEDED(hr))
+    {
+        WARN("Can't get context menu for item\n");
+        DestroyMenu(treeMenu);
+        goto Cleanup;
+    }
+    uCommand = TrackPopupMenu(treeMenu, TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+        x, y, 0, m_hWnd, NULL);
+
+    ExecuteCommand(contextMenu, uCommand);
+Cleanup:
+    if(treeMenu)
+        DestroyMenu(treeMenu);
+#ifdef __REACTOS__
+    bNavigating = TRUE;
+    TreeView_SelectItem(m_hWnd, oldSelected);
+    bNavigating = FALSE;
+#endif /* __REACTOS__ */
+    return TRUE;
 }
 
-CExplorerBand::~CExplorerBand()
+#ifdef __REACTOS__
+LRESULT CExplorerBand::ContextMenuHack(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
+    // Hack to make Wine explorer happy and select the folder we want to do
+    bHandled = TRUE;
+    if(uMsg == WM_RBUTTONDOWN)
+    {
+        TVHITTESTINFO info;
+        info.pt.x = LOWORD(lParam);
+        info.pt.y = HIWORD(lParam);
+        info.flags = TVHT_ONITEM;
+        info.hItem = NULL;
+
+        // Save the current location
+        oldSelected = TreeView_GetSelection(m_hWnd);
+        
+        // Move to the item selected by the treeview (don't change right pane)
+        TreeView_HitTest(m_hWnd, &info);
+        bNavigating = TRUE;
+        TreeView_SelectItem(m_hWnd, info.hItem);
+        bNavigating = FALSE;
+    }
+    return CallWindowProc(::DefWindowProc, m_hWnd, uMsg, wParam, lParam);
 }
+#endif
 
-// *** IOleWindow methods ***
-HRESULT STDMETHODCALLTYPE CExplorerBand::GetWindow(HWND *lphwnd)
+// *** Helper functions ***
+BOOL CExplorerBand::InsertSubitems(HTREEITEM hItem, NodeInfo *pNodeInfo)
 {
-    HRESULT hr;
-    if (m_internalDeskBand)
+    CComPtr<IEnumIDList>                pEnumIDList;
+    LPITEMIDLIST                        pidlSub;
+    LPITEMIDLIST                        entry;
+    SHCONTF                             EnumFlags;
+    HRESULT                             hr;
+    ULONG                               fetched;
+    ULONG                               uItemCount;
+    TV_INSERTSTRUCT                     tvInsert;
+    TV_ITEM*                            tvItem;
+    CComPtr<IShellFolder>               pFolder;
+    NodeInfo                            *pChildInfo;
+    TVSORTCB                            sortCallback;
+    WCHAR                               wszDisplayName[MAX_PATH];
+    entry = pNodeInfo->absolutePidl;
+    fetched = 1;
+    uItemCount = 0;
+    EnumFlags = SHCONTF_FOLDERS;
+
+    // Set up our treeview template
+    tvItem = &tvInsert.item;
+    tvInsert.hParent = hItem;
+    tvInsert.hInsertAfter = TVI_LAST;
+
+
+    hr = SHGetFolderLocation(m_hWnd, CSIDL_DESKTOP, NULL, 0, &pidlSub);
+    if(!SUCCEEDED(hr))
     {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::GetWindow(HWND *lphwnd=%p)\n", lphwnd);
-        hr = m_internalDeskBand->GetWindow(lphwnd);
-        if (lphwnd)
-            DbgPrint("\t*lphwnd=%p\n", *lphwnd);
-        DbgPrint("CExplorerBand::GetWindow returning %08lx\n", hr);
-        return hr;
+        ERR("Can't get desktop PIDL !\n");
+        return FALSE;
     }
 
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    if(!pDesktop->CompareIDs(NULL, pidlSub, entry))
+    {
+        // We are the desktop, so use pDesktop as pFolder
+        pFolder = pDesktop;
+    }
+    else
+    {
+        // Get an IShellFolder of our pidl
+        hr = pDesktop->BindToObject(entry, NULL, IID_PPV_ARG(IShellFolder, &pFolder));
+        if(!SUCCEEDED(hr))
+        {
+            ILFree(pidlSub);
+            ERR("Can't bind folder to desktop !\n");
+            return FALSE;
+        }
+    }
+    ILFree(pidlSub);
+
+    // TODO: handle hidden folders according to settings !
+    EnumFlags |= SHCONTF_INCLUDEHIDDEN;
+
+    // Enum through objects
+    hr = pFolder->EnumObjects(NULL,EnumFlags,&pEnumIDList);
+
+    // avoid broken IShellFolder implementations that return null pointer with success
+    if(!SUCCEEDED(hr) || !pEnumIDList)
+    {
+        ERR("Can't enum the folder !\n");
+        return FALSE;
+    }
+
+    /* Don't redraw while we add stuff into the tree */
+    SendMessage(WM_SETREDRAW, FALSE, 0);
+    while(SUCCEEDED(pEnumIDList->Next(1, &pidlSub, &fetched)) && pidlSub && fetched)
+    {
+        LPITEMIDLIST pidlSubComplete;
+        SHFILEINFOW shfi;
+        pidlSubComplete = ILCombine(entry, pidlSub);
+        SHGetFileInfoW((LPTSTR)pidlSubComplete, NULL, &shfi, NULL,
+            SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_ATTRIBUTES);
+
+        GetDisplayName(pidlSubComplete, wszDisplayName, MAX_PATH, SHGDN_INFOLDER);
+
+        if(!(shfi.dwAttributes & SFGAO_STREAM))
+        {
+            pChildInfo = new NodeInfo;
+            if(!pNodeInfo)
+            {
+                TreeView_Expand(m_hWnd, hItem, TVE_COLLAPSE | TVE_COLLAPSERESET);
+                SendMessage(m_hWnd, WM_SETREDRAW, TRUE, 0);
+                return FALSE;
+            }
+
+            tvItem->mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
+            tvItem->cchTextMax = MAX_PATH;
+            tvItem->pszText = wszDisplayName;
+            tvItem->iImage = tvItem->iSelectedImage = shfi.iIcon;
+            tvItem->cChildren = (shfi.dwAttributes & SFGAO_HASSUBFOLDER) ? 1 : 0;
+
+            // Store our node info
+            pChildInfo->absolutePidl = ILClone(pidlSubComplete);
+            pChildInfo->relativePidl = ILClone(pidlSub);
+            pChildInfo->expanded = FALSE;
+
+            tvItem->lParam = (LPARAM)pChildInfo;
+            TreeView_InsertItem(m_hWnd, &tvInsert);
+            uItemCount++;
+        }
+
+        ILFree(pidlSubComplete);
+        ILFree(pidlSub);
+    }
+    pNodeInfo->expanded = TRUE;
+    /* Let's do sorting */
+    sortCallback.hParent = hItem;
+    sortCallback.lpfnCompare = CompareTreeItems;
+    sortCallback.lParam = (LPARAM)this;
+    SendMessage(TVM_SORTCHILDRENCB, 0, (LPARAM)&sortCallback);
+
+    /* Now we can redraw */
+    SendMessage(WM_SETREDRAW, TRUE, 0);
+
+    return (uItemCount > 0) ? TRUE : FALSE;
 }
 
-HRESULT STDMETHODCALLTYPE CExplorerBand::ContextSensitiveHelp(BOOL fEnterMode)
+/**
+ * Navigate to a given PIDL in the treeview, and return matching tree item handle
+ *  - dest: The absolute PIDL we should navigate in the treeview
+ *  - item: Handle of the tree item matching the PIDL
+ *  - bExpand: expand collapsed nodes in order to find the right element
+ *  - bInsert: insert the element at the right place if we don't find it
+ *  - bSelect: select the item after we found it
+ */
+BOOL CExplorerBand::NavigateToPIDL(LPITEMIDLIST dest, HTREEITEM *item, BOOL bExpand, BOOL bInsert,
+        BOOL bSelect)
 {
-    HRESULT hr;
-    if (m_internalDeskBand)
+    HTREEITEM                           current;
+    HTREEITEM                           tmp;
+    BOOL                                found;
+    NodeInfo                            *nodeData;
+
+    if(!item)
+        return FALSE;
+
+    found = FALSE;
+    current = hRoot;
+    while(!found)
     {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::ContextSensitiveHelp(BOOL fEnterMode=%s)\n", fEnterMode ? "TRUE" : "FALSE");
-        hr = m_internalDeskBand->ContextSensitiveHelp(fEnterMode);
-        DbgPrint("CExplorerBand::ContextSensitiveHelp returning %08lx\n", hr);
-        return hr;
+        nodeData = (NodeInfo*)TreeView_GetItemData(m_hWnd, current);
+        if(!nodeData)
+        {
+            ERR("Something has gone wrong, no data associated to node !\n");
+            *item = NULL;
+            return FALSE;
+        }
+        // If we found our node, give it back
+        if(!pDesktop->CompareIDs(0, nodeData->absolutePidl, dest))
+        {
+            if(bSelect)
+                TreeView_SelectItem(m_hWnd, current);
+            *item = current;
+            return TRUE;
+        }
+
+        // Check if we are a parent of the requested item
+        if(ILFindChild(nodeData->absolutePidl, dest))
+        {
+            // If we can expand and the node isn't expanded yet, do it
+            if(bExpand)
+            {
+                if(!nodeData->expanded)
+                    InsertSubitems(current, nodeData);
+                TreeView_Expand(m_hWnd, current, TVE_EXPAND);
+            }
+
+            // Try to get a child
+            tmp = TreeView_GetChild(m_hWnd, current);
+            if(tmp)
+            {
+                // We have a child, let's continue with it
+                current = tmp;
+                continue;
+            }
+
+            if(bInsert)
+            {
+                ERR("Trying to insert item\n");
+                // TODO: write and call code to insert item into the tree
+            }
+            // We end up here, without any children, so we found nothing
+            *item = NULL;
+            return FALSE;
+        }
+
+        // Find sibling
+        tmp = TreeView_GetNextSibling(m_hWnd, current);
+        if(tmp)
+        {
+            current = tmp;
+            continue;
+        }
+        if(bInsert)
+        {
+            // TODO: write and call code to insert item into the tree
+        }
+        *item = NULL;
+        return FALSE;
     }
-
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    return FALSE;
 }
 
-
-// *** IDockingWindow methods ***
-HRESULT STDMETHODCALLTYPE CExplorerBand::CloseDW(DWORD dwReserved)
+BOOL CExplorerBand::NavigateToCurrentFolder()
 {
-    HRESULT hr;
-    if (m_internalDeskBand)
+    LPITEMIDLIST                        explorerPidl;
+    CComPtr<IBrowserService>            pBrowserService;
+    HRESULT                             hr;
+    HTREEITEM                           dummy;
+    BOOL                                result; 
+    explorerPidl = NULL;
+    hr = pServiceProvider->QueryService(SID_STopLevelBrowser, IID_PPV_ARG(IBrowserService, &pBrowserService));
+    if(!SUCCEEDED(hr))
     {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::CloseDW(DWORD dwReserved=%u)\n", dwReserved);
-        hr = m_internalDeskBand->CloseDW(dwReserved);
-        DbgPrint("CExplorerBand::CloseDW returning %08lx\n", hr);
-        return hr;
+        ERR("Can't get IBrowserService !\n");
+        return FALSE;
     }
-
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    
+    hr = pBrowserService->GetPidl(&explorerPidl);
+    if(!SUCCEEDED(hr) || !explorerPidl)
+    {
+        ERR("Unable to get browser PIDL !\n");
+        return FALSE;
+    }
+    bNavigating = TRUE;
+    /* find PIDL into our explorer */
+    result = NavigateToPIDL(explorerPidl, &dummy, TRUE, FALSE, TRUE);
+    bNavigating = FALSE;
+    return result;
 }
 
-HRESULT STDMETHODCALLTYPE CExplorerBand::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
+// *** Tree item sorting callback ***
+int CALLBACK CExplorerBand::CompareTreeItems(LPARAM p1, LPARAM p2, LPARAM p3)
 {
-    HRESULT hr;
-    if (m_internalDeskBand)
+    /*
+     * We first sort drive letters (Path root), then PIDLs and then regular folder
+     * display name.
+     * This is not how Windows sorts item, but it gives decent results.
+     */
+    NodeInfo                            *info1;
+    NodeInfo                            *info2;
+    CExplorerBand                       *pThis;
+    WCHAR                               wszFolder1[MAX_PATH];
+    WCHAR                               wszFolder2[MAX_PATH];
+
+    info1 = (NodeInfo*)p1;
+    info2 = (NodeInfo*)p2;
+    pThis = (CExplorerBand*)p3;
+
+    GetDisplayName(info1->absolutePidl, wszFolder1, MAX_PATH, SHGDN_FORPARSING);
+    GetDisplayName(info2->absolutePidl, wszFolder2, MAX_PATH, SHGDN_FORPARSING);
+    if(PathIsRoot(wszFolder1) && PathIsRoot(wszFolder2))
     {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::ResizeBorderDW(const RECT *prcBorder=%p, IUnknown *punkToolbarSite=%p, BOOL fReserved=%s)\n",
-                 prcBorder, punkToolbarSite, fReserved ? "TRUE" : "FALSE");
-        if (prcBorder)
-            DbgPrint("\t*prcBorder={%u, %u, %u, %u}\n", prcBorder->left, prcBorder->top, prcBorder->right, prcBorder->bottom);
-        hr = m_internalDeskBand->ResizeBorderDW(prcBorder, punkToolbarSite, fReserved);
-        DbgPrint("CExplorerBand::ResizeBorderDW returning %08lx\n", hr);
-        return hr;
+        return lstrcmpiW(wszFolder1,wszFolder2);
     }
+    if(PathIsRoot(wszFolder1) && !PathIsRoot(wszFolder2))
+    {
+        return -1;
+    }
+    if(!PathIsRoot(wszFolder1) && PathIsRoot(wszFolder2))
+    {
+        return 1;
+    }
+    // Now, we compare non-root folders, grab display name
+    GetDisplayName(info1->absolutePidl, wszFolder1, MAX_PATH, SHGDN_INFOLDER);
+    GetDisplayName(info2->absolutePidl, wszFolder2, MAX_PATH, SHGDN_INFOLDER);
 
+    if(_ILIsSpecialFolder(info1->relativePidl) && !_ILIsSpecialFolder(info2->relativePidl))
+    {
+        return -1;
+    }
+    if(!_ILIsSpecialFolder(info1->relativePidl) && _ILIsSpecialFolder(info2->relativePidl))
+    {
+        return 1;
+    }
+    if(_ILIsSpecialFolder(info1->relativePidl) && !_ILIsSpecialFolder(info2->relativePidl))
+    {
+        HRESULT hr;
+        hr = pThis->pDesktop->CompareIDs(0, info1->absolutePidl, info2->absolutePidl);
+        if(!hr) return 0;
+        return (hr > 0) ? -1 : 1;
+    }
+    return StrCmpLogicalW(wszFolder1, wszFolder2);
+}
+
+static LPARAM TreeView_GetItemData(HWND hwndTreeView, HTREEITEM hItem)
+{
+    TVITEM tvItem;
+
+    tvItem.mask = TVIF_PARAM;
+    tvItem.hItem = hItem;
+
+    if (!TreeView_GetItem(hwndTreeView, &tvItem))
+        return 0;
+
+    return tvItem.lParam;
+}
+
+
+// *** IOleWindow methods ***
+HRESULT STDMETHODCALLTYPE CExplorerBand::GetWindow(HWND *lphwnd)
+{
+    if(!lphwnd)
+        return E_INVALIDARG;
+    *lphwnd = m_hWnd;
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CExplorerBand::ContextSensitiveHelp(BOOL fEnterMode)
+{
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE CExplorerBand::ShowDW(BOOL fShow)
+
+// *** IDockingWindow methods ***
+HRESULT STDMETHODCALLTYPE CExplorerBand::CloseDW(DWORD dwReserved)
 {
-    HRESULT hr;
-    if (m_internalDeskBand)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::ShowDW(BOOL fShow=%s)\n", fShow ? "TRUE" : "FALSE");
-        hr = m_internalDeskBand->ShowDW(fShow);
-        DbgPrint("CExplorerBand::ShowDW returning %08lx\n", hr);
-        return hr;
-    }
+    // We do nothing, we don't have anything to save yet
+    TRACE("CloseDW called\n");
+    return S_OK;
+}
 
-    UNIMPLEMENTED;
+HRESULT STDMETHODCALLTYPE CExplorerBand::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
+{
+    /* Must return E_NOTIMPL according to MSDN */
     return E_NOTIMPL;
 }
 
+HRESULT STDMETHODCALLTYPE CExplorerBand::ShowDW(BOOL fShow)
+{
+    fVisible = fShow;
+    ShowWindow(fShow);
+    return S_OK;
+}
 
+
 // *** IDeskBand methods ***
 HRESULT STDMETHODCALLTYPE CExplorerBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
 {
-    HRESULT hr;
-    if (m_internalDeskBand)
+    if (!pdbi)
     {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::GetBandInfo(DWORD dwBandID=%u, DWORD dwViewMode=%u, DESKBANDINFO *pdbi=%p)\n", 
-                 dwBandID, dwViewMode, pdbi);
-        if (pdbi)
-            DbgPrint("\t*pdbi={dwMask=%u, ...}\n", pdbi->dwMask);
-        hr = m_internalDeskBand->GetBandInfo(dwBandID, dwViewMode, pdbi);
-        if (pdbi)
-            DbgPrint("\t*pdbi={dwMask=%u, crBkgnd=%u, ...}\n", pdbi->dwMask, pdbi->crBkgnd);
-        DbgPrint("CExplorerBand::GetBandInfo returning %08lx\n", hr);
-        return hr;
+        return E_INVALIDARG;
     }
+    this->dwBandID = dwBandID;
 
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    if (pdbi->dwMask & DBIM_MINSIZE)
+    {
+        pdbi->ptMinSize.x = 200;
+        pdbi->ptMinSize.y = 30;
+    }
+
+    if (pdbi->dwMask & DBIM_MAXSIZE)
+    {
+        pdbi->ptMaxSize.y = -1;
+    }
+
+    if (pdbi->dwMask & DBIM_INTEGRAL)
+    {
+        pdbi->ptIntegral.y = 1;
+    }
+
+    if (pdbi->dwMask & DBIM_ACTUAL)
+    {
+        pdbi->ptActual.x = 200;
+        pdbi->ptActual.y = 30;
+    }
+
+    if (pdbi->dwMask & DBIM_TITLE)
+    {
+        lstrcpyW(pdbi->wszTitle, L"Explorer");
+    }
+
+    if (pdbi->dwMask & DBIM_MODEFLAGS)
+    {
+        pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
+    }
+
+    if (pdbi->dwMask & DBIM_BKCOLOR)
+    {
+        pdbi->dwMask &= ~DBIM_BKCOLOR;
+    }
+    return S_OK;
 }
 
 
@@ -265,33 +768,70 @@
 HRESULT STDMETHODCALLTYPE CExplorerBand::SetSite(IUnknown *pUnkSite)
 {
     HRESULT hr;
-    if (m_internalObjectWithSite)
+    HWND parentWnd;
+
+    TRACE("SetSite called \n");
+    if(pUnkSite != pSite)
     {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::SetSite(IUnknown *pUnkSite=%p)\n", pUnkSite);
-        hr = m_internalObjectWithSite->SetSite(pUnkSite);
-        DbgPrint("CExplorerBand::SetSite returning %08lx\n", hr);
-        return hr;
+        // Release all refs to the old site
+        pSite = NULL;
+        pServiceProvider = NULL;
+        pBandOle = NULL;
     }
 
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    if(!pUnkSite)
+    {
+        DestroyExplorerBand();
+        DestroyWindow();
+        m_hWnd = NULL;
+        return S_OK;
+    }
+    pSite = pUnkSite;
+    // Grab IServiceProvider for later use
+    hr = pSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &pServiceProvider));
+    if(!SUCCEEDED(hr))
+    {
+        ERR("Query IServiceProvider interface for site failed with %08lx\n", hr);
+        return E_INVALIDARG;
+    }
+    hr = pSite->QueryInterface(IID_PPV_ARG(IOleWindow, &pBandOle));
+    if(!SUCCEEDED(hr))
+    {
+        ERR("Query IOleProvider interface for site failed with %08lx\n", hr);
+        return E_INVALIDARG;
+    }
+    hr = pBandOle->GetWindow(&parentWnd);
+    if(!SUCCEEDED(hr))
+    {
+        ERR("Could not get parent's window ! Status: %08lx\n");
+        return E_INVALIDARG;
+    }
+    if(m_hWnd)
+    {
+        // Change its parent
+        SetParent(parentWnd);
+    }
+    else
+    {
+        HWND wnd = CreateWindow(WC_TREEVIEW, NULL,
+            WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TVS_HASLINES | TVS_HASBUTTONS | TVS_SHOWSELALWAYS /* | TVS_SINGLEEXPAND*/ , // remove TVS_SINGLEEXPAND for now since it has strangr behaviour
+            0, 0, 0, 0, parentWnd, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
+
+        // Subclass the window
+        SubclassWindow(wnd);
+
+        // Initialize our treeview now
+        InitializeExplorerBand();
+    }
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::GetSite(REFIID riid, void **ppvSite)
 {
-    HRESULT hr;
-    if (m_internalObjectWithSite)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::GetSite(REFIID riid=%s, void **ppvSite=%p)\n", wine_dbgstr_guid(&riid), ppvSite);
-        hr = m_internalObjectWithSite->GetSite(riid, ppvSite);
-        if (ppvSite)
-            DbgPrint("\t*ppvSite=%p\n", *ppvSite);
-        DbgPrint("CExplorerBand::GetSite returning %08lx\n", hr);
-        return hr;
-    }
-
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    if(!ppvSite)
+        return E_POINTER;
+    *ppvSite = pSite;
+    return S_OK;
 }
 
 
@@ -298,16 +838,6 @@
 // *** IOleCommandTarget methods ***
 HRESULT STDMETHODCALLTYPE CExplorerBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
 {
-    HRESULT hr;
-    if (m_internalOleCommandTarget)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::QueryStatus(const GUID *pguidCmdGroup=%s, ULONG cCmds=%08x, OLECMD prgCmds []=%p, OLECMDTEXT *pCmdText=%p)\n",
-                 wine_dbgstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
-        hr = m_internalOleCommandTarget->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
-        DbgPrint("CExplorerBand::QueryStatus returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -314,16 +844,6 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
 {
-    HRESULT hr;
-    if (m_internalOleCommandTarget)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::Exec(const GUID *pguidCmdGroup=%s, DWORD nCmdID=%u, DWORD nCmdexecopt=%u, VARIANT *pvaIn=%p, VARIANT *pvaOut=%p)\n",
-                 wine_dbgstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
-        hr = m_internalOleCommandTarget->Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
-        DbgPrint("CExplorerBand::Exec returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -332,18 +852,6 @@
 // *** IServiceProvider methods ***
 HRESULT STDMETHODCALLTYPE CExplorerBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
 {
-    HRESULT hr;
-    if (m_internalServiceProvider)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::QueryService(REFGUID guidService=%s, REFIID riid=%s, void **ppvObject=%p)\n",
-                 wine_dbgstr_guid(&guidService), wine_dbgstr_guid(&riid), ppvObject);
-        hr = m_internalServiceProvider->QueryService(guidService, riid, ppvObject);
-        if (ppvObject)
-            DbgPrint("\t*ppvObject=%p\n", *ppvObject);
-        DbgPrint("CExplorerBand::QueryService returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -352,34 +860,14 @@
 // *** IInputObject methods ***
 HRESULT STDMETHODCALLTYPE CExplorerBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
 {
-    HRESULT hr;
-    if (m_internalInputObject)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::UIActivateIO(BOOL fActivate=%s, LPMSG lpMsg=%p)\n",
-                 fActivate ? "TRUE" : "FALSE", lpMsg);
-        hr = m_internalInputObject->UIActivateIO(fActivate, lpMsg);
-        if (lpMsg)
-            DbgPrint("\t*lpMsg={hwnd=%p, message=%x, wParam=%x, lParam=%x, time=%x, pt={%u %u}}\n",
-            lpMsg->hwnd, lpMsg->message, lpMsg->wParam, lpMsg->lParam, lpMsg->time, lpMsg->pt.x, lpMsg->pt.y);
-        DbgPrint("CExplorerBand::UIActivateIO returning %08lx\n", hr);
-        return hr;
-    }
-
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    if(fActivate)
+        SetFocus();
+    // TODO: handle message
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::HasFocusIO()
 {
-    HRESULT hr;
-    if (m_internalInputObject)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::HasFocusIO()\n");
-        hr = m_internalInputObject->HasFocusIO();
-        DbgPrint("CExplorerBand::HasFocusIO returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -386,18 +874,6 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::TranslateAcceleratorIO(LPMSG lpMsg)
 {
-    HRESULT hr;
-    if (m_internalInputObject)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::TranslateAcceleratorIO(LPMSG lpMsg=%p)\n", lpMsg);
-        hr = m_internalInputObject->TranslateAcceleratorIO(lpMsg);
-        if (lpMsg)
-            DbgPrint("\t*lpMsg={hwnd=%p, message=%x, wParam=%x, lParam=%x, time=%x, pt={%u %u}}\n",
-            lpMsg->hwnd, lpMsg->message, lpMsg->wParam, lpMsg->lParam, lpMsg->time, lpMsg->pt.x, lpMsg->pt.y);
-        DbgPrint("CExplorerBand::TranslateAcceleratorIO returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -406,19 +882,10 @@
 // *** IPersist methods ***
 HRESULT STDMETHODCALLTYPE CExplorerBand::GetClassID(CLSID *pClassID)
 {
-    HRESULT hr;
-    if (m_internalPersistStream)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::GetClassID(CLSID *pClassID=%p)\n", pClassID);
-        hr = m_internalPersistStream->GetClassID(pClassID);
-        if (pClassID)
-            DbgPrint("\t*pClassID=%s\n", wine_dbgstr_guid(pClassID));
-        DbgPrint("CExplorerBand::GetClassID returning %08lx\n", hr);
-        return hr;
-    }
-
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    if(!pClassID)
+        return E_POINTER;
+    memcpy(pClassID, &CLSID_ExplorerBand, sizeof(CLSID));
+    return S_OK;
 }
 
 
@@ -425,15 +892,6 @@
 // *** IPersistStream methods ***
 HRESULT STDMETHODCALLTYPE CExplorerBand::IsDirty()
 {
-    HRESULT hr;
-    if (m_internalPersistStream)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::IsDirty()\n");
-        hr = m_internalPersistStream->IsDirty();
-        DbgPrint("CExplorerBand::IsDirty returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -440,15 +898,6 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::Load(IStream *pStm)
 {
-    HRESULT hr;
-    if (m_internalPersistStream)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::Load(IStream *pStm=%p)\n", pStm);
-        hr = m_internalPersistStream->Load(pStm);
-        DbgPrint("CExplorerBand::Load returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -455,16 +904,6 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::Save(IStream *pStm, BOOL fClearDirty)
 {
-    HRESULT hr;
-    if (m_internalPersistStream)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::Save(IStream *pStm=%p, BOOL fClearDirty=%s)\n",
-                 pStm, fClearDirty ? "TRUE" : "FALSE");
-        hr = m_internalPersistStream->Save(pStm, fClearDirty);
-        DbgPrint("CExplorerBand::Save returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -471,17 +910,7 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
 {
-    HRESULT hr;
-    if (m_internalPersistStream)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::GetSizeMax(ULARGE_INTEGER *pcbSize=%p)\n", pcbSize);
-        hr = m_internalPersistStream->GetSizeMax(pcbSize);
-        if (pcbSize)
-            DbgPrint("\t*pcbSize=%llx\n", pcbSize->QuadPart);
-        DbgPrint("CExplorerBand::GetSizeMax returning %08lx\n", hr);
-        return hr;
-    }
-
+    // TODO: calculate max size
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -490,39 +919,35 @@
 // *** IWinEventHandler methods ***
 HRESULT STDMETHODCALLTYPE CExplorerBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
 {
-    HRESULT hr;
-    if (m_internalWinEventHandler)
+    BOOL bHandled;
+    if(uMsg == WM_NOTIFY)
     {
-        if (m_OnWinEventShown)
-            return m_internalWinEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
-        m_OnWinEventShown = TRUE;
-
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::OnWinEvent(HWND hWnd=%x, UINT uMsg=%x, WPARAM wParam=%x, LPARAM lParam=%x, LRESULT *theResult=%p)\n",
-                 hWnd, uMsg, wParam, lParam, theResult);
-        hr = m_internalWinEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
-        if (theResult)
-            DbgPrint("\t*theResult=%x\n", *theResult);
-        DbgPrint("CExplorerBand::OnWinEvent returning %08lx\n", hr);
-        return hr;
+        NMHDR *pNotifyHeader = (NMHDR*)lParam;
+        switch(pNotifyHeader->code)
+        {
+            case TVN_ITEMEXPANDING:
+                *theResult = OnTreeItemExpanding((LPNMTREEVIEW)lParam);
+                break;
+            case TVN_SELCHANGED:
+                OnTreeItemChanged((LPNMTREEVIEW)lParam);
+                break;
+            case TVN_DELETEITEM:
+                OnTreeItemDeleted((LPNMTREEVIEW)lParam);
+                break;
+            case NM_RCLICK:
+                OnContextMenu(WM_CONTEXTMENU, (WPARAM)m_hWnd, GetMessagePos(), bHandled);
+                *theResult = 1;
+                break;
+            default:
+                break;
+        }
     }
-
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::IsWindowOwner(HWND hWnd)
 {
-    HRESULT hr;
-    if (m_internalWinEventHandler)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::IsWindowOwner(HWND hWnd=%x)\n", hWnd);
-        hr = m_internalWinEventHandler->IsWindowOwner(hWnd);
-        DbgPrint("CExplorerBand::IsWindowOwner returning %08lx\n", hr);
-        return hr;
-    }
-
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    return (hWnd == m_hWnd) ? S_OK : S_FALSE;
 }
 
 
@@ -529,15 +954,6 @@
 // *** IBandNavigate methods ***
 HRESULT STDMETHODCALLTYPE CExplorerBand::Select(long paramC)
 {
-    HRESULT hr;
-    if (m_internalBandNavigate)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::Select(long paramC=%x)\n", paramC);
-        hr = m_internalBandNavigate->Select(paramC);
-        DbgPrint("CExplorerBand::Select returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -546,16 +962,6 @@
 // *** INamespaceProxy ***
 HRESULT STDMETHODCALLTYPE CExplorerBand::GetNavigateTarget(long paramC, long param10, long param14)
 {
-    HRESULT hr;
-    if (m_internalNamespaceProxy)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::GetNavigateTarget(long paramC=%08x, long param10=%08x, long param14=%08x)\n",
-                 paramC, param10, param14);
-        hr = m_internalNamespaceProxy->GetNavigateTarget(paramC, param10, param14);
-        DbgPrint("CExplorerBand::GetNavigateTarget returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -562,15 +968,6 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::Invoke(long paramC)
 {
-    HRESULT hr;
-    if (m_internalNamespaceProxy)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::Invoke(long paramC=%08x)\n", paramC);
-        hr = m_internalNamespaceProxy->Invoke(paramC);
-        DbgPrint("CExplorerBand::Invoke returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -577,15 +974,6 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::OnSelectionChanged(long paramC)
 {
-    HRESULT hr;
-    if (m_internalNamespaceProxy)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::OnSelectionChanged(long paramC=%08x)\n", paramC);
-        hr = m_internalNamespaceProxy->OnSelectionChanged(paramC);
-        DbgPrint("CExplorerBand::OnSelectionChanged returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -592,16 +980,6 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::RefreshFlags(long paramC, long param10, long param14)
 {
-    HRESULT hr;
-    if (m_internalNamespaceProxy)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::RefreshFlags(long paramC=%08x, long param10=%08x, long param14=%08x)\n",
-                 paramC, param10, param14);
-        hr = m_internalNamespaceProxy->RefreshFlags(paramC, param10, param14);
-        DbgPrint("CExplorerBand::RefreshFlags returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -608,15 +986,6 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::CacheItem(long paramC)
 {
-    HRESULT hr;
-    if (m_internalNamespaceProxy)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::CacheItem(long paramC=%08x)\n", paramC);
-        hr = m_internalNamespaceProxy->CacheItem(paramC);
-        DbgPrint("CExplorerBand::CacheItem returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -625,17 +994,6 @@
 // *** IDispatch methods ***
 HRESULT STDMETHODCALLTYPE CExplorerBand::GetTypeInfoCount(UINT *pctinfo)
 {
-    HRESULT hr;
-    if (m_internalDispatch)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::GetTypeInfoCount(UINT *pctinfo=%p)\n", pctinfo);
-        hr = m_internalDispatch->GetTypeInfoCount(pctinfo);
-        if (pctinfo)
-            DbgPrint("\t*pctinfo=%08x\n", *pctinfo);
-        DbgPrint("CExplorerBand::GetTypeInfoCount returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -642,18 +1000,6 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
 {
-    HRESULT hr;
-    if (m_internalDispatch)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::GetTypeInfo(UINT iTInfo=%u, LCID lcid=%08x, ITypeInfo **ppTInfo=%p)\n",
-                 iTInfo, lcid, ppTInfo);
-        hr = m_internalDispatch->GetTypeInfo(iTInfo, lcid, ppTInfo);
-        if (ppTInfo)
-            DbgPrint("\t*ppTInfo=%08x\n", *ppTInfo);
-        DbgPrint("CExplorerBand::GetTypeInfo returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -660,23 +1006,6 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
 {
-    HRESULT hr;
-    if (m_internalDispatch)
-    {
-        DbgPrint("HRESULT STDMETHODCALLTYPE CExplorerBand::GetIDsOfNames(REFIID riid=%s, LPOLESTR *rgszNames=%S, UINT cNames=%u, LCID lcid=%08x, DISPID *rgDispId=%p)\n",
-                 wine_dbgstr_guid(&riid), rgszNames, cNames, lcid, rgDispId);
-        hr = m_internalDispatch->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId);
-        if (rgDispId && SUCCEEDED(hr))
-        {
-            for (UINT i = 0; i < cNames; i++)
-            {
-                DbgPrint("\trgDispId[%d]=%08x\n", rgDispId[i]);
-            }
-        }
-        DbgPrint("CExplorerBand::GetTypeInfo returning %08lx\n", hr);
-        return hr;
-    }
-
     UNIMPLEMENTED;
     return E_NOTIMPL;
 }
@@ -683,7 +1012,12 @@
 
 HRESULT STDMETHODCALLTYPE CExplorerBand::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
 {
-    UNIMPLEMENTED;
+    switch (dispIdMember)
+    {
+        case DISPID_NAVIGATECOMPLETE2:
+           TRACE("DISPID_NAVIGATECOMPLETE2 received\n");
+           NavigateToCurrentFolder();
+           return S_OK;
+    }
     return E_NOTIMPL;
 }
-
