#define DISPID_DYNPROP_0 0x50000000
#define DISPID_DYNPROP_MAX 0x5fffffff
+#define FDEX_VERSION_MASK 0xf0000000
+
static ITypeLib *typelib;
static ITypeInfo *typeinfos[LAST_tid];
static struct list dispex_data_list = LIST_INIT(dispex_data_list);
&IID_IHTMLElement4,
&IID_IHTMLElementCollection,
&IID_IHTMLEventObj,
+ &IID_IHTMLFrameBase,
&IID_IHTMLFrameBase2,
&IID_IHTMLGenericElement,
+ &IID_IHTMLImageElementFactory,
&IID_IHTMLImgElement,
&IID_IHTMLInputElement,
&IID_IHTMLLocation,
data->funcs[data->func_cnt].id = desc->memid;
data->funcs[data->func_cnt].tid = tid;
- data->funcs[data->func_cnt].func_disp_idx = desc->invkind == INVOKE_FUNC ? data->func_disp_cnt++ : -1;
+ data->funcs[data->func_cnt].func_disp_idx = (desc->invkind & DISPATCH_METHOD) ? data->func_disp_cnt++ : -1;
data->func_cnt++;
}
: (This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t)));
}
-static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, BOOL alloc, dynamic_prop_t **ret)
+static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags, dynamic_prop_t **ret)
{
- dispex_dynamic_data_t *data = get_dynamic_data(This, alloc);
+ const BOOL alloc = flags & fdexNameEnsure;
+ dispex_dynamic_data_t *data;
unsigned i;
+ data = get_dynamic_data(This, alloc);
if(!data) {
if(alloc)
return E_OUTOFMEMORY;
}
for(i=0; i < data->prop_cnt; i++) {
- if(!strcmpW(data->props[i].name, name)) {
+ if(flags & fdexNameCaseInsensitive ? !strcmpiW(data->props[i].name, name) : !strcmpW(data->props[i].name, name)) {
*ret = data->props+i;
return S_OK;
}
}
+ if(!alloc)
+ return DISP_E_UNKNOWNNAME;
+
TRACE("creating dynamic prop %s\n", debugstr_w(name));
if(!data->buf_size) {
dynamic_prop_t *prop;
HRESULT hres;
- hres = get_dynamic_prop(This, name, alloc, &prop);
+ hres = get_dynamic_prop(This, name, alloc ? fdexNameEnsure : 0, &prop);
if(FAILED(hres))
return hres;
HRESULT hres;
switch(flags) {
+ case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
+ if(!res)
+ return E_INVALIDARG;
case DISPATCH_METHOD:
hres = typeinfo_invoke(This->obj, This->info, flags, params, res, ei);
break;
HRESULT hres;
switch(flags) {
+ case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
+ if(!res)
+ return E_INVALIDARG;
case DISPATCH_METHOD:
hres = typeinfo_invoke(This, func, flags, dp, res, ei);
break;
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
- if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit))
+ if(grfdex & ~(fdexNameCaseSensitive|fdexNameCaseInsensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK))
FIXME("Unsupported grfdex %x\n", grfdex);
data = get_dispex_data(This);
return hres;
}
- hres = get_dynamic_prop(This, bstrName, grfdex&fdexNameEnsure, &dprop);
+ hres = get_dynamic_prop(This, bstrName, grfdex, &dprop);
if(FAILED(hres))
return hres;
return This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
if(wFlags == DISPATCH_CONSTRUCT) {
- FIXME("DISPATCH_CONSTRUCT not implemented\n");
- return E_NOTIMPL;
+ if(id == DISPID_VALUE) {
+ if(This->data->vtbl && This->data->vtbl->value) {
+ return This->data->vtbl->value(This->outer, lcid, wFlags, pdp,
+ pvarRes, pei, pspCaller);
+ }
+ FIXME("DISPATCH_CONSTRUCT flag but missing value function\n");
+ return E_FAIL;
+ }
+ FIXME("DISPATCH_CONSTRUCT flag without DISPID_VALUE\n");
+ return E_FAIL;
}
if(is_dynamic_dispid(id)) {
var = &This->dynamic_data->props[idx].var;
switch(wFlags) {
- case INVOKE_FUNC: {
+ case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
+ if(!pvarRes)
+ return E_INVALIDARG;
+ case DISPATCH_METHOD: {
DISPID named_arg = DISPID_THIS;
DISPPARAMS dp = {NULL, &named_arg, 0, 1};
IDispatchEx *dispex;
heap_free(dp.rgvarg);
return hres;
}
- case INVOKE_PROPERTYGET:
+ case DISPATCH_PROPERTYGET:
return VariantCopy(pvarRes, var);
- case INVOKE_PROPERTYPUT:
+ case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF:
+ case DISPATCH_PROPERTYPUT:
+ if(pdp->cArgs != 1 || (pdp->cNamedArgs == 1 && *pdp->rgdispidNamedArgs != DISPID_PROPERTYPUT)
+ || pdp->cNamedArgs > 1) {
+ FIXME("invalid args\n");
+ return E_INVALIDARG;
+ }
+
+ TRACE("put %s\n", debugstr_variant(pdp->rgvarg));
VariantClear(var);
return VariantCopy(var, pdp->rgvarg);
default: