mirror of
https://github.com/reactos/reactos.git
synced 2025-06-20 07:36:05 +00:00
[RSHELL]
* Some code improvements, refactoring, and commenting. * Using alternative method of handling hot-tracking, which does not break in win2003. CORE-7586 svn path=/branches/shell-experiments/; revision=62681
This commit is contained in:
parent
c46d671641
commit
c21f759be0
5 changed files with 302 additions and 310 deletions
|
@ -260,26 +260,26 @@ HRESULT STDMETHODCALLTYPE CMenuBand::GetWindow(
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CMenuBand::OnPosRectChangeDB(RECT *prc)
|
HRESULT STDMETHODCALLTYPE CMenuBand::OnPosRectChangeDB(RECT *prc)
|
||||||
{
|
{
|
||||||
SIZE sizeStatic = { 0 };
|
SIZE maxStatic = { 0 };
|
||||||
SIZE sizeShlFld = { 0 };
|
SIZE maxShlFld = { 0 };
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
if (m_staticToolbar != NULL)
|
if (m_staticToolbar != NULL)
|
||||||
hr = m_staticToolbar->GetIdealSize(sizeStatic);
|
hr = m_staticToolbar->GetSizes(NULL, &maxStatic, NULL);
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
if (m_SFToolbar != NULL)
|
if (m_SFToolbar != NULL)
|
||||||
hr = m_SFToolbar->GetIdealSize(sizeShlFld);
|
hr = m_SFToolbar->GetSizes(NULL, &maxShlFld, NULL);
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
if (m_staticToolbar == NULL && m_SFToolbar == NULL)
|
if (m_staticToolbar == NULL && m_SFToolbar == NULL)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
int sy = min(prc->bottom - prc->top, sizeStatic.cy + sizeShlFld.cy);
|
int sy = min(prc->bottom - prc->top, maxStatic.cy + maxShlFld.cy);
|
||||||
|
|
||||||
int syStatic = sizeStatic.cy;
|
int syStatic = maxStatic.cy;
|
||||||
int syShlFld = sy - syStatic;
|
int syShlFld = sy - syStatic;
|
||||||
|
|
||||||
if (m_SFToolbar)
|
if (m_SFToolbar)
|
||||||
|
@ -306,28 +306,46 @@ HRESULT STDMETHODCALLTYPE CMenuBand::GetBandInfo(
|
||||||
DWORD dwViewMode,
|
DWORD dwViewMode,
|
||||||
DESKBANDINFO *pdbi)
|
DESKBANDINFO *pdbi)
|
||||||
{
|
{
|
||||||
SIZE sizeStatic = { 0 };
|
SIZE minStatic = { 0 };
|
||||||
SIZE sizeShlFld = { 0 };
|
SIZE minShlFld = { 0 };
|
||||||
|
SIZE maxStatic = { 0 };
|
||||||
|
SIZE maxShlFld = { 0 };
|
||||||
|
SIZE intStatic = { 0 };
|
||||||
|
SIZE intShlFld = { 0 };
|
||||||
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
if (m_staticToolbar != NULL)
|
if (m_staticToolbar != NULL)
|
||||||
hr = m_staticToolbar->GetIdealSize(sizeStatic);
|
hr = m_staticToolbar->GetSizes(&minStatic, &maxStatic, &intStatic);
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
if (m_SFToolbar != NULL)
|
if (m_SFToolbar != NULL)
|
||||||
hr = m_SFToolbar->GetIdealSize(sizeShlFld);
|
hr = m_SFToolbar->GetSizes(&minShlFld, &maxShlFld, &intShlFld);
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
if (m_staticToolbar == NULL && m_SFToolbar == NULL)
|
if (m_staticToolbar == NULL && m_SFToolbar == NULL)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
pdbi->ptMinSize.x = max(sizeStatic.cx, sizeShlFld.cx) + 20;
|
if (m_dwFlags & SMINIT_VERTICAL)
|
||||||
pdbi->ptMinSize.y = sizeStatic.cy + sizeShlFld.cy;
|
{
|
||||||
pdbi->ptMaxSize.x = max(sizeStatic.cx, sizeShlFld.cx) + 20;
|
pdbi->ptMinSize.x = max(minStatic.cx, minStatic.cx) + 20;
|
||||||
pdbi->ptMaxSize.y = sizeStatic.cy + sizeShlFld.cy;
|
pdbi->ptMinSize.y = minStatic.cy + minStatic.cy;
|
||||||
|
pdbi->ptMaxSize.x = max(maxStatic.cx, maxShlFld.cx) + 20;
|
||||||
|
pdbi->ptMaxSize.y = maxStatic.cy + maxShlFld.cy;
|
||||||
|
pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pdbi->ptMinSize.x = minStatic.cx + minStatic.cx;
|
||||||
|
pdbi->ptMinSize.y = max(minStatic.cy, minStatic.cy);
|
||||||
|
pdbi->ptMaxSize.x = maxStatic.cx + maxShlFld.cx;
|
||||||
|
pdbi->ptMaxSize.y = max(maxStatic.cy, maxShlFld.cy);
|
||||||
|
}
|
||||||
|
pdbi->ptIntegral.x = max(intStatic.cx, intStatic.cx);
|
||||||
|
pdbi->ptIntegral.y = max(intStatic.cy, intShlFld.cy);
|
||||||
|
pdbi->ptActual = pdbi->ptMinSize;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -652,12 +670,10 @@ HRESULT CMenuBand::_CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam, UINT id, LPI
|
||||||
smData.uId = id;
|
smData.uId = id;
|
||||||
smData.uIdParent = m_uId;
|
smData.uIdParent = m_uId;
|
||||||
smData.uIdAncestor = m_uIdAncestor;
|
smData.uIdAncestor = m_uIdAncestor;
|
||||||
smData.hwnd = hwnd;
|
|
||||||
smData.pidlItem = pidl;
|
smData.pidlItem = pidl;
|
||||||
if (m_staticToolbar)
|
smData.hwnd = hwnd;
|
||||||
{
|
if (m_hmenu)
|
||||||
smData.hmenu = m_hmenu;
|
smData.hmenu = m_hmenu;
|
||||||
}
|
|
||||||
smData.pvUserData = NULL;
|
smData.pvUserData = NULL;
|
||||||
if (m_SFToolbar)
|
if (m_SFToolbar)
|
||||||
m_SFToolbar->GetShellFolder(NULL, &smData.pidlFolder, IID_PPV_ARG(IShellFolder, &smData.psf));
|
m_SFToolbar->GetShellFolder(NULL, &smData.pidlFolder, IID_PPV_ARG(IShellFolder, &smData.psf));
|
||||||
|
@ -668,7 +684,7 @@ HRESULT CMenuBand::_CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam, UINT id, LPI
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CMenuBand::_TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, RECT& rcExclude)
|
HRESULT CMenuBand::_TrackSubMenu(HMENU popup, INT x, INT y, RECT& rcExclude)
|
||||||
{
|
{
|
||||||
TPMPARAMS params = { sizeof(TPMPARAMS), rcExclude };
|
TPMPARAMS params = { sizeof(TPMPARAMS), rcExclude };
|
||||||
|
|
||||||
|
@ -690,6 +706,41 @@ HRESULT CMenuBand::_TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, R
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT CMenuBand::_TrackContextMenu(IContextMenu * contextMenu, INT x, INT y)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
UINT uCommand;
|
||||||
|
HMENU popup = CreatePopupMenu();
|
||||||
|
|
||||||
|
if (popup == NULL)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
hr = contextMenu->QueryContextMenu(popup, 0, 0, UINT_MAX, CMF_NORMAL);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
{
|
||||||
|
DestroyMenu(popup);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND hwnd = m_menuOwner ? m_menuOwner : m_topLevelWindow;
|
||||||
|
|
||||||
|
m_focusManager->PushTrackedPopup(popup);
|
||||||
|
uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, x, y, m_menuOwner, NULL);
|
||||||
|
m_focusManager->PopTrackedPopup(popup);
|
||||||
|
|
||||||
|
if (uCommand == 0)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
CMINVOKECOMMANDINFO cmi = { 0 };
|
||||||
|
cmi.cbSize = sizeof(cmi);
|
||||||
|
cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
|
||||||
|
cmi.hwnd = hwnd;
|
||||||
|
hr = contextMenu->InvokeCommand(&cmi);
|
||||||
|
|
||||||
|
DestroyMenu(popup);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT CMenuBand::_GetTopLevelWindow(HWND*topLevel)
|
HRESULT CMenuBand::_GetTopLevelWindow(HWND*topLevel)
|
||||||
{
|
{
|
||||||
*topLevel = m_topLevelWindow;
|
*topLevel = m_topLevelWindow;
|
||||||
|
@ -728,119 +779,91 @@ HRESULT CMenuBand::_ChangePopupItem(CMenuToolbarBase * tb, INT id)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT CMenuBand::_KeyboardItemChange(DWORD change)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
CMenuToolbarBase *tb = m_hotBar;
|
||||||
|
|
||||||
|
if (!tb)
|
||||||
|
{
|
||||||
|
// If no hot item was selected
|
||||||
|
// choose the first toolbar (prefer shell-folder, which will be positionedat the top)
|
||||||
|
|
||||||
|
if (m_SFToolbar)
|
||||||
|
tb = m_SFToolbar;
|
||||||
|
else
|
||||||
|
tb = m_staticToolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask the first toolbar to change
|
||||||
|
hr = tb->KeyboardItemChange(change);
|
||||||
|
|
||||||
|
if (hr != S_FALSE)
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
// Select the second toolbar based on the first
|
||||||
|
if (tb == m_SFToolbar)
|
||||||
|
tb = m_staticToolbar;
|
||||||
|
else
|
||||||
|
tb = m_SFToolbar;
|
||||||
|
|
||||||
|
if (!tb)
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
// Ask the second toolbar to change
|
||||||
|
return tb->KeyboardItemChange(change == VK_DOWN ? VK_END : VK_HOME);
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
|
HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (!(m_dwFlags & SMINIT_VERTICAL))
|
|
||||||
|
if (m_dwFlags & SMINIT_VERTICAL)
|
||||||
{
|
{
|
||||||
if (changeType == MPOS_SELECTRIGHT)
|
switch (changeType)
|
||||||
{
|
{
|
||||||
SendMessageW(m_menuOwner, WM_CANCELMODE, 0, 0);
|
case VK_UP:
|
||||||
if (m_SFToolbar && (m_hotBar == m_SFToolbar || m_hotBar == NULL))
|
case VK_DOWN:
|
||||||
{
|
return _KeyboardItemChange(changeType);
|
||||||
DbgPrint("SF Toolbars in Horizontal menus is not implemented.\n");
|
|
||||||
return S_FALSE;
|
// TODO: Left/Right across multi-column menus, if they ever work.
|
||||||
}
|
case VK_LEFT:
|
||||||
else if (m_staticToolbar && m_hotBar == m_staticToolbar)
|
changeType = MPOS_SELECTLEFT;
|
||||||
{
|
break;
|
||||||
hr = m_staticToolbar->KeyboardItemChange(VK_DOWN);
|
case VK_RIGHT:
|
||||||
if (hr == S_FALSE)
|
changeType = MPOS_SELECTRIGHT;
|
||||||
{
|
break;
|
||||||
if (m_SFToolbar)
|
}
|
||||||
return m_SFToolbar->KeyboardItemChange(VK_HOME);
|
}
|
||||||
else
|
else
|
||||||
return m_staticToolbar->KeyboardItemChange(VK_HOME);
|
{
|
||||||
}
|
// In horizontal menubars, left/right are equivalent to vertical's up/down
|
||||||
|
switch(changeType)
|
||||||
|
{
|
||||||
|
case VK_LEFT:
|
||||||
|
hr = _KeyboardItemChange(VK_UP);
|
||||||
|
if (hr != S_FALSE)
|
||||||
return hr;
|
return hr;
|
||||||
}
|
case VK_RIGHT:
|
||||||
}
|
hr = _KeyboardItemChange(VK_DOWN);
|
||||||
else if (changeType == MPOS_SELECTLEFT)
|
if (hr != S_FALSE)
|
||||||
{
|
|
||||||
SendMessageW(m_menuOwner, WM_CANCELMODE, 0, 0);
|
|
||||||
if (m_staticToolbar && (m_hotBar == m_staticToolbar || m_hotBar == NULL))
|
|
||||||
{
|
|
||||||
hr = m_staticToolbar->KeyboardItemChange(VK_UP);
|
|
||||||
if (hr == S_FALSE)
|
|
||||||
{
|
|
||||||
if (m_SFToolbar)
|
|
||||||
return m_SFToolbar->KeyboardItemChange(VK_END);
|
|
||||||
else
|
|
||||||
return m_staticToolbar->KeyboardItemChange(VK_END);
|
|
||||||
}
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
|
||||||
else if (m_SFToolbar && m_hotBar == m_SFToolbar)
|
|
||||||
{
|
|
||||||
DbgPrint("SF Toolbars in Horizontal menus is not implemented.\n");
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (changeType == VK_DOWN)
|
|
||||||
|
switch (changeType)
|
||||||
{
|
{
|
||||||
if (m_SFToolbar && (m_hotBar == m_SFToolbar || m_hotBar == NULL))
|
case MPOS_SELECTLEFT:
|
||||||
{
|
|
||||||
hr = m_SFToolbar->KeyboardItemChange(VK_DOWN);
|
|
||||||
if (hr == S_FALSE)
|
|
||||||
{
|
|
||||||
if (m_staticToolbar)
|
|
||||||
return m_staticToolbar->KeyboardItemChange(VK_HOME);
|
|
||||||
else
|
|
||||||
return m_SFToolbar->KeyboardItemChange(VK_HOME);
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
else if (m_staticToolbar && m_hotBar == m_staticToolbar)
|
|
||||||
{
|
|
||||||
hr = m_staticToolbar->KeyboardItemChange(VK_DOWN);
|
|
||||||
if (hr == S_FALSE)
|
|
||||||
{
|
|
||||||
if (m_SFToolbar)
|
|
||||||
return m_SFToolbar->KeyboardItemChange(VK_HOME);
|
|
||||||
else
|
|
||||||
return m_staticToolbar->KeyboardItemChange(VK_HOME);
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (changeType == VK_UP)
|
|
||||||
{
|
|
||||||
if (m_staticToolbar && (m_hotBar == m_staticToolbar || m_hotBar == NULL))
|
|
||||||
{
|
|
||||||
hr = m_staticToolbar->KeyboardItemChange(VK_UP);
|
|
||||||
if (hr == S_FALSE)
|
|
||||||
{
|
|
||||||
if (m_SFToolbar)
|
|
||||||
return m_SFToolbar->KeyboardItemChange(VK_END);
|
|
||||||
else
|
|
||||||
return m_staticToolbar->KeyboardItemChange(VK_END);
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
else if (m_SFToolbar && m_hotBar == m_SFToolbar)
|
|
||||||
{
|
|
||||||
hr = m_SFToolbar->KeyboardItemChange(VK_UP);
|
|
||||||
if (hr == S_FALSE)
|
|
||||||
{
|
|
||||||
if (m_staticToolbar)
|
|
||||||
return m_staticToolbar->KeyboardItemChange(VK_END);
|
|
||||||
else
|
|
||||||
return m_SFToolbar->KeyboardItemChange(VK_END);
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (changeType == MPOS_SELECTLEFT)
|
|
||||||
{
|
|
||||||
if (m_subMenuChild)
|
|
||||||
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);
|
||||||
}
|
|
||||||
else if (changeType == MPOS_SELECTRIGHT)
|
case MPOS_SELECTRIGHT:
|
||||||
{
|
|
||||||
if (m_hotBar && m_hotItem >= 0)
|
if (m_hotBar && m_hotItem >= 0)
|
||||||
{
|
{
|
||||||
if (m_hotBar->PopupItem(m_hotItem) == S_OK)
|
if (m_hotBar->PopupItem(m_hotItem) == S_OK)
|
||||||
|
@ -848,14 +871,14 @@ HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
|
||||||
}
|
}
|
||||||
if (!m_subMenuParent)
|
if (!m_subMenuParent)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
return m_subMenuParent->OnSelect(changeType);
|
return m_subMenuParent->OnSelect(MPOS_SELECTRIGHT);
|
||||||
}
|
|
||||||
else
|
default:
|
||||||
{
|
|
||||||
if (!m_subMenuParent)
|
if (!m_subMenuParent)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
return m_subMenuParent->OnSelect(changeType);
|
return m_subMenuParent->OnSelect(changeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,8 +891,60 @@ HRESULT CMenuBand::_CancelCurrentPopup()
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CMenuBand::_OnPopupSubMenu(IMenuPopup * popup, POINTL * pAt, RECTL * pExclude)
|
HRESULT CMenuBand::_OnPopupSubMenu(IShellMenu * childShellMenu, POINTL * pAt, RECTL * pExclude)
|
||||||
{
|
{
|
||||||
|
HRESULT hr = 0;
|
||||||
|
IBandSite* pBandSite;
|
||||||
|
IDeskBar* pDeskBar;
|
||||||
|
|
||||||
|
// Create the necessary objects
|
||||||
|
|
||||||
|
#if USE_SYSTEM_MENUSITE
|
||||||
|
hr = CoCreateInstance(CLSID_MenuBandSite,
|
||||||
|
NULL,
|
||||||
|
CLSCTX_INPROC_SERVER,
|
||||||
|
IID_PPV_ARG(IBandSite, &pBandSite));
|
||||||
|
#else
|
||||||
|
hr = CMenuSite_Constructor(IID_PPV_ARG(IBandSite, &pBandSite));
|
||||||
|
#endif
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
#if WRAP_MENUSITE
|
||||||
|
hr = CMenuSite_Wrapper(pBandSite, IID_PPV_ARG(IBandSite, &pBandSite));
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_SYSTEM_MENUDESKBAR
|
||||||
|
hr = CoCreateInstance(CLSID_MenuDeskBar,
|
||||||
|
NULL,
|
||||||
|
CLSCTX_INPROC_SERVER,
|
||||||
|
IID_PPV_ARG(IDeskBar, &pDeskBar));
|
||||||
|
#else
|
||||||
|
hr = CMenuDeskBar_Constructor(IID_PPV_ARG(IDeskBar, &pDeskBar));
|
||||||
|
#endif
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
#if WRAP_MENUDESKBAR
|
||||||
|
hr = CMenuDeskBar_Wrapper(pDeskBar, IID_PPV_ARG(IDeskBar, &pDeskBar));
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hr = pDeskBar->SetClient(pBandSite);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
hr = pBandSite->AddBand(childShellMenu);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
//
|
||||||
|
CComPtr<IMenuPopup> popup;
|
||||||
|
hr = pDeskBar->QueryInterface(IID_PPV_ARG(IMenuPopup, &popup));
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
m_subMenuChild = popup;
|
m_subMenuChild = popup;
|
||||||
|
|
||||||
if (m_subMenuParent)
|
if (m_subMenuParent)
|
||||||
|
|
|
@ -175,13 +175,14 @@ public:
|
||||||
|
|
||||||
HRESULT _CallCBWithItemId(UINT Id, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
HRESULT _CallCBWithItemId(UINT Id, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
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 _TrackSubMenu(HMENU popup, INT x, INT y, RECT& rcExclude);
|
||||||
|
HRESULT _TrackContextMenu(IContextMenu * popup, INT x, INT y);
|
||||||
HRESULT _GetTopLevelWindow(HWND*topLevel);
|
HRESULT _GetTopLevelWindow(HWND*topLevel);
|
||||||
HRESULT _ChangeHotItem(CMenuToolbarBase * tb, INT id, DWORD dwFlags);
|
HRESULT _ChangeHotItem(CMenuToolbarBase * tb, INT id, DWORD dwFlags);
|
||||||
HRESULT _ChangePopupItem(CMenuToolbarBase * tb, INT id);
|
HRESULT _ChangePopupItem(CMenuToolbarBase * tb, INT id);
|
||||||
HRESULT _MenuItemHotTrack(DWORD changeType);
|
HRESULT _MenuItemHotTrack(DWORD changeType);
|
||||||
HRESULT _CancelCurrentPopup();
|
HRESULT _CancelCurrentPopup();
|
||||||
HRESULT _OnPopupSubMenu(IMenuPopup * popup, POINTL * pAt, RECTL * pExclude);
|
HRESULT _OnPopupSubMenu(IShellMenu * childShellMenu, 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);
|
||||||
|
@ -195,5 +196,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
HRESULT _KeyboardItemChange(DWORD change);
|
||||||
HRESULT _CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam, UINT id = 0, LPITEMIDLIST pidl = NULL);
|
HRESULT _CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam, UINT id = 0, LPITEMIDLIST pidl = NULL);
|
||||||
};
|
};
|
||||||
|
|
|
@ -261,7 +261,7 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg)
|
||||||
|
|
||||||
// Don't do anything if another window is capturing the mouse.
|
// Don't do anything if another window is capturing the mouse.
|
||||||
HWND cCapture = ::GetCapture();
|
HWND cCapture = ::GetCapture();
|
||||||
if (cCapture && cCapture != m_captureHwnd)
|
if (cCapture && cCapture != m_captureHwnd && m_current->type != TrackedMenuEntry)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
m_ptPrev = pt;
|
m_ptPrev = pt;
|
||||||
|
@ -283,7 +283,8 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg)
|
||||||
{
|
{
|
||||||
m_entryUnderMouse->mb->_ChangeHotItem(NULL, -1, HICF_MOUSE);
|
m_entryUnderMouse->mb->_ChangeHotItem(NULL, -1, HICF_MOUSE);
|
||||||
}
|
}
|
||||||
SetCapture(NULL);
|
if (cCapture == m_captureHwnd)
|
||||||
|
SetCapture(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -303,7 +304,8 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg)
|
||||||
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, isTracking);
|
PostMessage(child, WM_USER_CHANGETRACKEDITEM, iHitTestResult, isTracking);
|
||||||
return FALSE;
|
if (m_current->type == TrackedMenuEntry)
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,10 +313,10 @@ LRESULT CMenuFocusManager::ProcessMouseMove(MSG* msg)
|
||||||
{
|
{
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
SetCapture(child);
|
|
||||||
|
|
||||||
if (m_current->type == MenuPopupEntry)
|
if (m_current->type == MenuPopupEntry)
|
||||||
{
|
{
|
||||||
|
//SetCapture(child);
|
||||||
|
|
||||||
ScreenToClient(child, &pt2);
|
ScreenToClient(child, &pt2);
|
||||||
SendMessage(child, WM_MOUSEMOVE, msg->wParam, MAKELPARAM(pt2.x, pt2.y));
|
SendMessage(child, WM_MOUSEMOVE, msg->wParam, MAKELPARAM(pt2.x, pt2.y));
|
||||||
}
|
}
|
||||||
|
@ -399,6 +401,10 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
callNext = ProcessMouseMove(msg);
|
callNext = ProcessMouseMove(msg);
|
||||||
break;
|
break;
|
||||||
|
case WM_MOUSELEAVE:
|
||||||
|
callNext = ProcessMouseMove(msg);
|
||||||
|
//callNext = ProcessMouseLeave(msg);
|
||||||
|
break;
|
||||||
case WM_SYSKEYDOWN:
|
case WM_SYSKEYDOWN:
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
if (m_current->type == MenuPopupEntry)
|
if (m_current->type == MenuPopupEntry)
|
||||||
|
@ -406,16 +412,17 @@ LRESULT CMenuFocusManager::GetMsgHook(INT nCode, WPARAM wParam, LPARAM lParam)
|
||||||
DisableMouseTrack(m_current->hwnd, TRUE);
|
DisableMouseTrack(m_current->hwnd, TRUE);
|
||||||
switch (msg->wParam)
|
switch (msg->wParam)
|
||||||
{
|
{
|
||||||
|
case VK_ESCAPE:
|
||||||
case VK_MENU:
|
case VK_MENU:
|
||||||
case VK_LMENU:
|
case VK_LMENU:
|
||||||
case VK_RMENU:
|
case VK_RMENU:
|
||||||
m_current->mb->_MenuItemHotTrack(MPOS_FULLCANCEL);
|
m_current->mb->_MenuItemHotTrack(MPOS_FULLCANCEL);
|
||||||
break;
|
break;
|
||||||
case VK_LEFT:
|
case VK_LEFT:
|
||||||
m_current->mb->_MenuItemHotTrack(MPOS_SELECTLEFT);
|
m_current->mb->_MenuItemHotTrack(VK_LEFT);
|
||||||
break;
|
break;
|
||||||
case VK_RIGHT:
|
case VK_RIGHT:
|
||||||
m_current->mb->_MenuItemHotTrack(MPOS_SELECTRIGHT);
|
m_current->mb->_MenuItemHotTrack(VK_RIGHT);
|
||||||
break;
|
break;
|
||||||
case VK_UP:
|
case VK_UP:
|
||||||
m_current->mb->_MenuItemHotTrack(VK_UP);
|
m_current->mb->_MenuItemHotTrack(VK_UP);
|
||||||
|
|
|
@ -159,7 +159,7 @@ HRESULT CMenuToolbarBase::DisableMouseTrack(BOOL bDisable)
|
||||||
HRESULT CMenuToolbarBase::OnPagerCalcSize(LPNMPGCALCSIZE csize)
|
HRESULT CMenuToolbarBase::OnPagerCalcSize(LPNMPGCALCSIZE csize)
|
||||||
{
|
{
|
||||||
SIZE tbs;
|
SIZE tbs;
|
||||||
GetIdealSize(tbs);
|
GetSizes(NULL, &tbs, NULL);
|
||||||
if (csize->dwFlag == PGF_CALCHEIGHT)
|
if (csize->dwFlag == PGF_CALCHEIGHT)
|
||||||
{
|
{
|
||||||
csize->iHeight = tbs.cy;
|
csize->iHeight = tbs.cy;
|
||||||
|
@ -284,12 +284,16 @@ CMenuToolbarBase::CMenuToolbarBase(CMenuBand *menuBand, BOOL usePager) :
|
||||||
m_menuBand(menuBand),
|
m_menuBand(menuBand),
|
||||||
m_hwndToolbar(NULL),
|
m_hwndToolbar(NULL),
|
||||||
m_dwMenuFlags(0),
|
m_dwMenuFlags(0),
|
||||||
m_hasIdealSize(FALSE),
|
m_hasSizes(FALSE),
|
||||||
m_usePager(usePager),
|
m_usePager(usePager),
|
||||||
m_hotItem(-1),
|
m_hotItem(-1),
|
||||||
m_popupItem(-1),
|
m_popupItem(-1),
|
||||||
m_isTracking(FALSE)
|
m_isTrackingPopup(FALSE)
|
||||||
{
|
{
|
||||||
|
m_idealSize.cx = 0;
|
||||||
|
m_idealSize.cy = 0;
|
||||||
|
m_itemSize.cx = 0;
|
||||||
|
m_itemSize.cy = 0;
|
||||||
m_marlett = CreateFont(
|
m_marlett = CreateFont(
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET,
|
0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET,
|
||||||
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||||
|
@ -452,18 +456,38 @@ HRESULT CMenuToolbarBase::CreateToolbar(HWND hwndParent, DWORD dwFlags)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CMenuToolbarBase::GetIdealSize(SIZE& size)
|
HRESULT CMenuToolbarBase::GetSizes(SIZE* pMinSize, SIZE* pMaxSize, SIZE* pIntegralSize)
|
||||||
{
|
{
|
||||||
size.cx = size.cy = 0;
|
if (pMinSize)
|
||||||
|
*pMinSize = m_idealSize;
|
||||||
|
if (pMaxSize)
|
||||||
|
*pMaxSize = m_idealSize;
|
||||||
|
if (pIntegralSize)
|
||||||
|
*pIntegralSize = m_itemSize;
|
||||||
|
|
||||||
|
if (m_hasSizes)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
if (m_hwndToolbar && !m_hasIdealSize)
|
if (!m_hwndToolbar)
|
||||||
{
|
return S_OK;
|
||||||
SendMessageW(m_hwndToolbar, TB_AUTOSIZE, 0, 0);
|
|
||||||
SendMessageW(m_hwndToolbar, TB_GETMAXSIZE, 0, reinterpret_cast<LPARAM>(&m_idealSize));
|
|
||||||
m_hasIdealSize = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = m_idealSize;
|
// Obtain the ideal size, to be used as min and max
|
||||||
|
SendMessageW(m_hwndToolbar, TB_AUTOSIZE, 0, 0);
|
||||||
|
SendMessageW(m_hwndToolbar, TB_GETMAXSIZE, 0, reinterpret_cast<LPARAM>(&m_idealSize));
|
||||||
|
SendMessageW(m_hwndToolbar, TB_GETIDEALSIZE, (m_initFlags & SMINIT_VERTICAL) != 0, reinterpret_cast<LPARAM>(&m_idealSize));
|
||||||
|
|
||||||
|
// Obtain the button size, to be used as the integral size
|
||||||
|
DWORD size = SendMessageW(m_hwndToolbar, TB_GETBUTTONSIZE, 0, 0);
|
||||||
|
m_itemSize.cx = GET_X_LPARAM(size);
|
||||||
|
m_itemSize.cy = GET_Y_LPARAM(size);
|
||||||
|
m_hasSizes = TRUE;
|
||||||
|
|
||||||
|
if (pMinSize)
|
||||||
|
*pMinSize = m_idealSize;
|
||||||
|
if (pMaxSize)
|
||||||
|
*pMaxSize = m_idealSize;
|
||||||
|
if (pIntegralSize)
|
||||||
|
*pIntegralSize = m_itemSize;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -560,46 +584,21 @@ HRESULT CMenuToolbarBase::KillPopupTimer()
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CMenuToolbarBase::OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * theResult)
|
HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DWORD dwFlags)
|
||||||
{
|
{
|
||||||
|
// Ignore the change if it already matches the stored info
|
||||||
|
if (m_hotBar == toolbar && m_hotItem == item)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
// Prevent a change of hot item if the change was triggered by the mouse,
|
// Prevent a change of hot item if the change was triggered by the mouse,
|
||||||
// and mouse tracking is disabled.
|
// and mouse tracking is disabled.
|
||||||
if (m_disableMouseTrack && hot->dwFlags & HICF_MOUSE)
|
if (m_disableMouseTrack && dwFlags & HICF_MOUSE)
|
||||||
{
|
{
|
||||||
*theResult = 1;
|
|
||||||
DbgPrint("Hot item change prevented by DisableMouseTrack\n");
|
DbgPrint("Hot item change prevented by DisableMouseTrack\n");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = S_OK;
|
// Notify the toolbar if the hot-tracking left this toolbar
|
||||||
if (hot->dwFlags & HICF_LEAVING)
|
|
||||||
{
|
|
||||||
// Only notify of LEAVING if this was the hot toolbar.
|
|
||||||
if (m_hotBar == this)
|
|
||||||
{
|
|
||||||
DbgPrint("The hot bar is now cold.\n");
|
|
||||||
hr = m_menuBand->_ChangeHotItem(NULL, -1, hot->dwFlags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hr = m_menuBand->_ChangeHotItem(this, hot->idNew, hot->dwFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
// Reuse S_OK/S_FALSE as Continue/Cancel
|
|
||||||
*theResult = hr;
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DWORD dwFlags)
|
|
||||||
{
|
|
||||||
if (m_hotBar == toolbar && m_hotItem == item)
|
|
||||||
return S_FALSE;
|
|
||||||
|
|
||||||
if (m_hotBar == this && toolbar != this)
|
if (m_hotBar == this && toolbar != this)
|
||||||
{
|
{
|
||||||
SendMessage(m_hwndToolbar, TB_SETHOTITEM, (WPARAM)-1, 0);
|
SendMessage(m_hwndToolbar, TB_SETHOTITEM, (WPARAM)-1, 0);
|
||||||
|
@ -623,8 +622,9 @@ HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DW
|
||||||
m_timerEnabled = TRUE;
|
m_timerEnabled = TRUE;
|
||||||
DbgPrint("SetTimer called with m_hotItem=%d\n", m_hotItem);
|
DbgPrint("SetTimer called with m_hotItem=%d\n", m_hotItem);
|
||||||
}
|
}
|
||||||
else if (m_isTracking)
|
else if (m_isTrackingPopup)
|
||||||
{
|
{
|
||||||
|
// If the menubar has an open submenu, switch to the new item's submenu immediately
|
||||||
PopupItem(m_hotItem);
|
PopupItem(m_hotItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,13 +646,15 @@ HRESULT CMenuToolbarBase::ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DW
|
||||||
|
|
||||||
HRESULT CMenuToolbarBase::ChangePopupItem(CMenuToolbarBase * toolbar, INT item)
|
HRESULT CMenuToolbarBase::ChangePopupItem(CMenuToolbarBase * toolbar, INT item)
|
||||||
{
|
{
|
||||||
|
// Ignore the change if it already matches the stored info
|
||||||
if (m_popupBar == toolbar && m_popupItem == item)
|
if (m_popupBar == toolbar && m_popupItem == item)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
|
// Notify the toolbar if the popup-tracking this toolbar
|
||||||
if (m_popupBar == this && toolbar != this)
|
if (m_popupBar == this && toolbar != this)
|
||||||
{
|
{
|
||||||
SendMessage(m_hwndToolbar, TB_CHECKBUTTON, m_popupItem, FALSE);
|
SendMessage(m_hwndToolbar, TB_CHECKBUTTON, m_popupItem, FALSE);
|
||||||
m_isTracking = FALSE;
|
m_isTrackingPopup = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_popupBar = toolbar;
|
m_popupBar = toolbar;
|
||||||
|
@ -693,7 +695,7 @@ HRESULT CMenuToolbarBase::ChangeTrackedItem(INT index, BOOL wasTracking)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
DbgPrint("Changing tracked item to %d...\n", index);
|
DbgPrint("Changing tracked item to %d...\n", index);
|
||||||
m_isTracking = wasTracking;
|
m_isTrackingPopup = wasTracking;
|
||||||
m_menuBand->_ChangeHotItem(this, btn.idCommand, HICF_MOUSE);
|
m_menuBand->_ChangeHotItem(this, btn.idCommand, HICF_MOUSE);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -701,10 +703,7 @@ HRESULT CMenuToolbarBase::ChangeTrackedItem(INT index, BOOL wasTracking)
|
||||||
|
|
||||||
HRESULT CMenuToolbarBase::PopupSubMenu(UINT iItem, UINT index, IShellMenu* childShellMenu)
|
HRESULT CMenuToolbarBase::PopupSubMenu(UINT iItem, UINT index, IShellMenu* childShellMenu)
|
||||||
{
|
{
|
||||||
IBandSite* pBandSite;
|
// Calculate the submenu position and exclude area
|
||||||
IDeskBar* pDeskBar;
|
|
||||||
|
|
||||||
HRESULT hr = 0;
|
|
||||||
RECT rc = { 0 };
|
RECT rc = { 0 };
|
||||||
RECT rcx = { 0 };
|
RECT rcx = { 0 };
|
||||||
|
|
||||||
|
@ -732,81 +731,31 @@ HRESULT CMenuToolbarBase::PopupSubMenu(UINT iItem, UINT index, IShellMenu* child
|
||||||
pt.y = a.y - 3;
|
pt.y = a.y - 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SYSTEM_MENUSITE
|
// Display the submenu
|
||||||
hr = CoCreateInstance(CLSID_MenuBandSite,
|
m_isTrackingPopup = TRUE;
|
||||||
NULL,
|
|
||||||
CLSCTX_INPROC_SERVER,
|
|
||||||
IID_PPV_ARG(IBandSite, &pBandSite));
|
|
||||||
#else
|
|
||||||
hr = CMenuSite_Constructor(IID_PPV_ARG(IBandSite, &pBandSite));
|
|
||||||
#endif
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
#if WRAP_MENUSITE
|
|
||||||
hr = CMenuSite_Wrapper(pBandSite, IID_PPV_ARG(IBandSite, &pBandSite));
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if USE_SYSTEM_MENUDESKBAR
|
|
||||||
hr = CoCreateInstance(CLSID_MenuDeskBar,
|
|
||||||
NULL,
|
|
||||||
CLSCTX_INPROC_SERVER,
|
|
||||||
IID_PPV_ARG(IDeskBar, &pDeskBar));
|
|
||||||
#else
|
|
||||||
hr = CMenuDeskBar_Constructor(IID_PPV_ARG(IDeskBar, &pDeskBar));
|
|
||||||
#endif
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
#if WRAP_MENUDESKBAR
|
|
||||||
hr = CMenuDeskBar_Wrapper(pDeskBar, IID_PPV_ARG(IDeskBar, &pDeskBar));
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hr = pDeskBar->SetClient(pBandSite);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
hr = pBandSite->AddBand(childShellMenu);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
CComPtr<IMenuPopup> popup;
|
|
||||||
hr = pDeskBar->QueryInterface(IID_PPV_ARG(IMenuPopup, &popup));
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
m_isTracking = TRUE;
|
|
||||||
|
|
||||||
m_menuBand->_ChangePopupItem(this, iItem);
|
m_menuBand->_ChangePopupItem(this, iItem);
|
||||||
m_menuBand->_OnPopupSubMenu(popup, &pt, &rcl);
|
m_menuBand->_OnPopupSubMenu(childShellMenu, &pt, &rcl);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CMenuToolbarBase::PopupSubMenu(UINT iItem, UINT index, HMENU menu)
|
HRESULT CMenuToolbarBase::PopupSubMenu(UINT iItem, UINT index, HMENU menu)
|
||||||
{
|
{
|
||||||
|
// Calculate the submenu position and exclude area
|
||||||
RECT rc = { 0 };
|
RECT rc = { 0 };
|
||||||
RECT rcx = { 0 };
|
|
||||||
|
|
||||||
if (!SendMessage(m_hwndToolbar, TB_GETITEMRECT, index, reinterpret_cast<LPARAM>(&rc)))
|
if (!SendMessage(m_hwndToolbar, TB_GETITEMRECT, index, reinterpret_cast<LPARAM>(&rc)))
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
GetClientRect(m_hwndToolbar, &rcx);
|
|
||||||
|
|
||||||
POINT a = { rc.left, rc.top };
|
POINT a = { rc.left, rc.top };
|
||||||
POINT b = { rc.right, rc.bottom };
|
POINT b = { rc.right, rc.bottom };
|
||||||
POINT c = { rc.left, rc.top };
|
|
||||||
POINT d = { rc.right, rc.bottom };
|
|
||||||
|
|
||||||
ClientToScreen(m_hwndToolbar, &a);
|
ClientToScreen(m_hwndToolbar, &a);
|
||||||
ClientToScreen(m_hwndToolbar, &b);
|
ClientToScreen(m_hwndToolbar, &b);
|
||||||
ClientToScreen(m_hwndToolbar, &c);
|
|
||||||
ClientToScreen(m_hwndToolbar, &d);
|
|
||||||
|
|
||||||
POINT pt = { a.x, b.y };
|
POINT pt = { a.x, b.y };
|
||||||
RECT rcl = { c.x, c.y, d.x, d.y };
|
RECT rcl = { a.x, a.y, b.x, b.y };
|
||||||
|
|
||||||
if (m_initFlags & SMINIT_VERTICAL)
|
if (m_initFlags & SMINIT_VERTICAL)
|
||||||
{
|
{
|
||||||
|
@ -816,45 +765,24 @@ HRESULT CMenuToolbarBase::PopupSubMenu(UINT iItem, UINT index, HMENU menu)
|
||||||
|
|
||||||
HMENU popup = GetSubMenu(menu, index);
|
HMENU popup = GetSubMenu(menu, index);
|
||||||
|
|
||||||
m_isTracking = TRUE;
|
// Display the submenu
|
||||||
|
m_isTrackingPopup = TRUE;
|
||||||
m_menuBand->_ChangePopupItem(this, iItem);
|
m_menuBand->_ChangePopupItem(this, iItem);
|
||||||
m_menuBand->_TrackSubMenuUsingTrackPopupMenu(popup, pt.x, pt.y, rcl);
|
m_menuBand->_TrackSubMenu(popup, pt.x, pt.y, rcl);
|
||||||
m_menuBand->_ChangePopupItem(NULL, -1);
|
m_menuBand->_ChangePopupItem(NULL, -1);
|
||||||
|
m_isTrackingPopup = FALSE;
|
||||||
m_isTracking = FALSE;
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CMenuToolbarBase::DoContextMenu(IContextMenu* contextMenu)
|
HRESULT CMenuToolbarBase::DoContextMenu(IContextMenu* contextMenu)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
// Calculate the context menu position
|
||||||
HMENU hPopup = CreatePopupMenu();
|
|
||||||
|
|
||||||
if (hPopup == NULL)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
hr = contextMenu->QueryContextMenu(hPopup, 0, 0, UINT_MAX, CMF_NORMAL);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
{
|
|
||||||
DestroyMenu(hPopup);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD dwPos = GetMessagePos();
|
DWORD dwPos = GetMessagePos();
|
||||||
UINT uCommand = ::TrackPopupMenu(hPopup, TPM_RETURNCMD, GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos), 0, m_hwnd, NULL);
|
POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
|
||||||
if (uCommand == 0)
|
|
||||||
return S_FALSE;
|
|
||||||
|
|
||||||
CMINVOKECOMMANDINFO cmi = { 0 };
|
// Display the submenu
|
||||||
cmi.cbSize = sizeof(cmi);
|
return m_menuBand->_TrackContextMenu(contextMenu, pt.x, pt.y);
|
||||||
cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
|
|
||||||
cmi.hwnd = m_hwnd;
|
|
||||||
hr = contextMenu->InvokeCommand(&cmi);
|
|
||||||
|
|
||||||
DestroyMenu(hPopup);
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CMenuToolbarBase::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
HRESULT CMenuToolbarBase::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
||||||
|
@ -866,6 +794,13 @@ HRESULT CMenuToolbarBase::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theRe
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a button is clicked while a submenu was open, cancel the submenu.
|
||||||
|
if (!(m_initFlags & SMINIT_VERTICAL) && m_isTrackingPopup)
|
||||||
|
{
|
||||||
|
DbgPrint("OnCommand cancelled because it was tracking submenu.\n");
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
*theResult = 0;
|
*theResult = 0;
|
||||||
|
|
||||||
m_menuBand->_KillPopupTimers();
|
m_menuBand->_KillPopupTimers();
|
||||||
|
@ -883,7 +818,7 @@ HRESULT CMenuToolbarBase::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theRe
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
return S_OK; // filter out a possible S_FALSE from here.
|
return OnCommandInternal(wParam, lParam, theResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CMenuToolbarBase::KeyboardItemChange(DWORD dwSelectType)
|
HRESULT CMenuToolbarBase::KeyboardItemChange(DWORD dwSelectType)
|
||||||
|
@ -948,7 +883,7 @@ HRESULT CMenuToolbarBase::KeyboardItemChange(DWORD dwSelectType)
|
||||||
if (prev != btn.idCommand)
|
if (prev != btn.idCommand)
|
||||||
{
|
{
|
||||||
DbgPrint("Setting Hot item to %d\n", index);
|
DbgPrint("Setting Hot item to %d\n", index);
|
||||||
SendMessage(m_hwndToolbar, TB_SETHOTITEM, index, 0);
|
m_menuBand->_ChangeHotItem(this, index, 0);
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -967,8 +902,9 @@ HRESULT CMenuToolbarBase::KeyboardItemChange(DWORD dwSelectType)
|
||||||
if (prev != -1)
|
if (prev != -1)
|
||||||
{
|
{
|
||||||
DbgPrint("Setting Hot item to null\n");
|
DbgPrint("Setting Hot item to null\n");
|
||||||
SendMessage(m_hwndToolbar, TB_SETHOTITEM, (WPARAM) -1, 0);
|
m_menuBand->_ChangeHotItem(NULL, -1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1219,25 +1155,8 @@ HRESULT CMenuStaticToolbar::OnContextMenu(NMMOUSE * rclick)
|
||||||
return DoContextMenu(contextMenu);
|
return DoContextMenu(contextMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CMenuStaticToolbar::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
HRESULT CMenuStaticToolbar::OnCommandInternal(WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if (m_isTracking)
|
|
||||||
{
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = CMenuToolbarBase::OnCommand(wParam, lParam, theResult);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
// in case the clicked item has a submenu, we do not need to execute the item
|
|
||||||
if (hr == S_FALSE)
|
|
||||||
{
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_menuBand->_CallCBWithItemId(wParam, SMC_EXEC, 0, 0);
|
return m_menuBand->_CallCBWithItemId(wParam, SMC_EXEC, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1313,7 +1232,6 @@ HRESULT CMenuSFToolbar::FillToolbar(BOOL clearFirst)
|
||||||
hr = m_shellFolder->GetAttributesOf(1, &itemc, &attrs);
|
hr = m_shellFolder->GetAttributesOf(1, &itemc, &attrs);
|
||||||
|
|
||||||
DWORD_PTR dwData = reinterpret_cast<DWORD_PTR>(ILClone(item));
|
DWORD_PTR dwData = reinterpret_cast<DWORD_PTR>(ILClone(item));
|
||||||
// FIXME: remove before deleting the toolbar or it will leak
|
|
||||||
|
|
||||||
// Fetch next item already, so we know if the current one is the last
|
// Fetch next item already, so we know if the current one is the last
|
||||||
hr = eidl->Next(1, &item, &fetched);
|
hr = eidl->Next(1, &item, &fetched);
|
||||||
|
@ -1399,21 +1317,10 @@ HRESULT CMenuSFToolbar::OnContextMenu(NMMOUSE * rclick)
|
||||||
return DoContextMenu(contextMenu);
|
return DoContextMenu(contextMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CMenuSFToolbar::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
HRESULT CMenuSFToolbar::OnCommandInternal(WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
|
||||||
hr = CMenuToolbarBase::OnCommand(wParam, lParam, theResult);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
// in case the clicked item has a submenu, we do not need to execute the item
|
|
||||||
if (hr == S_FALSE)
|
|
||||||
{
|
|
||||||
DbgPrint("CMenuToolbarBase::OnCommand told us to cancel.\n");
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD_PTR data;
|
DWORD_PTR data;
|
||||||
|
|
||||||
GetDataFromId(wParam, NULL, &data);
|
GetDataFromId(wParam, NULL, &data);
|
||||||
|
|
||||||
return m_menuBand->_CallCBWithItemPidl(reinterpret_cast<LPITEMIDLIST>(data), SMC_SFEXEC, 0, 0);
|
return m_menuBand->_CallCBWithItemPidl(reinterpret_cast<LPITEMIDLIST>(data), SMC_SFEXEC, 0, 0);
|
||||||
|
|
|
@ -40,8 +40,9 @@ protected:
|
||||||
CMenuBand * m_menuBand;
|
CMenuBand * m_menuBand;
|
||||||
HWND m_hwndToolbar;
|
HWND m_hwndToolbar;
|
||||||
DWORD m_dwMenuFlags;
|
DWORD m_dwMenuFlags;
|
||||||
BOOL m_hasIdealSize;
|
BOOL m_hasSizes;
|
||||||
SIZE m_idealSize;
|
SIZE m_idealSize;
|
||||||
|
SIZE m_itemSize;
|
||||||
BOOL m_usePager;
|
BOOL m_usePager;
|
||||||
CMenuToolbarBase * m_hotBar;
|
CMenuToolbarBase * m_hotBar;
|
||||||
INT m_hotItem;
|
INT m_hotItem;
|
||||||
|
@ -49,7 +50,7 @@ protected:
|
||||||
INT m_popupItem;
|
INT m_popupItem;
|
||||||
|
|
||||||
DWORD m_initFlags;
|
DWORD m_initFlags;
|
||||||
BOOL m_isTracking;
|
BOOL m_isTrackingPopup;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static LRESULT CALLBACK s_SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK s_SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
@ -74,12 +75,11 @@ public:
|
||||||
HRESULT DoContextMenu(IContextMenu* contextMenu);
|
HRESULT DoContextMenu(IContextMenu* contextMenu);
|
||||||
|
|
||||||
HRESULT KeyboardItemChange(DWORD changeType);
|
HRESULT KeyboardItemChange(DWORD changeType);
|
||||||
HRESULT OnHotItemChange(const NMTBHOTITEM * hot, LRESULT * theResult);
|
|
||||||
|
|
||||||
HRESULT IsTrackedItem(INT index);
|
HRESULT IsTrackedItem(INT index);
|
||||||
HRESULT ChangeTrackedItem(INT index, BOOL wasTracking);
|
HRESULT ChangeTrackedItem(INT index, BOOL wasTracking);
|
||||||
|
|
||||||
HRESULT GetIdealSize(SIZE& size);
|
HRESULT GetSizes(SIZE* pMinSize, SIZE* pMaxSize, SIZE* pIntegralSize);
|
||||||
HRESULT SetPosSize(int x, int y, int cx, int cy);
|
HRESULT SetPosSize(int x, int y, int cx, int cy);
|
||||||
|
|
||||||
void InvalidateDraw();
|
void InvalidateDraw();
|
||||||
|
@ -96,7 +96,7 @@ public:
|
||||||
HRESULT KillPopupTimer();
|
HRESULT KillPopupTimer();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult);
|
virtual HRESULT OnCommandInternal(WPARAM wParam, LPARAM lParam, LRESULT *theResult) = 0;
|
||||||
|
|
||||||
virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb) = 0;
|
virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb) = 0;
|
||||||
virtual HRESULT InternalPopupItem(INT iItem, INT index, DWORD_PTR dwData) = 0;
|
virtual HRESULT InternalPopupItem(INT iItem, INT index, DWORD_PTR dwData) = 0;
|
||||||
|
@ -113,6 +113,7 @@ protected:
|
||||||
HRESULT UpdateImageLists();
|
HRESULT UpdateImageLists();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult);
|
||||||
HRESULT OnPagerCalcSize(LPNMPGCALCSIZE csize);
|
HRESULT OnPagerCalcSize(LPNMPGCALCSIZE csize);
|
||||||
HRESULT OnPopupTimer(DWORD timerId);
|
HRESULT OnPopupTimer(DWORD timerId);
|
||||||
HRESULT OnCustomDraw(LPNMTBCUSTOMDRAW cdraw, LRESULT * theResult);
|
HRESULT OnCustomDraw(LPNMTBCUSTOMDRAW cdraw, LRESULT * theResult);
|
||||||
|
@ -133,7 +134,7 @@ public:
|
||||||
HRESULT GetMenu(HMENU *phmenu, HWND *phwnd, DWORD *pdwFlags);
|
HRESULT GetMenu(HMENU *phmenu, HWND *phwnd, DWORD *pdwFlags);
|
||||||
|
|
||||||
virtual HRESULT FillToolbar(BOOL clearFirst=FALSE);
|
virtual HRESULT FillToolbar(BOOL clearFirst=FALSE);
|
||||||
virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult);
|
virtual HRESULT OnCommandInternal(WPARAM wParam, LPARAM lParam, LRESULT *theResult);
|
||||||
virtual HRESULT OnContextMenu(NMMOUSE * rclick);
|
virtual HRESULT OnContextMenu(NMMOUSE * rclick);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -161,7 +162,7 @@ public:
|
||||||
HRESULT GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv);
|
HRESULT GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv);
|
||||||
|
|
||||||
virtual HRESULT FillToolbar(BOOL clearFirst=FALSE);
|
virtual HRESULT FillToolbar(BOOL clearFirst=FALSE);
|
||||||
virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult);
|
virtual HRESULT OnCommandInternal(WPARAM wParam, LPARAM lParam, LRESULT *theResult);
|
||||||
virtual HRESULT OnContextMenu(NMMOUSE * rclick);
|
virtual HRESULT OnContextMenu(NMMOUSE * rclick);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue