Sync with trunk r63502.
[reactos.git] / dll / win32 / browseui / internettoolbar.cpp
index adfd6ef..a7fd294 100644 (file)
@@ -25,6 +25,12 @@ toolbar, and address band for an explorer window
 
 #include "precomp.h"
 
+/* FIXME, I can't include windowsx because it conflicts with some #defines */
+#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
+
+#define USE_CUSTOM_MENUBAND 0
+
 // navigation controls and menubar just send a message to parent window
 /*
 TODO:
@@ -67,6 +73,8 @@ extern HRESULT CreateBrandBand(REFIID riid, void **ppv);
 extern HRESULT CreateBandProxy(REFIID riid, void **ppv);
 extern HRESULT CreateAddressBand(REFIID riid, void **ppv);
 
+typedef HRESULT(*PMENUBAND_CONSTRUCTOR)(REFIID riid, void **ppv);
+
 class CInternetToolbar;
 
 class CDockSite :
@@ -150,20 +158,20 @@ CDockSite::~CDockSite()
 
 HRESULT CDockSite::Initialize(IUnknown *containedBand, CInternetToolbar *browser, HWND hwnd, int bandID, int flags)
 {
-    CComPtr<IObjectWithSite>                site;
+    CComPtr<IObjectWithSite>                child;
     CComPtr<IOleWindow>                     oleWindow;
     CComPtr<IDeskBand>                      deskBand;
     TCHAR                                   textBuffer[40];
     REBARBANDINFOW                          bandInfo;
     HRESULT                                 hResult;
 
-    hResult = containedBand->QueryInterface(IID_IObjectWithSite, reinterpret_cast<void **>(&site));
+    hResult = containedBand->QueryInterface(IID_PPV_ARG(IObjectWithSite, &child));
     if (FAILED(hResult))
         return hResult;
-    hResult = containedBand->QueryInterface(IID_IOleWindow, reinterpret_cast<void **>(&oleWindow));
+    hResult = containedBand->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
     if (FAILED(hResult))
         return hResult;
-    hResult = containedBand->QueryInterface(IID_IDeskBand, reinterpret_cast<void **>(&deskBand));
+    hResult = containedBand->QueryInterface(IID_PPV_ARG(IDeskBand, &deskBand));
     if (FAILED(hResult))
         return hResult;
     fContainedBand = containedBand;
@@ -171,7 +179,7 @@ HRESULT CDockSite::Initialize(IUnknown *containedBand, CInternetToolbar *browser
     fRebarWindow = hwnd;
     fBandID = bandID;
     fFlags = flags;
-    hResult = site->SetSite(static_cast<IOleWindow *>(this));
+    hResult = child->SetSite(static_cast<IOleWindow *>(this));
     if (FAILED(hResult))
         return hResult;
     hResult = oleWindow->GetWindow(&fChildWindow);
@@ -195,7 +203,7 @@ HRESULT CDockSite::GetRBBandInfo(REBARBANDINFOW &bandInfo)
     CComPtr<IDeskBand>                      deskBand;
     HRESULT                                 hResult;
 
-    hResult = fContainedBand->QueryInterface(IID_IDeskBand, reinterpret_cast<void **>(&deskBand));
+    hResult = fContainedBand->QueryInterface(IID_PPV_ARG(IDeskBand, &deskBand));
     if (FAILED(hResult))
         return hResult;
 
@@ -321,15 +329,10 @@ HRESULT STDMETHODCALLTYPE CDockSite::Exec(const GUID *pguidCmdGroup, DWORD nCmdI
 
 HRESULT STDMETHODCALLTYPE CDockSite::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
 {
-    CComPtr<IServiceProvider>               serviceProvider;
-    HRESULT                                 hResult;
-
     if (IsEqualIID(guidService, SID_SMenuBandParent))
         return this->QueryInterface(riid, ppvObject);
-    hResult = fToolbar->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
-    if (FAILED(hResult))
-        return hResult;
-    return serviceProvider->QueryService(guidService, riid, ppvObject);
+
+    return fToolbar->QueryService(guidService, riid, ppvObject);
 }
 
 CMenuCallback::CMenuCallback()
@@ -363,7 +366,7 @@ HRESULT STDMETHODCALLTYPE CMenuCallback::GetObject(LPSMDATA psmd, REFIID riid, v
     if (fFavoritesMenu.p == NULL)
     {
         // create favorites menu
-        hResult = psmd->punk->QueryInterface(IID_IShellMenu, reinterpret_cast<void **>(&parentMenu));
+        hResult = psmd->punk->QueryInterface(IID_PPV_ARG(IShellMenu, &parentMenu));
         if (FAILED(hResult))
             return hResult;
         hResult = parentMenu->GetMenu(&parentHMenu, &ownerWindow, NULL);
@@ -372,8 +375,23 @@ HRESULT STDMETHODCALLTYPE CMenuCallback::GetObject(LPSMDATA psmd, REFIID riid, v
         favoritesHMenu = GetSubMenu(parentHMenu, 3);
         if (favoritesHMenu == NULL)
             return E_FAIL;
+#if USE_CUSTOM_MENUBAND
+        HMODULE hrs = LoadLibrary(L"rshell.dll");
+
+        PMENUBAND_CONSTRUCTOR func = (PMENUBAND_CONSTRUCTOR) GetProcAddress(hrs, "CMenuBand_Constructor");
+        if (func)
+        {
+            hResult = func(IID_PPV_ARG(IShellMenu, &newMenu));
+        }
+        else
+        {
+            hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
+                IID_PPV_ARG(IShellMenu, &newMenu));
+        }
+#else
         hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
-            IID_IShellMenu, reinterpret_cast<void **>(&newMenu));
+            IID_PPV_ARG(IShellMenu, &newMenu));
+#endif
         if (FAILED(hResult))
             return hResult;
         hResult = newMenu->Initialize(this, FCIDM_MENU_FAVORITES, -1, SMINIT_VERTICAL | SMINIT_CACHED);
@@ -500,30 +518,24 @@ void CInternetToolbar::AddDockItem(IUnknown *newItem, int bandID, int flags)
     newSite->Initialize(newItem, this, fMainReBar, bandID, flags);
 }
 
-HRESULT CInternetToolbar::ReserveBorderSpace()
+HRESULT CInternetToolbar::ReserveBorderSpace(LONG maxHeight)
 {
     CComPtr<IDockingWindowSite>             dockingWindowSite;
     RECT                                    availableBorderSpace;
-    RECT                                    neededBorderSpace;
-    HRESULT                                 hResult;
 
-    hResult = fSite->QueryInterface(IID_IDockingWindowSite, reinterpret_cast<void **>(&dockingWindowSite));
+    HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
     if (FAILED(hResult))
         return hResult;
     hResult = dockingWindowSite->GetBorderDW(static_cast<IDockingWindow *>(this), &availableBorderSpace);
     if (FAILED(hResult))
         return hResult;
-    SendMessage(fMainReBar, RB_SIZETORECT, RBSTR_CHANGERECT, reinterpret_cast<LPARAM>(&availableBorderSpace));
-    neededBorderSpace.left = 0;
-    neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top;
-    if (!fLocked)
-        neededBorderSpace.top += 3;
-    neededBorderSpace.right = 0;
-    neededBorderSpace.bottom = 0;
-    hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
-    if (FAILED(hResult))
-        return hResult;
-    return S_OK;
+
+    if (availableBorderSpace.top > maxHeight)
+    {
+        availableBorderSpace.top = maxHeight;
+    }
+
+    return ResizeBorderDW(&availableBorderSpace, fSite, FALSE);
 }
 
 HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **menuBar)
@@ -536,23 +548,50 @@ HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **menuBar)
     HWND                                    ownerWindow;
     HRESULT                                 hResult;
 
+#if USE_CUSTOM_MENUBAND
+    HMODULE hrs = LoadLibraryW(L"rshell.dll");
+
+    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));
+    }
+    else
+    {
+        DbgPrint("Failed: %d\n", GetLastError());
+        hResult = E_FAIL;
+    }
+    
+    if (FAILED(hResult))
+    {
+        hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
+            IID_PPV_ARG(IShellMenu, menuBar));
+    }
+#else
     hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
-        IID_IShellMenu, reinterpret_cast<void **>(menuBar));
+        IID_PPV_ARG(IShellMenu, menuBar));
+#endif
     if (FAILED(hResult))
         return hResult;
-    hResult = fMenuCallback.QueryInterface(IID_IShellMenuCallback, reinterpret_cast<void **>(&callback));
+    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_IOleWindow, reinterpret_cast<void **>(&oleWindow));
+    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_IOleCommandTarget, reinterpret_cast<void **>(&siteCommandTarget));
+    hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &siteCommandTarget));
     if (FAILED(hResult))
         return hResult;
     hResult = siteCommandTarget->Exec(&CGID_Explorer, 0x35, 0, NULL, &menuOut);
@@ -563,7 +602,7 @@ HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **menuBar)
     hResult = (*menuBar)->SetMenu((HMENU)V_INTREF(&menuOut), ownerWindow, SMSET_DONTOWN);
     if (FAILED(hResult))
         return hResult;
-    hResult = (*menuBar)->QueryInterface(IID_IOleCommandTarget, reinterpret_cast<void **>(&commandTarget));
+    hResult = (*menuBar)->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
     if (FAILED(hResult))
         return hResult;
     hResult = commandTarget->Exec(&CGID_MenuBand, 3, 1, NULL, NULL);
@@ -578,10 +617,9 @@ HRESULT CInternetToolbar::CreateBrandBand(IUnknown **logoBar)
     HRESULT                                 hResult;
 
 #if 1
-    hResult = ::CreateBrandBand(IID_IUnknown, reinterpret_cast<void **>(logoBar));
+    hResult = ::CreateBrandBand(IID_PPV_ARG(IUnknown, logoBar));
 #else
-    hResult = CoCreateInstance(CLSID_BrandBand, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown,
-        reinterpret_cast<void **>(logoBar));
+    hResult = CoCreateInstance(CLSID_BrandBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, logoBar));
 #endif
     if (FAILED(hResult))
         return hResult;
@@ -592,7 +630,7 @@ HRESULT CInternetToolbar::CreateToolsBar(IUnknown **toolsBar)
 {
     HRESULT                                 hResult;
 
-    hResult = ::CreateToolsBar(IID_IUnknown, reinterpret_cast<void **>(toolsBar));
+    hResult = ::CreateToolsBar(IID_PPV_ARG(IUnknown, toolsBar));
     if (FAILED(hResult))
         return hResult;
     return S_OK;
@@ -604,14 +642,13 @@ HRESULT CInternetToolbar::CreateAddressBand(IUnknown **toolsBar)
     HRESULT                                 hResult;
 
 #if 1
-    hResult = ::CreateAddressBand(IID_IUnknown, reinterpret_cast<void **>(toolsBar));
+    hResult = ::CreateAddressBand(IID_PPV_ARG(IUnknown, toolsBar));
 #else
-    hResult = CoCreateInstance(CLSID_SH_AddressBand, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown,
-        reinterpret_cast<void **>(toolsBar));
+    hResult = CoCreateInstance(CLSID_SH_AddressBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, toolsBar));
 #endif
     if (FAILED(hResult))
         return hResult;
-    hResult = (*toolsBar)->QueryInterface(IID_IAddressBand, reinterpret_cast<void **>(&addressBand));
+    hResult = (*toolsBar)->QueryInterface(IID_PPV_ARG(IAddressBand, &addressBand));
     return S_OK;
 }
 
@@ -643,6 +680,8 @@ HRESULT CInternetToolbar::LockUnlockToolbars(bool locked)
             }
         }
         hResult = ReserveBorderSpace();
+
+        // TODO: refresh view menu?
     }
     return S_OK;
 }
@@ -663,11 +702,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;
@@ -678,13 +717,13 @@ HRESULT CInternetToolbar::CreateAndInitBandProxy()
     CComPtr<IServiceProvider>               serviceProvider;
     HRESULT                                 hResult;
 
-    hResult = fSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
+    hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
     if (FAILED(hResult))
         return hResult;
-    hResult = serviceProvider->QueryService(SID_IBandProxy, IID_IBandProxy, reinterpret_cast<void **>(&fBandProxy));
+    hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy));
     if (FAILED(hResult))
     {
-        hResult = CreateBandProxy(IID_IBandProxy, reinterpret_cast<void **>(&fBandProxy));
+        hResult = CreateBandProxy(IID_PPV_ARG(IBandProxy, &fBandProxy));
         if (FAILED(hResult))
             return hResult;
         hResult = fBandProxy->SetSite(fSite);
@@ -729,7 +768,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
 
     // show the bar here
     hResult = ReserveBorderSpace();
-    hResult = fMenuBar->QueryInterface(IID_IDockingWindow, reinterpret_cast<void **>(&dockingWindow));
+    hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
     hResult = dockingWindow->ShowDW(fShow);
     return S_OK;
 }
@@ -742,7 +781,36 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved)
 HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
     IUnknown *punkToolbarSite, BOOL fReserved)
 {
-    return E_NOTIMPL;
+    RECT neededBorderSpace;
+    RECT availableBorderSpace = *prcBorder;
+
+    SendMessage(fMainReBar, RB_SIZETORECT, RBSTR_CHANGERECT, reinterpret_cast<LPARAM>(&availableBorderSpace));
+
+    // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
+    // Let's make sure we fetch the actual size properly.
+    GetWindowRect(fMainReBar, &availableBorderSpace);
+    neededBorderSpace.left = 0;
+    neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top;
+    if (!fLocked)
+        neededBorderSpace.top += 3;
+    neededBorderSpace.right = 0;
+    neededBorderSpace.bottom = 0;
+
+    CComPtr<IDockingWindowSite> dockingWindowSite;
+    
+    HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
+    if (FAILED(hResult))
+        return hResult;
+
+    hResult = dockingWindowSite->RequestBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
+    if (FAILED(hResult))
+        return hResult;
+
+    hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
+    if (FAILED(hResult))
+        return hResult;
+
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID)
@@ -784,40 +852,46 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew()
     CComPtr<IOleWindow>                     navigationOleWindow;
     HRESULT                                 hResult;
 
+    /* Create and attach the menubar to the rebar */
     hResult = CreateMenuBar(&menuBar);
     if (FAILED(hResult))
         return hResult;
-    AddDockItem(menuBar, ITBBID_MENUBAND,
-        CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
+    AddDockItem(menuBar, ITBBID_MENUBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
 
-    hResult = menuBar->QueryInterface(IID_IOleWindow, reinterpret_cast<void **>(&menuOleWindow));
+    hResult = menuBar->QueryInterface(IID_PPV_ARG(IOleWindow, &menuOleWindow));
     hResult = menuOleWindow->GetWindow(&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))
         return hResult;
-    AddDockItem(logoBar, ITBBID_BRANDBAND,
-        CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
+    AddDockItem(logoBar, ITBBID_BRANDBAND, CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
     fLogoBar.Attach(logoBar.Detach());                  // transfer the ref count
+#endif
 
+    /* Create and attach the standard toolbar to the rebar */
     hResult = CreateToolsBar(&toolsBar);
     if (FAILED(hResult))
         return hResult;
-    AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS);
+    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_IOleWindow, reinterpret_cast<void **>(&toolbarOleWindow));
+    hResult = fControlsBar->QueryInterface(IID_PPV_ARG(IOleWindow, &toolbarOleWindow));
     if (FAILED(hResult))
         return hResult;
     hResult = toolbarOleWindow->GetWindow(&fToolbarWindow);
     if (FAILED(hResult))
         return hResult;
 
+    /* Create and attach the address/navigation toolbar to the rebar */
     hResult = CreateAddressBand(&navigationBar);
     if (FAILED(hResult))
         return hResult;
-    AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS);
-    hResult = navigationBar->QueryInterface(IID_IOleWindow, reinterpret_cast<void **>(&navigationOleWindow));
+    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());
 
@@ -957,7 +1031,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget
     HRESULT                                 hResult;
 
     fCommandTarget.Release();
-    hResult = theTarget->QueryInterface(IID_IOleCommandTarget, reinterpret_cast<void **>(&fCommandTarget));
+    hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget));
     if (FAILED(hResult))
         return hResult;
     fCommandCategory = *category;
@@ -1052,7 +1126,6 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
     HWND                                    ownerWindow;
     HWND                                    dockContainer;
     HRESULT                                 hResult;
-    DWORD                                   style;
 
     if (pUnkSite == NULL)
     {
@@ -1064,7 +1137,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
     else
     {
         // get window handle of owner
-        hResult = pUnkSite->QueryInterface(IID_IOleWindow, reinterpret_cast<void **>(&oleWindow));
+        hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
         if (FAILED(hResult))
             return hResult;
         hResult = oleWindow->GetWindow(&ownerWindow);
@@ -1082,17 +1155,19 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
         SubclassWindow(dockContainer);
 
         // create rebar in dock container
-        style = WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | RBS_VARHEIGHT |
-            RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_AUTOSIZE | CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_TOP;
-        fMainReBar = CreateWindow(REBARCLASSNAMEW, NULL, style,
+        DWORD style = WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
+                      RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_AUTOSIZE | RBS_DBLCLKTOGGLE |
+                      CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_TOP;
+        DWORD exStyle = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TOOLWINDOW;
+        fMainReBar = CreateWindowEx(exStyle, REBARCLASSNAMEW, NULL, style,
                             0, 0, 700, 60, dockContainer, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
         if (fMainReBar == NULL)
             return E_FAIL;
 
         // take advice to watch events
-        hResult = pUnkSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
+        hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
         hResult = serviceProvider->QueryService(
-            SID_SShellBrowser, IID_IBrowserService, reinterpret_cast<void **>(&browserService));
+            SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
         hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
     }
     return S_OK;
@@ -1125,10 +1200,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, RE
         }
         return fBandProxy->QueryInterface(riid, ppvObject);
     }
-    hResult = fSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
-    if (FAILED(hResult))
-        return hResult;
-    return serviceProvider->QueryService(guidService, riid, ppvObject);
+    return IUnknown_QueryService(fSite, guidService, riid, ppvObject);
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
@@ -1137,12 +1209,16 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
     CComPtr<IWinEventHandler>               menuWinEventHandler;
     HRESULT                                 hResult;
 
-    if (fMenuBar.p != NULL)
+    if (fMenuBar)
     {
-        hResult = fMenuBar->QueryInterface(IID_IWinEventHandler, reinterpret_cast<void **>(&menuWinEventHandler));
-        return menuWinEventHandler->OnWinEvent(fMenuBandWindow, uMsg, wParam, lParam, theResult);
+        hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
+        if (menuWinEventHandler->IsWindowOwner(hWnd) == S_OK)
+        {
+            return menuWinEventHandler->OnWinEvent(fMenuBandWindow, uMsg, wParam, lParam, theResult);
+        }
     }
-    return E_FAIL;
+
+    return S_FALSE;
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd)
@@ -1166,9 +1242,9 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID,
     if (ppstb == NULL)
         return E_POINTER;
     if (dwBandID == ITBBID_MENUBAND && fMenuBar.p != NULL)
