shdocvw: Separate DocHost ref count from InternetExplorer ref count.

This commit is contained in:
Jacek Caban 2011-01-07 19:03:23 +01:00 committed by Alexandre Julliard
parent b0ba945eda
commit 967561f8ea
5 changed files with 130 additions and 39 deletions

View File

@ -83,13 +83,13 @@ static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID ri
static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
{
DocHost *This = impl_from_IOleClientSite(iface);
return IDispatch_AddRef(This->disp);
return This->container_vtbl->addref(This);
}
static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
{
DocHost *This = impl_from_IOleClientSite(iface);
return IDispatch_Release(This->disp);
return This->container_vtbl->release(This);
}
static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)

View File

@ -49,7 +49,7 @@ static HRESULT WINAPI InternetExplorer_QueryInterface(IWebBrowser2 *iface, REFII
*ppv = &This->IWebBrowser2_iface;
}else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
*ppv = &This->doc_host.cps.IConnectionPointContainer_iface;
*ppv = &This->doc_host->doc_host.cps.IConnectionPointContainer_iface;
}else if(HlinkFrame_QI(&This->hlink_frame, riid, ppv)) {
return S_OK;
}
@ -79,8 +79,17 @@ static ULONG WINAPI InternetExplorer_Release(IWebBrowser2 *iface)
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
DocHost_Release(&This->doc_host);
if(This->doc_host) {
DocHost_Release(&This->doc_host->doc_host);
if(This->doc_host)
This->doc_host->ie = NULL;
}
if(This->frame_hwnd)
DestroyWindow(This->frame_hwnd);
heap_free(This);
released_obj();
}
return ref;
@ -140,7 +149,7 @@ static HRESULT WINAPI InternetExplorer_GoHome(IWebBrowser2 *iface)
{
InternetExplorer *This = impl_from_IWebBrowser2(iface);
TRACE("(%p)\n", This);
return go_home(&This->doc_host);
return go_home(&This->doc_host->doc_host);
}
static HRESULT WINAPI InternetExplorer_GoSearch(IWebBrowser2 *iface)
@ -159,7 +168,7 @@ static HRESULT WINAPI InternetExplorer_Navigate(IWebBrowser2 *iface, BSTR szUrl,
TRACE("(%p)->(%s %p %p %p %p)\n", This, debugstr_w(szUrl), Flags, TargetFrameName,
PostData, Headers);
return navigate_url(&This->doc_host, szUrl, Flags, TargetFrameName, PostData, Headers);
return navigate_url(&This->doc_host->doc_host, szUrl, Flags, TargetFrameName, PostData, Headers);
}
static HRESULT WINAPI InternetExplorer_Refresh(IWebBrowser2 *iface)
@ -294,7 +303,7 @@ static HRESULT WINAPI InternetExplorer_get_LocationURL(IWebBrowser2 *iface, BSTR
TRACE("(%p)->(%p)\n", This, LocationURL);
return get_location_url(&This->doc_host, LocationURL);
return get_location_url(&This->doc_host->doc_host, LocationURL);
}
static HRESULT WINAPI InternetExplorer_get_Busy(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
@ -473,7 +482,7 @@ static HRESULT WINAPI InternetExplorer_Navigate2(IWebBrowser2 *iface, VARIANT *U
return E_INVALIDARG;
}
return navigate_url(&This->doc_host, V_BSTR(URL), Flags, TargetFrameName, PostData, Headers);
return navigate_url(&This->doc_host->doc_host, V_BSTR(URL), Flags, TargetFrameName, PostData, Headers);
}
static HRESULT WINAPI InternetExplorer_QueryStatusWB(IWebBrowser2 *iface, OLECMDID cmdID, OLECMDF *pcmdf)

View File

