* Improvements on the focus manager. The menus work better, but still not fully. Commiting for backup/history purposes.
CORE-7586

svn path=/branches/shell-experiments/; revision=62601
This commit is contained in:
David Quintana 2014-04-02 17:37:37 +00:00
parent 8676a39ebc
commit a875dbf317
7 changed files with 810 additions and 577 deletions

View file

@ -65,7 +65,8 @@ CMenuBand::CMenuBand() :
m_topLevelWindow(NULL), m_topLevelWindow(NULL),
m_hotBar(NULL), m_hotBar(NULL),
m_hotItem(-1), m_hotItem(-1),
m_trackingPopup(FALSE) m_popupBar(NULL),
m_popupItem(-1)
{ {
m_focusManager = CMenuFocusManager::AcquireManager(); m_focusManager = CMenuFocusManager::AcquireManager();
} }
@ -504,6 +505,10 @@ HRESULT STDMETHODCALLTYPE CMenuBand::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
HRESULT CMenuBand::_SetChildBand(CMenuBand * child) HRESULT CMenuBand::_SetChildBand(CMenuBand * child)
{ {
m_childBand = child; m_childBand = child;
if (!child)
{
_ChangePopupItem(NULL, -1);
}
return S_OK; return S_OK;
} }
@ -524,13 +529,11 @@ HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
if (!punkClient) if (!punkClient)
{ {
if (m_staticToolbar) m_staticToolbar->OnPopupItemChanged(NULL, -1);
if (m_SFToolbar) m_SFToolbar->OnPopupItemChanged(NULL, -1);
return S_OK; 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; return hr;
} }
@ -666,8 +669,7 @@ HRESULT CMenuBand::_TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, R
UINT flags = TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_LEFTALIGN; UINT flags = TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_LEFTALIGN;
m_trackingPopup = TRUE; //_DisableMouseTrack(TRUE);
DbgPrint("Tracking: %d\n", m_trackingPopup);
m_focusManager->PushTrackedPopup(popup); m_focusManager->PushTrackedPopup(popup);
if (m_menuOwner) if (m_menuOwner)
@ -680,8 +682,7 @@ HRESULT CMenuBand::_TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, R
} }
m_focusManager->PopTrackedPopup(popup); m_focusManager->PopTrackedPopup(popup);
m_trackingPopup = FALSE; _DisableMouseTrack(FALSE);
DbgPrint("Tracking: %d\n", m_trackingPopup);
return S_OK; return S_OK;
} }
@ -692,16 +693,36 @@ HRESULT CMenuBand::_GetTopLevelWindow(HWND*topLevel)
return S_OK; return S_OK;
} }
HRESULT CMenuBand::_OnHotItemChanged(CMenuToolbarBase * tb, INT id) HRESULT CMenuBand::_ChangeHotItem(CMenuToolbarBase * tb, INT id, DWORD dwFlags)
{
if (m_trackingPopup && id == -1)
{ {
if (m_hotBar == tb && m_hotItem == id)
return S_FALSE; return S_FALSE;
}
DbgPrint("Hot item changed from %p %p, to %p %p\n", m_hotBar, m_hotItem, tb, id);
if (m_hotBar != tb)
_KillPopupTimers();
m_hotBar = tb; m_hotBar = tb;
m_hotItem = id; m_hotItem = id;
if (m_staticToolbar) m_staticToolbar->OnHotItemChanged(tb, id); if (m_staticToolbar) m_staticToolbar->ChangeHotItem(tb, id, dwFlags);
if (m_SFToolbar) m_SFToolbar->OnHotItemChanged(tb, id); if (m_SFToolbar) m_SFToolbar->ChangeHotItem(tb, id, dwFlags);
_MenuItemHotTrack(MPOS_CHILDTRACKING);
return S_OK;
}
HRESULT CMenuBand::_ChangePopupItem(CMenuToolbarBase * tb, INT id)
{
DbgPrint("Popup item changed from %p %p, to %p %p\n", m_popupBar, m_popupItem, tb, id);
m_popupBar = tb;
m_popupItem = id;
if (m_staticToolbar) m_staticToolbar->ChangePopupItem(tb, id);
if (m_SFToolbar) m_SFToolbar->ChangePopupItem(tb, id);
return S_OK; return S_OK;
} }
@ -721,13 +742,13 @@ HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
} }
else if (m_staticToolbar && m_hotBar == m_staticToolbar) else if (m_staticToolbar && m_hotBar == m_staticToolbar)
{ {
hr = m_staticToolbar->ChangeHotItem(VK_DOWN); hr = m_staticToolbar->KeyboardItemChange(VK_DOWN);
if (hr == S_FALSE) if (hr == S_FALSE)
{ {
if (m_SFToolbar) if (m_SFToolbar)
return m_SFToolbar->ChangeHotItem(VK_HOME); return m_SFToolbar->KeyboardItemChange(VK_HOME);
else else
return m_staticToolbar->ChangeHotItem(VK_HOME); return m_staticToolbar->KeyboardItemChange(VK_HOME);
} }
return hr; return hr;
} }
@ -737,13 +758,13 @@ HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
SendMessageW(m_menuOwner, WM_CANCELMODE, 0, 0); SendMessageW(m_menuOwner, WM_CANCELMODE, 0, 0);
if (m_staticToolbar && (m_hotBar == m_staticToolbar || m_hotBar == NULL)) if (m_staticToolbar && (m_hotBar == m_staticToolbar || m_hotBar == NULL))
{ {
hr = m_staticToolbar->ChangeHotItem(VK_UP); hr = m_staticToolbar->KeyboardItemChange(VK_UP);
if (hr == S_FALSE) if (hr == S_FALSE)
{ {
if (m_SFToolbar) if (m_SFToolbar)
return m_SFToolbar->ChangeHotItem(VK_END); return m_SFToolbar->KeyboardItemChange(VK_END);
else else
return m_staticToolbar->ChangeHotItem(VK_END); return m_staticToolbar->KeyboardItemChange(VK_END);
} }
return hr; return hr;
} }
@ -758,25 +779,25 @@ HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
{ {
if (m_SFToolbar && (m_hotBar == m_SFToolbar || m_hotBar == NULL)) if (m_SFToolbar && (m_hotBar == m_SFToolbar || m_hotBar == NULL))
{ {
hr = m_SFToolbar->ChangeHotItem(VK_DOWN); hr = m_SFToolbar->KeyboardItemChange(VK_DOWN);
if (hr == S_FALSE) if (hr == S_FALSE)
{ {
if (m_staticToolbar) if (m_staticToolbar)
return m_staticToolbar->ChangeHotItem(VK_HOME); return m_staticToolbar->KeyboardItemChange(VK_HOME);
else else
return m_SFToolbar->ChangeHotItem(VK_HOME); return m_SFToolbar->KeyboardItemChange(VK_HOME);
} }
return hr; return hr;
} }
else if (m_staticToolbar && m_hotBar == m_staticToolbar) else if (m_staticToolbar && m_hotBar == m_staticToolbar)
{ {
hr = m_staticToolbar->ChangeHotItem(VK_DOWN); hr = m_staticToolbar->KeyboardItemChange(VK_DOWN);
if (hr == S_FALSE) if (hr == S_FALSE)
{ {
if (m_SFToolbar) if (m_SFToolbar)
return m_SFToolbar->ChangeHotItem(VK_HOME); return m_SFToolbar->KeyboardItemChange(VK_HOME);
else else
return m_staticToolbar->ChangeHotItem(VK_HOME); return m_staticToolbar->KeyboardItemChange(VK_HOME);
} }
return hr; return hr;
} }
@ -785,25 +806,25 @@ HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
{ {
if (m_staticToolbar && (m_hotBar == m_staticToolbar || m_hotBar == NULL)) if (m_staticToolbar && (m_hotBar == m_staticToolbar || m_hotBar == NULL))
{ {
hr = m_staticToolbar->ChangeHotItem(VK_UP); hr = m_staticToolbar->KeyboardItemChange(VK_UP);
if (hr == S_FALSE) if (hr == S_FALSE)
{ {
if (m_SFToolbar) if (m_SFToolbar)
return m_SFToolbar->ChangeHotItem(VK_END); return m_SFToolbar->KeyboardItemChange(VK_END);
else else
return m_staticToolbar->ChangeHotItem(VK_END); return m_staticToolbar->KeyboardItemChange(VK_END);
} }
return hr; return hr;
} }
else if (m_SFToolbar && m_hotBar == m_SFToolbar) else if (m_SFToolbar && m_hotBar == m_SFToolbar)
{ {
hr = m_SFToolbar->ChangeHotItem(VK_UP); hr = m_SFToolbar->KeyboardItemChange(VK_UP);
if (hr == S_FALSE) if (hr == S_FALSE)
{ {
if (m_staticToolbar) if (m_staticToolbar)
return m_staticToolbar->ChangeHotItem(VK_END); return m_staticToolbar->KeyboardItemChange(VK_END);
else else
return m_SFToolbar->ChangeHotItem(VK_END); return m_SFToolbar->KeyboardItemChange(VK_END);
} }
return hr; return hr;
} }
@ -836,31 +857,25 @@ HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
return S_OK; return S_OK;
} }
HRESULT CMenuBand::_OnPopupSubMenu(IMenuPopup * popup, POINTL * pAt, RECTL * pExclude, CMenuToolbarBase * toolbar, INT item) HRESULT CMenuBand::_CancelCurrentPopup()
{
if (m_subMenuChild)
{ {
if (!m_subMenuChild)
return S_FALSE;
HRESULT hr = m_subMenuChild->OnSelect(MPOS_CANCELLEVEL); HRESULT hr = m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
} }
if (m_staticToolbar) m_staticToolbar->OnPopupItemChanged(toolbar, item); HRESULT CMenuBand::_OnPopupSubMenu(IMenuPopup * popup, POINTL * pAt, RECTL * pExclude)
if (m_SFToolbar) m_SFToolbar->OnPopupItemChanged(toolbar, item);
m_subMenuChild = popup;
m_trackingPopup = popup != NULL;
DbgPrint("Tracking: %d\n", m_trackingPopup);
if (popup)
{ {
m_subMenuChild = popup;
if (m_subMenuParent) if (m_subMenuParent)
IUnknown_SetSite(popup, m_subMenuParent); IUnknown_SetSite(popup, m_subMenuParent);
else else
IUnknown_SetSite(popup, m_site); IUnknown_SetSite(popup, m_site);
popup->Popup(pAt, pExclude, MPPF_RIGHT); popup->Popup(pAt, pExclude, MPPF_RIGHT);
}
return S_OK; return S_OK;
} }
@ -874,6 +889,20 @@ HRESULT CMenuBand::_DisableMouseTrack(BOOL bDisable)
return S_OK; return S_OK;
} }
HRESULT CMenuBand::_KillPopupTimers()
{
HRESULT hr = S_OK;
if (m_staticToolbar)
hr = m_staticToolbar->KillPopupTimer();
if (FAILED(hr))
return hr;
if (m_SFToolbar)
hr = m_SFToolbar->KillPopupTimer();
return hr;
}
HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags) HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;

View file

@ -62,7 +62,8 @@ private:
CMenuToolbarBase * m_hotBar; CMenuToolbarBase * m_hotBar;
INT m_hotItem; INT m_hotItem;
BOOL m_trackingPopup; CMenuToolbarBase * m_popupBar;
INT m_popupItem;
public: public:
CMenuBand(); CMenuBand();
@ -176,13 +177,16 @@ public:
HRESULT _CallCBWithItemPidl(LPITEMIDLIST pidl, UINT uMsg, WPARAM wParam, LPARAM lParam); HRESULT _CallCBWithItemPidl(LPITEMIDLIST pidl, UINT uMsg, WPARAM wParam, LPARAM lParam);
HRESULT _TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, RECT& rcExclude); HRESULT _TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, RECT& rcExclude);
HRESULT _GetTopLevelWindow(HWND*topLevel); HRESULT _GetTopLevelWindow(HWND*topLevel);
HRESULT _OnHotItemChanged(CMenuToolbarBase * tb, INT id); HRESULT _ChangeHotItem(CMenuToolbarBase * tb, INT id, DWORD dwFlags);
HRESULT _ChangePopupItem(CMenuToolbarBase * tb, INT id);
HRESULT _MenuItemHotTrack(DWORD changeType); HRESULT _MenuItemHotTrack(DWORD changeType);
HRESULT _OnPopupSubMenu(IMenuPopup * popup, POINTL * pAt, RECTL * pExclude, CMenuToolbarBase * toolbar, INT item); HRESULT _CancelCurrentPopup();
HRESULT _OnPopupSubMenu(IMenuPopup * popup, POINTL * pAt, RECTL * pExclude);
HRESULT _DisableMouseTrack(BOOL bDisable); HRESULT _DisableMouseTrack(BOOL bDisable);
HRESULT _SetChildBand(CMenuBand * child); HRESULT _SetChildBand(CMenuBand * child);
HRESULT _SetParentBand(CMenuBand * parent); HRESULT _SetParentBand(CMenuBand * parent);
HRESULT _IsPopup(); HRESULT _IsPopup();
HRESULT _KillPopupTimers();
BOOL UseBigIcons() BOOL UseBigIcons()
{ {

View file

@ -149,8 +149,6 @@ CMenuFocusManager::CMenuFocusManager() :
m_hMsgFilterHook(NULL), m_hMsgFilterHook(NULL),
m_hGetMsgHook(NULL), m_hGetMsgHook(NULL),
m_mouseTrackDisabled(FALSE), m_mouseTrackDisabled(FALSE),
m_lastMoveFlags(0),
m_lastMovePos(0),
m_captureHwnd(0), m_captureHwnd(0),
m_bandCount(0) m_bandCount(0)
{ {
@ -173,7 +171,7 @@ void CMenuFocusManager::DisableMouseTrack(HWND parent, BOOL disableThis)
{ {
StackEntry& entry = m_bandStack[i]; StackEntry& entry = m_bandStack[i];
if (entry.type == MenuPopupEntry) if (entry.type != TrackedMenuEntry)
{ {
HWND hwnd; HWND hwnd;
HRESULT hr = entry.mb->_GetTopLevelWindow(&hwnd); HRESULT hr = entry.mb->_GetTopLevelWindow(&hwnd);
@ -192,10 +190,10 @@ void CMenuFocusManager::DisableMouseTrack(HWND parent, BOOL disableThis)
entry.mb->_DisableMouseTrack(bDisable); entry.mb->_DisableMouseTrack(bDisable);
} }
} }
else //else
{ //{
continue; // continue;
} //}
} }
m_mouseTrackDisabled = lastDisable; m_mouseTrackDisabled = lastDisable;
} }
@ -220,22 +218,28 @@ void CMenuFocusManager::SetCapture(HWND child)
} }
} }
HRESULT CMenuFocusManager::IsTrackedWindow(HWND hWnd) HRESULT CMenuFocusManager::IsTrackedWindow(HWND hWnd, StackEntry ** pentry)
{ {
int i = m_bandCount; if (pentry)
while (--i >= 0) *pentry = NULL;
for (int i = m_bandCount; --i >= 0;)
{ {
StackEntry& entry = m_bandStack[i]; StackEntry& entry = m_bandStack[i];
if (entry.type == MenuPopupEntry) if (entry.type != TrackedMenuEntry)
{ {
HRESULT hr = entry.mb->IsWindowOwner(hWnd); HRESULT hr = entry.mb->IsWindowOwner(hWnd);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
if (hr == S_OK) if (hr == S_OK)
{
if (pentry)
*pentry = &entry;
return S_OK; return S_OK;
} }
} }
}
return S_FALSE; return S_FALSE;
} }
@ -243,43 +247,58 @@ HRESULT CMenuFocusManager::IsTrackedWindow(HWND hWnd)
LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg) LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg)
{ {
HWND child; HWND child;
POINT pt;
int iHitTestResult; int iHitTestResult;
pt = msg->pt; POINT pt2 = { GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam) };
ClientToScreen(msg->hwnd, &pt2);
/* Don't do anything if the mouse has not been moved */
POINT pt = msg->pt;
if (pt.x == m_ptPrev.x && pt.y == m_ptPrev.y)
return TRUE;
m_ptPrev = pt;
child = WindowFromPoint(pt); child = WindowFromPoint(pt);
if (!m_parent) if (m_hwndUnderMouse != child)
return TRUE;
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)
return TRUE;
m_ptPrev = 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 = child; WCHAR cn[1024];
if (SendMessage(hwndToolbar, WM_USER_ISTRACKEDITEM, iHitTestResult, 0)) 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)
{ {
DbgPrint("Hot item tracking detected a change...\n"); ScreenToClient(child, &pt);
iHitTestResult = SendMessageW(child, TB_HITTEST, 0, (LPARAM) &pt);
if (iHitTestResult >= 0 &&
SendMessage(child, WM_USER_ISTRACKEDITEM, iHitTestResult, 0) == S_FALSE)
{
DbgPrint("Hot item tracking detected a change (capture=%p)...\n", m_captureHwnd);
DisableMouseTrack(NULL, FALSE);
if (m_current->type == TrackedMenuEntry) if (m_current->type == TrackedMenuEntry)
SendMessage(m_parent->hwnd, WM_CANCELMODE, 0, 0); SendMessage(entry->hwnd, WM_CANCELMODE, 0, 0);
else PostMessage(child, WM_USER_CHANGETRACKEDITEM, iHitTestResult, iHitTestResult);
m_current->mb->_MenuItemHotTrack(MPOS_CANCELLEVEL);
PostMessage(hwndToolbar, WM_USER_CHANGETRACKEDITEM, iHitTestResult, iHitTestResult);
return FALSE; return FALSE;
} }
if (m_current->type == MenuPopupEntry)
{
SetCapture(child);
ScreenToClient(child, &pt2);
SendMessage(child, WM_MOUSEMOVE, msg->wParam, MAKELPARAM(pt2.x, pt2.y));
}
}
if (m_current->type == MenuPopupEntry)
{
HWND parent = GetAncestor(child, GA_ROOT);
DisableMouseTrack(parent, FALSE);
} }
return TRUE; return TRUE;
@ -297,13 +316,27 @@ LRESULT CMenuFocusManager::MsgFilterHook(INT nCode, WPARAM wParam, LPARAM lParam
switch (msg->message) switch (msg->message)
{ {
case WM_NCLBUTTONDOWN:
case WM_LBUTTONDOWN:
if (m_menuBar)
{
POINT pt = msg->pt;
HWND child = WindowFromPoint(pt);
BOOL hoveringMenuBar = m_menuBar->mb->IsWindowOwner(child) == S_OK;
if (hoveringMenuBar)
{
HWND parent = GetAncestor(child, GA_ROOT);
m_menuBar->mb->_DisableMouseTrack(TRUE);
}
}
break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
callNext = ProcessMouseMove(msg); callNext = ProcessMouseMove(msg);
break; break;
} }
if (!callNext) if (!callNext)
return 0; return 1;
} }
return CallNextHookEx(m_hMsgFilterHook, nCode, wParam, lParam); return CallNextHookEx(m_hMsgFilterHook, nCode, wParam, lParam);
@ -314,12 +347,11 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
if (nCode < 0) if (nCode < 0)
return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam); return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam);
LPARAM pos = (LPARAM) GetMessagePos();
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*>(lParam);
POINT pt = msg->pt;
switch (msg->message) switch (msg->message)
{ {
@ -330,53 +362,17 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
if (m_current->type == MenuPopupEntry) if (m_current->type == MenuPopupEntry)
{ {
POINT pt = { GET_X_LPARAM(pos), GET_Y_LPARAM(pos) };
HWND child = WindowFromPoint(pt); HWND child = WindowFromPoint(pt);
HWND window = GetAncestor(child, GA_ROOT);
if (IsTrackedWindow(window) != S_OK) if (IsTrackedWindow(child) != S_OK)
{ {
SetCapture(NULL);
m_current->mb->_MenuItemHotTrack(MPOS_FULLCANCEL); m_current->mb->_MenuItemHotTrack(MPOS_FULLCANCEL);
} }
} }
break; break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
if ((m_parent && m_parent->type==MenuPopupEntry) || ProcessMouseMove(msg)) callNext = 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; break;
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
case WM_KEYDOWN: case WM_KEYDOWN:
@ -405,7 +401,7 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
} }
if (!callNext) if (!callNext)
return 0; return 1;
} }
return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam); return CallNextHookEx(m_hGetMsgHook, nCode, wParam, lParam);
@ -413,12 +409,12 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
HRESULT CMenuFocusManager::PlaceHooks() HRESULT CMenuFocusManager::PlaceHooks()
{ {
if (m_current->hmenu) if (m_current->type == TrackedMenuEntry)
{ {
DbgPrint("Entering MSGFILTER hook...\n"); DbgPrint("Entering MSGFILTER hook...\n");
m_hMsgFilterHook = SetWindowsHookEx(WH_MSGFILTER, s_MsgFilterHook, NULL, m_threadId); m_hMsgFilterHook = SetWindowsHookEx(WH_MSGFILTER, s_MsgFilterHook, NULL, m_threadId);
} }
else else if (m_current->type == MenuPopupEntry)
{ {
DbgPrint("Entering GETMESSAGE hook...\n"); DbgPrint("Entering GETMESSAGE hook...\n");
m_hGetMsgHook = SetWindowsHookEx(WH_GETMESSAGE, s_GetMsgHook, NULL, m_threadId); m_hGetMsgHook = SetWindowsHookEx(WH_GETMESSAGE, s_GetMsgHook, NULL, m_threadId);
@ -468,9 +464,21 @@ HRESULT CMenuFocusManager::UpdateFocus()
m_parent = NULL; m_parent = NULL;
} }
if (m_bandCount >= 1 && m_bandStack[0].type == MenuBarEntry)
{
m_menuBar = &(m_bandStack[0]);
}
else
{
m_menuBar = NULL;
}
if (old && (!m_current || old->type != m_current->type)) if (old && (!m_current || old->type != m_current->type))
{ {
DisableMouseTrack(NULL, FALSE); if (m_current->type != TrackedMenuEntry)
{
DisableMouseTrack(m_current->hwnd, FALSE);
}
hr = RemoveHooks(); hr = RemoveHooks();
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
@ -484,13 +492,22 @@ HRESULT CMenuFocusManager::UpdateFocus()
return hr; return hr;
} }
if (m_parent)
{
DisableMouseTrack(m_parent->hwnd, TRUE);
}
if ((m_current && m_current->type == MenuPopupEntry) && if ((m_current && m_current->type == MenuPopupEntry) &&
(!m_parent || m_parent->type == MenuBarEntry)) (!m_parent || m_parent->type == MenuBarEntry))
{ {
DisableMouseTrack(m_current->hwnd, FALSE);
// When the mouse moves, it should set itself to the proper band // When the mouse moves, it should set itself to the proper band
SetCapture(m_current->hwnd); SetCapture(m_current->hwnd);
//// FIXME: Debugging code, probably not right
//POINT pt2;
//GetCursorPos(&pt2);
//ScreenToClient(m_current->hwnd, &pt2);
//SendMessage(m_current->hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(pt2.x, pt2.y));
} }
_ASSERT(!m_parent || m_parent->type != TrackedMenuEntry); _ASSERT(!m_parent || m_parent->type != TrackedMenuEntry);

View file

@ -58,6 +58,7 @@ private:
private: private:
StackEntry * m_current; StackEntry * m_current;
StackEntry * m_parent; StackEntry * m_parent;
StackEntry * m_menuBar;
HHOOK m_hMsgFilterHook; HHOOK m_hMsgFilterHook;
HHOOK m_hGetMsgHook; HHOOK m_hGetMsgHook;
@ -65,13 +66,12 @@ private:
BOOL m_mouseTrackDisabled; BOOL m_mouseTrackDisabled;
WPARAM m_lastMoveFlags;
LPARAM m_lastMovePos;
POINT m_ptPrev; POINT m_ptPrev;
HWND m_captureHwnd; HWND m_captureHwnd;
HWND m_hwndUnderMouse;
// TODO: make dynamic // TODO: make dynamic
#define MAX_RECURSE 20 #define MAX_RECURSE 20
StackEntry m_bandStack[MAX_RECURSE]; StackEntry m_bandStack[MAX_RECURSE];
@ -97,7 +97,7 @@ private:
HRESULT PlaceHooks(); HRESULT PlaceHooks();
HRESULT RemoveHooks(); HRESULT RemoveHooks();
HRESULT UpdateFocus(); HRESULT UpdateFocus();
HRESULT IsTrackedWindow(HWND hWnd); HRESULT IsTrackedWindow(HWND hWnd, StackEntry ** pentry = NULL);
void DisableMouseTrack(HWND parent, BOOL disableThis); void DisableMouseTrack(HWND parent, BOOL disableThis);
void SetCapture(HWND child); void SetCapture(HWND child);

File diff suppressed because it is too large Load diff

View file

@ -34,6 +34,7 @@ private:
BOOL m_useFlatMenus; BOOL m_useFlatMenus;
WNDPROC m_SubclassOld; WNDPROC m_SubclassOld;
BOOL m_disableMouseTrack; BOOL m_disableMouseTrack;
BOOL m_timerEnabled;
protected: protected:
CMenuBand * m_menuBand; CMenuBand * m_menuBand;
@ -47,7 +48,7 @@ protected:
CMenuToolbarBase * m_popupBar; CMenuToolbarBase * m_popupBar;
INT m_popupItem; INT m_popupItem;
DWORD m_toolbarFlags; DWORD m_initFlags;
BOOL m_isTracking; BOOL m_isTracking;
private: private:
@ -65,14 +66,14 @@ public:
HRESULT OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult); HRESULT OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult);
HRESULT OnHotItemChanged(CMenuToolbarBase * toolbar, INT item); HRESULT ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DWORD dwFlags);
HRESULT OnPopupItemChanged(CMenuToolbarBase * toolbar, INT item); HRESULT ChangePopupItem(CMenuToolbarBase * toolbar, INT item);
HRESULT PopupSubMenu(UINT itemId, UINT index, IShellMenu* childShellMenu); HRESULT PopupSubMenu(UINT itemId, UINT index, IShellMenu* childShellMenu);
HRESULT PopupSubMenu(UINT itemId, UINT index, HMENU menu); HRESULT PopupSubMenu(UINT itemId, UINT index, HMENU menu);
HRESULT DoContextMenu(IContextMenu* contextMenu); HRESULT DoContextMenu(IContextMenu* contextMenu);
HRESULT ChangeHotItem(DWORD changeType); HRESULT KeyboardItemChange(DWORD changeType);
HRESULT OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * theResult); HRESULT OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * theResult);
HRESULT IsTrackedItem(INT index); HRESULT IsTrackedItem(INT index);
@ -88,15 +89,20 @@ public:
virtual HRESULT FillToolbar(BOOL clearFirst=FALSE) = 0; virtual HRESULT FillToolbar(BOOL clearFirst=FALSE) = 0;
virtual HRESULT OnContextMenu(NMMOUSE * rclick) = 0; virtual HRESULT OnContextMenu(NMMOUSE * rclick) = 0;
HRESULT PopupItem(INT uItem); HRESULT CancelCurrentPopup();
HRESULT GetDataFromId(INT uItem, INT* pIndex, DWORD_PTR* pData); HRESULT PopupItem(INT iItem);
HRESULT GetDataFromId(INT iItem, INT* pIndex, DWORD_PTR* pData);
HRESULT KillPopupTimer();
protected: protected:
virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult); virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult);
virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb) = 0; virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb) = 0;
virtual HRESULT InternalPopupItem(INT uItem, INT index, DWORD_PTR dwData) = 0; virtual HRESULT InternalPopupItem(INT iItem, INT index, DWORD_PTR dwData) = 0;
virtual HRESULT InternalHasSubMenu(INT uItem, INT index, DWORD_PTR dwData) = 0; virtual HRESULT InternalHasSubMenu(INT iItem, INT index, DWORD_PTR dwData) = 0;
virtual HRESULT GetInfoTip(LPWSTR pszText, INT cchTextMax, INT iItem, INT index, DWORD_PTR dwData)=0;
LRESULT CALLBACK SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
@ -107,7 +113,10 @@ protected:
HRESULT UpdateImageLists(); HRESULT UpdateImageLists();
private: private:
HRESULT OnPagerCalcSize(LPNMPGCALCSIZE csize);
HRESULT OnPopupTimer(DWORD timerId);
HRESULT OnCustomDraw(LPNMTBCUSTOMDRAW cdraw, LRESULT * theResult); HRESULT OnCustomDraw(LPNMTBCUSTOMDRAW cdraw, LRESULT * theResult);
HRESULT OnGetInfoTip(NMTBGETINFOTIP * tip);
}; };
class CMenuStaticToolbar : class CMenuStaticToolbar :
@ -130,8 +139,10 @@ public:
protected: protected:
virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb); virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb);
virtual HRESULT InternalPopupItem(INT uItem, INT index, DWORD_PTR dwData); virtual HRESULT GetInfoTip(LPWSTR pszText, INT cchTextMax, INT iItem, INT index, DWORD_PTR dwData);
virtual HRESULT InternalHasSubMenu(INT uItem, INT index, DWORD_PTR dwData);
virtual HRESULT InternalPopupItem(INT iItem, INT index, DWORD_PTR dwData);
virtual HRESULT InternalHasSubMenu(INT iItem, INT index, DWORD_PTR dwData);
}; };
class CMenuSFToolbar : class CMenuSFToolbar :
@ -156,6 +167,8 @@ public:
protected: protected:
virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb); virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb);
virtual HRESULT InternalPopupItem(INT uItem, INT index, DWORD_PTR dwData); virtual HRESULT GetInfoTip(LPWSTR pszText, INT cchTextMax, INT iItem, INT index, DWORD_PTR dwData);
virtual HRESULT InternalHasSubMenu(INT uItem, INT index, DWORD_PTR dwData);
virtual HRESULT InternalPopupItem(INT iItem, INT index, DWORD_PTR dwData);
virtual HRESULT InternalHasSubMenu(INT iItem, INT index, DWORD_PTR dwData);
}; };

View file

@ -72,7 +72,7 @@ Win32DbgPrint(const char *filename, int line, const char *lpFormat, ...)
else else
fname++; fname++;
szMsgStart = szMsg + sprintf(szMsg, "%s:%d: ", fname, line); szMsgStart = szMsg + sprintf(szMsg, "[%10d] %s:%d: ", GetTickCount(), fname, line);
va_start(vl, lpFormat); va_start(vl, lpFormat);
uRet = (ULONG) vsprintf(szMsgStart, lpFormat, vl); uRet = (ULONG) vsprintf(szMsgStart, lpFormat, vl);