WINE_DEFAULT_DEBUG_CHANNEL(CMenuBand);
+#undef UNIMPLEMENTED
+
+#define UNIMPLEMENTED DbgPrint("%s is UNIMPLEMENTED!\n", __FUNCTION__)
+
extern "C"
-HRESULT CMenuBand_Constructor(REFIID riid, LPVOID *ppv)
+HRESULT WINAPI CMenuBand_Constructor(REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
HRESULT hr = site->QueryInterface(riid, ppv);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
site->Release();
return hr;
m_site(NULL),
m_psmc(NULL),
m_subMenuChild(NULL),
+ m_hmenu(NULL),
+ m_menuOwner(NULL),
m_useBigIcons(FALSE),
+ m_topLevelWindow(NULL),
m_hotBar(NULL),
m_hotItem(-1),
- m_popupItem(-1)
+ m_trackingPopup(FALSE)
{
m_focusManager = CMenuFocusManager::AcquireManager();
-
- m_marlett = CreateFont(
- 0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET,
- OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, FF_DONTCARE, L"Marlett");
}
CMenuBand::~CMenuBand()
if (m_SFToolbar)
delete m_SFToolbar;
-
- DeleteObject(m_marlett);
}
HRESULT STDMETHODCALLTYPE CMenuBand::Initialize(
HWND hwnd,
DWORD dwFlags)
{
+ DbgPrint("CMenuBand::SetMenu called, hmenu=%p; hwnd=%p, flags=%x\n", hmenu, hwnd, dwFlags);
+
+ BOOL created = FALSE;
+
if (m_staticToolbar == NULL)
{
m_staticToolbar = new CMenuStaticToolbar(this);
+ created = true;
}
m_hmenu = hmenu;
- m_menuOwner;
+ m_menuOwner = hwnd;
HRESULT hr = m_staticToolbar->SetMenu(hmenu, hwnd, dwFlags);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (m_site)
HWND hwndParent;
hr = m_site->GetWindow(&hwndParent);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
- hr = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
- if (FAILED(hr))
- return hr;
+ if (created)
+ {
+ hr = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- hr = m_staticToolbar->FillToolbar();
+ hr = m_staticToolbar->FillToolbar();
+ }
+ else
+ {
+ hr = m_staticToolbar->FillToolbar(TRUE);
+ }
}
return hr;
hwndParent = NULL;
hr = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &m_site));
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = m_site->GetWindow(&hwndParent);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (!::IsWindow(hwndParent))
if (m_staticToolbar != NULL)
{
hr = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = m_staticToolbar->FillToolbar();
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
}
if (m_SFToolbar != NULL)
{
hr = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = m_SFToolbar->FillToolbar();
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
}
hr = IUnknown_QueryService(m_site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_subMenuParent));
- if (FAILED(hr))
+ if (hr != E_NOINTERFACE && FAILED_UNEXPECTEDLY(hr))
return hr;
CComPtr<IOleWindow> pTopLevelWindow;
hr = IUnknown_QueryService(m_site, SID_STopLevelBrowser, IID_PPV_ARG(IOleWindow, &pTopLevelWindow));
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
return pTopLevelWindow->GetWindow(&m_topLevelWindow);
if (m_staticToolbar != NULL)
hr = m_staticToolbar->GetIdealSize(sizeStatic);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (m_SFToolbar != NULL)
hr = m_SFToolbar->GetIdealSize(sizeShlFld);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (m_staticToolbar == NULL && m_SFToolbar == NULL)
if (m_staticToolbar != NULL)
hr = m_staticToolbar->GetIdealSize(sizeStatic);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (m_SFToolbar != NULL)
hr = m_SFToolbar->GetIdealSize(sizeShlFld);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (m_staticToolbar == NULL && m_SFToolbar == NULL)
return E_FAIL;
+ pdbi->ptMinSize.x = max(sizeStatic.cx, sizeShlFld.cx) + 20;
+ pdbi->ptMinSize.y = sizeStatic.cy + sizeShlFld.cy;
pdbi->ptMaxSize.x = max(sizeStatic.cx, sizeShlFld.cx) + 20;
pdbi->ptMaxSize.y = sizeStatic.cy + sizeShlFld.cy;
if (m_staticToolbar != NULL)
hr = m_staticToolbar->ShowWindow(fShow);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (m_SFToolbar != NULL)
hr = m_SFToolbar->ShowWindow(fShow);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (fShow)
{
hr = _CallCB(SMC_INITMENU, 0, 0);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
}
- if (fShow)
- hr = m_focusManager->PushMenu(this);
- else
- hr = m_focusManager->PopMenu(this);
+ {
+ if (fShow)
+ hr = m_focusManager->PushMenu(this);
+ else
+ hr = m_focusManager->PopMenu(this);
+ }
return S_OK;
}
{
HRESULT hr;
- hr = m_subMenuParent->SetSubMenu(this, fActivate);
- if (FAILED(hr))
- return hr;
+ if (m_subMenuParent)
+ {
+ hr = m_subMenuParent->SetSubMenu(this, fActivate);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+ }
if (fActivate)
{
CComPtr<IOleWindow> pTopLevelWindow;
hr = IUnknown_QueryService(m_site, SID_SMenuPopup, IID_PPV_ARG(IOleWindow, &pTopLevelWindow));
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = pTopLevelWindow->GetWindow(&m_topLevelWindow);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
}
else
{
return S_FALSE;
}
+
+ return S_FALSE;
}
UNIMPLEMENTED;
switch (dwSelectType)
{
case MPOS_CHILDTRACKING:
+ if (!m_subMenuParent)
+ break;
// TODO: Cancel timers?
return m_subMenuParent->OnSelect(dwSelectType);
case MPOS_SELECTLEFT:
if (m_subMenuChild)
m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
+ if (!m_subMenuParent)
+ break;
return m_subMenuParent->OnSelect(dwSelectType);
case MPOS_SELECTRIGHT:
+ if (!m_subMenuParent)
+ break;
return m_subMenuParent->OnSelect(dwSelectType);
case MPOS_EXECUTE:
case MPOS_FULLCANCEL:
if (m_subMenuChild)
m_subMenuChild->OnSelect(dwSelectType);
+ if (!m_subMenuParent)
+ break;
return m_subMenuParent->OnSelect(dwSelectType);
case MPOS_CANCELLEVEL:
if (m_subMenuChild)
HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
{
- UNIMPLEMENTED;
- return S_OK;
+ if (m_subMenuChild)
+ m_subMenuChild = NULL;
+ if (!punkClient)
+ {
+ if (m_staticToolbar) m_staticToolbar->OnPopupItemChanged(NULL, -1);
+ if (m_SFToolbar) m_SFToolbar->OnPopupItemChanged(NULL, -1);
+ return S_OK;
+ }
+ HRESULT hr = punkClient->QueryInterface(IID_PPV_ARG(IMenuPopup, &m_subMenuChild));
+ m_trackingPopup = m_subMenuChild != NULL;
+ return hr;
}
HRESULT STDMETHODCALLTYPE CMenuBand::GetClient(IUnknown **ppunkClient)
}
HRESULT hr = m_SFToolbar->SetShellFolder(psf, pidlFolder, hKey, dwFlags);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (m_site)
HWND hwndParent;
hr = m_site->GetWindow(&hwndParent);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = m_SFToolbar->FillToolbar();
HRESULT STDMETHODCALLTYPE CMenuBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
{
- RECT rc;
- HDC hdc;
- HBRUSH bgBrush;
- HBRUSH hotBrush;
- NMHDR * hdr;
- NMTBCUSTOMDRAW * cdraw;
- NMTBHOTITEM * hot;
- NMMOUSE * rclick;
- NMPGCALCSIZE* csize;
- TBBUTTONINFO btni;
- BOOL useFlatMenus = FALSE;
- COLORREF clrText;
- COLORREF clrTextHighlight;
-
-
*theResult = 0;
- switch (uMsg)
- {
- case WM_COMMAND:
-
- if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
- {
- return m_staticToolbar->OnCommand(wParam, lParam, theResult);
- }
-
- if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
- {
- return m_SFToolbar->OnCommand(wParam, lParam, theResult);
- }
-
- return S_OK;
-
- case WM_NOTIFY:
- hdr = reinterpret_cast<LPNMHDR>(lParam);
- switch (hdr->code)
- {
- case PGN_CALCSIZE:
- csize = reinterpret_cast<LPNMPGCALCSIZE>(hdr);
-
- if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
- {
- SIZE tbs;
- m_staticToolbar->GetIdealSize(tbs);
- if (csize->dwFlag == PGF_CALCHEIGHT)
- {
- csize->iHeight = tbs.cy;
- }
- else if (csize->dwFlag == PGF_CALCWIDTH)
- {
- csize->iHeight = tbs.cx;
- }
- }
-
- if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
- {
- SIZE tbs;
- m_SFToolbar->GetIdealSize(tbs);
- if (csize->dwFlag == PGF_CALCHEIGHT)
- {
- csize->iHeight = tbs.cy;
- }
- else if (csize->dwFlag == PGF_CALCWIDTH)
- {
- csize->iHeight = tbs.cx;
- }
- }
- return S_OK;
-
- case TBN_DROPDOWN:
-
- if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
- {
- WPARAM wp = reinterpret_cast<LPNMTOOLBAR>(hdr)->iItem;
- return m_staticToolbar->OnCommand(wp, 0, theResult);
- }
-
- if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
- {
- WPARAM wp = reinterpret_cast<LPNMTOOLBAR>(hdr)->iItem;
- return m_SFToolbar->OnCommand(wp, 0, theResult);
- }
-
- return S_OK;
-
- case TBN_HOTITEMCHANGE:
- hot = reinterpret_cast<LPNMTBHOTITEM>(hdr);
-
- if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
- {
- return m_staticToolbar->OnHotItemChange(hot);
- }
-
- if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
- {
- return m_SFToolbar->OnHotItemChange(hot);
- }
-
- return S_OK;
-
- case NM_RCLICK:
- rclick = reinterpret_cast<LPNMMOUSE>(hdr);
-
- if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
- {
- return m_staticToolbar->OnContextMenu(rclick);
- }
-
- if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
- {
- return m_SFToolbar->OnContextMenu(rclick);
- }
-
- return S_OK;
-
- case NM_CUSTOMDRAW:
- cdraw = reinterpret_cast<LPNMTBCUSTOMDRAW>(hdr);
- switch (cdraw->nmcd.dwDrawStage)
- {
- case CDDS_PREPAINT:
- *theResult = CDRF_NOTIFYITEMDRAW;
- return S_OK;
-
- case CDDS_ITEMPREPAINT:
-
- SystemParametersInfo(SPI_GETFLATMENU, 0, &useFlatMenus, 0);
-
- clrText = GetSysColor(COLOR_MENUTEXT);
- clrTextHighlight = GetSysColor(COLOR_HIGHLIGHTTEXT);
-
- bgBrush = GetSysColorBrush(COLOR_MENU);
- hotBrush = GetSysColorBrush(useFlatMenus ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT);
-
- rc = cdraw->nmcd.rc;
- hdc = cdraw->nmcd.hdc;
-
- if (((INT)cdraw->nmcd.dwItemSpec == m_hotItem ||
- (m_hotItem < 0 && (INT)cdraw->nmcd.dwItemSpec == m_popupItem)))
- {
- cdraw->nmcd.uItemState = CDIS_HOT;
- }
- switch (cdraw->nmcd.uItemState)
- {
- case CDIS_HOT:
- case CDIS_FOCUS:
- FillRect(hdc, &rc, hotBrush);
- SetTextColor(hdc, clrTextHighlight);
- cdraw->clrText = clrTextHighlight;
- break;
- default:
- FillRect(hdc, &rc, bgBrush);
- SetTextColor(hdc, clrText);
- cdraw->clrText = clrText;
- break;
- }
-
- *theResult = CDRF_NOTIFYPOSTPAINT | TBCDRF_NOBACKGROUND | TBCDRF_NOEDGES | TBCDRF_NOOFFSET | TBCDRF_NOMARK | 0x00800000; // FIXME: the last bit is Vista+, for debugging only
- return S_OK;
-
- case CDDS_ITEMPOSTPAINT:
- btni.cbSize = sizeof(btni);
- btni.dwMask = TBIF_STYLE;
- SendMessage(hWnd, TB_GETBUTTONINFO, cdraw->nmcd.dwItemSpec, reinterpret_cast<LPARAM>(&btni));
- if (btni.fsStyle & BTNS_DROPDOWN)
- {
- SelectObject(cdraw->nmcd.hdc, m_marlett);
- WCHAR text [] = L"8";
- SetBkMode(cdraw->nmcd.hdc, TRANSPARENT);
- DrawTextEx(cdraw->nmcd.hdc, text, 1, &cdraw->nmcd.rc, DT_NOCLIP | DT_VCENTER | DT_RIGHT | DT_SINGLELINE, NULL);
- }
- *theResult = TRUE;
- return S_OK;
- }
- return S_OK;
- }
- return S_OK;
+ if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
+ {
+ return m_staticToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
}
+ if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
+ {
+ return m_SFToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
+ }
+
return S_FALSE;
}
return hr;
}
-HRESULT CMenuBand::_TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y)
+HRESULT CMenuBand::_TrackSubMenuUsingTrackPopupMenu(HMENU popup, INT x, INT y, RECT& rcExclude)
{
- ::TrackPopupMenu(popup, 0, x, y, 0, m_menuOwner, NULL);
+ TPMPARAMS params = { sizeof(TPMPARAMS), rcExclude };
+
+ UINT flags = TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_LEFTALIGN;
+
+ m_trackingPopup = TRUE;
+ m_focusManager->PushTrackedPopup(this, popup);
+ if (m_menuOwner)
+ {
+ ::TrackPopupMenuEx(popup, flags, x, y, m_menuOwner, ¶ms);
+ }
+ else
+ {
+ ::TrackPopupMenuEx(popup, flags, x, y, m_topLevelWindow, ¶ms);
+ }
+ m_trackingPopup = FALSE;
+ m_focusManager->PopTrackedPopup(this, popup);
+
return S_OK;
}
HRESULT CMenuBand::_OnHotItemChanged(CMenuToolbarBase * tb, INT id)
{
- if (m_hotBar && m_hotBar != tb)
- m_hotBar->ChangeHotItem(-1);
+ if (m_trackingPopup && id == -1)
+ {
+ return S_FALSE;
+ }
m_hotBar = tb;
m_hotItem = id;
- if (m_staticToolbar) m_staticToolbar->InvalidateDraw();
- if (m_SFToolbar) m_SFToolbar->InvalidateDraw();
+ if (m_staticToolbar) m_staticToolbar->OnHotItemChanged(tb, id);
+ if (m_SFToolbar) m_SFToolbar->OnHotItemChanged(tb, id);
return S_OK;
}
{
HRESULT hr;
- if (changeType == VK_DOWN)
+ if (!(m_dwFlags & SMINIT_VERTICAL))
+ {
+ if (changeType == MPOS_SELECTRIGHT)
+ {
+ SendMessageW(m_menuOwner, WM_CANCELMODE, 0, 0);
+ if (m_SFToolbar && (m_hotBar == m_SFToolbar || m_hotBar == NULL))
+ {
+ DbgPrint("SF Toolbars in Horizontal menus is not implemented.\n");
+ return S_FALSE;
+ }
+ else if (m_staticToolbar && m_hotBar == m_staticToolbar)
+ {
+ hr = m_staticToolbar->ChangeHotItem(VK_DOWN);
+ if (hr == S_FALSE)
+ {
+ if (m_SFToolbar)
+ return m_SFToolbar->ChangeHotItem(VK_HOME);
+ else
+ return m_staticToolbar->ChangeHotItem(VK_HOME);
+ }
+ return hr;
+ }
+ }
+ else if (changeType == MPOS_SELECTLEFT)
+ {
+ SendMessageW(m_menuOwner, WM_CANCELMODE, 0, 0);
+ if (m_staticToolbar && (m_hotBar == m_staticToolbar || m_hotBar == NULL))
+ {
+ hr = m_staticToolbar->ChangeHotItem(VK_UP);
+ if (hr == S_FALSE)
+ {
+ if (m_SFToolbar)
+ return m_SFToolbar->ChangeHotItem(VK_END);
+ else
+ return m_staticToolbar->ChangeHotItem(VK_END);
+ }
+ 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)
{
if (m_SFToolbar && (m_hotBar == m_SFToolbar || m_hotBar == NULL))
{
{
if (m_subMenuChild)
m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
+ if (!m_subMenuParent)
+ return S_OK;
return m_subMenuParent->OnSelect(MPOS_CANCELLEVEL);
}
else if (changeType == MPOS_SELECTRIGHT)
return S_FALSE;
}
}
+ if (!m_subMenuParent)
+ return S_OK;
return m_subMenuParent->OnSelect(changeType);
}
else
{
+ if (!m_subMenuParent)
+ return S_OK;
return m_subMenuParent->OnSelect(changeType);
}
return S_OK;
}
-HRESULT CMenuBand::_OnPopupSubMenu(INT popupItem, IMenuPopup * popup, POINTL * pAt, RECTL * pExclude)
+HRESULT CMenuBand::_OnPopupSubMenu(IMenuPopup * popup, POINTL * pAt, RECTL * pExclude, CMenuToolbarBase * toolbar, INT item)
{
if (m_subMenuChild)
{
HRESULT hr = m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
}
- m_popupItem = popupItem;
- m_subMenuChild = popup;
+ if (m_staticToolbar) m_staticToolbar->OnPopupItemChanged(toolbar, item);
+ if (m_SFToolbar) m_SFToolbar->OnPopupItemChanged(toolbar, item);
+ m_trackingPopup = popup != NULL;
if (popup)
{
- IUnknown_SetSite(popup, m_subMenuParent);
+ if (m_subMenuParent)
+ IUnknown_SetSite(popup, m_subMenuParent);
+ else
+ IUnknown_SetSite(popup, m_site);
+
popup->Popup(pAt, pExclude, MPPF_RIGHT);
}
- if (m_staticToolbar) m_staticToolbar->InvalidateDraw();
- if (m_SFToolbar) m_SFToolbar->InvalidateDraw();
+ return S_OK;
+}
+
+HRESULT CMenuBand::_DisableMouseTrack(BOOL bDisable)
+{
+ if (m_staticToolbar)
+ m_staticToolbar->DisableMouseTrack(bDisable);
+ if (m_SFToolbar)
+ m_SFToolbar->DisableMouseTrack(bDisable);
return S_OK;
}