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/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 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/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 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/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 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/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
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/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 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/rs…
==============================================================================
--- 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/rs…
==============================================================================
--- 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);