extern "C"
HRESULT WINAPI CMenuDeskBar_Constructor(REFIID riid, LPVOID *ppv)
{
- HRESULT hr;
-#if USE_SYSTEM_MENUDESKBAR
- hr = CoCreateInstance(CLSID_MenuDeskBar,
- NULL,
- CLSCTX_INPROC_SERVER,
- riid, ppv);
-#else
- *ppv = NULL;
-
- CMenuDeskBar * deskbar = new CComObject<CMenuDeskBar>();
-
- if (!deskbar)
- return E_OUTOFMEMORY;
-
- hr = deskbar->QueryInterface(riid, ppv);
-
- if (FAILED_UNEXPECTEDLY(hr))
- delete deskbar;
-
-#endif
- return hr;
+ return ShellObjectCreator<CMenuDeskBar>(riid, ppv);
}
CMenuDeskBar::CMenuDeskBar() :
m_Client(NULL),
+ m_ClientWindow(NULL),
+ m_IconSize(0),
m_Banner(NULL),
- m_Shown(FALSE)
+ m_Shown(FALSE),
+ m_ShowFlags(0),
+ m_didAddRef(FALSE)
{
}
{
}
+LRESULT CMenuDeskBar::_OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
+{
+ if (!m_didAddRef)
+ {
+ this->AddRef();
+ m_didAddRef = TRUE;
+ }
+
+ bHandled = FALSE;
+ return 0;
+}
+
+void CMenuDeskBar::OnFinalMessage(HWND /* hWnd */)
+{
+ if (m_didAddRef)
+ {
+ this->Release();
+ m_didAddRef = FALSE;
+ }
+}
+
HRESULT STDMETHODCALLTYPE CMenuDeskBar::Initialize(THIS)
{
return S_OK;
HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
{
+ HRESULT hr;
+
if (IsEqualGUID(guidService, SID_SMenuPopup) ||
IsEqualGUID(guidService, SID_SMenuBandParent) ||
IsEqualGUID(guidService, SID_STopLevelBrowser))
{
- return this->QueryInterface(riid, ppvObject);
+ hr = this->QueryInterface(riid, ppvObject);
+ if (SUCCEEDED(hr))
+ return hr;
}
if (IsEqualGUID(guidService, SID_SMenuBandBottom) ||
if (m_Client == NULL)
return E_NOINTERFACE;
- return IUnknown_QueryService(m_Client, guidService, riid, ppvObject);
+ hr = IUnknown_QueryService(m_Client, guidService, riid, ppvObject);
+ if (SUCCEEDED(hr))
+ return hr;
}
CComPtr<IDeskBarClient> pDeskBandClient;
HRESULT hr;
- m_Client.Release();
+ if (m_Client)
+ {
+ hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pDeskBandClient));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ pDeskBandClient->SetDeskBarSite(NULL);
+
+ pDeskBandClient = NULL;
+ m_Client = NULL;
+ }
if (punkClient == NULL)
return S_OK;
if (m_Shown)
_CloseBar();
+ m_SubMenuParent = NULL;
+
m_Site = pUnkSite;
- IUnknown_QueryService(m_Site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_SubMenuParent));
+ if (m_Site)
+ {
+ IUnknown_QueryService(m_Site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_SubMenuParent));
+ }
+ else
+ {
+ SetClient(NULL);
+ DestroyWindow();
+ }
return S_OK;
}
y = rcWorkArea.bottom - cy;
}
- this->SetWindowPos(HWND_TOPMOST, x, y, cx, cy, SWP_SHOWWINDOW | SWP_NOACTIVATE);
+ this->SetWindowPos(HWND_TOPMOST, x, y, cx, cy, SWP_SHOWWINDOW);
m_ShowFlags = dwFlags;
m_Shown = true;
HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(DWORD dwSelectType)
{
+ CComPtr<IDeskBar> safeThis = this;
+
/* As far as I can tell, the submenu hierarchy looks like this:
*
* The DeskBar's Child is the Band it contains.
*
*/
+ CComPtr<IMenuPopup> oldParent = m_SubMenuParent;
+
switch (dwSelectType)
{
case MPOS_EXECUTE:
case MPOS_SELECTLEFT:
case MPOS_SELECTRIGHT:
case MPOS_CHILDTRACKING:
- if (m_SubMenuParent)
- return m_SubMenuParent->OnSelect(dwSelectType);
+ if (oldParent)
+ return oldParent->OnSelect(dwSelectType);
break;
}
HRESULT CMenuDeskBar::_CloseBar()
{
+ CComPtr<IDeskBar> safeThis = this;
CComPtr<IDeskBarClient> dbc;
HRESULT hr;