Author: dquintana
Date: Wed Mar 19 15:33:41 2014
New Revision: 62534
URL: 
http://svn.reactos.org/svn/reactos?rev=62534&view=rev
Log:
[RSHELL]
* Implement WH_MSGFILTER hooking to handle the popup menus from the horizontal menubar.
Switching between menu items wby moving the mouse now works, but at the moment, the
non-menu popups (including the start menu) are somewhat glitchy.
CORE-7586
Modified:
    branches/shell-experiments/base/shell/rshell/CMenuBand.cpp
    branches/shell-experiments/base/shell/rshell/CMenuDeskBar.cpp
    branches/shell-experiments/base/shell/rshell/CMenuFocusManager.cpp
    branches/shell-experiments/base/shell/rshell/CMenuFocusManager.h
    branches/shell-experiments/base/shell/rshell/CMenuSite.cpp
    branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp
    branches/shell-experiments/base/shell/rshell/CMenuToolbars.h
    branches/shell-experiments/dll/win32/browseui/internettoolbar.cpp
Modified: branches/shell-experiments/base/shell/rshell/CMenuBand.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuBand.cpp  [iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/CMenuBand.cpp  [iso-8859-1] Wed Mar 19
15:33:41 2014
@@ -348,22 +348,6 @@
             return hr;
     }
-    CComPtr<IServiceProvider> sp;
-    CComPtr<IUnknown> unk0;
-    CComPtr<IDeskBar> db0, db, db1;
-    if (SUCCEEDED(IUnknown_GetSite(m_subMenuParent, IID_PPV_ARG(IServiceProvider,
&sp))) &&
-        SUCCEEDED(sp->QueryInterface(IID_PPV_ARG(IDeskBar, &db0))) &&
-        SUCCEEDED(db0->GetClient(&unk0)) &&
-        SUCCEEDED(IUnknown_QueryService(unk0, SID_SMenuBandChild, IID_PPV_ARG(IDeskBar,
&db))) &&
-        SUCCEEDED(IUnknown_QueryService(m_site, SID_SMenuBandParent,
IID_PPV_ARG(IDeskBar, &db1))))
-    {
-        if (fShow)
-            db->SetClient(db1);
-        else
-            db->SetClient(NULL);
-    }
-
-    if (m_dwFlags & SMINIT_VERTICAL)
     {
         if (fShow)
             hr = m_focusManager->PushMenu(this);
@@ -513,14 +497,13 @@
     if (m_subMenuChild)
         m_subMenuChild = NULL;
     if (!punkClient)
+    {
+        if (m_staticToolbar) m_staticToolbar->OnPopupItemChanged(NULL, -1);
+        if (m_SFToolbar) m_SFToolbar->OnPopupItemChanged(NULL, -1);
         return S_OK;
+    }
     HRESULT hr =  punkClient->QueryInterface(IID_PPV_ARG(IMenuPopup,
&m_subMenuChild));
     m_trackingPopup = m_subMenuChild != NULL;
-    if (!m_trackingPopup)
-    {
-        if (m_staticToolbar) m_staticToolbar->OnPopupItemChanged(NULL, -1);
-        if (m_SFToolbar) m_SFToolbar->OnPopupItemChanged(NULL, -1);
-    }
     return hr;
 }
Modified: branches/shell-experiments/base/shell/rshell/CMenuDeskBar.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuDeskBar.cpp       [iso-8859-1]
(original)
+++ branches/shell-experiments/base/shell/rshell/CMenuDeskBar.cpp       [iso-8859-1] Wed
Mar 19 15:33:41 2014
@@ -133,6 +133,17 @@
     {
         return this->QueryInterface(riid, ppvObject);
     }
+
+    if (IsEqualGUID(guidService, SID_SMenuBandBottom) ||
+        IsEqualGUID(guidService, SID_SMenuBandBottomSelected) ||
+        IsEqualGUID(guidService, SID_SMenuBandChild))
+    {
+        if (m_Client == NULL)
+            return E_NOINTERFACE;
+
+        return IUnknown_QueryService(m_Client, guidService, riid, ppvObject);
+    }
+
     if (m_Site == NULL)
         return E_NOINTERFACE;
@@ -643,7 +654,7 @@
 LRESULT CMenuDeskBar::_OnAppActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
&bHandled)
 {
-    if (wParam == 0)
+    if (wParam == 0 && m_Shown)
     {
         OnSelect(MPOS_FULLCANCEL);
     }
Modified: branches/shell-experiments/base/shell/rshell/CMenuFocusManager.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuFocusManager.cpp  [iso-8859-1]
(original)
+++ branches/shell-experiments/base/shell/rshell/CMenuFocusManager.cpp  [iso-8859-1] Wed
Mar 19 15:33:41 2014
@@ -23,6 +23,7 @@
 #include <shlwapi_undoc.h>
 #include "CMenuFocusManager.h"
+#include "CMenuToolbars.h"
 #include "CMenuBand.h"
 WINE_DEFAULT_DEBUG_CHANNEL(CMenuFocus);
@@ -65,6 +66,11 @@
     }
 }
+LRESULT CALLBACK CMenuFocusManager::s_MsgFilterHook(INT nCode, WPARAM wParam, LPARAM
lParam)
+{
+    return GetManager()->MsgFilterHook(nCode, wParam, lParam);
+}
+
 LRESULT CALLBACK CMenuFocusManager::s_GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
 {
     return GetManager()->GetMsgHook(nCode, wParam, lParam);
@@ -85,7 +91,7 @@
         *pItem = NULL;
     if (m_bandCount <= 0)
-        return E_FAIL;
+        return S_FALSE;
     m_bandCount--;
@@ -115,6 +121,10 @@
 CMenuFocusManager::CMenuFocusManager() :
     m_currentBand(NULL),
     m_currentFocus(NULL),
+    m_currentMenu(NULL),
+    m_parentToolbar(NULL),
+    m_hMsgFilterHook(NULL),
+    m_hGetMsgHook(NULL),
     m_mouseTrackDisabled(FALSE),
     m_lastMoveFlags(0),
     m_lastMovePos(0),
@@ -167,10 +177,7 @@
 HRESULT CMenuFocusManager::IsTrackedWindow(HWND hWnd)
 {
-    if (hWnd == m_currentFocus)
-        return S_OK;
-
-    int i = m_bandCount - 1;
+    int i = m_bandCount;
     while (--i >= 0)
     {
         CMenuBand * band = m_bandStack[i];
@@ -187,14 +194,17 @@
     return S_FALSE;
 }
-LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
-{
+LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam)
+{
+    HWND parent;
+    HWND child;
+    POINT pt;
+    int iHitTestResult;
+
     if (nCode < 0)
-        return CallNextHookEx(m_hHook, nCode, wParam, lParam);
-
-    LPARAM pos = (LPARAM) GetMessagePos();
-
-    if (nCode == HC_ACTION)
+        return CallNextHookEx(m_hMsgFilterHook, nCode, wParam, lParam);
+
+    if (nCode == MSGF_MENU)
     {
         BOOL callNext = TRUE;
         MSG* msg = reinterpret_cast<MSG*>(lParam);
@@ -203,15 +213,74 @@
         switch (msg->message)
         {
-        case WM_ACTIVATE: // does not trigger
-            ActivationChange(msg->hwnd);
+        case WM_MOUSEMOVE:
+
+            pt = msg->pt;
+
+            parent = WindowFromPoint(pt);
+
+            ScreenToClient(parent, &pt);
+
+            child = ChildWindowFromPoint(parent, pt);
+
+            if (child != m_parentToolbar)
+                break;
+
+            ScreenToClient(m_parentToolbar, &msg->pt);
+
+            /* Don't do anything if the mouse has not been moved */
+            if (msg->pt.x == m_ptPrev.x && msg->pt.y == m_ptPrev.y)
+                return TRUE;
+
+            m_ptPrev = msg->pt;
+
+            iHitTestResult = SendMessageW(m_parentToolbar, TB_HITTEST, 0, (LPARAM)
&msg->pt);
+
+            /* Make sure that iHitTestResult is one of the menu items and that it is not
the current menu item */
+            if (iHitTestResult >= 0)
+            {
+                if (SendMessage(m_parentToolbar, WM_USER_ISTRACKEDITEM, iHitTestResult,
0))
+                {
+                    SendMessage(m_currentFocus, WM_CANCELMODE, 0, 0);
+                    PostMessage(m_parentToolbar, WM_USER_CHANGETRACKEDITEM,
iHitTestResult, iHitTestResult);
+                    return TRUE;
+                }
+            }
+            break;
+        }
+
+        if (!callNext)
+            return 0;
+    }
+
+    return CallNextHookEx(m_hMsgFilterHook, nCode, wParam, lParam);
+}
+
+LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
+{
+    if (nCode < 0)
+        return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam);
+
+    LPARAM pos = (LPARAM) GetMessagePos();
+
+    if (nCode == HC_ACTION)
+    {
+        BOOL callNext = TRUE;
+        MSG* msg = reinterpret_cast<MSG*>(lParam);
+
+        // Do whatever is necessary here
+
+        switch (msg->message)
+        {
         case WM_CLOSE:
             break;
+
+        case WM_NCLBUTTONDOWN:
         case WM_LBUTTONDOWN:
         {
             POINT pt = { GET_X_LPARAM(pos), GET_Y_LPARAM(pos) };
-            HWND window = WindowFromPoint(pt);
+            HWND window = GetAncestor(WindowFromPoint(pt), GA_ROOT);
             if (IsTrackedWindow(window) != S_OK)
             {
@@ -274,88 +343,72 @@
             return 0;
     }
-    return CallNextHookEx(m_hHook, nCode, wParam, lParam);
-}
-
-HRESULT CMenuFocusManager::PlaceHooks(HWND window)
+    return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam);
+}
+
+HRESULT CMenuFocusManager::PlaceHooks()
 {
     //SetCapture(window);
-    m_hHook = SetWindowsHookEx(WH_GETMESSAGE, s_GetMsgHook, NULL, m_threadId);
-    return S_OK;
-}
-
-HRESULT CMenuFocusManager::RemoveHooks(HWND window)
-{
-    UnhookWindowsHookEx(m_hHook);
-    //ReleaseCapture();
-    return S_OK;
-}
-
-HRESULT CMenuFocusManager::ActivationChange(HWND newHwnd)
+    if (m_currentMenu)
+    {
+        m_hMsgFilterHook = SetWindowsHookEx(WH_MSGFILTER, s_MsgFilterHook, NULL,
m_threadId);
+    }
+    else
+    {
+        m_hGetMsgHook = SetWindowsHookEx(WH_GETMESSAGE, s_GetMsgHook, NULL, m_threadId);
+    }
+    return S_OK;
+}
+
+HRESULT CMenuFocusManager::RemoveHooks()
+{
+    if (m_hMsgFilterHook)
+        UnhookWindowsHookEx(m_hMsgFilterHook);
+    if (m_hGetMsgHook)
+        UnhookWindowsHookEx(m_hGetMsgHook);
+    m_hMsgFilterHook = NULL;
+    m_hGetMsgHook = NULL;
+    return S_OK;
+}
+
+HRESULT CMenuFocusManager::UpdateFocus(CMenuBand * newBand, HMENU popupToTrack)
 {
     HRESULT hr;
-    CMenuBand * newBand = NULL;
-
-    CMenuBand * band;
-    PeekArray(&band);
-
-    while (m_bandCount >= 0)
-    {
-        HWND hwnd;
-        hr = band->_GetTopLevelWindow(&hwnd);
+    HWND newFocus = NULL;
+    HWND oldFocus = m_currentFocus;
+    HMENU oldMenu = m_currentMenu;
+
+    if (newBand)
+    {
+        hr = newBand->_GetTopLevelWindow(&newFocus);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
-
-        if (hwnd == newHwnd)
-        {
-            newBand = band;
-            break;
-        }
-        else
-        {
-            PopFromArray(NULL);
-            PeekArray(&band);
-        }
-    }
-
-    return UpdateFocus(newBand);
-}
-
-HRESULT CMenuFocusManager::UpdateFocus(CMenuBand * newBand, HMENU popupToTrack)
-{
-    HRESULT hr;
-    HWND newFocus;
-
-    if (newBand == NULL)
-    {
-        DisableMouseTrack(NULL, FALSE);
-
-        hr = RemoveHooks(m_currentFocus);
-        m_currentFocus = NULL;
-        m_currentBand = NULL;
-        m_currentMenu = NULL;
-        return S_OK;
-    }
-
-    hr = newBand->_GetTopLevelWindow(&newFocus);
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    if (!m_currentBand)
-    {
-        hr = PlaceHooks(newFocus);
-        if (FAILED_UNEXPECTEDLY(hr))
-            return hr;
-    }
-
-    CHAR title[1024];
-    GetWindowTextA(newFocus, title, 1024);
-
-    DbgPrint("Focus is now at %08p, hwnd=%08x, title='%s'.
m_bandCount=%d\n", newBand, newFocus, title, m_bandCount);
-
-    m_currentFocus = newFocus;
+    }
+
     m_currentBand = newBand;
     m_currentMenu = popupToTrack;
+    m_currentFocus = newFocus;
+    if (m_currentMenu)
+    {
+        m_currentBand->GetWindow(&m_parentToolbar);
+    }
+
+    if (oldFocus && (!newFocus || (oldMenu != popupToTrack)))
+    {
+        DisableMouseTrack(NULL, FALSE);
+
+        hr = RemoveHooks();
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+    }
+
+    if (newFocus && (!oldFocus || (oldMenu != popupToTrack)))
+    {
+        hr = PlaceHooks();
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+    }
+
     return S_OK;
 }
@@ -364,9 +417,16 @@
 {
     HRESULT hr;
+    CMenuBand * mbParent = m_currentBand;
+
     hr = PushToArray(mb);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
+
+    if (mbParent)
+    {
+        mbParent->SetClient(static_cast<IMenuPopup*>(mb));
+    }
     return UpdateFocus(mb);
 }
@@ -387,11 +447,14 @@
         hr = PopFromArray(&mbc);
         if (FAILED_UNEXPECTEDLY(hr))
         {
-            mbc = NULL;
+            UpdateFocus(NULL);
             return hr;
         }
     }
     while (mbc && mb != mbc);
+
+    if (!mbc)
+        return E_FAIL;
     hr = PeekArray(&mb);
     if (FAILED_UNEXPECTEDLY(hr))
@@ -401,24 +464,61 @@
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
+    if (mb)
+    {
+        mb->SetClient(NULL);
+    }
+
+    return S_OK;
+}
+
+HRESULT CMenuFocusManager::PushTrackedPopup(CMenuBand * mb, HMENU popup)
+{
+    HRESULT hr;
+
+    hr = PushToArray(mb);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    return UpdateFocus(mb, popup);
+}
+
+HRESULT CMenuFocusManager::PopTrackedPopup(CMenuBand * mb, HMENU popup)
+{
+    CMenuBand * mbc;
+    HRESULT hr;
+
+    HWND newFocus;
+    hr = mb->_GetTopLevelWindow(&newFocus);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    DbgPrint("Trying to pop %08p, hwnd=%08x\n", mb, newFocus);
+
+    do {
+        hr = PopFromArray(&mbc);
+        if (FAILED_UNEXPECTEDLY(hr))
+        {
+            UpdateFocus(NULL);
+            return hr;
+        }
+    } while (mbc && mb != mbc);
+
     if (!mbc)
         return E_FAIL;
-    return S_OK;
-}
-
-HRESULT CMenuFocusManager::PushTrackedPopup(CMenuBand * mb, HMENU popup)
-{
-    HRESULT hr;
-
-    hr = PushToArray(mb);
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    return UpdateFocus(mb, popup);
-}
-
-HRESULT CMenuFocusManager::PopTrackedPopup(CMenuBand * mb, HMENU popup)
-{
-    return PopMenu(mb);
+    hr = PeekArray(&mb);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    hr = UpdateFocus(mb);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    if (mb)
+    {
+        mb->SetClient(NULL);
+    }
+
+    return S_OK;
 }
Modified: branches/shell-experiments/base/shell/rshell/CMenuFocusManager.h
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuFocusManager.h    [iso-8859-1]
(original)
+++ branches/shell-experiments/base/shell/rshell/CMenuFocusManager.h    [iso-8859-1] Wed
Mar 19 15:33:41 2014
@@ -36,17 +36,21 @@
     static void ReleaseManager(CMenuFocusManager * obj);
 private:
+    static LRESULT CALLBACK s_MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam);
     static LRESULT CALLBACK s_GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam);
 private:
     CMenuBand * m_currentBand;
     HWND m_currentFocus;
     HMENU m_currentMenu;
-    HHOOK m_hHook;
+    HWND m_parentToolbar;
+    HHOOK m_hGetMsgHook;
+    HHOOK m_hMsgFilterHook;
     DWORD m_threadId;
     BOOL m_mouseTrackDisabled;
     WPARAM m_lastMoveFlags;
     LPARAM m_lastMovePos;
+    POINT m_ptPrev;
     // TODO: make dynamic
 #define MAX_RECURSE 20
@@ -70,12 +74,13 @@
 private:
     LRESULT GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam);
-    HRESULT PlaceHooks(HWND window);
-    HRESULT RemoveHooks(HWND window);
+    LRESULT MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam);
+    HRESULT PlaceHooks();
+    HRESULT RemoveHooks();
     HRESULT UpdateFocus(CMenuBand * newBand, HMENU popupToTrack = NULL);
-    HRESULT ActivationChange(HWND newHwnd);
+    HRESULT IsTrackedWindow(HWND hWnd);
+
     void DisableMouseTrack(HWND enableTo, BOOL disableThis);
-    HRESULT IsTrackedWindow(HWND hWnd);
 public:
     HRESULT PushMenu(CMenuBand * mb);
Modified: branches/shell-experiments/base/shell/rshell/CMenuSite.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuSite.cpp  [iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/CMenuSite.cpp  [iso-8859-1] Wed Mar 19
15:33:41 2014
@@ -252,13 +252,13 @@
         IsEqualGUID(guidService, SID_SMenuBandChild))
     {
         if (m_BandObject == NULL)
-            return E_FAIL;
+            return E_NOINTERFACE;
         return IUnknown_QueryService(m_BandObject, guidService, riid, ppvObject);
     }
     if (!m_DeskBarSite)
-        return E_FAIL;
+        return E_NOINTERFACE;
     return IUnknown_QueryService(m_DeskBarSite, guidService, riid, ppvObject);
 }
Modified: branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp      [iso-8859-1]
(original)
+++ branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp      [iso-8859-1] Wed
Mar 19 15:33:41 2014
@@ -197,7 +197,8 @@
     m_hasIdealSize(FALSE),
     m_usePager(usePager),
     m_hotItem(-1),
