From dc8f232870bc2bd03e2456cfbbad7eda3571e812 Mon Sep 17 00:00:00 2001 From: David Quintana Date: Wed, 16 Apr 2014 12:14:02 +0000 Subject: [PATCH] [RSHELL] * Implemented horizontal keyboard navigation on the menubar. Does not yet work for the Favorites menu, which is a shell popup and not a tracked popup. Also missing the system menu in the rotation. svn path=/branches/shell-experiments/; revision=62757 --- base/shell/rshell/CMenuBand.cpp | 39 +++++++++++++++---------- base/shell/rshell/CMenuFocusManager.cpp | 35 ++++++++++++---------- base/shell/rshell/CMenuToolbars.cpp | 28 +++++++++++------- 3 files changed, 61 insertions(+), 41 deletions(-) diff --git a/base/shell/rshell/CMenuBand.cpp b/base/shell/rshell/CMenuBand.cpp index 194bc79b898..ded18a1cac2 100644 --- a/base/shell/rshell/CMenuBand.cpp +++ b/base/shell/rshell/CMenuBand.cpp @@ -793,13 +793,21 @@ HRESULT CMenuBand::_KeyboardItemChange(DWORD change) if (!tb) { - // If no hot item was selected - // choose the first toolbar (prefer shell-folder, which will be positioned at the top) - - if (m_SFToolbar) - tb = m_SFToolbar; - else - tb = m_staticToolbar; + // If no hot item was selected choose the appropriate toolbar + if (change == VK_UP) + { + if (m_staticToolbar) + tb = m_staticToolbar; + else + tb = m_SFToolbar; + } + else if (change == VK_DOWN) + { + if (m_SFToolbar) + tb = m_SFToolbar; + else + tb = m_staticToolbar; + } } // Ask the first toolbar to change @@ -861,20 +869,19 @@ HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType) switch (changeType) { case MPOS_SELECTLEFT: + if (m_parentBand && m_parentBand->_IsPopup()==S_FALSE) + return m_parentBand->_MenuItemHotTrack(VK_LEFT); + if (m_subMenuChild) + return m_subMenuChild->OnSelect(MPOS_CANCELLEVEL); if (!m_subMenuParent) - { - if (m_subMenuChild) - return m_subMenuChild->OnSelect(MPOS_CANCELLEVEL); return S_OK; - } return m_subMenuParent->OnSelect(MPOS_CANCELLEVEL); case MPOS_SELECTRIGHT: - if (m_hotBar && m_hotItem >= 0) - { - if (m_hotBar->PopupItem(m_hotItem) == S_OK) - return S_FALSE; - } + if (m_hotBar && m_hotItem >= 0 && m_hotBar->PopupItem(m_hotItem) == S_OK) + return S_FALSE; + if (m_parentBand) + return m_parentBand->_MenuItemHotTrack(VK_RIGHT); if (!m_subMenuParent) return S_OK; return m_subMenuParent->OnSelect(MPOS_SELECTRIGHT); diff --git a/base/shell/rshell/CMenuFocusManager.cpp b/base/shell/rshell/CMenuFocusManager.cpp index ec4a33e86dc..5018ef81809 100644 --- a/base/shell/rshell/CMenuFocusManager.cpp +++ b/base/shell/rshell/CMenuFocusManager.cpp @@ -330,15 +330,15 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg) return TRUE; } -LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam) +LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM hookWParam, LPARAM hookLParam) { if (nCode < 0) - return CallNextHookEx(m_hMsgFilterHook, nCode, wParam, lParam); + return CallNextHookEx(m_hMsgFilterHook, nCode, hookWParam, hookLParam); if (nCode == MSGF_MENU) { BOOL callNext = TRUE; - MSG* msg = reinterpret_cast(lParam); + MSG* msg = reinterpret_cast(hookLParam); switch (msg->message) { @@ -359,16 +359,16 @@ LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam callNext = ProcessMouseMove(msg); break; case WM_INITMENUPOPUP: - DbgPrint("WM_INITMENUPOPUP %p %p\n", wParam, lParam); - m_selectedMenu = reinterpret_cast(lParam); + DbgPrint("WM_INITMENUPOPUP %p %p\n", msg->wParam, msg->lParam); + m_selectedMenu = reinterpret_cast(msg->lParam); m_selectedItem = -1; m_selectedItemFlags = 0; break; case WM_MENUSELECT: - DbgPrint("WM_MENUSELECT %p %p\n", wParam, lParam); - m_selectedMenu = reinterpret_cast(lParam); - m_selectedItem = LOWORD(wParam); - m_selectedItemFlags = HIWORD(wParam); + DbgPrint("WM_MENUSELECT %p %p\n", msg->wParam, msg->lParam); + m_selectedMenu = reinterpret_cast(msg->lParam); + m_selectedItem = GET_X_LPARAM(msg->wParam); + m_selectedItemFlags = HIWORD(msg->wParam); break; case WM_KEYDOWN: switch (msg->wParam) @@ -380,7 +380,7 @@ LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam } break; case VK_RIGHT: - if (!(m_selectedItemFlags & MF_POPUP)) + if (m_selectedItem < 0 || !(m_selectedItemFlags & MF_POPUP)) { m_parent->mb->_MenuItemHotTrack(VK_RIGHT); } @@ -393,18 +393,18 @@ LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam return 1; } - return CallNextHookEx(m_hMsgFilterHook, nCode, wParam, lParam); + return CallNextHookEx(m_hMsgFilterHook, nCode, hookWParam, hookLParam); } -LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam) +LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM hookWParam, LPARAM hookLParam) { if (nCode < 0) - return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam); + return CallNextHookEx(m_hGetMsgHook, nCode, hookWParam, hookLParam); if (nCode == HC_ACTION) { BOOL callNext = TRUE; - MSG* msg = reinterpret_cast(lParam); + MSG* msg = reinterpret_cast(hookLParam); POINT pt = msg->pt; switch (msg->message) @@ -463,7 +463,7 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam) return 1; } - return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam); + return CallNextHookEx(m_hGetMsgHook, nCode, hookWParam, hookLParam); } HRESULT CMenuFocusManager::PlaceHooks() @@ -621,6 +621,11 @@ HRESULT CMenuFocusManager::PushTrackedPopup(HMENU popup) if (FAILED_UNEXPECTEDLY(hr)) return hr; + DbgPrint("PushTrackedPopup %p\n", popup); + m_selectedMenu = popup; + m_selectedItem = -1; + m_selectedItemFlags = 0; + return UpdateFocus(); } diff --git a/base/shell/rshell/CMenuToolbars.cpp b/base/shell/rshell/CMenuToolbars.cpp index 8cd26ea772b..9368e5a3f69 100644 --- a/base/shell/rshell/CMenuToolbars.cpp +++ b/base/shell/rshell/CMenuToolbars.cpp @@ -609,11 +609,15 @@ HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DW if (m_hotBar == this) { - if (dwFlags & HICF_MOUSE) + if (m_isTrackingPopup && !(m_initFlags & SMINIT_VERTICAL)) + { + // If the menubar has an open submenu, switch to the new item's submenu immediately + PopupItem(m_hotItem); + } + else if (dwFlags & HICF_MOUSE) { // Vertical menus show/hide the submenu after a delay, - // but horizontal menubars switch between items instantly, - // if they were open. + // but only with the mouse. if (m_initFlags & SMINIT_VERTICAL) { DWORD elapsed = 0; @@ -622,11 +626,6 @@ HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DW m_timerEnabled = TRUE; TRACE("SetTimer called with m_hotItem=%d\n", m_hotItem); } - else if (m_isTrackingPopup) - { - // If the menubar has an open submenu, switch to the new item's submenu immediately - PopupItem(m_hotItem); - } } else { @@ -704,6 +703,7 @@ HRESULT CMenuToolbarBase::ChangeTrackedItem(INT index, BOOL wasTracking) if (!SendMessage(m_hwndToolbar, TB_GETBUTTON, index, reinterpret_cast(&btn))) return E_FAIL; + DbgPrint("ChangeTrackedItem %d, %d\n", index, wasTracking); m_isTrackingPopup = wasTracking; return m_menuBand->_ChangeHotItem(this, btn.idCommand, HICF_MOUSE); } @@ -912,8 +912,16 @@ HRESULT CMenuToolbarBase::KeyboardItemChange(DWORD dwSelectType) { if (prev != btn.idCommand) { - TRACE("Setting Hot item to %d\n", index); - m_menuBand->_ChangeHotItem(this, btn.idCommand, 0); + DbgPrint("Setting Hot item to %d\n", index); + if (!(m_initFlags & SMINIT_VERTICAL) && m_isTrackingPopup) + { + HWND tlw; + m_menuBand->_GetTopLevelWindow(&tlw); + SendMessage(tlw, WM_CANCELMODE, 0, 0); + PostMessage(m_hwndToolbar, WM_USER_CHANGETRACKEDITEM, index, m_isTrackingPopup); + } + else + m_menuBand->_ChangeHotItem(this, btn.idCommand, 0); } return S_OK; }