Jacek Caban : mshtml: Added OnChanged(DISPID_READYSTATE) semi-stub implementation.

Alexandre Julliard julliard at winehq.org
Fri Dec 10 11:57:02 CST 2010


Module: wine
Branch: master
Commit: 06f3b1a34380490636824eee2f62df3ca1307203
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=06f3b1a34380490636824eee2f62df3ca1307203

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Dec 10 16:37:08 2010 +0100

mshtml: Added OnChanged(DISPID_READYSTATE) semi-stub implementation.

---

 dlls/mshtml/pluginhost.c    |   43 +++++++++++++++-
 dlls/mshtml/tests/activex.c |  114 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 155 insertions(+), 2 deletions(-)

diff --git a/dlls/mshtml/pluginhost.c b/dlls/mshtml/pluginhost.c
index d1932de..d7a83e7 100644
--- a/dlls/mshtml/pluginhost.c
+++ b/dlls/mshtml/pluginhost.c
@@ -60,6 +60,34 @@ static BOOL check_load_safety(PluginHost *host)
     return policy == URLPOLICY_ALLOW;
 }
 
+static void update_readystate(PluginHost *host)
+{
+    DISPPARAMS params = {NULL,NULL,0,0};
+    IDispatchEx *dispex;
+    IDispatch *disp;
+    ULONG err = 0;
+    VARIANT v;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatchEx, (void**)&dispex);
+    if(SUCCEEDED(hres)) {
+        FIXME("Use IDispatchEx\n");
+        IDispatchEx_Release(dispex);
+    }
+
+    hres = IUnknown_QueryInterface(host->plugin_unk, &IID_IDispatch, (void**)&disp);
+    if(FAILED(hres))
+        return;
+
+    hres = IDispatch_Invoke(disp, DISPID_READYSTATE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, &v, NULL, &err);
+    IDispatch_Release(disp);
+    if(SUCCEEDED(hres)) {
+        /* FIXME: make plugin readystate affect document readystate */
+        TRACE("readystate = %s\n", debugstr_variant(&v));
+        VariantClear(&v);
+    }
+}
+
 static void load_prop_bag(PluginHost *host, IPersistPropertyBag *persist_prop_bag)
 {
     IPropertyBag *prop_bag;
@@ -399,8 +427,19 @@ static ULONG WINAPI PHPropertyNotifySink_Release(IPropertyNotifySink *iface)
 static HRESULT WINAPI PHPropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
 {
     PluginHost *This = impl_from_IPropertyNotifySink(iface);
-    FIXME("(%p)->(%d)\n", This, dispID);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%d)\n", This, dispID);
+
+    switch(dispID) {
+    case DISPID_READYSTATE:
+        update_readystate(This);
+        break;
+    default :
+        FIXME("Unimplemented dispID %d\n", dispID);
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
 }
 
 static HRESULT WINAPI PHPropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
diff --git a/dlls/mshtml/tests/activex.c b/dlls/mshtml/tests/activex.c
index 2229d51..9d8e668 100644
--- a/dlls/mshtml/tests/activex.c
+++ b/dlls/mshtml/tests/activex.c
@@ -62,6 +62,7 @@ DEFINE_EXPECT(FreezeEvents_FALSE);
 DEFINE_EXPECT(QuickActivate);
 DEFINE_EXPECT(IPersistPropertyBag_InitNew);
 DEFINE_EXPECT(IPersistPropertyBag_Load);
+DEFINE_EXPECT(Invoke_READYSTATE);
 
 static HWND container_hwnd;
 
@@ -142,6 +143,25 @@ static int strcmp_wa(LPCWSTR strw, const char *stra)
     return lstrcmpA(stra, buf);
 }
 
+static IOleClientSite *client_site;
+static READYSTATE plugin_readystate = READYSTATE_UNINITIALIZED;
+
+static void set_plugin_readystate(READYSTATE state)
+{
+    IPropertyNotifySink *prop_notif;
+    HRESULT hres;
+
+    plugin_readystate = state;
+
+    hres = IOleClientSite_QueryInterface(client_site, &IID_IPropertyNotifySink, (void**)&prop_notif);
+    ok(hres == S_OK, "Could not get IPropertyNotifySink iface: %08x\n", hres);
+
+    hres = IPropertyNotifySink_OnChanged(prop_notif, DISPID_READYSTATE);
+    ok(hres == S_OK, "OnChanged(DISPID_READYSTATE) failed: %08x\n", hres);
+
+    IPropertyNotifySink_Release(prop_notif);
+}
+
 static HRESULT ax_qi(REFIID,void**);
 
 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
@@ -252,6 +272,9 @@ static HRESULT WINAPI QuickActivate_QuickActivate(IQuickActivate *iface, QACONTA
        "container->pClientSite != container->pPropertyNotifySink\n");
     test_ifaces((IUnknown*)container->pClientSite, pluginhost_iids);
 
+    IOleClientSite_AddRef(container->pClientSite);
+    client_site = container->pClientSite;
+
     return S_OK;
 }
 
@@ -360,6 +383,9 @@ static HRESULT WINAPI PersistPropertyBag_Load(IPersistPropertyBag *face, IProper
     ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
     ok(V_BSTR(&v) == (BSTR)0xdeadbeef, "V_BSTR(v) = %p\n", V_BSTR(&v));
 
+    set_plugin_readystate(READYSTATE_INTERACTIVE);
+    set_plugin_readystate(READYSTATE_COMPLETE);
+
     return S_OK;
 }
 
@@ -382,6 +408,82 @@ static const IPersistPropertyBagVtbl PersistPropertyBagVtbl = {
 
 static IPersistPropertyBag PersistPropertyBag = { &PersistPropertyBagVtbl };
 
+static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
+{
+    return ax_qi(riid, ppv);
+}
+
+static ULONG WINAPI Dispatch_AddRef(IDispatch *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI Dispatch_Release(IDispatch *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid,
+        ITypeInfo **ppTInfo)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
+        UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
+        LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
+        EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    ok(IsEqualGUID(riid, &IID_NULL), "riid = %s\n", debugstr_guid(riid));
+    ok(pDispParams != NULL, "pDispParams == NULL\n");
+    ok(!pDispParams->cNamedArgs, "pDispParams->cNamedArgs = %d\n", pDispParams->cNamedArgs);
+    ok(!pDispParams->rgdispidNamedArgs, "pDispParams->rgdispidNamedArgs != NULL\n");
+    ok(pVarResult != NULL, "pVarResult == NULL\n");
+    ok(!pExcepInfo, "pExcepInfo != NULL\n");
+    ok(puArgErr != NULL, "puArgErr == NULL\n");
+
+    switch(dispIdMember) {
+    case DISPID_READYSTATE:
+        CHECK_EXPECT2(Invoke_READYSTATE);
+        ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
+        ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
+        ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
+
+        V_VT(pVarResult) = VT_I4;
+        V_I4(pVarResult) = plugin_readystate;
+        return S_OK;
+    default:
+        ok(0, "unexpected call %d\n", dispIdMember);
+    }
+
+    return E_NOTIMPL;
+}
+
+static const IDispatchVtbl DispatchVtbl = {
+    Dispatch_QueryInterface,
+    Dispatch_AddRef,
+    Dispatch_Release,
+    Dispatch_GetTypeInfoCount,
+    Dispatch_GetTypeInfo,
+    Dispatch_GetIDsOfNames,
+    Dispatch_Invoke
+};
+
+static IDispatch Dispatch = { &DispatchVtbl };
+
 static HRESULT ax_qi(REFIID riid, void **ppv)
 {
     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IOleControl)) {
@@ -399,6 +501,11 @@ static HRESULT ax_qi(REFIID riid, void **ppv)
         return S_OK;
     }
 
+    if(IsEqualGUID(riid, &IID_IDispatch)) {
+        *ppv = &Dispatch;
+        return S_OK;
+    }
+
     *ppv = NULL;
     return E_NOINTERFACE;
 }
@@ -1004,6 +1111,11 @@ static void release_doc(IHTMLDocument2 *doc)
 {
     ULONG ref;
 
+    if(client_site) {
+        IOleClientSite_Release(client_site);
+        client_site = NULL;
+    }
+
     set_client_site(doc, FALSE);
     ref = IHTMLDocument2_Release(doc);
     ok(!ref, "ref = %d\n", ref);
@@ -1023,6 +1135,7 @@ static void test_object_ax(void)
     SET_EXPECT(QuickActivate);
     SET_EXPECT(FreezeEvents_FALSE);
     SET_EXPECT(IPersistPropertyBag_Load);
+    SET_EXPECT(Invoke_READYSTATE);
 
     doc = create_doc(object_ax_str, &called_CreateInstance);
 
@@ -1033,6 +1146,7 @@ static void test_object_ax(void)
     todo_wine
     CHECK_CALLED(FreezeEvents_FALSE);
     CHECK_CALLED(IPersistPropertyBag_Load);
+    CHECK_CALLED(Invoke_READYSTATE);
 
     release_doc(doc);
 }




More information about the wine-cvs mailing list