-        return fMenuBar->QueryInterface(IID_IDeskBand, reinterpret_cast<void **>(ppstb));
-    if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
-        return fLogoBar->QueryInterface(IID_IDeskBand, reinterpret_cast<void **>(ppstb));
+        return fMenuBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
+    //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
+    //    return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
     *ppstb = NULL;
     return E_FAIL;
 }
@@ -1204,11 +1280,11 @@ LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl,
     CComPtr<IWebBrowser>                    webBrowser;
     HRESULT                                 hResult;
 
-    hResult = fSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
+    hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
     if (FAILED(hResult))
         return 0;
     hResult = serviceProvider->QueryService(SID_SShellBrowser,
-        IID_IWebBrowser, reinterpret_cast<void **>(&webBrowser));
+        IID_PPV_ARG(IWebBrowser, &webBrowser));
     if (FAILED(hResult))
         return 0;
     hResult = webBrowser->GoBack();
@@ -1221,11 +1297,11 @@ LRESULT CInternetToolbar::OnTravelForward(WORD wNotifyCode, WORD wID, HWND hWndC
     CComPtr<IWebBrowser>                    webBrowser;
     HRESULT                                 hResult;
 
-    hResult = fSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
+    hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
     if (FAILED(hResult))
         return 0;
     hResult = serviceProvider->QueryService(
-        SID_SShellBrowser, IID_IWebBrowser, reinterpret_cast<void **>(&webBrowser));
+        SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
     if (FAILED(hResult))
         return 0;
     hResult = webBrowser->GoForward();
@@ -1237,7 +1313,7 @@ LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BO
     CComPtr<IOleCommandTarget>              oleCommandTarget;
     HRESULT                                 hResult;
 
-    hResult = fSite->QueryInterface(IID_IOleCommandTarget, reinterpret_cast<void **>(&oleCommandTarget));
+    hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
     if (FAILED(hResult))
         return hResult;
     hResult = oleCommandTarget->Exec(&CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL);
@@ -1261,10 +1337,10 @@ LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOO
     commandInfo.nShow = SW_SHOWNORMAL;
 
     hResult = CoCreateInstance(CLSID_ShellSearchExt, NULL, CLSCTX_INPROC_SERVER,
-        IID_IContextMenu, reinterpret_cast<void **>(&contextMenu));
+        IID_PPV_ARG(IContextMenu, &contextMenu));
     if (FAILED(hResult))
         return 0;
-    hResult = contextMenu->QueryInterface(IID_IObjectWithSite, reinterpret_cast<void **>(&objectWithSite));
+    hResult = contextMenu->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
     if (FAILED(hResult))
         return 0;
     hResult = objectWithSite->SetSite(fSite);
@@ -1280,7 +1356,7 @@ LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BO
     CComPtr<IOleCommandTarget>              oleCommandTarget;
     HRESULT                                 hResult;
 
-    hResult = fSite->QueryInterface(IID_IOleCommandTarget, reinterpret_cast<void **>(&oleCommandTarget));
+    hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
     if (FAILED(hResult))
         return hResult;
     hResult = oleCommandTarget->Exec(&CGID_Explorer, 0x23, 0, NULL, NULL);
@@ -1324,14 +1400,14 @@ 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_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
+            hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
             hResult = serviceProvider->QueryService(
-                SID_SShellBrowser, IID_IBrowserService, reinterpret_cast<void **>(&browserService));
+                SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
             hResult = browserService->GetTravelLog(&travelLog);
             hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK);
-            hResult = browserService->QueryInterface(IID_IOleCommandTarget, reinterpret_cast<void **>(&commandTarget));
+            hResult = browserService->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
             commandInfo.cmdID = 0x1d;
             hResult = commandTarget->QueryStatus(&CGID_Explorer, 1, &commandInfo, NULL);
             if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
@@ -1354,14 +1430,13 @@ 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_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
-            hResult = serviceProvider->QueryService(SID_SShellBrowser, IID_IBrowserService,
-                reinterpret_cast<void **>(&browserService));
+            hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
+            hResult = serviceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
             hResult = browserService->GetTravelLog(&travelLog);
             hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE);
-            hResult = browserService->QueryInterface(IID_IOleCommandTarget, reinterpret_cast<void **>(&commandTarget));
+            hResult = browserService->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
             commandInfo.cmdID = 0x1d;
             hResult = commandTarget->QueryStatus(&CGID_Explorer, 1, &commandInfo, NULL);
             if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
@@ -1410,20 +1485,6 @@ LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHa
     return 1;
 }
 
-LRESULT CInternetToolbar::OnNavigateCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
-{
-    CComPtr<IWinEventHandler>               winEventHandler;
-    LRESULT                                 theResult;
-    HRESULT                                 hResult;
-
-    hResult = fNavigationBar->QueryInterface(IID_IWinEventHandler, reinterpret_cast<void **>(&winEventHandler));
-    hResult = winEventHandler->OnWinEvent(m_hWnd, uMsg, wParam, lParam, &theResult);
-    if (SUCCEEDED(hResult))
-        return theResult;
-    bHandled = FALSE;
-    return 0;
-}
-
 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
     HMENU                                   contextMenuBar;
