[BROWSEUI]
[reactos.git] / dll / win32 / browseui / shellbrowser.cpp
index 05e322c..ceba070 100644 (file)
 #include <shellapi.h>
 #include <htiframe.h>
 
+extern "C"
+BOOL WINAPI Shell_GetImageLists(
+    _Out_  HIMAGELIST *phiml,
+    _Out_  HIMAGELIST *phimlSmall
+    );
+
 #include "newatlinterfaces.h"
 
 /*
@@ -194,8 +200,8 @@ HRESULT WINAPI SHBindToFolder(LPCITEMIDLIST path, IShellFolder **newFolder)
 {
     CComPtr<IShellFolder>                   desktop;
 
-    ::SHGetDesktopFolder(&desktop);
-    if (desktop == NULL)
+    HRESULT hr = ::SHGetDesktopFolder(&desktop);
+    if (FAILED(hr))
         return E_FAIL;
     if (path == NULL || path->mkid.cb == 0)
     {
@@ -203,7 +209,7 @@ HRESULT WINAPI SHBindToFolder(LPCITEMIDLIST path, IShellFolder **newFolder)
         desktop.p->AddRef ();
         return S_OK;
     }
-    return desktop->BindToObject (path, NULL, IID_IShellFolder, reinterpret_cast<void **>(newFolder));
+    return desktop->BindToObject (path, NULL, IID_PPV_ARG(IShellFolder, newFolder));
 }
 
 static const TCHAR szCabinetWndClass[] = TEXT("CabinetWClassX");
@@ -243,7 +249,7 @@ void CToolbarProxy::Initialize(HWND parent, IUnknown *explorerToolbar)
         SubclassWindow(myWindow);
         SetWindowPos(NULL, -32000, -32000, 0, 0, SWP_NOOWNERZORDER | SWP_NOZORDER);
         hResult = explorerToolbar->QueryInterface(
-            IID_IExplorerToolbar, reinterpret_cast<void **>(&fExplorerToolbar));
+            IID_PPV_ARG(IExplorerToolbar, &fExplorerToolbar));
     }
 }
 
@@ -281,7 +287,7 @@ Switch to a new bar when it receives an Exec(CGID_IDeskBand, 1, 1, vaIn, NULL);
 */
 
 class CShellBrowser :
-    public CWindowImpl<CShellBrowser, CWindow, CControlWinTraits>,
+    public CWindowImpl<CShellBrowser, CWindow, CFrameWinTraits>,
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IShellBrowser,
     public IDropTarget,
@@ -326,6 +332,7 @@ private:
     IOleObject                              *fHistoryObject;
     IStream                                 *fHistoryStream;
     IBindCtx                                *fHistoryBindContext;
+    HACCEL m_hAccel;
 public:
 #if 0
     ULONG InternalAddRef()
@@ -609,6 +616,7 @@ public:
     virtual HRESULT STDMETHODCALLTYPE GetPositionCookie(DWORD *pdwPositioncookie);
 
     // message handlers
+    LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
     LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
     LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
     LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
@@ -621,6 +629,7 @@ public:
     LRESULT OnGoBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
     LRESULT OnGoForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
     LRESULT OnGoUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
+    LRESULT OnBackspace(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
     LRESULT OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
     LRESULT OnIsThisLegal(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
     LRESULT OnToggleStatusBarVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
@@ -646,6 +655,7 @@ public:
     }
 
     BEGIN_MSG_MAP(CShellBrowser)
+        MESSAGE_HANDLER(WM_CREATE, OnCreate)
         MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
         MESSAGE_HANDLER(WM_SIZE, OnSize)
         MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
@@ -669,6 +679,7 @@ public:
         COMMAND_ID_HANDLER(IDM_TOOLBARS_LINKSBAR, OnToggleLinksBandVisible)
         COMMAND_ID_HANDLER(IDM_TOOLBARS_TEXTLABELS, OnToggleTextLabels)
         COMMAND_ID_HANDLER(IDM_TOOLBARS_CUSTOMIZE, OnToolbarCustomize)
+        COMMAND_ID_HANDLER(IDM_BACKSPACE, OnBackspace)
         COMMAND_RANGE_HANDLER(IDM_GOTO_TRAVEL_FIRSTTARGET, IDM_GOTO_TRAVEL_LASTTARGET, OnGoTravel)
         MESSAGE_HANDLER(WM_COMMAND, RelayCommands)
     END_MSG_MAP()
@@ -708,8 +719,7 @@ CShellBrowser::CShellBrowser()
     fCurrentDirectoryPIDL = NULL;
     fStatusBar = NULL;
     fStatusBarVisible = true;
-    for (INT x = 0; x < 3; x++)
-        fClientBars[x].hwnd = NULL;
+    memset(fClientBars, 0, sizeof(fClientBars));
     fCurrentMenuBar = NULL;
     fHistoryObject = NULL;
     fHistoryStream = NULL;
@@ -727,7 +737,6 @@ HRESULT CShellBrowser::Initialize(LPITEMIDLIST pidl, long b, long c, long d)
     CComPtr<IPersistStreamInit>             persistStreamInit;
     CComPtr<IOleCommandTarget>              commandTarget;
     CComPtr<IObjectWithSite>                objectSite;
-    RECT                                    bounds = {0, 0, 800, 591};
     HRESULT                                 hResult;
 
     _AtlInitialConstruct();
@@ -738,35 +747,35 @@ HRESULT CShellBrowser::Initialize(LPITEMIDLIST pidl, long b, long c, long d)
     }
 
     // create window
