extern "C"
HRESULT WINAPI CMenuBand_Constructor(REFIID riid, LPVOID *ppv)
{
- HRESULT hr;
-#if USE_SYSTEM_MENUBAND
- hr = CoCreateInstance(CLSID_MenuBand,
- NULL,
- CLSCTX_INPROC_SERVER,
- riid, ppv);
-#else
- *ppv = NULL;
-
- CMenuBand * site = new CComObject<CMenuBand>();
-
- if (!site)
- return E_OUTOFMEMORY;
-
- hr = site->QueryInterface(riid, ppv);
-
- if (FAILED_UNEXPECTEDLY(hr))
- delete site;
-#endif
-
- return hr;
+ return ShellObjectCreator<CMenuBand>(riid, ppv);
}
CMenuBand::CMenuBand() :
m_popupBar(NULL),
m_popupItem(-1),
m_Show(FALSE),
- m_shellBottom(FALSE)
+ m_shellBottom(FALSE),
+ m_trackedPopup(NULL),
+ m_trackedHwnd(NULL)
{
m_focusManager = CMenuFocusManager::AcquireManager();
}
if (m_SFToolbar)
delete m_SFToolbar;
+
+ if (m_hmenu)
+ DestroyMenu(m_hmenu);
}
HRESULT STDMETHODCALLTYPE CMenuBand::Initialize(
return E_INVALIDARG;
if (ppsmc)
+ {
+ m_psmc->AddRef();
*ppsmc = m_psmc;
+ }
if (puId)
*puId = m_uId;
BOOL created = FALSE;
+ if (m_hmenu)
+ {
+ DestroyMenu(m_hmenu);
+ m_hmenu = NULL;
+ }
+
if (m_staticToolbar == NULL)
{
m_staticToolbar = new CMenuStaticToolbar(this);
if (m_Show == fShow)
return S_OK;
+ m_Show = fShow;
+
if (m_staticToolbar != NULL)
{
hr = m_staticToolbar->ShowWindow(fShow);
hr = m_focusManager->PopMenuBar(this);
}
- m_Show = fShow;
-
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMenuBand::CloseDW(DWORD dwReserved)
{
+ if (m_subMenuChild)
+ {
+ m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
+ }
+
+ if (m_subMenuChild)
+ {
+ DbgPrint("Child object should have removed itself.\n");
+ }
+
ShowDW(FALSE);
if (m_staticToolbar != NULL)
{
m_staticToolbar->Close();
- delete m_staticToolbar;
- m_staticToolbar = NULL;
}
if (m_SFToolbar != NULL)
{
m_SFToolbar->Close();
- delete m_staticToolbar;
- m_staticToolbar = NULL;
}
if (m_site) m_site.Release();
- if (m_psmc) m_psmc.Release();
if (m_subMenuChild) m_subMenuChild.Release();
if (m_subMenuParent) m_subMenuParent.Release();
if (m_childBand) m_childBand.Release();
HRESULT CMenuBand::_IsPopup()
{
- return m_subMenuParent ? S_OK : S_FALSE;
+ return !(m_dwFlags & SMINIT_VERTICAL);
}
HRESULT CMenuBand::_IsTracking()
HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
{
+ CComPtr<IMenuPopup> child = m_subMenuChild;
+
m_subMenuChild = NULL;
+
+ if (child)
+ {
+ IUnknown_SetSite(child, NULL);
+ child.Release();
+ }
if (!punkClient)
{
return S_OK;
}
- HRESULT hr = punkClient->QueryInterface(IID_PPV_ARG(IMenuPopup, &m_subMenuChild));
-
- return hr;
+ return punkClient->QueryInterface(IID_PPV_ARG(IMenuPopup, &m_subMenuChild));
}
HRESULT STDMETHODCALLTYPE CMenuBand::GetClient(IUnknown **ppunkClient)
{
// HACK, so I can test for a submenu in the DeskBar
- if (ppunkClient)
+ if (!ppunkClient)
+ return E_POINTER;
+ *ppunkClient = NULL;
+
+ if (m_subMenuChild)
{
- if (m_subMenuChild)
- *ppunkClient = m_subMenuChild;
- else
- *ppunkClient = NULL;
+ m_subMenuChild->AddRef();
+ *ppunkClient = m_subMenuChild;
}
+
return S_OK;
}
UINT flags = TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_LEFTALIGN;
HWND hwnd = m_menuOwner ? m_menuOwner : m_topLevelWindow;
+ m_trackedPopup = popup;
+ m_trackedHwnd = hwnd;
+
m_focusManager->PushTrackedPopup(popup);
::TrackPopupMenuEx(popup, flags, x, y, hwnd, ¶ms);
m_focusManager->PopTrackedPopup(popup);
+ m_trackedPopup = NULL;
+ m_trackedHwnd = NULL;
+
_DisableMouseTrack(FALSE);
return S_OK;
HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType)
{
+ CComPtr<CMenuBand> safeThis = this;
HRESULT hr;
if (m_dwFlags & SMINIT_VERTICAL)
switch (changeType)
{
case MPOS_EXECUTE:
- m_hotBar->ExecuteItem(m_hotItem);
+ {
+ CMenuToolbarBase * tb = m_hotBar;
+ int item = m_hotItem;
+ tb->PrepareExecuteItem(item);
+ if (m_subMenuParent)
+ {
+ m_subMenuParent->OnSelect(changeType);
+ }
+ TRACE("Menu closed, executing item...\n");
+ tb->ExecuteItem();
break;
-
+ }
case MPOS_SELECTLEFT:
if (m_parentBand && m_parentBand->_IsPopup()==S_FALSE)
return m_parentBand->_MenuItemHotTrack(VK_LEFT);
HRESULT CMenuBand::_CancelCurrentPopup()
{
- if (!m_subMenuChild)
- return S_FALSE;
+ if (m_subMenuChild)
+ {
+ HRESULT hr = m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
+ return hr;
+ }
- HRESULT hr = m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
- return hr;
+ if (m_trackedPopup)
+ {
+ ::SendMessage(m_trackedHwnd, WM_CANCELMODE, 0, 0);
+ return S_OK;
+ }
+
+ return S_FALSE;
}
HRESULT CMenuBand::_OnPopupSubMenu(IShellMenu * childShellMenu, POINTL * pAt, RECTL * pExclude, BOOL keyInitiated)
{
HRESULT hr = 0;
- IBandSite* pBandSite;
- IDeskBar* pDeskBar;
+ CComPtr<IBandSite> pBandSite;
+ CComPtr<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 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;
return S_OK;
}
+HRESULT CMenuBand::_HasSubMenu()
+{
+ return m_popupBar ? S_OK : S_FALSE;
+}
+
HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags)
{
UNIMPLEMENTED;