mshtml: Added ref counting to NSContainer.

- Added ref counting to NSContainer.
- Better destroying of NSContainer.
This commit is contained in:
Jacek Caban 2006-02-15 11:51:44 +01:00 committed by Alexandre Julliard
parent db73ae9e3d
commit 4acea60922
4 changed files with 100 additions and 51 deletions

View File

@ -142,8 +142,10 @@ static ULONG WINAPI HTMLDocument_Release(IHTMLDocument2 *iface)
IOleDocumentView_SetInPlaceSite(DOCVIEW(This), NULL); IOleDocumentView_SetInPlaceSite(DOCVIEW(This), NULL);
if(This->hwnd) if(This->hwnd)
DestroyWindow(This->hwnd); DestroyWindow(This->hwnd);
if(This->nscontainer) if(This->nscontainer)
HTMLDocument_NSContainer_Destroy(This); NSContainer_Release(This->nscontainer);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
UNLOCK_MODULE(); UNLOCK_MODULE();
@ -979,6 +981,7 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(HTMLDocument)); ret = HeapAlloc(GetProcessHeap(), 0, sizeof(HTMLDocument));
ret->lpHTMLDocument2Vtbl = &HTMLDocumentVtbl; ret->lpHTMLDocument2Vtbl = &HTMLDocumentVtbl;
ret->ref = 0; ret->ref = 0;
ret->nscontainer = NULL;
hres = IHTMLDocument_QueryInterface(HTMLDOC(ret), riid, ppvObject); hres = IHTMLDocument_QueryInterface(HTMLDOC(ret), riid, ppvObject);
if(FAILED(hres)) { if(FAILED(hres)) {
@ -995,7 +998,8 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
HTMLDocument_Window_Init(ret); HTMLDocument_Window_Init(ret);
HTMLDocument_Service_Init(ret); HTMLDocument_Service_Init(ret);
HTMLDocument_Hlink_Init(ret); HTMLDocument_Hlink_Init(ret);
HTMLDocument_NSContainer_Init(ret);
NSContainer_Create(ret);
return hres; return hres;
} }

View File

