mshtml: Added support for forwarding object element's DOM calls to ActiveX control.

This commit is contained in:
Jacek Caban 2010-12-17 03:38:33 +01:00 committed by Alexandre Julliard
parent 26049daf47
commit 42d9e0c813
4 changed files with 163 additions and 3 deletions

View File

@ -439,6 +439,26 @@ static HRESULT HTMLObjectElement_get_readystate(HTMLDOMNode *iface, BSTR *p)
return E_NOTIMPL;
}
static HRESULT HTMLObjectElement_get_dispid(HTMLDOMNode *iface, BSTR name,
DWORD grfdex, DISPID *pid)
{
HTMLObjectElement *This = HTMLOBJECT_NODE_THIS(iface);
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(name), grfdex, pid);
return get_plugin_dispid(&This->plugin_container, name, pid);
}
static HRESULT HTMLObjectElement_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid,
WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{
HTMLObjectElement *This = HTMLOBJECT_NODE_THIS(iface);
TRACE("(%p)->(%d)\n", This, id);
return invoke_plugin_prop(&This->plugin_container, id, lcid, flags, params, res, ei);
}
#undef HTMLOBJECT_NODE_THIS
static const NodeImplVtbl HTMLObjectElementImplVtbl = {
@ -450,7 +470,9 @@ static const NodeImplVtbl HTMLObjectElementImplVtbl = {
NULL,
NULL,
NULL,
HTMLObjectElement_get_readystate
HTMLObjectElement_get_readystate,
HTMLObjectElement_get_dispid,
HTMLObjectElement_invoke
};
static const tid_t HTMLObjectElement_iface_tids[] = {

View File

@ -318,6 +318,82 @@ HRESULT get_plugin_disp(HTMLPluginContainer *plugin_container, IDispatch **ret)
return S_OK;
}
HRESULT get_plugin_dispid(HTMLPluginContainer *plugin_container, WCHAR *name, DISPID *ret)
{
IDispatch *disp;
DISPID id;
DWORD i;
HRESULT hres;
if(!plugin_container->plugin_host) {
WARN("no plugin host\n");
return DISP_E_UNKNOWNNAME;
}
disp = plugin_container->plugin_host->disp;
if(!disp)
return DISP_E_UNKNOWNNAME;
hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, &id);
if(FAILED(hres)) {
TRACE("no prop %s\n", debugstr_w(name));
return DISP_E_UNKNOWNNAME;
}
for(i=0; i < plugin_container->props_len; i++) {
if(id == plugin_container->props[i]) {
*ret = MSHTML_DISPID_CUSTOM_MIN+i;
return S_OK;
}
}
if(!plugin_container->props) {
plugin_container->props = heap_alloc(8*sizeof(DISPID));
if(!plugin_container->props)
return E_OUTOFMEMORY;
plugin_container->props_size = 8;
}else if(plugin_container->props_len == plugin_container->props_size) {
DISPID *new_props;
new_props = heap_realloc(plugin_container->props, plugin_container->props_size*2);
if(!new_props)
return E_OUTOFMEMORY;
plugin_container->props = new_props;
plugin_container->props_size *= 2;
}
plugin_container->props[plugin_container->props_len] = id;
*ret = MSHTML_DISPID_CUSTOM_MIN+plugin_container->props_len;
plugin_container->props_len++;
return S_OK;
}
HRESULT invoke_plugin_prop(HTMLPluginContainer *plugin_container, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
VARIANT *res, EXCEPINFO *ei)
{
PluginHost *host;
host = plugin_container->plugin_host;
if(!host || !host->disp) {
FIXME("Called with no disp\n");
return E_UNEXPECTED;
}
if(!check_script_safety(host)) {
FIXME("Insecure object\n");
return E_FAIL;
}
if(id < MSHTML_DISPID_CUSTOM_MIN || id > MSHTML_DISPID_CUSTOM_MIN + plugin_container->props_len) {
ERR("Invalid id\n");
return E_FAIL;
}
return IDispatch_Invoke(host->disp, plugin_container->props[id-MSHTML_DISPID_CUSTOM_MIN], &IID_NULL,
lcid, flags, params, res, ei, NULL);
}
static inline PluginHost *impl_from_IOleClientSite(IOleClientSite *iface)
{
return CONTAINING_RECORD(iface, PluginHost, IOleClientSite_iface);

View File

@ -50,6 +50,10 @@ struct HTMLPluginContainer {
HTMLElement element;
PluginHost *plugin_host;
DISPID *props;
DWORD props_size;
DWORD props_len;
};
extern const IID IID_HTMLPluginContainer;
@ -64,3 +68,5 @@ HRESULT create_ip_window(IOleInPlaceUIWindow**);
HRESULT create_ip_frame(IOleInPlaceFrame**);
HRESULT get_plugin_disp(HTMLPluginContainer*,IDispatch**);
HRESULT get_plugin_dispid(HTMLPluginContainer*,WCHAR*,DISPID*);
HRESULT invoke_plugin_prop(HTMLPluginContainer*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*);

View File

@ -70,6 +70,8 @@ DEFINE_EXPECT(Invoke_READYSTATE);
DEFINE_EXPECT(Invoke_ENABLED);
DEFINE_EXPECT(Invoke_VALID);
DEFINE_EXPECT(Invoke_SECURITYCTX);
DEFINE_EXPECT(Invoke_SCRIPTPROP);
DEFINE_EXPECT(GetIDsOfNames_scriptprop);
DEFINE_EXPECT(DoVerb);
DEFINE_EXPECT(SetExtent);
DEFINE_EXPECT(GetExtent);
@ -570,8 +572,15 @@ static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID l
static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
UINT cNames, LCID lcid, DISPID *rgDispId)
{
ok(0, "unexpected call\n");
return E_FAIL;
CHECK_EXPECT(GetIDsOfNames_scriptprop);
ok(IsEqualGUID(riid, &IID_NULL), "riid = %s\n", debugstr_guid(riid));
ok(cNames == 1, "cNames = %d\n", cNames);
ok(rgszNames != NULL, "rgszNames == NULL\n");
ok(!strcmp_wa(rgszNames[0], "scriptprop"), "rgszNames[0] = %s\n", wine_dbgstr_w(rgszNames[0]));
ok(rgDispId != NULL, "rgDispId == NULL\n");
*rgDispId = DISPID_SCRIPTPROP;
return S_OK;
}
static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
@ -620,6 +629,17 @@ static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REF
ok(!pExcepInfo, "pExcepInfo != NULL\n");
ok(puArgErr != NULL, "puArgErr == NULL\n");
return DISP_E_MEMBERNOTFOUND;
case DISPID_SCRIPTPROP:
CHECK_EXPECT(Invoke_SCRIPTPROP);
ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
ok(pExcepInfo != NULL, "pExcepInfo == NULL\n");
ok(!puArgErr, "puArgErr != NULL\n");
V_VT(pVarResult) = VT_I4;
V_I4(pVarResult) = 4;
return S_OK;
default:
ok(0, "unexpected call %d\n", dispIdMember);
}
@ -1197,10 +1217,42 @@ static const IClassFactoryVtbl ClassFactoryVtbl = {
static IClassFactory activex_cf = { &ClassFactoryVtbl };
static void test_elem_dispex(IDispatchEx *dispex)
{
DISPPARAMS dp;
EXCEPINFO ei;
VARIANT v;
DISPID id;
BSTR str;
HRESULT hres;
str = a2bstr("scriptprop");
SET_EXPECT(GetIDsOfNames_scriptprop);
hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
CHECK_CALLED(GetIDsOfNames_scriptprop);
SysFreeString(str);
ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
todo_wine
ok(id == DISPID_SCRIPTPROP, "id = %d\n", id);
SET_EXPECT(Invoke_SECURITYCTX);
SET_EXPECT(Invoke_SCRIPTPROP);
memset(&dp, 0, sizeof(dp));
memset(&ei, 0, sizeof(ei));
V_VT(&v) = VT_EMPTY;
hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
ok(V_I4(&v) == 4, "V_I4(v) = %d\n", V_I4(&v));
CHECK_CALLED(Invoke_SECURITYCTX);
CHECK_CALLED(Invoke_SCRIPTPROP);
}
static void test_object_elem(IHTMLDocument2 *doc)
{
IHTMLObjectElement *objelem;
IHTMLDocument3 *doc3;
IDispatchEx *dispex;
IHTMLElement *elem;
IDispatch *disp;
BSTR str;
@ -1227,6 +1279,10 @@ static void test_object_elem(IHTMLDocument2 *doc)
ok(disp == &Dispatch, "disp != Dispatch\n");
CHECK_CALLED(Invoke_SECURITYCTX);
hres = IHTMLObjectElement_QueryInterface(objelem, &IID_IDispatchEx, (void**)&dispex);
test_elem_dispex(dispex);
IDispatchEx_Release(dispex);
IHTMLObjectElement_Release(objelem);
}