[BROWSEUI]
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Tue, 8 Nov 2016 23:38:42 +0000 (23:38 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Tue, 8 Nov 2016 23:38:42 +0000 (23:38 +0000)
- CAddressBand: Call the SetOwner method with NULL parameter to CAddressEditBox to let it know that it should deinitialize.
- CAddressEditBox: Release the connection with the browse window and release the pointer to the site during deinitialization.
- CInternetToolbar: Destroy the toolbar and release pointers when CloseDW method gets called.
- CBaseBar: Destroy the window when SetClient is called with NULL parameter.
- CToolbarProxy: Add a Destroy method to release resources because we hold a pointer to the CInternetToolbar.
- CShellBrowser: When storing the pointer  to the new basebar add a new reference because we directly change the pointer in the smart pointer and not the smart pointer itself. Destroy the toolbar proxy and properly release all references to containted objects. Also expect the reference count of the shell view to reach zero after the internet toolbar gets freed because it also keeps a reference.

This should fix all the leaking objects and windows when closing the shell browser. It should also fix CORE-12066.

svn path=/trunk/; revision=73175

reactos/dll/win32/browseui/addressband.cpp
reactos/dll/win32/browseui/addresseditbox.cpp
reactos/dll/win32/browseui/basebar.cpp
reactos/dll/win32/browseui/internettoolbar.cpp
reactos/dll/win32/browseui/shellbrowser.cpp

index 97d672f..3cc67e0 100644 (file)
@@ -197,7 +197,10 @@ HRESULT STDMETHODCALLTYPE CAddressBand::CloseDW(DWORD dwReserved)
 
     m_hWnd = NULL;
 
-    IUnknown_SetSite(fAddressEditBox, NULL);
+    CComPtr<IShellService> pservice;
+    HRESULT hres = fAddressEditBox->QueryInterface(IID_PPV_ARG(IShellService, &pservice));
+    if (SUCCEEDED(hres ))
+        pservice->SetOwner(NULL);
 
     if (fAddressEditBox) fAddressEditBox.Release();
     if (fSite) fSite.Release();
index 9d03803..9633d88 100644 (file)
@@ -43,8 +43,16 @@ CAddressEditBox::~CAddressEditBox()
 {
 }
 
-HRESULT STDMETHODCALLTYPE CAddressEditBox::SetOwner(IUnknown *)
+HRESULT STDMETHODCALLTYPE CAddressEditBox::SetOwner(IUnknown *pOwner)
 {
+    if (!pOwner)
+    {
+        CComPtr<IBrowserService> browserService;
+        HRESULT hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
+        if (SUCCEEDED(hResult))
+            AtlUnadvise(browserService, DIID_DWebBrowserEvents, fAdviseCookie);
+        fSite = NULL; 
+    }
     // connect to browser connection point
     return 0;
 }
index 6a30462..bd84b4a 100644 (file)
@@ -328,6 +328,10 @@ HRESULT STDMETHODCALLTYPE CBaseBar::SetClient(IUnknown *punkClient)
             WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_TOOLWINDOW);
         ReserveBorderSpace();
     }
+    else
+    {
+        DestroyWindow();
+    }
     return S_OK;
 }
 
index 64393af..8b5717b 100644 (file)
@@ -934,6 +934,8 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved)
             return hResult;
         ReleaseCComPtrExpectZero(fLogoBar);
     }
+
+    SetSite(NULL);
     return S_OK;
 }
 
index 63c5869..db05015 100644 (file)
@@ -179,7 +179,7 @@ private:
     CComPtr<IExplorerToolbar>               fExplorerToolbar;
 public:
     void Initialize(HWND parent, IUnknown *explorerToolbar);
-
+    void Destroy();
 private:
 
     // message handlers
@@ -207,6 +207,12 @@ void CToolbarProxy::Initialize(HWND parent, IUnknown *explorerToolbar)
     }
 }
 
+void CToolbarProxy::Destroy()
+{
+    DestroyWindow();
+    fExplorerToolbar = NULL;
+}
+
 LRESULT CToolbarProxy::OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
 {
     long int                                result;
@@ -1116,6 +1122,7 @@ HRESULT CShellBrowser::GetBaseBar(bool vertical, REFIID riid, void **theBaseBar)
     
         // we have to store our basebar into cache now
         *cache = newBaseBar;
+        newBaseBar->AddRef();
         
         // tell the new base bar about the shell browser
         hResult = IUnknown_SetSite(newBaseBar, static_cast<IDropTarget *>(this));
@@ -3362,9 +3369,10 @@ LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
 
     // TODO: rip down everything
     {
+        fToolbarProxy.Destroy();
+
         fCurrentShellView->DestroyViewWindow();
         fCurrentShellView->UIActivate(SVUIA_DEACTIVATE);
-        ReleaseCComPtrExpectZero(fCurrentShellView);
 
         for (int i = 0; i < 3; i++)
         {
@@ -3393,16 +3401,14 @@ LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
                 }
             }
             pdw->CloseDW(0);
+
+            pClient = NULL;
+            pBarSite = NULL;
             pdw = NULL;
-            /* For some reasons, it's like we miss some AddRef in ATL when QueryInterface on
-             * same interface or inherited one, so we are removing already removed (!) object.
-             * TODO: check with MSVC's ATL to see if this behaviour happens too
-             */
-            bar.Detach();
-            pClient.Detach();
-            pBarSite.Detach();
+            bar = NULL;
             ReleaseCComPtrExpectZero(fClientBars[i].clientBar);
         }
+        ReleaseCComPtrExpectZero(fCurrentShellView);
         ReleaseCComPtrExpectZero(fTravelLog);
 
         fCurrentShellFolder.Release();