Author: dquintana
Date: Mon Apr  7 18:41:47 2014
New Revision: 62681

URL: http://svn.reactos.org/svn/reactos?rev=62681&view=rev
Log:
[RSHELL]
* Some code improvements, refactoring, and commenting.
* Using alternative method of handling hot-tracking, which does not break in 
win2003.
CORE-7586

Modified:
    branches/shell-experiments/base/shell/rshell/CMenuBand.cpp
    branches/shell-experiments/base/shell/rshell/CMenuBand.h
    branches/shell-experiments/base/shell/rshell/CMenuFocusManager.cpp
    branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp
    branches/shell-experiments/base/shell/rshell/CMenuToolbars.h

Modified: branches/shell-experiments/base/shell/rshell/CMenuBand.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rshell/CMenuBand.cpp?rev=62681&r1=62680&r2=62681&view=diff
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuBand.cpp  [iso-8859-1] 
(original)
+++ branches/shell-experiments/base/shell/rshell/CMenuBand.cpp  [iso-8859-1] 
Mon Apr  7 18:41:47 2014
@@ -260,26 +260,26 @@
 
 HRESULT STDMETHODCALLTYPE CMenuBand::OnPosRectChangeDB(RECT *prc)
 {
-    SIZE sizeStatic = { 0 };
-    SIZE sizeShlFld = { 0 };
+    SIZE maxStatic = { 0 };
+    SIZE maxShlFld = { 0 };
     HRESULT hr = S_OK;
 
     if (m_staticToolbar != NULL)
-        hr = m_staticToolbar->GetIdealSize(sizeStatic);
+        hr = m_staticToolbar->GetSizes(NULL, &maxStatic, NULL);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
     if (m_SFToolbar != NULL)
-        hr = m_SFToolbar->GetIdealSize(sizeShlFld);
+        hr = m_SFToolbar->GetSizes(NULL, &maxShlFld, NULL);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
     if (m_staticToolbar == NULL && m_SFToolbar == NULL)
         return E_FAIL;
 
-    int sy = min(prc->bottom - prc->top, sizeStatic.cy + sizeShlFld.cy);
-
-    int syStatic = sizeStatic.cy;
+    int sy = min(prc->bottom - prc->top, maxStatic.cy + maxShlFld.cy);
+
+    int syStatic = maxStatic.cy;
     int syShlFld = sy - syStatic;
 
     if (m_SFToolbar)
@@ -306,28 +306,46 @@
     DWORD dwViewMode,
     DESKBANDINFO *pdbi)
 {
-    SIZE sizeStatic = { 0 };
-    SIZE sizeShlFld = { 0 };
+    SIZE minStatic = { 0 };
+    SIZE minShlFld = { 0 };
+    SIZE maxStatic = { 0 };
+    SIZE maxShlFld = { 0 };
+    SIZE intStatic = { 0 };
+    SIZE intShlFld = { 0 };
 
     HRESULT hr = S_OK;
 
     if (m_staticToolbar != NULL)
-        hr = m_staticToolbar->GetIdealSize(sizeStatic);
+        hr = m_staticToolbar->GetSizes(&minStatic, &maxStatic, &intStatic);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
     if (m_SFToolbar != NULL)
-        hr = m_SFToolbar->GetIdealSize(sizeShlFld);
+        hr = m_SFToolbar->GetSizes(&minShlFld, &maxShlFld, &intShlFld);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
     if (m_staticToolbar == NULL && m_SFToolbar == NULL)
         return E_FAIL;
 
-    pdbi->ptMinSize.x = max(sizeStatic.cx, sizeShlFld.cx) + 20;
-    pdbi->ptMinSize.y = sizeStatic.cy + sizeShlFld.cy;
-    pdbi->ptMaxSize.x = max(sizeStatic.cx, sizeShlFld.cx) + 20;
-    pdbi->ptMaxSize.y = sizeStatic.cy + sizeShlFld.cy;
+    if (m_dwFlags & SMINIT_VERTICAL)
+    {
+        pdbi->ptMinSize.x = max(minStatic.cx, minStatic.cx) + 20;
+        pdbi->ptMinSize.y = minStatic.cy + minStatic.cy;
+        pdbi->ptMaxSize.x = max(maxStatic.cx, maxShlFld.cx) + 20;
+        pdbi->ptMaxSize.y = maxStatic.cy + maxShlFld.cy;
+        pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
+    }
+    else
+    {
+        pdbi->ptMinSize.x = minStatic.cx + minStatic.cx;
+        pdbi->ptMinSize.y = max(minStatic.cy, minStatic.cy);
+        pdbi->ptMaxSize.x = maxStatic.cx + maxShlFld.cx;
+        pdbi->ptMaxSize.y = max(maxStatic.cy, maxShlFld.cy);
+    }
+    pdbi->ptIntegral.x = max(intStatic.cx, intStatic.cx);
+    pdbi->ptIntegral.y = max(intStatic.cy, intShlFld.cy);
+    pdbi->ptActual = pdbi->ptMinSize;
 
     return S_OK;
 }
@@ -652,12 +670,10 @@
     smData.uId = id;
     smData.uIdParent = m_uId;
     smData.uIdAncestor = m_uIdAncestor;
+    smData.pidlItem = pidl;
     smData.hwnd = hwnd;
-    smData.pidlItem = pidl;
-    if (m_staticToolbar)
-    {
+    if (m_hmenu)
         smData.hmenu = m_hmenu;
-    }
     smData.pvUserData = NULL;
     if (m_SFToolbar)
         m_SFToolbar->GetShellFolder(NULL, &smData.pidlFolder, 
IID_PPV_ARG(IShellFolder, &smData.psf));
@@ -668,7 +684,7 @@
     return hr;
 }
 
-HRESULT CMenuBand::_TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, 
RECT& rcExclude)
+HRESULT CMenuBand::_TrackSubMenu(HMENU popup, INT x, INT y, RECT& rcExclude)
 {
     TPMPARAMS params = { sizeof(TPMPARAMS), rcExclude };
 
@@ -688,6 +704,41 @@
     _DisableMouseTrack(FALSE);
 
     return S_OK;
+}
+
+HRESULT CMenuBand::_TrackContextMenu(IContextMenu * contextMenu, INT x, INT y)
+{
+    HRESULT hr;
+    UINT uCommand;
+    HMENU popup = CreatePopupMenu();
+
+    if (popup == NULL)
+        return E_FAIL;
+
+    hr = contextMenu->QueryContextMenu(popup, 0, 0, UINT_MAX, CMF_NORMAL);
+    if (FAILED_UNEXPECTEDLY(hr))
+    {
+        DestroyMenu(popup);
+        return hr;
+    }
+
+    HWND hwnd = m_menuOwner ? m_menuOwner : m_topLevelWindow;
+
+    m_focusManager->PushTrackedPopup(popup);
+    uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, x, y, m_menuOwner, 
NULL);
+    m_focusManager->PopTrackedPopup(popup);
+
+    if (uCommand == 0)
+        return S_FALSE;
+
+    CMINVOKECOMMANDINFO cmi = { 0 };
+    cmi.cbSize = sizeof(cmi);
+    cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
+    cmi.hwnd = hwnd;
+    hr = contextMenu->InvokeCommand(&cmi);
+
+    DestroyMenu(popup);
+    return hr;
 }
 
 HRESULT CMenuBand::_GetTopLevelWindow(HWND*topLevel)
@@ -728,119 +779,91 @@
     return S_OK;
 }
 
+HRESULT  CMenuBand::_KeyboardItemChange(DWORD change)
+{
+    HRESULT hr;
+    CMenuToolbarBase *tb = m_hotBar;
+
+    if (!tb)
+    {
+        // If no hot item was selected
+        // choose the first toolbar (prefer shell-folder, which will be 
positionedat the top)
+
+        if (m_SFToolbar)
+            tb = m_SFToolbar;
+        else
+            tb = m_staticToolbar;
+    }
+
+    // Ask the first toolbar to change
+    hr = tb->KeyboardItemChange(change);
+
+    if (hr != S_FALSE)
+        return hr;
+
+    // Select the second toolbar based on the first
+    if (tb == m_SFToolbar)
+        tb = m_staticToolbar;
+    else
+        tb = m_SFToolbar;
+
+    if (!tb)
+        return hr;
+
+    // Ask the second toolbar to change
+    return tb->KeyboardItemChange(change == VK_DOWN ? VK_END : VK_HOME);
+}
+
 HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
 {
     HRESULT hr;
 
-    if (!(m_dwFlags & SMINIT_VERTICAL))
-    {
-        if (changeType == MPOS_SELECTRIGHT)
+    
+    if (m_dwFlags & SMINIT_VERTICAL)
+    {
+        switch (changeType)
         {
-            SendMessageW(m_menuOwner, WM_CANCELMODE, 0, 0);
-            if (m_SFToolbar && (m_hotBar == m_SFToolbar || m_hotBar == NULL))
-            {
-                DbgPrint("SF Toolbars in Horizontal menus is not 
implemented.\n");
-                return S_FALSE;
-            }
-            else if (m_staticToolbar && m_hotBar == m_staticToolbar)
-            {
-                hr = m_staticToolbar->KeyboardItemChange(VK_DOWN);
-                if (hr == S_FALSE)
-                {
-                    if (m_SFToolbar)
-                        return m_SFToolbar->KeyboardItemChange(VK_HOME);
-                    else
-                        return m_staticToolbar->KeyboardItemChange(VK_HOME);
-                }
+        case VK_UP:
+        case VK_DOWN:
+            return _KeyboardItemChange(changeType);
+
+            // TODO: Left/Right across multi-column menus, if they ever work.
+        case VK_LEFT:
+            changeType = MPOS_SELECTLEFT;
+            break;
+        case VK_RIGHT:
+            changeType = MPOS_SELECTRIGHT;
+            break;
+        }
+    }
+    else
+    {
+        // In horizontal menubars, left/right are equivalent to vertical's 
up/down
+        switch(changeType)
+        {
+        case VK_LEFT:
+            hr = _KeyboardItemChange(VK_UP);
+            if (hr != S_FALSE)
                 return hr;
-            }
+        case VK_RIGHT:
+            hr = _KeyboardItemChange(VK_DOWN);
+            if (hr != S_FALSE)
+                return hr;
         }
-        else if (changeType == MPOS_SELECTLEFT)
+    }
+
+    switch (changeType)
+    {
+    case MPOS_SELECTLEFT:
+        if (!m_subMenuParent)
         {
-            SendMessageW(m_menuOwner, WM_CANCELMODE, 0, 0);
-            if (m_staticToolbar && (m_hotBar == m_staticToolbar || m_hotBar == 
NULL))
-            {
-                hr = m_staticToolbar->KeyboardItemChange(VK_UP);
-                if (hr == S_FALSE)
-                {
-                    if (m_SFToolbar)
-                        return m_SFToolbar->KeyboardItemChange(VK_END);
-                    else
-                        return m_staticToolbar->KeyboardItemChange(VK_END);
-                }
-                return hr;
-            }
-            else if (m_SFToolbar && m_hotBar == m_SFToolbar)
-            {
-                DbgPrint("SF Toolbars in Horizontal menus is not 
implemented.\n");
-                return S_FALSE;
-            }
+            if (m_subMenuChild)
+                return m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
+            return S_OK;
         }
-    }
-    else if (changeType == VK_DOWN)
-    {
-        if (m_SFToolbar && (m_hotBar == m_SFToolbar || m_hotBar == NULL))
-        {
-            hr = m_SFToolbar->KeyboardItemChange(VK_DOWN);
-            if (hr == S_FALSE)
-            {
-                if (m_staticToolbar)
-                    return m_staticToolbar->KeyboardItemChange(VK_HOME);
-                else
-                    return m_SFToolbar->KeyboardItemChange(VK_HOME);
-            }
-            return hr;
-        }
-        else if (m_staticToolbar && m_hotBar == m_staticToolbar)
-        {
-            hr = m_staticToolbar->KeyboardItemChange(VK_DOWN);
-            if (hr == S_FALSE)
-            {
-                if (m_SFToolbar)
-                    return m_SFToolbar->KeyboardItemChange(VK_HOME);
-                else
-                    return m_staticToolbar->KeyboardItemChange(VK_HOME);
-            }
-            return hr;
-        }
-    }
-    else if (changeType == VK_UP)
-    {
-        if (m_staticToolbar && (m_hotBar == m_staticToolbar || m_hotBar == 
NULL))
-        {
-            hr = m_staticToolbar->KeyboardItemChange(VK_UP);
-            if (hr == S_FALSE)
-            {
-                if (m_SFToolbar)
-                    return m_SFToolbar->KeyboardItemChange(VK_END);
-                else
-                    return m_staticToolbar->KeyboardItemChange(VK_END);
-            }
-            return hr;
-        }
-        else if (m_SFToolbar && m_hotBar == m_SFToolbar)
-        {
-            hr = m_SFToolbar->KeyboardItemChange(VK_UP);
-            if (hr == S_FALSE)
-            {
-                if (m_staticToolbar)
-                    return m_staticToolbar->KeyboardItemChange(VK_END);
-                else
-                    return m_SFToolbar->KeyboardItemChange(VK_END);
-            }
-            return hr;
-        }
-    }
-    else if (changeType == MPOS_SELECTLEFT)
-    {
-        if (m_subMenuChild)
-            m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
-        if (!m_subMenuParent)
-            return S_OK;
         return m_subMenuParent->OnSelect(MPOS_CANCELLEVEL);
-    }
-    else if (changeType == MPOS_SELECTRIGHT)
-    {
+
+    case MPOS_SELECTRIGHT:
         if (m_hotBar && m_hotItem >= 0)
         {
             if (m_hotBar->PopupItem(m_hotItem) == S_OK)
@@ -848,14 +871,14 @@
         }
         if (!m_subMenuParent)
             return S_OK;
-        return m_subMenuParent->OnSelect(changeType);
-    }
-    else
-    {
+        return m_subMenuParent->OnSelect(MPOS_SELECTRIGHT);
+
+    default:
         if (!m_subMenuParent)
             return S_OK;
         return m_subMenuParent->OnSelect(changeType);
     }
+
     return S_OK;
 }
 
@@ -868,8 +891,60 @@
     return hr;
 }
 
-HRESULT CMenuBand::_OnPopupSubMenu(IMenuPopup * popup, POINTL * pAt, RECTL * 
pExclude)
-{
+HRESULT CMenuBand::_OnPopupSubMenu(IShellMenu * childShellMenu, POINTL * pAt, 
RECTL * pExclude)
+{
+    HRESULT hr = 0;
+    IBandSite* pBandSite;
+    IDeskBar* pDeskBar;
+
+    // Create the necessary objects
+
+#if USE_SYSTEM_MENUSITE
+    hr = CoCreateInstance(CLSID_MenuBandSite,
+        NULL,
+        CLSCTX_INPROC_SERVER,
+        IID_PPV_ARG(IBandSite, &pBandSite));
+#else
+    hr = CMenuSite_Constructor(IID_PPV_ARG(IBandSite, &pBandSite));
+#endif
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+#if WRAP_MENUSITE
+    hr = CMenuSite_Wrapper(pBandSite, IID_PPV_ARG(IBandSite, &pBandSite));
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+#endif
+
+#if USE_SYSTEM_MENUDESKBAR
+    hr = CoCreateInstance(CLSID_MenuDeskBar,
+        NULL,
+        CLSCTX_INPROC_SERVER,
+        IID_PPV_ARG(IDeskBar, &pDeskBar));
+#else
+    hr = CMenuDeskBar_Constructor(IID_PPV_ARG(IDeskBar, &pDeskBar));
+#endif
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+#if WRAP_MENUDESKBAR
+    hr = CMenuDeskBar_Wrapper(pDeskBar, IID_PPV_ARG(IDeskBar, &pDeskBar));
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+#endif
+
+    hr = pDeskBar->SetClient(pBandSite);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    hr = pBandSite->AddBand(childShellMenu);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    // 
+    CComPtr<IMenuPopup> popup;
+    hr = pDeskBar->QueryInterface(IID_PPV_ARG(IMenuPopup, &popup));
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
     m_subMenuChild = popup;
     
     if (m_subMenuParent)

Modified: branches/shell-experiments/base/shell/rshell/CMenuBand.h
URL: 
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rshell/CMenuBand.h?rev=62681&r1=62680&r2=62681&view=diff
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuBand.h    [iso-8859-1] 
(original)
+++ branches/shell-experiments/base/shell/rshell/CMenuBand.h    [iso-8859-1] 
Mon Apr  7 18:41:47 2014
@@ -175,13 +175,14 @@
 
     HRESULT _CallCBWithItemId(UINT Id, UINT uMsg, WPARAM wParam, LPARAM 
lParam);
     HRESULT _CallCBWithItemPidl(LPITEMIDLIST pidl, UINT uMsg, WPARAM wParam, 
LPARAM lParam);
-    HRESULT _TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, RECT& 
rcExclude);
+    HRESULT _TrackSubMenu(HMENU popup, INT x, INT y, RECT& rcExclude);
+    HRESULT _TrackContextMenu(IContextMenu * popup, INT x, INT y);
     HRESULT _GetTopLevelWindow(HWND*topLevel);
     HRESULT _ChangeHotItem(CMenuToolbarBase * tb, INT id, DWORD dwFlags);
     HRESULT _ChangePopupItem(CMenuToolbarBase * tb, INT id);
     HRESULT _MenuItemHotTrack(DWORD changeType);
     HRESULT _CancelCurrentPopup();
-    HRESULT _OnPopupSubMenu(IMenuPopup * popup, POINTL * pAt, RECTL * 
pExclude);
+    HRESULT _OnPopupSubMenu(IShellMenu * childShellMenu, POINTL * pAt, RECTL * 
pExclude);
     HRESULT _DisableMouseTrack(BOOL bDisable);
     HRESULT _SetChildBand(CMenuBand * child);
     HRESULT _SetParentBand(CMenuBand * parent);
@@ -195,5 +196,6 @@
     }
 
 private:
+    HRESULT _KeyboardItemChange(DWORD change);
     HRESULT _CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam, UINT id = 0, 
LPITEMIDLIST pidl = NULL);
 };

Modified: branches/shell-experiments/base/shell/rshell/CMenuFocusManager.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rshell/CMenuFocusManager.cpp?rev=62681&r1=62680&r2=62681&view=diff
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuFocusManager.cpp  
[iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/CMenuFocusManager.cpp  
[iso-8859-1] Mon Apr  7 18:41:47 2014
@@ -261,7 +261,7 @@
 
     // Don't do anything if another window is capturing the mouse.
     HWND cCapture = ::GetCapture();
-    if (cCapture && cCapture != m_captureHwnd)
+    if (cCapture && cCapture != m_captureHwnd && m_current->type != 
TrackedMenuEntry)
         return TRUE;
 
     m_ptPrev = pt;
@@ -283,7 +283,8 @@
             {
                 m_entryUnderMouse->mb->_ChangeHotItem(NULL, -1, HICF_MOUSE);
             }
-            SetCapture(NULL);
+            if (cCapture == m_captureHwnd)
+                SetCapture(NULL);
         }
 
     }
@@ -303,7 +304,8 @@
             if (m_current->type == TrackedMenuEntry)
                 SendMessage(entry->hwnd, WM_CANCELMODE, 0, 0);
             PostMessage(child, WM_USER_CHANGETRACKEDITEM, iHitTestResult, 
isTracking);
-            return FALSE;
+            if (m_current->type == TrackedMenuEntry)
+                return FALSE;
         }
     }
 
@@ -311,10 +313,10 @@
     {
         if (entry)
         {
-            SetCapture(child);
-
             if (m_current->type == MenuPopupEntry)
             {
+                //SetCapture(child);
+
                 ScreenToClient(child, &pt2);
                 SendMessage(child, WM_MOUSEMOVE, msg->wParam, 
MAKELPARAM(pt2.x, pt2.y));
             }
@@ -399,6 +401,10 @@
         case WM_MOUSEMOVE:
             callNext = ProcessMouseMove(msg);
             break;
+        case WM_MOUSELEAVE:
+            callNext = ProcessMouseMove(msg);
+            //callNext = ProcessMouseLeave(msg);
+            break;
         case WM_SYSKEYDOWN:
         case WM_KEYDOWN:
             if (m_current->type == MenuPopupEntry)
@@ -406,16 +412,17 @@
                 DisableMouseTrack(m_current->hwnd, TRUE);
                 switch (msg->wParam)
                 {
+                case VK_ESCAPE:
                 case VK_MENU:
                 case VK_LMENU:
                 case VK_RMENU:
                     m_current->mb->_MenuItemHotTrack(MPOS_FULLCANCEL);
                     break;
                 case VK_LEFT:
-                    m_current->mb->_MenuItemHotTrack(MPOS_SELECTLEFT);
+                    m_current->mb->_MenuItemHotTrack(VK_LEFT);
                     break;
                 case VK_RIGHT:
-                    m_current->mb->_MenuItemHotTrack(MPOS_SELECTRIGHT);
+                    m_current->mb->_MenuItemHotTrack(VK_RIGHT);
                     break;
                 case VK_UP:
                     m_current->mb->_MenuItemHotTrack(VK_UP);

Modified: branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp?rev=62681&r1=62680&r2=62681&view=diff
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp      
[iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp      
[iso-8859-1] Mon Apr  7 18:41:47 2014
@@ -159,7 +159,7 @@
 HRESULT CMenuToolbarBase::OnPagerCalcSize(LPNMPGCALCSIZE csize)
 {
     SIZE tbs;
-    GetIdealSize(tbs);
+    GetSizes(NULL, &tbs, NULL);
     if (csize->dwFlag == PGF_CALCHEIGHT)
     {
         csize->iHeight = tbs.cy;
@@ -284,12 +284,16 @@
     m_menuBand(menuBand),
     m_hwndToolbar(NULL),
     m_dwMenuFlags(0),
-    m_hasIdealSize(FALSE),
+    m_hasSizes(FALSE),
     m_usePager(usePager),
     m_hotItem(-1),
     m_popupItem(-1),
-    m_isTracking(FALSE)
-{
+    m_isTrackingPopup(FALSE)
+{
+    m_idealSize.cx = 0;
+    m_idealSize.cy = 0;
+    m_itemSize.cx = 0;
+    m_itemSize.cy = 0;
     m_marlett = CreateFont(
         0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET,
         OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
@@ -452,18 +456,38 @@
     return S_OK;
 }
 
-HRESULT CMenuToolbarBase::GetIdealSize(SIZE& size)
-{
-    size.cx = size.cy = 0;
-
-    if (m_hwndToolbar && !m_hasIdealSize)
-    {
-        SendMessageW(m_hwndToolbar, TB_AUTOSIZE, 0, 0);
-        SendMessageW(m_hwndToolbar, TB_GETMAXSIZE, 0, 
reinterpret_cast<LPARAM>(&m_idealSize));
-        m_hasIdealSize = TRUE;
-    }
-
-    size = m_idealSize;
+HRESULT CMenuToolbarBase::GetSizes(SIZE* pMinSize, SIZE* pMaxSize, SIZE* 
pIntegralSize)
+{
+    if (pMinSize)
+        *pMinSize = m_idealSize;
+    if (pMaxSize)
+        *pMaxSize = m_idealSize;
+    if (pIntegralSize)
+        *pIntegralSize = m_itemSize;
+    
+    if (m_hasSizes)
+        return S_OK;
+
+    if (!m_hwndToolbar)
+        return S_OK;
+
+    // Obtain the ideal size, to be used as min and max
+    SendMessageW(m_hwndToolbar, TB_AUTOSIZE, 0, 0);
+    SendMessageW(m_hwndToolbar, TB_GETMAXSIZE, 0, 
reinterpret_cast<LPARAM>(&m_idealSize));
+    SendMessageW(m_hwndToolbar, TB_GETIDEALSIZE, (m_initFlags & 
SMINIT_VERTICAL) != 0, reinterpret_cast<LPARAM>(&m_idealSize));
+    
+    // Obtain the button size, to be used as the integral size
+    DWORD size = SendMessageW(m_hwndToolbar, TB_GETBUTTONSIZE, 0, 0);
+    m_itemSize.cx = GET_X_LPARAM(size);
+    m_itemSize.cy = GET_Y_LPARAM(size);
+    m_hasSizes = TRUE;
+
+    if (pMinSize)
+        *pMinSize = m_idealSize;
+    if (pMaxSize)
+        *pMaxSize = m_idealSize;
+    if (pIntegralSize)
+        *pIntegralSize = m_itemSize;
 
     return S_OK;
 }
@@ -560,46 +584,21 @@
     return S_FALSE;
 }
 
-HRESULT CMenuToolbarBase::OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * 
theResult)
-{
+HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, 
DWORD dwFlags)
+{
+    // Ignore the change if it already matches the stored info
+    if (m_hotBar == toolbar && m_hotItem == item)
+        return S_FALSE;
+
     // Prevent a change of hot item if the change was triggered by the mouse,
     // and mouse tracking is disabled.
-    if (m_disableMouseTrack && hot->dwFlags & HICF_MOUSE)
-    {
-        *theResult = 1;
+    if (m_disableMouseTrack && dwFlags & HICF_MOUSE)
+    {
         DbgPrint("Hot item change prevented by DisableMouseTrack\n");
         return S_OK;
     }
 
-    HRESULT hr = S_OK;
-    if (hot->dwFlags & HICF_LEAVING)
-    {
-        // Only notify of LEAVING if this was the hot toolbar.
-        if (m_hotBar == this)
-        {
-            DbgPrint("The hot bar is now cold.\n");
-            hr = m_menuBand->_ChangeHotItem(NULL, -1, hot->dwFlags);
-        }
-    }
-    else
-    {
-        hr = m_menuBand->_ChangeHotItem(this, hot->idNew, hot->dwFlags);
-    }
-
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    // Reuse S_OK/S_FALSE as Continue/Cancel
-    *theResult = hr;
-
-    return S_OK;
-}
-
-HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, 
DWORD dwFlags)
-{
-    if (m_hotBar == toolbar && m_hotItem == item)
-        return S_FALSE;
-
+    // Notify the toolbar if the hot-tracking left this toolbar
     if (m_hotBar == this && toolbar != this)
     {
         SendMessage(m_hwndToolbar, TB_SETHOTITEM, (WPARAM)-1, 0);
@@ -623,8 +622,9 @@
                 m_timerEnabled = TRUE;
                 DbgPrint("SetTimer called with m_hotItem=%d\n", m_hotItem);
             }
-            else if (m_isTracking)
+            else if (m_isTrackingPopup)
             {
+                // If the menubar has an open submenu, switch to the new 
item's submenu immediately
                 PopupItem(m_hotItem);
             }
         }
@@ -646,13 +646,15 @@
 
 HRESULT CMenuToolbarBase::ChangePopupItem(CMenuToolbarBase * toolbar, INT item)
 {
+    // Ignore the change if it already matches the stored info
     if (m_popupBar == toolbar && m_popupItem == item)
         return S_FALSE;
 
+    // Notify the toolbar if the popup-tracking this toolbar
     if (m_popupBar == this && toolbar != this)
     {
         SendMessage(m_hwndToolbar, TB_CHECKBUTTON, m_popupItem, FALSE);
-        m_isTracking = FALSE;
+        m_isTrackingPopup = FALSE;
     }
 
     m_popupBar = toolbar;
@@ -693,7 +695,7 @@
         return E_FAIL;
 
     DbgPrint("Changing tracked item to %d...\n", index);
-    m_isTracking = wasTracking;
+    m_isTrackingPopup = wasTracking;
     m_menuBand->_ChangeHotItem(this, btn.idCommand, HICF_MOUSE);
 
     return S_OK;
@@ -701,10 +703,7 @@
 
 HRESULT CMenuToolbarBase::PopupSubMenu(UINT iItem, UINT index, IShellMenu* 
childShellMenu)
 {
-    IBandSite* pBandSite;
-    IDeskBar* pDeskBar;
-
-    HRESULT hr = 0;
+    // Calculate the submenu position and exclude area
     RECT rc = { 0 };
     RECT rcx = { 0 };
 
@@ -732,81 +731,31 @@
         pt.y = a.y - 3;
     }
 
-#if USE_SYSTEM_MENUSITE
-    hr = CoCreateInstance(CLSID_MenuBandSite,
-        NULL,
-        CLSCTX_INPROC_SERVER,
-        IID_PPV_ARG(IBandSite, &pBandSite));
-#else
-    hr = CMenuSite_Constructor(IID_PPV_ARG(IBandSite, &pBandSite));
-#endif
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-#if WRAP_MENUSITE
-    hr = CMenuSite_Wrapper(pBandSite, IID_PPV_ARG(IBandSite, &pBandSite));
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-#endif
-
-#if USE_SYSTEM_MENUDESKBAR
-    hr = CoCreateInstance(CLSID_MenuDeskBar,
-        NULL,
-        CLSCTX_INPROC_SERVER,
-        IID_PPV_ARG(IDeskBar, &pDeskBar));
-#else
-    hr = CMenuDeskBar_Constructor(IID_PPV_ARG(IDeskBar, &pDeskBar));
-#endif
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-#if WRAP_MENUDESKBAR
-    hr = CMenuDeskBar_Wrapper(pDeskBar, IID_PPV_ARG(IDeskBar, &pDeskBar));
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-#endif
-
-    hr = pDeskBar->SetClient(pBandSite);
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    hr = pBandSite->AddBand(childShellMenu);
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    CComPtr<IMenuPopup> popup;
-    hr = pDeskBar->QueryInterface(IID_PPV_ARG(IMenuPopup, &popup));
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    m_isTracking = TRUE;
+    // Display the submenu
+    m_isTrackingPopup = TRUE;
 
     m_menuBand->_ChangePopupItem(this, iItem);
-    m_menuBand->_OnPopupSubMenu(popup, &pt, &rcl);
+    m_menuBand->_OnPopupSubMenu(childShellMenu, &pt, &rcl);
 
     return S_OK;
 }
 
 HRESULT CMenuToolbarBase::PopupSubMenu(UINT iItem, UINT index, HMENU menu)
 {
+    // Calculate the submenu position and exclude area
     RECT rc = { 0 };
-    RECT rcx = { 0 };
 
     if (!SendMessage(m_hwndToolbar, TB_GETITEMRECT, index, 
reinterpret_cast<LPARAM>(&rc)))
         return E_FAIL;
-
-    GetClientRect(m_hwndToolbar, &rcx);
-
+    
     POINT a = { rc.left, rc.top };
     POINT b = { rc.right, rc.bottom };
-    POINT c = { rc.left, rc.top };
-    POINT d = { rc.right, rc.bottom };
 
     ClientToScreen(m_hwndToolbar, &a);
     ClientToScreen(m_hwndToolbar, &b);
-    ClientToScreen(m_hwndToolbar, &c);
-    ClientToScreen(m_hwndToolbar, &d);
 
     POINT pt = { a.x, b.y };
-    RECT rcl = { c.x, c.y, d.x, d.y };
+    RECT rcl = { a.x, a.y, b.x, b.y };
 
     if (m_initFlags & SMINIT_VERTICAL)
     {
@@ -816,45 +765,24 @@
 
     HMENU popup = GetSubMenu(menu, index);
 
-    m_isTracking = TRUE;
-
+    // Display the submenu
+    m_isTrackingPopup = TRUE;
     m_menuBand->_ChangePopupItem(this, iItem);
-    m_menuBand->_TrackSubMenuUsingTrackPopupMenu(popup, pt.x, pt.y, rcl);
+    m_menuBand->_TrackSubMenu(popup, pt.x, pt.y, rcl);
     m_menuBand->_ChangePopupItem(NULL, -1);
-
-    m_isTracking = FALSE;
+    m_isTrackingPopup = FALSE;
 
     return S_OK;
 }
 
 HRESULT CMenuToolbarBase::DoContextMenu(IContextMenu* contextMenu)
 {
-    HRESULT hr;
-    HMENU hPopup = CreatePopupMenu();
-
-    if (hPopup == NULL)
-        return E_FAIL;
-
-    hr = contextMenu->QueryContextMenu(hPopup, 0, 0, UINT_MAX, CMF_NORMAL);
-    if (FAILED_UNEXPECTEDLY(hr))
-    {
-        DestroyMenu(hPopup);
-        return hr;
-    }
-
+    // Calculate the context menu position
     DWORD dwPos = GetMessagePos();
-    UINT uCommand = ::TrackPopupMenu(hPopup, TPM_RETURNCMD, 
GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos), 0, m_hwnd, NULL);
-    if (uCommand == 0)
-        return S_FALSE;
-
-    CMINVOKECOMMANDINFO cmi = { 0 };
-    cmi.cbSize = sizeof(cmi);
-    cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
-    cmi.hwnd = m_hwnd;
-    hr = contextMenu->InvokeCommand(&cmi);
-
-    DestroyMenu(hPopup);
-    return hr;
+    POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
+
+    // Display the submenu
+    return m_menuBand->_TrackContextMenu(contextMenu, pt.x, pt.y);
 }
 
 HRESULT CMenuToolbarBase::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT 
*theResult)
@@ -866,6 +794,13 @@
         return S_OK;
     }
 
+    // If a button is clicked while a submenu was open, cancel the submenu.
+    if (!(m_initFlags & SMINIT_VERTICAL) && m_isTrackingPopup)
+    {
+        DbgPrint("OnCommand cancelled because it was tracking submenu.\n");
+        return S_FALSE;
+    }
+    
     *theResult = 0;
 
     m_menuBand->_KillPopupTimers();
@@ -883,7 +818,7 @@
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
-    return S_OK; // filter out a possible S_FALSE from here.
+    return OnCommandInternal(wParam, lParam, theResult);
 }
 
 HRESULT CMenuToolbarBase::KeyboardItemChange(DWORD dwSelectType)
@@ -948,7 +883,7 @@
                 if (prev != btn.idCommand)
                 {
                     DbgPrint("Setting Hot item to %d\n", index);
-                    SendMessage(m_hwndToolbar, TB_SETHOTITEM, index, 0);
+                    m_menuBand->_ChangeHotItem(this, index, 0);
                 }
                 return S_OK;
             }
@@ -967,8 +902,9 @@
     if (prev != -1)
     {
         DbgPrint("Setting Hot item to null\n");
-        SendMessage(m_hwndToolbar, TB_SETHOTITEM, (WPARAM) -1, 0);
-    }
+        m_menuBand->_ChangeHotItem(NULL, -1, 0);
+    }
+
     return S_FALSE;
 }
 
@@ -1219,25 +1155,8 @@
     return DoContextMenu(contextMenu);
 }
 