-    Create(HWND_DESKTOP, bounds, NULL, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0U);
+    Create(HWND_DESKTOP);
     if (m_hWnd == NULL)
         return E_FAIL;
 
 #if 0
-    hResult = CoCreateInstance(CLSID_InternetToolbar, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)&fClientBars[BIInternetToolbar].clientBar);
+    hResult = CoCreateInstance(CLSID_InternetToolbar, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, &fClientBars[BIInternetToolbar].clientBar));
     if (FAILED(hResult))
         return hResult;
 #else
-    hResult = CreateInternetToolbar(IID_IUnknown, (void **)&fClientBars[BIInternetToolbar].clientBar);
+    hResult = CreateInternetToolbar(IID_PPV_ARG(IUnknown, &fClientBars[BIInternetToolbar].clientBar));
     if (FAILED(hResult))
         return hResult;
 #endif
 
     // create interfaces
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IDockingWindow, reinterpret_cast<void **>(&dockingWindow));
+        IID_PPV_ARG(IDockingWindow, &dockingWindow));
     if (FAILED(hResult))
         return hResult;
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IPersistStreamInit, reinterpret_cast<void **>(&persistStreamInit));
+        IID_PPV_ARG(IPersistStreamInit, &persistStreamInit));
     if (FAILED(hResult))
         return hResult;
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IOleCommandTarget, reinterpret_cast<void **>(&commandTarget));
+        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
     if (FAILED(hResult))
         return hResult;
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IObjectWithSite, reinterpret_cast<void **>(&objectSite));
+        IID_PPV_ARG(IObjectWithSite, &objectSite));
     if (FAILED(hResult))
         return hResult;
 
@@ -803,40 +812,13 @@ HRESULT CShellBrowser::Initialize(LPITEMIDLIST pidl, long b, long c, long d)
                     _AtlBaseModule.GetModuleInstance(), 0);
     fStatusBarVisible = true;
 
-    FOLDERSETTINGS                          newFolderSettings;
-
     // browse 
-    newFolderSettings.ViewMode = FVM_LIST;
-    newFolderSettings.fFlags = 0;
     hResult = BrowseToPIDL(pidl, BTP_UPDATE_NEXT_HISTORY);
     if (FAILED(hResult))
         return hResult;
 
     ShowWindow(SW_SHOWNORMAL);
 
-
-    // test code to make brand band animate
-    {
-        CComPtr<IOleCommandTarget>              oleCommandTarget;
-        CComPtr<IServiceProvider>               serviceProvider;
-        CComPtr<IBandSite>                      bandSite;
-        CComPtr<IDeskBand>                      deskBand;
-        CComPtr<IWinEventHandler>               winEventHandler;
-        HRESULT                                 hResult;
-
-        if (fClientBars[BIInternetToolbar].clientBar.p == NULL)
-            return 0;
-        hResult = fClientBars[BIInternetToolbar].clientBar->
-            QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
-        hResult = serviceProvider->QueryService(SID_IBandSite, IID_IBandSite, reinterpret_cast<void **>(&bandSite));
-        hResult = bandSite->QueryBand(5, &deskBand, NULL, NULL, 0);
-        deskBand->QueryInterface(IID_IWinEventHandler, reinterpret_cast<void **>(&winEventHandler));
-        winEventHandler->IsWindowOwner(NULL);
-        deskBand->QueryInterface(IID_IOleCommandTarget, reinterpret_cast<void **>(&oleCommandTarget));
-        oleCommandTarget->QueryStatus(&CGID_BrandCmdGroup, 0, NULL, NULL);
-        oleCommandTarget->Exec(&CGID_BrandCmdGroup, BBID_STARTANIMATION, 0, NULL, NULL);
-    }
-
     return S_OK;
 }
 
@@ -849,7 +831,10 @@ HRESULT CShellBrowser::BrowseToPIDL(LPCITEMIDLIST pidl, long flags)
     // called by shell view to browse to new folder
     // also called by explorer band to navigate to new folder
     hResult = SHBindToFolder(pidl, &newFolder);
-    newFolderSettings.ViewMode = FVM_LIST;
+    if (FAILED(hResult))
+        return hResult;
+
+    newFolderSettings.ViewMode = FVM_ICON;
     newFolderSettings.fFlags = 0;
     hResult = BrowseToPath(newFolder, pidl, &newFolderSettings, flags);
     if (FAILED(hResult))
@@ -926,8 +911,7 @@ HRESULT IEGetNameAndFlagsEx(LPITEMIDLIST pidl, SHGDNF uFlags, long param10,
     STRRET                                  L108;
     HRESULT                                 hResult;
 
-    hResult = SHBindToFolderIDListParent(NULL, pidl, &IID_IShellFolder,
-        reinterpret_cast<void **>(&parentFolder), &childPIDL);
+    hResult = SHBindToFolderIDListParent(NULL, pidl, &IID_PPV_ARG(IShellFolder, &parentFolder), &childPIDL);
     hResult = parentFolder->GetDisplayNameOf(childPIDL, uFlags, &L108);
     StrRetToBufW(&L108, childPIDL, pszBuf, cchBuf);
     if (rgfInOut)
@@ -944,7 +928,6 @@ long IEGetNameAndFlags(LPITEMIDLIST pidl, SHGDNF uFlags, LPWSTR pszBuf, UINT cch
 HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
     LPCITEMIDLIST absolutePIDL, FOLDERSETTINGS *folderSettings, long flags)
 {
-    CComPtr<IOleCommandTarget>              oleCommandTarget;
     CComPtr<IObjectWithSite>                objectWithSite;
     CComPtr<IShellFolder>                   saveCurrentShellFolder;
     CComPtr<IShellView>                     saveCurrentShellView;
@@ -975,7 +958,7 @@ HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
     }
 
     // create view object
-    hResult = newShellFolder->CreateViewObject(m_hWnd, IID_IShellView, reinterpret_cast<void **>(&newShellView));
+    hResult = newShellFolder->CreateViewObject(m_hWnd, IID_PPV_ARG(IShellView, &newShellView));
     if (FAILED(hResult))
         return hResult;
     previousView = fCurrentShellViewWindow;
@@ -987,7 +970,7 @@ HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
         ::SendMessage(fCurrentShellViewWindow, WM_SETREDRAW, 0, 0);
 
     // set site
-    hResult = newShellView->QueryInterface(IID_IObjectWithSite, reinterpret_cast<void **>(&objectWithSite));
+    hResult = newShellView->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
     if (SUCCEEDED(hResult) && objectWithSite.p != NULL)
         hResult = objectWithSite->SetSite(static_cast<IDropTarget *>(this));
 
@@ -1030,10 +1013,6 @@ HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
         saveCurrentShellView->DestroyViewWindow();
     fCurrentShellViewWindow = newShellViewWindow;
 
-    // get command target
-    oleCommandTarget.Release();
-    hResult = newShellView->QueryInterface(IID_IOleCommandTarget, reinterpret_cast<void **>(&oleCommandTarget));
-
     // no use
     saveCurrentShellView.Release();
     saveCurrentShellFolder.Release();
@@ -1053,7 +1032,18 @@ HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
     }
 
     // completed
-    FireNavigateComplete(L"c:\\temp");      // TODO: use real path here
+    nameFlags = SHGDN_FORADDRESSBAR | SHGDN_FORPARSING;
+    hResult = IEGetNameAndFlags(fCurrentDirectoryPIDL, nameFlags, newTitle,
+        sizeof(newTitle) / sizeof(wchar_t), NULL);
+    if (SUCCEEDED(hResult))
+    {
+        FireNavigateComplete(newTitle);
+    }
+    else
+    {
+        FireNavigateComplete(L"ERROR");
+    }
+
     if (fCabinetState.fFullPathTitle)
         nameFlags = SHGDN_FORADDRESSBAR | SHGDN_FORPARSING;
     else
@@ -1061,8 +1051,27 @@ HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
     hResult = IEGetNameAndFlags(fCurrentDirectoryPIDL, nameFlags, newTitle,
         sizeof(newTitle) / sizeof(wchar_t), NULL);
     if (SUCCEEDED(hResult))
+    {
         SetWindowText(newTitle);
 
+        LPCITEMIDLIST pidlChild;
+        INT index, indexOpen;
+        HIMAGELIST himlSmall, himlLarge;
+
+        CComPtr<IShellFolder> sf;
+        SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild);
+
+        index = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen);
+
+        Shell_GetImageLists(&himlLarge, &himlSmall);
+
+        HICON icSmall = ImageList_GetIcon(himlSmall, indexOpen, 0);
+        HICON icLarge = ImageList_GetIcon(himlLarge, indexOpen, 0);
+
+        SendMessage(WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(icSmall));
+        SendMessage(WM_SETICON, ICON_BIG,   reinterpret_cast<LPARAM>(icLarge));
+    }
+
     // TODO: Update the window icon
 
     FireCommandStateChangeAll();
@@ -1080,10 +1089,10 @@ HRESULT CShellBrowser::GetMenuBand(REFIID riid, void **shellMenu)
     if (fClientBars[BIInternetToolbar].clientBar.p == NULL)
         return E_FAIL;
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
+        IID_PPV_ARG(IServiceProvider, &serviceProvider));
     if (FAILED(hResult))
         return hResult;
-    hResult = serviceProvider->QueryService(SID_IBandSite, IID_IBandSite, reinterpret_cast<void **>(&bandSite));
+    hResult = serviceProvider->QueryService(SID_IBandSite, IID_PPV_ARG(IBandSite, &bandSite));
     if (FAILED(hResult))
         return hResult;
     hResult = bandSite->QueryBand(1, &deskBand, NULL, NULL, 0);
@@ -1108,15 +1117,15 @@ HRESULT CShellBrowser::GetBaseBar(bool vertical, IUnknown **theBaseBar)
         cache = &fClientBars[BIHorizontalBaseBar].clientBar.p;
     if (*cache == NULL)
     {
-        hResult = CreateBaseBar(IID_IUnknown, reinterpret_cast<void **>(&newBaseBar));
+        hResult = CreateBaseBar(IID_PPV_ARG(IUnknown, &newBaseBar));
         if (FAILED(hResult))
             return hResult;
-        hResult = CreateBaseBarSite(IID_IUnknown, reinterpret_cast<void **>(&newBaseBarSite));
+        hResult = CreateBaseBarSite(IID_PPV_ARG(IUnknown, &newBaseBarSite));
         if (FAILED(hResult))
             return hResult;
 
         // tell the new base bar about the shell browser
-        hResult = newBaseBar->QueryInterface(IID_IObjectWithSite, reinterpret_cast<void **>(&objectWithSite));
+        hResult = newBaseBar->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
         if (FAILED(hResult))
             return hResult;
         hResult = objectWithSite->SetSite(static_cast<IDropTarget *>(this));
@@ -1124,7 +1133,7 @@ HRESULT CShellBrowser::GetBaseBar(bool vertical, IUnknown **theBaseBar)
             return hResult;
 
         // tell the new base bar about the new base bar site
-        hResult = newBaseBar->QueryInterface(IID_IDeskBar, reinterpret_cast<void **>(&deskBar));
+        hResult = newBaseBar->QueryInterface(IID_PPV_ARG(IDeskBar, &deskBar));
         if (FAILED(hResult))
             return hResult;
         hResult = deskBar->SetClient(newBaseBarSite);
@@ -1132,7 +1141,7 @@ HRESULT CShellBrowser::GetBaseBar(bool vertical, IUnknown **theBaseBar)
             return hResult;
 
         // tell the new base bar site about the new base bar
-        hResult = newBaseBarSite->QueryInterface(IID_IDeskBarClient, reinterpret_cast<void **>(&deskBarClient));
+        hResult = newBaseBarSite->QueryInterface(IID_PPV_ARG(IDeskBarClient, &deskBarClient));
         if (FAILED(hResult))
             return hResult;
         hResult = deskBarClient->SetDeskBarSite(newBaseBar);
@@ -1141,7 +1150,7 @@ HRESULT CShellBrowser::GetBaseBar(bool vertical, IUnknown **theBaseBar)
 
         *cache = newBaseBar.Detach();
     }
-    return (*cache)->QueryInterface(IID_IUnknown, reinterpret_cast<void **>(theBaseBar));
+    return (*cache)->QueryInterface(IID_PPV_ARG(IUnknown, theBaseBar));
 }
 
 HRESULT CShellBrowser::ShowBand(const CLSID &classID, bool vertical)
@@ -1155,23 +1164,24 @@ HRESULT CShellBrowser::ShowBand(const CLSID &classID, bool vertical)
     VARIANT                                 vaIn;
     HRESULT                                 hResult;
 
+    __debugbreak();
+
     hResult = GetBaseBar(vertical, (IUnknown **)&theBaseBar);
     if (FAILED(hResult))
         return hResult;
-    hResult = CoCreateInstance(classID, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown,
-        reinterpret_cast<void **>(&newBand));
+    hResult = CoCreateInstance(classID, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, &newBand));
     if (FAILED(hResult))
         return hResult;
-    hResult = theBaseBar->QueryInterface(IID_IDeskBar, reinterpret_cast<void **>(&deskBar));
+    hResult = theBaseBar->QueryInterface(IID_PPV_ARG(IDeskBar, &deskBar));
     if (FAILED(hResult))
         return hResult;
     hResult = deskBar->GetClient(&baseBarSite);
     if (FAILED(hResult))
         return hResult;
-    hResult = theBaseBar->QueryInterface(IID_IDockingWindow, reinterpret_cast<void **>(&dockingWindow));
+    hResult = theBaseBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
     if (FAILED(hResult))
         return hResult;
-    hResult = baseBarSite->QueryInterface(IID_IOleCommandTarget, reinterpret_cast<void **>(&oleCommandTarget));
+    hResult = baseBarSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
     if (FAILED(hResult))
         return hResult;
     V_VT(&vaIn) = VT_UNKNOWN;
@@ -1228,18 +1238,18 @@ HRESULT CShellBrowser::DoFolderOptions()
 
     // create sheet object
     hResult = CoCreateInstance(CLSID_ShellFldSetExt, NULL, CLSCTX_INPROC_SERVER,
-        IID_IShellPropSheetExt, reinterpret_cast<void **>(&folderOptionsSheet));
+        IID_PPV_ARG(IShellPropSheetExt, &folderOptionsSheet));
     if (FAILED(hResult))
         return E_FAIL;
 
     // must set site in order for Apply to all Folders on Advanced page to be enabled
-    hResult = folderOptionsSheet->QueryInterface(IID_IObjectWithSite, reinterpret_cast<void **>(&objectWithSite));
+    hResult = folderOptionsSheet->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
     if (SUCCEEDED(hResult) && objectWithSite.p != NULL)
         hResult = objectWithSite->SetSite(static_cast<IDispatch *>(this));
     m_PropSheet.phpage = m_psp;
 
 #if 0
-    hResult = CoCreateInstance(CLSID_GlobalFolderSettings, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalFolderSettings, (void **)&globalSettings);
+    hResult = CoCreateInstance(CLSID_GlobalFolderSettings, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IGlobalFolderSettings, &globalSettings));
     if (FAILED(hResult))
         return E_FAIL;
     hResult = globalSettings->Get(&shellState, sizeof(shellState));
@@ -1286,7 +1296,7 @@ LRESULT CALLBACK CShellBrowser::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam,
     previousMessage = pThis->m_pCurrentMsg;
     pThis->m_pCurrentMsg = &msg;
 
