* Further improvements. Not working yet. Commiting as backup/history.

svn path=/branches/shell-experiments/; revision=62603
This commit is contained in:
David Quintana 2014-04-03 18:30:25 +00:00
parent a875dbf317
commit 97b02b410b
7 changed files with 79 additions and 50 deletions

View file

@ -523,6 +523,11 @@ HRESULT CMenuBand::_IsPopup()
return m_subMenuParent ? S_OK : S_FALSE; return m_subMenuParent ? S_OK : S_FALSE;
} }
HRESULT CMenuBand::_IsTracking()
{
return m_popupBar != NULL;
}
HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient) HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
{ {
m_subMenuChild = NULL; 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; UINT flags = TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_LEFTALIGN;
//_DisableMouseTrack(TRUE);
m_focusManager->PushTrackedPopup(popup); m_focusManager->PushTrackedPopup(popup);
if (m_menuOwner) 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); 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_hotBar = tb;
m_hotItem = id; m_hotItem = id;

View file

@ -186,6 +186,7 @@ public:
HRESULT _SetChildBand(CMenuBand * child); HRESULT _SetChildBand(CMenuBand * child);
HRESULT _SetParentBand(CMenuBand * parent); HRESULT _SetParentBand(CMenuBand * parent);
HRESULT _IsPopup(); HRESULT _IsPopup();
HRESULT _IsTracking();
HRESULT _KillPopupTimers(); HRESULT _KillPopupTimers();
BOOL UseBigIcons() BOOL UseBigIcons()

View file

@ -150,6 +150,8 @@ CMenuFocusManager::CMenuFocusManager() :
m_hGetMsgHook(NULL), m_hGetMsgHook(NULL),
m_mouseTrackDisabled(FALSE), m_mouseTrackDisabled(FALSE),
m_captureHwnd(0), m_captureHwnd(0),
m_hwndUnderMouse(NULL),
m_entryUnderMouse(NULL),
m_bandCount(0) m_bandCount(0)
{ {
m_ptPrev.x = 0; m_ptPrev.x = 0;
@ -261,21 +263,33 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg)
child = WindowFromPoint(pt); child = WindowFromPoint(pt);
StackEntry * entry = NULL;
IsTrackedWindow(child, &entry);
if (m_hwndUnderMouse != child) if (m_hwndUnderMouse != child)
{ {
WCHAR cn[1024]; WCHAR cn[1024];
GetClassName(child, cn, 1023); GetClassName(child, cn, 1023);
DbgPrint("Mouse moved to %p (%S)\n", child, cn); 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); ScreenToClient(child, &pt);
iHitTestResult = SendMessageW(child, TB_HITTEST, 0, (LPARAM) &pt); iHitTestResult = SendMessageW(child, TB_HITTEST, 0, (LPARAM) &pt);
BOOL isTracking = entry->mb->_IsTracking();
if (iHitTestResult >= 0 && if (iHitTestResult >= 0 &&
SendMessage(child, WM_USER_ISTRACKEDITEM, iHitTestResult, 0) == S_FALSE) SendMessage(child, WM_USER_ISTRACKEDITEM, iHitTestResult, 0) == S_FALSE)
{ {
@ -283,16 +297,26 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg)
DisableMouseTrack(NULL, FALSE); DisableMouseTrack(NULL, FALSE);
if (m_current->type == TrackedMenuEntry) if (m_current->type == TrackedMenuEntry)
SendMessage(entry->hwnd, WM_CANCELMODE, 0, 0); SendMessage(entry->hwnd, WM_CANCELMODE, 0, 0);
PostMessage(child, WM_USER_CHANGETRACKEDITEM, iHitTestResult, iHitTestResult); PostMessage(child, WM_USER_CHANGETRACKEDITEM, iHitTestResult, isTracking);
return FALSE; return FALSE;
} }
}
if (m_current->type == MenuPopupEntry) if (m_hwndUnderMouse != child)
{
if (entry)
{ {
SetCapture(child); 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) 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; BOOL hoveringMenuBar = m_menuBar->mb->IsWindowOwner(child) == S_OK;
if (hoveringMenuBar) if (hoveringMenuBar)
{ {
HWND parent = GetAncestor(child, GA_ROOT);
m_menuBar->mb->_DisableMouseTrack(TRUE); m_menuBar->mb->_DisableMouseTrack(TRUE);
} }
} }
@ -352,18 +375,15 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
BOOL callNext = TRUE; BOOL callNext = TRUE;
MSG* msg = reinterpret_cast<MSG*>(lParam); MSG* msg = reinterpret_cast<MSG*>(lParam);
POINT pt = msg->pt; POINT pt = msg->pt;
switch (msg->message) switch (msg->message)
{ {
case WM_CLOSE:
break;
case WM_NCLBUTTONDOWN: case WM_NCLBUTTONDOWN:
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
if (m_current->type == MenuPopupEntry) if (m_current->type == MenuPopupEntry)
{ {
HWND child = WindowFromPoint(pt); HWND child = WindowFromPoint(pt);
if (IsTrackedWindow(child) != S_OK) if (IsTrackedWindow(child) != S_OK)
{ {
SetCapture(NULL); SetCapture(NULL);
@ -376,26 +396,29 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
break; break;
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
case WM_KEYDOWN: case WM_KEYDOWN:
DisableMouseTrack(m_current->hwnd, TRUE); if (m_current->type == MenuPopupEntry)
switch (msg->wParam)
{ {
case VK_MENU: DisableMouseTrack(m_current->hwnd, TRUE);
case VK_LMENU: switch (msg->wParam)
case VK_RMENU: {
m_current->mb->_MenuItemHotTrack(MPOS_FULLCANCEL); case VK_MENU:
break; case VK_LMENU:
case VK_LEFT: case VK_RMENU:
m_current->mb->_MenuItemHotTrack(MPOS_SELECTLEFT); m_current->mb->_MenuItemHotTrack(MPOS_FULLCANCEL);
break; break;
case VK_RIGHT: case VK_LEFT:
m_current->mb->_MenuItemHotTrack(MPOS_SELECTRIGHT); m_current->mb->_MenuItemHotTrack(MPOS_SELECTLEFT);
break; break;
case VK_UP: case VK_RIGHT:
m_current->mb->_MenuItemHotTrack(VK_UP); m_current->mb->_MenuItemHotTrack(MPOS_SELECTRIGHT);
break; break;
case VK_DOWN: case VK_UP:
m_current->mb->_MenuItemHotTrack(VK_DOWN); m_current->mb->_MenuItemHotTrack(VK_UP);
break; break;
case VK_DOWN:
m_current->mb->_MenuItemHotTrack(VK_DOWN);
break;
}
} }
break; break;
} }
@ -414,7 +437,7 @@ HRESULT CMenuFocusManager::PlaceHooks()
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 if (m_current->type == MenuPopupEntry) else
{ {
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);
@ -475,7 +498,7 @@ HRESULT CMenuFocusManager::UpdateFocus()
if (old && (!m_current || old->type != m_current->type)) 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); DisableMouseTrack(m_current->hwnd, FALSE);
} }

View file

@ -71,6 +71,7 @@ private:
HWND m_captureHwnd; HWND m_captureHwnd;
HWND m_hwndUnderMouse; HWND m_hwndUnderMouse;
StackEntry * m_entryUnderMouse;
// TODO: make dynamic // TODO: make dynamic
#define MAX_RECURSE 20 #define MAX_RECURSE 20

View file

@ -64,7 +64,8 @@ HRESULT CMenuToolbarBase::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
return OnCommand(reinterpret_cast<LPNMTOOLBAR>(hdr)->iItem, 0, theResult); return OnCommand(reinterpret_cast<LPNMTOOLBAR>(hdr)->iItem, 0, theResult);
case TBN_HOTITEMCHANGE: case TBN_HOTITEMCHANGE:
return OnHotItemChange(reinterpret_cast<LPNMTBHOTITEM>(hdr), theResult); //return OnHotItemChange(reinterpret_cast<LPNMTBHOTITEM>(hdr), theResult);
return S_OK;
case NM_RCLICK: case NM_RCLICK:
return OnContextMenu(reinterpret_cast<LPNMMOUSE>(hdr)); return OnContextMenu(reinterpret_cast<LPNMMOUSE>(hdr));
@ -100,6 +101,9 @@ HRESULT CMenuToolbarBase::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
case NM_TOOLTIPSCREATED: case NM_TOOLTIPSCREATED:
break; break;
// Unknown
case -714: return S_FALSE;
default: default:
DbgPrint("WM_NOTIFY unknown code %d, %d\n", hdr->code, hdr->idFrom); DbgPrint("WM_NOTIFY unknown code %d, %d\n", hdr->code, hdr->idFrom);
return S_OK; return S_OK;
@ -127,7 +131,7 @@ LRESULT CMenuToolbarBase::SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
return IsTrackedItem(wParam); return IsTrackedItem(wParam);
case WM_USER_CHANGETRACKEDITEM: case WM_USER_CHANGETRACKEDITEM:
m_SubclassOld(hWnd, uMsg, wParam, lParam); m_SubclassOld(hWnd, uMsg, wParam, lParam);
return ChangeTrackedItem(wParam); return ChangeTrackedItem(wParam, lParam);
case WM_COMMAND: case WM_COMMAND:
OnWinEvent(hWnd, uMsg, wParam, lParam, &lr); OnWinEvent(hWnd, uMsg, wParam, lParam, &lr);
@ -188,8 +192,8 @@ HRESULT CMenuToolbarBase::OnCustomDraw(LPNMTBCUSTOMDRAW cdraw, LRESULT * theResu
hdc = cdraw->nmcd.hdc; hdc = cdraw->nmcd.hdc;
// The item with an active submenu gets the CHECKED flag. // The item with an active submenu gets the CHECKED flag.
isHot = m_hotBar == this && cdraw->nmcd.dwItemSpec == m_hotItem; isHot = m_hotBar == this && (int)cdraw->nmcd.dwItemSpec == m_hotItem;
isPopup = m_popupBar == this && cdraw->nmcd.dwItemSpec == m_popupItem; isPopup = m_popupBar == this && (int)cdraw->nmcd.dwItemSpec == m_popupItem;
if (m_initFlags & SMINIT_VERTICAL) if (m_initFlags & SMINIT_VERTICAL)
{ {
@ -621,8 +625,6 @@ HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DW
} }
else if (m_isTracking) else if (m_isTracking)
{ {
m_menuBand->_KillPopupTimers();
PopupItem(m_hotItem); PopupItem(m_hotItem);
} }
} }
@ -684,14 +686,14 @@ HRESULT CMenuToolbarBase::IsTrackedItem(INT index)
return S_FALSE; return S_FALSE;
} }
HRESULT CMenuToolbarBase::ChangeTrackedItem(INT index) HRESULT CMenuToolbarBase::ChangeTrackedItem(INT index, BOOL wasTracking)
{ {
TBBUTTON btn; TBBUTTON btn;
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("Changing tracked item to %d...\n", index); DbgPrint("Changing tracked item to %d...\n", index);
m_isTracking = TRUE; m_isTracking = wasTracking;
m_menuBand->_ChangeHotItem(this, btn.idCommand, HICF_MOUSE); m_menuBand->_ChangeHotItem(this, btn.idCommand, HICF_MOUSE);
return S_OK; return S_OK;

View file

@ -77,7 +77,7 @@ public:
HRESULT OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * theResult); HRESULT OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * theResult);
HRESULT IsTrackedItem(INT index); HRESULT IsTrackedItem(INT index);
HRESULT ChangeTrackedItem(INT index); HRESULT ChangeTrackedItem(INT index, BOOL wasTracking);
HRESULT GetIdealSize(SIZE& size); HRESULT GetIdealSize(SIZE& size);
HRESULT SetPosSize(int x, int y, int cx, int cy); HRESULT SetPosSize(int x, int y, int cx, int cy);

View file

@ -72,7 +72,7 @@ Win32DbgPrint(const char *filename, int line, const char *lpFormat, ...)
else else
fname++; 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); va_start(vl, lpFormat);
uRet = (ULONG) vsprintf(szMsgStart, lpFormat, vl); uRet = (ULONG) vsprintf(szMsgStart, lpFormat, vl);