[RSHELL]
[reactos.git] / dll / win32 / browseui / internettoolbar.cpp
index 0a9604e..eaad484 100644 (file)
@@ -73,6 +73,66 @@ extern HRESULT CreateBrandBand(REFIID riid, void **ppv);
 extern HRESULT CreateBandProxy(REFIID riid, void **ppv);
 extern HRESULT CreateAddressBand(REFIID riid, void **ppv);
 
+HRESULT IUnknown_HasFocusIO(IUnknown * punk)
+{
+    CComPtr<IInputObject> pio;
+    HRESULT hr;
+    hr = punk->QueryInterface(IID_PPV_ARG(IInputObject, &pio));
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+    return pio->HasFocusIO();
+}
+
+HRESULT IUnknown_TranslateAcceleratorIO(IUnknown * punk, MSG * pmsg)
+{
+    CComPtr<IInputObject> pio;
+    HRESULT hr;
+    if (!punk)
+        return E_FAIL;
+    hr = punk->QueryInterface(IID_PPV_ARG(IInputObject, &pio));
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+    return pio->TranslateAcceleratorIO(pmsg);
+}
+
+HRESULT IUnknown_RelayWinEvent(IUnknown * punk, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
+{
+    CComPtr<IWinEventHandler> menuWinEventHandler;
+    HRESULT hResult = punk->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
+    if (FAILED_UNEXPECTEDLY(hResult))
+        return hResult;
+    hResult = menuWinEventHandler->IsWindowOwner(hWnd);
+    if (FAILED_UNEXPECTEDLY(hResult))
+        return hResult;
+    if (hResult == S_OK)
+        return menuWinEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
+    return S_FALSE;
+}
+
+HRESULT IUnknown_ShowDW(IUnknown * punk, BOOL fShow)
+{
+    CComPtr<IDockingWindow> dockingWindow;
+    HRESULT hResult = punk->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
+    if (FAILED_UNEXPECTEDLY(hResult))
+        return hResult;
+    hResult = dockingWindow->ShowDW(fShow);
+    if (FAILED_UNEXPECTEDLY(hResult))
+        return hResult;
+    return S_OK;
+}
+
+HRESULT IUnknown_CloseDW(IUnknown * punk, DWORD dwReserved)
+{
+    CComPtr<IDockingWindow> dockingWindow;
+    HRESULT hResult = punk->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
+    if (FAILED_UNEXPECTEDLY(hResult))
+        return hResult;
+    hResult = dockingWindow->CloseDW(dwReserved);
+    if (FAILED_UNEXPECTEDLY(hResult))
+        return hResult;
+    return S_OK;
+}
+
 typedef HRESULT(*PMENUBAND_CONSTRUCTOR)(REFIID riid, void **ppv);
 
 class CInternetToolbar;
@@ -158,32 +218,20 @@ CDockSite::~CDockSite()
 
 HRESULT CDockSite::Initialize(IUnknown *containedBand, CInternetToolbar *browser, HWND hwnd, int bandID, int flags)
 {
-    CComPtr<IObjectWithSite>                site;
-    CComPtr<IOleWindow>                     oleWindow;
-    CComPtr<IDeskBand>                      deskBand;
     TCHAR                                   textBuffer[40];
     REBARBANDINFOW                          bandInfo;
     HRESULT                                 hResult;
 
-    hResult = containedBand->QueryInterface(IID_PPV_ARG(IObjectWithSite, &site));
-    if (FAILED(hResult))
-        return hResult;
-    hResult = containedBand->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
-    if (FAILED(hResult))
-        return hResult;
-    hResult = containedBand->QueryInterface(IID_PPV_ARG(IDeskBand, &deskBand));
-    if (FAILED(hResult))
-        return hResult;
     fContainedBand = containedBand;
     fToolbar = browser;
     fRebarWindow = hwnd;
     fBandID = bandID;
     fFlags = flags;
-    hResult = site->SetSite(static_cast<IOleWindow *>(this));
-    if (FAILED(hResult))
+    hResult = IUnknown_SetSite(containedBand, static_cast<IOleWindow *>(this));
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
-    hResult = oleWindow->GetWindow(&fChildWindow);
-    if (FAILED(hResult))
+    hResult = IUnknown_GetWindow(containedBand, &fChildWindow);
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
 
     memset(&bandInfo, 0, sizeof(bandInfo));
@@ -204,7 +252,7 @@ HRESULT CDockSite::GetRBBandInfo(REBARBANDINFOW &bandInfo)
     HRESULT                                 hResult;
 
     hResult = fContainedBand->QueryInterface(IID_PPV_ARG(IDeskBand, &deskBand));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
 
     fDeskBandInfo.dwMask = DBIM_BKCOLOR | DBIM_MODEFLAGS | DBIM_TITLE | DBIM_ACTUAL |
@@ -317,7 +365,7 @@ HRESULT STDMETHODCALLTYPE CDockSite::Exec(const GUID *pguidCmdGroup, DWORD nCmdI
                 bandInfo.lpText = textBuffer;
                 bandInfo.cch = sizeof(textBuffer) / sizeof(TCHAR);
                 hResult = GetRBBandInfo(bandInfo);
-                if (FAILED(hResult))
+                if (FAILED_UNEXPECTEDLY(hResult))
                     return hResult;
                 index = (int)SendMessage(fRebarWindow, RB_IDTOINDEX, fBandID, 0);
                 SendMessage(fRebarWindow, RB_SETBANDINFOW, index, (LPARAM)&bandInfo);
@@ -367,10 +415,10 @@ HRESULT STDMETHODCALLTYPE CMenuCallback::GetObject(LPSMDATA psmd, REFIID riid, v
     {
         // create favorites menu
         hResult = psmd->punk->QueryInterface(IID_PPV_ARG(IShellMenu, &parentMenu));
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
         hResult = parentMenu->GetMenu(&parentHMenu, &ownerWindow, NULL);
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
         favoritesHMenu = GetSubMenu(parentHMenu, 3);
         if (favoritesHMenu == NULL)
@@ -392,19 +440,19 @@ HRESULT STDMETHODCALLTYPE CMenuCallback::GetObject(LPSMDATA psmd, REFIID riid, v
         hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
             IID_PPV_ARG(IShellMenu, &newMenu));
 #endif
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
         hResult = newMenu->Initialize(this, FCIDM_MENU_FAVORITES, -1, SMINIT_VERTICAL | SMINIT_CACHED);
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
         hResult = newMenu->SetMenu(favoritesHMenu, ownerWindow, SMSET_TOP | SMSET_DONTOWN);
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
         hResult = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &favoritesPIDL);
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
         hResult = SHBindToFolder(favoritesPIDL, &favoritesFolder);
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
         RegCreateKeyEx(HKEY_CURRENT_USER, szFavoritesKey,
                 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &orderRegKey, &disposition);
@@ -499,9 +547,11 @@ CInternetToolbar::CInternetToolbar()
     fLocked = false;
     fMenuBandWindow = NULL;
     fNavigationWindow = NULL;
-    fMenuCallback.AddRef();
+    fMenuCallback = new CComDebugObject<CMenuCallback>();
     fToolbarWindow = NULL;
     fAdviseCookie = 0;
+
+    fMenuCallback->AddRef();
 }
 
 CInternetToolbar::~CInternetToolbar()
@@ -511,10 +561,9 @@ CInternetToolbar::~CInternetToolbar()
 
 void CInternetToolbar::AddDockItem(IUnknown *newItem, int bandID, int flags)
 {
-    CDockSite           *newSite;
+    CComPtr<CDockSite> newSite;
 
     newSite = new CComObject<CDockSite>;
-    newSite->AddRef();
     newSite->Initialize(newItem, this, fMainReBar, bandID, flags);
 }
 
@@ -524,10 +573,10 @@ HRESULT CInternetToolbar::ReserveBorderSpace(LONG maxHeight)
     RECT                                    availableBorderSpace;
 
     HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
     hResult = dockingWindowSite->GetBorderDW(static_cast<IDockingWindow *>(this), &availableBorderSpace);
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
 
     if (availableBorderSpace.top > maxHeight)
@@ -538,118 +587,101 @@ HRESULT CInternetToolbar::ReserveBorderSpace(LONG maxHeight)
     return ResizeBorderDW(&availableBorderSpace, fSite, FALSE);
 }
 
-HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **menuBar)
+HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **pMenuBar)
 {
-    CComPtr<IOleCommandTarget>              siteCommandTarget;
-    CComPtr<IOleWindow>                     oleWindow;
-    CComPtr<IOleCommandTarget>              commandTarget;
+    CComPtr<IShellMenu>                     menubar;
     CComPtr<IShellMenuCallback>             callback;
     VARIANT                                 menuOut;
     HWND                                    ownerWindow;
     HRESULT                                 hResult;
+    if (!pMenuBar)
+        return E_POINTER;
+
 
+    *pMenuBar = NULL;
+
+    hResult = E_FAIL;
 #if USE_CUSTOM_MENUBAND
-    HMODULE hrs = LoadLibraryW(L"rshell.dll");
+    HMODULE hrs = GetModuleHandleW(L"rshell.dll");
+    
+    if (!hrs) hrs = LoadLibraryW(L"rshell.dll");
 
-    if (!hrs)
+    if (hrs)
     {
-        DbgPrint("Failed: %d\n", GetLastError());
-        return E_FAIL;
+        PMENUBAND_CONSTRUCTOR func = (PMENUBAND_CONSTRUCTOR) GetProcAddress(hrs, "CMenuBand_Constructor");
+        if (func)
+        {
+            hResult = func(IID_PPV_ARG(IShellMenu, &menubar));
+        }
     }
+#endif
 
-    PMENUBAND_CONSTRUCTOR func = (PMENUBAND_CONSTRUCTOR) GetProcAddress(hrs, "CMenuBand_Constructor");
-    if (func)
-    {
-        hResult = func(IID_PPV_ARG(IShellMenu, menuBar));
-    }
-    else
-    {
-        DbgPrint("Failed: %d\n", GetLastError());
-        hResult = E_FAIL;
-    }
-    
-    if (FAILED(hResult))
+    menubar->AddRef();
+
+    if (FAILED_UNEXPECTEDLY(hResult))
     {
         hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
-            IID_PPV_ARG(IShellMenu, menuBar));
+            IID_PPV_ARG(IShellMenu, &menubar));
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
     }
-#else
-    hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
-        IID_PPV_ARG(IShellMenu, menuBar));
-#endif
-    if (FAILED(hResult))
-        return hResult;
-    hResult = fMenuCallback.QueryInterface(IID_PPV_ARG(IShellMenuCallback, &callback));
-    if (FAILED(hResult))
-        return hResult;
-    hResult = (*menuBar)->Initialize(callback, -1, ANCESTORDEFAULT, SMINIT_HORIZONTAL | SMINIT_TOPLEVEL);
-    if (FAILED(hResult))
-        return hResult;
-    hResult = fSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
-    if (FAILED(hResult))
-        return hResult;
-    hResult = oleWindow->GetWindow(&ownerWindow);
-    if (FAILED(hResult))
-        return hResult;
-    hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &siteCommandTarget));
-    if (FAILED(hResult))
-        return hResult;
-    hResult = siteCommandTarget->Exec(&CGID_Explorer, 0x35, 0, NULL, &menuOut);
-    if (FAILED(hResult))
-        return hResult;
-    if (V_VT(&menuOut) != VT_INT_PTR || V_INTREF(&menuOut) == NULL)
-        return E_FAIL;
-    hResult = (*menuBar)->SetMenu((HMENU)V_INTREF(&menuOut), ownerWindow, SMSET_DONTOWN);
-    if (FAILED(hResult))
+    
+    hResult = fMenuCallback->QueryInterface(IID_PPV_ARG(IShellMenuCallback, &callback));
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
-    hResult = (*menuBar)->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
-    if (FAILED(hResult))
+
+    hResult = menubar->Initialize(callback, -1, ANCESTORDEFAULT, SMINIT_HORIZONTAL | SMINIT_TOPLEVEL);
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
-    hResult = commandTarget->Exec(&CGID_MenuBand, 3, 1, NULL, NULL);
-    if (FAILED(hResult))
+
+    // Set Menu
+    {
+        hResult = IUnknown_Exec(fSite, CGID_Explorer, 0x35, 0, NULL, &menuOut);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+
+        if (V_VT(&menuOut) != VT_INT_PTR || V_INTREF(&menuOut) == NULL)
+            return E_FAIL;
+
+        hResult = IUnknown_GetWindow(fSite, &ownerWindow);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+
+        hResult = menubar->SetMenu((HMENU) V_INTREF(&menuOut), ownerWindow, SMSET_DONTOWN);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+    }
+
+    hResult = IUnknown_Exec(menubar, CGID_MenuBand, 3, 1, NULL, NULL);
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
+
+    *pMenuBar = menubar.Detach();
+
     return S_OK;
 }
 
 HRESULT CInternetToolbar::CreateBrandBand(IUnknown **logoBar)
 {
-    CComPtr<IUnknown>                       tempBand;
-    HRESULT                                 hResult;
-
 #if 1
-    hResult = ::CreateBrandBand(IID_PPV_ARG(IUnknown, logoBar));
+    return ::CreateBrandBand(IID_PPV_ARG(IUnknown, logoBar));
 #else
-    hResult = CoCreateInstance(CLSID_BrandBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, logoBar));
+    return CoCreateInstance(CLSID_BrandBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, logoBar));
 #endif
-    if (FAILED(hResult))
-        return hResult;
-    return S_OK;
 }
 
 HRESULT CInternetToolbar::CreateToolsBar(IUnknown **toolsBar)
 {
-    HRESULT                                 hResult;
-
-    hResult = ::CreateToolsBar(IID_PPV_ARG(IUnknown, toolsBar));
-    if (FAILED(hResult))
-        return hResult;
-    return S_OK;
+    return ::CreateToolsBar(IID_PPV_ARG(IUnknown, toolsBar));
 }
 
 HRESULT CInternetToolbar::CreateAddressBand(IUnknown **toolsBar)
 {
-    CComPtr<IAddressBand>                   addressBand;
-    HRESULT                                 hResult;
-
 #if 1
-    hResult = ::CreateAddressBand(IID_PPV_ARG(IUnknown, toolsBar));
+    return ::CreateAddressBand(IID_PPV_ARG(IUnknown, toolsBar));
 #else
-    hResult = CoCreateInstance(CLSID_SH_AddressBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, toolsBar));
+    return CoCreateInstance(CLSID_SH_AddressBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, toolsBar));
 #endif
-    if (FAILED(hResult))
-        return hResult;
-    hResult = (*toolsBar)->QueryInterface(IID_PPV_ARG(IAddressBand, &addressBand));
-    return S_OK;
 }
 
 HRESULT CInternetToolbar::LockUnlockToolbars(bool locked)
@@ -680,6 +712,8 @@ HRESULT CInternetToolbar::LockUnlockToolbars(bool locked)
             }
         }
         hResult = ReserveBorderSpace();
+
+        // TODO: refresh view menu?
     }
     return S_OK;
 }
@@ -700,11 +734,11 @@ HRESULT CInternetToolbar::CommandStateChanged(bool newValue, int commandID)
             break;
         case 1:
             // forward
-            hResult = SetState(&CLSID_CommonButtons, gForwardCommandID, newValue ? TBSTATE_ENABLED : 0);
+            hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_FORWARD, newValue ? TBSTATE_ENABLED : 0);
             break;
         case 2:
             // back
-            hResult = SetState(&CLSID_CommonButtons, gBackCommandID, newValue ? TBSTATE_ENABLED : 0);
+            hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_BACK, newValue ? TBSTATE_ENABLED : 0);
             break;
     }
     return hResult;
@@ -716,16 +750,16 @@ HRESULT CInternetToolbar::CreateAndInitBandProxy()
     HRESULT                                 hResult;
 
     hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
     hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
     {
         hResult = CreateBandProxy(IID_PPV_ARG(IBandProxy, &fBandProxy));
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
         hResult = fBandProxy->SetSite(fSite);
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
     }
     return S_OK;
