mshtml: Added HTMLWindow's IServiceProvider implementation.
authorJacek Caban <jacek@codeweavers.com>
Fri, 12 Nov 2010 11:30:36 +0000 (12:30 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Fri, 12 Nov 2010 13:38:55 +0000 (14:38 +0100)
dlls/mshtml/htmlwindow.c
dlls/mshtml/mshtml_private.h
dlls/mshtml/tests/htmldoc.c

index d4069972471ef64f2cd760f271a50b8cca63589e..298f8037a80e0f971afe4b2db863cc4c29446db5 100644 (file)
@@ -191,6 +191,9 @@ static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID rii
     }else if(IsEqualGUID(&IID_IHTMLPrivateWindow, riid)) {
         TRACE("(%p)->(IID_IHTMLPrivateWindow %p)\n", This, ppv);
         *ppv = HTMLPRIVWINDOW(This);
+    }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
+        TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
+        *ppv = SERVPROV(This);
     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
         return *ppv ? S_OK : E_NOINTERFACE;
     }
@@ -2114,6 +2117,52 @@ static const IDispatchExVtbl WindowDispExVtbl = {
     WindowDispEx_GetNameSpaceParent
 };
 
+#define SERVPROV_THIS(iface) DEFINE_THIS(HTMLWindow, ServiceProvider, iface)
+
+static HRESULT WINAPI HTMLWindowSP_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
+{
+    HTMLWindow *This = SERVPROV_THIS(iface);
+    return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
+}
+
+static ULONG WINAPI HTMLWindowSP_AddRef(IServiceProvider *iface)
+{
+    HTMLWindow *This = SERVPROV_THIS(iface);
+    return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
+}
+
+static ULONG WINAPI HTMLWindowSP_Release(IServiceProvider *iface)
+{
+    HTMLWindow *This = SERVPROV_THIS(iface);
+    return IHTMLWindow2_Release(HTMLWINDOW2(This));
+}
+
+static HRESULT WINAPI HTMLWindowSP_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
+{
+    HTMLWindow *This = SERVPROV_THIS(iface);
+
+    if(IsEqualGUID(guidService, &IID_IHTMLWindow2)) {
+        TRACE("IID_IHTMLWindow2\n");
+        return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
+    }
+
+    TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
+
+    if(!This->doc_obj)
+        return E_NOINTERFACE;
+
+    return IServiceProvider_QueryService(SERVPROV(&This->doc_obj->basedoc), guidService, riid, ppv);
+}
+
+#undef SERVPROV_THIS
+
+static const IServiceProviderVtbl ServiceProviderVtbl = {
+    HTMLWindowSP_QueryInterface,
+    HTMLWindowSP_AddRef,
+    HTMLWindowSP_Release,
+    HTMLWindowSP_QueryService
+};
+
 static const tid_t HTMLWindow_iface_tids[] = {
     IHTMLWindow2_tid,
     IHTMLWindow3_tid,
@@ -2153,6 +2202,7 @@ HRESULT HTMLWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow, HTML
     window->lpHTMLWindow4Vtbl = &HTMLWindow4Vtbl;
     window->lpIHTMLPrivateWindowVtbl = &HTMLPrivateWindowVtbl;
     window->lpIDispatchExVtbl = &WindowDispExVtbl;
+    window->lpServiceProviderVtbl = &ServiceProviderVtbl;
     window->ref = 1;
     window->doc_obj = doc_obj;
 
index a9099435e3d1bba823405950c1003dc8d62d40b3..2bc96a7bf2fb99e172ae65e5b0b06887b4c8cfe1 100644 (file)
@@ -262,7 +262,8 @@ struct HTMLWindow {
     const IHTMLWindow3Vtbl *lpHTMLWindow3Vtbl;
     const IHTMLWindow4Vtbl *lpHTMLWindow4Vtbl;
     const IHTMLPrivateWindowVtbl *lpIHTMLPrivateWindowVtbl;
-    const IDispatchExVtbl  *lpIDispatchExVtbl;
+    const IDispatchExVtbl         *lpIDispatchExVtbl;
+    const IServiceProviderVtbl    *lpServiceProviderVtbl;
 
     LONG ref;
 
index 80f137b9abdd763c61394b549bf0a53f822a6d89..e8ce9b4a838f388cb4644b6e7ea9a27fcaa51318 100644 (file)
@@ -4813,6 +4813,7 @@ static void test_HTMLDocument_http(void)
 
 static void test_QueryService(IHTMLDocument2 *doc, BOOL success)
 {
+    IHTMLWindow2 *window, *sp_window;
     IServiceProvider *sp;
     IHlinkFrame *hf;
     HRESULT hres;
@@ -4821,12 +4822,36 @@ static void test_QueryService(IHTMLDocument2 *doc, BOOL success)
     ok(hres == S_OK, "QueryService returned %08x\n", hres);
 
     hres = IServiceProvider_QueryService(sp, &IID_IHlinkFrame, &IID_IHlinkFrame, (void**)&hf);
-    if(SUCCEEDED(hres))
-        IHlinkFrame_Release(hf);
+    if(!success) {
+        ok(hres == E_NOINTERFACE, "QueryService returned %08x, expected E_NOINTERFACE\n", hres);
+        IServiceProvider_Release(sp);
+        return;
+    }
 
-    ok(hres == (success?S_OK:E_NOINTERFACE), "QueryService returned %08x, expected %08x\n", hres, success?S_OK:E_NOINTERFACE);
+    ok(hres == S_OK, "QueryService(IID_IHlinkFrame) failed: %08x\n", hres);
+    ok(hf == &HlinkFrame, "hf != HlinkFrame\n");
+    IHlinkFrame_Release(hf);
 
     IServiceProvider_Release(sp);
+
+    hres = IHTMLDocument2_get_parentWindow(doc, &window);
+    ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
+
+    hres = IHTMLWindow2_QueryInterface(window, &IID_IServiceProvider, (void**)&sp);
+    ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
+
+    hres = IServiceProvider_QueryService(sp, &IID_IHTMLWindow2, &IID_IHTMLWindow2, (void**)&sp_window);
+    ok(hres == S_OK, "QueryService(IID_IHTMLWindow2) failed: %08x\n", hres);
+    /* FIXME: test returned window */
+    IHTMLWindow2_Release(sp_window);
+
+    hres = IServiceProvider_QueryService(sp, &IID_IHlinkFrame, &IID_IHlinkFrame, (void**)&hf);
+    ok(hres == S_OK, "QueryService(IID_IHlinkFrame) failed: %08x\n", hres);
+    ok(hf == &HlinkFrame, "hf != HlinkFrame\n");
+    IHlinkFrame_Release(hf);
+
+    IServiceProvider_Release(sp);
+    IHTMLWindow2_Release(window);
 }
 
 static void test_HTMLDocument_StreamLoad(void)