-    m_popupItem(-1)
+    m_popupItem(-1),
+    m_isTracking(FALSE)
 {
     m_marlett = CreateFont(
         0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET,
@@ -401,6 +402,14 @@
     switch (uMsg)
     {
+    case WM_USER_ISTRACKEDITEM:
+        m_SubclassOld(hWnd, uMsg, wParam, lParam);
+        return IsTrackedItem(wParam);
+    case WM_USER_CHANGETRACKEDITEM:
+        m_isTracking = TRUE;
+        m_SubclassOld(hWnd, uMsg, wParam, lParam);
+        return ChangeTrackedItem(wParam);
+
     case WM_COMMAND:
         OnWinEvent(hWnd, uMsg, wParam, lParam, &lr);
         break;
@@ -461,6 +470,18 @@
         m_hotItem = hot->idNew;
         m_menuBand->_OnHotItemChanged(this, m_hotItem);
         m_menuBand->_MenuItemHotTrack(MPOS_CHILDTRACKING);
+
+        if (m_isTracking && !(m_toolbarFlags & SMINIT_VERTICAL))
+        {
+            KillTimer(m_hwndToolbar, TIMERID_HOTTRACK);
+
+            m_menuBand->_OnPopupSubMenu(NULL, NULL, NULL, NULL, -1);
+
+            if (HasSubMenu(m_hotItem) == S_OK)
+            {
+                PopupItem(m_hotItem);
+            }
+        }
         return S_OK;
     }
     return S_OK;
@@ -491,11 +512,38 @@
 {
     if (toolbar == NULL && m_popupBar == this)
     {
-        SendMessage(m_hwndToolbar, TB_CHECKBUTTON, item, FALSE);
+        SendMessage(m_hwndToolbar, TB_CHECKBUTTON, m_popupItem, FALSE);
+        m_isTracking = FALSE;
     }
     m_popupBar = toolbar;
     m_popupItem = item;
     InvalidateDraw();
+    return S_OK;
+}
+
+HRESULT CMenuToolbarBase::IsTrackedItem(INT index)
+{
+    TBBUTTON btn;
+
+    if (m_hotBar != this)
+        return S_FALSE;
+
+    SendMessage(m_hwndToolbar, TB_GETBUTTON, index,
reinterpret_cast<LPARAM>(&btn));
+
+    if (m_hotItem == btn.idCommand)
+        return S_OK;
+    return S_FALSE;
+}
+
+HRESULT CMenuToolbarBase::ChangeTrackedItem(INT index)
+{
+    TBBUTTON btn;
+    SendMessage(m_hwndToolbar, TB_GETBUTTON, index,
reinterpret_cast<LPARAM>(&btn));
+
+    if (m_hotItem != btn.idCommand)
+    {
+        SendMessage(m_hwndToolbar, TB_SETHOTITEM, index, 0);
+    }
     return S_OK;
 }
@@ -577,7 +625,8 @@
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
-    m_menuBand->_OnPopupSubMenu(popup, &pt, &rcl, this, m_popupItem);
+    m_isTracking = TRUE;
+    m_menuBand->_OnPopupSubMenu(popup, &pt, &rcl, this, uItem);
     return S_OK;
 }
@@ -613,9 +662,11 @@
     HMENU popup = GetSubMenu(menu, index);
+    m_isTracking = TRUE;
     m_menuBand->_TrackSubMenuUsingTrackPopupMenu(popup, pt.x, pt.y, rcl);
     SendMessage(m_hwndToolbar, TB_CHECKBUTTON, uItem, FALSE);
+    m_isTracking = FALSE;
     return S_OK;
 }
@@ -841,6 +892,12 @@
     INT index;
     DWORD_PTR dwData;
+    if (!(m_toolbarFlags & SMINIT_VERTICAL))
+    {
+        SendMessage(m_hwndToolbar, TB_SETHOTITEM, uItem, 0);
+        SendMessage(m_hwndToolbar, TB_CHECKBUTTON, uItem, TRUE);
+    }
+
     GetDataFromId(uItem, &index, &dwData);
     return InternalPopupItem(uItem, index, dwData);
Modified: branches/shell-experiments/base/shell/rshell/CMenuToolbars.h
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rs…
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuToolbars.h        [iso-8859-1]
(original)
+++ branches/shell-experiments/base/shell/rshell/CMenuToolbars.h        [iso-8859-1] Wed
Mar 19 15:33:41 2014
@@ -22,6 +22,10 @@
 class CMenuBand;
 class CMenuFocusManager;
+#define WM_USER_ISTRACKEDITEM (WM_USER+41)
+#define WM_USER_CHANGETRACKEDITEM (WM_USER+42)
+
+
 class CMenuToolbarBase
 {
 private:
@@ -44,6 +48,7 @@
     INT                m_popupItem;
     DWORD m_toolbarFlags;
+    BOOL m_isTracking;
 private:
     static LRESULT CALLBACK s_SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam);
@@ -69,6 +74,9 @@
     HRESULT ChangeHotItem(DWORD changeType);
     HRESULT OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * theResult);
+
+    HRESULT IsTrackedItem(INT index);
+    HRESULT ChangeTrackedItem(INT index);
     HRESULT GetIdealSize(SIZE& size);
     HRESULT SetPosSize(int x, int y, int cx, int cy);
Modified: branches/shell-experiments/dll/win32/browseui/internettoolbar.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/shell-experiments/dll/win32/bro…
==============================================================================
--- branches/shell-experiments/dll/win32/browseui/internettoolbar.cpp   [iso-8859-1]
(original)
+++ branches/shell-experiments/dll/win32/browseui/internettoolbar.cpp   [iso-8859-1] Wed
Mar 19 15:33:41 2014
@@ -325,15 +325,10 @@
 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()
@@ -1173,10 +1168,7 @@
         }
         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(