diff --git a/dlls/wshom.ocx/shell.c b/dlls/wshom.ocx/shell.c index b00bc1060e8..a023786cc18 100644 --- a/dlls/wshom.ocx/shell.c +++ b/dlls/wshom.ocx/shell.c @@ -1275,11 +1275,81 @@ static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style, } } -static HRESULT WINAPI WshShell3_Popup(IWshShell3 *iface, BSTR Text, VARIANT* SecondsToWait, VARIANT *Title, VARIANT *Type, int *button) +struct popup_thread_param { - FIXME("(%s %s %s %s %p): stub\n", debugstr_w(Text), debugstr_variant(SecondsToWait), - debugstr_variant(Title), debugstr_variant(Type), button); - return E_NOTIMPL; + WCHAR *text; + VARIANT title; + VARIANT type; + INT button; +}; + +static DWORD WINAPI popup_thread_proc(void *arg) +{ + static const WCHAR defaulttitleW[] = {'W','i','n','d','o','w','s',' ','S','c','r','i','p','t',' ','H','o','s','t',0}; + struct popup_thread_param *param = (struct popup_thread_param *)arg; + + param->button = MessageBoxW(NULL, param->text, is_optional_argument(¶m->title) ? + defaulttitleW : V_BSTR(¶m->title), V_I4(¶m->type)); + return 0; +} + +static HRESULT WINAPI WshShell3_Popup(IWshShell3 *iface, BSTR text, VARIANT *seconds_to_wait, VARIANT *title, + VARIANT *type, int *button) +{ + struct popup_thread_param param; + DWORD tid, status; + VARIANT timeout; + HANDLE hthread; + HRESULT hr; + + TRACE("(%s %s %s %s %p)\n", debugstr_w(text), debugstr_variant(seconds_to_wait), debugstr_variant(title), + debugstr_variant(type), button); + + if (!seconds_to_wait || !title || !type || !button) + return E_POINTER; + + VariantInit(&timeout); + if (!is_optional_argument(seconds_to_wait)) + { + hr = VariantChangeType(&timeout, seconds_to_wait, 0, VT_I4); + if (FAILED(hr)) + return hr; + } + + VariantInit(¶m.type); + if (!is_optional_argument(type)) + { + hr = VariantChangeType(¶m.type, type, 0, VT_I4); + if (FAILED(hr)) + return hr; + } + + if (is_optional_argument(title)) + param.title = *title; + else + { + VariantInit(¶m.title); + hr = VariantChangeType(¶m.title, title, 0, VT_BSTR); + if (FAILED(hr)) + return hr; + } + + param.text = text; + param.button = -1; + hthread = CreateThread(NULL, 0, popup_thread_proc, ¶m, 0, &tid); + status = MsgWaitForMultipleObjects(1, &hthread, FALSE, V_I4(&timeout) ? V_I4(&timeout) * 1000: INFINITE, 0); + if (status == WAIT_TIMEOUT) + { + PostThreadMessageW(tid, WM_QUIT, 0, 0); + MsgWaitForMultipleObjects(1, &hthread, FALSE, INFINITE, 0); + param.button = -1; + } + *button = param.button; + + VariantClear(¶m.title); + CloseHandle(hthread); + + return S_OK; } static HRESULT WINAPI WshShell3_CreateShortcut(IWshShell3 *iface, BSTR PathLink, IDispatch** Shortcut) diff --git a/dlls/wshom.ocx/tests/wshom.c b/dlls/wshom.ocx/tests/wshom.c index 7e82f30c180..18ff4d62281 100644 --- a/dlls/wshom.ocx/tests/wshom.c +++ b/dlls/wshom.ocx/tests/wshom.c @@ -566,6 +566,54 @@ static void test_registry(void) IWshShell3_Release(sh3); } +static void test_popup(void) +{ + static const WCHAR textW[] = {'T','e','x','t',0}; + VARIANT timeout, type, title, optional; + IWshShell *sh; + int button; + HRESULT hr; + BSTR text; + + hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, + &IID_IWshShell, (void **)&sh); + ok(hr == S_OK, "Failed to create WshShell object, hr %#x.\n", hr); + + button = 123; + text = SysAllocString(textW); + + hr = IWshShell_Popup(sh, NULL, NULL, NULL, NULL, &button); + ok(hr == E_POINTER, "Unexpected retval %#x.\n", hr); + ok(button == 123, "Unexpected button id %d.\n", button); + + hr = IWshShell_Popup(sh, text, NULL, NULL, NULL, &button); + ok(hr == E_POINTER, "Unexpected retval %#x.\n", hr); + ok(button == 123, "Unexpected button id %d.\n", button); + + V_VT(&optional) = VT_ERROR; + V_ERROR(&optional) = DISP_E_PARAMNOTFOUND; + + V_VT(&timeout) = VT_I2; + V_I2(&timeout) = 1; + + V_VT(&type) = VT_I2; + V_I2(&type) = 1; + + V_VT(&title) = VT_BSTR; + V_BSTR(&title) = NULL; + + hr = IWshShell_Popup(sh, text, &timeout, &optional, &type, &button); + ok(hr == S_OK, "Unexpected retval %#x.\n", hr); + ok(button == -1, "Unexpected button id %d.\n", button); + + hr = IWshShell_Popup(sh, text, &timeout, &title, &optional, &button); + ok(hr == S_OK, "Unexpected retval %#x.\n", hr); + ok(button == -1, "Unexpected button id %d.\n", button); + + SysFreeString(text); + IWshShell_Release(sh); +} + START_TEST(wshom) { IUnknown *unk; @@ -583,6 +631,7 @@ START_TEST(wshom) test_wshshell(); test_registry(); + test_popup(); CoUninitialize(); }