diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 57b64a0593f..3942831bce4 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -64,6 +64,7 @@ typedef struct { BOOL in_place_active; BOOL ui_active; + BOOL window_active; BOOL has_key_path; BindStatusCallback *status_callback; diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index a85a8418902..eb4edeafa6a 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -460,6 +460,7 @@ static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface) return 1; } +static BOOL call_UIActivate = TRUE; static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate) { IOleDocument *document; @@ -503,47 +504,70 @@ static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocum ok(hwnd == NULL, "hwnd=%p, expeted NULL\n", hwnd); } - SET_EXPECT(CanInPlaceActivate); - SET_EXPECT(GetWindowContext); - SET_EXPECT(GetWindow); - SET_EXPECT(OnInPlaceActivate); - SET_EXPECT(OnUIActivate); - SET_EXPECT(SetActiveObject); - SET_EXPECT(ShowUI); - expect_SetActiveObject_active = TRUE; - hres = IOleDocumentView_UIActivate(view, TRUE); - ok(hres == S_OK, "UIActivate failed: %08lx\n", hres); - CHECK_CALLED(CanInPlaceActivate); - CHECK_CALLED(GetWindowContext); - CHECK_CALLED(GetWindow); - CHECK_CALLED(OnInPlaceActivate); - CHECK_CALLED(OnUIActivate); - CHECK_CALLED(SetActiveObject); - CHECK_CALLED(ShowUI); + if(call_UIActivate) { + SET_EXPECT(CanInPlaceActivate); + SET_EXPECT(GetWindowContext); + SET_EXPECT(GetWindow); + SET_EXPECT(OnInPlaceActivate); + SET_EXPECT(OnUIActivate); + SET_EXPECT(SetActiveObject); + SET_EXPECT(ShowUI); + expect_SetActiveObject_active = TRUE; + hres = IOleDocumentView_UIActivate(view, TRUE); + ok(hres == S_OK, "UIActivate failed: %08lx\n", hres); + CHECK_CALLED(CanInPlaceActivate); + CHECK_CALLED(GetWindowContext); + CHECK_CALLED(GetWindow); + CHECK_CALLED(OnInPlaceActivate); + CHECK_CALLED(OnUIActivate); + CHECK_CALLED(SetActiveObject); + CHECK_CALLED(ShowUI); - if(activeobj) { - IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd); - ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); - ok(hwnd != NULL, "hwnd == NULL\n"); - if(last_hwnd) - ok(hwnd == last_hwnd, "hwnd != last_hwnd\n"); - } + if(activeobj) { + IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd); + ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); + ok(hwnd != NULL, "hwnd == NULL\n"); + if(last_hwnd) + ok(hwnd == last_hwnd, "hwnd != last_hwnd\n"); + } - hres = IOleDocumentView_UIActivate(view, TRUE); - ok(hres == S_OK, "UIActivate failed: %08lx\n", hres); + hres = IOleDocumentView_UIActivate(view, TRUE); + ok(hres == S_OK, "UIActivate failed: %08lx\n", hres); - if(activeobj) { - IOleInPlaceActiveObject_GetWindow(activeobj, &tmp_hwnd); - ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); - ok(tmp_hwnd == hwnd, "tmp_hwnd=%p, expected %p\n", tmp_hwnd, hwnd); + if(activeobj) { + IOleInPlaceActiveObject_GetWindow(activeobj, &tmp_hwnd); + ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); + ok(tmp_hwnd == hwnd, "tmp_hwnd=%p, expected %p\n", tmp_hwnd, hwnd); + } } hres = IOleDocumentView_SetRect(view, &rect); ok(hres == S_OK, "SetRect failed: %08lx\n", hres); - hres = IOleDocumentView_Show(view, TRUE); - ok(hres == S_OK, "Show failed: %08lx\n", hres); - + if(call_UIActivate) { + hres = IOleDocumentView_Show(view, TRUE); + ok(hres == S_OK, "Show failed: %08lx\n", hres); + }else { + SET_EXPECT(CanInPlaceActivate); + SET_EXPECT(GetWindowContext); + SET_EXPECT(GetWindow); + SET_EXPECT(OnInPlaceActivate); + hres = IOleDocumentView_Show(view, TRUE); + ok(hres == S_OK, "Show failed: %08lx\n", hres); + CHECK_CALLED(CanInPlaceActivate); + CHECK_CALLED(GetWindowContext); + CHECK_CALLED(GetWindow); + CHECK_CALLED(OnInPlaceActivate); + + if(activeobj) { + IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd); + ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); + ok(hwnd != NULL, "hwnd == NULL\n"); + if(last_hwnd) + ok(hwnd == last_hwnd, "hwnd != last_hwnd\n"); + } + } + if(activeobj) IOleInPlaceActiveObject_Release(activeobj); } @@ -1046,12 +1070,11 @@ static void test_HTMLDocument(void) ok(hres == E_FAIL, "GetWindow returned %08lx, expected E_FAIL\n", hres); ok(IsWindow(hwnd), "hwnd is destroyed\n"); } - + if(view) { hres = IOleDocumentView_Show(view, FALSE); ok(hres == S_OK, "Show failed: %08lx\n", hres); } - if(windowlessobj) { hres = IOleInPlaceObjectWindowless_InPlaceDeactivate(windowlessobj); ok(hres == S_OK, "InPlaceDeactivate failed: %08lx\n", hres); @@ -1151,6 +1174,87 @@ static void test_HTMLDocument(void) CHECK_CALLED(OnInPlaceDeactivate); } + if(oleobj) { + SET_EXPECT(GetContainer); + SET_EXPECT(LockContainer); + expect_LockContainer_fLock = FALSE; + hres = IOleObject_Close(oleobj, OLECLOSE_NOSAVE); + ok(hres == S_OK, "Close failed: %08lx\n", hres); + CHECK_CALLED(GetContainer); + CHECK_CALLED(LockContainer); + + if(view) + IOleDocumentView_Release(view); + + hres = IOleObject_GetClientSite(oleobj, &clientsite); + ok(clientsite == &ClientSite, "clientsite=%p, expected %p\n", clientsite, &ClientSite); + + hres = IOleObject_SetClientSite(oleobj, NULL); + ok(hres == S_OK, "SetClientSite failed: %08lx\n", hres); + + hres = IOleObject_GetClientSite(oleobj, &clientsite); + ok(hres == S_OK, "GetClientSite failed: %08lx\n", hres); + ok(clientsite == NULL, "GetClientSite() = %p, expected NULL\n", clientsite); + + SET_EXPECT(GetHostInfo); + SET_EXPECT(GetWindow); + hres = IOleObject_SetClientSite(oleobj, &ClientSite); + ok(hres == S_OK, "SetClientSite failed: %08lx\n", hres); + CHECK_CALLED(GetHostInfo); + CHECK_CALLED(GetWindow); + + /* Activate HTMLDocument again, this time without UIActivate */ + last_hwnd = hwnd; + call_UIActivate = FALSE; + + SET_EXPECT(GetContainer); + SET_EXPECT(LockContainer); + SET_EXPECT(ActivateMe); + expect_LockContainer_fLock = TRUE; + hres = IOleObject_DoVerb(oleobj, OLEIVERB_SHOW, NULL, &ClientSite, -1, container_hwnd, &rect); + ok(hres == S_OK, "DoVerb failed: %08lx\n", hres); + CHECK_CALLED(GetContainer); + CHECK_CALLED(LockContainer); + CHECK_CALLED(ActivateMe); + } + + if(activeobject) { + HWND tmp_hwnd; + hres = IOleInPlaceActiveObject_GetWindow(activeobject, &tmp_hwnd); + ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); + ok(tmp_hwnd == hwnd, "tmp_hwnd=%p, expected %p\n", tmp_hwnd, hwnd); + } + + if(view) { + expect_SetActiveObject_active = FALSE; + hres = IOleDocumentView_UIActivate(view, FALSE); + ok(hres == S_OK, "UIActivate failed: %08lx\n", hres); + } + + if(windowlessobj) { + SET_EXPECT(OnInPlaceDeactivate); + hres = IOleInPlaceObjectWindowless_InPlaceDeactivate(windowlessobj); + ok(hres == S_OK, "InPlaceDeactivate failed: %08lx\n", hres); + CHECK_CALLED(OnInPlaceDeactivate); + } + + if(view) { + IOleInPlaceSite *inplacesite = (IOleInPlaceSite*)0xff00ff00; + + hres = IOleDocumentView_Show(view, FALSE); + ok(hres == S_OK, "Show failed: %08lx\n", hres); + + hres = IOleDocumentView_CloseView(view, 0); + ok(hres == S_OK, "CloseView failed: %08lx\n", hres); + + hres = IOleDocumentView_SetInPlaceSite(view, NULL); + ok(hres == S_OK, "SetInPlaceSite failed: %08lx\n", hres); + + hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite); + ok(hres == S_OK, "SetInPlaceSite failed: %08lx\n", hres); + ok(inplacesite == NULL, "inplacesite=%p, expected NULL\n", inplacesite); + } + if(view) { IOleInPlaceSite *inplacesite = (IOleInPlaceSite*)0xff00ff00; @@ -1166,9 +1270,7 @@ static void test_HTMLDocument(void) hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite); ok(hres == S_OK, "SetInPlaceSite failed: %08lx\n", hres); ok(inplacesite == NULL, "inplacesite=%p, expected NULL\n", inplacesite); - } - if(oleobj) { SET_EXPECT(GetContainer); SET_EXPECT(LockContainer); expect_LockContainer_fLock = FALSE; diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c index b39c0d401b7..0798dfe1919 100644 --- a/dlls/mshtml/view.c +++ b/dlls/mshtml/view.c @@ -123,6 +123,87 @@ static void register_serverwnd_class(void) serverwnd_class = RegisterClassExW(&wndclass); } +static HRESULT activate_window(HTMLDocument *This) +{ + IOleInPlaceUIWindow *pIPWnd; + IOleInPlaceFrame *pIPFrame; + RECT posrect, cliprect; + OLEINPLACEFRAMEINFO frameinfo; + HWND parent_hwnd; + HRESULT hres; + + if(!serverwnd_class) + register_serverwnd_class(); + + hres = IOleInPlaceSite_CanInPlaceActivate(This->ipsite); + if(hres != S_OK) { + WARN("CanInPlaceActivate returned: %08lx\n", hres); + return FAILED(hres) ? hres : E_FAIL; + } + + hres = IOleInPlaceSite_GetWindowContext(This->ipsite, &pIPFrame, &pIPWnd, &posrect, &cliprect, &frameinfo); + if(FAILED(hres)) { + WARN("GetWindowContext failed: %08lx\n", hres); + return hres; + } + if(pIPWnd) + IOleInPlaceUIWindow_Release(pIPWnd); + TRACE("got window context: %p %p {%ld %ld %ld %ld} {%ld %ld %ld %ld} {%d %x %p %p %d}\n", + pIPFrame, pIPWnd, posrect.left, posrect.top, posrect.right, posrect.bottom, + cliprect.left, cliprect.top, cliprect.right, cliprect.bottom, + frameinfo.cb, frameinfo.fMDIApp, frameinfo.hwndFrame, frameinfo.haccel, frameinfo.cAccelEntries); + + hres = IOleInPlaceSite_GetWindow(This->ipsite, &parent_hwnd); + if(FAILED(hres)) { + WARN("GetWindow failed: %08lx\n", hres); + return hres; + } + + TRACE("got parent window %p\n", parent_hwnd); + + if(This->hwnd) { + if(GetParent(This->hwnd) != parent_hwnd) + SetParent(This->hwnd, parent_hwnd); + SetWindowPos(This->hwnd, HWND_TOP, + posrect.left, posrect.top, posrect.right-posrect.left, posrect.bottom-posrect.top, + SWP_NOACTIVATE | SWP_SHOWWINDOW); + }else { + CreateWindowExW(0, wszInternetExplorer_Server, NULL, + WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + posrect.left, posrect.top, posrect.right-posrect.left, posrect.bottom-posrect.top, + parent_hwnd, NULL, hInst, This); + + TRACE("Created window %p\n", This->hwnd); + + SetWindowPos(This->hwnd, NULL, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_SHOWWINDOW); + RedrawWindow(This->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE | RDW_ALLCHILDREN); + SetFocus(This->hwnd); + + /* NOTE: + * Windows implementation calls: + * RegisterWindowMessage("MSWHEEL_ROLLMSG"); + * SetTimer(This->hwnd, TIMER_ID, 100, NULL); + */ + } + + This->in_place_active = TRUE; + hres = IOleInPlaceSite_OnInPlaceActivate(This->ipsite); + if(FAILED(hres)) { + WARN("OnInPlaceActivate failed: %08lx\n", hres); + This->in_place_active = FALSE; + return hres; + } + + if(This->frame) + IOleInPlaceFrame_Release(This->frame); + This->frame = pIPFrame; + + This->window_active = TRUE; + + return S_OK; +} + /********************************************************** * IOleDocumentView implementation */ @@ -236,10 +317,20 @@ static HRESULT WINAPI OleDocumentView_SetRectComplex(IOleDocumentView *iface, LP static HRESULT WINAPI OleDocumentView_Show(IOleDocumentView *iface, BOOL fShow) { HTMLDocument *This = DOCVIEW_THIS(iface); + HRESULT hres; + TRACE("(%p)->(%x)\n", This, fShow); - if(This->hwnd) - ShowWindow(This->hwnd, fShow); + if(fShow) { + if(!This->ui_active) { + hres = activate_window(This); + if(FAILED(hres)) + return hres; + } + ShowWindow(This->hwnd, SW_SHOW); + }else { + ShowWindow(This->hwnd, SW_HIDE); + } return S_OK; } @@ -248,11 +339,6 @@ static HRESULT WINAPI OleDocumentView_UIActivate(IOleDocumentView *iface, BOOL f { HTMLDocument *This = DOCVIEW_THIS(iface); HRESULT hres; - IOleInPlaceUIWindow *pIPWnd; - IOleInPlaceFrame *pIPFrame; - RECT posrect, cliprect; - OLEINPLACEFRAMEINFO frameinfo; - HWND parent_hwnd; TRACE("(%p)->(%x)\n", This, fUIActivate); @@ -264,94 +350,41 @@ static HRESULT WINAPI OleDocumentView_UIActivate(IOleDocumentView *iface, BOOL f if(fUIActivate) { if(This->ui_active) return S_OK; - if(!serverwnd_class) - register_serverwnd_class(); - hres = IOleInPlaceSite_CanInPlaceActivate(This->ipsite); - if(hres != S_OK) { - WARN("CanInPlaceActivate returned: %08lx\n", hres); - return FAILED(hres) ? hres : E_FAIL; + if(!This->window_active) { + hres = activate_window(This); + if(FAILED(hres)) + return hres; } - hres = IOleInPlaceSite_GetWindowContext(This->ipsite, &pIPFrame, &pIPWnd, &posrect, &cliprect, &frameinfo); - if(FAILED(hres)) { - WARN("GetWindowContext failed: %08lx\n", hres); - return hres; - } - if(pIPWnd) - IOleInPlaceUIWindow_Release(pIPWnd); - TRACE("got window context: %p %p {%ld %ld %ld %ld} {%ld %ld %ld %ld} {%d %x %p %p %d}\n", - pIPFrame, pIPWnd, posrect.left, posrect.top, posrect.right, posrect.bottom, - cliprect.left, cliprect.top, cliprect.right, cliprect.bottom, - frameinfo.cb, frameinfo.fMDIApp, frameinfo.hwndFrame, frameinfo.haccel, frameinfo.cAccelEntries); - - hres = IOleInPlaceSite_GetWindow(This->ipsite, &parent_hwnd); - if(FAILED(hres)) { - WARN("GetWindow failed: %08lx\n", hres); - return hres; - } - - TRACE("got parent window %p\n", parent_hwnd); - - if(This->hwnd) { - if(GetParent(This->hwnd) != parent_hwnd) - SetParent(This->hwnd, parent_hwnd); - SetWindowPos(This->hwnd, HWND_TOP, - posrect.left, posrect.top, posrect.right-posrect.left, posrect.bottom-posrect.top, - SWP_NOACTIVATE | SWP_SHOWWINDOW); - }else { - CreateWindowExW(0, wszInternetExplorer_Server, NULL, - WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, - posrect.left, posrect.top, posrect.right-posrect.left, posrect.bottom-posrect.top, - parent_hwnd, NULL, hInst, This); - - TRACE("Created window %p\n", This->hwnd); - - SetWindowPos(This->hwnd, NULL, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_SHOWWINDOW); - RedrawWindow(This->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE | RDW_ALLCHILDREN); - SetFocus(This->hwnd); - } - - This->in_place_active = TRUE; - hres = IOleInPlaceSite_OnInPlaceActivate(This->ipsite); - if(FAILED(hres)) { - WARN("OnInPlaceActivate failed: %08lx\n", hres); - This->in_place_active = FALSE; - return hres; - } - - /* NOTE: - * Windows implementation calls: - * RegisterWindowMessage("MSWHEEL_ROLLMSG"); - * SetTimer(This->hwnd, TIMER_ID, 100, NULL); - */ - - This->ui_active = TRUE; hres = IOleInPlaceSite_OnUIActivate(This->ipsite); if(SUCCEEDED(hres)) { - IOleInPlaceFrame_SetActiveObject(pIPFrame, ACTOBJ(This), wszHTML_Document); + IOleInPlaceFrame_SetActiveObject(This->frame, ACTOBJ(This), wszHTML_Document); }else { FIXME("OnUIActivate failed: %08lx\n", hres); + IOleInPlaceFrame_Release(This->frame); + This->frame = NULL; This->ui_active = FALSE; return hres; } - if(This->frame) - IOleInPlaceFrame_Release(This->frame); - This->frame = pIPFrame; hres = IDocHostUIHandler_ShowUI(This->hostui, 0, ACTOBJ(This), CMDTARGET(This), - pIPFrame, NULL); + This->frame, NULL); if(FAILED(hres)) IDocHostUIHandler_HideUI(This->hostui); + + This->ui_active = TRUE; }else { - This->ui_active = FALSE; - if(This->frame) - IOleInPlaceFrame_SetActiveObject(This->frame, NULL, NULL); - if(This->hostui) - IDocHostUIHandler_HideUI(This->hostui); - if(This->ipsite) - IOleInPlaceSite_OnUIDeactivate(This->ipsite, FALSE); + This->window_active = FALSE; + if(This->ui_active) { + This->ui_active = FALSE; + if(This->frame) + IOleInPlaceFrame_SetActiveObject(This->frame, NULL, NULL); + if(This->hostui) + IDocHostUIHandler_HideUI(This->hostui); + if(This->ipsite) + IOleInPlaceSite_OnUIDeactivate(This->ipsite, FALSE); + } } return S_OK; } @@ -529,4 +562,5 @@ void HTMLDocument_View_Init(HTMLDocument *This) This->in_place_active = FALSE; This->ui_active = FALSE; + This->window_active = FALSE; }