@@ -738,12 +772,46 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::UIActivateIO(BOOL fActivate, LPMSG l
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::HasFocusIO()
 {
-    return E_NOTIMPL;
+    HRESULT hr = S_FALSE;
+
+    if (fMenuBar)
+        hr = IUnknown_HasFocusIO(fMenuBar);
+    if (hr != S_FALSE)
+        return hr;
+
+    if (fControlsBar)
+        hr = IUnknown_HasFocusIO(fControlsBar);
+    if (hr != S_FALSE)
+        return hr;
+
+    if (fNavigationBar)
+        hr = IUnknown_HasFocusIO(fNavigationBar);
+    if (hr != S_FALSE)
+        return hr;
+
+    return S_FALSE;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg)
 {
-    return E_NOTIMPL;
+    HRESULT hr = S_FALSE;
+
+    if (fMenuBar)
+        hr = IUnknown_TranslateAcceleratorIO(fMenuBar, lpMsg);
+    if (hr == S_OK)
+        return hr;
+
+    if (fControlsBar)
+        hr = IUnknown_TranslateAcceleratorIO(fControlsBar, lpMsg);
+    if (hr == S_OK)
+        return hr;
+
+    if (fNavigationBar)
+        hr = IUnknown_TranslateAcceleratorIO(fNavigationBar, lpMsg);
+    if (hr == S_OK)
+        return hr;
+
+    return S_FALSE;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetWindow(HWND *lphwnd)
@@ -761,19 +829,98 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
 {
-    CComPtr<IDockingWindow>     dockingWindow;
     HRESULT                     hResult;
 
     // show the bar here
-    hResult = ReserveBorderSpace();
-    hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
-    hResult = dockingWindow->ShowDW(fShow);
+    if (fShow)
+    {
+        hResult = ReserveBorderSpace();
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+    }
+
+    if (fMenuBar)
+    {
+        hResult = IUnknown_ShowDW(fMenuBar, fShow);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+    }
+
+    if (fControlsBar)
+    {
+        hResult = IUnknown_ShowDW(fControlsBar, fShow);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+    }
+    if (fNavigationBar)
+    {
+        hResult = IUnknown_ShowDW(fNavigationBar, fShow);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+    }
+    if (fLogoBar)
+    {
+        hResult = IUnknown_ShowDW(fLogoBar, fShow);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+    }
     return S_OK;
 }
 
+template<class T>
+void ReleaseCComPtrExpectZero(CComPtr<T>& cptr, BOOL forceRelease = FALSE)
+{
+    if (cptr.p != NULL)
+    {
+        int nrc = cptr->Release();
+        if (nrc > 0)
+        {
+            DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc);
+            if (forceRelease)
+            {
+                while (nrc > 0)
+                {
+                    nrc = cptr->Release();
+                }
+            }
+        }
+        cptr.Detach();
+    }
+}
+
 HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved)
 {
-    return E_NOTIMPL;
+    HRESULT                     hResult;
+
+    if (fMenuBar)
+    {
+        hResult = IUnknown_CloseDW(fMenuBar, dwReserved);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+        ReleaseCComPtrExpectZero(fMenuBar);
+    }
+    if (fControlsBar)
+    {
+        hResult = IUnknown_CloseDW(fControlsBar, dwReserved);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+        ReleaseCComPtrExpectZero(fControlsBar);
+    }
+    if (fNavigationBar)
+    {
+        hResult = IUnknown_CloseDW(fNavigationBar, dwReserved);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+        ReleaseCComPtrExpectZero(fNavigationBar);
+    }
+    if (fLogoBar)
+    {
+        hResult = IUnknown_CloseDW(fLogoBar, dwReserved);
+        if (FAILED_UNEXPECTEDLY(hResult))
+            return hResult;
+        ReleaseCComPtrExpectZero(fLogoBar);
+    }
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
@@ -797,15 +944,15 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
     CComPtr<IDockingWindowSite> dockingWindowSite;
     
     HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
 
     hResult = dockingWindowSite->RequestBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
 
     hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
 
     return S_OK;
@@ -845,25 +992,23 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew()
     CComPtr<IUnknown>                       logoBar;
     CComPtr<IUnknown>                       toolsBar;
     CComPtr<IUnknown>                       navigationBar;
-    CComPtr<IOleWindow>                     menuOleWindow;
-    CComPtr<IOleWindow>                     toolbarOleWindow;
-    CComPtr<IOleWindow>                     navigationOleWindow;
     HRESULT                                 hResult;
 
     /* Create and attach the menubar to the rebar */
     hResult = CreateMenuBar(&menuBar);
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
     AddDockItem(menuBar, ITBBID_MENUBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
 
-    hResult = menuBar->QueryInterface(IID_PPV_ARG(IOleWindow, &menuOleWindow));
-    hResult = menuOleWindow->GetWindow(&fMenuBandWindow);
+    hResult = IUnknown_GetWindow(menuBar, &fMenuBandWindow);
     fMenuBar.Attach(menuBar.Detach());                  // transfer the ref count
 
+    // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
+    // and it will put them in their own row, sized to take up the whole row.
 #if 0
     /* Create and attach the brand/logo to the rebar */
     hResult = CreateBrandBand(&logoBar);
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
     AddDockItem(logoBar, ITBBID_BRANDBAND, CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
     fLogoBar.Attach(logoBar.Detach());                  // transfer the ref count
@@ -871,25 +1016,21 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew()
 
     /* Create and attach the standard toolbar to the rebar */
     hResult = CreateToolsBar(&toolsBar);
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
     AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
     fControlsBar.Attach(toolsBar.Detach());             // transfer the ref count
-    hResult = fControlsBar->QueryInterface(IID_PPV_ARG(IOleWindow, &toolbarOleWindow));
-    if (FAILED(hResult))
-        return hResult;
-    hResult = toolbarOleWindow->GetWindow(&fToolbarWindow);
-    if (FAILED(hResult))
+    hResult = IUnknown_GetWindow(fControlsBar, &fToolbarWindow);
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
 
     /* Create and attach the address/navigation toolbar to the rebar */
     hResult = CreateAddressBand(&navigationBar);
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
     AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
-    hResult = navigationBar->QueryInterface(IID_PPV_ARG(IOleWindow, &navigationOleWindow));
-    hResult = navigationOleWindow->GetWindow(&fNavigationWindow);
     fNavigationBar.Attach(navigationBar.Detach());
+    hResult = IUnknown_GetWindow(fNavigationBar, &fNavigationWindow);
 
     return S_OK;
 }
@@ -1028,7 +1169,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget
 
     fCommandTarget.Release();
     hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
     fCommandCategory = *category;
     return S_OK;
@@ -1134,10 +1275,10 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
     {
         // get window handle of owner
         hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
         hResult = oleWindow->GetWindow(&ownerWindow);
-        if (FAILED(hResult))
+        if (FAILED_UNEXPECTEDLY(hResult))
             return hResult;
         if (ownerWindow == NULL)
             return E_FAIL;
@@ -1191,7 +1332,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, RE
         if (fBandProxy.p == NULL)
         {
             hResult = CreateAndInitBandProxy();
-            if (FAILED(hResult))
+            if (FAILED_UNEXPECTEDLY(hResult))
                 return hResult;
         }
         return fBandProxy->QueryInterface(riid, ppvObject);
@@ -1202,16 +1343,27 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, RE
 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
     HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
 {
-    CComPtr<IWinEventHandler>               menuWinEventHandler;
     HRESULT                                 hResult;
 
     if (fMenuBar)
     {
-        hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
-        if (menuWinEventHandler->IsWindowOwner(hWnd) == S_OK)
-        {
-            return menuWinEventHandler->OnWinEvent(fMenuBandWindow, uMsg, wParam, lParam, theResult);
-        }
+        hResult = IUnknown_RelayWinEvent(fMenuBar, hWnd, uMsg, wParam, lParam, theResult);
+        if (hResult != S_FALSE)
+            return hResult;
+    }
+
+    if (fNavigationBar)
+    {
+        hResult = IUnknown_RelayWinEvent(fNavigationBar, hWnd, uMsg, wParam, lParam, theResult);
+        if (hResult != S_FALSE)
+            return hResult;
+    }
+
+    if (fLogoBar)
+    {
+        hResult = IUnknown_RelayWinEvent(fLogoBar, hWnd, uMsg, wParam, lParam, theResult);
+        if (hResult != S_FALSE)
+            return hResult;
     }
 
     return S_FALSE;
@@ -1219,16 +1371,19 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd)
 {
+    UNIMPLEMENTED;
     return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBand(IUnknown *punk)
 {
+    UNIMPLEMENTED;
     return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::EnumBands(UINT uBand, DWORD *pdwBandID)
 {
+    UNIMPLEMENTED;
     return E_NOTIMPL;
 }
 
@@ -1247,26 +1402,31 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID,
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
 {
+    UNIMPLEMENTED;
     return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::RemoveBand(DWORD dwBandID)
 {
+    UNIMPLEMENTED;
     return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv)
 {
+    UNIMPLEMENTED;
     return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
 {
+    UNIMPLEMENTED;
     return E_NOTIMPL;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
 {
+    UNIMPLEMENTED;
     return E_NOTIMPL;
 }
 
@@ -1277,11 +1437,11 @@ LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl,
     HRESULT                                 hResult;
 
     hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return 0;
     hResult = serviceProvider->QueryService(SID_SShellBrowser,
         IID_PPV_ARG(IWebBrowser, &webBrowser));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return 0;
     hResult = webBrowser->GoBack();
     return 1;
@@ -1294,11 +1454,11 @@ LRESULT CInternetToolbar::OnTravelForward(WORD wNotifyCode, WORD wID, HWND hWndC
     HRESULT                                 hResult;
 
     hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return 0;
     hResult = serviceProvider->QueryService(
         SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return 0;
     hResult = webBrowser->GoForward();
     return 1;
@@ -1310,7 +1470,7 @@ LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BO
     HRESULT                                 hResult;
 
     hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
     hResult = oleCommandTarget->Exec(&CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL);
     return 1;
@@ -1334,13 +1494,13 @@ LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOO
 
     hResult = CoCreateInstance(CLSID_ShellSearchExt, NULL, CLSCTX_INPROC_SERVER,
         IID_PPV_ARG(IContextMenu, &contextMenu));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return 0;
     hResult = contextMenu->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return 0;
     hResult = objectWithSite->SetSite(fSite);
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return 0;
     hResult = contextMenu->InvokeCommand(&commandInfo);
     hResult = objectWithSite->SetSite(NULL);
@@ -1353,7 +1513,7 @@ LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BO
     HRESULT                                 hResult;
 
     hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
         return hResult;
     hResult = oleCommandTarget->Exec(&CGID_Explorer, 0x23, 0, NULL, NULL);
     return 1;
@@ -1396,7 +1556,7 @@ LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bH
     ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2);
     switch (notifyInfo->iItem)
     {
-        case gBackCommandID:
+        case IDM_GOTO_BACK:
             newMenu = CreatePopupMenu();
             hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
             hResult = serviceProvider->QueryService(
@@ -1426,7 +1586,7 @@ LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bH
                 hResult = travelLog->Travel(browserService, -selectedItem);
             DestroyMenu(newMenu);
             break;
-        case gForwardCommandID:
+        case IDM_GOTO_FORWARD:
             newMenu = CreatePopupMenu();
             hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
             hResult = serviceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
@@ -1527,6 +1687,13 @@ LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
         default:
             break;
     }
+
+    MENUITEMINFO mii;
+    mii.cbSize = sizeof(mii);
+    mii.fMask = MIIM_STATE;
+    mii.fState = fLocked ? MFS_CHECKED : MFS_UNCHECKED;
+    SetMenuItemInfo(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, FALSE, &mii);
+
     // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
     command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
                 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL);
@@ -1545,6 +1712,8 @@ LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
             SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
             break;
     }
+
+    DestroyMenu(contextMenuBar);
     return 1;
 }
 
@@ -1586,15 +1755,15 @@ LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandle
 
     if (nID != 0)
     {
-        if (nID == (UINT)gBackCommandID || nID == (UINT)gForwardCommandID)
+        if (nID == (UINT)IDM_GOTO_BACK || nID == (UINT)IDM_GOTO_FORWARD)
         {
             // TODO: Should this call QueryService?
             hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService));
             hResult = browserService->GetTravelLog(&travelLog);
             hResult = travelLog->GetToolTipText(browserService,
-                (nID == (UINT)gBackCommandID) ? TLOG_BACK : TLOG_FORE,
+                (nID == (UINT)IDM_GOTO_BACK) ? TLOG_BACK : TLOG_FORE,
                 0, tempString, 299);
-            if (FAILED(hResult))
+            if (FAILED_UNEXPECTEDLY(hResult))
             {
                 bHandled = FALSE;
                 return 0;
@@ -1614,37 +1783,12 @@ LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOO
 {
     LRESULT theResult;
     HRESULT hResult;
-    HWND    target = (HWND) lParam;
 
-    if (fMenuBar)
-    {
-        CComPtr<IWinEventHandler> menuWinEventHandler;
-        hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
-        if (SUCCEEDED(hResult))
-        {
-            if (menuWinEventHandler->IsWindowOwner(target) == S_OK)
-            {
-                hResult = menuWinEventHandler->OnWinEvent(target, uMsg, wParam, lParam, &theResult);
-                return FAILED(hResult) ? 0 : theResult;
-            }
-        }
-    }
+    hResult = OnWinEvent((HWND) lParam, uMsg, wParam, lParam, &theResult);
 
-    if (fNavigationBar)
-    {
-        CComPtr<IWinEventHandler> menuWinEventHandler;
-        hResult = fNavigationBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
-        if (SUCCEEDED(hResult))
-        {
-            if (menuWinEventHandler->IsWindowOwner(target) == S_OK)
-            {
-                hResult = menuWinEventHandler->OnWinEvent(target, uMsg, wParam, lParam, &theResult);
-                return FAILED(hResult) ? 0 : theResult;
-            }
-        }
-    }
+    bHandled = hResult == S_OK;
 
-    return 0;
+    return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
 }
 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
@@ -1652,37 +1796,13 @@ LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
     LRESULT theResult;
     HRESULT hResult;
 
-    notifyHeader = (NMHDR *) lParam;
+    notifyHeader = reinterpret_cast<NMHDR *>(lParam);
 
-    if (fMenuBar)
-    {
-        CComPtr<IWinEventHandler> menuWinEventHandler;
-        hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
-        if (SUCCEEDED(hResult))
-        {
-            if (menuWinEventHandler->IsWindowOwner(notifyHeader->hwndFrom) == S_OK)
-            {
-                hResult = menuWinEventHandler->OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
-                return FAILED(hResult) ? 0 : theResult;
-            }
-        }
-    }
+    hResult = OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
 
-    if (fNavigationBar)
-    {
-        CComPtr<IWinEventHandler> menuWinEventHandler;
-        hResult = fNavigationBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
-        if (SUCCEEDED(hResult))
-        {
-            if (menuWinEventHandler->IsWindowOwner(notifyHeader->hwndFrom) == S_OK)
-            {
-                hResult = menuWinEventHandler->OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
-                return FAILED(hResult) ? 0 : theResult;
-            }
-        }
-    }
+    bHandled = hResult == S_OK;
 
-    return 0;
+    return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
 }
 
 LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
@@ -1747,8 +1867,8 @@ LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b
 
 HRESULT CreateInternetToolbar(REFIID riid, void **ppv)
 {
-    CComObject<CInternetToolbar>            *theToolbar;
-    HRESULT                                 hResult;
+    CInternetToolbar            *theToolbar;
+    HRESULT                     hResult;
 
     if (ppv == NULL)
         return E_POINTER;
@@ -1757,7 +1877,7 @@ HRESULT CreateInternetToolbar(REFIID riid, void **ppv)
     if (theToolbar == NULL)
         return E_OUTOFMEMORY;
     hResult = theToolbar->QueryInterface (riid, reinterpret_cast<void **>(ppv));
-    if (FAILED(hResult))
+    if (FAILED_UNEXPECTEDLY(hResult))
     {
         delete theToolbar;
         return hResult;