@ -50,6 +50,8 @@ static const WCHAR szIEWinFrame[] = { 'I','E','F','r','a','m','e',0 };
static const WCHAR wszWineInternetExplorer[] =
{'W','i','n','e',' ','I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',0};
static LONG obj_cnt;
HRESULT update_ie_statustext(InternetExplorer* This, LPCWSTR text)
{
if(!SendMessageW(This->status_hwnd, SB_SETTEXTW, MAKEWORD(SB_SIMPLEID, 0), (LPARAM)text))
@ -505,8 +507,8 @@ static LRESULT iewnd_OnSize(InternetExplorer *This, INT width, INT height)
adjust_ie_docobj_rect(This->frame_hwnd, &docarea);
if(This->doc_host.hwnd)
SetWindowPos(This->doc_host.hwnd, NULL, docarea.left, docarea.top, docarea.right, docarea.bottom,
if(This->doc_host->doc_host.hwnd)
SetWindowPos(This->doc_host->doc_host.hwnd, NULL, docarea.left, docarea.top, docarea.right, docarea.bottom,
SWP_NOZORDER | SWP_NOACTIVATE);
SetWindowPos(hwndRebar, NULL, 0, 0, width, barHeight, SWP_NOZORDER | SWP_NOACTIVATE);
@ -551,7 +553,6 @@ static LRESULT iewnd_OnDestroy(InternetExplorer *This)
free_fav_menu_data(get_fav_menu(This->menu));
ImageList_Destroy(list);
This->frame_hwnd = NULL;
PostQuitMessage(0); /* FIXME */
return 0;
}
@ -565,11 +566,11 @@ static LRESULT iewnd_OnCommand(InternetExplorer *This, HWND hwnd, UINT msg, WPAR
break;
case ID_BROWSE_PRINT:
if(This->doc_host.document)
if(This->doc_host->doc_host.document)
{
IOleCommandTarget* target;
if(FAILED(IUnknown_QueryInterface(This->doc_host.document, &IID_IOleCommandTarget, (LPVOID*)&target)))
if(FAILED(IUnknown_QueryInterface(This->doc_host->doc_host.document, &IID_IOleCommandTarget, (LPVOID*)&target)))
break;
IOleCommandTarget_Exec(target, &CGID_MSHTML, IDM_PRINT, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
@ -587,7 +588,7 @@ static LRESULT iewnd_OnCommand(InternetExplorer *This, HWND hwnd, UINT msg, WPAR
break;
case ID_BROWSE_QUIT:
iewnd_OnDestroy(This);
ShowWindow(hwnd, SW_HIDE);
break;
default:
@ -624,6 +625,17 @@ ie_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
case WM_CREATE:
return iewnd_OnCreate(hwnd, (LPCREATESTRUCTW)lparam);
case WM_CLOSE:
TRACE("WM_CLOSE\n");
ShowWindow(hwnd, SW_HIDE);
return 0;
case WM_SHOWWINDOW:
TRACE("WM_SHOWWINDOW %lx\n", wparam);
if(wparam)
IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
else
IWebBrowser2_Release(&This->IWebBrowser2_iface);
break;
case WM_DESTROY:
return iewnd_OnDestroy(This);
case WM_SIZE:
@ -633,7 +645,7 @@ ie_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
case WM_NOTIFY:
return iewnd_OnNotify(This, wparam, lparam);
case WM_DOCHOSTTASK:
return process_dochost_task(&This->doc_host, lparam);
return process_dochost_task(&This->doc_host->doc_host, lparam);
case WM_UPDATEADDRBAR:
return update_addrbar(This, lparam);
}
@ -678,13 +690,13 @@ static void create_frame_hwnd(InternetExplorer *This)
NULL, NULL /* FIXME */, shdocvw_hinstance, This);
}
static IWebBrowser2 *create_ie_window(LPCSTR cmdline)
static BOOL create_ie_window(LPCSTR cmdline)
{
IWebBrowser2 *wb = NULL;
InternetExplorer_Create(NULL, &IID_IWebBrowser2, (void**)&wb);
if(!wb)
return NULL;
return FALSE;
IWebBrowser2_put_Visible(wb, VARIANT_TRUE);
IWebBrowser2_put_MenuBar(wb, VARIANT_TRUE);
@ -718,12 +730,39 @@ static IWebBrowser2 *create_ie_window(LPCSTR cmdline)
SysFreeString(V_BSTR(&var_url));
}
return wb;
IWebBrowser2_Release(wb);
return TRUE;
}
static inline InternetExplorer *impl_from_DocHost(DocHost *iface)
static inline IEDocHost *impl_from_DocHost(DocHost *iface)
{
return CONTAINING_RECORD(iface, InternetExplorer, doc_host);
return CONTAINING_RECORD(iface, IEDocHost, doc_host);
}
static ULONG IEDocHost_addref(DocHost *iface)
{
IEDocHost *This = impl_from_DocHost(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG IEDocHost_release(DocHost *iface)
{
IEDocHost *This = impl_from_DocHost(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
if(This->ie)
This->ie->doc_host = NULL;
heap_free(This);
}
return ref;
}
static void WINAPI DocHostContainer_GetDocObjRect(DocHost* This, RECT* rc)
@ -732,10 +771,10 @@ static void WINAPI DocHostContainer_GetDocObjRect(DocHost* This, RECT* rc)
adjust_ie_docobj_rect(This->frame_hwnd, rc);
}
static HRESULT WINAPI DocHostContainer_SetStatusText(DocHost* This, LPCWSTR text)
static HRESULT WINAPI DocHostContainer_SetStatusText(DocHost *iface, LPCWSTR text)
{
InternetExplorer* ie = impl_from_DocHost(This);
return update_ie_statustext(ie, text);
IEDocHost *This = impl_from_DocHost(iface);
return update_ie_statustext(This->ie, text);
}
static void WINAPI DocHostContainer_SetURL(DocHost* This, LPCWSTR url)
@ -749,6 +788,8 @@ static HRESULT DocHostContainer_exec(DocHost* This, const GUID *cmd_group, DWORD
return S_OK;
}
static const IDocHostContainerVtbl DocHostContainerVtbl = {
IEDocHost_addref,
IEDocHost_release,
DocHostContainer_GetDocObjRect,
DocHostContainer_SetStatusText,
DocHostContainer_SetURL,
@ -763,25 +804,40 @@ HRESULT InternetExplorer_Create(IUnknown *pOuter, REFIID riid, void **ppv)
TRACE("(%p %s %p)\n", pOuter, debugstr_guid(riid), ppv);
ret = heap_alloc_zero(sizeof(InternetExplorer));
ret->ref = 0;
if(!ret)
return E_OUTOFMEMORY;
ret->doc_host.disp = (IDispatch*)&ret->IWebBrowser2_iface;
DocHost_Init(&ret->doc_host, (IDispatch*)&ret->IWebBrowser2_iface, &DocHostContainerVtbl);
ret->doc_host = heap_alloc_zero(sizeof(IEDocHost));
if(!ret->doc_host) {
heap_free(ret);
return E_OUTOFMEMORY;
}
ret->ref = 1;
ret->doc_host->ie = ret;
DocHost_Init(&ret->doc_host->doc_host, (IDispatch*)&ret->IWebBrowser2_iface, &DocHostContainerVtbl);
InternetExplorer_WebBrowser_Init(ret);
HlinkFrame_Init(&ret->hlink_frame, (IUnknown*)&ret->IWebBrowser2_iface, &ret->doc_host);
HlinkFrame_Init(&ret->hlink_frame, (IUnknown*)&ret->IWebBrowser2_iface, &ret->doc_host->doc_host);
create_frame_hwnd(ret);
ret->doc_host.frame_hwnd = ret->frame_hwnd;
ret->doc_host->doc_host.frame_hwnd = ret->frame_hwnd;
hres = IWebBrowser2_QueryInterface(&ret->IWebBrowser2_iface, riid, ppv);
if(FAILED(hres)) {
heap_free(ret);
IWebBrowser2_Release(&ret->IWebBrowser2_iface);
if(FAILED(hres))
return hres;
}
return hres;
InterlockedIncrement(&obj_cnt);
return S_OK;
}
void released_obj(void)
{
if(!InterlockedDecrement(&obj_cnt))
PostQuitMessage(0);
}
/******************************************************************
@ -791,7 +847,6 @@ HRESULT InternetExplorer_Create(IUnknown *pOuter, REFIID riid, void **ppv)
*/
DWORD WINAPI IEWinMain(LPSTR szCommandLine, int nShowWindow)
{
IWebBrowser2 *wb = NULL;
MSG msg;
HRESULT hres;
@ -812,8 +867,12 @@ DWORD WINAPI IEWinMain(LPSTR szCommandLine, int nShowWindow)
ExitProcess(1);
}
if(strcasecmp(szCommandLine, "-embedding"))
wb = create_ie_window(szCommandLine);
if(strcasecmp(szCommandLine, "-embedding")) {
if(!create_ie_window(szCommandLine)) {
CoUninitialize();
ExitProcess(1);
}
}
/* run the message loop for this thread */
while (GetMessageW(&msg, 0, 0, 0))
@ -822,9 +881,6 @@ DWORD WINAPI IEWinMain(LPSTR szCommandLine, int nShowWindow)
DispatchMessageW(&msg);
}
if(wb)
IWebBrowser2_Release(wb);
register_class_object(FALSE);
CoUninitialize();

View File

@ -86,6 +86,8 @@ typedef struct _task_header_t {
typedef struct _IDocHostContainerVtbl
{
ULONG (*addref)(DocHost*);
ULONG (*release)(DocHost*);
void (WINAPI* GetDocObjRect)(DocHost*,RECT*);
HRESULT (WINAPI* SetStatusText)(DocHost*,LPCWSTR);
void (WINAPI* SetURL)(DocHost*,LPCWSTR);
@ -182,6 +184,14 @@ struct WebBrowser {
DocHost doc_host;
};
typedef struct {
DocHost doc_host;
LONG ref;
InternetExplorer *ie;
} IEDocHost;
struct InternetExplorer {
IWebBrowser2 IWebBrowser2_iface;
HlinkFrame hlink_frame;
@ -192,7 +202,7 @@ struct InternetExplorer {
HWND status_hwnd;
HMENU menu;
DocHost doc_host;
IEDocHost *doc_host;
};
void WebBrowser_OleObject_Init(WebBrowser*);
@ -235,6 +245,8 @@ LRESULT process_dochost_task(DocHost*,LPARAM);
HRESULT InternetExplorer_Create(IUnknown*,REFIID,void**);
void InternetExplorer_WebBrowser_Init(InternetExplorer*);
void released_obj(void);
HRESULT CUrlHistory_Create(IUnknown*,REFIID,void**);
HRESULT InternetShortcut_Create(IUnknown*,REFIID,void**);

View File

@ -1110,6 +1110,18 @@ static inline WebBrowser *impl_from_DocHost(DocHost *iface)
return CONTAINING_RECORD(iface, WebBrowser, doc_host);
}
static ULONG WebBrowser_addref(DocHost *iface)
{
WebBrowser *This = impl_from_DocHost(iface);
return IWebBrowser2_AddRef(&This->IWebBrowser2_iface);
}
static ULONG WebBrowser_release(DocHost *iface)
{
WebBrowser *This = impl_from_DocHost(iface);
return IWebBrowser2_Release(&This->IWebBrowser2_iface);
}
static void WINAPI DocHostContainer_GetDocObjRect(DocHost* This, RECT* rc)
{
GetClientRect(This->frame_hwnd, rc);
@ -1156,6 +1168,8 @@ static HRESULT DocHostContainer_exec(DocHost *doc_host, const GUID *cmd_group, D
}
static const IDocHostContainerVtbl DocHostContainerVtbl = {
WebBrowser_addref,
WebBrowser_release,
DocHostContainer_GetDocObjRect,
DocHostContainer_SetStatusText,
DocHostContainer_SetURL,