diff --git a/include/libwinevbs.h b/include/libwinevbs.h index 3ba4df9..6cac7df 100644 --- a/include/libwinevbs.h +++ b/include/libwinevbs.h @@ -52,6 +52,14 @@ LIBWINEVBS_API const char* libwinevbs_hresult_name(HRESULT hr); typedef struct { void (*log)(libwinevbs_log_level_t level, const char* format, va_list args); HRESULT (*create_object)(const WCHAR* progid, IClassFactory* cf, IUnknown** obj); + /* Answers a VBScript MsgBox() call. Must return synchronously (its result + is used by the calling script statement immediately) - e.g. a real, + blocking confirm()/alert() call under Emscripten. type is the raw + VBScript "buttons" argument (MB_OK=0, MB_OKCANCEL=1, MB_YESNO=4, ...); + title may be NULL. Return the matching button id (IDOK=1, IDCANCEL=2, + IDABORT=3, IDRETRY=4, IDIGNORE=5, IDYES=6, IDNO=7), matching vbOK..vbNo. + If unset, MsgBox always answers IDOK/vbOK without asking anything. */ + int (*msgbox)(const char* prompt, int type, const char* title); } libwinevbs_callbacks_t; LIBWINEVBS_API void libwinevbs_init(const libwinevbs_callbacks_t* callbacks); diff --git a/src/libwinevbs.c b/src/libwinevbs.c index 7b3d6f0..91091e4 100644 --- a/src/libwinevbs.c +++ b/src/libwinevbs.c @@ -32,6 +32,14 @@ HRESULT libwinevbs_create_object(const WCHAR* progid, IClassFactory* cf, IUnknow return CLASS_E_CLASSNOTAVAILABLE; } +int libwinevbs_msgbox(const char* prompt, int type, const char* title) +{ + if (g_callbacks.msgbox) + return g_callbacks.msgbox(prompt, type, title); + + return 1; /* IDOK/vbOK - no host callback registered, so just proceed */ +} + const char* libwinevbs_hresult_name(HRESULT hr) { switch (hr) { diff --git a/wine/dlls/vbscript/global.c b/wine/dlls/vbscript/global.c index 0e0e144..351f967 100644 --- a/wine/dlls/vbscript/global.c +++ b/wine/dlls/vbscript/global.c @@ -33,6 +33,7 @@ #include #include "scrrun_private.h" HRESULT libwinevbs_create_object(const WCHAR *progid, IClassFactory* cf, IUnknown** obj); +int libwinevbs_msgbox(const char *prompt, int type, const char *title); extern HRESULT WINAPI WshShellFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**); #endif @@ -2834,9 +2835,12 @@ static HRESULT Global_MsgBox(BuiltinDisp *This, VARIANT *args, unsigned args_cnt hres = show_msgbox(This->ctx, prompt, type, title, res); #else if(SUCCEEDED(hres)) { - char buf[2048]; + char buf[2048], title_buf[256] = {0}; WideCharToMultiByte(CP_ACP, 0, prompt, -1, buf, sizeof(buf) - 1, NULL, NULL); + if (title) + WideCharToMultiByte(CP_ACP, 0, title, -1, title_buf, sizeof(title_buf) - 1, NULL, NULL); libwinevbs_log(LIBWINEVBS_LOG_INFO, "vbscript: MsgBox prompt=%s", buf); + hres = return_short(res, libwinevbs_msgbox(buf, type, title ? title_buf : NULL)); } #endif