@ -90,6 +90,8 @@ struct NSContainer {
nsIWebBrowserStream *stream; nsIWebBrowserStream *stream;
nsIWebBrowserFocus *focus; nsIWebBrowserFocus *focus;
LONG ref;
HTMLDocument *doc; HTMLDocument *doc;
HWND hwnd; HWND hwnd;
@ -134,9 +136,9 @@ void HTMLDocument_View_Init(HTMLDocument*);
void HTMLDocument_Window_Init(HTMLDocument*); void HTMLDocument_Window_Init(HTMLDocument*);
void HTMLDocument_Service_Init(HTMLDocument*); void HTMLDocument_Service_Init(HTMLDocument*);
void HTMLDocument_Hlink_Init(HTMLDocument*); void HTMLDocument_Hlink_Init(HTMLDocument*);
void HTMLDocument_NSContainer_Init(HTMLDocument*);
void HTMLDocument_NSContainer_Destroy(HTMLDocument*); void NSContainer_Create(HTMLDocument *doc);
void NSContainer_Release(NSContainer*);
void HTMLDocument_LockContainer(HTMLDocument*,BOOL); void HTMLDocument_LockContainer(HTMLDocument*,BOOL);
void HTMLDocument_ShowContextMenu(HTMLDocument*,DWORD,POINT*); void HTMLDocument_ShowContextMenu(HTMLDocument*,DWORD,POINT*);

View File

@ -427,12 +427,14 @@ static nsresult NSAPI nsWebBrowserChrome_QueryInterface(nsIWebBrowserChrome *ifa
TRACE("(%p)->(IID_nsIURIContentListener %p)\n", This, result); TRACE("(%p)->(IID_nsIURIContentListener %p)\n", This, result);
*result = NSURICL(This); *result = NSURICL(This);
}else if(IsEqualGUID(&IID_nsIEmbeddingSiteWindow, riid)) { }else if(IsEqualGUID(&IID_nsIEmbeddingSiteWindow, riid)) {
TRACE("(%p)->(IIS_nsIEmbeddingSiteWindow %p)\n", This, result); TRACE("(%p)->(IID_nsIEmbeddingSiteWindow %p)\n", This, result);
*result = NSEMBWNDS(This); *result = NSEMBWNDS(This);
} }
if(*result) if(*result) {
nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
return NS_OK; return NS_OK;
}
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result); TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
return NS_NOINTERFACE; return NS_NOINTERFACE;
@ -441,15 +443,24 @@ static nsresult NSAPI nsWebBrowserChrome_QueryInterface(nsIWebBrowserChrome *ifa
static nsrefcnt NSAPI nsWebBrowserChrome_AddRef(nsIWebBrowserChrome *iface) static nsrefcnt NSAPI nsWebBrowserChrome_AddRef(nsIWebBrowserChrome *iface)
{ {
NSContainer *This = NSWBCHROME_THIS(iface); NSContainer *This = NSWBCHROME_THIS(iface);
TRACE("(%p)\n", This); LONG ref = InterlockedIncrement(&This->ref);
return 2; /* Should we implement ref conunting here? */
TRACE("(%p) ref=%ld\n", This, ref);
return ref;
} }
static nsrefcnt NSAPI nsWebBrowserChrome_Release(nsIWebBrowserChrome *iface) static nsrefcnt NSAPI nsWebBrowserChrome_Release(nsIWebBrowserChrome *iface)
{ {
NSContainer *This = NSWBCHROME_THIS(iface); NSContainer *This = NSWBCHROME_THIS(iface);
TRACE("(%p)\n", This); LONG ref = InterlockedDecrement(&This->ref);
return 1;
TRACE("(%p) ref=%ld\n", This, ref);
if(!ref)
HeapFree(GetProcessHeap(), 0, This);
return ref;
} }
static nsresult NSAPI nsWebBrowserChrome_SetStatus(nsIWebBrowserChrome *iface, static nsresult NSAPI nsWebBrowserChrome_SetStatus(nsIWebBrowserChrome *iface,
@ -470,6 +481,8 @@ static nsresult NSAPI nsWebBrowserChrome_GetWebBrowser(nsIWebBrowserChrome *ifac
if(!aWebBrowser) if(!aWebBrowser)
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
if(This->webbrowser)
nsIWebBrowser_AddRef(This->webbrowser);
*aWebBrowser = This->webbrowser; *aWebBrowser = This->webbrowser;
return S_OK; return S_OK;
} }
@ -875,42 +888,44 @@ static const nsIEmbeddingSiteWindowVtbl nsEmbeddingSiteWindowVtbl = {
nsEmbeddingSiteWindow_GetSiteWindow nsEmbeddingSiteWindow_GetSiteWindow
}; };
void HTMLDocument_NSContainer_Init(HTMLDocument *This) void NSContainer_Create(HTMLDocument *doc)
{ {
nsIWebBrowserSetup *wbsetup; nsIWebBrowserSetup *wbsetup;
NSContainer *ret;
nsresult nsres; nsresult nsres;
This->nscontainer = NULL;
if(!load_gecko()) if(!load_gecko())
return; return;
This->nscontainer = HeapAlloc(GetProcessHeap(), 0, sizeof(NSContainer)); ret = HeapAlloc(GetProcessHeap(), 0, sizeof(NSContainer));
This->nscontainer->lpWebBrowserChromeVtbl = &nsWebBrowserChromeVtbl; ret->lpWebBrowserChromeVtbl = &nsWebBrowserChromeVtbl;
This->nscontainer->lpContextMenuListenerVtbl = &nsContextMenuListenerVtbl; ret->lpContextMenuListenerVtbl = &nsContextMenuListenerVtbl;
This->nscontainer->lpURIContentListenerVtbl = &nsURIContentListenerVtbl; ret->lpURIContentListenerVtbl = &nsURIContentListenerVtbl;
This->nscontainer->lpEmbeddingSiteWindowVtbl = &nsEmbeddingSiteWindowVtbl; ret->lpEmbeddingSiteWindowVtbl = &nsEmbeddingSiteWindowVtbl;
This->nscontainer->doc = This; ret->doc = doc;
ret->ref = 1;
ret->load_call = FALSE;
doc->nscontainer = ret;
nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_WEBBROWSER_CONTRACTID, nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_WEBBROWSER_CONTRACTID,
NULL, &IID_nsIWebBrowser, (void**)&This->nscontainer->webbrowser); NULL, &IID_nsIWebBrowser, (void**)&ret->webbrowser);
if(NS_FAILED(nsres)) if(NS_FAILED(nsres))
ERR("Creating WebBrowser failed: %08lx\n", nsres); ERR("Creating WebBrowser failed: %08lx\n", nsres);
nsres = nsIWebBrowser_SetContainerWindow(This->nscontainer->webbrowser, nsres = nsIWebBrowser_SetContainerWindow(ret->webbrowser, NSWBCHROME(ret));
NSWBCHROME(This->nscontainer));
if(NS_FAILED(nsres)) if(NS_FAILED(nsres))
ERR("SetContainerWindow failed: %08lx\n", nsres); ERR("SetContainerWindow failed: %08lx\n", nsres);
nsres = nsIWebBrowser_QueryInterface(This->nscontainer->webbrowser, &IID_nsIBaseWindow, nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, &IID_nsIBaseWindow,
(void**)&This->nscontainer->window); (void**)&ret->window);
if(NS_FAILED(nsres)) if(NS_FAILED(nsres))
ERR("Could not get nsIBaseWindow interface: %08lx\n", nsres); ERR("Could not get nsIBaseWindow interface: %08lx\n", nsres);
nsres = nsIWebBrowser_QueryInterface(This->nscontainer->webbrowser, nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, &IID_nsIWebBrowserSetup,
&IID_nsIWebBrowserSetup, (void**)&wbsetup); (void**)&wbsetup);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsres = nsIWebBrowserSetup_SetProperty(wbsetup, SETUP_IS_CHROME_WRAPPER, TRUE); nsres = nsIWebBrowserSetup_SetProperty(wbsetup, SETUP_IS_CHROME_WRAPPER, TRUE);
nsIWebBrowserSetup_Release(wbsetup); nsIWebBrowserSetup_Release(wbsetup);
@ -920,63 +935,89 @@ void HTMLDocument_NSContainer_Init(HTMLDocument *This)
ERR("Could not get nsIWebBrowserSetup interface\n"); ERR("Could not get nsIWebBrowserSetup interface\n");
} }
nsres = nsIWebBrowser_QueryInterface(This->nscontainer->webbrowser, &IID_nsIWebNavigation, nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, &IID_nsIWebNavigation,
(void**)&This->nscontainer->navigation); (void**)&ret->navigation);
if(NS_FAILED(nsres)) if(NS_FAILED(nsres))
ERR("Could not get nsIWebNavigation interface: %08lx\n", nsres); ERR("Could not get nsIWebNavigation interface: %08lx\n", nsres);
nsres = nsIWebBrowserFocus_QueryInterface(This->nscontainer->webbrowser, &IID_nsIWebBrowserFocus, nsres = nsIWebBrowserFocus_QueryInterface(ret->webbrowser, &IID_nsIWebBrowserFocus,
(void**)&This->nscontainer->focus); (void**)&ret->focus);
if(NS_FAILED(nsres)) if(NS_FAILED(nsres))
ERR("Could not get nsIWebBrowserFocus interface: %08lx\n", nsres); ERR("Could not get nsIWebBrowserFocus interface: %08lx\n", nsres);
#if 0 #if 0
nsres = nsIWebBrowserStream_QueryInterface(This->nscontainer->webbrowser, &IID_nsIWebBrowserStream, nsres = nsIWebBrowserStream_QueryInterface(ret->webbrowser, &IID_nsIWebBrowserStream,
(void**)&This->nscontainer->stream); (void**)&ret->stream);
if(NS_FAILED(nsres)) if(NS_FAILED(nsres))
ERR("Could not get nsIWebBrowserStream interface: %08lx\n", nsres); ERR("Could not get nsIWebBrowserStream interface: %08lx\n", nsres);
#else #else
This->nscontainer->stream = NULL; ret->stream = NULL;
#endif #endif
if(!nscontainer_class) if(!nscontainer_class)
register_nscontainer_class(); register_nscontainer_class();
This->nscontainer->hwnd = CreateWindowExW(0, wszNsContainer, NULL, ret->hwnd = CreateWindowExW(0, wszNsContainer, NULL,
WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 100, 100, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 100, 100,
GetDesktopWindow(), NULL, hInst, This); GetDesktopWindow(), NULL, hInst, doc);
nsres = nsIBaseWindow_InitWindow(This->nscontainer->window, This->nscontainer->hwnd, NULL, nsres = nsIBaseWindow_InitWindow(ret->window, ret->hwnd, NULL, 0, 0, 100, 100);
0, 0, 100, 100);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsres = nsIBaseWindow_Create(This->nscontainer->window); nsres = nsIBaseWindow_Create(ret->window);
if(NS_FAILED(nsres)) if(NS_FAILED(nsres))
WARN("Creating window failed: %08lx\n", nsres); WARN("Creating window failed: %08lx\n", nsres);
nsIBaseWindow_SetVisibility(This->nscontainer->window, FALSE); nsIBaseWindow_SetVisibility(ret->window, FALSE);
nsIBaseWindow_SetEnabled(This->nscontainer->window, FALSE); nsIBaseWindow_SetEnabled(ret->window, FALSE);
}else { }else {
ERR("InitWindow failed: %08lx\n", nsres); ERR("InitWindow failed: %08lx\n", nsres);
} }
nsres = nsIWebBrowser_SetParentURIContentListener(This->nscontainer->webbrowser, nsres = nsIWebBrowser_SetParentURIContentListener(ret->webbrowser, NSURICL(ret));
NSURICL(This->nscontainer));
if(NS_FAILED(nsres)) if(NS_FAILED(nsres))
ERR("SetParentURIContentListener failed: %08lx\n", nsres); ERR("SetParentURIContentListener failed: %08lx\n", nsres);
This->nscontainer->load_call = FALSE;
} }
void HTMLDocument_NSContainer_Destroy(HTMLDocument *This) void NSContainer_Release(NSContainer *This)
{ {
nsIBaseWindow *base_window;
nsresult nsres;
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
nsIWebBrowser_Release(This->nscontainer->webbrowser); ShowWindow(This->hwnd, SW_HIDE);
nsIWebNavigation_Release(This->nscontainer->navigation); SetParent(This->hwnd, NULL);
nsIBaseWindow_Release(This->nscontainer->window);
if(This->nscontainer->stream) nsres = nsIWebBrowser_QueryInterface(This->webbrowser, &IID_nsIBaseWindow,
nsIWebBrowserStream_Release(This->nscontainer->stream); (void**)&base_window);
if(NS_SUCCEEDED(nsres)) {
nsIBaseWindow_SetVisibility(base_window, FALSE);
nsIBaseWindow_Destroy(base_window);
nsIBaseWindow_Release(base_window);
}else {
ERR("Could not get nsIBaseWindow interface: %08lx\n", nsres);
}
HeapFree(GetProcessHeap(), 0, This->nscontainer); nsIWebBrowser_SetContainerWindow(This->webbrowser, NULL);
nsIWebBrowser_Release(This->webbrowser);
This->webbrowser = NULL;
nsIWebNavigation_Release(This->navigation);
This->navigation = NULL;
nsIBaseWindow_Release(This->window);
This->window = NULL;
if(This->stream) {
nsIWebBrowserStream_Release(This->stream);
This->stream = NULL;
}
if(This->hwnd) {
DestroyWindow(This->hwnd);
This->hwnd = NULL;
}
nsIWebBrowserChrome_Release(NSWBCHROME(This));
} }

View File

@ -856,6 +856,8 @@ static nsrefcnt NSAPI nsURI_Release(nsIWineURI *iface)
TRACE("(%p) ref=%ld\n", This, ref); TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) { if(!ref) {
if(This->container)
nsIWebBrowserChrome_Release(NSWBCHROME(This->container));
nsIURI_Release(This->uri); nsIURI_Release(This->uri);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }