[PATCH v2] ieframe: Deactivate UI when processing IOleObject::DoVerb(OLEIVERB_HIDE).
Dmitry Timoshkov
dmitry at baikal.ru
Tue Aug 4 10:56:26 CDT 2020
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 at 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);
--
2.26.2
More information about the wine-devel
mailing list