vbscript: Added property invoke implementation.

This commit is contained in:
Jacek Caban 2011-09-16 13:27:48 +02:00 committed by Alexandre Julliard
parent 4bb10ad385
commit e843608748
4 changed files with 112 additions and 3 deletions

View File

@ -404,6 +404,14 @@ Class TestClass
Public Sub publicSub
End Sub
Public Sub setPrivateProp(x)
privateProp = x
End Sub
Function getPrivateProp
getPrivateProp = privateProp
End Function
Private Sub privateSub
End Sub
End Class
@ -419,4 +427,12 @@ obj.publicSub()
Call obj.publicSub
Call obj.publicFunction()
Call ok(getVT(obj.publicProp) = "VT_EMPTY", "getVT(obj.publicProp) = " & getVT(obj.publicProp))
obj.publicProp = 3
Call ok(obj.publicProp = 3, "obj.publicProp = " & obj.publicProp)
obj.publicProp() = 3
Call obj.setPrivateProp(6)
Call ok(obj.getPrivateProp = 6, "obj.getPrivateProp = " & obj.getPrivateProp)
reportSuccess()

View File

@ -188,6 +188,36 @@ static void test_disp(IDispatch *disp)
SysFreeString(str);
ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
V_VT(args) = VT_BOOL;
V_BOOL(args) = VARIANT_TRUE;
dp.cArgs = dp.cNamedArgs = 1;
V_VT(&v) = VT_BOOL;
hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, &v, &ei, NULL);
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
dp.cArgs = dp.cNamedArgs = 0;
hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
dp.cArgs = 1;
hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
V_VT(args) = VT_BOOL;
V_BOOL(args) = VARIANT_FALSE;
dp.cArgs = 1;
V_VT(&v) = VT_BOOL;
hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
ok(hres == DISP_E_PARAMNOTOPTIONAL, "InvokeEx failed: %08x, expected DISP_E_PARAMNOTOPTIONAL\n", hres);
str = a2bstr("publicFunction");
hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_func_id);
SysFreeString(str);

View File

@ -67,6 +67,64 @@ HRESULT vbdisp_get_id(vbdisp_t *This, BSTR name, BOOL search_private, DISPID *id
return DISP_E_UNKNOWNNAME;
}
static VARIANT *get_propput_arg(const DISPPARAMS *dp)
{
unsigned i;
for(i=0; i < dp->cNamedArgs; i++) {
if(dp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT)
return dp->rgvarg+i;
}
return NULL;
}
static HRESULT invoke_variant_prop(vbdisp_t *This, VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res)
{
HRESULT hres;
switch(flags) {
case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
if(dp->cArgs) {
WARN("called with arguments\n");
return DISP_E_MEMBERNOTFOUND; /* That's what tests show */
}
hres = VariantCopy(res, v);
break;
case DISPATCH_PROPERTYPUT: {
VARIANT *put_val;
put_val = get_propput_arg(dp);
if(!put_val) {
WARN("no value to set\n");
return DISP_E_PARAMNOTOPTIONAL;
}
if(res)
V_VT(res) = VT_EMPTY;
hres = VariantCopy(v, put_val);
break;
}
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
}
return hres;
}
static void clean_props(vbdisp_t *This)
{
unsigned i;
for(i=0; i < This->desc->prop_cnt; i++)
VariantClear(This->props+i);
}
static inline vbdisp_t *impl_from_IDispatchEx(IDispatchEx *iface)
{
return CONTAINING_RECORD(iface, vbdisp_t, IDispatchEx_iface);
@ -110,8 +168,10 @@ static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
vbdisp_t *This = impl_from_IDispatchEx(iface);
LONG ref = InterlockedIncrement(&This->ref);
if(!ref)
if(!ref) {
clean_props(This);
heap_free(This);
}
return ref;
}
@ -200,7 +260,9 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
}
}
FIXME("not implemented for non-function ids\n");
if(id < This->desc->prop_cnt + This->desc->func_cnt)
return invoke_variant_prop(This, This->props+(id-This->desc->func_cnt), wFlags, pdp, pvarRes);
return DISP_E_MEMBERNOTFOUND;
}
@ -275,7 +337,7 @@ HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret)
{
vbdisp_t *vbdisp;
vbdisp = heap_alloc_zero(sizeof(*vbdisp));
vbdisp = heap_alloc_zero(sizeof(*vbdisp) + (desc->prop_cnt-1)*sizeof(VARIANT));
if(!vbdisp)
return E_OUTOFMEMORY;

View File

@ -89,6 +89,7 @@ typedef struct {
LONG ref;
const class_desc_t *desc;
VARIANT props[1];
} vbdisp_t;
HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**);