[RSHELL]
authorDavid Quintana <gigaherz@gmail.com>
Wed, 19 Mar 2014 15:33:41 +0000 (15:33 +0000)
committerDavid Quintana <gigaherz@gmail.com>
Wed, 19 Mar 2014 15:33:41 +0000 (15:33 +0000)
* 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

svn path=/branches/shell-experiments/; revision=62534

base/shell/rshell/CMenuBand.cpp
base/shell/rshell/CMenuDeskBar.cpp
base/shell/rshell/CMenuFocusManager.cpp
base/shell/rshell/CMenuFocusManager.h
base/shell/rshell/CMenuSite.cpp
base/shell/rshell/CMenuToolbars.cpp
base/shell/rshell/CMenuToolbars.h
dll/win32/browseui/internettoolbar.cpp

index 6c340f3..30703b5 100644 (file)
@@ -348,22 +348,6 @@ HRESULT STDMETHODCALLTYPE  CMenuBand::ShowDW(BOOL fShow)
             return hr;
     }
 
             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);
     {
         if (fShow)
             hr = m_focusManager->PushMenu(this);
@@ -513,14 +497,13 @@ HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
     if (m_subMenuChild)
         m_subMenuChild = NULL;
     if (!punkClient)
     if (m_subMenuChild)
         m_subMenuChild = NULL;
     if (!punkClient)
-        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);
     {
         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;
     return hr;
 }
 
     return hr;
 }
 
index c12d3ce..94340cd 100644 (file)
@@ -133,6 +133,17 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryService(REFGUID guidService, REFIID
     {
         return this->QueryInterface(riid, ppvObject);
     }
     {
         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;
 
     if (m_Site == NULL)
         return E_NOINTERFACE;
@@ -643,7 +654,7 @@ LRESULT CMenuDeskBar::_OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam,
 
 LRESULT CMenuDeskBar::_OnAppActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
 
 LRESULT CMenuDeskBar::_OnAppActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
-    if (wParam == 0)
+    if (wParam == 0 && m_Shown)
     {
         OnSelect(MPOS_FULLCANCEL);
     }
     {
         OnSelect(MPOS_FULLCANCEL);
     }
index 3ab2890..aca523c 100644 (file)
@@ -23,6 +23,7 @@
 #include <shlwapi_undoc.h>
 
 #include "CMenuFocusManager.h"
 #include <shlwapi_undoc.h>
 
 #include "CMenuFocusManager.h"
+#include "CMenuToolbars.h"
 #include "CMenuBand.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(CMenuFocus);
 #include "CMenuBand.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(CMenuFocus);
@@ -65,6 +66,11 @@ void CMenuFocusManager::ReleaseManager(CMenuFocusManager * obj)
     }
 }
 
     }
 }
 
+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);
 LRESULT CALLBACK CMenuFocusManager::s_GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
 {
     return GetManager()->GetMsgHook(nCode, wParam, lParam);
@@ -85,7 +91,7 @@ HRESULT CMenuFocusManager::PopFromArray(CMenuBand ** pItem)
         *pItem = NULL;
 
     if (m_bandCount <= 0)
         *pItem = NULL;
 
     if (m_bandCount <= 0)
-        return E_FAIL;
+        return S_FALSE;
 
     m_bandCount--;
 
 
     m_bandCount--;
 
@@ -115,6 +121,10 @@ HRESULT CMenuFocusManager::PeekArray(CMenuBand ** pItem)
 CMenuFocusManager::CMenuFocusManager() :
     m_currentBand(NULL),
     m_currentFocus(NULL),
 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),
     m_mouseTrackDisabled(FALSE),
     m_lastMoveFlags(0),
     m_lastMovePos(0),
@@ -167,10 +177,7 @@ void CMenuFocusManager::DisableMouseTrack(HWND enableTo, BOOL disableThis)
 
 HRESULT CMenuFocusManager::IsTrackedWindow(HWND hWnd)
 {
 
 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];
     while (--i >= 0)
     {
         CMenuBand * band = m_bandStack[i];
@@ -187,10 +194,72 @@ HRESULT CMenuFocusManager::IsTrackedWindow(HWND hWnd)
     return S_FALSE;
 }
 
     return S_FALSE;
 }
 
+LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam)
+{
+    HWND parent;
+    HWND child;
+    POINT pt;
+    int iHitTestResult;
+
+    if (nCode < 0)
+        return CallNextHookEx(m_hMsgFilterHook, nCode, wParam, lParam);
+
+    if (nCode == MSGF_MENU)
+    {
+        BOOL callNext = TRUE;
+        MSG* msg = reinterpret_cast<MSG*>(lParam);
+
+        // Do whatever is necessary here
+
+        switch (msg->message)
+        {
+        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)
 LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
 {
     if (nCode < 0)
-        return CallNextHookEx(m_hHook, nCode, wParam, lParam);
+        return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam);
 
     LPARAM pos = (LPARAM) GetMessagePos();
 
 
     LPARAM pos = (LPARAM) GetMessagePos();
 
@@ -203,15 +272,15 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
 
         switch (msg->message)
         {
 
         switch (msg->message)
         {
-        case WM_ACTIVATE: // does not trigger
-            ActivationChange(msg->hwnd);
         case WM_CLOSE:
             break;
         case WM_CLOSE:
             break;
+
+        case WM_NCLBUTTONDOWN:
         case WM_LBUTTONDOWN:
         {
             POINT pt = { GET_X_LPARAM(pos), GET_Y_LPARAM(pos) };
 
         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)
             {
 
             if (IsTrackedWindow(window) != S_OK)
             {
@@ -274,88 +343,72 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
             return 0;
     }
 
             return 0;
     }
 
-    return CallNextHookEx(m_hHook, nCode, wParam, lParam);
+    return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam);
 }
 
 }
 
-HRESULT CMenuFocusManager::PlaceHooks(HWND window)
+HRESULT CMenuFocusManager::PlaceHooks()
 {
     //SetCapture(window);
 {
     //SetCapture(window);
-    m_hHook = SetWindowsHookEx(WH_GETMESSAGE, s_GetMsgHook, NULL, m_threadId);
+    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;
 }
 
     return S_OK;
 }
 
-HRESULT CMenuFocusManager::RemoveHooks(HWND window)
+HRESULT CMenuFocusManager::RemoveHooks()
 {
 {
-    UnhookWindowsHookEx(m_hHook);
-    //ReleaseCapture();
+    if (m_hMsgFilterHook)
+        UnhookWindowsHookEx(m_hMsgFilterHook);
+    if (m_hGetMsgHook)
+        UnhookWindowsHookEx(m_hGetMsgHook);
+    m_hMsgFilterHook = NULL;
+    m_hGetMsgHook = NULL;
     return S_OK;
 }
 
     return S_OK;
 }
 
-HRESULT CMenuFocusManager::ActivationChange(HWND newHwnd)
+HRESULT CMenuFocusManager::UpdateFocus(CMenuBand * newBand, HMENU popupToTrack)
 {
     HRESULT hr;
 {
     HRESULT hr;
-    CMenuBand * newBand = NULL;
-    
-    CMenuBand * band;
-    PeekArray(&band);
+    HWND newFocus = NULL;
+    HWND oldFocus = m_currentFocus;
+    HMENU oldMenu = m_currentMenu;
 
 
-    while (m_bandCount >= 0)
+    if (newBand)
     {
     {
-        HWND hwnd;
-        hr = band->_GetTopLevelWindow(&hwnd);
+        hr = newBand->_GetTopLevelWindow(&newFocus);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
         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;
+    m_currentBand = newBand;
+    m_currentMenu = popupToTrack;
+    m_currentFocus = newFocus;
+    if (m_currentMenu)
+    {
+        m_currentBand->GetWindow(&m_parentToolbar);
+    }
 
 
-    if (newBand == NULL)
+    if (oldFocus && (!newFocus || (oldMenu != popupToTrack)))
     {
         DisableMouseTrack(NULL, FALSE);
 
     {
         DisableMouseTrack(NULL, FALSE);
 
-        hr = RemoveHooks(m_currentFocus);
-        m_currentFocus = NULL;
-        m_currentBand = NULL;
-        m_currentMenu = NULL;
-        return S_OK;
+        hr = RemoveHooks();
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
     }
     }
-
-    hr = newBand->_GetTopLevelWindow(&newFocus);
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    if (!m_currentBand)
+    
+    if (newFocus && (!oldFocus || (oldMenu != popupToTrack)))
     {
     {
-        hr = PlaceHooks(newFocus);
+        hr = PlaceHooks();
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
     }
 
         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;
 
     return S_OK;
 }
 
     return S_OK;
 }
@@ -364,10 +417,17 @@ HRESULT CMenuFocusManager::PushMenu(CMenuBand * mb)
 {
     HRESULT hr;
 
 {
     HRESULT hr;
 
+    CMenuBand * mbParent = m_currentBand;
+
     hr = PushToArray(mb);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
     hr = PushToArray(mb);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
+    if (mbParent)
+    {
+        mbParent->SetClient(static_cast<IMenuPopup*>(mb));
+    }
+
     return UpdateFocus(mb);
 }
 
     return UpdateFocus(mb);
 }
 
@@ -387,11 +447,14 @@ HRESULT CMenuFocusManager::PopMenu(CMenuBand * mb)
         hr = PopFromArray(&mbc);
         if (FAILED_UNEXPECTEDLY(hr))
         {
         hr = PopFromArray(&mbc);
         if (FAILED_UNEXPECTEDLY(hr))
         {
-            mbc = NULL;
+            UpdateFocus(NULL);
             return hr;
         }
     }
     while (mbc && mb != mbc);
             return hr;
         }
     }
     while (mbc && mb != mbc);
+
+    if (!mbc)
+        return E_FAIL;
     
     hr = PeekArray(&mb);
     if (FAILED_UNEXPECTEDLY(hr))
     
     hr = PeekArray(&mb);
     if (FAILED_UNEXPECTEDLY(hr))
@@ -401,8 +464,10 @@ HRESULT CMenuFocusManager::PopMenu(CMenuBand * mb)
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
-    if (!mbc)
-        return E_FAIL;
+    if (mb)
+    {
+        mb->SetClient(NULL);
+    }
 
     return S_OK;
 }
 
     return S_OK;
 }
@@ -420,5 +485,40 @@ HRESULT CMenuFocusManager::PushTrackedPopup(CMenuBand * mb, HMENU popup)
 
 HRESULT CMenuFocusManager::PopTrackedPopup(CMenuBand * mb, HMENU popup)
 {
 
 HRESULT CMenuFocusManager::PopTrackedPopup(CMenuBand * mb, HMENU popup)
 {
-    return PopMenu(mb);
+    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;
+
+    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;
 }
\ No newline at end of file
 }
\ No newline at end of file
index ed5c588..79eea36 100644 (file)
@@ -36,17 +36,21 @@ public:
     static void ReleaseManager(CMenuFocusManager * obj);
 
 private:
     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;
     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;
     DWORD m_threadId;
     BOOL m_mouseTrackDisabled;
     WPARAM m_lastMoveFlags;
     LPARAM m_lastMovePos;
+    POINT m_ptPrev;
 
     // TODO: make dynamic
 #define MAX_RECURSE 20
 
     // TODO: make dynamic
 #define MAX_RECURSE 20
@@ -70,13 +74,14 @@ public:
 
 private:
     LRESULT GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam);
 
 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 UpdateFocus(CMenuBand * newBand, HMENU popupToTrack = NULL);
-    HRESULT ActivationChange(HWND newHwnd);
-    void DisableMouseTrack(HWND enableTo, BOOL disableThis);
     HRESULT IsTrackedWindow(HWND hWnd);
 
     HRESULT IsTrackedWindow(HWND hWnd);
 
+    void DisableMouseTrack(HWND enableTo, BOOL disableThis);
+
 public:
     HRESULT PushMenu(CMenuBand * mb);
     HRESULT PopMenu(CMenuBand * mb);
 public:
     HRESULT PushMenu(CMenuBand * mb);
     HRESULT PopMenu(CMenuBand * mb);
index d824d63..a90c89b 100644 (file)
@@ -252,13 +252,13 @@ HRESULT STDMETHODCALLTYPE CMenuSite::QueryService(REFGUID guidService, REFIID ri
         IsEqualGUID(guidService, SID_SMenuBandChild))
     {
         if (m_BandObject == NULL)
         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 IUnknown_QueryService(m_BandObject, guidService, riid, ppvObject);
     }
 
     if (!m_DeskBarSite)
-        return E_FAIL;
+        return E_NOINTERFACE;
 
     return IUnknown_QueryService(m_DeskBarSite, guidService, riid, ppvObject);
 }
 
     return IUnknown_QueryService(m_DeskBarSite, guidService, riid, ppvObject);
 }
index 8328426..5fc5b7e 100644 (file)
@@ -197,7 +197,8 @@ CMenuToolbarBase::CMenuToolbarBase(CMenuBand *menuBand, BOOL usePager) :
     m_hasIdealSize(FALSE),
     m_usePager(usePager),
     m_hotItem(-1),
     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,
 {
     m_marlett = CreateFont(
         0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET,
@@ -401,6 +402,14 @@ LRESULT CMenuToolbarBase::SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
 
     switch (uMsg)
     {
 
     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;
     case WM_COMMAND:
         OnWinEvent(hWnd, uMsg, wParam, lParam, &lr);
         break;
@@ -461,6 +470,18 @@ HRESULT CMenuToolbarBase::OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * the
         m_hotItem = hot->idNew;
         m_menuBand->_OnHotItemChanged(this, m_hotItem);
         m_menuBand->_MenuItemHotTrack(MPOS_CHILDTRACKING);
         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;
         return S_OK;
     }
     return S_OK;
@@ -491,7 +512,8 @@ HRESULT CMenuToolbarBase::OnPopupItemChanged(CMenuToolbarBase * toolbar, INT ite
 {
     if (toolbar == NULL && m_popupBar == this)
     {
 {
     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;
     }
     m_popupBar = toolbar;
     m_popupItem = item;
@@ -499,6 +521,32 @@ HRESULT CMenuToolbarBase::OnPopupItemChanged(CMenuToolbarBase * toolbar, INT ite
     return S_OK;
 }
 
     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;
+}
+
 HRESULT CMenuToolbarBase::PopupSubMenu(UINT uItem, UINT index, IShellMenu* childShellMenu)
 {
     IBandSite* pBandSite;
 HRESULT CMenuToolbarBase::PopupSubMenu(UINT uItem, UINT index, IShellMenu* childShellMenu)
 {
     IBandSite* pBandSite;
@@ -577,7 +625,8 @@ HRESULT CMenuToolbarBase::PopupSubMenu(UINT uItem, UINT index, IShellMenu* child
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
     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;
 }
 
     return S_OK;
 }
@@ -613,9 +662,11 @@ HRESULT CMenuToolbarBase::PopupSubMenu(UINT uItem, UINT index, HMENU menu)
 
     HMENU popup = GetSubMenu(menu, index);
 
 
     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_menuBand->_TrackSubMenuUsingTrackPopupMenu(popup, pt.x, pt.y, rcl);
 
     SendMessage(m_hwndToolbar, TB_CHECKBUTTON, uItem, FALSE);
+    m_isTracking = FALSE;
 
     return S_OK;
 }
 
     return S_OK;
 }
@@ -841,6 +892,12 @@ HRESULT CMenuToolbarBase::PopupItem(INT uItem)
     INT index;
     DWORD_PTR dwData;
 
     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);
     GetDataFromId(uItem, &index, &dwData);
 
     return InternalPopupItem(uItem, index, dwData);
index a611813..0a33ec7 100644 (file)
 class CMenuBand;
 class CMenuFocusManager;
 
 class CMenuBand;
 class CMenuFocusManager;
 
+#define WM_USER_ISTRACKEDITEM (WM_USER+41)
+#define WM_USER_CHANGETRACKEDITEM (WM_USER+42)
+
+
 class CMenuToolbarBase
 {
 private:
 class CMenuToolbarBase
 {
 private:
@@ -44,6 +48,7 @@ protected:
     INT                m_popupItem;
 
     DWORD m_toolbarFlags;
     INT                m_popupItem;
 
     DWORD m_toolbarFlags;
+    BOOL m_isTracking;
 
 private:
     static LRESULT CALLBACK s_SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
 private:
     static LRESULT CALLBACK s_SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
@@ -70,6 +75,9 @@ public:
     HRESULT ChangeHotItem(DWORD changeType);
     HRESULT OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * theResult);
 
     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);
 
     HRESULT GetIdealSize(SIZE& size);
     HRESULT SetPosSize(int x, int y, int cx, int cy);
 
index b81772d..ec48dd9 100644 (file)
@@ -325,15 +325,10 @@ HRESULT STDMETHODCALLTYPE CDockSite::Exec(const GUID *pguidCmdGroup, DWORD nCmdI
 
 HRESULT STDMETHODCALLTYPE CDockSite::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
 {
 
 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);
     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()
 }
 
 CMenuCallback::CMenuCallback()
@@ -1173,10 +1168,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, RE
         }
         return fBandProxy->QueryInterface(riid, ppvObject);
     }
         }
         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(
 }
 
 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(