From d870b8c3e37f91e885dabc99eca4b0e05539e486 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 9 Jan 2012 17:56:54 +0100 Subject: [PATCH] mshtml: Added IHTMLWindow::open implementation. --- dlls/mshtml/binding.h | 1 + dlls/mshtml/htmlwindow.c | 43 +++++++++++++++++++++++++-- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/navigate.c | 57 ++++++++++++++++++++++++++++++++++++ dlls/mshtml/tests/htmldoc.c | 4 --- 5 files changed, 100 insertions(+), 6 deletions(-) diff --git a/dlls/mshtml/binding.h b/dlls/mshtml/binding.h index 0d7a3a79c4e..dfb14cf1f34 100644 --- a/dlls/mshtml/binding.h +++ b/dlls/mshtml/binding.h @@ -108,6 +108,7 @@ HRESULT load_nsuri(HTMLWindow*,nsWineURI*,nsChannelBSC*,DWORD) DECLSPEC_HIDDEN; HRESULT set_moniker(HTMLDocument*,IMoniker*,IBindCtx*,nsChannelBSC*,BOOL) DECLSPEC_HIDDEN; void prepare_for_binding(HTMLDocument*,IMoniker*,BOOL) DECLSPEC_HIDDEN; HRESULT super_navigate(HTMLWindow*,IUri*,const WCHAR*,BYTE*,DWORD) DECLSPEC_HIDDEN; +HRESULT navigate_new_window(HTMLWindow*,IUri*,const WCHAR*,IHTMLWindow2**) DECLSPEC_HIDDEN; HRESULT create_channelbsc(IMoniker*,const WCHAR*,BYTE*,DWORD,nsChannelBSC**) DECLSPEC_HIDDEN; HRESULT channelbsc_load_stream(nsChannelBSC*,IStream*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index f907776b4d0..654f2e058cb 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -26,6 +26,7 @@ #include "ole2.h" #include "mshtmdid.h" #include "shlguid.h" +#include "shobjidl.h" #define NO_SHLWAPI_REG #include "shlwapi.h" @@ -776,9 +777,47 @@ static HRESULT WINAPI HTMLWindow2_open(IHTMLWindow2 *iface, BSTR url, BSTR name, BSTR features, VARIANT_BOOL replace, IHTMLWindow2 **pomWindowResult) { HTMLWindow *This = impl_from_IHTMLWindow2(iface); - FIXME("(%p)->(%s %s %s %x %p)\n", This, debugstr_w(url), debugstr_w(name), + INewWindowManager *new_window_mgr; + IUri *uri; + HRESULT hres; + + TRACE("(%p)->(%s %s %s %x %p)\n", This, debugstr_w(url), debugstr_w(name), debugstr_w(features), replace, pomWindowResult); - return E_NOTIMPL; + + if(!This->doc_obj) + return E_UNEXPECTED; + + if(name && *name == '_') { + FIXME("Unsupported name %s\n", debugstr_w(name)); + return E_NOTIMPL; + } + + hres = do_query_service((IUnknown*)This->doc_obj->client, &SID_SNewWindowManager, &IID_INewWindowManager, + (void**)&new_window_mgr); + if(FAILED(hres)) { + FIXME("No INewWindowManager\n"); + return E_NOTIMPL; + } + + hres = INewWindowManager_EvaluateNewWindow(new_window_mgr, url, name, This->url, + features, !!replace, This->doc_obj->has_popup ? 0 : NWMF_FIRST, 0); + INewWindowManager_Release(new_window_mgr); + This->doc_obj->has_popup = TRUE; + if(FAILED(hres)) { + *pomWindowResult = NULL; + return S_OK; + } + + if(This->uri) + hres = CoInternetCombineUrlEx(This->uri, url, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, &uri, 0); + else + hres = CreateUri(url, 0, 0, &uri); + if(FAILED(hres)) + return hres; + + hres = navigate_new_window(This, uri, name, pomWindowResult); + IUri_Release(uri); + return hres; } static HRESULT WINAPI HTMLWindow2_get_self(IHTMLWindow2 *iface, IHTMLWindow2 **p) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 0c6d73f7a7e..54804350d63 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -466,6 +466,7 @@ struct HTMLDocumentObj { BOOL is_webbrowser; BOOL container_locked; BOOL focus; + BOOL has_popup; INT download_state; USERMODE usermode; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index bfee591d166..f5375e415d9 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -33,6 +33,8 @@ #include "shlguid.h" #include "wininet.h" #include "shlwapi.h" +#include "htiface.h" +#include "shdeprecated.h" #include "wine/debug.h" @@ -44,6 +46,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); #define CONTENT_LENGTH "Content-Length" #define UTF16_STR "utf-16" +static const WCHAR emptyW[] = {0}; + struct nsProtocolStream { nsIInputStream nsIInputStream_iface; @@ -1977,6 +1981,59 @@ HRESULT super_navigate(HTMLWindow *window, IUri *uri, const WCHAR *headers, BYTE return S_OK; } +HRESULT navigate_new_window(HTMLWindow *window, IUri *uri, const WCHAR *name, IHTMLWindow2 **ret) +{ + IWebBrowser2 *web_browser; + IHTMLWindow2 *new_window; + IBindCtx *bind_ctx; + nsChannelBSC *bsc; + HRESULT hres; + + hres = create_channelbsc(NULL, NULL, NULL, 0, &bsc); + if(FAILED(hres)) + return hres; + + hres = CreateAsyncBindCtx(0, &bsc->bsc.IBindStatusCallback_iface, NULL, &bind_ctx); + if(FAILED(hres)) { + IBindStatusCallback_Release(&bsc->bsc.IBindStatusCallback_iface); + return hres; + } + + hres = CoCreateInstance(&CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, + &IID_IWebBrowser2, (void**)&web_browser); + if(SUCCEEDED(hres)) { + ITargetFramePriv2 *target_frame_priv; + + hres = IWebBrowser_QueryInterface(web_browser, &IID_ITargetFramePriv2, (void**)&target_frame_priv); + if(SUCCEEDED(hres)) { + hres = ITargetFramePriv2_AggregatedNavigation2(target_frame_priv, + HLNF_DISABLEWINDOWRESTRICTIONS|HLNF_OPENINNEWWINDOW, bind_ctx, &bsc->bsc.IBindStatusCallback_iface, + name, uri, emptyW); + ITargetFramePriv2_Release(target_frame_priv); + + if(SUCCEEDED(hres)) + hres = do_query_service((IUnknown*)web_browser, &SID_SHTMLWindow, &IID_IHTMLWindow2, (void**)&new_window); + } + if(FAILED(hres)) { + IWebBrowser2_Quit(web_browser); + IWebBrowser2_Release(web_browser); + } + }else { + WARN("Could not create InternetExplorer instance: %08x\n", hres); + } + + IBindStatusCallback_Release(&bsc->bsc.IBindStatusCallback_iface); + IBindCtx_Release(bind_ctx); + if(FAILED(hres)) + return hres; + + IWebBrowser2_put_Visible(web_browser, VARIANT_TRUE); + IWebBrowser2_Release(web_browser); + + *ret = new_window; + return S_OK; +} + HRESULT hlink_frame_navigate(HTMLDocument *doc, LPCWSTR url, nsChannel *nschannel, DWORD hlnf, BOOL *cancel) { IHlinkFrame *hlink_frame; diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index d72eb1bb5a1..174b4482466 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -5194,19 +5194,15 @@ static void test_open_window(IHTMLDocument2 *doc) CHECK_CALLED(TranslateUrl); if(!called_EvaluateNewWindow) { - todo_wine win_skip("INewWindowManager not supported\n"); if(SUCCEEDED(hres) && new_window) IHTMLWindow2_Release(new_window); IHTMLWindow2_Release(window); return; } - todo_wine CHECK_CALLED(EvaluateNewWindow); - todo_wine ok(hres == S_OK, "open failed: %08x\n", hres); - todo_wine ok(new_window == NULL, "new_window != NULL\n"); IHTMLWindow2_Release(window);