mshtml: Support type conversion in functions with arguments using default values.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7d32c24c4a
commit
64ff525b6a
|
@ -48,6 +48,10 @@ static CRITICAL_SECTION cs_dispex_static_data = { &cs_dispex_static_data_dbg, -1
|
||||||
|
|
||||||
static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
|
static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
VARIANT default_value;
|
||||||
|
} func_arg_info_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DISPID id;
|
DISPID id;
|
||||||
BSTR name;
|
BSTR name;
|
||||||
|
@ -58,8 +62,10 @@ typedef struct {
|
||||||
SHORT get_vtbl_off;
|
SHORT get_vtbl_off;
|
||||||
SHORT func_disp_idx;
|
SHORT func_disp_idx;
|
||||||
USHORT argc;
|
USHORT argc;
|
||||||
|
USHORT default_value_cnt;
|
||||||
VARTYPE prop_vt;
|
VARTYPE prop_vt;
|
||||||
VARTYPE *arg_types;
|
VARTYPE *arg_types;
|
||||||
|
func_arg_info_t *arg_info;
|
||||||
} func_info_t;
|
} func_info_t;
|
||||||
|
|
||||||
struct dispex_data_t {
|
struct dispex_data_t {
|
||||||
|
@ -165,14 +171,21 @@ static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
|
||||||
void release_typelib(void)
|
void release_typelib(void)
|
||||||
{
|
{
|
||||||
dispex_data_t *iter;
|
dispex_data_t *iter;
|
||||||
unsigned i;
|
unsigned i, j;
|
||||||
|
|
||||||
while(!list_empty(&dispex_data_list)) {
|
while(!list_empty(&dispex_data_list)) {
|
||||||
iter = LIST_ENTRY(list_head(&dispex_data_list), dispex_data_t, entry);
|
iter = LIST_ENTRY(list_head(&dispex_data_list), dispex_data_t, entry);
|
||||||
list_remove(&iter->entry);
|
list_remove(&iter->entry);
|
||||||
|
|
||||||
for(i=0; i < iter->func_cnt; i++)
|
for(i = 0; i < iter->func_cnt; i++) {
|
||||||
|
if(iter->funcs[i].default_value_cnt && iter->funcs[i].arg_info) {
|
||||||
|
for(j = 0; j < iter->funcs[i].argc; j++)
|
||||||
|
VariantClear(&iter->funcs[i].arg_info[j].default_value);
|
||||||
|
}
|
||||||
|
heap_free(iter->funcs[i].arg_types);
|
||||||
|
heap_free(iter->funcs[i].arg_info);
|
||||||
SysFreeString(iter->funcs[i].name);
|
SysFreeString(iter->funcs[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
heap_free(iter->funcs);
|
heap_free(iter->funcs);
|
||||||
heap_free(iter->name_table);
|
heap_free(iter->name_table);
|
||||||
|
@ -283,7 +296,11 @@ static void add_func_info(dispex_data_t *data, tid_t tid, const FUNCDESC *desc,
|
||||||
|
|
||||||
info->arg_types = heap_alloc(sizeof(*info->arg_types) * info->argc);
|
info->arg_types = heap_alloc(sizeof(*info->arg_types) * info->argc);
|
||||||
if(!info->arg_types)
|
if(!info->arg_types)
|
||||||
return; /* FIXME: real error instead of fallback */
|
return;
|
||||||
|
info->arg_info = heap_alloc_zero(sizeof(*info->arg_info) * info->argc);
|
||||||
|
if(!info->arg_types)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
for(i=0; i < info->argc; i++)
|
for(i=0; i < info->argc; i++)
|
||||||
info->arg_types[i] = desc->lprgelemdescParam[i].tdesc.vt;
|
info->arg_types[i] = desc->lprgelemdescParam[i].tdesc.vt;
|
||||||
|
@ -305,8 +322,15 @@ static void add_func_info(dispex_data_t *data, tid_t tid, const FUNCDESC *desc,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(desc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
|
if(desc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
|
||||||
TRACE("%s param %d: default value\n", debugstr_w(info->name), i);
|
hres = VariantCopy(&info->arg_info[i].default_value,
|
||||||
return; /* Fallback to ITypeInfo::Invoke */
|
&desc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
ERR("Could not copy default value: %08x\n", hres);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TRACE("%s param %d: default value %s\n", debugstr_w(info->name),
|
||||||
|
i, debugstr_variant(&info->arg_info[i].default_value));
|
||||||
|
info->default_value_cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,7 +1114,7 @@ static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISP
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dp->cArgs != func->argc) {
|
if(dp->cArgs > func->argc || dp->cArgs + func->default_value_cnt < func->argc) {
|
||||||
FIXME("Invalid argument count (expected %u, got %u)\n", func->argc, dp->cArgs);
|
FIXME("Invalid argument count (expected %u, got %u)\n", func->argc, dp->cArgs);
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
@ -1100,6 +1124,11 @@ static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISP
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
for(i=0; i < func->argc; i++) {
|
for(i=0; i < func->argc; i++) {
|
||||||
|
if(i >= dp->cArgs) {
|
||||||
|
/* use default value */
|
||||||
|
arg_ptrs[i] = &func->arg_info[i].default_value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
arg = dp->rgvarg+dp->cArgs-i-1;
|
arg = dp->rgvarg+dp->cArgs-i-1;
|
||||||
if(func->arg_types[i] == V_VT(arg)) {
|
if(func->arg_types[i] == V_VT(arg)) {
|
||||||
arg_ptrs[i] = arg;
|
arg_ptrs[i] = arg;
|
||||||
|
|
Loading…
Reference in New Issue