diff --git a/base/shell/rshell/CMenuBand.cpp b/base/shell/rshell/CMenuBand.cpp index f3c007eb223..f2b67e44dd8 100644 --- a/base/shell/rshell/CMenuBand.cpp +++ b/base/shell/rshell/CMenuBand.cpp @@ -523,6 +523,11 @@ HRESULT CMenuBand::_IsPopup() return m_subMenuParent ? S_OK : S_FALSE; } +HRESULT CMenuBand::_IsTracking() +{ + return m_popupBar != NULL; +} + HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient) { m_subMenuChild = NULL; @@ -669,8 +674,6 @@ HRESULT CMenuBand::_TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, R UINT flags = TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_LEFTALIGN; - //_DisableMouseTrack(TRUE); - m_focusManager->PushTrackedPopup(popup); if (m_menuOwner) { @@ -700,8 +703,7 @@ HRESULT CMenuBand::_ChangeHotItem(CMenuToolbarBase * tb, INT id, DWORD dwFlags) DbgPrint("Hot item changed from %p %p, to %p %p\n", m_hotBar, m_hotItem, tb, id); - if (m_hotBar != tb) - _KillPopupTimers(); + _KillPopupTimers(); m_hotBar = tb; m_hotItem = id; diff --git a/base/shell/rshell/CMenuBand.h b/base/shell/rshell/CMenuBand.h index d982a5aea09..2d1bcc497ff 100644 --- a/base/shell/rshell/CMenuBand.h +++ b/base/shell/rshell/CMenuBand.h @@ -186,6 +186,7 @@ public: HRESULT _SetChildBand(CMenuBand * child); HRESULT _SetParentBand(CMenuBand * parent); HRESULT _IsPopup(); + HRESULT _IsTracking(); HRESULT _KillPopupTimers(); BOOL UseBigIcons() diff --git a/base/shell/rshell/CMenuFocusManager.cpp b/base/shell/rshell/CMenuFocusManager.cpp index be7b6e796be..5b1f78f4ffb 100644 --- a/base/shell/rshell/CMenuFocusManager.cpp +++ b/base/shell/rshell/CMenuFocusManager.cpp @@ -150,6 +150,8 @@ CMenuFocusManager::CMenuFocusManager() : m_hGetMsgHook(NULL), m_mouseTrackDisabled(FALSE), m_captureHwnd(0), + m_hwndUnderMouse(NULL), + m_entryUnderMouse(NULL), m_bandCount(0) { m_ptPrev.x = 0; @@ -261,21 +263,33 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg) child = WindowFromPoint(pt); + StackEntry * entry = NULL; + IsTrackedWindow(child, &entry); + if (m_hwndUnderMouse != child) { WCHAR cn[1024]; GetClassName(child, cn, 1023); DbgPrint("Mouse moved to %p (%S)\n", child, cn); - m_hwndUnderMouse = child; - } - - StackEntry * entry = NULL; - if (IsTrackedWindow(child, &entry) == S_OK) + if (!entry) + { + if (m_entryUnderMouse) + { + m_entryUnderMouse->mb->_ChangeHotItem(NULL, -1, HICF_MOUSE); + } + SetCapture(NULL); + } + + } + + if (entry) { ScreenToClient(child, &pt); iHitTestResult = SendMessageW(child, TB_HITTEST, 0, (LPARAM) &pt); + BOOL isTracking = entry->mb->_IsTracking(); + if (iHitTestResult >= 0 && SendMessage(child, WM_USER_ISTRACKEDITEM, iHitTestResult, 0) == S_FALSE) { @@ -283,16 +297,26 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg) DisableMouseTrack(NULL, FALSE); if (m_current->type == TrackedMenuEntry) SendMessage(entry->hwnd, WM_CANCELMODE, 0, 0); - PostMessage(child, WM_USER_CHANGETRACKEDITEM, iHitTestResult, iHitTestResult); + PostMessage(child, WM_USER_CHANGETRACKEDITEM, iHitTestResult, isTracking); return FALSE; } + } - if (m_current->type == MenuPopupEntry) + if (m_hwndUnderMouse != child) + { + if (entry) { SetCapture(child); - ScreenToClient(child, &pt2); - SendMessage(child, WM_MOUSEMOVE, msg->wParam, MAKELPARAM(pt2.x, pt2.y)); + + if (m_current->type == MenuPopupEntry) + { + ScreenToClient(child, &pt2); + SendMessage(child, WM_MOUSEMOVE, msg->wParam, MAKELPARAM(pt2.x, pt2.y)); + } } + + m_hwndUnderMouse = child; + m_entryUnderMouse = entry; } if (m_current->type == MenuPopupEntry) @@ -325,7 +349,6 @@ LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam BOOL hoveringMenuBar = m_menuBar->mb->IsWindowOwner(child) == S_OK; if (hoveringMenuBar) { - HWND parent = GetAncestor(child, GA_ROOT); m_menuBar->mb->_DisableMouseTrack(TRUE); } } @@ -352,18 +375,15 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam) BOOL callNext = TRUE; MSG* msg = reinterpret_cast(lParam); POINT pt = msg->pt; - + switch (msg->message) { - case WM_CLOSE: - break; - case WM_NCLBUTTONDOWN: case WM_LBUTTONDOWN: if (m_current->type == MenuPopupEntry) { HWND child = WindowFromPoint(pt); - + if (IsTrackedWindow(child) != S_OK) { SetCapture(NULL); @@ -376,26 +396,29 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam) break; case WM_SYSKEYDOWN: case WM_KEYDOWN: - DisableMouseTrack(m_current->hwnd, TRUE); - switch (msg->wParam) + if (m_current->type == MenuPopupEntry) { - 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; + DisableMouseTrack(m_current->hwnd, TRUE); + switch (msg->wParam) + { + 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; } @@ -414,7 +437,7 @@ HRESULT CMenuFocusManager::PlaceHooks() DbgPrint("Entering MSGFILTER hook...\n"); m_hMsgFilterHook = SetWindowsHookEx(WH_MSGFILTER, s_MsgFilterHook, NULL, m_threadId); } - else if (m_current->type == MenuPopupEntry) + else { DbgPrint("Entering GETMESSAGE hook...\n"); m_hGetMsgHook = SetWindowsHookEx(WH_GETMESSAGE, s_GetMsgHook, NULL, m_threadId); @@ -475,7 +498,7 @@ HRESULT CMenuFocusManager::UpdateFocus() if (old && (!m_current || old->type != m_current->type)) { - if (m_current->type != TrackedMenuEntry) + if (m_current && m_current->type != TrackedMenuEntry) { DisableMouseTrack(m_current->hwnd, FALSE); } diff --git a/base/shell/rshell/CMenuFocusManager.h b/base/shell/rshell/CMenuFocusManager.h index 88a40dc48b1..6c5ec86b6ca 100644 --- a/base/shell/rshell/CMenuFocusManager.h +++ b/base/shell/rshell/CMenuFocusManager.h @@ -71,6 +71,7 @@ private: HWND m_captureHwnd; HWND m_hwndUnderMouse; + StackEntry * m_entryUnderMouse; // TODO: make dynamic #define MAX_RECURSE 20 diff --git a/base/shell/rshell/CMenuToolbars.cpp b/base/shell/rshell/CMenuToolbars.cpp index e50aa357eb7..55d59219d9e 100644 --- a/base/shell/rshell/CMenuToolbars.cpp +++ b/base/shell/rshell/CMenuToolbars.cpp @@ -64,7 +64,8 @@ HRESULT CMenuToolbarBase::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM return OnCommand(reinterpret_cast(hdr)->iItem, 0, theResult); case TBN_HOTITEMCHANGE: - return OnHotItemChange(reinterpret_cast(hdr), theResult); + //return OnHotItemChange(reinterpret_cast(hdr), theResult); + return S_OK; case NM_RCLICK: return OnContextMenu(reinterpret_cast(hdr)); @@ -100,6 +101,9 @@ HRESULT CMenuToolbarBase::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM case NM_TOOLTIPSCREATED: break; + // Unknown + case -714: return S_FALSE; + default: DbgPrint("WM_NOTIFY unknown code %d, %d\n", hdr->code, hdr->idFrom); return S_OK; @@ -127,7 +131,7 @@ LRESULT CMenuToolbarBase::SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR return IsTrackedItem(wParam); case WM_USER_CHANGETRACKEDITEM: m_SubclassOld(hWnd, uMsg, wParam, lParam); - return ChangeTrackedItem(wParam); + return ChangeTrackedItem(wParam, lParam); case WM_COMMAND: OnWinEvent(hWnd, uMsg, wParam, lParam, &lr); @@ -188,8 +192,8 @@ HRESULT CMenuToolbarBase::OnCustomDraw(LPNMTBCUSTOMDRAW cdraw, LRESULT * theResu hdc = cdraw->nmcd.hdc; // The item with an active submenu gets the CHECKED flag. - isHot = m_hotBar == this && cdraw->nmcd.dwItemSpec == m_hotItem; - isPopup = m_popupBar == this && cdraw->nmcd.dwItemSpec == m_popupItem; + isHot = m_hotBar == this && (int)cdraw->nmcd.dwItemSpec == m_hotItem; + isPopup = m_popupBar == this && (int)cdraw->nmcd.dwItemSpec == m_popupItem; if (m_initFlags & SMINIT_VERTICAL) { @@ -621,8 +625,6 @@ HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DW } else if (m_isTracking) { - m_menuBand->_KillPopupTimers(); - PopupItem(m_hotItem); } } @@ -684,14 +686,14 @@ HRESULT CMenuToolbarBase::IsTrackedItem(INT index) return S_FALSE; } -HRESULT CMenuToolbarBase::ChangeTrackedItem(INT index) +HRESULT CMenuToolbarBase::ChangeTrackedItem(INT index, BOOL wasTracking) { TBBUTTON btn; if (!SendMessage(m_hwndToolbar, TB_GETBUTTON, index, reinterpret_cast(&btn))) return E_FAIL; DbgPrint("Changing tracked item to %d...\n", index); - m_isTracking = TRUE; + m_isTracking = wasTracking; m_menuBand->_ChangeHotItem(this, btn.idCommand, HICF_MOUSE); return S_OK; diff --git a/base/shell/rshell/CMenuToolbars.h b/base/shell/rshell/CMenuToolbars.h index 598c85a519a..6b5e8bc4e03 100644 --- a/base/shell/rshell/CMenuToolbars.h +++ b/base/shell/rshell/CMenuToolbars.h @@ -77,7 +77,7 @@ public: HRESULT OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * theResult); HRESULT IsTrackedItem(INT index); - HRESULT ChangeTrackedItem(INT index); + HRESULT ChangeTrackedItem(INT index, BOOL wasTracking); HRESULT GetIdealSize(SIZE& size); HRESULT SetPosSize(int x, int y, int cx, int cy); diff --git a/base/shell/rshell/precomp.h b/base/shell/rshell/precomp.h index 0eef2e0e113..99f724e02b5 100644 --- a/base/shell/rshell/precomp.h +++ b/base/shell/rshell/precomp.h @@ -72,7 +72,7 @@ Win32DbgPrint(const char *filename, int line, const char *lpFormat, ...) else fname++; - szMsgStart = szMsg + sprintf(szMsg, "[%10d] %s:%d: ", GetTickCount(), fname, line); + szMsgStart = szMsg + sprintf(szMsg, "[%10lu] %s:%d: ", GetTickCount(), fname, line); va_start(vl, lpFormat); uRet = (ULONG) vsprintf(szMsgStart, lpFormat, vl);