[RSHELL]
[reactos.git] / base / shell / rshell / CMenuDeskBar.cpp
index 91088f5..673e793 100644 (file)
@@ -30,33 +30,17 @@ const static GUID CGID_MenuDeskBar = { 0x5C9F0A12, 0x959E, 0x11D0, { 0xA3, 0xA4,
 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)
 {
 }
 
@@ -64,6 +48,27 @@ CMenuDeskBar::~CMenuDeskBar()
 {
 }
 
+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;
@@ -135,11 +140,15 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::Exec(const GUID *pguidCmdGroup, DWORD nC
 
 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) ||
@@ -149,7 +158,9 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryService(REFGUID guidService, REFIID
         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;
     }
 
 
@@ -191,7 +202,17 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetClient(IUnknown *punkClient)
     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;
@@ -242,9 +263,19 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSite(IUnknown *pUnkSite)
     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;
 }
@@ -359,7 +390,7 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::Popup(POINTL *ppt, RECTL *prcExclude, MP
         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;
@@ -447,6 +478,8 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
 
 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.
@@ -466,6 +499,8 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(DWORD dwSelectType)
      *
      */
 
+    CComPtr<IMenuPopup> oldParent = m_SubMenuParent;
+
     switch (dwSelectType)
     {
     case MPOS_EXECUTE:
@@ -480,8 +515,8 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(DWORD dwSelectType)
     case MPOS_SELECTLEFT:
     case MPOS_SELECTRIGHT:
     case MPOS_CHILDTRACKING:
-        if (m_SubMenuParent)
-            return m_SubMenuParent->OnSelect(dwSelectType);
+        if (oldParent)
+            return oldParent->OnSelect(dwSelectType);
         break;
     }
 
@@ -490,6 +525,7 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(DWORD dwSelectType)
 
 HRESULT CMenuDeskBar::_CloseBar()
 {
+    CComPtr<IDeskBar> safeThis = this;
     CComPtr<IDeskBarClient> dbc;
     HRESULT hr;