* 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
This commit is contained in:
David Quintana 2014-04-16 12:14:02 +00:00
parent 9c589bb131
commit dc8f232870
3 changed files with 61 additions and 41 deletions

View file

@ -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);

View file

@ -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<MSG*>(lParam);
MSG* msg = reinterpret_cast<MSG*>(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<HMENU>(lParam);
DbgPrint("WM_INITMENUPOPUP %p %p\n", msg->wParam, msg->lParam);
m_selectedMenu = reinterpret_cast<HMENU>(msg->lParam);
m_selectedItem = -1;
m_selectedItemFlags = 0;
break;
case WM_MENUSELECT:
DbgPrint("WM_MENUSELECT %p %p\n", wParam, lParam);
m_selectedMenu = reinterpret_cast<HMENU>(lParam);
m_selectedItem = LOWORD(wParam);
m_selectedItemFlags = HIWORD(wParam);
DbgPrint("WM_MENUSELECT %p %p\n", msg->wParam, msg->lParam);
m_selectedMenu = reinterpret_cast<HMENU>(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<MSG*>(lParam);
MSG* msg = reinterpret_cast<MSG*>(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();
}

View file

@ -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<LPARAM>(&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;
}