This fixes an application that expects to go through full UI activation after IOleObject::DoVerb(OLEIVERB_HIDE) + IOleObject::DoVerb(OLEIVERB_UIACTIVATE).
v2: Move the tests to test_WebBrowser_DoVerb().
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/ieframe/ieframe.h | 2 + dlls/ieframe/oleobject.c | 44 ++++++--- dlls/ieframe/tests/webbrowser.c | 154 +++++++++++++++++++++++++++++++- 3 files changed, 183 insertions(+), 17 deletions(-)
diff --git a/dlls/ieframe/ieframe.h b/dlls/ieframe/ieframe.h index 329cea2f7c..24d490c272 100644 --- a/dlls/ieframe/ieframe.h +++ b/dlls/ieframe/ieframe.h @@ -210,6 +210,8 @@ struct WebBrowser { OLEINPLACEFRAMEINFO frameinfo; SIZEL extent;
+ BOOL ui_activated; + HWND shell_embedding_hwnd;
VARIANT_BOOL register_browser; diff --git a/dlls/ieframe/oleobject.c b/dlls/ieframe/oleobject.c index 031994caa5..a2f87dda2f 100644 --- a/dlls/ieframe/oleobject.c +++ b/dlls/ieframe/oleobject.c @@ -214,6 +214,9 @@ static HRESULT activate_ui(WebBrowser *This, IOleClientSite *active_site) if(FAILED(hres)) return hres;
+ if(This->ui_activated) + return S_OK; + IOleInPlaceSiteEx_OnUIActivate(This->inplace);
if(This->doc_host.frame) @@ -227,6 +230,8 @@ static HRESULT activate_ui(WebBrowser *This, IOleClientSite *active_site) SetFocus(This->shell_embedding_hwnd); notify_on_focus(This, TRUE);
+ This->ui_activated = TRUE; + return S_OK; }
@@ -579,6 +584,26 @@ static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szCont return S_OK; }
+static void deactivate_ui(WebBrowser *This) +{ + if(This->ui_activated) { + if(This->doc_host.frame) + IOleInPlaceFrame_SetActiveObject(This->doc_host.frame, NULL, NULL); + + if(This->uiwindow) + IOleInPlaceUIWindow_SetActiveObject(This->uiwindow, NULL, NULL); + + if(This->inplace) + IOleInPlaceSiteEx_OnUIDeactivate(This->inplace, FALSE); + notify_on_focus(This, FALSE); + + This->ui_activated = FALSE; + } + + if(This->inplace) + IOleInPlaceSiteEx_OnInPlaceDeactivate(This->inplace); +} + static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption) { WebBrowser *This = impl_from_IOleObject(iface); @@ -592,17 +617,7 @@ static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption) return E_NOTIMPL; }
- if(This->doc_host.frame) - IOleInPlaceFrame_SetActiveObject(This->doc_host.frame, NULL, NULL); - - if(This->uiwindow) - IOleInPlaceUIWindow_SetActiveObject(This->uiwindow, NULL, NULL); - - if(This->inplace) - IOleInPlaceSiteEx_OnUIDeactivate(This->inplace, FALSE); - notify_on_focus(This, FALSE); - if(This->inplace) - IOleInPlaceSiteEx_OnInPlaceDeactivate(This->inplace); + deactivate_ui(This);
/* store old client site - we need to restore it in DoVerb */ client = This->client; @@ -677,8 +692,11 @@ static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, struct tag return activate_inplace(This, pActiveSite); case OLEIVERB_HIDE: TRACE("OLEIVERB_HIDE\n"); - if(This->inplace) - IOleInPlaceSiteEx_OnInPlaceDeactivate(This->inplace); + if(This->inplace) { + deactivate_ui(This); + IOleInPlaceSiteEx_Release(This->inplace); + This->inplace = NULL; + } if(This->shell_embedding_hwnd) ShowWindow(This->shell_embedding_hwnd, SW_HIDE); return S_OK; diff --git a/dlls/ieframe/tests/webbrowser.c b/dlls/ieframe/tests/webbrowser.c index e0af0d4642..9c2c393aaf 100644 --- a/dlls/ieframe/tests/webbrowser.c +++ b/dlls/ieframe/tests/webbrowser.c @@ -167,7 +167,8 @@ static VARIANT_BOOL exvb; static IWebBrowser2 *wb;
static HWND container_hwnd, shell_embedding_hwnd; -static BOOL is_downloading, do_download, is_first_load, use_container_olecmd, test_close, is_http, use_container_dochostui; +static BOOL is_downloading, do_download, is_first_load, use_container_olecmd; +static BOOL test_close, test_hide, is_http, use_container_dochostui; static HRESULT hr_dochost_TranslateAccelerator = E_NOTIMPL; static HRESULT hr_site_TranslateAccelerator = E_NOTIMPL; static const WCHAR *current_url; @@ -1265,7 +1266,7 @@ static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceFrame *iface, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) { CHECK_EXPECT(UIWindow_SetActiveObject); - if(!test_close) { + if(!test_close && !test_hide) { ok(pActiveObject != NULL, "pActiveObject = NULL\n"); ok(!lstrcmpW(pszObjName, wszItem), "unexpected pszObjName\n"); } else { @@ -1279,7 +1280,7 @@ static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) { CHECK_EXPECT(Frame_SetActiveObject); - if(!test_close) { + if(!test_close && !test_hide) { ok(pActiveObject != NULL, "pActiveObject = NULL\n"); ok(!lstrcmpW(pszObjName, wszItem), "unexpected pszObjName\n"); } else { @@ -3743,7 +3744,7 @@ static void test_Close(IWebBrowser2 *wb, BOOL do_download) SET_EXPECT(Advise_OnClose); hres = IOleObject_Close(oo, OLECLOSE_NOSAVE); ok(hres == S_OK, "OleObject_Close failed: %x\n", hres); - todo_wine CHECK_NOT_CALLED(OnFocus_FALSE); + CHECK_NOT_CALLED(OnFocus_FALSE); todo_wine CHECK_NOT_CALLED(Invoke_COMMANDSTATECHANGE_NAVIGATEBACK_FALSE); todo_wine CHECK_NOT_CALLED(Invoke_COMMANDSTATECHANGE_NAVIGATEFORWARD_FALSE); CHECK_CALLED(Advise_OnClose); @@ -4018,6 +4019,8 @@ static void test_WebBrowser_DoVerb(void) HWND hwnd; ULONG ref; BOOL res; + HRESULT hres; + VARIANT_BOOL b;
webbrowser = create_webbrowser(); init_test(webbrowser, 0); @@ -4050,6 +4053,149 @@ static void test_WebBrowser_DoVerb(void) call_DoVerb(webbrowser, OLEIVERB_HIDE); CHECK_CALLED(OnInPlaceDeactivate);
+ b = 0x100; + hres = IWebBrowser2_get_Visible(webbrowser, &b); + ok(hres == S_OK, "get_Visible failed: %08x\n", hres); + ok(b == VARIANT_TRUE, "Visible = %x\n", b); + + SET_EXPECT(CanInPlaceActivate); + SET_EXPECT(Site_GetWindow); + SET_EXPECT(OnInPlaceActivate); + SET_EXPECT(GetWindowContext); + SET_EXPECT(ShowObject); + SET_EXPECT(GetContainer); + SET_EXPECT(Frame_GetWindow); + SET_EXPECT(OnUIActivate); + SET_EXPECT(Frame_SetActiveObject); + SET_EXPECT(UIWindow_SetActiveObject); + SET_EXPECT(SetMenu); + SET_EXPECT(OnFocus_TRUE); + call_DoVerb(webbrowser, OLEIVERB_SHOW); + CHECK_CALLED(CanInPlaceActivate); + CHECK_CALLED(Site_GetWindow); + CHECK_CALLED(OnInPlaceActivate); + CHECK_CALLED(GetWindowContext); + CHECK_CALLED(ShowObject); + CHECK_CALLED(GetContainer); + CHECK_CALLED(Frame_GetWindow); + CHECK_CALLED(OnUIActivate); + CHECK_CALLED(Frame_SetActiveObject); + CHECK_CALLED(UIWindow_SetActiveObject); + CHECK_CALLED(SetMenu); + CHECK_CALLED(OnFocus_TRUE); + + b = 0x100; + hres = IWebBrowser2_get_Visible(webbrowser, &b); + ok(hres == S_OK, "get_Visible failed: %08x\n", hres); + ok(b == VARIANT_TRUE, "Visible = %x\n", b); + + call_DoVerb(webbrowser, OLEIVERB_SHOW); + call_DoVerb(webbrowser, OLEIVERB_UIACTIVATE); + + SET_EXPECT(Frame_SetActiveObject); + SET_EXPECT(UIWindow_SetActiveObject); + SET_EXPECT(OnUIDeactivate); + SET_EXPECT(OnFocus_FALSE); + SET_EXPECT(OnInPlaceDeactivate); + test_hide = TRUE; + call_DoVerb(webbrowser, OLEIVERB_HIDE); + test_hide = FALSE; + CHECK_CALLED(Frame_SetActiveObject); + CHECK_CALLED(UIWindow_SetActiveObject); + CHECK_CALLED(OnUIDeactivate); + CHECK_CALLED(OnFocus_FALSE); + CHECK_CALLED(OnInPlaceDeactivate); + + b = 0x100; + hres = IWebBrowser2_get_Visible(webbrowser, &b); + ok(hres == S_OK, "get_Visible failed: %08x\n", hres); + ok(b == VARIANT_TRUE, "Visible = %x\n", b); + + SET_EXPECT(CanInPlaceActivate); + SET_EXPECT(Site_GetWindow); + SET_EXPECT(OnInPlaceActivate); + SET_EXPECT(GetWindowContext); + SET_EXPECT(ShowObject); + SET_EXPECT(GetContainer); + SET_EXPECT(Frame_GetWindow); + SET_EXPECT(OnUIActivate); + SET_EXPECT(Frame_SetActiveObject); + SET_EXPECT(UIWindow_SetActiveObject); + SET_EXPECT(SetMenu); + SET_EXPECT(OnFocus_TRUE); + call_DoVerb(webbrowser, OLEIVERB_SHOW); + CHECK_CALLED(CanInPlaceActivate); + CHECK_CALLED(Site_GetWindow); + CHECK_CALLED(OnInPlaceActivate); + CHECK_CALLED(GetWindowContext); + CHECK_CALLED(ShowObject); + CHECK_CALLED(GetContainer); + CHECK_CALLED(Frame_GetWindow); + CHECK_CALLED(OnUIActivate); + CHECK_CALLED(Frame_SetActiveObject); + CHECK_CALLED(UIWindow_SetActiveObject); + CHECK_CALLED(SetMenu); + CHECK_CALLED(OnFocus_TRUE); + + b = 0x100; + hres = IWebBrowser2_get_Visible(webbrowser, &b); + ok(hres == S_OK, "get_Visible failed: %08x\n", hres); + ok(b == VARIANT_TRUE, "Visible = %x\n", b); + + SET_EXPECT(Frame_SetActiveObject); + SET_EXPECT(UIWindow_SetActiveObject); + SET_EXPECT(OnUIDeactivate); + SET_EXPECT(OnFocus_FALSE); + SET_EXPECT(OnInPlaceDeactivate); + test_hide = TRUE; + call_DoVerb(webbrowser, OLEIVERB_HIDE); + CHECK_CALLED(Frame_SetActiveObject); + CHECK_CALLED(UIWindow_SetActiveObject); + CHECK_CALLED(OnUIDeactivate); + CHECK_CALLED(OnFocus_FALSE); + CHECK_CALLED(OnInPlaceDeactivate); + + call_DoVerb(webbrowser, OLEIVERB_HIDE); + test_hide = FALSE; + + b = 0x100; + hres = IWebBrowser2_get_Visible(webbrowser, &b); + ok(hres == S_OK, "get_Visible failed: %08x\n", hres); + ok(b == VARIANT_TRUE, "Visible = %x\n", b); + + SET_EXPECT(CanInPlaceActivate); + SET_EXPECT(Site_GetWindow); + SET_EXPECT(OnInPlaceActivate); + SET_EXPECT(GetWindowContext); + SET_EXPECT(ShowObject); + SET_EXPECT(GetContainer); + SET_EXPECT(Frame_GetWindow); + SET_EXPECT(OnUIActivate); + SET_EXPECT(Frame_SetActiveObject); + SET_EXPECT(UIWindow_SetActiveObject); + SET_EXPECT(SetMenu); + SET_EXPECT(OnFocus_TRUE); + call_DoVerb(webbrowser, OLEIVERB_UIACTIVATE); + CHECK_CALLED(CanInPlaceActivate); + CHECK_CALLED(Site_GetWindow); + CHECK_CALLED(OnInPlaceActivate); + CHECK_CALLED(GetWindowContext); + CHECK_CALLED(ShowObject); + CHECK_CALLED(GetContainer); + CHECK_CALLED(Frame_GetWindow); + CHECK_CALLED(OnUIActivate); + CHECK_CALLED(Frame_SetActiveObject); + CHECK_CALLED(UIWindow_SetActiveObject); + CHECK_CALLED(SetMenu); + CHECK_CALLED(OnFocus_TRUE); + + b = 0x100; + hres = IWebBrowser2_get_Visible(webbrowser, &b); + ok(hres == S_OK, "get_Visible failed: %08x\n", hres); + ok(b == VARIANT_TRUE, "Visible = %x\n", b); + + call_DoVerb(webbrowser, OLEIVERB_SHOW); + test_ClientSite(webbrowser, NULL, FALSE);
ref = IWebBrowser2_Release(webbrowser);