[PATCH 0/1] MR10820: vbscript: Return the script class name from TypeName() on a class instance.
Native VBScript's TypeName() returns the class name (e.g. "EmptyClass") for instances of script-defined classes; wine returned the generic "Object" string. Add a vbdisp_class_name() helper that pulls the name out of the vbdisp_t -> class_desc_t chain when the IDispatch is one of ours, and consult it before the ITypeInfo path in Global_TypeName. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10820
From: Francis De Brabandere <francisdb@gmail.com> Native VBScript's TypeName() returns the class name (e.g. "EmptyClass") for instances of script-defined classes; wine returned the generic "Object" string. Add a vbdisp_class_name() helper that pulls the name out of the vbdisp_t -> class_desc_t chain when the IDispatch is one of ours, and consult it before the ITypeInfo path in Global_TypeName. --- dlls/vbscript/global.c | 7 ++++++- dlls/vbscript/tests/api.vbs | 3 +++ dlls/vbscript/vbdisp.c | 6 ++++++ dlls/vbscript/vbscript.h | 1 + 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c index ac7e707a041..b9ef3bf0871 100644 --- a/dlls/vbscript/global.c +++ b/dlls/vbscript/global.c @@ -3068,9 +3068,13 @@ static HRESULT Global_TypeName(BuiltinDisp *This, VARIANT *arg, unsigned args_cn return return_string(res, L"Empty"); case VT_NULL: return return_string(res, L"Null"); - case VT_DISPATCH: + case VT_DISPATCH: { + const WCHAR *class_name; + if (!V_DISPATCH(arg)) return return_string(res, L"Nothing"); + if ((class_name = vbdisp_class_name(V_DISPATCH(arg)))) + return return_string(res, class_name); if (SUCCEEDED(IDispatch_GetTypeInfo(V_DISPATCH(arg), 0, GetUserDefaultLCID(), &typeinfo))) { hres = ITypeInfo_GetDocumentation(typeinfo, MEMBERID_NIL, &name, NULL, NULL, NULL); @@ -3082,6 +3086,7 @@ static HRESULT Global_TypeName(BuiltinDisp *This, VARIANT *arg, unsigned args_cn SysFreeString(name); } return return_string(res, L"Object"); + } default: FIXME("arg %s not supported\n", debugstr_variant(arg)); return E_NOTIMPL; diff --git a/dlls/vbscript/tests/api.vbs b/dlls/vbscript/tests/api.vbs index 9917997a9aa..cd93379785d 100644 --- a/dlls/vbscript/tests/api.vbs +++ b/dlls/vbscript/tests/api.vbs @@ -1710,6 +1710,9 @@ Call ok(TypeName(collectionObj) = "Object", "TypeName(collectionObj) = " & TypeN Dim regex set regex = new RegExp Call ok(TypeName(regex) = "IRegExp2", "TypeName(regex) = " & TypeName(regex)) +Dim ec +set ec = new EmptyClass +Call ok(TypeName(ec) = "EmptyClass", "TypeName(EmptyClass) = " & TypeName(ec)) Call ok(VarType(Empty) = vbEmpty, "VarType(Empty) = " & VarType(Empty)) Call ok(getVT(VarType(Empty)) = "VT_I2", "getVT(VarType(Empty)) = " & getVT(VarType(Empty))) diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c index 5cf7b5ae596..90f3d18156b 100644 --- a/dlls/vbscript/vbdisp.c +++ b/dlls/vbscript/vbdisp.c @@ -564,6 +564,12 @@ static inline vbdisp_t *unsafe_impl_from_IDispatch(IDispatch *iface) : NULL; } +const WCHAR *vbdisp_class_name(IDispatch *disp) +{ + vbdisp_t *vbdisp = unsafe_impl_from_IDispatch(disp); + return vbdisp && vbdisp->desc ? vbdisp->desc->name : NULL; +} + HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret) { vbdisp_t *vbdisp; diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 3857186620b..1420e2da0d1 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -169,6 +169,7 @@ typedef struct named_item_t { HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**); HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*); +const WCHAR *vbdisp_class_name(IDispatch*); HRESULT vbdisp_get_id(vbdisp_t*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*); HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*); HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,WORD,DISPPARAMS*); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10820
This merge request was approved by Jacek Caban. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10820
participants (3)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb) -
Jacek Caban (@jacek)