-    hResult = pThis->GetMenuBand(IID_IMenuBand, reinterpret_cast<void **>(&menuBand));
+    hResult = pThis->GetMenuBand(IID_PPV_ARG(IMenuBand, &menuBand));
     if (SUCCEEDED(hResult) && menuBand.p != NULL)
     {
         hResult = menuBand->TranslateMenuMessage(&msg, &lResult);
@@ -1326,13 +1336,11 @@ void CShellBrowser::RepositionBars()
 {
     RECT                                    clientRect;
     RECT                                    statusRect;
-    RECT                                    toolbarRect;
     int                                     x;
-    HRESULT                                 hResult;
 
     GetClientRect(&clientRect);
 
-    if (fStatusBarVisible)
+    if (fStatusBarVisible && fStatusBar)
     {
         ::GetWindowRect(fStatusBar, &statusRect);
         ::SetWindowPos(fStatusBar, NULL, clientRect.left, clientRect.bottom - (statusRect.bottom - statusRect.top),
@@ -1343,33 +1351,56 @@ void CShellBrowser::RepositionBars()
 
     for (x = 0; x < 3; x++)
     {
-        CComPtr<IOleWindow>                 oleWindow;
-
-        if (fClientBars[x].hwnd == NULL && fClientBars[x].clientBar != NULL)
+        HWND hwnd = fClientBars[x].hwnd;
+        RECT borderSpace = fClientBars[x].borderSpace;
+        if (hwnd == NULL && fClientBars[x].clientBar != NULL)
         {
-            hResult = fClientBars[x].clientBar->QueryInterface(
-                IID_IOleWindow, reinterpret_cast<void **>(&oleWindow));
-            if (SUCCEEDED(hResult))
-                hResult = oleWindow->GetWindow(&fClientBars[x].hwnd);
+            IUnknown_GetWindow(fClientBars[x].clientBar, &hwnd);
+            fClientBars[x].hwnd = hwnd;
         }
-        if (fClientBars[x].hwnd != NULL)
+        if (hwnd != NULL)
         {
-            toolbarRect = clientRect;
-            if (fClientBars[x].borderSpace.top != 0)
-                toolbarRect.bottom = toolbarRect.top + fClientBars[x].borderSpace.top;
-            else if (fClientBars[x].borderSpace.bottom != 0)
-                toolbarRect.top = toolbarRect.bottom - fClientBars[x].borderSpace.bottom;
-            if (fClientBars[x].borderSpace.left != 0)
-                toolbarRect.right = toolbarRect.left + fClientBars[x].borderSpace.left;
-            else if (fClientBars[x].borderSpace.right != 0)
-                toolbarRect.left = toolbarRect.right - fClientBars[x].borderSpace.right;
-            ::SetWindowPos(fClientBars[x].hwnd, NULL, toolbarRect.left, toolbarRect.top,
-                                toolbarRect.right - toolbarRect.left,
-                                toolbarRect.bottom - toolbarRect.top, SWP_NOOWNERZORDER | SWP_NOZORDER);
-            clientRect.top += fClientBars[x].borderSpace.top;
-            clientRect.left += fClientBars[x].borderSpace.left;
-            clientRect.bottom += fClientBars[x].borderSpace.bottom;
-            clientRect.right += fClientBars[x].borderSpace.right;
+            RECT toolbarRect = clientRect;
+            if (borderSpace.top != 0)
+            {
+                toolbarRect.bottom = toolbarRect.top + borderSpace.top;
+            }
+            else if (borderSpace.bottom != 0)
+            {
+                toolbarRect.top = toolbarRect.bottom - borderSpace.bottom;
+            }
+            else if (borderSpace.left != 0)
+            {
+                toolbarRect.right = toolbarRect.left + borderSpace.left;
+            }
+            else if (borderSpace.right != 0)
+            {
+                toolbarRect.left = toolbarRect.right - borderSpace.right;
+            }
+
+            ::SetWindowPos(hwnd, NULL,
+                toolbarRect.left,
+                toolbarRect.top,
+                toolbarRect.right - toolbarRect.left,
+                toolbarRect.bottom - toolbarRect.top,
+                SWP_NOOWNERZORDER | SWP_NOZORDER);
+
+            if (borderSpace.top != 0)
+            {
+                clientRect.top = toolbarRect.bottom;
+            }
+            else if (borderSpace.bottom != 0)
+            {
+                clientRect.bottom = toolbarRect.top;
+            }
+            else if (borderSpace.left != 0)
+            {
+                clientRect.left = toolbarRect.right;
+            }
+            else if (borderSpace.right != 0)
+            {
+                clientRect.right = toolbarRect.left;
+            }
         }
     }
     ::SetWindowPos(fCurrentShellViewWindow, NULL, clientRect.left, clientRect.top,
@@ -1395,7 +1426,7 @@ HRESULT CShellBrowser::FireEvent(DISPID dispIdMember, int argCount, VARIANT *arg
         {
             CComPtr<IDispatch>          theDispatch;
 
-            hResult = (*pp)->QueryInterface(IID_IDispatch, reinterpret_cast<void **>(&theDispatch));
+            hResult = (*pp)->QueryInterface(IID_PPV_ARG(IDispatch, &theDispatch));
             hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
         }
         pp++;
@@ -1407,7 +1438,7 @@ HRESULT CShellBrowser::FireEvent(DISPID dispIdMember, int argCount, VARIANT *arg
         {
             CComPtr<IDispatch>          theDispatch;
 
-            hResult = (*pp)->QueryInterface(IID_IDispatch, reinterpret_cast<void **>(&theDispatch));
+            hResult = (*pp)->QueryInterface(IID_PPV_ARG(IDispatch, &theDispatch));
             hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
         }
         pp++;
@@ -1528,7 +1559,7 @@ void CShellBrowser::UpdateViewMenu(HMENU theMenu)
     commandList[4].cmdID = ITID_CUSTOMIZEENABLED;
 
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IOleCommandTarget, reinterpret_cast<void **>(&oleCommandTarget));
+        IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
     if (SUCCEEDED(hResult))
         hResult = oleCommandTarget->QueryStatus(&CGID_PrivCITCommands, 5, commandList, NULL);
     if (FAILED(hResult))
@@ -1565,10 +1596,10 @@ bool IUnknownIsEqual(IUnknown *int1, IUnknown *int2)
         return true;
     if (int1 == NULL || int2 == NULL)
         return false;
-    hResult = int1->QueryInterface(IID_IUnknown, reinterpret_cast<void **>(&int1Retry));
+    hResult = int1->QueryInterface(IID_PPV_ARG(IUnknown, &int1Retry));
     if (FAILED(hResult))
         return false;
-    hResult = int2->QueryInterface(IID_IUnknown, reinterpret_cast<void **>(&int2Retry));
+    hResult = int2->QueryInterface(IID_PPV_ARG(IUnknown, &int2Retry));
     if (FAILED(hResult))
         return false;
     if (int1Retry == int2Retry)
@@ -1578,8 +1609,9 @@ bool IUnknownIsEqual(IUnknown *int1, IUnknown *int2)
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::GetBorderDW(IUnknown *punkObj, LPRECT prcBorder)
 {
-    RECT                                    availableBounds;
-    static const INT                        excludeItems[] = {1, 1, 1, 0xa001, 0, 0};
+    static const INT excludeItems[] = { 1, 1, 1, 0xa001, 0, 0 };
+
+    RECT availableBounds;
 
     GetEffectiveClientRect(m_hWnd, &availableBounds, excludeItems);
     for (INT x = 0; x < 3; x++)
@@ -1628,8 +1660,7 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::QueryStatus(const GUID *pguidCmdGroup,
     {
         if (fCurrentShellView.p != NULL)
         {
-            hResult = fCurrentShellView->QueryInterface(IID_IOleCommandTarget,
-                reinterpret_cast<void **>(&commandTarget));
+            hResult = fCurrentShellView->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
             if (SUCCEEDED(hResult) && commandTarget.p != NULL)
                 return commandTarget->QueryStatus(NULL, 1, prgCmds, pCmdText);
         }
@@ -1824,7 +1855,7 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU h
 
     if (IsMenu(hmenuShared) == FALSE)
         return E_FAIL;
-    hResult = GetMenuBand(IID_IShellMenu, reinterpret_cast<void **>(&shellMenu));
+    hResult = GetMenuBand(IID_PPV_ARG(IShellMenu, &shellMenu));
     if (FAILED(hResult))
         return hResult;
     hResult = shellMenu->SetMenu(hmenuShared, NULL, SMSET_DONTOWN);
@@ -1843,6 +1874,15 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::RemoveMenusSB(HMENU hmenuShared)
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::SetStatusTextSB(LPCOLESTR pszStatusText)
 {
+    //
+    if (pszStatusText)
+    {
+        ::SetWindowText(fStatusBar, pszStatusText);
+    }
+    else
+    {
+
+    }
     return E_NOTIMPL;
 }
 
@@ -1853,7 +1893,9 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::EnableModelessSB(BOOL fEnable)
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::TranslateAcceleratorSB(MSG *pmsg, WORD wID)
 {
-    return E_NOTIMPL;
+    if (!::TranslateAcceleratorW(m_hWnd, m_hAccel, pmsg))
+        return S_FALSE;
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags)
@@ -1971,6 +2013,8 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::QueryService(REFGUID guidService, REFII
         return this->QueryInterface(riid, ppvObject);
     if (IsEqualIID(guidService, SID_IExplorerToolbar))
         return fClientBars[BIInternetToolbar].clientBar->QueryInterface(riid, ppvObject);
+    if (IsEqualIID(riid, IID_IShellBrowser))
+        return this->QueryInterface(riid, ppvObject);
     return E_NOINTERFACE;
 }
 
@@ -2029,11 +2073,13 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::GetTravelLog(ITravelLog **pptl)
     HRESULT                                 hResult;
 
     // called by toolbar when displaying tooltips
-    if (pptl != NULL)
-        *pptl = NULL;
+    if (pptl == NULL)
+        return E_FAIL;
+
+    *pptl = NULL;
     if (fTravelLog.p == NULL)
     {
-        hResult = CreateTravelLog(IID_ITravelLog, reinterpret_cast<void **>(&fTravelLog));
+        hResult = CreateTravelLog(IID_PPV_ARG(ITravelLog, &fTravelLog));
         if (FAILED(hResult))
             return hResult;
     }
@@ -2210,7 +2256,8 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::OnSize(WPARAM wParam)
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::OnCreate(struct tagCREATESTRUCTW *pcs)
 {
-    return E_NOTIMPL;
+    m_hAccel = LoadAcceleratorsW(GetModuleHandle(L"browseui.dll"), MAKEINTRESOURCEW(256));
+    return S_OK;
 }
 
 LRESULT STDMETHODCALLTYPE CShellBrowser::OnCommand(WPARAM wParam, LPARAM lParam)
@@ -2489,7 +2536,13 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::_SetFocus(LPTOOLBARITEM ptbi, HWND hwnd
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::v_MayTranslateAccelerator(MSG *pmsg)
 {
-    return E_NOTIMPL;
+    if (fCurrentShellView->TranslateAcceleratorW(pmsg) != S_OK)
+    {
+        if (TranslateAcceleratorSB(pmsg, 0) != S_OK)
+            return S_FALSE;
+        return S_OK;
+    }
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CShellBrowser::_GetBorderDWHelper(IUnknown *punkSrc, LPRECT lprectBorder, BOOL bUseHmonitor)
@@ -2554,7 +2607,7 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::Refresh2(VARIANT *Level)
     CComPtr<IOleCommandTarget>              oleCommandTarget;
     HRESULT                                 hResult;
 
-    hResult = fCurrentShellView->QueryInterface(IID_IOleCommandTarget, reinterpret_cast<void **>(&oleCommandTarget));
+    hResult = fCurrentShellView->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
     if (FAILED(hResult))
         return hResult;
     return oleCommandTarget->Exec(NULL, 22, 1, Level, NULL);
@@ -2932,7 +2985,7 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::LoadHistory(IStream *pStream, IBindCtx
         return E_FAIL;
     }
     hResult = CoCreateInstance(oldState.persistClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER,
-        IID_IOleObject, reinterpret_cast<void **>(&viewHistoryObject));
+        IID_PPV_ARG(IOleObject, &viewHistoryObject));
     fHistoryObject = viewHistoryObject;
     fHistoryStream = pStream;
     fHistoryBindContext = pbc;
@@ -2953,7 +3006,7 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::SaveHistory(IStream *pStream)
     HRESULT                                 hResult;
 
     hResult = fCurrentShellView->GetItemObject(
-        SVGIO_BACKGROUND, IID_IPersistHistory, reinterpret_cast<void **>(&viewPersistHistory));
+        SVGIO_BACKGROUND, IID_PPV_ARG(IPersistHistory, &viewPersistHistory));
     memset(&newState, 0, sizeof(newState));
     newState.dwSize = sizeof(newState);
     newState.browseType = 2;
@@ -2990,6 +3043,12 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::GetPositionCookie(DWORD *pdwPositioncoo
     return E_NOTIMPL;
 }
 
+LRESULT CShellBrowser::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+    OnCreate(reinterpret_cast<LPCREATESTRUCT> (lParam));
+    return 0;
+}
+
 LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
     // TODO: rip down everything
@@ -3012,7 +3071,7 @@ LRESULT CShellBrowser::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHa
             if (fClientBars[x].clientBar != NULL)
             {
                 hResult = fClientBars[x].clientBar->QueryInterface(
-                    IID_IDockingWindow, reinterpret_cast<void **>(&dockingWindow));
+                    IID_PPV_ARG(IDockingWindow, &dockingWindow));
                 if (SUCCEEDED(hResult) && dockingWindow != NULL)
                 {
                     hResult = dockingWindow->ResizeBorderDW(
@@ -3110,19 +3169,24 @@ LRESULT CShellBrowser::OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &
     return 0;
 }
 
+LRESULT CShellBrowser::OnBackspace(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
+{
+    HRESULT                                 hResult;
+
+    // FIXME: This does not appear to be what windows does.
+    hResult = NavigateToParent();
+    return 0;
+}
+
 LRESULT CShellBrowser::OnIsThisLegal(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
 {
     HRESULT                                 hResult;
 
     typedef HRESULT (WINAPI *PSHOpenNewFrame)(LPITEMIDLIST pidl, IUnknown *b, long c, long d);
-    PSHOpenNewFrame Func;
-    HMODULE hShlwapi;
-
-    hShlwapi = LoadLibrary(TEXT("browseui.dll"));
-    if (hShlwapi != NULL)
-        Func = reinterpret_cast<PSHOpenNewFrame>(GetProcAddress(hShlwapi, (LPCSTR)103));
-    else
-        Func = NULL;
+    PSHOpenNewFrame Func = NULL;
+    HMODULE Module = GetModuleHandle(TEXT("browseui.dll"));
+    if (Module != NULL)
+        Func = reinterpret_cast<PSHOpenNewFrame>(GetProcAddress(Module, (LPCSTR) 103));
     if (Func != NULL)
     {
         LPITEMIDLIST                        desktopPIDL;
@@ -3149,7 +3213,7 @@ LRESULT CShellBrowser::OnToggleToolbarLock(WORD wNotifyCode, WORD wID, HWND hWnd
     HRESULT                                 hResult;
 
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IOleCommandTarget, reinterpret_cast<void **>(&commandTarget));
+        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
     if (FAILED(hResult))
         return 0;
     hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_TOOLBARLOCKED, 0, NULL, NULL);
@@ -3162,7 +3226,7 @@ LRESULT CShellBrowser::OnToggleToolbarBandVisible(WORD wNotifyCode, WORD wID, HW
     HRESULT                                 hResult;
 
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IOleCommandTarget, reinterpret_cast<void **>(&commandTarget));
+        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
     if (FAILED(hResult))
         return 0;
     hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_TOOLBARBANDSHOWN, 0, NULL, NULL);
@@ -3175,7 +3239,7 @@ LRESULT CShellBrowser::OnToggleAddressBandVisible(WORD wNotifyCode, WORD wID, HW
     HRESULT                                 hResult;
 
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IOleCommandTarget, reinterpret_cast<void **>(&commandTarget));
+        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
     if (FAILED(hResult))
         return 0;
     hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_ADDRESSBANDSHOWN, 0, NULL, NULL);
@@ -3188,7 +3252,7 @@ LRESULT CShellBrowser::OnToggleLinksBandVisible(WORD wNotifyCode, WORD wID, HWND
     HRESULT                                 hResult;
 
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IOleCommandTarget, reinterpret_cast<void **>(&commandTarget));
+        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
     if (FAILED(hResult))
         return 0;
     hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_LINKSBANDSHOWN, 0, NULL, NULL);
@@ -3201,7 +3265,7 @@ LRESULT CShellBrowser::OnToggleTextLabels(WORD wNotifyCode, WORD wID, HWND hWndC
     HRESULT                                 hResult;
 
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IOleCommandTarget, reinterpret_cast<void **>(&commandTarget));
+        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
     if (FAILED(hResult))
         return 0;
     hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_TEXTLABELS, 0, NULL, NULL);
@@ -3214,7 +3278,7 @@ LRESULT CShellBrowser::OnToolbarCustomize(WORD wNotifyCode, WORD wID, HWND hWndC
     HRESULT                                 hResult;
 
     hResult = fClientBars[BIInternetToolbar].clientBar->QueryInterface(
-        IID_IOleCommandTarget, reinterpret_cast<void **>(&commandTarget));
+        IID_PPV_ARG(IOleCommandTarget, &commandTarget));
     if (FAILED(hResult))
         return 0;
     hResult = commandTarget->Exec(&CGID_PrivCITCommands, ITID_CUSTOMIZEENABLED, 0, NULL, NULL);
@@ -3233,53 +3297,59 @@ LRESULT CShellBrowser::RelayCommands(UINT uMsg, WPARAM wParam, LPARAM lParam, BO
     return 0;
 }
 
-//static LRESULT CALLBACK ExplorerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-//{
-//    return DefWindowProc(hwnd, uMsg, wParam, lParam);
-//}
-
-static void ExplorerMessageLoop()
+static HRESULT ExplorerMessageLoop(IEThreadParamBlock * parameters)
 {
+    CComPtr<IShellBrowser>                  shellBrowser;
+    CComObject<CShellBrowser>               *theCabinet;
+    HRESULT                                 hResult;
     MSG Msg;
     BOOL Ret;
 
-    while (1)
+    OleInitialize(NULL);
+
+    ATLTRY(theCabinet = new CComObject<CShellBrowser>);
+    if (theCabinet == NULL)
+    {
+        hResult = E_OUTOFMEMORY;
+        goto uninitialize;
+    }
+
+    hResult = theCabinet->QueryInterface(IID_PPV_ARG(IShellBrowser, &shellBrowser));
+    if (FAILED(hResult))
     {
-        Ret = (GetMessage(&Msg, NULL, 0, 0) != 0);
+        delete theCabinet;
+        goto uninitialize;
+    }
+
+    hResult = theCabinet->Initialize(parameters->directoryPIDL, 0, 0, 0);
+    if (FAILED(hResult))
+        goto uninitialize;
 
-        if (Ret != -1)
+    while ((Ret = GetMessage(&Msg, NULL, 0, 0)) != 0)
+    {
+        if (Ret == -1)
         {
-            if (!Ret)
-                break;
+            // Error: continue or exit?
+            break;
+        }
 
+        if (theCabinet->v_MayTranslateAccelerator(&Msg) != S_OK)
+        {
             TranslateMessage(&Msg);
             DispatchMessage(&Msg);
         }
+
+        if (Msg.message == WM_QUIT)
+            break;
     }
+
+uninitialize:
+    OleUninitialize();
+    return hResult;
 }
 
 DWORD WINAPI BrowserThreadProc(LPVOID lpThreadParameter)
 {
-    CComPtr<IShellBrowser>                  shellBrowser;
-    CComObject<CShellBrowser>               *theCabinet;
-    IEThreadParamBlock                      *parameters;
-    HRESULT                                 hResult;
-
-    parameters = (IEThreadParamBlock *)lpThreadParameter;
-    OleInitialize(NULL);
-    ATLTRY (theCabinet = new CComObject<CShellBrowser>);
-    if (theCabinet == NULL)
-        return E_OUTOFMEMORY;
-    hResult = theCabinet->QueryInterface(IID_IShellBrowser, reinterpret_cast<void **>(&shellBrowser));
-    if (FAILED(hResult))
-    {
-        delete theCabinet;
-        return hResult;
-    }
-    hResult = theCabinet->Initialize(parameters->directoryPIDL, 0, 0, 0);
-    if (FAILED(hResult))
-        return hResult;
-    ExplorerMessageLoop();
-    OleUninitialize();
-    return 0;
+    IEThreadParamBlock * parameters = (IEThreadParamBlock *) lpThreadParameter;
+    return ExplorerMessageLoop(parameters);
 }