From: Francis De Brabandere <francisdb@gmail.com> When declaring variables with Dim in a visible named item context, check the named item's IDispatch for each variable name via GetIDsOfNames. This matches Windows VBScript behavior where Dim probes the host object before creating the variable. --- dlls/vbscript/tests/vbscript.c | 4 ++-- dlls/vbscript/vbscript.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/dlls/vbscript/tests/vbscript.c b/dlls/vbscript/tests/vbscript.c index adda087ce76..506e6869a7c 100644 --- a/dlls/vbscript/tests/vbscript.c +++ b/dlls/vbscript/tests/vbscript.c @@ -2088,8 +2088,8 @@ static void test_named_items(void) hres = IActiveScriptParse_ParseScriptText(parse, L"dim abc\n", L"visibleItem", NULL, NULL, 0, 0, 0, NULL, NULL); ok(hres == S_OK, "ParseScriptText failed: %08lx\n", hres); CHECK_CALLED(OnEnterScript); - todo_wine CHECK_CALLED(GetItemInfo_visible); - todo_wine CHECK_CALLED(GetIDsOfNames_visible); + CHECK_CALLED(GetItemInfo_visible); + CHECK_CALLED(GetIDsOfNames_visible); CHECK_CALLED(OnLeaveScript); SET_EXPECT(OnEnterScript); SET_EXPECT(OnLeaveScript); diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c index 715c98d32bb..0e311aee5ab 100644 --- a/dlls/vbscript/vbscript.c +++ b/dlls/vbscript/vbscript.c @@ -91,6 +91,8 @@ static inline BOOL is_started(VBScript *This) || This->state == SCRIPTSTATE_DISCONNECTED; } +static HRESULT retrieve_named_item_disp(IActiveScriptSite *site, named_item_t *item); + static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res) { ScriptDisp *obj = ctx->script_obj; @@ -136,6 +138,20 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res obj->global_funcs_size = cnt; } + /* For visible named items with Dim declarations, re-fetch the dispatch + from the host to ensure it is current before probing variable names. + Windows does this even if the dispatch was previously cached. */ + if(code->main_code.var_cnt && code->named_item + && !(code->named_item->flags & SCRIPTITEM_CODEONLY)) + { + if(code->named_item->disp) + { + IDispatch_Release(code->named_item->disp); + code->named_item->disp = NULL; + } + retrieve_named_item_disp(ctx->site, code->named_item); + } + for (i = 0; i < code->main_code.var_cnt; i++) { if (!(var = heap_pool_alloc(&obj->heap, sizeof(*var)))) @@ -148,6 +164,18 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res var->is_const = FALSE; var->array = NULL; + /* Probe the named item's dispatch for this variable name. The result + is intentionally ignored: the Dim always creates a local variable + regardless of whether the name exists on the host object. */ + if(code->named_item && code->named_item->disp + && !(code->named_item->flags & SCRIPTITEM_CODEONLY)) + { + DISPID id; + + if(SUCCEEDED(disp_get_id(code->named_item->disp, var->name, VBDISP_CALLGET, TRUE, &id))) + TRACE("dim %s shadows named item member\n", debugstr_w(var->name)); + } + obj->global_vars[obj->global_vars_cnt + i] = var; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10393