* 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 (!tb)
{ {
// If no hot item was selected // If no hot item was selected choose the appropriate toolbar
// choose the first toolbar (prefer shell-folder, which will be positioned at the top) if (change == VK_UP)
{
if (m_SFToolbar) if (m_staticToolbar)
tb = m_SFToolbar; tb = m_staticToolbar;
else else
tb = m_staticToolbar; tb = m_SFToolbar;
}
else if (change == VK_DOWN)
{
if (m_SFToolbar)
tb = m_SFToolbar;
else
tb = m_staticToolbar;
}
} }
// Ask the first toolbar to change // Ask the first toolbar to change
@ -861,20 +869,19 @@ HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
switch (changeType) switch (changeType)
{ {
case MPOS_SELECTLEFT: 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_subMenuParent)
{
if (m_subMenuChild)
return m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
return S_OK; return S_OK;
}
return m_subMenuParent->OnSelect(MPOS_CANCELLEVEL); return m_subMenuParent->OnSelect(MPOS_CANCELLEVEL);
case MPOS_SELECTRIGHT: case MPOS_SELECTRIGHT:
if (m_hotBar && m_hotItem >= 0) if (m_hotBar && m_hotItem >= 0 && m_hotBar->PopupItem(m_hotItem) == S_OK)
{ return S_FALSE;
if (m_hotBar->PopupItem(m_hotItem) == S_OK) if (m_parentBand)
return S_FALSE; return m_parentBand->_MenuItemHotTrack(VK_RIGHT);
}
if (!m_subMenuParent) if (!m_subMenuParent)
return S_OK; return S_OK;
return m_subMenuParent->OnSelect(MPOS_SELECTRIGHT); return m_subMenuParent->OnSelect(MPOS_SELECTRIGHT);

View file

@ -330,15 +330,15 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg)
return TRUE; return TRUE;
} }
LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam) LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM hookWParam, LPARAM hookLParam)
{ {
if (nCode < 0) if (nCode < 0)
return CallNextHookEx(m_hMsgFilterHook, nCode, wParam, lParam); return CallNextHookEx(m_hMsgFilterHook, nCode, hookWParam, hookLParam);
if (nCode == MSGF_MENU) if (nCode == MSGF_MENU)
{ {
BOOL callNext = TRUE; BOOL callNext = TRUE;
MSG* msg = reinterpret_cast<MSG*>(lParam); MSG* msg = reinterpret_cast<MSG*>(hookLParam);
switch (msg->message) switch (msg->message)
{ {
@ -359,16 +359,16 @@ LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam
callNext = ProcessMouseMove(msg); callNext = ProcessMouseMove(msg);
break; break;
case WM_INITMENUPOPUP: case WM_INITMENUPOPUP:
DbgPrint("WM_INITMENUPOPUP %p %p\n", wParam, lParam); DbgPrint("WM_INITMENUPOPUP %p %p\n", msg->wParam, msg->lParam);
m_selectedMenu = reinterpret_cast<HMENU>(lParam); m_selectedMenu = reinterpret_cast<HMENU>(msg->lParam);
m_selectedItem = -1; m_selectedItem = -1;
m_selectedItemFlags = 0; m_selectedItemFlags = 0;
break; break;
case WM_MENUSELECT: case WM_MENUSELECT:
DbgPrint("WM_MENUSELECT %p %p\n", wParam, lParam); DbgPrint("WM_MENUSELECT %p %p\n", msg->wParam, msg->lParam);
m_selectedMenu = reinterpret_cast<HMENU>(lParam); m_selectedMenu = reinterpret_cast<HMENU>(msg->lParam);
m_selectedItem = LOWORD(wParam); m_selectedItem = GET_X_LPARAM(msg->wParam);
m_selectedItemFlags = HIWORD(wParam); m_selectedItemFlags = HIWORD(msg->wParam);
break; break;
case WM_KEYDOWN: case WM_KEYDOWN:
switch (msg->wParam) switch (msg->wParam)
@ -380,7 +380,7 @@ LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam
} }
break; break;
case VK_RIGHT: case VK_RIGHT:
if (!(m_selectedItemFlags & MF_POPUP)) if (m_selectedItem < 0 || !(m_selectedItemFlags & MF_POPUP))
{ {
m_parent->mb->_MenuItemHotTrack(VK_RIGHT); m_parent->mb->_MenuItemHotTrack(VK_RIGHT);
} }
@ -393,18 +393,18 @@ LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam
return 1; 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) if (nCode < 0)
return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam); return CallNextHookEx(m_hGetMsgHook, nCode, hookWParam, hookLParam);
if (nCode == HC_ACTION) if (nCode == HC_ACTION)
{ {
BOOL callNext = TRUE; BOOL callNext = TRUE;
MSG* msg = reinterpret_cast<MSG*>(lParam); MSG* msg = reinterpret_cast<MSG*>(hookLParam);
POINT pt = msg->pt; POINT pt = msg->pt;
switch (msg->message) switch (msg->message)
@ -463,7 +463,7 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
return 1; return 1;
} }
return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam); return CallNextHookEx(m_hGetMsgHook, nCode, hookWParam, hookLParam);
} }
HRESULT CMenuFocusManager::PlaceHooks() HRESULT CMenuFocusManager::PlaceHooks()
@ -621,6 +621,11 @@ HRESULT CMenuFocusManager::PushTrackedPopup(HMENU popup)
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
DbgPrint("PushTrackedPopup %p\n", popup);
m_selectedMenu = popup;
m_selectedItem = -1;
m_selectedItemFlags = 0;
return UpdateFocus(); return UpdateFocus();
} }

View file

@ -609,11 +609,15 @@ HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DW
if (m_hotBar == this) 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, // Vertical menus show/hide the submenu after a delay,
// but horizontal menubars switch between items instantly, // but only with the mouse.
// if they were open.
if (m_initFlags & SMINIT_VERTICAL) if (m_initFlags & SMINIT_VERTICAL)
{ {
DWORD elapsed = 0; DWORD elapsed = 0;
@ -622,11 +626,6 @@ HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DW
m_timerEnabled = TRUE; m_timerEnabled = TRUE;
TRACE("SetTimer called with m_hotItem=%d\n", m_hotItem); 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 else
{ {
@ -704,6 +703,7 @@ HRESULT CMenuToolbarBase::ChangeTrackedItem(INT index, BOOL wasTracking)
if (!SendMessage(m_hwndToolbar, TB_GETBUTTON, index, reinterpret_cast<LPARAM>(&btn))) if (!SendMessage(m_hwndToolbar, TB_GETBUTTON, index, reinterpret_cast<LPARAM>(&btn)))
return E_FAIL; return E_FAIL;
DbgPrint("ChangeTrackedItem %d, %d\n", index, wasTracking);
m_isTrackingPopup = wasTracking; m_isTrackingPopup = wasTracking;
return m_menuBand->_ChangeHotItem(this, btn.idCommand, HICF_MOUSE); return m_menuBand->_ChangeHotItem(this, btn.idCommand, HICF_MOUSE);
} }
@ -912,8 +912,16 @@ HRESULT CMenuToolbarBase::KeyboardItemChange(DWORD dwSelectType)
{ {
if (prev != btn.idCommand) if (prev != btn.idCommand)
{ {
TRACE("Setting Hot item to %d\n", index); DbgPrint("Setting Hot item to %d\n", index);
m_menuBand->_ChangeHotItem(this, btn.idCommand, 0); 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; return S_OK;
} }