@@ -1470,6 +1531,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;
+    command = 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);
@@ -1529,13 +1597,13 @@ 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_IBrowserService, reinterpret_cast<void **>(&browserService));
+            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))
             {
@@ -1553,27 +1621,138 @@ LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandle
     return 0;
 }
 
+LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+    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;
+            }
+        }
+    }
+
+    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;
+            }
+        }
+    }
+
+    return 0;
+}
 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
-    NMHDR                                   *notifyHeader;
-    CComPtr<IWinEventHandler>               menuWinEventHandler;
-    LRESULT                                 theResult;
-    HRESULT                                 hResult;
+    NMHDR   *notifyHeader;
+    LRESULT theResult;
+    HRESULT hResult;
+
+    notifyHeader = (NMHDR *) lParam;
 
-    notifyHeader = (NMHDR *)lParam;
-    if (fMenuBar.p != NULL && notifyHeader->hwndFrom == fMenuBandWindow)
+    if (fMenuBar)
     {
-        hResult = fMenuBar->QueryInterface(IID_IWinEventHandler, reinterpret_cast<void **>(&menuWinEventHandler));
-        hResult = menuWinEventHandler->OnWinEvent(fMenuBandWindow, uMsg, wParam, lParam, &theResult);
-        return theResult;
+        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;
+            }
+        }
     }
-    if (fNavigationBar.p != NULL && notifyHeader->hwndFrom == fNavigationWindow)
+
+    if (fNavigationBar)
     {
-        hResult = fNavigationBar->QueryInterface(
-            IID_IWinEventHandler, reinterpret_cast<void **>(&menuWinEventHandler));
-        hResult = menuWinEventHandler->OnWinEvent(m_hWnd, uMsg, wParam, lParam, &theResult);
-        return theResult;
+        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;
+            }
+        }
     }
+
+    return 0;
+}
+
+LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+    bHandled = FALSE;
+    if (fLocked)
+        return 0;
+
+    if (wParam & MK_CONTROL)
+        return 0;
+
+    fSizing = TRUE;
+
+    DWORD msgp = GetMessagePos();
+    
+    fStartPosition.x = GET_X_LPARAM(msgp);
+    fStartPosition.y = GET_Y_LPARAM(msgp);
+    
+    RECT rc;
+    GetWindowRect(m_hWnd, &rc);
+
+    fStartHeight = rc.bottom - rc.top;
+
+    SetCapture();
+
+    bHandled = TRUE;
+    return 0;
+}
+
+LRESULT CInternetToolbar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+    bHandled = FALSE;
+    if (!fSizing)
+        return 0;
+
+    DWORD msgp = GetMessagePos();
+
+    POINT pt;
+    pt.x = GET_X_LPARAM(msgp);
+    pt.y = GET_Y_LPARAM(msgp);
+
+    ReserveBorderSpace(fStartHeight - fStartPosition.y + pt.y);
+
+    bHandled = TRUE;
+    return 0;
+}
+
+LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+    bHandled = FALSE;
+    if (!fSizing)
+        return 0;
+
+    OnMouseMove(uMsg, wParam, lParam, bHandled);
+
+    fSizing = FALSE;
+
+    ReleaseCapture();
+
     return 0;
 }