comctl32: toolbar: Fix the TB_ADDSTRING from resources for a NUL delimiter.
[wine] / dlls / mshtml / tests / htmldoc.c
1 /*
2  * Copyright 2005 Jacek Caban
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <wine/test.h>
23 #include <stdarg.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "ole2.h"
28 #include "mshtml.h"
29 #include "docobj.h"
30 #include "mshtmhst.h"
31 #include "mshtmdid.h"
32 #include "mshtmcid.h"
33 #include "hlink.h"
34 #include "idispids.h"
35 #include "shlguid.h"
36
37 #include "initguid.h"
38 DEFINE_SHLGUID(CGID_Undocumented, 0x000214D4L, 0, 0);
39
40 #define DEFINE_EXPECT(func) \
41     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
42
43 #define SET_EXPECT(func) \
44     expect_ ## func = TRUE
45
46 #define CHECK_EXPECT(func) \
47     do { \
48         ok(expect_ ##func, "unexpected call " #func "\n"); \
49         expect_ ## func = FALSE; \
50         called_ ## func = TRUE; \
51     }while(0)
52
53 #define CHECK_EXPECT2(func) \
54     do { \
55         ok(expect_ ##func, "unexpected call " #func "\n"); \
56         called_ ## func = TRUE; \
57     }while(0)
58
59 #define CHECK_CALLED(func) \
60     do { \
61         ok(called_ ## func, "expected " #func "\n"); \
62         expect_ ## func = called_ ## func = FALSE; \
63     }while(0)
64
65 static IOleDocumentView *view = NULL;
66 static HWND container_hwnd = NULL, hwnd = NULL, last_hwnd = NULL;
67
68 DEFINE_EXPECT(LockContainer);
69 DEFINE_EXPECT(SetActiveObject);
70 DEFINE_EXPECT(GetWindow);
71 DEFINE_EXPECT(CanInPlaceActivate);
72 DEFINE_EXPECT(OnInPlaceActivate);
73 DEFINE_EXPECT(OnUIActivate);
74 DEFINE_EXPECT(GetWindowContext);
75 DEFINE_EXPECT(OnUIDeactivate);
76 DEFINE_EXPECT(OnInPlaceDeactivate);
77 DEFINE_EXPECT(GetContainer);
78 DEFINE_EXPECT(ShowUI);
79 DEFINE_EXPECT(ActivateMe);
80 DEFINE_EXPECT(GetHostInfo);
81 DEFINE_EXPECT(HideUI);
82 DEFINE_EXPECT(GetOptionKeyPath);
83 DEFINE_EXPECT(GetOverrideKeyPath);
84 DEFINE_EXPECT(SetStatusText);
85 DEFINE_EXPECT(QueryStatus_SETPROGRESSTEXT);
86 DEFINE_EXPECT(QueryStatus_OPEN);
87 DEFINE_EXPECT(QueryStatus_NEW);
88 DEFINE_EXPECT(Exec_SETPROGRESSMAX);
89 DEFINE_EXPECT(Exec_SETPROGRESSPOS);
90 DEFINE_EXPECT(Exec_HTTPEQUIV_DONE); 
91 DEFINE_EXPECT(Exec_SETDOWNLOADSTATE_0);
92 DEFINE_EXPECT(Exec_SETDOWNLOADSTATE_1);
93 DEFINE_EXPECT(Exec_ShellDocView_37);
94 DEFINE_EXPECT(Exec_UPDATECOMMANDS);
95 DEFINE_EXPECT(Exec_SETTITLE);
96 DEFINE_EXPECT(Exec_HTTPEQUIV);
97 DEFINE_EXPECT(Exec_MSHTML_PARSECOMPLETE);
98 DEFINE_EXPECT(Invoke_AMBIENT_USERMODE);
99 DEFINE_EXPECT(Invoke_AMBIENT_DLCONTROL);
100 DEFINE_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
101 DEFINE_EXPECT(Invoke_AMBIENT_SILENT);
102 DEFINE_EXPECT(Invoke_AMBIENT_USERAGENT);
103 DEFINE_EXPECT(Invoke_AMBIENT_PALETTE);
104 DEFINE_EXPECT(GetDropTarget);
105 DEFINE_EXPECT(UpdateUI);
106 DEFINE_EXPECT(Navigate);
107 DEFINE_EXPECT(OnFrameWindowActivate);
108 DEFINE_EXPECT(OnChanged_READYSTATE);
109 DEFINE_EXPECT(OnChanged_1005);
110 DEFINE_EXPECT(GetDisplayName);
111 DEFINE_EXPECT(BindToStorage);
112 DEFINE_EXPECT(Abort);
113
114 static BOOL expect_LockContainer_fLock;
115 static BOOL expect_SetActiveObject_active;
116 static BOOL set_clientsite = FALSE, container_locked = FALSE;
117 static BOOL readystate_set_loading = FALSE;
118 static enum load_state_t {
119     LD_DOLOAD,
120     LD_LOADING,
121     LD_INTERACTIVE,
122     LD_COMPLETE,
123     LD_NO
124 } load_state;
125
126 static LPCOLESTR expect_status_text = NULL;
127
128 static HRESULT QueryInterface(REFIID riid, void **ppv);
129 static void test_readyState(IUnknown*);
130
131 static HRESULT WINAPI HlinkFrame_QueryInterface(IHlinkFrame *iface, REFIID riid, void **ppv)
132 {
133     ok(0, "unexpected call\n");
134     return E_NOTIMPL;
135 }
136
137 static ULONG WINAPI HlinkFrame_AddRef(IHlinkFrame *iface)
138 {
139     return 2;
140 }
141
142 static ULONG WINAPI HlinkFrame_Release(IHlinkFrame *iface)
143 {
144     return 1;
145 }
146
147 static HRESULT WINAPI HlinkFrame_SetBrowseContext(IHlinkFrame *iface,
148                                                   IHlinkBrowseContext *pihlbc)
149 {
150     ok(0, "unexpected call\n");
151     return E_NOTIMPL;
152 }
153
154 static HRESULT WINAPI HlinkFrame_GetBrowseContext(IHlinkFrame *iface,
155                                                   IHlinkBrowseContext **ppihlbc)
156 {
157     ok(0, "unexpected call\n");
158     return E_NOTIMPL;
159 }
160
161 static HRESULT WINAPI HlinkFrame_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPBC pbc,
162                                           IBindStatusCallback *pibsc, IHlink *pihlNavigate)
163 {
164     HRESULT hres;
165
166     CHECK_EXPECT(Navigate);
167
168     ok(grfHLNF == 0, "grfHLNF=%d, expected 0\n", grfHLNF);
169     ok(pbc != NULL, "pbc == NULL\n");
170     ok(pibsc != NULL, "pubsc == NULL\n");
171     ok(pihlNavigate != NULL, "puhlNavigate == NULL\n");
172
173     if(pihlNavigate) {
174         LPWSTR frame_name = (LPWSTR)0xdeadbeef;
175         LPWSTR location = (LPWSTR)0xdeadbeef;
176         IHlinkSite *site;
177         IMoniker *mon = NULL;
178         DWORD site_data = 0xdeadbeef;
179
180         hres = IHlink_GetTargetFrameName(pihlNavigate, &frame_name);
181         ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
182         ok(frame_name == NULL, "frame_name = %p\n", frame_name);
183
184         hres = IHlink_GetMonikerReference(pihlNavigate, 1, &mon, &location);
185         ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
186         ok(location == NULL, "location = %p\n", location);
187         ok(mon != NULL, "mon == NULL\n");
188
189         hres = IHlink_GetHlinkSite(pihlNavigate, &site, &site_data);
190         ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
191         ok(site == NULL, "site = %p\n, expected NULL\n", site);
192         ok(site_data == 0xdeadbeef, "site_data = %x\n", site_data);
193     }
194
195     return S_OK;
196 }
197
198 static HRESULT WINAPI HlinkFrame_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF,
199         IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, DWORD dwreserved)
200 {
201     ok(0, "unexpected call\n");
202     return E_NOTIMPL;
203 }
204
205 static HRESULT WINAPI HlinkFrame_UpdateHlink(IHlinkFrame *iface, ULONG uHLID,
206         IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
207 {
208     ok(0, "unexpected call\n");
209     return E_NOTIMPL;
210 }
211
212 static const IHlinkFrameVtbl HlinkFrameVtbl = {
213     HlinkFrame_QueryInterface,
214     HlinkFrame_AddRef,
215     HlinkFrame_Release,
216     HlinkFrame_SetBrowseContext,
217     HlinkFrame_GetBrowseContext,
218     HlinkFrame_Navigate,
219     HlinkFrame_OnNavigate,
220     HlinkFrame_UpdateHlink
221 };
222
223 static IHlinkFrame HlinkFrame = { &HlinkFrameVtbl };
224
225 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
226         REFIID riid, void**ppv)
227 {
228     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
229         *ppv = iface;
230         return S_OK;
231     }
232
233     ok(0, "unexpected call\n");
234     return E_NOINTERFACE;
235 }
236
237 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
238 {
239     return 2;
240 }
241
242 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
243 {
244     return 1;
245 }
246
247 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
248 {
249     switch(dispID) {
250     case DISPID_READYSTATE:
251         CHECK_EXPECT2(OnChanged_READYSTATE);
252         if(readystate_set_loading) {
253             readystate_set_loading = FALSE;
254             load_state = LD_LOADING;
255         }
256         test_readyState(NULL);
257         return S_OK;
258     case 1005:
259         CHECK_EXPECT(OnChanged_1005);
260         test_readyState(NULL);
261         load_state = LD_INTERACTIVE;
262         return S_OK;
263     }
264
265     ok(0, "unexpected id %d\n", dispID);
266     return E_NOTIMPL;
267 }
268
269 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
270 {
271     ok(0, "unexpected call\n");
272     return E_NOTIMPL;
273 }
274
275 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
276     PropertyNotifySink_QueryInterface,
277     PropertyNotifySink_AddRef,
278     PropertyNotifySink_Release,
279     PropertyNotifySink_OnChanged,
280     PropertyNotifySink_OnRequestEdit
281 };
282
283 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
284
285 static HRESULT WINAPI Binding_QueryInterface(IBinding *iface, REFIID riid, void **ppv)
286 {
287     if(IsEqualGUID(&IID_IWinInetHttpInfo, riid))
288         return E_NOINTERFACE; /* TODO */
289
290     if(IsEqualGUID(&IID_IWinInetInfo, riid))
291         return E_NOINTERFACE; /* TODO */
292
293     ok(0, "unexpected call\n");
294     return E_NOINTERFACE;
295 }
296
297 static ULONG WINAPI Binding_AddRef(IBinding *iface)
298 {
299     return 2;
300 }
301
302 static ULONG WINAPI Binding_Release(IBinding *iface)
303 {
304     return 1;
305 }
306
307 static HRESULT WINAPI Binding_Abort(IBinding *iface)
308 {
309     CHECK_EXPECT(Abort);
310     return S_OK;
311 }
312
313 static HRESULT WINAPI Binding_Suspend(IBinding *iface)
314 {
315     ok(0, "unexpected call\n");
316     return E_NOTIMPL;
317 }
318
319 static HRESULT WINAPI Binding_Resume(IBinding *iface)
320 {
321     ok(0, "unexpected call\n");
322     return E_NOTIMPL;
323 }
324
325 static HRESULT WINAPI Binding_SetPriority(IBinding *iface, LONG nPriority)
326 {
327     ok(0, "unexpected call\n");
328     return E_NOTIMPL;
329 }
330
331 static HRESULT WINAPI Binding_GetPriority(IBinding *iface, LONG *pnPriority)
332 {
333     ok(0, "unexpected call\n");
334     return E_NOTIMPL;
335 }
336
337 static HRESULT WINAPI Binding_GetBindResult(IBinding *iface, CLSID *pclsidProtocol,
338         DWORD *pdwResult, LPOLESTR *pszResult, DWORD *pdwReserved)
339 {
340     ok(0, "unexpected call\n");
341     return E_NOTIMPL;
342 }
343
344 static const IBindingVtbl BindingVtbl = {
345     Binding_QueryInterface,
346     Binding_AddRef,
347     Binding_Release,
348     Binding_Abort,
349     Binding_Suspend,
350     Binding_Resume,
351     Binding_SetPriority,
352     Binding_GetPriority,
353     Binding_GetBindResult
354 };
355
356 static IBinding Binding = { &BindingVtbl };
357
358 static HRESULT WINAPI Moniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
359 {
360     ok(0, "unexpected call\n");
361     return E_NOINTERFACE;
362 }
363
364 static ULONG WINAPI Moniker_AddRef(IMoniker *iface)
365 {
366     return 2;
367 }
368
369 static ULONG WINAPI Moniker_Release(IMoniker *iface)
370 {
371     return 1;
372 }
373
374 static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
375 {
376     ok(0, "unexpected call\n");
377     return E_NOTIMPL;
378 }
379
380 static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
381 {
382     ok(0, "unexpected call\n");
383     return E_NOTIMPL;
384 }
385
386 static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
387 {
388     ok(0, "unexpected call\n");
389     return E_NOTIMPL;
390 }
391
392 static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
393 {
394     ok(0, "unexpected call\n");
395     return E_NOTIMPL;
396 }
397
398 static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
399 {
400     ok(0, "unexpected call\n");
401     return E_NOTIMPL;
402 }
403
404 static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pcb, IMoniker *pmkToLeft,
405         REFIID riidResult, void **ppvResult)
406 {
407     ok(0, "unexpected call\n");
408     return E_NOTIMPL;
409 }
410
411 static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
412         REFIID riid, void **ppv)
413 {
414     IBindStatusCallback *callback = NULL;
415     FORMATETC formatetc = {0xc02d, NULL, 1, -1, TYMED_ISTREAM};
416     STGMEDIUM stgmedium;
417     BINDINFO bindinfo;
418     DWORD bindf, written=0;
419     IStream *stream;
420     HRESULT hres;
421
422     static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
423     static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};
424     static const char html_page[] = "<html><body>test</body></html>";
425
426     CHECK_EXPECT(BindToStorage);
427
428     ok(pbc != NULL, "pbc == NULL\n");
429     ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
430     ok(IsEqualGUID(&IID_IStream, riid), "unexpected riid\n");
431     ok(ppv != NULL, "ppv == NULL\n");
432     ok(*ppv == NULL, "*ppv=%p\n", *ppv);
433
434     hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown**)&callback);
435     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
436     ok(callback != NULL, "callback == NULL\n");
437
438     memset(&bindinfo, 0xf0, sizeof(bindinfo));
439     bindinfo.cbSize = sizeof(bindinfo);
440
441     hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo);
442     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
443     ok(bindf == (BINDF_PULLDATA|BINDF_ASYNCSTORAGE|BINDF_ASYNCHRONOUS), "bindf = %08x\n", bindf);
444     ok(bindinfo.cbSize == sizeof(bindinfo), "bindinfo.cbSize=%d\n", bindinfo.cbSize);
445     ok(bindinfo.szExtraInfo == NULL, "bindinfo.szExtraInfo=%p\n", bindinfo.szExtraInfo);
446     /* TODO: test stgmedData */
447     ok(bindinfo.grfBindInfoF == 0, "bindinfo.grfBinfInfoF=%08x\n", bindinfo.grfBindInfoF);
448     ok(bindinfo.dwBindVerb == 0, "bindinfo.dwBindVerb=%d\n", bindinfo.dwBindVerb);
449     ok(bindinfo.szCustomVerb == 0, "bindinfo.szCustomVerb=%p\n", bindinfo.szCustomVerb);
450     ok(bindinfo.cbstgmedData == 0, "bindinfo.cbstgmedData=%d\n", bindinfo.cbstgmedData);
451     ok(bindinfo.dwOptions == 0x80000, "bindinfo.dwOptions=%x\n", bindinfo.dwOptions);
452     ok(bindinfo.dwOptionsFlags == 0, "bindinfo.dwOptionsFlags=%d\n", bindinfo.dwOptionsFlags);
453     /* TODO: test dwCodePage */
454     /* TODO: test securityAttributes */
455     ok(IsEqualGUID(&IID_NULL, &bindinfo.iid), "unexepected bindinfo.iid\n");
456     ok(bindinfo.pUnk == NULL, "bindinfo.pUnk=%p\n", bindinfo.pUnk);
457     ok(bindinfo.dwReserved == 0, "bindinfo.dwReserved=%d\n", bindinfo.dwReserved);
458
459     hres = IBindStatusCallback_OnStartBinding(callback, 0, &Binding);
460     ok(hres == S_OK, "OnStartBinding failed: %08x\n", hres);
461
462     hres = IBindStatusCallback_OnProgress(callback, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE,
463                                           wszTextHtml);
464     ok(hres == S_OK, "OnProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
465
466     hres = IBindStatusCallback_OnProgress(callback, 0, 0, BINDSTATUS_BEGINDOWNLOADDATA,
467                                           NULL);
468     ok(hres == S_OK, "OnProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
469
470     CreateStreamOnHGlobal(0, TRUE, &stream);
471     IStream_Write(stream, html_page, sizeof(html_page)-1, &written);
472
473     stgmedium.tymed = TYMED_ISTREAM;
474     U(stgmedium).pstm = stream;
475     stgmedium.pUnkForRelease = (IUnknown*)iface;
476     hres = IBindStatusCallback_OnDataAvailable(callback,
477             BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
478             100, &formatetc, &stgmedium);
479     ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
480     IStream_Release(stream);
481
482     hres = IBindStatusCallback_OnProgress(callback, sizeof(html_page)-1, sizeof(html_page)-1,
483             BINDSTATUS_ENDDOWNLOADDATA, NULL);
484     ok(hres == S_OK, "OnProgress(BINDSTATUS_ENDDOWNLOADDATA) failed: %08x\n", hres);
485
486     hres = IBindStatusCallback_OnStopBinding(callback, S_OK, NULL);
487     ok(hres == S_OK, "OnStopBinding failed: %08x\n", hres);
488
489     IBindStatusCallback_Release(callback);
490
491     return S_OK;
492 }
493
494 static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
495         IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
496 {
497     ok(0, "unexpected call\n");
498     return E_NOTIMPL;
499 }
500
501 static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
502         BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
503 {
504     ok(0, "unexpected call\n");
505     return E_NOTIMPL;
506 }
507
508 static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
509 {
510     ok(0, "unexpected call\n");
511     return E_NOTIMPL;
512 }
513
514 static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
515 {
516     ok(0, "unexpected call\n");
517     return E_NOTIMPL;
518 }
519
520 static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
521 {
522     ok(0, "unexpected call\n");
523     return E_NOTIMPL;
524 }
525
526 static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
527         IMoniker *pmkNewlyRunning)
528 {
529     ok(0, "unexpected call\n");
530     return E_NOTIMPL;
531 }
532
533 static HRESULT WINAPI Moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc,
534         IMoniker *pmkToLeft, FILETIME *pFileTime)
535 {
536     ok(0, "unexpected call\n");
537     return E_NOTIMPL;
538 }
539
540 static HRESULT WINAPI Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
541 {
542     ok(0, "unexpected call\n");
543     return E_NOTIMPL;
544 }
545
546 static HRESULT WINAPI Moniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther,
547         IMoniker **ppmkPrefix)
548 {
549     ok(0, "unexpected call\n");
550     return E_NOTIMPL;
551 }
552
553 static HRESULT WINAPI Moniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther,
554         IMoniker **pmkRelPath)
555 {
556     ok(0, "unexpected call\n");
557     return E_NOTIMPL;
558 }
559
560 static HRESULT WINAPI Moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
561         IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
562 {
563     static const WCHAR winetest_test[] =
564         {'w','i','n','e','t','e','s','t',':','t','e','s','t',0};
565
566     CHECK_EXPECT2(GetDisplayName);
567
568     /* ok(pbc != NULL, "pbc == NULL\n"); */
569     ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
570     ok(ppszDisplayName != NULL, "ppszDisplayName == NULL\n");
571     ok(*ppszDisplayName == NULL, "*ppszDisplayName=%p\n", *ppszDisplayName);
572
573     *ppszDisplayName = CoTaskMemAlloc(sizeof(winetest_test));
574     memcpy(*ppszDisplayName, winetest_test, sizeof(winetest_test));
575
576     return S_OK;
577 }
578
579 static HRESULT WINAPI Moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
580         IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
581 {
582     ok(0, "unexpected call\n");
583     return E_NOTIMPL;
584 }
585
586 static HRESULT WINAPI Moniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
587 {
588     ok(0, "unexpected call\n");
589     return E_NOTIMPL;
590 }
591
592 static const IMonikerVtbl MonikerVtbl = {
593     Moniker_QueryInterface,
594     Moniker_AddRef,
595     Moniker_Release,
596     Moniker_GetClassID,
597     Moniker_IsDirty,
598     Moniker_Load,
599     Moniker_Save,
600     Moniker_GetSizeMax,
601     Moniker_BindToObject,
602     Moniker_BindToStorage,
603     Moniker_Reduce,
604     Moniker_ComposeWith,
605     Moniker_Enum,
606     Moniker_IsEqual,
607     Moniker_Hash,
608     Moniker_IsRunning,
609     Moniker_GetTimeOfLastChange,
610     Moniker_Inverse,
611     Moniker_CommonPrefixWith,
612     Moniker_RelativePathTo,
613     Moniker_GetDisplayName,
614     Moniker_ParseDisplayName,
615     Moniker_IsSystemMoniker
616 };
617
618 static IMoniker Moniker = { &MonikerVtbl };
619
620 static HRESULT WINAPI OleContainer_QueryInterface(IOleContainer *iface, REFIID riid, void **ppv)
621 {
622     return QueryInterface(riid, ppv);
623 }
624
625 static ULONG WINAPI OleContainer_AddRef(IOleContainer *iface)
626 {
627     return 2;
628 }
629
630 static ULONG WINAPI OleContainer_Release(IOleContainer *iface)
631 {
632     return 1;
633 }
634
635 static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer *iface, IBindCtx *pbc,
636         LPOLESTR pszDiaplayName, ULONG *pchEaten, IMoniker **ppmkOut)
637 {
638     ok(0, "unexpected call\n");
639     return E_NOTIMPL;
640 }
641
642 static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer *iface, DWORD grfFlags,
643         IEnumUnknown **ppenum)
644 {
645     ok(0, "unexpected call\n");
646     return E_NOTIMPL;
647 }
648
649 static HRESULT WINAPI OleContainer_LockContainer(IOleContainer *iface, BOOL fLock)
650 {
651     CHECK_EXPECT(LockContainer);
652     ok(expect_LockContainer_fLock == fLock, "fLock=%x, expected %x\n", fLock, expect_LockContainer_fLock);
653     return S_OK;
654 }
655
656 static const IOleContainerVtbl OleContainerVtbl = {
657     OleContainer_QueryInterface,
658     OleContainer_AddRef,
659     OleContainer_Release,
660     OleContainer_ParseDisplayName,
661     OleContainer_EnumObjects,
662     OleContainer_LockContainer
663 };
664
665 static IOleContainer OleContainer = { &OleContainerVtbl };
666
667 static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
668 {
669     return QueryInterface(riid, ppv);
670 }
671
672 static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
673 {
674     return 2;
675 }
676
677 static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
678 {
679     return 1;
680 }
681
682 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
683 {
684     ok(0, "unexpected call\n");
685     return E_NOTIMPL;
686 }
687
688 static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
689 {
690     ok(0, "unexpected call\n");
691     return E_NOTIMPL;
692 }
693
694 static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
695 {
696     ok(0, "unexpected call\n");
697     return E_NOTIMPL;
698 }
699
700 static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
701         LPCBORDERWIDTHS pborderwidths)
702 {
703     ok(0, "unexpected call\n");
704     return E_NOTIMPL;
705 }
706
707 static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
708         LPCBORDERWIDTHS pborderwidths)
709 {
710     ok(0, "unexpected call\n");
711     return E_NOTIMPL;
712 }
713
714 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
715         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
716 {
717     static const WCHAR wszHTML_Document[] =
718         {'H','T','M','L',' ','D','o','c','u','m','e','n','t',0};
719
720     CHECK_EXPECT2(SetActiveObject);
721
722     if(expect_SetActiveObject_active) {
723         ok(pActiveObject != NULL, "pActiveObject = NULL\n");
724         if(pActiveObject && PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_ENGLISH)
725             ok(!lstrcmpW(wszHTML_Document, pszObjName), "pszObjName != \"HTML Document\"\n");
726     }else {
727         ok(pActiveObject == NULL, "pActiveObject=%p, expected NULL\n", pActiveObject);
728         ok(pszObjName == NULL, "pszObjName=%p, expected NULL\n", pszObjName);
729     }
730
731     return S_OK;
732 }
733
734 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
735         LPOLEMENUGROUPWIDTHS lpMenuWidths)
736 {
737     ok(0, "unexpected call\n");
738     return E_NOTIMPL;
739 }
740
741 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
742         HOLEMENU holemenu, HWND hwndActiveObject)
743 {
744     ok(0, "unexpected call\n");
745     return E_NOTIMPL;
746 }
747
748 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
749 {
750     ok(0, "unexpected call\n");
751     return E_NOTIMPL;
752 }
753
754 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
755 {
756     CHECK_EXPECT2(SetStatusText);
757     if(!expect_status_text)
758         ok(pszStatusText == NULL, "pszStatusText=%p, expected NULL\n", pszStatusText);
759     return S_OK;
760 }
761
762 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
763 {
764     ok(0, "unexpected call\n");
765     return E_NOTIMPL;
766 }
767
768 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
769 {
770     ok(0, "unexpected call\n");
771     return E_NOTIMPL;
772 }
773
774 static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
775     InPlaceFrame_QueryInterface,
776     InPlaceFrame_AddRef,
777     InPlaceFrame_Release,
778     InPlaceFrame_GetWindow,
779     InPlaceFrame_ContextSensitiveHelp,
780     InPlaceFrame_GetBorder,
781     InPlaceFrame_RequestBorderSpace,
782     InPlaceFrame_SetBorderSpace,
783     InPlaceFrame_SetActiveObject,
784     InPlaceFrame_InsertMenus,
785     InPlaceFrame_SetMenu,
786     InPlaceFrame_RemoveMenus,
787     InPlaceFrame_SetStatusText,
788     InPlaceFrame_EnableModeless,
789     InPlaceFrame_TranslateAccelerator
790 };
791
792 static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
793
794 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv)
795 {
796     return QueryInterface(riid, ppv);
797 }
798
799 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface)
800 {
801     return 2;
802 }
803
804 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface)
805 {
806     return 1;
807 }
808
809 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd)
810 {
811     CHECK_EXPECT(GetWindow);
812     ok(phwnd != NULL, "phwnd = NULL\n");
813     *phwnd = container_hwnd;
814     return S_OK;
815 }
816
817 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
818 {
819     ok(0, "unexpected call\n");
820     return E_NOTIMPL;
821 }
822
823 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface)
824 {
825     CHECK_EXPECT(CanInPlaceActivate);
826     return S_OK;
827 }
828
829 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface)
830 {
831     CHECK_EXPECT(OnInPlaceActivate);
832     return S_OK;
833 }
834
835 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface)
836 {
837     CHECK_EXPECT(OnUIActivate);
838     return S_OK;
839 }
840
841 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface,
842         IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
843         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
844 {
845     static const RECT rect = {0,0,500,500};
846
847     CHECK_EXPECT(GetWindowContext);
848
849     ok(ppFrame != NULL, "ppFrame = NULL\n");
850     if(ppFrame)
851         *ppFrame = &InPlaceFrame;
852     ok(ppDoc != NULL, "ppDoc = NULL\n");
853     if(ppDoc)
854         *ppDoc = NULL;
855     ok(lprcPosRect != NULL, "lprcPosRect = NULL\n");
856     if(lprcPosRect)
857         memcpy(lprcPosRect, &rect, sizeof(RECT));
858     ok(lprcClipRect != NULL, "lprcClipRect = NULL\n");
859     if(lprcClipRect)
860         memcpy(lprcClipRect, &rect, sizeof(RECT));
861     ok(lpFrameInfo != NULL, "lpFrameInfo = NULL\n");
862     if(lpFrameInfo) {
863         lpFrameInfo->cb = sizeof(*lpFrameInfo);
864         lpFrameInfo->fMDIApp = FALSE;
865         lpFrameInfo->hwndFrame = container_hwnd;
866         lpFrameInfo->haccel = NULL;
867         lpFrameInfo->cAccelEntries = 0;
868     }
869
870     return S_OK;
871 }
872
873 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant)
874 {
875     ok(0, "unexpected call\n");
876     return E_NOTIMPL;
877 }
878
879 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
880 {
881     CHECK_EXPECT(OnUIDeactivate);
882     ok(!fUndoable, "fUndoable = TRUE\n");
883     return S_OK;
884 }
885
886 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface)
887 {
888     CHECK_EXPECT(OnInPlaceDeactivate);
889     return S_OK;
890 }
891
892 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface)
893 {
894     ok(0, "unexpected call\n");
895     return E_NOTIMPL;
896 }
897
898 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface)
899 {
900     ok(0, "unexpected call\n");
901     return E_NOTIMPL;
902 }
903
904 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
905 {
906     ok(0, "unexpected call\n");
907     return E_NOTIMPL;
908 }
909
910 static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = {
911     InPlaceSite_QueryInterface,
912     InPlaceSite_AddRef,
913     InPlaceSite_Release,
914     InPlaceSite_GetWindow,
915     InPlaceSite_ContextSensitiveHelp,
916     InPlaceSite_CanInPlaceActivate,
917     InPlaceSite_OnInPlaceActivate,
918     InPlaceSite_OnUIActivate,
919     InPlaceSite_GetWindowContext,
920     InPlaceSite_Scroll,
921     InPlaceSite_OnUIDeactivate,
922     InPlaceSite_OnInPlaceDeactivate,
923     InPlaceSite_DiscardUndoState,
924     InPlaceSite_DeactivateAndUndo,
925     InPlaceSite_OnPosRectChange
926 };
927
928 static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl };
929
930 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
931 {
932     return QueryInterface(riid, ppv);
933 }
934
935 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
936 {
937     return 2;
938 }
939
940 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
941 {
942     return 1;
943 }
944
945 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
946 {
947     ok(0, "unexpected call\n");
948     return E_NOTIMPL;
949 }
950
951 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAsign, DWORD dwWhichMoniker,
952         IMoniker **ppmon)
953 {
954     ok(0, "unexpected call\n");
955     return E_NOTIMPL;
956 }
957
958 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
959 {
960     CHECK_EXPECT(GetContainer);
961     ok(ppContainer != NULL, "ppContainer = NULL\n");
962     *ppContainer = &OleContainer;
963     return S_OK;
964 }
965
966 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
967 {
968     ok(0, "unexpected call\n");
969     return E_NOTIMPL;
970 }
971
972 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
973 {
974     ok(0, "unexpected call\n");
975     return E_NOTIMPL;
976 }
977
978 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
979 {
980     ok(0, "unexpected call\n");
981     return E_NOTIMPL;
982 }
983
984 static const IOleClientSiteVtbl ClientSiteVtbl = {
985     ClientSite_QueryInterface,
986     ClientSite_AddRef,
987     ClientSite_Release,
988     ClientSite_SaveObject,
989     ClientSite_GetMoniker,
990     ClientSite_GetContainer,
991     ClientSite_ShowObject,
992     ClientSite_OnShowWindow,
993     ClientSite_RequestNewObjectLayout
994 };
995
996 static IOleClientSite ClientSite = { &ClientSiteVtbl };
997
998 static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv)
999 {
1000     return QueryInterface(riid, ppv);
1001 }
1002
1003 static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface)
1004 {
1005     return 2;
1006 }
1007
1008 static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface)
1009 {
1010     return 1;
1011 }
1012
1013 static BOOL call_UIActivate = TRUE;
1014 static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate)
1015 {
1016     IOleDocument *document;
1017     HRESULT hres;
1018
1019     CHECK_EXPECT(ActivateMe);
1020     ok(pViewToActivate != NULL, "pViewToActivate = NULL\n");
1021
1022     hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document);
1023     ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
1024
1025     if(SUCCEEDED(hres)) {
1026         hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view);
1027         ok(hres == S_OK, "CreateView failed: %08x\n", hres);
1028
1029         if(SUCCEEDED(hres)) {
1030             IOleInPlaceActiveObject *activeobj = NULL;
1031             IOleInPlaceSite *inplacesite = NULL;
1032             HWND tmp_hwnd = NULL;
1033             static RECT rect = {0,0,400,500};
1034
1035             hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
1036             ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres);
1037             ok(inplacesite == &InPlaceSite, "inplacesite=%p, expected %p\n",
1038                     inplacesite, &InPlaceSite);
1039
1040             hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite);
1041             ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
1042
1043             hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
1044             ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres);
1045             ok(inplacesite == &InPlaceSite, "inplacesite=%p, expected %p\n",
1046                     inplacesite, &InPlaceSite);
1047
1048             hres = IOleDocumentView_QueryInterface(view, &IID_IOleInPlaceActiveObject, (void**)&activeobj);
1049             ok(hres == S_OK, "Could not get IOleInPlaceActiveObject: %08x\n", hres);
1050
1051             if(activeobj) {
1052                 IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd);
1053                 ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
1054                 ok(hwnd == NULL, "hwnd=%p, expeted NULL\n", hwnd);
1055             }
1056             
1057             if(call_UIActivate) {
1058                 SET_EXPECT(CanInPlaceActivate);
1059                 SET_EXPECT(GetWindowContext);
1060                 SET_EXPECT(GetWindow);
1061                 SET_EXPECT(OnInPlaceActivate);
1062                 SET_EXPECT(SetStatusText);
1063                 SET_EXPECT(Exec_SETPROGRESSMAX);
1064                 SET_EXPECT(Exec_SETPROGRESSPOS);
1065                 SET_EXPECT(OnUIActivate);
1066                 SET_EXPECT(SetActiveObject);
1067                 SET_EXPECT(ShowUI);
1068                 expect_SetActiveObject_active = TRUE;
1069                 expect_status_text = NULL;
1070
1071                 hres = IOleDocumentView_UIActivate(view, TRUE);
1072
1073                 if(FAILED(hres)) {
1074                     trace("UIActivate failed: %08x\n", hres);
1075                     return hres;
1076                 }
1077                 ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
1078
1079                 CHECK_CALLED(CanInPlaceActivate);
1080                 CHECK_CALLED(GetWindowContext);
1081                 CHECK_CALLED(GetWindow);
1082                 CHECK_CALLED(OnInPlaceActivate);
1083                 CHECK_CALLED(SetStatusText);
1084                 CHECK_CALLED(Exec_SETPROGRESSMAX);
1085                 CHECK_CALLED(Exec_SETPROGRESSPOS);
1086                 CHECK_CALLED(OnUIActivate);
1087                 CHECK_CALLED(SetActiveObject);
1088                 CHECK_CALLED(ShowUI);
1089
1090                 if(activeobj) {
1091                     hres = IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd);
1092                     ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
1093                     ok(hwnd != NULL, "hwnd == NULL\n");
1094                     if(last_hwnd)
1095                         ok(hwnd == last_hwnd, "hwnd != last_hwnd\n");
1096                 }
1097
1098                 hres = IOleDocumentView_UIActivate(view, TRUE);
1099                 ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
1100
1101                 if(activeobj) {
1102                     hres = IOleInPlaceActiveObject_GetWindow(activeobj, &tmp_hwnd);
1103                     ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
1104                     ok(tmp_hwnd == hwnd, "tmp_hwnd=%p, expected %p\n", tmp_hwnd, hwnd);
1105                 }
1106             }
1107
1108             hres = IOleDocumentView_SetRect(view, &rect);
1109             ok(hres == S_OK, "SetRect failed: %08x\n", hres);
1110
1111             if(call_UIActivate) {
1112                 hres = IOleDocumentView_Show(view, TRUE);
1113                 ok(hres == S_OK, "Show failed: %08x\n", hres);
1114             }else {
1115                 SET_EXPECT(CanInPlaceActivate);
1116                 SET_EXPECT(GetWindowContext);
1117                 SET_EXPECT(GetWindow);
1118                 SET_EXPECT(OnInPlaceActivate);
1119                 SET_EXPECT(SetStatusText);
1120                 SET_EXPECT(Exec_SETPROGRESSMAX);
1121                 SET_EXPECT(Exec_SETPROGRESSPOS);
1122                 SET_EXPECT(OnUIActivate);
1123                 expect_status_text = (load_state == LD_COMPLETE ? (LPCOLESTR)0xdeadbeef : NULL);
1124
1125                 hres = IOleDocumentView_Show(view, TRUE);
1126                 ok(hres == S_OK, "Show failed: %08x\n", hres);
1127
1128                 CHECK_CALLED(CanInPlaceActivate);
1129                 CHECK_CALLED(GetWindowContext);
1130                 CHECK_CALLED(GetWindow);
1131                 CHECK_CALLED(OnInPlaceActivate);
1132                 CHECK_CALLED(SetStatusText);
1133                 CHECK_CALLED(Exec_SETPROGRESSMAX);
1134                 CHECK_CALLED(Exec_SETPROGRESSPOS);
1135
1136                 if(activeobj) {
1137                     hres = IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd);
1138                     ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
1139                     ok(hwnd != NULL, "hwnd == NULL\n");
1140                     if(last_hwnd)
1141                         ok(hwnd == last_hwnd, "hwnd != last_hwnd\n");
1142                 }
1143             }
1144
1145             if(activeobj)
1146                 IOleInPlaceActiveObject_Release(activeobj);
1147         }
1148
1149         IOleDocument_Release(document);
1150     }
1151
1152     return S_OK;
1153 }
1154
1155 static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
1156     DocumentSite_QueryInterface,
1157     DocumentSite_AddRef,
1158     DocumentSite_Release,
1159     DocumentSite_ActivateMe
1160 };
1161
1162 static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
1163
1164 static HRESULT WINAPI DocHostUIHandler_QueryInterface(IDocHostUIHandler2 *iface, REFIID riid, void **ppv)
1165 {
1166     return QueryInterface(riid, ppv);
1167 }
1168
1169 static ULONG WINAPI DocHostUIHandler_AddRef(IDocHostUIHandler2 *iface)
1170 {
1171     return 2;
1172 }
1173
1174 static ULONG WINAPI DocHostUIHandler_Release(IDocHostUIHandler2 *iface)
1175 {
1176     return 1;
1177 }
1178
1179 static HRESULT WINAPI DocHostUIHandler_ShowContextMenu(IDocHostUIHandler2 *iface, DWORD dwID, POINT *ppt,
1180         IUnknown *pcmdtReserved, IDispatch *pdicpReserved)
1181 {
1182     ok(0, "unexpected call\n");
1183     return E_NOTIMPL;
1184 }
1185
1186 static HRESULT WINAPI DocHostUIHandler_GetHostInfo(IDocHostUIHandler2 *iface, DOCHOSTUIINFO *pInfo)
1187 {
1188     CHECK_EXPECT(GetHostInfo);
1189     ok(pInfo != NULL, "pInfo=NULL\n");
1190     if(pInfo) {
1191         ok(pInfo->cbSize == sizeof(DOCHOSTUIINFO), "pInfo->cbSize=%u\n", pInfo->cbSize);
1192         ok(!pInfo->dwFlags, "pInfo->dwFlags=%08x, expected 0\n", pInfo->dwFlags);
1193         pInfo->dwFlags = DOCHOSTUIFLAG_DISABLE_HELP_MENU | DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE
1194             | DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY | DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION
1195             | DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION;
1196         ok(!pInfo->dwDoubleClick, "pInfo->dwDoubleClick=%08x, expected 0\n", pInfo->dwDoubleClick);
1197         ok(!pInfo->pchHostCss, "pInfo->pchHostCss=%p, expected NULL\n", pInfo->pchHostCss);
1198         ok(!pInfo->pchHostNS, "pInfo->pchhostNS=%p, expected NULL\n", pInfo->pchHostNS);
1199     }
1200     return S_OK;
1201 }
1202
1203 static HRESULT WINAPI DocHostUIHandler_ShowUI(IDocHostUIHandler2 *iface, DWORD dwID,
1204         IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget,
1205         IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
1206 {
1207     CHECK_EXPECT(ShowUI);
1208
1209     ok(dwID == DOCHOSTUITYPE_BROWSE, "dwID=%d, expected DOCHOSTUITYPE_BROWSE\n", dwID);
1210     ok(pActiveObject != NULL, "pActiveObject = NULL\n");
1211     ok(pCommandTarget != NULL, "pCommandTarget = NULL\n");
1212     ok(pFrame == &InPlaceFrame, "pFrame=%p, expected %p\n", pFrame, &InPlaceFrame);
1213     ok(pDoc == NULL, "pDoc=%p, expected NULL\n", pDoc);
1214
1215     return S_OK;
1216 }
1217
1218 static HRESULT WINAPI DocHostUIHandler_HideUI(IDocHostUIHandler2 *iface)
1219 {
1220     CHECK_EXPECT(HideUI);
1221     return S_OK;
1222 }
1223
1224 static HRESULT WINAPI DocHostUIHandler_UpdateUI(IDocHostUIHandler2 *iface)
1225 {
1226     CHECK_EXPECT(UpdateUI);
1227     return S_OK;
1228 }
1229
1230 static HRESULT WINAPI DocHostUIHandler_EnableModeless(IDocHostUIHandler2 *iface, BOOL fEnable)
1231 {
1232     ok(0, "unexpected call\n");
1233     return E_NOTIMPL;
1234 }
1235
1236 static HRESULT WINAPI DocHostUIHandler_OnDocWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
1237 {
1238     ok(0, "unexpected call\n");
1239     return E_NOTIMPL;
1240 }
1241
1242 static BOOL expect_OnFrameWindowActivate_fActivate;
1243 static HRESULT WINAPI DocHostUIHandler_OnFrameWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
1244 {
1245     CHECK_EXPECT2(OnFrameWindowActivate);
1246     ok(fActivate == expect_OnFrameWindowActivate_fActivate, "fActivate=%x\n", fActivate);
1247     return S_OK;
1248 }
1249
1250 static HRESULT WINAPI DocHostUIHandler_ResizeBorder(IDocHostUIHandler2 *iface, LPCRECT prcBorder,
1251         IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
1252 {
1253     ok(0, "unexpected call\n");
1254     return E_NOTIMPL;
1255 }
1256
1257 static HRESULT WINAPI DocHostUIHandler_TranslateAccelerator(IDocHostUIHandler2 *iface, LPMSG lpMsg,
1258         const GUID *pguidCmdGroup, DWORD nCmdID)
1259 {
1260     ok(0, "unexpected call\n");
1261     return E_NOTIMPL;
1262 }
1263
1264 static HRESULT WINAPI DocHostUIHandler_GetOptionKeyPath(IDocHostUIHandler2 *iface,
1265         LPOLESTR *pchKey, DWORD dw)
1266 {
1267     CHECK_EXPECT(GetOptionKeyPath);
1268     ok(pchKey != NULL, "pchKey = NULL\n");
1269     ok(!dw, "dw=%d, expected 0\n", dw);
1270     if(pchKey)
1271         ok(!*pchKey, "*pchKey=%p, expected NULL\n", *pchKey);
1272     return S_OK;
1273 }
1274
1275 static HRESULT WINAPI DocHostUIHandler_GetDropTarget(IDocHostUIHandler2 *iface,
1276         IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
1277 {
1278     CHECK_EXPECT(GetDropTarget);
1279     /* TODO */
1280     return E_NOTIMPL;
1281 }
1282
1283 static HRESULT WINAPI DocHostUIHandler_GetExternal(IDocHostUIHandler2 *iface, IDispatch **ppDispatch)
1284 {
1285     ok(0, "unexpected call\n");
1286     return E_NOTIMPL;
1287 }
1288
1289 static HRESULT WINAPI DocHostUIHandler_TranslateUrl(IDocHostUIHandler2 *iface, DWORD dwTranslate,
1290         OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
1291 {
1292     ok(0, "unexpected call\n");
1293     return E_NOTIMPL;
1294 }
1295
1296 static HRESULT WINAPI DocHostUIHandler_FilterDataObject(IDocHostUIHandler2 *iface, IDataObject *pDO,
1297         IDataObject **ppPORet)
1298 {
1299     ok(0, "unexpected call\n");
1300     return E_NOTIMPL;
1301 }
1302
1303 static HRESULT WINAPI DocHostUIHandler_GetOverrideKeyPath(IDocHostUIHandler2 *iface,
1304         LPOLESTR *pchKey, DWORD dw)
1305 {
1306     CHECK_EXPECT(GetOverrideKeyPath);
1307     ok(pchKey != NULL, "pchKey = NULL\n");
1308     if(pchKey)
1309         ok(!*pchKey, "*pchKey=%p, expected NULL\n", *pchKey);
1310     ok(!dw, "dw=%d, xepected 0\n", dw);
1311     return S_OK;
1312 }
1313
1314 static const IDocHostUIHandler2Vtbl DocHostUIHandlerVtbl = {
1315     DocHostUIHandler_QueryInterface,
1316     DocHostUIHandler_AddRef,
1317     DocHostUIHandler_Release,
1318     DocHostUIHandler_ShowContextMenu,
1319     DocHostUIHandler_GetHostInfo,
1320     DocHostUIHandler_ShowUI,
1321     DocHostUIHandler_HideUI,
1322     DocHostUIHandler_UpdateUI,
1323     DocHostUIHandler_EnableModeless,
1324     DocHostUIHandler_OnDocWindowActivate,
1325     DocHostUIHandler_OnFrameWindowActivate,
1326     DocHostUIHandler_ResizeBorder,
1327     DocHostUIHandler_TranslateAccelerator,
1328     DocHostUIHandler_GetOptionKeyPath,
1329     DocHostUIHandler_GetDropTarget,
1330     DocHostUIHandler_GetExternal,
1331     DocHostUIHandler_TranslateUrl,
1332     DocHostUIHandler_FilterDataObject,
1333     DocHostUIHandler_GetOverrideKeyPath
1334 };
1335
1336 static IDocHostUIHandler2 DocHostUIHandler = { &DocHostUIHandlerVtbl };
1337
1338 static HRESULT WINAPI OleCommandTarget_QueryInterface(IOleCommandTarget *iface,
1339         REFIID riid, void **ppv)
1340 {
1341     return QueryInterface(riid, ppv);
1342 }
1343
1344 static ULONG WINAPI OleCommandTarget_AddRef(IOleCommandTarget *iface)
1345 {
1346     return 2;
1347 }
1348
1349 static ULONG WINAPI OleCommandTarget_Release(IOleCommandTarget *iface)
1350 {
1351     return 1;
1352 }
1353
1354 static HRESULT WINAPI OleCommandTarget_QueryStatus(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
1355         ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
1356 {
1357     ok(!pguidCmdGroup, "pguidCmdGroup != MULL\n");
1358     ok(cCmds == 1, "cCmds=%d, expected 1\n", cCmds);
1359     ok(!pCmdText, "pCmdText != NULL\n");
1360
1361     switch(prgCmds[0].cmdID) {
1362     case OLECMDID_SETPROGRESSTEXT:
1363         CHECK_EXPECT(QueryStatus_SETPROGRESSTEXT);
1364         prgCmds[0].cmdf = OLECMDF_ENABLED;
1365         return S_OK;
1366     case OLECMDID_OPEN:
1367         CHECK_EXPECT(QueryStatus_OPEN);
1368         prgCmds[0].cmdf = 0;
1369         return S_OK;
1370     case OLECMDID_NEW:
1371         CHECK_EXPECT(QueryStatus_NEW);
1372         prgCmds[0].cmdf = 0;
1373         return S_OK;
1374     default:
1375         ok(0, "unexpected command %d\n", prgCmds[0].cmdID);
1376     };
1377
1378     return E_FAIL;
1379 }
1380
1381 static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
1382         DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1383 {
1384     test_readyState(NULL);
1385
1386     if(!pguidCmdGroup) {
1387         switch(nCmdID) {
1388         case OLECMDID_SETPROGRESSMAX:
1389             CHECK_EXPECT2(Exec_SETPROGRESSMAX);
1390             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
1391             ok(pvaIn != NULL, "pvaIn == NULL\n");
1392             if(pvaIn) {
1393                 ok(V_VT(pvaIn) == VT_I4, "V_VT(pvaIn)=%d, expected VT_I4\n", V_VT(pvaIn));
1394                 if(load_state == LD_NO)
1395                     ok(V_I4(pvaIn) == 0, "V_I4(pvaIn)=%d, expected 0\n", V_I4(pvaIn));
1396             }
1397             ok(pvaOut == NULL, "pvaOut=%p, expected NULL\n", pvaOut);
1398             return S_OK;
1399         case OLECMDID_SETPROGRESSPOS:
1400             CHECK_EXPECT2(Exec_SETPROGRESSPOS);
1401             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
1402             ok(pvaIn != NULL, "pvaIn == NULL\n");
1403             if(pvaIn) {
1404                 ok(V_VT(pvaIn) == VT_I4, "V_VT(pvaIn)=%d, expected VT_I4\n", V_VT(pvaIn));
1405                 if(load_state == LD_NO)
1406                     ok(V_I4(pvaIn) == 0, "V_I4(pvaIn)=%d, expected 0\n", V_I4(pvaIn));
1407             }
1408             ok(pvaOut == NULL, "pvaOut=%p, expected NULL\n", pvaOut);
1409             return S_OK;
1410         case OLECMDID_HTTPEQUIV_DONE:
1411             CHECK_EXPECT(Exec_HTTPEQUIV_DONE);
1412             ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt);
1413             ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut);
1414             ok(pvaIn == NULL, "pvaIn=%p\n", pvaIn);
1415             load_state = LD_COMPLETE;
1416             return S_OK;
1417         case OLECMDID_SETDOWNLOADSTATE:
1418             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
1419             ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut);
1420             ok(pvaIn != NULL, "pvaIn == NULL\n");
1421             ok(V_VT(pvaIn) == VT_I4, "V_VT(pvaIn)=%d\n", V_VT(pvaIn));
1422
1423             switch(V_I4(pvaIn)) {
1424             case 0:
1425                 CHECK_EXPECT(Exec_SETDOWNLOADSTATE_0);
1426                 load_state = LD_INTERACTIVE;
1427                 break;
1428             case 1:
1429                 CHECK_EXPECT(Exec_SETDOWNLOADSTATE_1);
1430                 break;
1431             default:
1432                 ok(0, "unexpevted V_I4(pvaIn)=%d\n", V_I4(pvaIn));
1433             }
1434
1435             return S_OK;
1436         case OLECMDID_UPDATECOMMANDS:
1437             CHECK_EXPECT(Exec_UPDATECOMMANDS);
1438             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
1439             ok(pvaIn == NULL, "pvaIn=%p\n", pvaIn);
1440             ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut);
1441             return S_OK;
1442         case OLECMDID_SETTITLE:
1443             CHECK_EXPECT2(Exec_SETTITLE);
1444             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
1445             ok(pvaIn != NULL, "pvaIn == NULL\n");
1446             ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut);
1447             ok(V_VT(pvaIn) == VT_BSTR, "V_VT(pvaIn)=%d\n", V_VT(pvaIn));
1448             ok(V_BSTR(pvaIn) != NULL, "V_BSTR(pvaIn) == NULL\n"); /* TODO */
1449             return S_OK;
1450         case OLECMDID_HTTPEQUIV:
1451             CHECK_EXPECT2(Exec_HTTPEQUIV);
1452             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
1453             /* TODO */
1454             return S_OK;
1455         default:
1456             ok(0, "unexpected command %d\n", nCmdID);
1457             return E_FAIL;
1458         };
1459     }
1460
1461     if(IsEqualGUID(&CGID_ShellDocView, pguidCmdGroup)) {
1462         ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt);
1463
1464         switch(nCmdID) {
1465         case 37:
1466             CHECK_EXPECT2(Exec_ShellDocView_37);
1467             ok(pvaOut == NULL, "pvaOut=%p, expected NULL\n", pvaOut);
1468             ok(pvaIn != NULL, "pvaIn == NULL\n");
1469             if(pvaIn) {
1470                 ok(V_VT(pvaIn) == VT_I4, "V_VT(pvaIn)=%d, expected VT_I4\n", V_VT(pvaIn));
1471                 ok(V_I4(pvaIn) == 0, "V_I4(pvaIn)=%d, expected 0\n", V_I4(pvaIn));
1472             }
1473             return S_OK;
1474         default:
1475             ok(0, "unexpected command %d\n", nCmdID);
1476             return E_FAIL;
1477         };
1478     }
1479
1480     if(IsEqualGUID(&CGID_MSHTML, pguidCmdGroup)) {
1481         ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt);
1482
1483         switch(nCmdID) {
1484         case IDM_PARSECOMPLETE:
1485             CHECK_EXPECT(Exec_MSHTML_PARSECOMPLETE);
1486             ok(pvaIn == NULL, "pvaIn != NULL\n");
1487             ok(pvaOut == NULL, "pvaOut != NULL\n");
1488             return S_OK;
1489         default:
1490             ok(0, "unexpected command %d\n", nCmdID);
1491         };
1492     }
1493
1494     if(IsEqualGUID(&CGID_Undocumented, pguidCmdGroup))
1495         return E_FAIL; /* TODO */
1496
1497     ok(0, "unexpected call\n");
1498     return E_NOTIMPL;
1499 }
1500
1501 static IOleCommandTargetVtbl OleCommandTargetVtbl = {
1502     OleCommandTarget_QueryInterface,
1503     OleCommandTarget_AddRef,
1504     OleCommandTarget_Release,
1505     OleCommandTarget_QueryStatus,
1506     OleCommandTarget_Exec
1507 };
1508
1509 static IOleCommandTarget OleCommandTarget = { &OleCommandTargetVtbl };
1510
1511 static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
1512 {
1513     return QueryInterface(riid, ppv);
1514 }
1515
1516 static ULONG WINAPI Dispatch_AddRef(IDispatch *iface)
1517 {
1518     return 2;
1519 }
1520
1521 static ULONG WINAPI Dispatch_Release(IDispatch *iface)
1522 {
1523     return 1;
1524 }
1525
1526 static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
1527 {
1528     ok(0, "unexpected call\n");
1529     return E_NOTIMPL;
1530 }
1531
1532 static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid,
1533         ITypeInfo **ppTInfo)
1534 {
1535     ok(0, "unexpected call\n");
1536     return E_NOTIMPL;
1537 }
1538
1539 static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
1540         UINT cNames, LCID lcid, DISPID *rgDispId)
1541 {
1542     ok(0, "unexpected call\n");
1543     return E_NOTIMPL;
1544 }
1545
1546 static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
1547         LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1548         EXCEPINFO *pExcepInfo, UINT *puArgErr)
1549 {
1550     ok(IsEqualGUID(&IID_NULL, riid), "riid != IID_NULL\n");
1551     ok(pDispParams != NULL, "pDispParams == NULL\n");
1552     ok(pExcepInfo == NULL, "pExcepInfo=%p, expected NULL\n", pExcepInfo);
1553     ok(puArgErr != NULL, "puArgErr == NULL\n");
1554     ok(V_VT(pVarResult) == 0, "V_VT(pVarResult)=%d, expected 0\n", V_VT(pVarResult));
1555     ok(wFlags == DISPATCH_PROPERTYGET, "wFlags=%08x, expected DISPATCH_PROPERTYGET\n", wFlags);
1556     test_readyState(NULL);
1557
1558     switch(dispIdMember) {
1559     case DISPID_AMBIENT_USERMODE:
1560         CHECK_EXPECT2(Invoke_AMBIENT_USERMODE);
1561         V_VT(pVarResult) = VT_BOOL;
1562         V_BOOL(pVarResult) = VARIANT_TRUE;
1563         return S_OK;
1564     case DISPID_AMBIENT_DLCONTROL:
1565         CHECK_EXPECT2(Invoke_AMBIENT_DLCONTROL);
1566         return E_FAIL;
1567     case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
1568         CHECK_EXPECT2(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
1569         return E_FAIL;
1570     case DISPID_AMBIENT_SILENT:
1571         CHECK_EXPECT2(Invoke_AMBIENT_SILENT);
1572         V_VT(pVarResult) = VT_BOOL;
1573         V_BOOL(pVarResult) = VARIANT_FALSE;
1574         return S_OK;
1575     case DISPID_AMBIENT_USERAGENT:
1576         CHECK_EXPECT(Invoke_AMBIENT_USERAGENT);
1577         return E_FAIL;
1578     case DISPID_AMBIENT_PALETTE:
1579         CHECK_EXPECT(Invoke_AMBIENT_PALETTE);
1580         return E_FAIL;
1581     };
1582
1583     ok(0, "unexpected dispid %d\n", dispIdMember);
1584     return E_FAIL;
1585 }
1586
1587 static IDispatchVtbl DispatchVtbl = {
1588     Dispatch_QueryInterface,
1589     Dispatch_AddRef,
1590     Dispatch_Release,
1591     Dispatch_GetTypeInfoCount,
1592     Dispatch_GetTypeInfo,
1593     Dispatch_GetIDsOfNames,
1594     Dispatch_Invoke
1595 };
1596
1597 static IDispatch Dispatch = { &DispatchVtbl };
1598
1599 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface,
1600                                                      REFIID riid, void **ppv)
1601 {
1602     return QueryInterface(riid, ppv);
1603 }
1604
1605 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
1606 {
1607     return 2;
1608 }
1609
1610 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
1611 {
1612     return 1;
1613 }
1614
1615 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
1616                                     REFIID riid, void **ppv)
1617 {
1618     /*
1619      * Services used by HTMLDocument:
1620      *
1621      * IOleUndoManager
1622      * IInternetSecurityManager
1623      * ITargetFrame
1624      * {D5F78C80-5252-11CF-90FA-00AA0042106E}
1625      * HTMLFrameBase
1626      * IShellObject
1627      * {3050F312-98B5-11CF-BB82-00AA00BDCE0B}
1628      * {53A2D5B1-D2FC-11D0-84E0-006097C9987D}
1629      * {AD7F6C62-F6BD-11D2-959B-006097C553C8}
1630      * DefView (?)
1631      * {6D12FE80-7911-11CF-9534-0000C05BAE0B}
1632      * IElementBehaviorFactory
1633      * {3050F429-98B5-11CF-BB82-00AA00BDCE0B}
1634      * STopLevelBrowser
1635      * IHTMLWindow2
1636      * IInternetProtocol
1637      * IWebBrowserApp
1638      * UrlHostory
1639      * IHTMLEditHost
1640      * IHlinkFrame
1641      */
1642
1643     if(IsEqualGUID(&IID_IHlinkFrame, guidService)) {
1644         ok(IsEqualGUID(&IID_IHlinkFrame, riid), "unexpected riid\n");
1645         *ppv = &HlinkFrame;
1646         return S_OK;
1647     }
1648
1649     return E_NOINTERFACE;
1650 }
1651
1652 static const IServiceProviderVtbl ServiceProviderVtbl = {
1653     ServiceProvider_QueryInterface,
1654     ServiceProvider_AddRef,
1655     ServiceProvider_Release,
1656     ServiceProvider_QueryService
1657 };
1658
1659 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
1660
1661 static HRESULT QueryInterface(REFIID riid, void **ppv)
1662 {
1663     *ppv = NULL;
1664
1665     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid))
1666         *ppv = &ClientSite;
1667     else if(IsEqualGUID(&IID_IOleDocumentSite, riid))
1668         *ppv = &DocumentSite;
1669     else if(IsEqualGUID(&IID_IDocHostUIHandler, riid) || IsEqualGUID(&IID_IDocHostUIHandler2, riid))
1670         *ppv = &DocHostUIHandler;
1671     else if(IsEqualGUID(&IID_IOleContainer, riid))
1672         *ppv = &OleContainer;
1673     else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
1674         *ppv = &InPlaceSite;
1675     else if(IsEqualGUID(&IID_IOleInPlaceUIWindow, riid) || IsEqualGUID(&IID_IOleInPlaceFrame, riid))
1676         *ppv = &InPlaceFrame;
1677     else if(IsEqualGUID(&IID_IOleCommandTarget , riid))
1678         *ppv = &OleCommandTarget;
1679     else if(IsEqualGUID(&IID_IDispatch, riid))
1680         *ppv = &Dispatch;
1681     else if(IsEqualGUID(&IID_IServiceProvider, riid))
1682         *ppv = &ServiceProvider;
1683
1684     /* TODO:
1685      * IOleInPlaceSiteEx
1686      * {D48A6EC6-6A4A-11CF-94A7-444553540000}
1687      * {7BB0B520-B1A7-11D2-BB23-00C04F79ABCD}
1688      * {000670BA-0000-0000-C000-000000000046}
1689      */
1690
1691     if(*ppv)
1692         return S_OK;
1693     return E_NOINTERFACE;
1694 }
1695
1696 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1697 {
1698     return DefWindowProc(hwnd, msg, wParam, lParam);
1699 }
1700
1701 static void test_readyState(IUnknown *unk)
1702 {
1703     IHTMLDocument2 *htmldoc;
1704     BSTR state;
1705     HRESULT hres;
1706
1707     static IUnknown *_unk;
1708
1709     static const WCHAR wszUninitialized[] = {'u','n','i','n','i','t','i','a','l','i','z','e','d',0};
1710     static const WCHAR wszLoading[] = {'l','o','a','d','i','n','g',0};
1711     static const WCHAR wszInteractive[] = {'i','n','t','e','r','a','c','t','i','v','e',0};
1712     static const WCHAR wszComplete[] = {'c','o','m','p','l','e','t','e',0};
1713
1714     static const LPCWSTR expected_state[] = {
1715         wszUninitialized,
1716         wszLoading,
1717         wszInteractive,
1718         wszComplete,
1719         wszUninitialized
1720     };
1721
1722     if(!unk) unk = _unk;
1723     else _unk = unk;
1724
1725     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument2, (void**)&htmldoc);
1726     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument2) failed: %08x\n", hres);
1727     if(FAILED(hres))
1728         return;
1729
1730     hres = IHTMLDocument2_get_readyState(htmldoc, NULL);
1731     ok(hres == E_POINTER, "get_readyState failed: %08x, expected\n", hres);
1732
1733     hres = IHTMLDocument2_get_readyState(htmldoc, &state);
1734     ok(hres == S_OK, "get_ReadyState failed: %08x\n", hres);
1735     ok(!lstrcmpW(state, expected_state[load_state]), "unexpected state, expected %d\n", load_state);
1736
1737     IHTMLDocument_Release(htmldoc);
1738 }
1739
1740 static void test_ConnectionPoint(IConnectionPointContainer *container, REFIID riid)
1741 {
1742     IConnectionPointContainer *tmp_container = NULL;
1743     IConnectionPoint *cp;
1744     IID iid;
1745     HRESULT hres;
1746
1747     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
1748     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
1749     if(FAILED(hres))
1750         return;
1751
1752     hres = IConnectionPoint_GetConnectionInterface(cp, &iid);
1753     ok(hres == S_OK, "GetConnectionInterface failed: %08x\n", hres);
1754     ok(IsEqualGUID(riid, &iid), "wrong iid\n");
1755
1756     hres = IConnectionPoint_GetConnectionInterface(cp, NULL);
1757     ok(hres == E_POINTER, "GetConnectionInterface failed: %08x, expected E_POINTER\n", hres);
1758
1759     hres = IConnectionPoint_GetConnectionPointContainer(cp, &tmp_container);
1760     ok(hres == S_OK, "GetConnectionPointContainer failed: %08x\n", hres);
1761     ok(tmp_container == container, "container != tmp_container\n");
1762     if(SUCCEEDED(hres))
1763         IConnectionPointContainer_Release(tmp_container);
1764
1765     hres = IConnectionPoint_GetConnectionPointContainer(cp, NULL);
1766     ok(hres == E_POINTER, "GetConnectionPointContainer failed: %08x, expected E_POINTER\n", hres);
1767
1768     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
1769         DWORD cookie;
1770
1771         hres = IConnectionPoint_Advise(cp, (IUnknown*)&PropertyNotifySink, &cookie);
1772         ok(hres == S_OK, "Advise failed: %08x\n", hres);
1773     }
1774
1775     IConnectionPoint_Release(cp);
1776 }
1777
1778 static void test_ConnectionPointContainer(IUnknown *unk)
1779 {
1780     IConnectionPointContainer *container;
1781     HRESULT hres;
1782
1783     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
1784     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
1785     if(FAILED(hres))
1786         return;
1787
1788     test_ConnectionPoint(container, &IID_IPropertyNotifySink);
1789     test_ConnectionPoint(container, &DIID_HTMLDocumentEvents);
1790     test_ConnectionPoint(container, &DIID_HTMLDocumentEvents2);
1791
1792     IConnectionPointContainer_Release(container);
1793 }
1794
1795 static void test_Load(IPersistMoniker *persist)
1796 {
1797     IBindCtx *bind;
1798     HRESULT hres;
1799
1800     test_readyState((IUnknown*)persist);
1801
1802     CreateBindCtx(0, &bind);
1803     IBindCtx_RegisterObjectParam(bind, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM,
1804                                  (IUnknown*)&ClientSite);
1805
1806     SET_EXPECT(GetDisplayName);
1807     SET_EXPECT(GetHostInfo);
1808     SET_EXPECT(Invoke_AMBIENT_USERMODE);
1809     SET_EXPECT(Invoke_AMBIENT_SILENT);
1810     SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
1811     SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
1812     SET_EXPECT(Invoke_AMBIENT_USERAGENT);
1813     SET_EXPECT(Invoke_AMBIENT_PALETTE);
1814     SET_EXPECT(GetOptionKeyPath);
1815     SET_EXPECT(GetOverrideKeyPath);
1816     SET_EXPECT(GetWindow);
1817     SET_EXPECT(QueryStatus_SETPROGRESSTEXT);
1818     SET_EXPECT(Exec_SETPROGRESSMAX);
1819     SET_EXPECT(Exec_SETPROGRESSPOS);
1820     SET_EXPECT(Exec_ShellDocView_37);
1821     SET_EXPECT(OnChanged_READYSTATE);
1822     SET_EXPECT(BindToStorage);
1823     SET_EXPECT(GetContainer);
1824     SET_EXPECT(LockContainer);
1825     expect_LockContainer_fLock = TRUE;
1826     readystate_set_loading = TRUE;
1827
1828     hres = IPersistMoniker_Load(persist, FALSE, &Moniker, bind, 0x12);
1829     ok(hres == S_OK, "Load failed: %08x\n", hres);
1830
1831     CHECK_CALLED(GetDisplayName);
1832     CHECK_CALLED(GetHostInfo);
1833     CHECK_CALLED(Invoke_AMBIENT_USERMODE);
1834     CHECK_CALLED(Invoke_AMBIENT_SILENT);
1835     CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
1836     CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
1837     CHECK_CALLED(Invoke_AMBIENT_USERAGENT);
1838     CHECK_CALLED(Invoke_AMBIENT_PALETTE);
1839     CHECK_CALLED(GetOptionKeyPath);
1840     CHECK_CALLED(GetOverrideKeyPath);
1841     CHECK_CALLED(GetWindow);
1842     CHECK_CALLED(QueryStatus_SETPROGRESSTEXT);
1843     CHECK_CALLED(Exec_SETPROGRESSMAX);
1844     CHECK_CALLED(Exec_SETPROGRESSPOS);
1845     CHECK_CALLED(Exec_ShellDocView_37);
1846     CHECK_CALLED(OnChanged_READYSTATE);
1847     CHECK_CALLED(BindToStorage);
1848     CHECK_CALLED(GetContainer);
1849     CHECK_CALLED(LockContainer);
1850
1851     set_clientsite = container_locked = TRUE;
1852
1853     IBindCtx_Release(bind);
1854
1855     test_readyState((IUnknown*)persist);
1856 }
1857
1858 static void test_download(void)
1859 {
1860     HWND hwnd;
1861     MSG msg;
1862
1863     hwnd = FindWindowA("Internet Explorer_Hidden", NULL);
1864     ok(hwnd != NULL, "Could not find hidden window\n");
1865
1866     test_readyState(NULL);
1867
1868     SET_EXPECT(SetStatusText);
1869     SET_EXPECT(Exec_SETDOWNLOADSTATE_1);
1870     SET_EXPECT(GetDropTarget);
1871     SET_EXPECT(OnChanged_1005);
1872     SET_EXPECT(OnChanged_READYSTATE);
1873     SET_EXPECT(Exec_SETPROGRESSPOS);
1874     SET_EXPECT(Exec_SETDOWNLOADSTATE_0);
1875     SET_EXPECT(Exec_MSHTML_PARSECOMPLETE);
1876     SET_EXPECT(Exec_HTTPEQUIV_DONE);
1877     SET_EXPECT(Exec_SETTITLE);
1878     expect_status_text = (LPWSTR)0xdeadbeef; /* TODO */
1879
1880     while(!called_Exec_HTTPEQUIV_DONE && GetMessage(&msg, hwnd, 0, 0)) {
1881         TranslateMessage(&msg);
1882         DispatchMessage(&msg);
1883     }
1884
1885     CHECK_CALLED(SetStatusText);
1886     CHECK_CALLED(Exec_SETDOWNLOADSTATE_1);
1887     CHECK_CALLED(GetDropTarget);
1888     CHECK_CALLED(OnChanged_1005);
1889     CHECK_CALLED(OnChanged_READYSTATE);
1890     CHECK_CALLED(Exec_SETPROGRESSPOS);
1891     CHECK_CALLED(Exec_SETDOWNLOADSTATE_0);
1892     CHECK_CALLED(Exec_MSHTML_PARSECOMPLETE);
1893     CHECK_CALLED(Exec_HTTPEQUIV_DONE);
1894     CHECK_CALLED(Exec_SETTITLE);
1895
1896     load_state = LD_COMPLETE;
1897
1898     test_readyState(NULL);
1899 }
1900
1901 static void test_Persist(IUnknown *unk)
1902 {
1903     IPersistMoniker *persist_mon;
1904     IPersistFile *persist_file;
1905     GUID guid;
1906     HRESULT hres;
1907
1908     hres = IUnknown_QueryInterface(unk, &IID_IPersistFile, (void**)&persist_file);
1909     ok(hres == S_OK, "QueryInterface(IID_IPersist) failed: %08x\n", hres);
1910     if(SUCCEEDED(hres)) {
1911         hres = IPersist_GetClassID(persist_file, NULL);
1912         ok(hres == E_INVALIDARG, "GetClassID returned: %08x, expected E_INVALIDARG\n", hres);
1913
1914         hres = IPersist_GetClassID(persist_file, &guid);
1915         ok(hres == S_OK, "GetClassID failed: %08x\n", hres);
1916         ok(IsEqualGUID(&CLSID_HTMLDocument, &guid), "guid != CLSID_HTMLDocument\n");
1917
1918         IPersist_Release(persist_file);
1919     }
1920
1921     hres = IUnknown_QueryInterface(unk, &IID_IPersistMoniker, (void**)&persist_mon);
1922     ok(hres == S_OK, "QueryInterface(IID_IPersistMoniker) failed: %08x\n", hres);
1923     if(SUCCEEDED(hres)) {
1924         hres = IPersistMoniker_GetClassID(persist_mon, NULL);
1925         ok(hres == E_INVALIDARG, "GetClassID returned: %08x, expected E_INVALIDARG\n", hres);
1926
1927         hres = IPersistMoniker_GetClassID(persist_mon, &guid);
1928         ok(hres == S_OK, "GetClassID failed: %08x\n", hres);
1929         ok(IsEqualGUID(&CLSID_HTMLDocument, &guid), "guid != CLSID_HTMLDocument\n");
1930
1931         if(load_state == LD_DOLOAD)
1932             test_Load(persist_mon);
1933
1934         test_readyState(unk);
1935
1936         IPersistMoniker_Release(persist_mon);
1937     }
1938 }
1939
1940 static const OLECMDF expect_cmds[OLECMDID_GETPRINTTEMPLATE+1] = {
1941     0,
1942     OLECMDF_SUPPORTED,                  /* OLECMDID_OPEN */
1943     OLECMDF_SUPPORTED,                  /* OLECMDID_NEW */
1944     OLECMDF_SUPPORTED,                  /* OLECMDID_SAVE */
1945     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_SAVEAS */
1946     OLECMDF_SUPPORTED,                  /* OLECMDID_SAVECOPYAS */
1947     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_PRINT */
1948     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_PRINTPREVIEW */
1949     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_PAGESETUP */
1950     OLECMDF_SUPPORTED,                  /* OLECMDID_SPELL */
1951     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_PROPERTIES */
1952     OLECMDF_SUPPORTED,                  /* OLECMDID_CUT */
1953     OLECMDF_SUPPORTED,                  /* OLECMDID_COPY */
1954     OLECMDF_SUPPORTED,                  /* OLECMDID_PASTE */
1955     OLECMDF_SUPPORTED,                  /* OLECMDID_PASTESPECIAL */
1956     OLECMDF_SUPPORTED,                  /* OLECMDID_UNDO */
1957     OLECMDF_SUPPORTED,                  /* OLECMDID_REDO */
1958     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_SELECTALL */
1959     OLECMDF_SUPPORTED,                  /* OLECMDID_CLEARSELECTION */
1960     OLECMDF_SUPPORTED,                  /* OLECMDID_ZOOM */
1961     OLECMDF_SUPPORTED,                  /* OLECMDID_GETZOOMRANGE */
1962     0,
1963     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_REFRESH */
1964     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_STOP */
1965     0,0,0,0,0,0,
1966     OLECMDF_SUPPORTED,                  /* OLECMDID_STOPDOWNLOAD */
1967     0,0,
1968     OLECMDF_SUPPORTED,                  /* OLECMDID_DELETE */
1969     0,0,
1970     OLECMDF_SUPPORTED,                  /* OLECMDID_ENABLE_INTERACTION */
1971     OLECMDF_SUPPORTED,                  /* OLECMDID_ONUNLOAD */
1972     0,0,0,0,0,
1973     OLECMDF_SUPPORTED,                  /* OLECMDID_SHOWPAGESETUP */
1974     OLECMDF_SUPPORTED,                  /* OLECMDID_SHOWPRINT */
1975     0,0,
1976     OLECMDF_SUPPORTED,                  /* OLECMDID_CLOSE */
1977     0,0,0,
1978     OLECMDF_SUPPORTED,                  /* OLECMDID_SETPRINTTEMPLATE */
1979     OLECMDF_SUPPORTED                   /* OLECMDID_GETPRINTTEMPLATE */
1980 };
1981
1982 static void test_OleCommandTarget(IUnknown *unk)
1983 {
1984     IOleCommandTarget *cmdtrg;
1985     OLECMD cmds[OLECMDID_GETPRINTTEMPLATE];
1986     int i;
1987     HRESULT hres;
1988
1989     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
1990     ok(hres == S_OK, "QueryInterface(IIDIOleM=CommandTarget failed: %08x\n", hres);
1991     if(FAILED(hres))
1992         return;
1993
1994     for(i=0; i<OLECMDID_GETPRINTTEMPLATE; i++) {
1995         cmds[i].cmdID = i+1;
1996         cmds[i].cmdf = 0xf0f0;
1997     }
1998
1999     SET_EXPECT(QueryStatus_OPEN);
2000     SET_EXPECT(QueryStatus_NEW);
2001     hres = IOleCommandTarget_QueryStatus(cmdtrg, NULL, sizeof(cmds)/sizeof(cmds[0]), cmds, NULL);
2002     ok(hres == S_OK, "QueryStatus failed: %08x\n", hres);
2003     CHECK_CALLED(QueryStatus_OPEN);
2004     CHECK_CALLED(QueryStatus_NEW);
2005
2006     for(i=0; i<OLECMDID_GETPRINTTEMPLATE; i++) {
2007         ok(cmds[i].cmdID == i+1, "cmds[%d].cmdID canged to %x\n", i, cmds[i].cmdID);
2008         ok(cmds[i].cmdf == expect_cmds[i+1], "cmds[%d].cmdf=%x, expected %x\n",
2009                 i+1, cmds[i].cmdf, expect_cmds[i+1]);
2010     }
2011
2012     IOleCommandTarget_Release(cmdtrg);
2013 }
2014
2015 static void test_OleCommandTarget_fail(IUnknown *unk)
2016 {
2017     IOleCommandTarget *cmdtrg;
2018     int i;
2019     HRESULT hres;
2020
2021     OLECMD cmd[2] = {
2022         {OLECMDID_OPEN, 0xf0f0},
2023         {OLECMDID_GETPRINTTEMPLATE+1, 0xf0f0}
2024     };
2025
2026     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
2027     ok(hres == S_OK, "QueryInterface(IIDIOleM=CommandTarget failed: %08x\n", hres);
2028     if(FAILED(hres))
2029         return;
2030
2031     hres = IOleCommandTarget_QueryStatus(cmdtrg, NULL, 0, NULL, NULL);
2032     ok(hres == S_OK, "QueryStatus failed: %08x\n", hres);
2033
2034     SET_EXPECT(QueryStatus_OPEN);
2035     hres = IOleCommandTarget_QueryStatus(cmdtrg, NULL, 2, cmd, NULL);
2036     CHECK_CALLED(QueryStatus_OPEN);
2037
2038     ok(hres == OLECMDERR_E_NOTSUPPORTED,
2039             "QueryStatus failed: %08x, expected OLECMDERR_E_NOTSUPPORTED\n", hres);
2040     ok(cmd[1].cmdID == OLECMDID_GETPRINTTEMPLATE+1,
2041             "cmd[0].cmdID=%d, expected OLECMDID_GETPRINTTEMPLATE+1\n", cmd[0].cmdID);
2042     ok(cmd[1].cmdf == 0, "cmd[0].cmdf=%x, expected 0\n", cmd[0].cmdf);
2043     ok(cmd[0].cmdf == OLECMDF_SUPPORTED,
2044             "cmd[1].cmdf=%x, expected OLECMDF_SUPPORTED\n", cmd[1].cmdf);
2045
2046     hres = IOleCommandTarget_QueryStatus(cmdtrg, &IID_IHTMLDocument2, 2, cmd, NULL);
2047     ok(hres == OLECMDERR_E_UNKNOWNGROUP,
2048             "QueryStatus failed: %08x, expected OLECMDERR_E_UNKNOWNGROUP\n", hres);
2049
2050     for(i=0; i<OLECMDID_GETPRINTTEMPLATE; i++) {
2051         if(!expect_cmds[i]) {
2052             hres = IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_UPDATECOMMANDS,
2053                     OLECMDEXECOPT_DODEFAULT, NULL, NULL);
2054             ok(hres == OLECMDERR_E_NOTSUPPORTED,
2055                     "Exec failed: %08x, expected OLECMDERR_E_NOTSUPPORTED\n", hres);
2056         }
2057     }
2058
2059     hres = IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_GETPRINTTEMPLATE+1,
2060             OLECMDEXECOPT_DODEFAULT, NULL, NULL);
2061     ok(hres == OLECMDERR_E_NOTSUPPORTED,
2062             "Exec failed: %08x, expected OLECMDERR_E_NOTSUPPORTED\n", hres);
2063
2064     IOleCommandTarget_Release(cmdtrg);
2065 }
2066
2067 static void test_exec_onunload(IUnknown *unk)
2068 {
2069     IOleCommandTarget *cmdtrg;
2070     VARIANT var;
2071     HRESULT hres;
2072
2073     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
2074     ok(hres == S_OK, "QueryInterface(IID_IOleCommandTarget) failed: %08x\n", hres);
2075     if(FAILED(hres))
2076         return;
2077
2078     memset(&var, 0x0a, sizeof(var));
2079     hres = IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_ONUNLOAD,
2080             OLECMDEXECOPT_DODEFAULT, NULL, &var);
2081     ok(hres == S_OK, "Exec(..., OLECMDID_ONUNLOAD, ...) failed: %08x\n", hres);
2082     ok(V_VT(&var) == VT_BOOL, "V_VT(var)=%d, expected VT_BOOL\n", V_VT(&var));
2083     ok(V_BOOL(&var) == VARIANT_TRUE, "V_BOOL(var)=%x, expected VARIANT_TRUE\n", V_BOOL(&var));
2084
2085     hres = IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_ONUNLOAD,
2086             OLECMDEXECOPT_DODEFAULT, NULL, NULL);
2087     ok(hres == S_OK, "Exec(..., OLECMDID_ONUNLOAD, ...) failed: %08x\n", hres);
2088
2089     IOleCommandTarget_Release(cmdtrg);
2090 }
2091
2092 static void test_exec_editmode(IUnknown *unk)
2093 {
2094     IOleCommandTarget *cmdtrg;
2095     HRESULT hres;
2096
2097     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
2098     ok(hres == S_OK, "QueryInterface(IID_IOleCommandTarget) failed: %08x\n", hres);
2099     if(FAILED(hres))
2100         return;
2101
2102     SET_EXPECT(SetStatusText);
2103     SET_EXPECT(Exec_ShellDocView_37);
2104     SET_EXPECT(GetHostInfo);
2105     SET_EXPECT(Invoke_AMBIENT_SILENT);
2106     SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
2107     SET_EXPECT(OnChanged_READYSTATE);
2108     expect_status_text = NULL;
2109     readystate_set_loading = TRUE;
2110
2111     hres = IOleCommandTarget_Exec(cmdtrg, &CGID_MSHTML, IDM_EDITMODE,
2112             OLECMDEXECOPT_DODEFAULT, NULL, NULL);
2113     ok(hres == S_OK, "Exec failed: %08x\n", hres);
2114
2115     CHECK_CALLED(SetStatusText);
2116     CHECK_CALLED(Exec_ShellDocView_37);
2117     CHECK_CALLED(GetHostInfo);
2118     CHECK_CALLED(Invoke_AMBIENT_SILENT);
2119     CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
2120     CHECK_CALLED(OnChanged_READYSTATE);
2121
2122     IOleCommandTarget_Release(cmdtrg);
2123 }
2124
2125 static HWND create_container_window(void)
2126 {
2127     static const WCHAR wszHTMLDocumentTest[] =
2128         {'H','T','M','L','D','o','c','u','m','e','n','t','T','e','s','t',0};
2129     static WNDCLASSEXW wndclass = {
2130         sizeof(WNDCLASSEXW),
2131         0,
2132         wnd_proc,
2133         0, 0, NULL, NULL, NULL, NULL, NULL,
2134         wszHTMLDocumentTest,
2135         NULL
2136     };
2137
2138     RegisterClassExW(&wndclass);
2139     return CreateWindowW(wszHTMLDocumentTest, wszHTMLDocumentTest,
2140             WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
2141             CW_USEDEFAULT, NULL, NULL, NULL, NULL);
2142 }
2143
2144 static HRESULT test_DoVerb(IOleObject *oleobj)
2145 {
2146     RECT rect = {0,0,500,500};
2147     HRESULT hres;
2148
2149     if(!container_locked) {
2150         SET_EXPECT(GetContainer);
2151         SET_EXPECT(LockContainer);
2152     }
2153     SET_EXPECT(ActivateMe);
2154     expect_LockContainer_fLock = TRUE;
2155
2156     hres = IOleObject_DoVerb(oleobj, OLEIVERB_SHOW, NULL, &ClientSite, -1, container_hwnd, &rect);
2157     if(FAILED(hres))
2158         return hres;
2159     ok(hres == S_OK, "DoVerb failed: %08x\n", hres);
2160
2161     if(!container_locked) {
2162         CHECK_CALLED(GetContainer);
2163         CHECK_CALLED(LockContainer);
2164         container_locked = TRUE;
2165     }
2166     CHECK_CALLED(ActivateMe);
2167
2168     return hres;
2169 }
2170
2171 #define CLIENTSITE_EXPECTPATH 0x00000001
2172 #define CLIENTSITE_SETNULL    0x00000002
2173 #define CLIENTSITE_DONTSET    0x00000004
2174
2175 static void test_ClientSite(IOleObject *oleobj, DWORD flags)
2176 {
2177     IOleClientSite *clientsite;
2178     HRESULT hres;
2179
2180     if(flags & CLIENTSITE_SETNULL) {
2181         hres = IOleObject_GetClientSite(oleobj, &clientsite);
2182         ok(clientsite == &ClientSite, "clientsite=%p, expected %p\n", clientsite, &ClientSite);
2183
2184         hres = IOleObject_SetClientSite(oleobj, NULL);
2185         ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
2186
2187         set_clientsite = FALSE;
2188     }
2189
2190     if(flags & CLIENTSITE_DONTSET)
2191         return;
2192
2193     hres = IOleObject_GetClientSite(oleobj, &clientsite);
2194     ok(hres == S_OK, "GetClientSite failed: %08x\n", hres);
2195     ok(clientsite == (set_clientsite ? &ClientSite : NULL), "GetClientSite() = %p, expected %p\n",
2196             clientsite, set_clientsite ? &ClientSite : NULL);
2197
2198     if(!set_clientsite) {
2199         SET_EXPECT(GetHostInfo);
2200         if(flags & CLIENTSITE_EXPECTPATH) {
2201             SET_EXPECT(GetOptionKeyPath);
2202             SET_EXPECT(GetOverrideKeyPath);
2203         }
2204         SET_EXPECT(GetWindow);
2205         SET_EXPECT(QueryStatus_SETPROGRESSTEXT);
2206         SET_EXPECT(Exec_SETPROGRESSMAX);
2207         SET_EXPECT(Exec_SETPROGRESSPOS);
2208         SET_EXPECT(Invoke_AMBIENT_USERMODE);
2209         SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
2210         SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
2211         SET_EXPECT(Invoke_AMBIENT_SILENT);
2212         SET_EXPECT(Invoke_AMBIENT_USERAGENT);
2213         SET_EXPECT(Invoke_AMBIENT_PALETTE);
2214
2215         hres = IOleObject_SetClientSite(oleobj, &ClientSite);
2216         ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
2217
2218         CHECK_CALLED(GetHostInfo);
2219         if(flags & CLIENTSITE_EXPECTPATH) {
2220             CHECK_CALLED(GetOptionKeyPath);
2221             CHECK_CALLED(GetOverrideKeyPath);
2222         }
2223         CHECK_CALLED(GetWindow);
2224         CHECK_CALLED(QueryStatus_SETPROGRESSTEXT);
2225         CHECK_CALLED(Exec_SETPROGRESSMAX);
2226         CHECK_CALLED(Exec_SETPROGRESSPOS);
2227         CHECK_CALLED(Invoke_AMBIENT_USERMODE);
2228         CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
2229         CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED); 
2230         CHECK_CALLED(Invoke_AMBIENT_SILENT);
2231         CHECK_CALLED(Invoke_AMBIENT_USERAGENT);
2232         CHECK_CALLED(Invoke_AMBIENT_PALETTE);
2233
2234         set_clientsite = TRUE;
2235     }
2236
2237     hres = IOleObject_SetClientSite(oleobj, &ClientSite);
2238     ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
2239
2240     hres = IOleObject_GetClientSite(oleobj, &clientsite);
2241     ok(hres == S_OK, "GetClientSite failed: %08x\n", hres);
2242     ok(clientsite == &ClientSite, "GetClientSite() = %p, expected %p\n", clientsite, &ClientSite);
2243 }
2244
2245 static void test_OnAmbientPropertyChange(IUnknown *unk)
2246 {
2247     IOleControl *control = NULL;
2248     HRESULT hres;
2249
2250     hres = IUnknown_QueryInterface(unk, &IID_IOleControl, (void**)&control);
2251     ok(hres == S_OK, "QueryInterface(IID_IOleControl failed: %08x\n", hres);
2252     if(FAILED(hres))
2253         return;
2254
2255     SET_EXPECT(Invoke_AMBIENT_USERMODE);
2256     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_USERMODE);
2257     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
2258     CHECK_CALLED(Invoke_AMBIENT_USERMODE);
2259
2260     SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
2261     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_DLCONTROL);
2262     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
2263     CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
2264
2265     SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
2266     SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
2267     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_OFFLINEIFNOTCONNECTED);
2268     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
2269     CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
2270     CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
2271
2272     SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
2273     SET_EXPECT(Invoke_AMBIENT_SILENT);
2274     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_SILENT);
2275     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
2276     CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
2277     CHECK_CALLED(Invoke_AMBIENT_SILENT);
2278
2279     SET_EXPECT(Invoke_AMBIENT_USERAGENT);
2280     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_USERAGENT);
2281     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
2282     CHECK_CALLED(Invoke_AMBIENT_USERAGENT);
2283
2284     SET_EXPECT(Invoke_AMBIENT_PALETTE);
2285     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_PALETTE);
2286     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
2287     CHECK_CALLED(Invoke_AMBIENT_PALETTE);
2288
2289     IOleControl_Release(control);
2290 }
2291
2292
2293
2294 static void test_OnAmbientPropertyChange2(IUnknown *unk)
2295 {
2296     IOleControl *control = NULL;
2297     HRESULT hres;
2298
2299     hres = IUnknown_QueryInterface(unk, &IID_IOleControl, (void**)&control);
2300     ok(hres == S_OK, "QueryInterface(IID_IOleControl failed: %08x\n", hres);
2301     if(FAILED(hres))
2302         return;
2303
2304     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_PALETTE);
2305     ok(hres == S_OK, "OnAmbientPropertyChange failed: %08x\n", hres);
2306
2307     IOleControl_Release(control);
2308 }
2309
2310 static void test_Close(IUnknown *unk, BOOL set_client)
2311 {
2312     IOleObject *oleobj = NULL;
2313     HRESULT hres;
2314
2315     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
2316     ok(hres == S_OK, "QueryInterface(IID_IOleObject) failed: %08x\n", hres);
2317     if(FAILED(hres))
2318         return;
2319
2320     SET_EXPECT(GetContainer);
2321     SET_EXPECT(LockContainer);
2322     expect_LockContainer_fLock = FALSE;
2323     hres = IOleObject_Close(oleobj, OLECLOSE_NOSAVE);
2324     ok(hres == S_OK, "Close failed: %08x\n", hres);
2325     CHECK_CALLED(GetContainer);
2326     CHECK_CALLED(LockContainer);
2327     container_locked = FALSE;
2328
2329     if(set_client)
2330         test_ClientSite(oleobj, CLIENTSITE_SETNULL|CLIENTSITE_DONTSET);
2331
2332     IOleObject_Release(oleobj);
2333 }
2334
2335 static void test_OnFrameWindowActivate(IUnknown *unk)
2336 {
2337     IOleInPlaceActiveObject *inplaceact;
2338     HRESULT hres;
2339
2340     hres = IUnknown_QueryInterface(unk, &IID_IOleInPlaceActiveObject, (void**)&inplaceact);
2341     ok(hres == S_OK, "QueryInterface(IID_IOleInPlaceActiveObject) failed: %08x\n", hres);
2342     if(FAILED(hres))
2343         return;
2344
2345     if(set_clientsite) {
2346         expect_OnFrameWindowActivate_fActivate = TRUE;
2347         SET_EXPECT(OnFrameWindowActivate);
2348         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, TRUE);
2349         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
2350         CHECK_CALLED(OnFrameWindowActivate);
2351
2352         SET_EXPECT(OnFrameWindowActivate);
2353         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, TRUE);
2354         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
2355         CHECK_CALLED(OnFrameWindowActivate);
2356
2357         expect_OnFrameWindowActivate_fActivate = FALSE;
2358         SET_EXPECT(OnFrameWindowActivate);
2359         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, FALSE);
2360         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
2361         CHECK_CALLED(OnFrameWindowActivate);
2362
2363         expect_OnFrameWindowActivate_fActivate = TRUE;
2364         SET_EXPECT(OnFrameWindowActivate);
2365         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, TRUE);
2366         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
2367         CHECK_CALLED(OnFrameWindowActivate);
2368     }else {
2369         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, FALSE);
2370         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
2371
2372         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, TRUE);
2373         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
2374     }
2375
2376     IOleInPlaceActiveObject_Release(inplaceact);
2377 }
2378
2379 static void test_InPlaceDeactivate(IUnknown *unk, BOOL expect_call)
2380 {
2381     IOleInPlaceObjectWindowless *windowlessobj = NULL;
2382     HRESULT hres;
2383
2384     hres = IUnknown_QueryInterface(unk, &IID_IOleInPlaceObjectWindowless,
2385             (void**)&windowlessobj);
2386     ok(hres == S_OK, "QueryInterface(IID_IOleInPlaceObjectWindowless) failed: %08x\n", hres);
2387     if(FAILED(hres))
2388         return;
2389
2390     if(expect_call) SET_EXPECT(OnInPlaceDeactivate);
2391     hres = IOleInPlaceObjectWindowless_InPlaceDeactivate(windowlessobj);
2392     ok(hres == S_OK, "InPlaceDeactivate failed: %08x\n", hres);
2393     if(expect_call) CHECK_CALLED(OnInPlaceDeactivate);
2394
2395     IOleInPlaceObjectWindowless_Release(windowlessobj);
2396 }
2397
2398 static HRESULT test_Activate(IUnknown *unk, DWORD flags)
2399 {
2400     IOleObject *oleobj = NULL;
2401     GUID guid;
2402     HRESULT hres;
2403
2404     last_hwnd = hwnd;
2405
2406     if(view)
2407         IOleDocumentView_Release(view);
2408     view = NULL;
2409
2410     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
2411     ok(hres == S_OK, "QueryInterface(IID_IOleObject) failed: %08x\n", hres);
2412     if(FAILED(hres))
2413         return hres;
2414
2415     hres = IOleObject_GetUserClassID(oleobj, NULL);
2416     ok(hres == E_INVALIDARG, "GetUserClassID returned: %08x, expected E_INVALIDARG\n", hres);
2417
2418     hres = IOleObject_GetUserClassID(oleobj, &guid);
2419     ok(hres == S_OK, "GetUserClassID failed: %08x\n", hres);
2420     ok(IsEqualGUID(&guid, &CLSID_HTMLDocument), "guid != CLSID_HTMLDocument\n");
2421
2422     test_OnFrameWindowActivate(unk);
2423
2424     test_ClientSite(oleobj, flags);
2425     test_InPlaceDeactivate(unk, FALSE);
2426
2427     hres = test_DoVerb(oleobj);
2428
2429     IOleObject_Release(oleobj);
2430
2431     test_OnFrameWindowActivate(unk);
2432
2433     return hres;
2434 }
2435
2436 static void test_Window(IUnknown *unk, BOOL expect_success)
2437 {
2438     IOleInPlaceActiveObject *activeobject = NULL;
2439     HWND tmp_hwnd;
2440     HRESULT hres;
2441
2442     hres = IOleDocumentView_QueryInterface(view, &IID_IOleInPlaceActiveObject, (void**)&activeobject);
2443     ok(hres == S_OK, "Could not get IOleInPlaceActiveObject interface: %08x\n", hres);
2444     if(FAILED(hres))
2445         return;
2446
2447     hres = IOleInPlaceActiveObject_GetWindow(activeobject, &tmp_hwnd);
2448
2449     if(expect_success) {
2450         ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
2451         ok(tmp_hwnd == hwnd, "tmp_hwnd=%p, expected %p\n", tmp_hwnd, hwnd);
2452     }else {
2453         ok(hres == E_FAIL, "GetWindow returned %08x, expected E_FAIL\n", hres);
2454         ok(IsWindow(hwnd), "hwnd is destroyed\n");
2455     }
2456
2457     IOleInPlaceActiveObject_Release(activeobject);
2458 }
2459
2460 static void test_CloseView(void)
2461 {
2462     IOleInPlaceSite *inplacesite = (IOleInPlaceSite*)0xff00ff00;
2463     HRESULT hres;
2464
2465     if(!view)
2466         return;
2467
2468     hres = IOleDocumentView_Show(view, FALSE);
2469     ok(hres == S_OK, "Show failed: %08x\n", hres);
2470
2471     hres = IOleDocumentView_CloseView(view, 0);
2472     ok(hres == S_OK, "CloseView failed: %08x\n", hres);
2473
2474     hres = IOleDocumentView_SetInPlaceSite(view, NULL);
2475     ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
2476
2477     hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
2478     ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
2479     ok(inplacesite == NULL, "inplacesite=%p, expected NULL\n", inplacesite);
2480 }
2481
2482 static void test_UIDeactivate(void)
2483 {
2484     HRESULT hres;
2485
2486     if(call_UIActivate) {
2487         SET_EXPECT(SetActiveObject);
2488         SET_EXPECT(HideUI);
2489         SET_EXPECT(OnUIDeactivate);
2490     }
2491
2492     expect_SetActiveObject_active = FALSE;
2493     hres = IOleDocumentView_UIActivate(view, FALSE);
2494     ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
2495
2496     if(call_UIActivate) {
2497         CHECK_CALLED(SetActiveObject);
2498         CHECK_CALLED(HideUI);
2499         CHECK_CALLED(OnUIDeactivate);
2500     }
2501 }
2502
2503 static void test_Hide(void)
2504 {
2505     HRESULT hres;
2506
2507     if(!view)
2508         return;
2509
2510     hres = IOleDocumentView_Show(view, FALSE);
2511     ok(hres == S_OK, "Show failed: %08x\n", hres);
2512 }
2513
2514 static HRESULT create_document(IUnknown **unk)
2515 {
2516     HRESULT hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2517             &IID_IUnknown, (void**)unk);
2518     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2519     return hres;
2520 }
2521
2522 static void test_Navigate(IUnknown *unk)
2523 {
2524     IHlinkTarget *hlink;
2525     HRESULT hres;
2526
2527     hres = IUnknown_QueryInterface(unk, &IID_IHlinkTarget, (void**)&hlink);
2528     ok(hres == S_OK, "QueryInterface(IID_IHlinkTarget) failed: %08x\n", hres);
2529
2530     SET_EXPECT(ActivateMe);
2531     hres = IHlinkTarget_Navigate(hlink, 0, NULL);
2532     ok(hres == S_OK, "Navigate failed: %08x\n", hres);
2533     CHECK_CALLED(ActivateMe);
2534
2535     IHlinkTarget_Release(hlink);
2536 }
2537
2538 static void test_QueryInterface(IUnknown *unk)
2539 {
2540     IRunnableObject *runnable = (IRunnableObject*)0xdeadbeef;
2541     HRESULT hres;
2542
2543     hres = IUnknown_QueryInterface(unk, &IID_IRunnableObject, (void**)&runnable);
2544     ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
2545     ok(runnable == NULL, "runnable=%p, ezpected NULL\n", runnable);
2546 }
2547
2548 static void init_test(enum load_state_t ls) {
2549     hwnd = last_hwnd = NULL;
2550     set_clientsite = FALSE;
2551     call_UIActivate = FALSE;
2552     load_state = ls;
2553 }
2554
2555 static void test_HTMLDocument(enum load_state_t ls)
2556 {
2557     IUnknown *unk;
2558     HRESULT hres;
2559     ULONG ref;
2560
2561     trace("Testing HTMLDocument (%s)...\n", (ls == LD_DOLOAD ? " load" : "no load"));
2562
2563     init_test(ls);
2564
2565     hres = create_document(&unk);
2566     if(FAILED(hres))
2567         return;
2568
2569     test_QueryInterface(unk);
2570     test_ConnectionPointContainer(unk);
2571     test_Persist(unk);
2572     if(load_state == LD_NO)
2573         test_OnAmbientPropertyChange2(unk);
2574
2575     hres = test_Activate(unk, CLIENTSITE_EXPECTPATH);
2576     if(FAILED(hres)) {
2577         IUnknown_Release(unk);
2578         return;
2579     }
2580
2581     if(load_state == LD_LOADING)
2582         test_download();
2583
2584     test_OleCommandTarget_fail(unk);
2585     test_OleCommandTarget(unk);
2586     test_OnAmbientPropertyChange(unk);
2587     test_Window(unk, TRUE);
2588     test_UIDeactivate();
2589     test_OleCommandTarget(unk);
2590     test_Window(unk, TRUE);
2591     test_InPlaceDeactivate(unk, TRUE);
2592
2593     /* Calling test_OleCommandTarget here couses Segmentation Fault with native
2594      * MSHTML. It doesn't with Wine. */
2595
2596     test_Window(unk, FALSE);
2597     test_Hide();
2598     test_InPlaceDeactivate(unk, FALSE);
2599     test_CloseView();
2600     test_Close(unk, FALSE);
2601
2602     /* Activate HTMLDocument again */
2603     test_Activate(unk, CLIENTSITE_SETNULL);
2604     test_Window(unk, TRUE);
2605     test_OleCommandTarget(unk);
2606     test_UIDeactivate();
2607     test_InPlaceDeactivate(unk, TRUE);
2608     test_Close(unk, FALSE);
2609
2610     /* Activate HTMLDocument again, this time without UIActivate */
2611     call_UIActivate = FALSE;
2612     test_Activate(unk, CLIENTSITE_SETNULL);
2613     test_Window(unk, TRUE);
2614     test_UIDeactivate();
2615     test_InPlaceDeactivate(unk, TRUE);
2616     test_CloseView();
2617     test_CloseView();
2618     test_Close(unk, TRUE);
2619     test_OnAmbientPropertyChange2(unk);
2620
2621     if(view)
2622         IOleDocumentView_Release(view);
2623     view = NULL;
2624
2625     ok(IsWindow(hwnd), "hwnd is destroyed\n");
2626
2627     ref = IUnknown_Release(unk);
2628     ok(ref == 0, "ref=%d, expected 0\n", ref);
2629
2630     ok(!IsWindow(hwnd), "hwnd is not destroyed\n");
2631 }
2632
2633 static void test_HTMLDocument_hlink(void)
2634 {
2635     IUnknown *unk;
2636     HRESULT hres;
2637     ULONG ref;
2638
2639     trace("Testing HTMLDocument (hlink)...\n");
2640
2641     init_test(LD_DOLOAD);
2642
2643     hres = create_document(&unk);
2644     if(FAILED(hres))
2645         return;
2646
2647     test_ConnectionPointContainer(unk);
2648     test_Persist(unk);
2649     test_Navigate(unk);
2650
2651     test_download();
2652
2653     test_exec_onunload(unk);
2654     test_Window(unk, TRUE);
2655     test_InPlaceDeactivate(unk, TRUE);
2656     test_Close(unk, FALSE);
2657
2658     if(view)
2659         IOleDocumentView_Release(view);
2660     view = NULL;
2661
2662     ref = IUnknown_Release(unk);
2663     ok(ref == 0, "ref=%d, expected 0\n", ref);
2664 }
2665
2666 static void test_editing_mode(void)
2667 {
2668     IUnknown *unk;
2669     IOleObject *oleobj;
2670     HRESULT hres;
2671     ULONG ref;
2672
2673     trace("Testing HTMLDocument (edit)...\n");
2674
2675     init_test(LD_DOLOAD);
2676
2677     hres = create_document(&unk);
2678     if(FAILED(hres))
2679         return;
2680
2681     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
2682     ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres);
2683
2684     test_readyState(unk);
2685     test_ConnectionPointContainer(unk);
2686     test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH);
2687     test_DoVerb(oleobj);
2688
2689     IOleObject_Release(oleobj);
2690
2691     test_exec_editmode(unk);
2692
2693     test_UIDeactivate();
2694     test_InPlaceDeactivate(unk, TRUE);
2695     test_Close(unk, FALSE);
2696
2697     if(view) {
2698         IOleDocumentView_Release(view);
2699         view = NULL;
2700     }
2701
2702     ref = IUnknown_Release(unk);
2703     ok(ref == 0, "ref=%d, expected 0\n", ref);
2704 }
2705
2706 static void gecko_installer_workaround(BOOL disable)
2707 {
2708     HKEY hkey;
2709     DWORD res;
2710
2711     static BOOL has_url = FALSE;
2712     static char url[2048];
2713
2714     if(!disable && !has_url)
2715         return;
2716
2717     res = RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\MSHTML", &hkey);
2718     if(res != ERROR_SUCCESS)
2719         return;
2720
2721     if(disable) {
2722         DWORD type, size = sizeof(url);
2723
2724         res = RegQueryValueEx(hkey, "GeckoUrl", NULL, &type, (PVOID)url, &size);
2725         if(res == ERROR_SUCCESS && type == REG_SZ)
2726             has_url = TRUE;
2727
2728         RegDeleteValue(hkey, "GeckoUrl");
2729     }else {
2730         RegSetValueEx(hkey, "GeckoUrl", 0, REG_SZ, (PVOID)url, lstrlenA(url)+1);
2731     }
2732
2733     RegCloseKey(hkey);
2734 }
2735
2736 START_TEST(htmldoc)
2737 {
2738     gecko_installer_workaround(TRUE);
2739
2740     CoInitialize(NULL);
2741     container_hwnd = create_container_window();
2742
2743     test_HTMLDocument(LD_NO);
2744     test_HTMLDocument(LD_DOLOAD);
2745     test_HTMLDocument_hlink();
2746     test_editing_mode();
2747
2748     DestroyWindow(container_hwnd);
2749     CoUninitialize();
2750
2751     gecko_installer_workaround(FALSE);
2752 }