ieframe: Keep track of InternetExplore external references and use that to release document.

This commit is contained in:
Jacek Caban 2013-05-24 10:39:20 +02:00 committed by Alexandre Julliard
parent d256bf4b5f
commit b51af0b1c9
3 changed files with 46 additions and 6 deletions

View File

@ -713,6 +713,31 @@ static inline InternetExplorer *impl_from_IExternalConnection(IExternalConnectio
return CONTAINING_RECORD(iface, InternetExplorer, IExternalConnection_iface);
}
/*
* Document may keep references to InternetExplorer object causing circular references.
* We keep track of external references and release the document object when all
* external references are released. A visible main window is also considered as
* an external reference.
*/
DWORD release_extern_ref(InternetExplorer *This, BOOL last_closes)
{
LONG ref = InterlockedDecrement(&This->extern_ref);
TRACE("ref = %d\n", ref);
if(ref)
return ref;
if(!last_closes) {
WARN("Last external connection released with FALSE last_closes.\n");
return ref;
}
if(This->doc_host)
deactivate_document(&This->doc_host->doc_host);
return ref;
}
static HRESULT WINAPI ExternalConnection_QueryInterface(IExternalConnection *iface, REFIID riid, void **ppv)
{
InternetExplorer *This = impl_from_IExternalConnection(iface);
@ -734,16 +759,26 @@ static ULONG WINAPI ExternalConnection_Release(IExternalConnection *iface)
static DWORD WINAPI ExternalConnection_AddConnection(IExternalConnection *iface, DWORD extconn, DWORD reserved)
{
InternetExplorer *This = impl_from_IExternalConnection(iface);
FIXME("(%p)\n", This);
return 2;
TRACE("(%p)->(%x %x)\n", This, extconn, reserved);
if(extconn != EXTCONN_STRONG)
return 0;
return InterlockedIncrement(&This->extern_ref);
}
static DWORD WINAPI ExternalConnection_ReleaseConnection(IExternalConnection *iface, DWORD extconn,
DWORD reserved, BOOL fLastReleaseCloses)
{
InternetExplorer *This = impl_from_IExternalConnection(iface);
FIXME("(%p)\n", This);
return 1;
TRACE("(%p)->(%x %x %x)\n", This, extconn, reserved, fLastReleaseCloses);
if(extconn != EXTCONN_STRONG)
return 0;
return release_extern_ref(This, fLastReleaseCloses);
}
static const IExternalConnectionVtbl ExternalConnectionVtbl = {

View File

@ -229,6 +229,7 @@ struct InternetExplorer {
HlinkFrame hlink_frame;
LONG ref;
LONG extern_ref;
HWND frame_hwnd;
HWND status_hwnd;
@ -288,6 +289,7 @@ LRESULT process_dochost_tasks(DocHost*) DECLSPEC_HIDDEN;
void InternetExplorer_WebBrowser_Init(InternetExplorer*) DECLSPEC_HIDDEN;
HRESULT update_ie_statustext(InternetExplorer*, LPCWSTR) DECLSPEC_HIDDEN;
void released_obj(void) DECLSPEC_HIDDEN;
DWORD release_extern_ref(InternetExplorer*,BOOL) DECLSPEC_HIDDEN;
void register_iewindow_class(void) DECLSPEC_HIDDEN;
void unregister_iewindow_class(void) DECLSPEC_HIDDEN;

View File

@ -669,10 +669,13 @@ static LRESULT WINAPI ie_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
return 0;
case WM_SHOWWINDOW:
TRACE("WM_SHOWWINDOW %lx\n", wparam);
if(wparam)
if(wparam) {
IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
else
InterlockedIncrement(&This->extern_ref);
}else {
release_extern_ref(This, TRUE);
IWebBrowser2_Release(&This->IWebBrowser2_iface);
}
break;
case WM_DESTROY:
return iewnd_OnDestroy(This);