- Added more tests.
- Make tests pass under Wine.

diff --git a/dlls/mshtml/Makefile.in b/dlls/mshtml/Makefile.in
index 299e2fe..9353b64 100644
--- a/dlls/mshtml/Makefile.in
+++ b/dlls/mshtml/Makefile.in
@@ -4,7 +4,7 @@
 VPATH     = @srcdir@
 MODULE    = mshtml.dll
 IMPORTLIB = libmshtml.$(IMPLIBEXT)
-IMPORTS   = user32 gdi32 advapi32 kernel32 ntdll
+IMPORTS   = ole32 user32 gdi32 advapi32 kernel32 ntdll
 EXTRALIBS = $(LIBUNICODE) -lstrmiids -luuid
 EXTRADEFS = -DCOM_NO_WINDOWS_H
 
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 50f6db5..095bb61 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -41,6 +41,7 @@
 
     BOOL in_place_active;
     BOOL ui_active;
+    BOOL has_key_path;
 } HTMLDocument;
 
 #define HTMLDOC(x)       ((IHTMLDocument2*)               &(x)->lpHTMLDocument2Vtbl)
diff --git a/dlls/mshtml/oleobj.c b/dlls/mshtml/oleobj.c
index d874408..f23ce18 100644
--- a/dlls/mshtml/oleobj.c
+++ b/dlls/mshtml/oleobj.c
@@ -96,18 +96,30 @@
                     hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick,
                     debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS));
 
-        hres = IDocHostUIHandler_GetOptionKeyPath(pDocHostUIHandler, &key_path, 0);
-        if(hres == S_OK && key_path && key_path[0])
-            /* FIXME: use key_path */
-            TRACE("key_path = %s\n", debugstr_w(key_path));
+        if(!This->has_key_path) {
+            hres = IDocHostUIHandler_GetOptionKeyPath(pDocHostUIHandler, &key_path, 0);
+            if(hres == S_OK && key_path) {
+                if(key_path[0]) {
+                    /* FIXME: use key_path */
+                    TRACE("key_path = %s\n", debugstr_w(key_path));
+                }
+                CoTaskMemFree(key_path);
+            }
 
-        hres = IDocHostUIHandler_QueryInterface(pDocHostUIHandler, &IID_IDocHostUIHandler2,
-                (void**)&pDocHostUIHandler2);
-        if(SUCCEEDED(hres)) {
-            /*FIXME: use override_key_path */
-            hres = IDocHostUIHandler2_GetOverrideKeyPath(pDocHostUIHandler2, &override_key_path, 0);
-            if(hres == S_OK && override_key_path && override_key_path[0])
-                FIXME("override_key_path = %s\n", debugstr_w(override_key_path));
+            hres = IDocHostUIHandler_QueryInterface(pDocHostUIHandler, &IID_IDocHostUIHandler2,
+                    (void**)&pDocHostUIHandler2);
+            if(SUCCEEDED(hres)) {
+                hres = IDocHostUIHandler2_GetOverrideKeyPath(pDocHostUIHandler2, &override_key_path, 0);
+                if(hres == S_OK && override_key_path && override_key_path[0]) {
+                    if(override_key_path[0]) {
+                        /*FIXME: use override_key_path */
+                        TRACE("override_key_path = %s\n", debugstr_w(override_key_path));
+                    }
+                    CoTaskMemFree(override_key_path);
+                }
+            }
+
+            This->has_key_path = TRUE;
         }
     }
 
@@ -503,4 +515,6 @@
 
     This->client = NULL;
     This->hostui = NULL;
+
+    This->has_key_path = FALSE;
 }
diff --git a/dlls/mshtml/olewnd.c b/dlls/mshtml/olewnd.c
index 316e444..97f349a 100644
--- a/dlls/mshtml/olewnd.c
+++ b/dlls/mshtml/olewnd.c
@@ -71,8 +71,10 @@
     if(!phwnd)
         return E_INVALIDARG;
 
-    if(!This->in_place_active)
+    if(!This->in_place_active) {
+        *phwnd = NULL;
         return E_FAIL;
+    }
 
     *phwnd = This->hwnd;
     return S_OK;
diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c
index ba28717..c8131fc 100644
--- a/dlls/mshtml/tests/htmldoc.c
+++ b/dlls/mshtml/tests/htmldoc.c
@@ -40,12 +40,12 @@
     called_ ## func = TRUE
 
 #define CHECK_CALLED(func) \
-    ok(called_ ## func, "unexpected call\n"); \
+    ok(called_ ## func, "expected " #func "\n"); \
     expect_ ## func = called_ ## func = FALSE
 
 static IUnknown *htmldoc_unk = NULL;
 static IOleDocumentView *view = NULL;
-static HWND container_hwnd = NULL, hwnd = NULL;
+static HWND container_hwnd = NULL, hwnd = NULL, last_hwnd = NULL;
 
 DEFINE_EXPECT(LockContainer);
 DEFINE_EXPECT(SetActiveObject);
@@ -525,6 +525,8 @@
                 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);
@@ -927,7 +929,7 @@
     if(activeobject) {
         HWND tmp_hwnd;
         hres = IOleInPlaceActiveObject_GetWindow(activeobject, &tmp_hwnd);
-        ok(hres == E_FAIL, "GetWindow failed: %08lx\n", hres);
+        ok(hres == E_FAIL, "GetWindow returned %08lx, expected E_FAIL\n", hres);
         ok(IsWindow(hwnd), "hwnd is destroyed\n");
     }
     
@@ -939,8 +941,97 @@
     if(windowlessobj) {
         hres = IOleInPlaceObjectWindowless_InPlaceDeactivate(windowlessobj);
         ok(hres == S_OK, "InPlaceDeactivate failed: %08lx\n", hres);
+    }
 
-        IOleInPlaceObjectWindowless_Release(windowlessobj);
+    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, "CloseVire 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(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);
+
+        /* Activate HTMLDocument again */
+        last_hwnd = hwnd;
+
+        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);
+
+        if(windowlessobj) {
+            hres = IOleInPlaceObjectWindowless_InPlaceDeactivate(windowlessobj);
+            ok(hres == S_OK, "InPlaceDeactivate failed: %08lx\n", hres);
+        }
+
+        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) {
+        SET_EXPECT(SetActiveObject);
+        SET_EXPECT(HideUI);
+        SET_EXPECT(OnUIDeactivate);
+        expect_SetActiveObject_active = FALSE;
+        hres = IOleDocumentView_UIActivate(view, FALSE);
+        ok(hres == S_OK, "UIActivate failed: %08lx\n", hres);
+        CHECK_CALLED(SetActiveObject);
+        CHECK_CALLED(HideUI);
+        CHECK_CALLED(OnUIDeactivate);
+    }
+
+    if(windowlessobj) {
+        SET_EXPECT(OnInPlaceDeactivate);
+        hres = IOleInPlaceObjectWindowless_InPlaceDeactivate(windowlessobj);
+        ok(hres == S_OK, "InPlaceDeactivate failed: %08lx\n", hres);
+        CHECK_CALLED(OnInPlaceDeactivate);
     }
 
     if(view) {
@@ -976,6 +1067,8 @@
         ok(hres == S_OK, "SetClientSite failed: %08lx\n", hres);
     }
 
+    if(windowlessobj)
+        IOleInPlaceObjectWindowless_Release(windowlessobj);
     if(oleobj)
         IOleObject_Release(oleobj);
     if(view)
diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c
index 82c423a..d2f8ce6 100644
--- a/dlls/mshtml/view.c
+++ b/dlls/mshtml/view.c
@@ -221,7 +221,7 @@
     IOleInPlaceFrame *pIPFrame;
     RECT posrect, cliprect;
     OLEINPLACEFRAMEINFO frameinfo;
-    HWND parent_hwnd, hwnd;
+    HWND parent_hwnd;
 
     TRACE("(%p)->(%x)\n", This, fUIActivate);
 
@@ -262,10 +262,22 @@
 
         TRACE("got parent window %p\n", parent_hwnd);
 
-        hwnd = 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);
+        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 {
+            This->hwnd = 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);
+            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);
@@ -275,11 +287,6 @@
             return hres;
         }
 
-        SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
-                SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_SHOWWINDOW);
-        RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE | RDW_ALLCHILDREN);
-        SetFocus(hwnd);
-
         /* NOTE:
          * Windows implementation calls:
          * RegisterWindowMessage("MSWHEEL_ROLLMSG");
@@ -293,13 +300,11 @@
         }else {
             FIXME("OnUIActivate failed: %08lx\n", hres);
             This->ui_active = FALSE;
-            DestroyWindow(hwnd);
             return hres;
         }
         if(This->frame)
             IOleInPlaceFrame_Release(This->frame);
         This->frame = pIPFrame;
-        This->hwnd = hwnd;
 
         hres = IDocHostUIHandler_ShowUI(This->hostui, 0, ACTOBJ(This), CMDTARGET(This),
                 pIPFrame, NULL);