Author: dquintana Date: Wed Mar 26 11:33:52 2014 New Revision: 62567
URL: http://svn.reactos.org/svn/reactos?rev=62567&view=rev Log: [RSHELL] * Redesigned large portions of the focus manager. All the mouse interactions seem to work now 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/CMenuToolbars.cpp branches/shell-experiments/base/shell/rshell/misc.cpp branches/shell-experiments/base/shell/rshell/precomp.h
Modified: branches/shell-experiments/base/shell/rshell/CMenuBand.cpp URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rsh... ============================================================================== --- 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 26 11:33:52 2014 @@ -284,17 +284,17 @@ if (m_SFToolbar) { m_SFToolbar->SetPosSize( - prc->left, - prc->top, - prc->right - prc->left, + prc->left, + prc->top, + prc->right - prc->left, syShlFld); } if (m_staticToolbar) { m_staticToolbar->SetPosSize( - prc->left, - prc->top + syShlFld, - prc->right - prc->left, + prc->left, + prc->top + syShlFld, + prc->right - prc->left, syStatic); }
@@ -360,10 +360,20 @@ m_parentBand->SetClient(NULL); }
- if (fShow) - hr = m_focusManager->PushMenu(this); + if (_IsPopup() == S_OK) + { + if (fShow) + hr = m_focusManager->PushMenuPopup(this); + else + hr = m_focusManager->PopMenuPopup(this); + } else - hr = m_focusManager->PopMenu(this); + { + if (fShow) + hr = m_focusManager->PushMenuBar(this); + else + hr = m_focusManager->PopMenuBar(this); + }
return S_OK; } @@ -510,15 +520,15 @@
HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient) { - if (m_subMenuChild) - m_subMenuChild = NULL; + 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)); + HRESULT hr = punkClient->QueryInterface(IID_PPV_ARG(IMenuPopup, &m_subMenuChild)); m_trackingPopup = m_subMenuChild != NULL; DbgPrint("Tracking: %d\n", m_trackingPopup); return hr; @@ -596,7 +606,7 @@ { return m_SFToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult); } - + return S_FALSE; }
@@ -659,7 +669,7 @@ m_trackingPopup = TRUE; DbgPrint("Tracking: %d\n", m_trackingPopup);
- m_focusManager->PushTrackedPopup(this, popup); + m_focusManager->PushTrackedPopup(popup); if (m_menuOwner) { ::TrackPopupMenuEx(popup, flags, x, y, m_menuOwner, ¶ms); @@ -668,7 +678,7 @@ { ::TrackPopupMenuEx(popup, flags, x, y, m_topLevelWindow, ¶ms); } - m_focusManager->PopTrackedPopup(this, popup); + m_focusManager->PopTrackedPopup(popup);
m_trackingPopup = FALSE; DbgPrint("Tracking: %d\n", m_trackingPopup); @@ -1008,8 +1018,8 @@ return S_OK; }
-HRESULT STDMETHODCALLTYPE CMenuBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) -{ - UNIMPLEMENTED; - return S_OK; -} +HRESULT STDMETHODCALLTYPE CMenuBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText) +{ + UNIMPLEMENTED; + return S_OK; +}
Modified: branches/shell-experiments/base/shell/rshell/CMenuDeskBar.cpp URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rsh... ============================================================================== --- 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 26 11:33:52 2014 @@ -133,7 +133,7 @@ { return this->QueryInterface(riid, ppvObject); } - + if (IsEqualGUID(guidService, SID_SMenuBandBottom) || IsEqualGUID(guidService, SID_SMenuBandBottomSelected) || IsEqualGUID(guidService, SID_SMenuBandChild)) @@ -299,7 +299,7 @@ ::GetObject(m_Banner, sizeof(bm), &bm); rc.right += bm.bmWidth; } - + int x, y, cx, cy;
RECT rcWorkArea; @@ -350,7 +350,7 @@ { cy = waHeight; } - + if (y + cy > rcWorkArea.bottom) { y = rcWorkArea.bottom - cy; @@ -438,23 +438,23 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(DWORD dwSelectType) { /* As far as I can tell, the submenu hierarchy looks like this: - - The DeskBar's Child is the Band it contains. - The DeskBar's Parent is the SID_SMenuPopup of the Site. - - The Band's Child is the IMenuPopup of the child submenu. - The Band's Parent is the SID_SMenuPopup of the Site (the DeskBar). - - When the DeskBar receives a selection event: - If it requires closing the window, it will notify the Child (Band) using CancelLevel. - If it has to spread upwards (everything but CancelLevel), it will notify the Parent. - - When the Band receives a selection event, this is where it gets fuzzy: - In which cases does it call the Parent? Probably not CancelLevel. - In which cases does it call the Child? - How does it react to calls? - - */ + * + * The DeskBar's Child is the Band it contains. + * The DeskBar's Parent is the SID_SMenuPopup of the Site. + * + * The Band's Child is the IMenuPopup of the child submenu. + * The Band's Parent is the SID_SMenuPopup of the Site (the DeskBar). + * + * When the DeskBar receives a selection event: + * If it requires closing the window, it will notify the Child (Band) using CancelLevel. + * If it has to spread upwards (everything but CancelLevel), it will notify the Parent. + * + * When the Band receives a selection event, this is where it gets fuzzy: + * In which cases does it call the Parent? Probably not CancelLevel. + * In which cases does it call the Child? + * How does it react to calls? + * + */
switch (dwSelectType) {
Modified: branches/shell-experiments/base/shell/rshell/CMenuFocusManager.cpp URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rsh... ============================================================================== --- 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 26 11:33:52 2014 @@ -26,6 +26,36 @@ #include "CMenuToolbars.h" #include "CMenuBand.h"
+#undef _ASSERT +#define _ASSERT(x) DbgAssert(!!(x), __FILE__, __LINE__, #x) + +bool DbgAssert(bool x, const char * filename, int line, const char * expr) +{ + if (!x) + { + char szMsg[512]; + const char *fname; + + fname = strrchr(filename, '\'); + if (fname == NULL) + { + fname = strrchr(filename, '/'); + } + + if (fname == NULL) + fname = filename; + else + fname++; + + sprintf(szMsg, "%s:%d: Assertion failed: %s\n", fname, line, expr); + + OutputDebugStringA(szMsg); + + __debugbreak(); + } + return x; +} + WINE_DEFAULT_DEBUG_CHANNEL(CMenuFocus);
DWORD CMenuFocusManager::TlsIndex = 0; @@ -76,60 +106,56 @@ return GetManager()->GetMsgHook(nCode, wParam, lParam); }
-HRESULT CMenuFocusManager::PushToArray(CMenuBand * item) +HRESULT CMenuFocusManager::PushToArray(StackEntryType type, CMenuBand * mb, HMENU hmenu) { if (m_bandCount >= MAX_RECURSE) return E_OUTOFMEMORY;
- m_bandStack[m_bandCount++] = item; - return S_OK; -} - -HRESULT CMenuFocusManager::PopFromArray(CMenuBand ** pItem) -{ - if (pItem) - *pItem = NULL; + m_bandStack[m_bandCount].type = type; + m_bandStack[m_bandCount].mb = mb; + m_bandStack[m_bandCount].hmenu = hmenu; + m_bandCount++; + + return S_OK; +} + +HRESULT CMenuFocusManager::PopFromArray(StackEntryType * pType, CMenuBand ** pMb, HMENU * pHmenu) +{ + if (pType) *pType = NoEntry; + if (pMb) *pMb = NULL; + if (pHmenu) *pHmenu = NULL;
if (m_bandCount <= 0) return S_FALSE;
m_bandCount--;
- if (pItem) - *pItem = m_bandStack[m_bandCount]; - - m_bandStack[m_bandCount] = NULL; - - return S_OK; -} - -HRESULT CMenuFocusManager::PeekArray(CMenuBand ** pItem) -{ - if (!pItem) - return E_FAIL; - - *pItem = NULL; - - if (m_bandCount <= 0) - return S_FALSE; - - *pItem = m_bandStack[m_bandCount - 1]; - + if (pType) *pType = m_bandStack[m_bandCount].type; + if (*pType == TrackedMenuEntry) + { + if (pHmenu) *pHmenu = m_bandStack[m_bandCount].hmenu; + } + else + { + if (pMb) *pMb = m_bandStack[m_bandCount].mb; + } + return S_OK; }
CMenuFocusManager::CMenuFocusManager() : - m_currentBand(NULL), - m_currentFocus(NULL), - m_currentMenu(NULL), - m_parentToolbar(NULL), + m_current(NULL), + m_parent(NULL), m_hMsgFilterHook(NULL), m_hGetMsgHook(NULL), m_mouseTrackDisabled(FALSE), m_lastMoveFlags(0), m_lastMovePos(0), + m_captureHwnd(0), m_bandCount(0) { + m_ptPrev.x = 0; + m_ptPrev.y = 0; m_threadId = GetCurrentThreadId(); }
@@ -137,41 +163,60 @@ { }
-void CMenuFocusManager::DisableMouseTrack(HWND enableTo, BOOL disableThis) +void CMenuFocusManager::DisableMouseTrack(HWND parent, BOOL disableThis) { BOOL bDisable = FALSE; + BOOL lastDisable = FALSE;
int i = m_bandCount; while (--i >= 0) { - CMenuBand * band = m_bandStack[i]; - - HWND hwnd; - HRESULT hr = band->_GetTopLevelWindow(&hwnd); - if (FAILED_UNEXPECTEDLY(hr)) - break; - - if (hwnd == enableTo) - { - band->_DisableMouseTrack(disableThis); - bDisable = TRUE; + StackEntry& entry = m_bandStack[i]; + + if (entry.type == MenuPopupEntry) + { + HWND hwnd; + HRESULT hr = entry.mb->_GetTopLevelWindow(&hwnd); + if (FAILED_UNEXPECTEDLY(hr)) + break; + + if (hwnd == parent) + { + lastDisable = disableThis; + entry.mb->_DisableMouseTrack(disableThis); + bDisable = TRUE; + } + else + { + lastDisable = bDisable; + entry.mb->_DisableMouseTrack(bDisable); + } } else { - band->_DisableMouseTrack(bDisable); - } - } - - if (m_mouseTrackDisabled == bDisable) - { - if (bDisable) - { - SetCapture(m_currentFocus); + continue; + } + } + m_mouseTrackDisabled = lastDisable; +} + +void CMenuFocusManager::SetCapture(HWND child) +{ + if (m_captureHwnd != child) + { + if (child) + { + ::SetCapture(child); + m_captureHwnd = child; + DbgPrint("MouseTrack is now capturing %p\n", child); } else - ReleaseCapture(); - - m_mouseTrackDisabled = bDisable; + { + ::ReleaseCapture(); + m_captureHwnd = NULL; + DbgPrint("MouseTrack is now off\n"); + } + } }
@@ -180,16 +225,15 @@ int i = m_bandCount; while (--i >= 0) { - CMenuBand * band = m_bandStack[i]; - - HWND hwnd; - HRESULT hr = band->_GetTopLevelWindow(&hwnd); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - if (hwnd == hWnd) - { - return band->_IsPopup(); + StackEntry& entry = m_bandStack[i]; + + if (entry.type == MenuPopupEntry) + { + HRESULT hr = entry.mb->IsWindowOwner(hWnd); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + if (hr == S_OK) + return S_OK; } }
@@ -198,23 +242,21 @@
LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg) { - HWND parent; HWND child; POINT pt; int iHitTestResult;
pt = msg->pt;
- parent = WindowFromPoint(pt); - - ScreenToClient(parent, &pt); - - child = ChildWindowFromPoint(parent, pt); - - if (child != m_parentToolbar) + child = WindowFromPoint(pt); + + if (!m_parent) return TRUE;
- ScreenToClient(m_parentToolbar, &msg->pt); + if (m_parent->mb->IsWindowOwner(child) != S_OK) + return TRUE; + + ScreenToClient(child, &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) @@ -222,20 +264,19 @@
m_ptPrev = msg->pt;
- iHitTestResult = SendMessageW(m_parentToolbar, TB_HITTEST, 0, (LPARAM) &msg->pt); + iHitTestResult = SendMessageW(child, 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) { - HWND hwndToolbar = m_parentToolbar; + HWND hwndToolbar = child; if (SendMessage(hwndToolbar, WM_USER_ISTRACKEDITEM, iHitTestResult, 0)) { DbgPrint("Hot item tracking detected a change...\n"); - if (m_currentMenu) - SendMessage(m_currentFocus, WM_CANCELMODE, 0, 0); + if (m_current->type == TrackedMenuEntry) + SendMessage(m_parent->hwnd, WM_CANCELMODE, 0, 0); else - m_currentBand->_MenuItemHotTrack(MPOS_CANCELLEVEL); - DbgPrint("Active popup cancelled, notifying of change...\n"); + m_current->mb->_MenuItemHotTrack(MPOS_CANCELLEVEL); PostMessage(hwndToolbar, WM_USER_CHANGETRACKEDITEM, iHitTestResult, iHitTestResult); return FALSE; } @@ -253,9 +294,7 @@ { BOOL callNext = TRUE; MSG* msg = reinterpret_cast<MSG*>(lParam); - - // Do whatever is necessary here - + switch (msg->message) { case WM_MOUSEMOVE: @@ -281,9 +320,7 @@ { BOOL callNext = TRUE; MSG* msg = reinterpret_cast<MSG*>(lParam); - - // Do whatever is necessary here - + switch (msg->message) { case WM_CLOSE: @@ -291,65 +328,78 @@
case WM_NCLBUTTONDOWN: case WM_LBUTTONDOWN: - { - POINT pt = { GET_X_LPARAM(pos), GET_Y_LPARAM(pos) }; - - HWND window = GetAncestor(WindowFromPoint(pt), GA_ROOT); - - if (IsTrackedWindow(window) != S_OK) + if (m_current->type == MenuPopupEntry) { - DisableMouseTrack(NULL, FALSE); - m_currentBand->_MenuItemHotTrack(MPOS_FULLCANCEL); - } - - break; - } - case WM_MOUSEMOVE: - if (m_lastMoveFlags != wParam || m_lastMovePos != pos) - { - m_lastMoveFlags = wParam; - m_lastMovePos = pos; - POINT pt = { GET_X_LPARAM(pos), GET_Y_LPARAM(pos) };
- HWND window = WindowFromPoint(pt); - - if (IsTrackedWindow(window) == S_OK) + HWND child = WindowFromPoint(pt); + HWND window = GetAncestor(child, GA_ROOT); + + if (IsTrackedWindow(window) != S_OK) { - DisableMouseTrack(window, FALSE); - } - else - { - DisableMouseTrack(NULL, FALSE); + m_current->mb->_MenuItemHotTrack(MPOS_FULLCANCEL); } } - callNext = ProcessMouseMove(msg); + break; + case WM_MOUSEMOVE: + if ((m_parent && m_parent->type==MenuPopupEntry) || ProcessMouseMove(msg)) + { + if (m_current->type == MenuPopupEntry) + { + if (m_lastMoveFlags != wParam || m_lastMovePos != pos) + { + m_lastMoveFlags = wParam; + m_lastMovePos = pos; + + POINT pt = { GET_X_LPARAM(pos), GET_Y_LPARAM(pos) }; + + HWND child = WindowFromPoint(pt); + HWND window = GetAncestor(child, GA_ROOT); + + if (m_parent && m_parent->mb->IsWindowOwner(child) == S_OK) + { + DisableMouseTrack(window, FALSE); + } + else if (IsTrackedWindow(child) == S_OK) + { + DisableMouseTrack(window, FALSE); + SetCapture(child); + } + else + { + DisableMouseTrack(NULL, FALSE); + SetCapture(NULL); + } + } + } + } + else + { + callNext = FALSE; + } break; case WM_SYSKEYDOWN: case WM_KEYDOWN: - //if (!m_currentMenu) + DisableMouseTrack(m_current->hwnd, TRUE); + switch (msg->wParam) { - DisableMouseTrack(m_currentFocus, TRUE); - switch (msg->wParam) - { - case VK_MENU: - case VK_LMENU: - case VK_RMENU: - m_currentBand->_MenuItemHotTrack(MPOS_FULLCANCEL); - break; - case VK_LEFT: - m_currentBand->_MenuItemHotTrack(MPOS_SELECTLEFT); - break; - case VK_RIGHT: - m_currentBand->_MenuItemHotTrack(MPOS_SELECTRIGHT); - break; - case VK_UP: - m_currentBand->_MenuItemHotTrack(VK_UP); - break; - case VK_DOWN: - m_currentBand->_MenuItemHotTrack(VK_DOWN); - break; - } + 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); + break; + case VK_RIGHT: + m_current->mb->_MenuItemHotTrack(MPOS_SELECTRIGHT); + break; + case VK_UP: + m_current->mb->_MenuItemHotTrack(VK_UP); + break; + case VK_DOWN: + m_current->mb->_MenuItemHotTrack(VK_DOWN); + break; } break; } @@ -363,8 +413,7 @@
HRESULT CMenuFocusManager::PlaceHooks() { - //SetCapture(window); - if (m_currentMenu) + if (m_current->hmenu) { DbgPrint("Entering MSGFILTER hook...\n"); m_hMsgFilterHook = SetWindowsHookEx(WH_MSGFILTER, s_MsgFilterHook, NULL, m_threadId); @@ -389,34 +438,37 @@ return S_OK; }
-HRESULT CMenuFocusManager::UpdateFocus(CMenuBand * newBand, HMENU popupToTrack) +HRESULT CMenuFocusManager::UpdateFocus() { HRESULT hr; - HWND newFocus = NULL; - HWND oldFocus = m_currentFocus; - HMENU oldMenu = m_currentMenu; - - if (newBand) - { - hr = newBand->_GetTopLevelWindow(&newFocus); + StackEntry * old = m_current; + + if (old) + SetCapture(NULL); + + if (m_bandCount > 0) + m_current = &(m_bandStack[m_bandCount - 1]); + else + m_current = NULL; + + if (m_current && m_current->type != TrackedMenuEntry) + { + hr = m_current->mb->_GetTopLevelWindow(&(m_current->hwnd)); if (FAILED_UNEXPECTEDLY(hr)) return hr; }
- m_currentBand = newBand; - m_currentMenu = popupToTrack; - m_currentFocus = newFocus; - m_parentToolbar = NULL; - if (popupToTrack) - { - m_currentBand->GetWindow(&m_parentToolbar); - } - else if (m_bandCount >= 2) - { - m_bandStack[m_bandCount - 2]->GetWindow(&m_parentToolbar); - } - - if (oldFocus && (!newFocus || (oldMenu != popupToTrack))) + if (m_bandCount >= 2) + { + m_parent = &(m_bandStack[m_bandCount - 2]); + _ASSERT(m_parent->type != TrackedMenuEntry); + } + else + { + m_parent = NULL; + } + + if (old && (!m_current || old->type != m_current->type)) { DisableMouseTrack(NULL, FALSE);
@@ -424,123 +476,161 @@ if (FAILED_UNEXPECTEDLY(hr)) return hr; } - - if (newFocus && (!oldFocus || (oldMenu != popupToTrack))) + + if (m_current && (!old || old->type != m_current->type)) { hr = PlaceHooks(); if (FAILED_UNEXPECTEDLY(hr)) return hr; }
- - return S_OK; -} - -HRESULT CMenuFocusManager::PushMenu(CMenuBand * mb) -{ - HRESULT hr; - - CMenuBand * mbParent = m_currentBand; - - hr = PushToArray(mb); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - if (mbParent) - { - mbParent->_SetChildBand(mb); - mb->_SetParentBand(mbParent); - } - - return UpdateFocus(mb); -} - -HRESULT CMenuFocusManager::PopMenu(CMenuBand * mb) -{ + if ((m_current && m_current->type == MenuPopupEntry) && + (!m_parent || m_parent->type == MenuBarEntry)) + { + DisableMouseTrack(m_current->hwnd, FALSE); + + // When the mouse moves, it should set itself to the proper band + SetCapture(m_current->hwnd); + } + + _ASSERT(!m_parent || m_parent->type != TrackedMenuEntry); + + return S_OK; +} + +HRESULT CMenuFocusManager::PushMenuBar(CMenuBand * mb) +{ + _ASSERT(m_bandCount == 0); + + HRESULT hr = PushToArray(MenuBarEntry, mb, NULL); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + return UpdateFocus(); +} + +HRESULT CMenuFocusManager::PushMenuPopup(CMenuBand * mb) +{ + _ASSERT(!m_current || m_current->type != TrackedMenuEntry); + + HRESULT hr = PushToArray(MenuPopupEntry, mb, NULL); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + hr = UpdateFocus(); + + if (m_parent && m_parent->type != TrackedMenuEntry) + { + m_parent->mb->_SetChildBand(mb); + mb->_SetParentBand(m_parent->mb); + } + + return hr; +} + +HRESULT CMenuFocusManager::PushTrackedPopup(HMENU popup) +{ + _ASSERT(m_bandCount > 0); + _ASSERT(!m_current || m_current->type != TrackedMenuEntry); + + HRESULT hr = PushToArray(TrackedMenuEntry, NULL, popup); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + return UpdateFocus(); +} + +HRESULT CMenuFocusManager::PopMenuBar(CMenuBand * mb) +{ + StackEntryType type; CMenuBand * mbc; HRESULT hr;
- if (m_currentBand) - { - m_currentBand->_SetParentBand(NULL); - } - - 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); + hr = PopFromArray(&type, &mbc, NULL); + if (FAILED_UNEXPECTEDLY(hr)) + { + UpdateFocus(); + return hr; + } + + _ASSERT(type == MenuBarEntry); + if (type != MenuBarEntry) + return E_FAIL;
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->_SetChildBand(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) -{ + + mbc->_SetParentBand(NULL); + + hr = UpdateFocus(); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + if (m_current) + { + _ASSERT(m_current->type != TrackedMenuEntry); + m_current->mb->_SetChildBand(NULL); + } + + return S_OK; +} + +HRESULT CMenuFocusManager::PopMenuPopup(CMenuBand * mb) +{ + StackEntryType type; 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); + hr = PopFromArray(&type, &mbc, NULL); + if (FAILED_UNEXPECTEDLY(hr)) + { + UpdateFocus(); + return hr; + } + + _ASSERT(type == MenuPopupEntry); + if (type != MenuPopupEntry) + return E_FAIL;
if (!mbc) return E_FAIL;
- hr = PeekArray(&mb); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - hr = UpdateFocus(mb); + mbc->_SetParentBand(NULL); + + hr = UpdateFocus(); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + if (m_current) + { + _ASSERT(m_current->type != TrackedMenuEntry); + m_current->mb->_SetChildBand(NULL); + } + + return S_OK; +} + +HRESULT CMenuFocusManager::PopTrackedPopup(HMENU popup) +{ + StackEntryType type; + HMENU hmenu; + HRESULT hr; + + hr = PopFromArray(&type, NULL, &hmenu); + if (FAILED_UNEXPECTEDLY(hr)) + { + UpdateFocus(); + return hr; + } + + _ASSERT(type == TrackedMenuEntry); + if (type != TrackedMenuEntry) + return E_FAIL; + + if (hmenu != popup) + return E_FAIL; + + hr = UpdateFocus(); if (FAILED_UNEXPECTEDLY(hr)) return hr;
Modified: branches/shell-experiments/base/shell/rshell/CMenuFocusManager.h URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rsh... ============================================================================== --- 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 26 11:33:52 2014 @@ -30,6 +30,22 @@
static CMenuFocusManager * GetManager();
+ enum StackEntryType + { + NoEntry, + MenuBarEntry, + MenuPopupEntry, + TrackedMenuEntry + }; + + struct StackEntry + { + StackEntryType type; + CMenuBand * mb; + HMENU hmenu; + HWND hwnd; + }; + public: static CMenuFocusManager * AcquireManager();
@@ -40,26 +56,29 @@ static LRESULT CALLBACK s_GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam);
private: - CMenuBand * m_currentBand; - HWND m_currentFocus; - HMENU m_currentMenu; - HWND m_parentToolbar; + StackEntry * m_current; + StackEntry * m_parent; + HHOOK m_hMsgFilterHook; HHOOK m_hGetMsgHook; DWORD m_threadId; + BOOL m_mouseTrackDisabled; + WPARAM m_lastMoveFlags; LPARAM m_lastMovePos; + POINT m_ptPrev; + + HWND m_captureHwnd;
// TODO: make dynamic #define MAX_RECURSE 20 - CMenuBand* m_bandStack[MAX_RECURSE]; + StackEntry m_bandStack[MAX_RECURSE]; int m_bandCount;
- HRESULT PushToArray(CMenuBand * item); - HRESULT PopFromArray(CMenuBand ** pItem); - HRESULT PeekArray(CMenuBand ** pItem); + HRESULT PushToArray(StackEntryType type, CMenuBand * mb, HMENU hmenu); + HRESULT PopFromArray(StackEntryType * pType, CMenuBand ** pMb, HMENU * pHmenu);
protected: CMenuFocusManager(); @@ -77,15 +96,18 @@ LRESULT MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam); HRESULT PlaceHooks(); HRESULT RemoveHooks(); - HRESULT UpdateFocus(CMenuBand * newBand, HMENU popupToTrack = NULL); + HRESULT UpdateFocus(); HRESULT IsTrackedWindow(HWND hWnd);
- void DisableMouseTrack(HWND enableTo, BOOL disableThis); + void DisableMouseTrack(HWND parent, BOOL disableThis); + void SetCapture(HWND child);
LRESULT ProcessMouseMove(MSG* msg); public: - HRESULT PushMenu(CMenuBand * mb); - HRESULT PopMenu(CMenuBand * mb); - HRESULT PushTrackedPopup(CMenuBand * mb, HMENU popup); - HRESULT PopTrackedPopup(CMenuBand * mb, HMENU popup); + HRESULT PushMenuBar(CMenuBand * mb); + HRESULT PushMenuPopup(CMenuBand * mb); + HRESULT PushTrackedPopup(HMENU popup); + HRESULT PopMenuBar(CMenuBand * mb); + HRESULT PopMenuPopup(CMenuBand * mb); + HRESULT PopTrackedPopup(HMENU popup); };
Modified: branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rsh... ============================================================================== --- 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 26 11:33:52 2014 @@ -121,9 +121,9 @@
default: DbgPrint("WM_NOTIFY unknown code %d, %d\n", hdr->code, hdr->idFrom); - break; - } - return S_OK; + return S_OK; + } + return S_FALSE; }
return S_FALSE; @@ -195,7 +195,7 @@ if (btni.fsStyle & BTNS_DROPDOWN) { SelectObject(cdraw->nmcd.hdc, m_marlett); - WCHAR text[] = L"8"; + WCHAR text [] = L"8"; SetBkMode(cdraw->nmcd.hdc, TRANSPARENT); RECT rc = cdraw->nmcd.rc; rc.right += 1; @@ -210,7 +210,7 @@ CMenuToolbarBase::CMenuToolbarBase(CMenuBand *menuBand, BOOL usePager) : m_hwnd(NULL), m_useFlatMenus(FALSE), - m_SubclassOld(NULL), + m_SubclassOld(NULL), m_disableMouseTrack(FALSE), m_menuBand(menuBand), m_hwndToolbar(NULL), @@ -235,7 +235,7 @@ HRESULT CMenuToolbarBase::IsWindowOwner(HWND hwnd) { return (m_hwnd && m_hwnd == hwnd) || - (m_hwndToolbar && m_hwndToolbar == hwnd) ? S_OK : S_FALSE; + (m_hwndToolbar && m_hwndToolbar == hwnd) ? S_OK : S_FALSE; }
void CMenuToolbarBase::InvalidateDraw() @@ -256,7 +256,7 @@
HRESULT CMenuToolbarBase::UpdateImageLists() { - if ((m_toolbarFlags & (SMINIT_TOPLEVEL| SMINIT_VERTICAL)) == SMINIT_TOPLEVEL) // not vertical. + if ((m_toolbarFlags & (SMINIT_TOPLEVEL | SMINIT_VERTICAL)) == SMINIT_TOPLEVEL) // not vertical. { /* Hide the placeholders for the button images */ SendMessageW(m_hwnd, TB_SETIMAGELIST, 0, 0); @@ -358,7 +358,7 @@ m_hwndToolbar = hwndToolbar; m_hwnd = hwndToolbar; } - + /* Identify the version of the used Common Controls DLL by sending the size of the TBBUTTON structure */ SendMessageW(hwndToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
@@ -441,9 +441,13 @@ { KillTimer(hWnd, TIMERID_HOTTRACK);
+ DbgPrint("Closing previous submenu...\n"); + m_menuBand->_OnPopupSubMenu(NULL, NULL, NULL, NULL, -1);
- PopupItem(m_hotItem); + DbgPrint("Opening new submenu...\n"); + + PopupItem(m_hotItem); } }
@@ -474,11 +478,9 @@
return S_OK; } - + if (m_hotItem != hot->idNew) { - DbgPrint("Hot item is now %d\n", hot->idNew); - if (hot->dwFlags & HICF_MOUSE && m_toolbarFlags & SMINIT_VERTICAL) { @@ -531,7 +533,7 @@ { SendMessage(m_hwndToolbar, TB_CHECKBUTTON, m_popupItem, FALSE); m_isTracking = FALSE; - DbgPrint("Is Tracking: %d\n", m_isTracking); + DbgPrint("%s -- Is Tracking: %d\n", __FUNCTION__, m_isTracking); } m_popupBar = toolbar; m_popupItem = item; @@ -558,13 +560,16 @@ TBBUTTON btn; SendMessage(m_hwndToolbar, TB_GETBUTTON, index, reinterpret_cast<LPARAM>(&btn));
+ DbgPrint("Changing tracked item to %d...\n", index); + if (m_hotItem != btn.idCommand) { m_isTracking = TRUE; - DbgPrint("Is Tracking: %d\n", m_isTracking); + DbgPrint("%s -- Is Tracking: %d\n", __FUNCTION__, m_isTracking);
SendMessage(m_hwndToolbar, TB_SETHOTITEM, index, 0); } + return S_OK; }
@@ -595,7 +600,7 @@ POINTL pt = { a.x, b.y }; RECTL rcl = { c.x, c.y, d.x, d.y };
- if(m_toolbarFlags & SMINIT_VERTICAL) + if (m_toolbarFlags & SMINIT_VERTICAL) { pt.x = b.x - 3; pt.y = a.y - 3; @@ -647,7 +652,7 @@ return hr;
m_isTracking = TRUE; - DbgPrint("Is Tracking: %d\n", m_isTracking); + DbgPrint("%s -- Is Tracking: %d\n", __FUNCTION__, m_isTracking);
m_menuBand->_OnPopupSubMenu(popup, &pt, &rcl, this, uItem);
@@ -686,14 +691,14 @@ HMENU popup = GetSubMenu(menu, index);
m_isTracking = TRUE; - DbgPrint("Is Tracking: %d\n", m_isTracking); + DbgPrint("%s -- Is Tracking: %d\n", __FUNCTION__, m_isTracking);
m_menuBand->_TrackSubMenuUsingTrackPopupMenu(popup, pt.x, pt.y, rcl);
SendMessage(m_hwndToolbar, TB_CHECKBUTTON, uItem, FALSE);
m_isTracking = FALSE; - DbgPrint("Is Tracking: %d\n", m_isTracking); + DbgPrint("%s -- Is Tracking: %d\n", __FUNCTION__, m_isTracking);
return S_OK; } @@ -1095,6 +1100,7 @@ return ::GetSubMenu(m_hmenu, index) ? S_OK : S_FALSE; }
+ CMenuSFToolbar::CMenuSFToolbar(CMenuBand * menuBand) : CMenuToolbarBase(menuBand, TRUE), m_shellFolder(NULL),
Modified: branches/shell-experiments/base/shell/rshell/misc.cpp URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rsh... ============================================================================== --- branches/shell-experiments/base/shell/rshell/misc.cpp [iso-8859-1] (original) +++ branches/shell-experiments/base/shell/rshell/misc.cpp [iso-8859-1] Wed Mar 26 11:33:52 2014 @@ -50,7 +50,7 @@ new (&_AtlComModule) CAtlComModule;
gModule.Init(NULL, hInstance, NULL); - DisableThreadLibraryCalls (hInstance); + DisableThreadLibraryCalls(hInstance); } else if (dwReason == DLL_PROCESS_DETACH) {
Modified: branches/shell-experiments/base/shell/rshell/precomp.h URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rsh... ============================================================================== --- branches/shell-experiments/base/shell/rshell/precomp.h [iso-8859-1] (original) +++ branches/shell-experiments/base/shell/rshell/precomp.h [iso-8859-1] Wed Mar 26 11:33:52 2014 @@ -65,14 +65,12 @@ if (fname == NULL) { fname = strrchr(filename, '/'); - if (fname != NULL) - fname++; } - else - fname++;
if (fname == NULL) fname = filename; + else + fname++;
szMsgStart = szMsg + sprintf(szMsg, "%s:%d: ", fname, line);