vbscript: Added property invoke implementation.
This commit is contained in:
parent
4bb10ad385
commit
e843608748
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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**);
|
||||
|
|
Loading…
Reference in New Issue