-HRESULT CMenuStaticToolbar::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT 
*theResult)
-{
-    HRESULT hr;
-
-    if (m_isTracking)
-    {
-        return S_FALSE;
-    }
-
-    hr = CMenuToolbarBase::OnCommand(wParam, lParam, theResult);
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    // in case the clicked item has a submenu, we do not need to execute the 
item
-    if (hr == S_FALSE)
-    {
-        return hr;
-    }
-
+HRESULT CMenuStaticToolbar::OnCommandInternal(WPARAM wParam, LPARAM lParam, 
LRESULT *theResult)
+{
     return m_menuBand->_CallCBWithItemId(wParam, SMC_EXEC, 0, 0);
 }
 
@@ -1313,7 +1232,6 @@
         hr = m_shellFolder->GetAttributesOf(1, &itemc, &attrs);
 
         DWORD_PTR dwData = reinterpret_cast<DWORD_PTR>(ILClone(item));
-        // FIXME: remove before deleting the toolbar or it will leak
 
         // Fetch next item already, so we know if the current one is the last
         hr = eidl->Next(1, &item, &fetched);
@@ -1399,21 +1317,10 @@
     return DoContextMenu(contextMenu);
 }
 
-HRESULT CMenuSFToolbar::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT 
*theResult)
-{
-    HRESULT hr;
-    hr = CMenuToolbarBase::OnCommand(wParam, lParam, theResult);
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    // in case the clicked item has a submenu, we do not need to execute the 
item
-    if (hr == S_FALSE)
-    {
-        DbgPrint("CMenuToolbarBase::OnCommand told us to cancel.\n");
-        return hr;
-    }
-
+HRESULT CMenuSFToolbar::OnCommandInternal(WPARAM wParam, LPARAM lParam, 
LRESULT *theResult)
+{
     DWORD_PTR data;
+
     GetDataFromId(wParam, NULL, &data);
 
     return 
m_menuBand->_CallCBWithItemPidl(reinterpret_cast<LPITEMIDLIST>(data), 
SMC_SFEXEC, 0, 0);

Modified: branches/shell-experiments/base/shell/rshell/CMenuToolbars.h
URL: 
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rshell/CMenuToolbars.h?rev=62681&r1=62680&r2=62681&view=diff
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuToolbars.h        
[iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/CMenuToolbars.h        
[iso-8859-1] Mon Apr  7 18:41:47 2014
@@ -40,8 +40,9 @@
     CMenuBand * m_menuBand;
     HWND        m_hwndToolbar;
     DWORD       m_dwMenuFlags;
-    BOOL        m_hasIdealSize;
+    BOOL        m_hasSizes;
     SIZE        m_idealSize;
+    SIZE        m_itemSize;
     BOOL        m_usePager;
     CMenuToolbarBase * m_hotBar;
     INT                m_hotItem;
@@ -49,7 +50,7 @@
     INT                m_popupItem;
 
     DWORD m_initFlags;
-    BOOL m_isTracking;
+    BOOL m_isTrackingPopup;
 
 private:
     static LRESULT CALLBACK s_SubclassProc(HWND hWnd, UINT uMsg, WPARAM 
wParam, LPARAM lParam);
@@ -74,12 +75,11 @@
     HRESULT DoContextMenu(IContextMenu* contextMenu);
 
     HRESULT KeyboardItemChange(DWORD changeType);
-    HRESULT OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * theResult);
 
     HRESULT IsTrackedItem(INT index);
     HRESULT ChangeTrackedItem(INT index, BOOL wasTracking);
 
-    HRESULT GetIdealSize(SIZE& size);
+    HRESULT GetSizes(SIZE* pMinSize, SIZE* pMaxSize, SIZE* pIntegralSize);
     HRESULT SetPosSize(int x, int y, int cx, int cy);
 
     void InvalidateDraw();
@@ -96,7 +96,7 @@
     HRESULT KillPopupTimer();
 
 protected:
-    virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT 
*theResult);
+    virtual HRESULT OnCommandInternal(WPARAM wParam, LPARAM lParam, LRESULT 
*theResult) = 0;
 
     virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb) = 0;
     virtual HRESULT InternalPopupItem(INT iItem, INT index, DWORD_PTR dwData) 
= 0;
@@ -113,6 +113,7 @@
     HRESULT UpdateImageLists();
 
 private:
+    HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult);
     HRESULT OnPagerCalcSize(LPNMPGCALCSIZE csize);
     HRESULT OnPopupTimer(DWORD timerId);
     HRESULT OnCustomDraw(LPNMTBCUSTOMDRAW cdraw, LRESULT * theResult);
@@ -133,7 +134,7 @@
     HRESULT GetMenu(HMENU *phmenu, HWND *phwnd, DWORD *pdwFlags);
 
     virtual HRESULT FillToolbar(BOOL clearFirst=FALSE);
-    virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT 
*theResult);
+    virtual HRESULT OnCommandInternal(WPARAM wParam, LPARAM lParam, LRESULT 
*theResult);
     virtual HRESULT OnContextMenu(NMMOUSE * rclick);
 
 protected:
@@ -161,7 +162,7 @@
     HRESULT GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, 
void **ppv);
 
     virtual HRESULT FillToolbar(BOOL clearFirst=FALSE);
-    virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT 
*theResult);
+    virtual HRESULT OnCommandInternal(WPARAM wParam, LPARAM lParam, LRESULT 
*theResult);
     virtual HRESULT OnContextMenu(NMMOUSE * rclick);
 
 protected:


Reply via email to