mshtml: Fix a few test failures in win2k3.
[wine] / dlls / mshtml / tests / htmldoc.c
1 /*
2  * Copyright 2005-2007 Jacek Caban for CodeWeavers
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 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "mshtml.h"
30 #include "docobj.h"
31 #include "mshtmhst.h"
32 #include "mshtmdid.h"
33 #include "mshtmcid.h"
34 #include "hlink.h"
35 #include "dispex.h"
36 #include "idispids.h"
37 #include "shlguid.h"
38
39 #include "initguid.h"
40 DEFINE_OLEGUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0);
41
42 #define DEFINE_EXPECT(func) \
43     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
44
45 #define SET_EXPECT(func) \
46     expect_ ## func = TRUE
47
48 #define SET_CALLED(func) \
49     called_ ## func = TRUE
50
51 #define CHECK_EXPECT2(func) \
52     do { \
53         ok(expect_ ##func, "unexpected call " #func "\n"); \
54         called_ ## func = TRUE; \
55     }while(0)
56
57 #define CHECK_EXPECT(func) \
58     do { \
59         CHECK_EXPECT2(func); \
60         expect_ ## func = FALSE; \
61     }while(0)
62
63 #define CHECK_CALLED(func) \
64     do { \
65         ok(called_ ## func, "expected " #func "\n"); \
66         expect_ ## func = called_ ## func = FALSE; \
67     }while(0)
68
69 static IOleDocumentView *view = NULL;
70 static HWND container_hwnd = NULL, hwnd = NULL, last_hwnd = NULL;
71
72 DEFINE_EXPECT(LockContainer);
73 DEFINE_EXPECT(SetActiveObject);
74 DEFINE_EXPECT(SetActiveObject_null);
75 DEFINE_EXPECT(GetWindow);
76 DEFINE_EXPECT(CanInPlaceActivate);
77 DEFINE_EXPECT(OnInPlaceActivate);
78 DEFINE_EXPECT(OnInPlaceActivateEx);
79 DEFINE_EXPECT(OnUIActivate);
80 DEFINE_EXPECT(GetWindowContext);
81 DEFINE_EXPECT(OnUIDeactivate);
82 DEFINE_EXPECT(OnInPlaceDeactivate);
83 DEFINE_EXPECT(OnInPlaceDeactivateEx);
84 DEFINE_EXPECT(GetContainer);
85 DEFINE_EXPECT(ShowUI);
86 DEFINE_EXPECT(ActivateMe);
87 DEFINE_EXPECT(GetHostInfo);
88 DEFINE_EXPECT(HideUI);
89 DEFINE_EXPECT(GetOptionKeyPath);
90 DEFINE_EXPECT(GetOverrideKeyPath);
91 DEFINE_EXPECT(SetStatusText);
92 DEFINE_EXPECT(QueryStatus_SETPROGRESSTEXT);
93 DEFINE_EXPECT(QueryStatus_OPEN);
94 DEFINE_EXPECT(QueryStatus_NEW);
95 DEFINE_EXPECT(Exec_SETPROGRESSMAX);
96 DEFINE_EXPECT(Exec_SETPROGRESSPOS);
97 DEFINE_EXPECT(Exec_HTTPEQUIV_DONE); 
98 DEFINE_EXPECT(Exec_SETDOWNLOADSTATE_0);
99 DEFINE_EXPECT(Exec_SETDOWNLOADSTATE_1);
100 DEFINE_EXPECT(Exec_ShellDocView_37);
101 DEFINE_EXPECT(Exec_ShellDocView_84);
102 DEFINE_EXPECT(Exec_UPDATECOMMANDS);
103 DEFINE_EXPECT(Exec_SETTITLE);
104 DEFINE_EXPECT(Exec_HTTPEQUIV);
105 DEFINE_EXPECT(Exec_MSHTML_PARSECOMPLETE);
106 DEFINE_EXPECT(Invoke_AMBIENT_USERMODE);
107 DEFINE_EXPECT(Invoke_AMBIENT_DLCONTROL);
108 DEFINE_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
109 DEFINE_EXPECT(Invoke_AMBIENT_SILENT);
110 DEFINE_EXPECT(Invoke_AMBIENT_USERAGENT);
111 DEFINE_EXPECT(Invoke_AMBIENT_PALETTE);
112 DEFINE_EXPECT(GetDropTarget);
113 DEFINE_EXPECT(UpdateUI);
114 DEFINE_EXPECT(Navigate);
115 DEFINE_EXPECT(OnFrameWindowActivate);
116 DEFINE_EXPECT(OnChanged_READYSTATE);
117 DEFINE_EXPECT(OnChanged_1005);
118 DEFINE_EXPECT(GetDisplayName);
119 DEFINE_EXPECT(BindToStorage);
120 DEFINE_EXPECT(IsSystemMoniker);
121 DEFINE_EXPECT(GetBindResult);
122 DEFINE_EXPECT(GetClassID);
123 DEFINE_EXPECT(Abort);
124 DEFINE_EXPECT(Read);
125 DEFINE_EXPECT(CreateInstance);
126 DEFINE_EXPECT(Start);
127 DEFINE_EXPECT(Terminate);
128 DEFINE_EXPECT(Protocol_Read);
129 DEFINE_EXPECT(LockRequest);
130 DEFINE_EXPECT(UnlockRequest);
131 DEFINE_EXPECT(OnFocus_TRUE);
132 DEFINE_EXPECT(OnFocus_FALSE);
133 DEFINE_EXPECT(RequestUIActivate);
134 DEFINE_EXPECT(InPlaceFrame_SetBorderSpace);
135 DEFINE_EXPECT(InPlaceUIWindow_SetActiveObject);
136 DEFINE_EXPECT(GetExternal);
137
138 static IUnknown *doc_unk;
139 static BOOL expect_LockContainer_fLock;
140 static BOOL expect_InPlaceUIWindow_SetActiveObject_active = TRUE;
141 static BOOL ipsex;
142 static BOOL set_clientsite = FALSE, container_locked = FALSE;
143 static BOOL readystate_set_loading = FALSE, load_from_stream;
144 static BOOL editmode = FALSE;
145 static int stream_read, protocol_read;
146 static enum load_state_t {
147     LD_DOLOAD,
148     LD_LOADING,
149     LD_LOADED,
150     LD_INTERACTIVE,
151     LD_COMPLETE,
152     LD_NO
153 } load_state;
154
155 static LPCOLESTR expect_status_text = NULL;
156
157 static const char html_page[] =
158 "<html>"
159 "<head><link rel=\"stylesheet\" type=\"text/css\" href=\"test.css\"></head>"
160 "<body>test</body>"
161 "</html>";
162
163 static const char css_data[] = "body {color: red}";
164
165 static const WCHAR doc_url[] = {'w','i','n','e','t','e','s','t',':','d','o','c',0};
166 static const WCHAR about_blank_url[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
167
168 static HRESULT QueryInterface(REFIID riid, void **ppv);
169 static void test_MSHTML_QueryStatus(IUnknown*,DWORD);
170 static BOOL nogecko = FALSE;
171
172 #define test_readyState(u) _test_readyState(__LINE__,u)
173 static void _test_readyState(unsigned,IUnknown*);
174
175 static void test_GetCurMoniker(IUnknown*,IMoniker*,LPCWSTR);
176
177 static const WCHAR wszTimesNewRoman[] =
178     {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n',0};
179 static const WCHAR wszArial[] =
180     {'A','r','i','a','l',0};
181
182 static const char *debugstr_guid(REFIID riid)
183 {
184     static char buf[50];
185
186     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
187             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
188             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
189             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
190
191     return buf;
192 }
193
194 static const char *debugstr_w(LPCWSTR str)
195 {
196     static char buf[1024];
197
198     if(!str)
199         return "(null)";
200
201     WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
202     return buf;
203 }
204
205 #define EXPECT_UPDATEUI  1
206 #define EXPECT_SETTITLE  2
207
208 static void test_timer(DWORD flags)
209 {
210     BOOL *b = &called_Exec_SETTITLE;
211     MSG msg;
212
213     if(flags & EXPECT_UPDATEUI) {
214         SET_EXPECT(UpdateUI);
215         SET_EXPECT(Exec_UPDATECOMMANDS);
216         b = &called_UpdateUI;
217     }
218     if(flags & EXPECT_SETTITLE)
219         SET_EXPECT(Exec_SETTITLE);
220
221     while(!*b && GetMessage(&msg, hwnd, 0, 0)) {
222         TranslateMessage(&msg);
223         DispatchMessage(&msg);
224     }
225
226     if(flags & EXPECT_UPDATEUI) {
227         CHECK_CALLED(UpdateUI);
228         CHECK_CALLED(Exec_UPDATECOMMANDS);
229     }
230     if(flags & EXPECT_SETTITLE)
231         CHECK_CALLED(Exec_SETTITLE);
232 }
233
234 DEFINE_GUID(IID_External_unk,0x30510406,0x98B5,0x11CF,0xBB,0x82,0x00,0xAA,0x00,0xBD,0xCE,0x0B);
235
236 static HRESULT WINAPI External_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
237 {
238     *ppv = NULL;
239
240     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDispatch, riid)) {
241         *ppv = iface;
242         return S_OK;
243     }
244
245     if(IsEqualGUID(&IID_IProxyManager, riid))
246         return E_NOINTERFACE; /* TODO */
247     if(IsEqualGUID(&IID_IDispatchEx, riid))
248         return E_NOINTERFACE; /* TODO */
249     if(IsEqualGUID(&IID_External_unk, riid))
250         return E_NOINTERFACE; /* TODO */
251
252     ok(0, "unexpected riid: %s\n", debugstr_guid(riid));
253     return E_NOINTERFACE;
254 }
255
256 static ULONG WINAPI Dispatch_AddRef(IDispatch *iface)
257 {
258     return 2;
259 }
260
261 static ULONG WINAPI Dispatch_Release(IDispatch *iface)
262 {
263     return 1;
264 }
265
266 static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
267 {
268     ok(0, "unexpected call\n");
269     return E_NOTIMPL;
270 }
271
272 static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid,
273         ITypeInfo **ppTInfo)
274 {
275     ok(0, "unexpected call\n");
276     return E_NOTIMPL;
277 }
278
279 static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
280         UINT cNames, LCID lcid, DISPID *rgDispId)
281 {
282     ok(0, "unexpected call\n");
283     return E_NOTIMPL;
284 }
285
286 static HRESULT WINAPI External_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
287         LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
288         EXCEPINFO *pExcepInfo, UINT *puArgErr)
289 {
290     ok(0, "unexpected call\n");
291     return E_NOTIMPL;
292 }
293
294 static const IDispatchVtbl ExternalVtbl = {
295     External_QueryInterface,
296     Dispatch_AddRef,
297     Dispatch_Release,
298     Dispatch_GetTypeInfoCount,
299     Dispatch_GetTypeInfo,
300     Dispatch_GetIDsOfNames,
301     External_Invoke
302 };
303
304 static IDispatch External = { &ExternalVtbl };
305
306 static HRESULT WINAPI Protocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
307 {
308     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
309         *ppv = iface;
310         return S_OK;
311     }
312
313     *ppv = NULL;
314     return E_NOINTERFACE;
315 }
316
317 static ULONG WINAPI Protocol_AddRef(IInternetProtocol *iface)
318 {
319     return 2;
320 }
321
322 static ULONG WINAPI Protocol_Release(IInternetProtocol *iface)
323 {
324     return 1;
325 }
326
327 static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
328         IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
329         DWORD grfPI, DWORD dwReserved)
330 {
331     BINDINFO bindinfo;
332     DWORD bindf = 0;
333     HRESULT hres;
334
335     static const WCHAR wszTextCss[] = {'t','e','x','t','/','c','s','s',0};
336     static const WCHAR empty_str = {0};
337
338     CHECK_EXPECT(Start);
339
340     ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
341     ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
342     ok(!grfPI, "grfPI = %x\n", grfPI);
343     ok(!dwReserved, "dwReserved = %d\n", dwReserved);
344
345     memset(&bindinfo, 0, sizeof(bindinfo));
346     bindinfo.cbSize = sizeof(bindinfo);
347     hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
348     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
349     ok(bindf == (BINDF_FROMURLMON|BINDF_PULLDATA|BINDF_NEEDFILE|BINDF_ASYNCSTORAGE|BINDF_ASYNCHRONOUS),
350        "bindf = %x\n", bindf);
351
352     ok(bindinfo.cbSize == sizeof(bindinfo), "bindinfo.cbSize=%d\n", bindinfo.cbSize);
353     ok(bindinfo.szExtraInfo == NULL, "bindinfo.szExtraInfo=%p\n", bindinfo.szExtraInfo);
354     /* TODO: test stgmedData */
355     ok(bindinfo.grfBindInfoF == 0, "bindinfo.grfBinfInfoF=%08x\n", bindinfo.grfBindInfoF);
356     ok(bindinfo.dwBindVerb == 0, "bindinfo.dwBindVerb=%d\n", bindinfo.dwBindVerb);
357     ok(bindinfo.szCustomVerb == 0, "bindinfo.szCustomVerb=%p\n", bindinfo.szCustomVerb);
358     ok(bindinfo.cbstgmedData == 0, "bindinfo.cbstgmedData=%d\n", bindinfo.cbstgmedData);
359     ok(bindinfo.dwOptions == 0x80000 ||
360        bindinfo.dwOptions == 0x4080000, /* win2k3 */
361        "bindinfo.dwOptions=%x\n", bindinfo.dwOptions);
362     ok(bindinfo.dwOptionsFlags == 0, "bindinfo.dwOptionsFlags=%d\n", bindinfo.dwOptionsFlags);
363     /* TODO: test dwCodePage */
364     /* TODO: test securityAttributes */
365     ok(IsEqualGUID(&IID_NULL, &bindinfo.iid), "unexpected bindinfo.iid\n");
366     ok(bindinfo.pUnk == NULL, "bindinfo.pUnk=%p\n", bindinfo.pUnk);
367     ok(bindinfo.dwReserved == 0, "bindinfo.dwReserved=%d\n", bindinfo.dwReserved);
368
369     hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
370             BINDSTATUS_CACHEFILENAMEAVAILABLE, &empty_str);
371     ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
372
373     hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
374             BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, wszTextCss);
375     ok(hres == S_OK,
376        "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
377
378     hres = IInternetProtocolSink_ReportData(pOIProtSink,
379             BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION, 13, 13);
380     ok(hres == S_OK, "ReportData failed: %08x\n", hres);
381
382     hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
383     ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
384
385     return S_OK;
386 }
387
388 static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface,
389         PROTOCOLDATA *pProtocolData)
390 {
391     ok(0, "unexpected call\n");
392     return E_NOTIMPL;
393 }
394
395 static HRESULT WINAPI Protocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
396         DWORD dwOptions)
397 {
398     ok(0, "unexpected call\n");
399     return E_NOTIMPL;
400 }
401
402 static HRESULT WINAPI Protocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
403 {
404     CHECK_EXPECT(Terminate);
405     return S_OK;
406 }
407
408 static HRESULT WINAPI Protocol_Suspend(IInternetProtocol *iface)
409 {
410     ok(0, "unexpected call\n");
411     return E_NOTIMPL;
412 }
413
414 static HRESULT WINAPI Protocol_Resume(IInternetProtocol *iface)
415 {
416     ok(0, "unexpected call\n");
417     return E_NOTIMPL;
418 }
419
420 static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv,
421         ULONG cb, ULONG *pcbRead)
422 {
423     CHECK_EXPECT2(Protocol_Read);
424
425     ok(pv != NULL, "pv == NULL\n");
426     ok(cb > sizeof(css_data), "cb < sizeof(css_data)\n");
427     ok(pcbRead != NULL, "pcbRead == NULL\n");
428     ok(!*pcbRead, "*pcbRead=%d\n", *pcbRead);
429
430     if(protocol_read)
431         return S_FALSE;
432
433     protocol_read += *pcbRead = sizeof(css_data)-1;
434     memcpy(pv, css_data, sizeof(css_data)-1);
435     return S_OK;
436 }
437
438 static HRESULT WINAPI Protocol_Seek(IInternetProtocol *iface,
439         LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
440 {
441     ok(0, "unexpected call\n");
442     return E_NOTIMPL;
443 }
444
445 static HRESULT WINAPI Protocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
446 {
447     CHECK_EXPECT(LockRequest);
448     return S_OK;
449 }
450
451 static HRESULT WINAPI Protocol_UnlockRequest(IInternetProtocol *iface)
452 {
453     CHECK_EXPECT(UnlockRequest);
454     return S_OK;
455 }
456
457 static const IInternetProtocolVtbl ProtocolVtbl = {
458     Protocol_QueryInterface,
459     Protocol_AddRef,
460     Protocol_Release,
461     Protocol_Start,
462     Protocol_Continue,
463     Protocol_Abort,
464     Protocol_Terminate,
465     Protocol_Suspend,
466     Protocol_Resume,
467     Protocol_Read,
468     Protocol_Seek,
469     Protocol_LockRequest,
470     Protocol_UnlockRequest
471 };
472
473 static IInternetProtocol Protocol = { &ProtocolVtbl };
474
475 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
476 {
477     if(!IsEqualGUID(&IID_IInternetProtocolInfo, riid))
478         ok(0, "unexpected call\n");
479     return E_NOINTERFACE;
480 }
481
482 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
483 {
484     return 2;
485 }
486
487 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
488 {
489     return 1;
490 }
491
492 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
493                                         REFIID riid, void **ppv)
494 {
495     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid))
496         return E_NOINTERFACE;
497
498     CHECK_EXPECT(CreateInstance);
499     ok(ppv != NULL, "ppv == NULL\n");
500
501     *ppv = &Protocol;
502     return S_OK;
503 }
504
505 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
506 {
507     ok(0, "unexpected call\n");
508     return S_OK;
509 }
510
511 static const IClassFactoryVtbl ClassFactoryVtbl = {
512     ClassFactory_QueryInterface,
513     ClassFactory_AddRef,
514     ClassFactory_Release,
515     ClassFactory_CreateInstance,
516     ClassFactory_LockServer
517 };
518
519 static IClassFactory ClassFactory = { &ClassFactoryVtbl };
520
521 static HRESULT WINAPI HlinkFrame_QueryInterface(IHlinkFrame *iface, REFIID riid, void **ppv)
522 {
523     ok(0, "unexpected call\n");
524     return E_NOTIMPL;
525 }
526
527 static ULONG WINAPI HlinkFrame_AddRef(IHlinkFrame *iface)
528 {
529     return 2;
530 }
531
532 static ULONG WINAPI HlinkFrame_Release(IHlinkFrame *iface)
533 {
534     return 1;
535 }
536
537 static HRESULT WINAPI HlinkFrame_SetBrowseContext(IHlinkFrame *iface,
538                                                   IHlinkBrowseContext *pihlbc)
539 {
540     ok(0, "unexpected call\n");
541     return E_NOTIMPL;
542 }
543
544 static HRESULT WINAPI HlinkFrame_GetBrowseContext(IHlinkFrame *iface,
545                                                   IHlinkBrowseContext **ppihlbc)
546 {
547     ok(0, "unexpected call\n");
548     return E_NOTIMPL;
549 }
550
551 static HRESULT WINAPI HlinkFrame_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPBC pbc,
552                                           IBindStatusCallback *pibsc, IHlink *pihlNavigate)
553 {
554     HRESULT hres;
555
556     CHECK_EXPECT(Navigate);
557
558     ok(grfHLNF == 0, "grfHLNF=%d, expected 0\n", grfHLNF);
559     ok(pbc != NULL, "pbc == NULL\n");
560     ok(pibsc != NULL, "pubsc == NULL\n");
561     ok(pihlNavigate != NULL, "puhlNavigate == NULL\n");
562
563     if(pihlNavigate) {
564         LPWSTR frame_name = (LPWSTR)0xdeadbeef;
565         LPWSTR location = (LPWSTR)0xdeadbeef;
566         IHlinkSite *site;
567         IMoniker *mon = NULL;
568         DWORD site_data = 0xdeadbeef;
569
570         hres = IHlink_GetTargetFrameName(pihlNavigate, &frame_name);
571         ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
572         ok(frame_name == NULL, "frame_name = %p\n", frame_name);
573
574         hres = IHlink_GetMonikerReference(pihlNavigate, 1, &mon, &location);
575         ok(hres == S_OK, "GetMonikerReference failed: %08x\n", hres);
576         ok(location == NULL, "location = %p\n", location);
577         ok(mon != NULL, "mon == NULL\n");
578
579         hres = IHlink_GetHlinkSite(pihlNavigate, &site, &site_data);
580         ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
581         ok(site == NULL, "site = %p\n, expected NULL\n", site);
582         ok(site_data == 0xdeadbeef, "site_data = %x\n", site_data);
583     }
584
585     return S_OK;
586 }
587
588 static HRESULT WINAPI HlinkFrame_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF,
589         IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, DWORD dwreserved)
590 {
591     ok(0, "unexpected call\n");
592     return E_NOTIMPL;
593 }
594
595 static HRESULT WINAPI HlinkFrame_UpdateHlink(IHlinkFrame *iface, ULONG uHLID,
596         IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
597 {
598     ok(0, "unexpected call\n");
599     return E_NOTIMPL;
600 }
601
602 static const IHlinkFrameVtbl HlinkFrameVtbl = {
603     HlinkFrame_QueryInterface,
604     HlinkFrame_AddRef,
605     HlinkFrame_Release,
606     HlinkFrame_SetBrowseContext,
607     HlinkFrame_GetBrowseContext,
608     HlinkFrame_Navigate,
609     HlinkFrame_OnNavigate,
610     HlinkFrame_UpdateHlink
611 };
612
613 static IHlinkFrame HlinkFrame = { &HlinkFrameVtbl };
614
615 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
616         REFIID riid, void**ppv)
617 {
618     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
619         *ppv = iface;
620         return S_OK;
621     }
622
623     ok(0, "unexpected call\n");
624     return E_NOINTERFACE;
625 }
626
627 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
628 {
629     return 2;
630 }
631
632 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
633 {
634     return 1;
635 }
636
637 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
638 {
639     switch(dispID) {
640     case DISPID_READYSTATE:
641         CHECK_EXPECT2(OnChanged_READYSTATE);
642         test_MSHTML_QueryStatus(NULL, OLECMDF_SUPPORTED
643             | (editmode && (load_state == LD_INTERACTIVE || load_state == LD_COMPLETE)
644                ? OLECMDF_ENABLED : 0));
645
646         if(readystate_set_loading) {
647             readystate_set_loading = FALSE;
648             load_state = LD_LOADING;
649         }
650         test_readyState(NULL);
651         return S_OK;
652     case 1005:
653         CHECK_EXPECT(OnChanged_1005);
654         test_readyState(NULL);
655         load_state = LD_INTERACTIVE;
656         return S_OK;
657     }
658
659     ok(0, "unexpected id %d\n", dispID);
660     return E_NOTIMPL;
661 }
662
663 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
664 {
665     ok(0, "unexpected call\n");
666     return E_NOTIMPL;
667 }
668
669 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
670     PropertyNotifySink_QueryInterface,
671     PropertyNotifySink_AddRef,
672     PropertyNotifySink_Release,
673     PropertyNotifySink_OnChanged,
674     PropertyNotifySink_OnRequestEdit
675 };
676
677 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
678
679 static HRESULT WINAPI Stream_QueryInterface(IStream *iface, REFIID riid, void **ppv)
680 {
681     ok(0, "unexpected call\n");
682     return E_NOINTERFACE;
683 }
684
685 static ULONG WINAPI Stream_AddRef(IStream *iface)
686 {
687     return 2;
688 }
689
690 static ULONG WINAPI Stream_Release(IStream *iface)
691 {
692     return 1;
693 }
694
695 static HRESULT WINAPI Stream_Read(IStream *iface, void *pv,
696                                   ULONG cb, ULONG *pcbRead)
697 {
698     CHECK_EXPECT2(Read);
699     ok(pv != NULL, "pv == NULL\n");
700     ok(cb > sizeof(html_page), "cb = %d\n", cb);
701     ok(pcbRead != NULL, "pcbRead == NULL\n");
702     ok(!*pcbRead, "*pcbRead = %d\n", *pcbRead);
703
704     if(stream_read)
705         return S_FALSE;
706
707     memcpy(pv, html_page, sizeof(html_page)-1);
708     stream_read += *pcbRead = sizeof(html_page)-1;
709     return S_OK;
710 }
711
712 static HRESULT WINAPI Stream_Write(IStream *iface, const void *pv,
713                                           ULONG cb, ULONG *pcbWritten)
714 {
715     ok(0, "unexpected call\n");
716     return E_NOTIMPL;
717 }
718
719 static HRESULT WINAPI Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove,
720                                          DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
721 {
722     ok(0, "unexpected call\n");
723     return E_NOTIMPL;
724 }
725
726 static HRESULT WINAPI Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize)
727 {
728     ok(0, "unexpected call\n");
729     return E_NOTIMPL;
730 }
731
732 static HRESULT WINAPI Stream_CopyTo(IStream *iface, IStream *pstm,
733         ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
734 {
735     ok(0, "unexpected call\n");
736     return E_NOTIMPL;
737 }
738
739 static HRESULT WINAPI Stream_Commit(IStream *iface, DWORD grfCommitFlags)
740 {
741     ok(0, "unexpected call\n");
742     return E_NOTIMPL;
743 }
744
745 static HRESULT WINAPI Stream_Revert(IStream *iface)
746 {
747     ok(0, "unexpected call\n");
748     return E_NOTIMPL;
749 }
750
751 static HRESULT WINAPI Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset,
752                                                ULARGE_INTEGER cb, DWORD dwLockType)
753 {
754     ok(0, "unexpected call\n");
755     return E_NOTIMPL;
756 }
757
758 static HRESULT WINAPI Stream_UnlockRegion(IStream *iface,
759         ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
760 {
761     ok(0, "unexpected call\n");
762     return E_NOTIMPL;
763 }
764
765 static HRESULT WINAPI Stream_Stat(IStream *iface, STATSTG *pstatstg,
766                                          DWORD dwStatFlag)
767 {
768     ok(0, "unexpected call\n");
769     return E_NOTIMPL;
770 }
771
772 static HRESULT WINAPI Stream_Clone(IStream *iface, IStream **ppstm)
773 {
774     ok(0, "unexpected call\n");
775     return E_NOTIMPL;
776 }
777
778 static const IStreamVtbl StreamVtbl = {
779     Stream_QueryInterface,
780     Stream_AddRef,
781     Stream_Release,
782     Stream_Read,
783     Stream_Write,
784     Stream_Seek,
785     Stream_SetSize,
786     Stream_CopyTo,
787     Stream_Commit,
788     Stream_Revert,
789     Stream_LockRegion,
790     Stream_UnlockRegion,
791     Stream_Stat,
792     Stream_Clone
793 };
794
795 static IStream Stream = { &StreamVtbl };
796
797 static HRESULT WINAPI Binding_QueryInterface(IBinding *iface, REFIID riid, void **ppv)
798 {
799     if(IsEqualGUID(&IID_IWinInetHttpInfo, riid))
800         return E_NOINTERFACE; /* TODO */
801
802     if(IsEqualGUID(&IID_IWinInetInfo, riid))
803         return E_NOINTERFACE; /* TODO */
804
805     ok(0, "unexpected call\n");
806     return E_NOINTERFACE;
807 }
808
809 static ULONG WINAPI Binding_AddRef(IBinding *iface)
810 {
811     return 2;
812 }
813
814 static ULONG WINAPI Binding_Release(IBinding *iface)
815 {
816     return 1;
817 }
818
819 static HRESULT WINAPI Binding_Abort(IBinding *iface)
820 {
821     CHECK_EXPECT(Abort);
822     return S_OK;
823 }
824
825 static HRESULT WINAPI Binding_Suspend(IBinding *iface)
826 {
827     ok(0, "unexpected call\n");
828     return E_NOTIMPL;
829 }
830
831 static HRESULT WINAPI Binding_Resume(IBinding *iface)
832 {
833     ok(0, "unexpected call\n");
834     return E_NOTIMPL;
835 }
836
837 static HRESULT WINAPI Binding_SetPriority(IBinding *iface, LONG nPriority)
838 {
839     ok(0, "unexpected call\n");
840     return E_NOTIMPL;
841 }
842
843 static HRESULT WINAPI Binding_GetPriority(IBinding *iface, LONG *pnPriority)
844 {
845     ok(0, "unexpected call\n");
846     return E_NOTIMPL;
847 }
848
849 static HRESULT WINAPI Binding_GetBindResult(IBinding *iface, CLSID *pclsidProtocol,
850         DWORD *pdwResult, LPOLESTR *pszResult, DWORD *pdwReserved)
851 {
852     CHECK_EXPECT(GetBindResult);
853     return E_NOTIMPL;
854 }
855
856 static const IBindingVtbl BindingVtbl = {
857     Binding_QueryInterface,
858     Binding_AddRef,
859     Binding_Release,
860     Binding_Abort,
861     Binding_Suspend,
862     Binding_Resume,
863     Binding_SetPriority,
864     Binding_GetPriority,
865     Binding_GetBindResult
866 };
867
868 static IBinding Binding = { &BindingVtbl };
869
870 DEFINE_GUID(IID_IMoniker_unk,0xA158A630,0xED6F,0x45FB,0xB9,0x87,0xF6,0x86,0x76,0xF5,0x77,0x52);
871 DEFINE_GUID(IID_IMoniker_unk2, 0x79EAC9D3,0xBAF9,0x11CE,0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B);
872
873 static HRESULT WINAPI Moniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
874 {
875     *ppv = NULL;
876
877     if(IsEqualGUID(&IID_IMoniker_unk, riid))
878         return E_NOINTERFACE; /* TODO */
879     if(IsEqualGUID(&IID_IMoniker_unk2, riid))
880         return E_NOINTERFACE; /* TODO */
881
882     ok(0, "unexpected riid: %s\n", debugstr_guid(riid));
883     return E_NOINTERFACE;
884 }
885
886 static ULONG WINAPI Moniker_AddRef(IMoniker *iface)
887 {
888     return 2;
889 }
890
891 static ULONG WINAPI Moniker_Release(IMoniker *iface)
892 {
893     return 1;
894 }
895
896 static HRESULT WINAPI Moniker_GetClassID(IMoniker *iface, CLSID *pClassID)
897 {
898     CHECK_EXPECT(GetClassID);
899     ok(IsEqualGUID(pClassID, &IID_NULL), "pClassID = %s\n", debugstr_guid(pClassID));
900     return E_FAIL;
901 }
902
903 static HRESULT WINAPI Moniker_IsDirty(IMoniker *iface)
904 {
905     ok(0, "unexpected call\n");
906     return E_NOTIMPL;
907 }
908
909 static HRESULT WINAPI Moniker_Load(IMoniker *iface, IStream *pStm)
910 {
911     ok(0, "unexpected call\n");
912     return E_NOTIMPL;
913 }
914
915 static HRESULT WINAPI Moniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
916 {
917     ok(0, "unexpected call\n");
918     return E_NOTIMPL;
919 }
920
921 static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
922 {
923     ok(0, "unexpected call\n");
924     return E_NOTIMPL;
925 }
926
927 static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pcb, IMoniker *pmkToLeft,
928         REFIID riidResult, void **ppvResult)
929 {
930     ok(0, "unexpected call\n");
931     return E_NOTIMPL;
932 }
933
934 static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
935         REFIID riid, void **ppv)
936 {
937     IBindStatusCallback *callback = NULL;
938     FORMATETC formatetc = {0xc02d, NULL, 1, -1, TYMED_ISTREAM};
939     STGMEDIUM stgmedium;
940     BINDINFO bindinfo;
941     DWORD bindf;
942     HRESULT hres;
943
944     static OLECHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
945     static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};
946
947     CHECK_EXPECT(BindToStorage);
948
949     load_state = LD_LOADING;
950
951     ok(pbc != NULL, "pbc == NULL\n");
952     ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
953     ok(IsEqualGUID(&IID_IStream, riid), "unexpected riid\n");
954     ok(ppv != NULL, "ppv == NULL\n");
955     ok(*ppv == NULL, "*ppv=%p\n", *ppv);
956
957     hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown**)&callback);
958     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
959     ok(callback != NULL, "callback == NULL\n");
960
961     memset(&bindinfo, 0xf0, sizeof(bindinfo));
962     bindinfo.cbSize = sizeof(bindinfo);
963
964     hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo);
965     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
966     ok(bindf == (BINDF_PULLDATA|BINDF_ASYNCSTORAGE|BINDF_ASYNCHRONOUS), "bindf = %08x\n", bindf);
967     ok(bindinfo.cbSize == sizeof(bindinfo), "bindinfo.cbSize=%d\n", bindinfo.cbSize);
968     ok(bindinfo.szExtraInfo == NULL, "bindinfo.szExtraInfo=%p\n", bindinfo.szExtraInfo);
969     /* TODO: test stgmedData */
970     ok(bindinfo.grfBindInfoF == 0, "bindinfo.grfBinfInfoF=%08x\n", bindinfo.grfBindInfoF);
971     ok(bindinfo.dwBindVerb == 0, "bindinfo.dwBindVerb=%d\n", bindinfo.dwBindVerb);
972     ok(bindinfo.szCustomVerb == 0, "bindinfo.szCustomVerb=%p\n", bindinfo.szCustomVerb);
973     ok(bindinfo.cbstgmedData == 0, "bindinfo.cbstgmedData=%d\n", bindinfo.cbstgmedData);
974     ok(bindinfo.dwOptions == 0x80000 || bindinfo.dwOptions == 0x4080000,
975        "bindinfo.dwOptions=%x\n", bindinfo.dwOptions);
976     ok(bindinfo.dwOptionsFlags == 0, "bindinfo.dwOptionsFlags=%d\n", bindinfo.dwOptionsFlags);
977     /* TODO: test dwCodePage */
978     /* TODO: test securityAttributes */
979     ok(IsEqualGUID(&IID_NULL, &bindinfo.iid), "unexpected bindinfo.iid\n");
980     ok(bindinfo.pUnk == NULL, "bindinfo.pUnk=%p\n", bindinfo.pUnk);
981     ok(bindinfo.dwReserved == 0, "bindinfo.dwReserved=%d\n", bindinfo.dwReserved);
982
983     hres = IBindStatusCallback_OnStartBinding(callback, 0, &Binding);
984     ok(hres == S_OK, "OnStartBinding failed: %08x\n", hres);
985
986     hres = IBindStatusCallback_OnProgress(callback, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE,
987                                           wszTextHtml);
988     ok(hres == S_OK, "OnProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
989
990     hres = IBindStatusCallback_OnProgress(callback, sizeof(html_page)-1, sizeof(html_page)-1,
991                                           BINDSTATUS_BEGINDOWNLOADDATA, doc_url);
992     ok(hres == S_OK, "OnProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
993
994     SET_EXPECT(Read);
995     stgmedium.tymed = TYMED_ISTREAM;
996     U(stgmedium).pstm = &Stream;
997     stgmedium.pUnkForRelease = (IUnknown*)iface;
998     hres = IBindStatusCallback_OnDataAvailable(callback,
999             BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION,
1000             sizeof(html_page)-1, &formatetc, &stgmedium);
1001     ok(hres == S_OK, "OnDataAvailable failed: %08x\n", hres);
1002     CHECK_CALLED(Read);
1003
1004     hres = IBindStatusCallback_OnProgress(callback, sizeof(html_page)-1, sizeof(html_page)-1,
1005             BINDSTATUS_ENDDOWNLOADDATA, NULL);
1006     ok(hres == S_OK, "OnProgress(BINDSTATUS_ENDDOWNLOADDATA) failed: %08x\n", hres);
1007
1008     hres = IBindStatusCallback_OnStopBinding(callback, S_OK, NULL);
1009     ok(hres == S_OK, "OnStopBinding failed: %08x\n", hres);
1010
1011     IBindStatusCallback_Release(callback);
1012
1013     return S_OK;
1014 }
1015
1016 static HRESULT WINAPI Moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar,
1017         IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
1018 {
1019     ok(0, "unexpected call\n");
1020     return E_NOTIMPL;
1021 }
1022
1023 static HRESULT WINAPI Moniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight,
1024         BOOL fOnlyIfNotGeneric, IMoniker **ppnkComposite)
1025 {
1026     ok(0, "unexpected call\n");
1027     return E_NOTIMPL;
1028 }
1029
1030 static HRESULT WINAPI Moniker_Enum(IMoniker *iface, BOOL fForwrd, IEnumMoniker **ppenumMoniker)
1031 {
1032     ok(0, "unexpected call\n");
1033     return E_NOTIMPL;
1034 }
1035
1036 static HRESULT WINAPI Moniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
1037 {
1038     ok(0, "unexpected call\n");
1039     return E_NOTIMPL;
1040 }
1041
1042 static HRESULT WINAPI Moniker_Hash(IMoniker *iface, DWORD *pdwHash)
1043 {
1044     ok(0, "unexpected call\n");
1045     return E_NOTIMPL;
1046 }
1047
1048 static HRESULT WINAPI Moniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
1049         IMoniker *pmkNewlyRunning)
1050 {
1051     ok(0, "unexpected call\n");
1052     return E_NOTIMPL;
1053 }
1054
1055 static HRESULT WINAPI Moniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc,
1056         IMoniker *pmkToLeft, FILETIME *pFileTime)
1057 {
1058     ok(0, "unexpected call\n");
1059     return E_NOTIMPL;
1060 }
1061
1062 static HRESULT WINAPI Moniker_Inverse(IMoniker *iface, IMoniker **ppmk)
1063 {
1064     ok(0, "unexpected call\n");
1065     return E_NOTIMPL;
1066 }
1067
1068 static HRESULT WINAPI Moniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOther,
1069         IMoniker **ppmkPrefix)
1070 {
1071     ok(0, "unexpected call\n");
1072     return E_NOTIMPL;
1073 }
1074
1075 static HRESULT WINAPI Moniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther,
1076         IMoniker **pmkRelPath)
1077 {
1078     ok(0, "unexpected call\n");
1079     return E_NOTIMPL;
1080 }
1081
1082 static HRESULT WINAPI Moniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
1083         IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
1084 {
1085     CHECK_EXPECT2(GetDisplayName);
1086
1087     /* ok(pbc != NULL, "pbc == NULL\n"); */
1088     ok(pmkToLeft == NULL, "pmkToLeft=%p\n", pmkToLeft);
1089     ok(ppszDisplayName != NULL, "ppszDisplayName == NULL\n");
1090
1091     *ppszDisplayName = CoTaskMemAlloc(sizeof(doc_url));
1092     memcpy(*ppszDisplayName, doc_url, sizeof(doc_url));
1093
1094     return S_OK;
1095 }
1096
1097 static HRESULT WINAPI Moniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc,
1098         IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
1099 {
1100     ok(0, "unexpected call\n");
1101     return E_NOTIMPL;
1102 }
1103
1104 static HRESULT WINAPI Moniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
1105 {
1106     CHECK_EXPECT(IsSystemMoniker);
1107     return E_NOTIMPL;
1108 }
1109
1110 static const IMonikerVtbl MonikerVtbl = {
1111     Moniker_QueryInterface,
1112     Moniker_AddRef,
1113     Moniker_Release,
1114     Moniker_GetClassID,
1115     Moniker_IsDirty,
1116     Moniker_Load,
1117     Moniker_Save,
1118     Moniker_GetSizeMax,
1119     Moniker_BindToObject,
1120     Moniker_BindToStorage,
1121     Moniker_Reduce,
1122     Moniker_ComposeWith,
1123     Moniker_Enum,
1124     Moniker_IsEqual,
1125     Moniker_Hash,
1126     Moniker_IsRunning,
1127     Moniker_GetTimeOfLastChange,
1128     Moniker_Inverse,
1129     Moniker_CommonPrefixWith,
1130     Moniker_RelativePathTo,
1131     Moniker_GetDisplayName,
1132     Moniker_ParseDisplayName,
1133     Moniker_IsSystemMoniker
1134 };
1135
1136 static IMoniker Moniker = { &MonikerVtbl };
1137
1138 static HRESULT WINAPI OleContainer_QueryInterface(IOleContainer *iface, REFIID riid, void **ppv)
1139 {
1140     return QueryInterface(riid, ppv);
1141 }
1142
1143 static ULONG WINAPI OleContainer_AddRef(IOleContainer *iface)
1144 {
1145     return 2;
1146 }
1147
1148 static ULONG WINAPI OleContainer_Release(IOleContainer *iface)
1149 {
1150     return 1;
1151 }
1152
1153 static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer *iface, IBindCtx *pbc,
1154         LPOLESTR pszDiaplayName, ULONG *pchEaten, IMoniker **ppmkOut)
1155 {
1156     ok(0, "unexpected call\n");
1157     return E_NOTIMPL;
1158 }
1159
1160 static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer *iface, DWORD grfFlags,
1161         IEnumUnknown **ppenum)
1162 {
1163     ok(0, "unexpected call\n");
1164     return E_NOTIMPL;
1165 }
1166
1167 static HRESULT WINAPI OleContainer_LockContainer(IOleContainer *iface, BOOL fLock)
1168 {
1169     CHECK_EXPECT(LockContainer);
1170     ok(expect_LockContainer_fLock == fLock, "fLock=%x, expected %x\n", fLock, expect_LockContainer_fLock);
1171     return S_OK;
1172 }
1173
1174 static const IOleContainerVtbl OleContainerVtbl = {
1175     OleContainer_QueryInterface,
1176     OleContainer_AddRef,
1177     OleContainer_Release,
1178     OleContainer_ParseDisplayName,
1179     OleContainer_EnumObjects,
1180     OleContainer_LockContainer
1181 };
1182
1183 static IOleContainer OleContainer = { &OleContainerVtbl };
1184
1185 static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
1186 {
1187     ok(0, "unexpected call\n");
1188     return E_NOINTERFACE;
1189 }
1190
1191 static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
1192 {
1193     return 2;
1194 }
1195
1196 static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
1197 {
1198     return 1;
1199 }
1200
1201 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
1202 {
1203     ok(0, "unexpected call\n");
1204     return E_NOTIMPL;
1205 }
1206
1207 static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
1208 {
1209     ok(0, "unexpected call\n");
1210     return E_NOTIMPL;
1211 }
1212
1213 static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
1214 {
1215     ok(0, "unexpected call\n");
1216     return E_NOTIMPL;
1217 }
1218
1219 static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
1220         LPCBORDERWIDTHS pborderwidths)
1221 {
1222     ok(0, "unexpected call\n");
1223     return E_NOTIMPL;
1224 }
1225
1226 static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
1227         LPCBORDERWIDTHS pborderwidths)
1228 {
1229     CHECK_EXPECT(InPlaceFrame_SetBorderSpace);
1230     return S_OK;
1231 }
1232
1233 static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceFrame *iface,
1234         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
1235 {
1236     static const WCHAR wszHTML_Document[] =
1237         {'H','T','M','L',' ','D','o','c','u','m','e','n','t',0};
1238
1239     CHECK_EXPECT2(InPlaceUIWindow_SetActiveObject);
1240
1241     if(expect_InPlaceUIWindow_SetActiveObject_active) {
1242         ok(pActiveObject != NULL, "pActiveObject = NULL\n");
1243         if(pActiveObject && PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_ENGLISH)
1244             ok(!lstrcmpW(wszHTML_Document, pszObjName), "pszObjName != \"HTML Document\"\n");
1245     }
1246     else {
1247         ok(pActiveObject == NULL, "pActiveObject=%p, expected NULL\n", pActiveObject);
1248         ok(pszObjName == NULL, "pszObjName=%p, expected NULL\n", pszObjName);
1249     }
1250     expect_InPlaceUIWindow_SetActiveObject_active = !expect_InPlaceUIWindow_SetActiveObject_active;
1251     return S_OK;
1252 }
1253
1254 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
1255         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
1256 {
1257     static const WCHAR wszHTML_Document[] =
1258         {'H','T','M','L',' ','D','o','c','u','m','e','n','t',0};
1259
1260     if(pActiveObject) {
1261         CHECK_EXPECT2(SetActiveObject);
1262
1263         if(pActiveObject && PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_ENGLISH)
1264             ok(!lstrcmpW(wszHTML_Document, pszObjName), "pszObjName != \"HTML Document\"\n");
1265     }else {
1266         CHECK_EXPECT(SetActiveObject_null);
1267
1268         ok(pActiveObject == NULL, "pActiveObject=%p, expected NULL\n", pActiveObject);
1269         ok(pszObjName == NULL, "pszObjName=%p, expected NULL\n", pszObjName);
1270     }
1271
1272     return S_OK;
1273 }
1274
1275 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
1276         LPOLEMENUGROUPWIDTHS lpMenuWidths)
1277 {
1278     ok(0, "unexpected call\n");
1279     return E_NOTIMPL;
1280 }
1281
1282 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
1283         HOLEMENU holemenu, HWND hwndActiveObject)
1284 {
1285     ok(0, "unexpected call\n");
1286     return E_NOTIMPL;
1287 }
1288
1289 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
1290 {
1291     ok(0, "unexpected call\n");
1292     return E_NOTIMPL;
1293 }
1294
1295 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
1296 {
1297     CHECK_EXPECT2(SetStatusText);
1298     if(!expect_status_text)
1299         ok(pszStatusText == NULL, "pszStatusText=%p, expected NULL\n", pszStatusText);
1300     return S_OK;
1301 }
1302
1303 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
1304 {
1305     ok(0, "unexpected call\n");
1306     return E_NOTIMPL;
1307 }
1308
1309 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
1310 {
1311     ok(0, "unexpected call\n");
1312     return E_NOTIMPL;
1313 }
1314
1315 static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
1316     InPlaceFrame_QueryInterface,
1317     InPlaceFrame_AddRef,
1318     InPlaceFrame_Release,
1319     InPlaceFrame_GetWindow,
1320     InPlaceFrame_ContextSensitiveHelp,
1321     InPlaceFrame_GetBorder,
1322     InPlaceFrame_RequestBorderSpace,
1323     InPlaceFrame_SetBorderSpace,
1324     InPlaceFrame_SetActiveObject,
1325     InPlaceFrame_InsertMenus,
1326     InPlaceFrame_SetMenu,
1327     InPlaceFrame_RemoveMenus,
1328     InPlaceFrame_SetStatusText,
1329     InPlaceFrame_EnableModeless,
1330     InPlaceFrame_TranslateAccelerator
1331 };
1332
1333 static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
1334
1335 static const IOleInPlaceFrameVtbl InPlaceUIWindowVtbl = {
1336     InPlaceFrame_QueryInterface,
1337     InPlaceFrame_AddRef,
1338     InPlaceFrame_Release,
1339     InPlaceFrame_GetWindow,
1340     InPlaceFrame_ContextSensitiveHelp,
1341     InPlaceFrame_GetBorder,
1342     InPlaceFrame_RequestBorderSpace,
1343     InPlaceFrame_SetBorderSpace,
1344     InPlaceUIWindow_SetActiveObject,
1345 };
1346
1347 static IOleInPlaceFrame InPlaceUIWindow = { &InPlaceUIWindowVtbl };
1348
1349 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSiteEx *iface, REFIID riid, void **ppv)
1350 {
1351     return QueryInterface(riid, ppv);
1352 }
1353
1354 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSiteEx *iface)
1355 {
1356     return 2;
1357 }
1358
1359 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSiteEx *iface)
1360 {
1361     return 1;
1362 }
1363
1364 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwnd)
1365 {
1366     CHECK_EXPECT(GetWindow);
1367     ok(phwnd != NULL, "phwnd = NULL\n");
1368     *phwnd = container_hwnd;
1369     return S_OK;
1370 }
1371
1372 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx *iface, BOOL fEnterMode)
1373 {
1374     ok(0, "unexpected call\n");
1375     return E_NOTIMPL;
1376 }
1377
1378 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx *iface)
1379 {
1380     CHECK_EXPECT(CanInPlaceActivate);
1381     return S_OK;
1382 }
1383
1384 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx *iface)
1385 {
1386     CHECK_EXPECT(OnInPlaceActivate);
1387     return S_OK;
1388 }
1389
1390 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSiteEx *iface)
1391 {
1392     CHECK_EXPECT(OnUIActivate);
1393     return S_OK;
1394 }
1395
1396 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface,
1397         IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1398         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1399 {
1400     static const RECT rect = {0,0,500,500};
1401
1402     CHECK_EXPECT(GetWindowContext);
1403
1404     ok(ppFrame != NULL, "ppFrame = NULL\n");
1405     if(ppFrame)
1406         *ppFrame = &InPlaceFrame;
1407     ok(ppDoc != NULL, "ppDoc = NULL\n");
1408     if(ppDoc)
1409         *ppDoc = (IOleInPlaceUIWindow*)&InPlaceUIWindow;
1410     ok(lprcPosRect != NULL, "lprcPosRect = NULL\n");
1411     if(lprcPosRect)
1412         memcpy(lprcPosRect, &rect, sizeof(RECT));
1413     ok(lprcClipRect != NULL, "lprcClipRect = NULL\n");
1414     if(lprcClipRect)
1415         memcpy(lprcClipRect, &rect, sizeof(RECT));
1416     ok(lpFrameInfo != NULL, "lpFrameInfo = NULL\n");
1417     if(lpFrameInfo) {
1418         lpFrameInfo->cb = sizeof(*lpFrameInfo);
1419         lpFrameInfo->fMDIApp = FALSE;
1420         lpFrameInfo->hwndFrame = container_hwnd;
1421         lpFrameInfo->haccel = NULL;
1422         lpFrameInfo->cAccelEntries = 0;
1423     }
1424
1425     return S_OK;
1426 }
1427
1428 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSiteEx *iface, SIZE scrollExtant)
1429 {
1430     ok(0, "unexpected call\n");
1431     return E_NOTIMPL;
1432 }
1433
1434 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx *iface, BOOL fUndoable)
1435 {
1436     CHECK_EXPECT(OnUIDeactivate);
1437     ok(!fUndoable, "fUndoable = TRUE\n");
1438     return S_OK;
1439 }
1440
1441 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx *iface)
1442 {
1443     CHECK_EXPECT(OnInPlaceDeactivate);
1444     return S_OK;
1445 }
1446
1447 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSiteEx *iface)
1448 {
1449     ok(0, "unexpected call\n");
1450     return E_NOTIMPL;
1451 }
1452
1453 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx *iface)
1454 {
1455     ok(0, "unexpected call\n");
1456     return E_NOTIMPL;
1457 }
1458
1459 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSiteEx *iface, LPCRECT lprcPosRect)
1460 {
1461     ok(0, "unexpected call\n");
1462     return E_NOTIMPL;
1463 }
1464
1465 static HRESULT WINAPI InPlaceSiteEx_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface, BOOL *pfNoRedraw, DWORD dwFlags)
1466 {
1467     CHECK_EXPECT(OnInPlaceActivateEx);
1468
1469     ok(pfNoRedraw != NULL, "pfNoRedraw == NULL\n");
1470     ok(!*pfNoRedraw, "*pfNoRedraw == TRUE\n");
1471     ok(dwFlags == 0, "dwFlags = %08x\n", dwFlags);
1472
1473     return S_OK;
1474 }
1475
1476 static HRESULT WINAPI InPlaceSiteEx_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *iface, BOOL fNoRedraw)
1477 {
1478     CHECK_EXPECT(OnInPlaceDeactivateEx);
1479
1480     ok(fNoRedraw, "fNoRedraw == FALSE\n");
1481
1482     return S_OK;
1483 }
1484
1485 static HRESULT WINAPI InPlaceSiteEx_RequestUIActivate(IOleInPlaceSiteEx *iface)
1486 {
1487     CHECK_EXPECT(RequestUIActivate);
1488     return S_OK;
1489 }
1490
1491 static const IOleInPlaceSiteExVtbl InPlaceSiteVtbl = {
1492     InPlaceSite_QueryInterface,
1493     InPlaceSite_AddRef,
1494     InPlaceSite_Release,
1495     InPlaceSite_GetWindow,
1496     InPlaceSite_ContextSensitiveHelp,
1497     InPlaceSite_CanInPlaceActivate,
1498     InPlaceSite_OnInPlaceActivate,
1499     InPlaceSite_OnUIActivate,
1500     InPlaceSite_GetWindowContext,
1501     InPlaceSite_Scroll,
1502     InPlaceSite_OnUIDeactivate,
1503     InPlaceSite_OnInPlaceDeactivate,
1504     InPlaceSite_DiscardUndoState,
1505     InPlaceSite_DeactivateAndUndo,
1506     InPlaceSite_OnPosRectChange,
1507     InPlaceSiteEx_OnInPlaceActivateEx,
1508     InPlaceSiteEx_OnInPlaceDeactivateEx,
1509     InPlaceSiteEx_RequestUIActivate
1510 };
1511
1512 static IOleInPlaceSiteEx InPlaceSiteEx = { &InPlaceSiteVtbl };
1513
1514 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
1515 {
1516     return QueryInterface(riid, ppv);
1517 }
1518
1519 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
1520 {
1521     return 2;
1522 }
1523
1524 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
1525 {
1526     return 1;
1527 }
1528
1529 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
1530 {
1531     ok(0, "unexpected call\n");
1532     return E_NOTIMPL;
1533 }
1534
1535 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker,
1536         IMoniker **ppmon)
1537 {
1538     ok(0, "unexpected call\n");
1539     return E_NOTIMPL;
1540 }
1541
1542 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
1543 {
1544     CHECK_EXPECT(GetContainer);
1545     ok(ppContainer != NULL, "ppContainer = NULL\n");
1546     *ppContainer = &OleContainer;
1547     return S_OK;
1548 }
1549
1550 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
1551 {
1552     ok(0, "unexpected call\n");
1553     return E_NOTIMPL;
1554 }
1555
1556 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
1557 {
1558     ok(0, "unexpected call\n");
1559     return E_NOTIMPL;
1560 }
1561
1562 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
1563 {
1564     ok(0, "unexpected call\n");
1565     return E_NOTIMPL;
1566 }
1567
1568 static const IOleClientSiteVtbl ClientSiteVtbl = {
1569     ClientSite_QueryInterface,
1570     ClientSite_AddRef,
1571     ClientSite_Release,
1572     ClientSite_SaveObject,
1573     ClientSite_GetMoniker,
1574     ClientSite_GetContainer,
1575     ClientSite_ShowObject,
1576     ClientSite_OnShowWindow,
1577     ClientSite_RequestNewObjectLayout
1578 };
1579
1580 static IOleClientSite ClientSite = { &ClientSiteVtbl };
1581
1582 static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv)
1583 {
1584     return QueryInterface(riid, ppv);
1585 }
1586
1587 static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface)
1588 {
1589     return 2;
1590 }
1591
1592 static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface)
1593 {
1594     return 1;
1595 }
1596
1597 typedef enum
1598 {
1599     CallUIActivate_None,
1600     CallUIActivate_ActivateMe,
1601     CallUIActivate_AfterShow,
1602 } CallUIActivate;
1603
1604 static BOOL call_UIActivate = CallUIActivate_ActivateMe;
1605 static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate)
1606 {
1607     IOleDocument *document;
1608     HRESULT hres;
1609
1610     CHECK_EXPECT(ActivateMe);
1611     ok(pViewToActivate != NULL, "pViewToActivate = NULL\n");
1612
1613     hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document);
1614     ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
1615
1616     if(SUCCEEDED(hres)) {
1617         hres = IOleDocument_CreateView(document, (IOleInPlaceSite*)&InPlaceSiteEx, NULL, 0, &view);
1618         ok(hres == S_OK, "CreateView failed: %08x\n", hres);
1619
1620         if(SUCCEEDED(hres)) {
1621             IOleInPlaceActiveObject *activeobj = NULL;
1622             IOleInPlaceSite *inplacesite = NULL;
1623             HWND tmp_hwnd = NULL;
1624             static RECT rect = {0,0,400,500};
1625
1626             hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
1627             ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres);
1628             ok(inplacesite == (IOleInPlaceSite*)&InPlaceSiteEx, "inplacesite=%p, expected %p\n",
1629                     inplacesite, &InPlaceSiteEx);
1630
1631             hres = IOleDocumentView_SetInPlaceSite(view, (IOleInPlaceSite*)&InPlaceSiteEx);
1632             ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
1633
1634             hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
1635             ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres);
1636             ok(inplacesite == (IOleInPlaceSite*)&InPlaceSiteEx, "inplacesite=%p, expected %p\n",
1637                     inplacesite, &InPlaceSiteEx);
1638
1639             hres = IOleDocumentView_QueryInterface(view, &IID_IOleInPlaceActiveObject, (void**)&activeobj);
1640             ok(hres == S_OK, "Could not get IOleInPlaceActiveObject: %08x\n", hres);
1641
1642             if(activeobj) {
1643                 IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd);
1644                 ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
1645                 ok(hwnd == NULL, "hwnd=%p, expeted NULL\n", hwnd);
1646             }
1647             
1648             if(call_UIActivate == CallUIActivate_ActivateMe) {
1649                 SET_EXPECT(CanInPlaceActivate);
1650                 SET_EXPECT(GetWindowContext);
1651                 SET_EXPECT(GetWindow);
1652                 if(ipsex)
1653                     SET_EXPECT(OnInPlaceActivateEx);
1654                 else
1655                     SET_EXPECT(OnInPlaceActivate);
1656                 SET_EXPECT(SetStatusText);
1657                 SET_EXPECT(Exec_SETPROGRESSMAX);
1658                 SET_EXPECT(Exec_SETPROGRESSPOS);
1659                 SET_EXPECT(OnUIActivate);
1660                 SET_EXPECT(SetActiveObject);
1661                 SET_EXPECT(ShowUI);
1662                 expect_status_text = NULL;
1663
1664                 hres = IOleDocumentView_UIActivate(view, TRUE);
1665
1666                 if(FAILED(hres)) {
1667                     skip("UIActivate failed: %08x\n", hres);
1668                     return hres;
1669                 }
1670                 ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
1671
1672                 CHECK_CALLED(CanInPlaceActivate);
1673                 CHECK_CALLED(GetWindowContext);
1674                 CHECK_CALLED(GetWindow);
1675                 if(ipsex)
1676                     CHECK_CALLED(OnInPlaceActivateEx);
1677                 else
1678                     CHECK_CALLED(OnInPlaceActivate);
1679                 CHECK_CALLED(SetStatusText);
1680                 CHECK_CALLED(Exec_SETPROGRESSMAX);
1681                 CHECK_CALLED(Exec_SETPROGRESSPOS);
1682                 CHECK_CALLED(OnUIActivate);
1683                 CHECK_CALLED(SetActiveObject);
1684                 CHECK_CALLED(ShowUI);
1685
1686                 if(activeobj) {
1687                     hres = IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd);
1688                     ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
1689                     ok(hwnd != NULL, "hwnd == NULL\n");
1690                     if(last_hwnd)
1691                         ok(hwnd == last_hwnd, "hwnd != last_hwnd\n");
1692                 }
1693
1694                 hres = IOleDocumentView_UIActivate(view, TRUE);
1695                 ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
1696
1697                 if(activeobj) {
1698                     hres = IOleInPlaceActiveObject_GetWindow(activeobj, &tmp_hwnd);
1699                     ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
1700                     ok(tmp_hwnd == hwnd, "tmp_hwnd=%p, expected %p\n", tmp_hwnd, hwnd);
1701                 }
1702             }
1703
1704             hres = IOleDocumentView_SetRect(view, &rect);
1705             ok(hres == S_OK, "SetRect failed: %08x\n", hres);
1706
1707             if(call_UIActivate == CallUIActivate_ActivateMe) {
1708                 hres = IOleDocumentView_Show(view, TRUE);
1709                 ok(hres == S_OK, "Show failed: %08x\n", hres);
1710             }else {
1711                 SET_EXPECT(CanInPlaceActivate);
1712                 SET_EXPECT(GetWindowContext);
1713                 SET_EXPECT(GetWindow);
1714                 if(ipsex)
1715                     SET_EXPECT(OnInPlaceActivateEx);
1716                 else
1717                     SET_EXPECT(OnInPlaceActivate);
1718                 SET_EXPECT(SetStatusText);
1719                 SET_EXPECT(Exec_SETPROGRESSMAX);
1720                 SET_EXPECT(Exec_SETPROGRESSPOS);
1721                 SET_EXPECT(OnUIActivate);
1722                 expect_status_text = (load_state == LD_COMPLETE ? (LPCOLESTR)0xdeadbeef : NULL);
1723
1724                 hres = IOleDocumentView_Show(view, TRUE);
1725                 ok(hres == S_OK, "Show failed: %08x\n", hres);
1726
1727                 CHECK_CALLED(CanInPlaceActivate);
1728                 CHECK_CALLED(GetWindowContext);
1729                 CHECK_CALLED(GetWindow);
1730                 if(ipsex)
1731                     CHECK_CALLED(OnInPlaceActivateEx);
1732                 else
1733                     CHECK_CALLED(OnInPlaceActivate);
1734                 CHECK_CALLED(SetStatusText);
1735                 CHECK_CALLED(Exec_SETPROGRESSMAX);
1736                 CHECK_CALLED(Exec_SETPROGRESSPOS);
1737
1738                 if(activeobj) {
1739                     hres = IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd);
1740                     ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
1741                     ok(hwnd != NULL, "hwnd == NULL\n");
1742                     if(last_hwnd)
1743                         ok(hwnd == last_hwnd, "hwnd != last_hwnd\n");
1744                 }
1745             }
1746
1747             test_timer(EXPECT_UPDATEUI | ((load_state == LD_LOADING) ? EXPECT_SETTITLE : 0));
1748
1749             if(activeobj)
1750                 IOleInPlaceActiveObject_Release(activeobj);
1751         }
1752
1753         IOleDocument_Release(document);
1754     }
1755
1756     return S_OK;
1757 }
1758
1759 static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
1760     DocumentSite_QueryInterface,
1761     DocumentSite_AddRef,
1762     DocumentSite_Release,
1763     DocumentSite_ActivateMe
1764 };
1765
1766 static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
1767
1768 static HRESULT WINAPI OleControlSite_QueryInterface(IOleControlSite *iface, REFIID riid, void **ppv)
1769 {
1770     return QueryInterface(riid, ppv);
1771 }
1772
1773 static ULONG WINAPI OleControlSite_AddRef(IOleControlSite *iface)
1774 {
1775     return 2;
1776 }
1777
1778 static ULONG WINAPI OleControlSite_Release(IOleControlSite *iface)
1779 {
1780     return 1;
1781 }
1782
1783 static HRESULT WINAPI OleControlSite_OnControlInfoChanged(IOleControlSite *iface)
1784 {
1785     ok(0, "unexpected call\n");
1786     return E_NOTIMPL;
1787 }
1788
1789 static HRESULT WINAPI OleControlSite_LockInPlaceActive(IOleControlSite *iface, BOOL fLock)
1790 {
1791     ok(0, "unexpected call\n");
1792     return E_NOTIMPL;
1793 }
1794
1795 static HRESULT WINAPI OleControlSite_GetExtendedControl(IOleControlSite *iface, IDispatch **ppDisp)
1796 {
1797     ok(0, "unexpected call\n");
1798     return E_NOTIMPL;
1799 }
1800
1801 static HRESULT WINAPI OleControlSite_TransformCoords(IOleControlSite *iface, POINTL *pPtHimetric,
1802         POINTF *pPtfContainer, DWORD dwFlags)
1803 {
1804     ok(0, "unexpected call\n");
1805     return E_NOTIMPL;
1806 }
1807
1808 static HRESULT WINAPI OleControlSite_TranslateAccelerator(IOleControlSite *iface,
1809         MSG *pMsg, DWORD grfModifiers)
1810 {
1811     ok(0, "unexpected call\n");
1812     return E_NOTIMPL;
1813 }
1814
1815 static HRESULT WINAPI OleControlSite_OnFocus(IOleControlSite *iface, BOOL fGotFocus)
1816 {
1817     if(fGotFocus)
1818         CHECK_EXPECT(OnFocus_TRUE);
1819     else
1820         CHECK_EXPECT2(OnFocus_FALSE);
1821     return S_OK;
1822 }
1823
1824 static HRESULT WINAPI OleControlSite_ShowPropertyFrame(IOleControlSite *iface)
1825 {
1826     ok(0, "unexpected call\n");
1827     return E_NOTIMPL;
1828 }
1829
1830 static const IOleControlSiteVtbl OleControlSiteVtbl = {
1831     OleControlSite_QueryInterface,
1832     OleControlSite_AddRef,
1833     OleControlSite_Release,
1834     OleControlSite_OnControlInfoChanged,
1835     OleControlSite_LockInPlaceActive,
1836     OleControlSite_GetExtendedControl,
1837     OleControlSite_TransformCoords,
1838     OleControlSite_TranslateAccelerator,
1839     OleControlSite_OnFocus,
1840     OleControlSite_ShowPropertyFrame
1841 };
1842
1843 static IOleControlSite OleControlSite = { &OleControlSiteVtbl };
1844
1845 static HRESULT WINAPI DocHostUIHandler_QueryInterface(IDocHostUIHandler2 *iface, REFIID riid, void **ppv)
1846 {
1847     return QueryInterface(riid, ppv);
1848 }
1849
1850 static ULONG WINAPI DocHostUIHandler_AddRef(IDocHostUIHandler2 *iface)
1851 {
1852     return 2;
1853 }
1854
1855 static ULONG WINAPI DocHostUIHandler_Release(IDocHostUIHandler2 *iface)
1856 {
1857     return 1;
1858 }
1859
1860 static HRESULT WINAPI DocHostUIHandler_ShowContextMenu(IDocHostUIHandler2 *iface, DWORD dwID, POINT *ppt,
1861         IUnknown *pcmdtReserved, IDispatch *pdicpReserved)
1862 {
1863     ok(0, "unexpected call\n");
1864     return E_NOTIMPL;
1865 }
1866
1867 static HRESULT WINAPI DocHostUIHandler_GetHostInfo(IDocHostUIHandler2 *iface, DOCHOSTUIINFO *pInfo)
1868 {
1869     CHECK_EXPECT(GetHostInfo);
1870     ok(pInfo != NULL, "pInfo=NULL\n");
1871     if(pInfo) {
1872         ok(pInfo->cbSize == sizeof(DOCHOSTUIINFO), "pInfo->cbSize=%u\n", pInfo->cbSize);
1873         ok(!pInfo->dwFlags, "pInfo->dwFlags=%08x, expected 0\n", pInfo->dwFlags);
1874         pInfo->dwFlags = DOCHOSTUIFLAG_DISABLE_HELP_MENU | DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE
1875             | DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY | DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION
1876             | DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION;
1877         ok(!pInfo->dwDoubleClick, "pInfo->dwDoubleClick=%08x, expected 0\n", pInfo->dwDoubleClick);
1878         ok(!pInfo->pchHostCss, "pInfo->pchHostCss=%p, expected NULL\n", pInfo->pchHostCss);
1879         ok(!pInfo->pchHostNS, "pInfo->pchhostNS=%p, expected NULL\n", pInfo->pchHostNS);
1880     }
1881     return S_OK;
1882 }
1883
1884 static HRESULT WINAPI DocHostUIHandler_ShowUI(IDocHostUIHandler2 *iface, DWORD dwID,
1885         IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget,
1886         IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
1887 {
1888     CHECK_EXPECT(ShowUI);
1889
1890     if (editmode)
1891         ok(dwID == DOCHOSTUITYPE_AUTHOR, "dwID=%d, expected DOCHOSTUITYPE_AUTHOR\n", dwID);
1892     else
1893         ok(dwID == DOCHOSTUITYPE_BROWSE, "dwID=%d, expected DOCHOSTUITYPE_BROWSE\n", dwID);
1894     ok(pActiveObject != NULL, "pActiveObject = NULL\n");
1895     ok(pCommandTarget != NULL, "pCommandTarget = NULL\n");
1896     ok(pFrame == &InPlaceFrame, "pFrame=%p, expected %p\n", pFrame, &InPlaceFrame);
1897     if (expect_InPlaceUIWindow_SetActiveObject_active)
1898         ok(pDoc == (IOleInPlaceUIWindow *)&InPlaceUIWindow, "pDoc=%p, expected %p\n", pDoc, &InPlaceUIWindow);
1899     else
1900         ok(pDoc == NULL, "pDoc=%p, expected NULL\n", pDoc);
1901
1902     return S_OK;
1903 }
1904
1905 static HRESULT WINAPI DocHostUIHandler_HideUI(IDocHostUIHandler2 *iface)
1906 {
1907     CHECK_EXPECT(HideUI);
1908     return S_OK;
1909 }
1910
1911 static HRESULT WINAPI DocHostUIHandler_UpdateUI(IDocHostUIHandler2 *iface)
1912 {
1913     CHECK_EXPECT(UpdateUI);
1914     return S_OK;
1915 }
1916
1917 static HRESULT WINAPI DocHostUIHandler_EnableModeless(IDocHostUIHandler2 *iface, BOOL fEnable)
1918 {
1919     ok(0, "unexpected call\n");
1920     return E_NOTIMPL;
1921 }
1922
1923 static HRESULT WINAPI DocHostUIHandler_OnDocWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
1924 {
1925     ok(0, "unexpected call\n");
1926     return E_NOTIMPL;
1927 }
1928
1929 static BOOL expect_OnFrameWindowActivate_fActivate;
1930 static HRESULT WINAPI DocHostUIHandler_OnFrameWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
1931 {
1932     CHECK_EXPECT2(OnFrameWindowActivate);
1933     ok(fActivate == expect_OnFrameWindowActivate_fActivate, "fActivate=%x\n", fActivate);
1934     return S_OK;
1935 }
1936
1937 static HRESULT WINAPI DocHostUIHandler_ResizeBorder(IDocHostUIHandler2 *iface, LPCRECT prcBorder,
1938         IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
1939 {
1940     ok(0, "unexpected call\n");
1941     return E_NOTIMPL;
1942 }
1943
1944 static HRESULT WINAPI DocHostUIHandler_TranslateAccelerator(IDocHostUIHandler2 *iface, LPMSG lpMsg,
1945         const GUID *pguidCmdGroup, DWORD nCmdID)
1946 {
1947     ok(0, "unexpected call\n");
1948     return E_NOTIMPL;
1949 }
1950
1951 static HRESULT WINAPI DocHostUIHandler_GetOptionKeyPath(IDocHostUIHandler2 *iface,
1952         LPOLESTR *pchKey, DWORD dw)
1953 {
1954     CHECK_EXPECT(GetOptionKeyPath);
1955     ok(pchKey != NULL, "pchKey = NULL\n");
1956     ok(!dw, "dw=%d, expected 0\n", dw);
1957     if(pchKey)
1958         ok(!*pchKey, "*pchKey=%p, expected NULL\n", *pchKey);
1959     return S_OK;
1960 }
1961
1962 static HRESULT WINAPI DocHostUIHandler_GetDropTarget(IDocHostUIHandler2 *iface,
1963         IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
1964 {
1965     CHECK_EXPECT(GetDropTarget);
1966     /* TODO */
1967     return E_NOTIMPL;
1968 }
1969
1970 static HRESULT WINAPI DocHostUIHandler_GetExternal(IDocHostUIHandler2 *iface, IDispatch **ppDispatch)
1971 {
1972     CHECK_EXPECT(GetExternal);
1973     *ppDispatch = &External;
1974     return S_FALSE;
1975 }
1976
1977 static HRESULT WINAPI DocHostUIHandler_TranslateUrl(IDocHostUIHandler2 *iface, DWORD dwTranslate,
1978         OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
1979 {
1980     ok(0, "unexpected call\n");
1981     return E_NOTIMPL;
1982 }
1983
1984 static HRESULT WINAPI DocHostUIHandler_FilterDataObject(IDocHostUIHandler2 *iface, IDataObject *pDO,
1985         IDataObject **ppPORet)
1986 {
1987     ok(0, "unexpected call\n");
1988     return E_NOTIMPL;
1989 }
1990
1991 static HRESULT WINAPI DocHostUIHandler_GetOverrideKeyPath(IDocHostUIHandler2 *iface,
1992         LPOLESTR *pchKey, DWORD dw)
1993 {
1994     CHECK_EXPECT(GetOverrideKeyPath);
1995     ok(pchKey != NULL, "pchKey = NULL\n");
1996     if(pchKey)
1997         ok(!*pchKey, "*pchKey=%p, expected NULL\n", *pchKey);
1998     ok(!dw, "dw=%d, xepected 0\n", dw);
1999     return S_OK;
2000 }
2001
2002 static const IDocHostUIHandler2Vtbl DocHostUIHandlerVtbl = {
2003     DocHostUIHandler_QueryInterface,
2004     DocHostUIHandler_AddRef,
2005     DocHostUIHandler_Release,
2006     DocHostUIHandler_ShowContextMenu,
2007     DocHostUIHandler_GetHostInfo,
2008     DocHostUIHandler_ShowUI,
2009     DocHostUIHandler_HideUI,
2010     DocHostUIHandler_UpdateUI,
2011     DocHostUIHandler_EnableModeless,
2012     DocHostUIHandler_OnDocWindowActivate,
2013     DocHostUIHandler_OnFrameWindowActivate,
2014     DocHostUIHandler_ResizeBorder,
2015     DocHostUIHandler_TranslateAccelerator,
2016     DocHostUIHandler_GetOptionKeyPath,
2017     DocHostUIHandler_GetDropTarget,
2018     DocHostUIHandler_GetExternal,
2019     DocHostUIHandler_TranslateUrl,
2020     DocHostUIHandler_FilterDataObject,
2021     DocHostUIHandler_GetOverrideKeyPath
2022 };
2023
2024 static IDocHostUIHandler2 DocHostUIHandler = { &DocHostUIHandlerVtbl };
2025
2026 static HRESULT WINAPI OleCommandTarget_QueryInterface(IOleCommandTarget *iface,
2027         REFIID riid, void **ppv)
2028 {
2029     return QueryInterface(riid, ppv);
2030 }
2031
2032 static ULONG WINAPI OleCommandTarget_AddRef(IOleCommandTarget *iface)
2033 {
2034     return 2;
2035 }
2036
2037 static ULONG WINAPI OleCommandTarget_Release(IOleCommandTarget *iface)
2038 {
2039     return 1;
2040 }
2041
2042 static HRESULT WINAPI OleCommandTarget_QueryStatus(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
2043         ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
2044 {
2045     ok(!pguidCmdGroup, "pguidCmdGroup != MULL\n");
2046     ok(cCmds == 1, "cCmds=%d, expected 1\n", cCmds);
2047     ok(!pCmdText, "pCmdText != NULL\n");
2048
2049     switch(prgCmds[0].cmdID) {
2050     case OLECMDID_SETPROGRESSTEXT:
2051         CHECK_EXPECT(QueryStatus_SETPROGRESSTEXT);
2052         prgCmds[0].cmdf = OLECMDF_ENABLED;
2053         return S_OK;
2054     case OLECMDID_OPEN:
2055         CHECK_EXPECT(QueryStatus_OPEN);
2056         prgCmds[0].cmdf = 0;
2057         return S_OK;
2058     case OLECMDID_NEW:
2059         CHECK_EXPECT(QueryStatus_NEW);
2060         prgCmds[0].cmdf = 0;
2061         return S_OK;
2062     default:
2063         ok(0, "unexpected command %d\n", prgCmds[0].cmdID);
2064     };
2065
2066     return E_FAIL;
2067 }
2068
2069 static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
2070         DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
2071 {
2072     test_readyState(NULL);
2073
2074     if(!pguidCmdGroup) {
2075         switch(nCmdID) {
2076         case OLECMDID_SETPROGRESSMAX:
2077             CHECK_EXPECT2(Exec_SETPROGRESSMAX);
2078             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
2079             ok(pvaIn != NULL, "pvaIn == NULL\n");
2080             if(pvaIn) {
2081                 ok(V_VT(pvaIn) == VT_I4, "V_VT(pvaIn)=%d, expected VT_I4\n", V_VT(pvaIn));
2082                 if(load_state == LD_NO)
2083                     ok(V_I4(pvaIn) == 0, "V_I4(pvaIn)=%d, expected 0\n", V_I4(pvaIn));
2084             }
2085             ok(pvaOut == NULL, "pvaOut=%p, expected NULL\n", pvaOut);
2086             return S_OK;
2087         case OLECMDID_SETPROGRESSPOS:
2088             CHECK_EXPECT2(Exec_SETPROGRESSPOS);
2089             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
2090             ok(pvaIn != NULL, "pvaIn == NULL\n");
2091             if(pvaIn) {
2092                 ok(V_VT(pvaIn) == VT_I4, "V_VT(pvaIn)=%d, expected VT_I4\n", V_VT(pvaIn));
2093                 if(load_state == LD_NO)
2094                     ok(V_I4(pvaIn) == 0, "V_I4(pvaIn)=%d, expected 0\n", V_I4(pvaIn));
2095             }
2096             ok(pvaOut == NULL, "pvaOut=%p, expected NULL\n", pvaOut);
2097             return S_OK;
2098         case OLECMDID_HTTPEQUIV_DONE:
2099             CHECK_EXPECT(Exec_HTTPEQUIV_DONE);
2100             ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt);
2101             ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut);
2102             ok(pvaIn == NULL, "pvaIn=%p\n", pvaIn);
2103             load_state = LD_COMPLETE;
2104             return S_OK;
2105         case OLECMDID_SETDOWNLOADSTATE:
2106             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
2107             ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut);
2108             ok(pvaIn != NULL, "pvaIn == NULL\n");
2109             ok(V_VT(pvaIn) == VT_I4, "V_VT(pvaIn)=%d\n", V_VT(pvaIn));
2110
2111             switch(V_I4(pvaIn)) {
2112             case 0:
2113                 CHECK_EXPECT(Exec_SETDOWNLOADSTATE_0);
2114                 load_state = LD_INTERACTIVE;
2115                 break;
2116             case 1:
2117                 CHECK_EXPECT(Exec_SETDOWNLOADSTATE_1);
2118                 break;
2119             default:
2120                 ok(0, "unexpevted V_I4(pvaIn)=%d\n", V_I4(pvaIn));
2121             }
2122
2123             return S_OK;
2124         case OLECMDID_UPDATECOMMANDS:
2125             CHECK_EXPECT(Exec_UPDATECOMMANDS);
2126             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
2127             ok(pvaIn == NULL, "pvaIn=%p\n", pvaIn);
2128             ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut);
2129             return S_OK;
2130         case OLECMDID_SETTITLE:
2131             CHECK_EXPECT2(Exec_SETTITLE);
2132             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
2133             ok(pvaIn != NULL, "pvaIn == NULL\n");
2134             ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut);
2135             ok(V_VT(pvaIn) == VT_BSTR, "V_VT(pvaIn)=%d\n", V_VT(pvaIn));
2136             ok(V_BSTR(pvaIn) != NULL, "V_BSTR(pvaIn) == NULL\n"); /* TODO */
2137             return S_OK;
2138         case OLECMDID_HTTPEQUIV:
2139             CHECK_EXPECT2(Exec_HTTPEQUIV);
2140             ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt);
2141             /* TODO */
2142             return S_OK;
2143         default:
2144             ok(0, "unexpected command %d\n", nCmdID);
2145             return E_FAIL;
2146         };
2147     }
2148
2149     if(IsEqualGUID(&CGID_ShellDocView, pguidCmdGroup)) {
2150         ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt);
2151
2152         switch(nCmdID) {
2153         case 37:
2154             CHECK_EXPECT2(Exec_ShellDocView_37);
2155
2156             if(load_from_stream)
2157                 test_GetCurMoniker(doc_unk, NULL, about_blank_url);
2158             else if(!editmode)
2159                 test_GetCurMoniker(doc_unk, &Moniker, NULL);
2160
2161             ok(pvaOut == NULL, "pvaOut=%p, expected NULL\n", pvaOut);
2162             ok(pvaIn != NULL, "pvaIn == NULL\n");
2163             if(pvaIn) {
2164                 ok(V_VT(pvaIn) == VT_I4, "V_VT(pvaIn)=%d, expected VT_I4\n", V_VT(pvaIn));
2165                 ok(V_I4(pvaIn) == 0, "V_I4(pvaIn)=%d, expected 0\n", V_I4(pvaIn));
2166             }
2167             return S_OK;
2168         case 84:
2169             CHECK_EXPECT2(Exec_ShellDocView_84);
2170
2171             ok(pvaIn == NULL, "pvaIn == NULL\n");
2172             ok(pvaOut != NULL, "pvaOut=%p, expected NULL\n", pvaOut);
2173             if(pvaIn)
2174                 ok(V_VT(pvaOut) == VT_EMPTY, "V_VT(pvaOut)=%d\n", V_VT(pvaOut));
2175
2176             return E_NOTIMPL;
2177         default:
2178             ok(0, "unexpected command %d\n", nCmdID);
2179             return E_FAIL;
2180         };
2181     }
2182
2183     if(IsEqualGUID(&CGID_MSHTML, pguidCmdGroup)) {
2184         ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt);
2185
2186         switch(nCmdID) {
2187         case IDM_PARSECOMPLETE:
2188             CHECK_EXPECT(Exec_MSHTML_PARSECOMPLETE);
2189             ok(pvaIn == NULL, "pvaIn != NULL\n");
2190             ok(pvaOut == NULL, "pvaOut != NULL\n");
2191             return S_OK;
2192         default:
2193             ok(0, "unexpected command %d\n", nCmdID);
2194         };
2195     }
2196
2197     if(IsEqualGUID(&CGID_DocHostCmdPriv, pguidCmdGroup))
2198         return E_FAIL; /* TODO */
2199
2200     if(IsEqualGUID(&CGID_Explorer, pguidCmdGroup)) {
2201         ok(0, "unexpected cmd %d of CGID_Explorer\n", nCmdID);
2202         return E_NOTIMPL;
2203     }
2204
2205     if(IsEqualGUID(&CGID_DocHostCommandHandler, pguidCmdGroup)) {
2206         ok(0, "unexpected cmd %d of CGID_DocHostCommandHandler\n", nCmdID);
2207         return E_NOTIMPL;
2208     }
2209
2210     ok(0, "unexpected pguidCmdGroup: %s\n", debugstr_guid(pguidCmdGroup));
2211     return E_NOTIMPL;
2212 }
2213
2214 static IOleCommandTargetVtbl OleCommandTargetVtbl = {
2215     OleCommandTarget_QueryInterface,
2216     OleCommandTarget_AddRef,
2217     OleCommandTarget_Release,
2218     OleCommandTarget_QueryStatus,
2219     OleCommandTarget_Exec
2220 };
2221
2222 static IOleCommandTarget OleCommandTarget = { &OleCommandTargetVtbl };
2223
2224 static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
2225 {
2226     return QueryInterface(riid, ppv);
2227 }
2228
2229 static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
2230         LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
2231         EXCEPINFO *pExcepInfo, UINT *puArgErr)
2232 {
2233     ok(IsEqualGUID(&IID_NULL, riid), "riid != IID_NULL\n");
2234     ok(pDispParams != NULL, "pDispParams == NULL\n");
2235     ok(pExcepInfo == NULL, "pExcepInfo=%p, expected NULL\n", pExcepInfo);
2236     ok(puArgErr != NULL, "puArgErr == NULL\n");
2237     ok(V_VT(pVarResult) == 0, "V_VT(pVarResult)=%d, expected 0\n", V_VT(pVarResult));
2238     ok(wFlags == DISPATCH_PROPERTYGET, "wFlags=%08x, expected DISPATCH_PROPERTYGET\n", wFlags);
2239     test_readyState(NULL);
2240
2241     switch(dispIdMember) {
2242     case DISPID_AMBIENT_USERMODE:
2243         CHECK_EXPECT2(Invoke_AMBIENT_USERMODE);
2244         V_VT(pVarResult) = VT_BOOL;
2245         V_BOOL(pVarResult) = VARIANT_TRUE;
2246         return S_OK;
2247     case DISPID_AMBIENT_DLCONTROL:
2248         CHECK_EXPECT2(Invoke_AMBIENT_DLCONTROL);
2249         return E_FAIL;
2250     case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
2251         CHECK_EXPECT2(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
2252         return E_FAIL;
2253     case DISPID_AMBIENT_SILENT:
2254         CHECK_EXPECT2(Invoke_AMBIENT_SILENT);
2255         V_VT(pVarResult) = VT_BOOL;
2256         V_BOOL(pVarResult) = VARIANT_FALSE;
2257         return S_OK;
2258     case DISPID_AMBIENT_USERAGENT:
2259         CHECK_EXPECT(Invoke_AMBIENT_USERAGENT);
2260         return E_FAIL;
2261     case DISPID_AMBIENT_PALETTE:
2262         CHECK_EXPECT(Invoke_AMBIENT_PALETTE);
2263         return E_FAIL;
2264     };
2265
2266     ok(0, "unexpected dispid %d\n", dispIdMember);
2267     return E_FAIL;
2268 }
2269
2270 static IDispatchVtbl DispatchVtbl = {
2271     Dispatch_QueryInterface,
2272     Dispatch_AddRef,
2273     Dispatch_Release,
2274     Dispatch_GetTypeInfoCount,
2275     Dispatch_GetTypeInfo,
2276     Dispatch_GetIDsOfNames,
2277     Dispatch_Invoke
2278 };
2279
2280 static IDispatch Dispatch = { &DispatchVtbl };
2281
2282 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface,
2283                                                      REFIID riid, void **ppv)
2284 {
2285     return QueryInterface(riid, ppv);
2286 }
2287
2288 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
2289 {
2290     return 2;
2291 }
2292
2293 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
2294 {
2295     return 1;
2296 }
2297
2298 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
2299                                     REFIID riid, void **ppv)
2300 {
2301     /*
2302      * Services used by HTMLDocument:
2303      *
2304      * IOleUndoManager
2305      * IInternetSecurityManager
2306      * ITargetFrame
2307      * {D5F78C80-5252-11CF-90FA-00AA0042106E}
2308      * HTMLFrameBase
2309      * IShellObject
2310      * {3050F312-98B5-11CF-BB82-00AA00BDCE0B}
2311      * {53A2D5B1-D2FC-11D0-84E0-006097C9987D}
2312      * {AD7F6C62-F6BD-11D2-959B-006097C553C8}
2313      * DefView (?)
2314      * {6D12FE80-7911-11CF-9534-0000C05BAE0B}
2315      * IElementBehaviorFactory
2316      * {3050F429-98B5-11CF-BB82-00AA00BDCE0B}
2317      * STopLevelBrowser
2318      * IHTMLWindow2
2319      * IInternetProtocol
2320      * IWebBrowserApp
2321      * UrlHostory
2322      * IHTMLEditHost
2323      * IHlinkFrame
2324      */
2325
2326     if(IsEqualGUID(&IID_IHlinkFrame, guidService)) {
2327         ok(IsEqualGUID(&IID_IHlinkFrame, riid), "unexpected riid\n");
2328         *ppv = &HlinkFrame;
2329         return S_OK;
2330     }
2331
2332     return E_NOINTERFACE;
2333 }
2334
2335 static const IServiceProviderVtbl ServiceProviderVtbl = {
2336     ServiceProvider_QueryInterface,
2337     ServiceProvider_AddRef,
2338     ServiceProvider_Release,
2339     ServiceProvider_QueryService
2340 };
2341
2342 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
2343
2344 DEFINE_GUID(IID_unk1, 0xD48A6EC6,0x6A4A,0x11CF,0x94,0xA7,0x44,0x45,0x53,0x54,0x00,0x00); /* HTMLWindow2 ? */
2345 DEFINE_GUID(IID_unk2, 0x7BB0B520,0xB1A7,0x11D2,0xBB,0x23,0x00,0xC0,0x4F,0x79,0xAB,0xCD);
2346 DEFINE_GUID(IID_unk3, 0x000670BA,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
2347
2348 static HRESULT QueryInterface(REFIID riid, void **ppv)
2349 {
2350     *ppv = NULL;
2351
2352     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid))
2353         *ppv = &ClientSite;
2354     else if(IsEqualGUID(&IID_IOleDocumentSite, riid))
2355         *ppv = &DocumentSite;
2356     else if(IsEqualGUID(&IID_IDocHostUIHandler, riid) || IsEqualGUID(&IID_IDocHostUIHandler2, riid))
2357         *ppv = &DocHostUIHandler;
2358     else if(IsEqualGUID(&IID_IOleContainer, riid))
2359         *ppv = &OleContainer;
2360     else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
2361         *ppv = &InPlaceSiteEx;
2362     else if(IsEqualGUID(&IID_IOleCommandTarget , riid))
2363         *ppv = &OleCommandTarget;
2364     else if(IsEqualGUID(&IID_IDispatch, riid))
2365         *ppv = &Dispatch;
2366     else if(IsEqualGUID(&IID_IServiceProvider, riid))
2367         *ppv = &ServiceProvider;
2368     else if(IsEqualGUID(&IID_IOleInPlaceSiteEx, riid))
2369         *ppv = ipsex ? &InPlaceSiteEx : NULL;
2370     else if(IsEqualGUID(&IID_IOleControlSite, riid))
2371         *ppv = &OleControlSite;
2372     else if(IsEqualGUID(&IID_IDocHostShowUI, riid))
2373         return E_NOINTERFACE; /* TODO */
2374     else if(IsEqualGUID(&IID_IProxyManager, riid))
2375         return E_NOINTERFACE; /* ? */
2376     else if(IsEqualGUID(&IID_unk1, riid))
2377         return E_NOINTERFACE; /* HTMLWindow2 ? */
2378     else if(IsEqualGUID(&IID_unk2, riid))
2379         return E_NOINTERFACE; /* ? */
2380     else if(IsEqualGUID(&IID_unk3, riid))
2381         return E_NOINTERFACE; /* ? */
2382     else
2383         ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2384
2385     if(*ppv)
2386         return S_OK;
2387     return E_NOINTERFACE;
2388 }
2389
2390 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2391 {
2392     return DefWindowProc(hwnd, msg, wParam, lParam);
2393 }
2394
2395 static void _test_readyState(unsigned line, IUnknown *unk)
2396 {
2397     IHTMLDocument2 *htmldoc;
2398     DISPPARAMS dispparams;
2399     BSTR state;
2400     VARIANT out;
2401     HRESULT hres;
2402
2403     static const WCHAR wszUninitialized[] = {'u','n','i','n','i','t','i','a','l','i','z','e','d',0};
2404     static const WCHAR wszLoading[] = {'l','o','a','d','i','n','g',0};
2405     static const WCHAR wszInteractive[] = {'i','n','t','e','r','a','c','t','i','v','e',0};
2406     static const WCHAR wszComplete[] = {'c','o','m','p','l','e','t','e',0};
2407
2408     static const LPCWSTR expected_state[] = {
2409         wszUninitialized,
2410         wszLoading,
2411         NULL,
2412         wszInteractive,
2413         wszComplete,
2414         wszUninitialized
2415     };
2416
2417     if(!unk)
2418         unk = doc_unk;
2419
2420     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument2, (void**)&htmldoc);
2421     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument2) failed: %08x\n", hres);
2422     if(FAILED(hres))
2423         return;
2424
2425     hres = IHTMLDocument2_get_readyState(htmldoc, NULL);
2426     ok(hres == E_POINTER, "get_readyState failed: %08x, expected\n", hres);
2427
2428     hres = IHTMLDocument2_get_readyState(htmldoc, &state);
2429     ok(hres == S_OK, "get_ReadyState failed: %08x\n", hres);
2430     ok_(__FILE__, line)
2431         (!lstrcmpW(state, expected_state[load_state]), "unexpected state \"%s\", expected %d\n",
2432          debugstr_w(state), load_state);
2433     SysFreeString(state);
2434
2435     dispparams.cArgs = 0;
2436     dispparams.cNamedArgs = 0;
2437     dispparams.rgdispidNamedArgs = NULL;
2438     dispparams.rgvarg = NULL;
2439
2440     VariantInit(&out);
2441
2442     hres = IHTMLDocument2_Invoke(htmldoc, DISPID_READYSTATE, &IID_NULL, 0, DISPATCH_PROPERTYGET,
2443                                  &dispparams, &out, NULL, NULL);
2444     ok(hres == S_OK, "Invoke(DISPID_READYSTATE) failed: %08x\n", hres);
2445
2446     ok_(__FILE__,line) (V_VT(&out) == VT_I4, "V_VT(out)=%d\n", V_VT(&out));
2447     ok_(__FILE__,line) (V_I4(&out) == load_state%5, "VT_I4(out)=%d, expected %d\n", V_I4(&out), load_state%5);
2448
2449     IHTMLDocument2_Release(htmldoc);
2450 }
2451
2452 static void test_ConnectionPoint(IConnectionPointContainer *container, REFIID riid)
2453 {
2454     IConnectionPointContainer *tmp_container = NULL;
2455     IConnectionPoint *cp;
2456     IID iid;
2457     HRESULT hres;
2458
2459     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
2460     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
2461     if(FAILED(hres))
2462         return;
2463
2464     hres = IConnectionPoint_GetConnectionInterface(cp, &iid);
2465     ok(hres == S_OK, "GetConnectionInterface failed: %08x\n", hres);
2466     ok(IsEqualGUID(riid, &iid), "wrong iid\n");
2467
2468     hres = IConnectionPoint_GetConnectionInterface(cp, NULL);
2469     ok(hres == E_POINTER, "GetConnectionInterface failed: %08x, expected E_POINTER\n", hres);
2470
2471     hres = IConnectionPoint_GetConnectionPointContainer(cp, &tmp_container);
2472     ok(hres == S_OK, "GetConnectionPointContainer failed: %08x\n", hres);
2473     ok(tmp_container == container, "container != tmp_container\n");
2474     if(SUCCEEDED(hres))
2475         IConnectionPointContainer_Release(tmp_container);
2476
2477     hres = IConnectionPoint_GetConnectionPointContainer(cp, NULL);
2478     ok(hres == E_POINTER, "GetConnectionPointContainer failed: %08x, expected E_POINTER\n", hres);
2479
2480     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
2481         DWORD cookie;
2482
2483         hres = IConnectionPoint_Advise(cp, (IUnknown*)&PropertyNotifySink, &cookie);
2484         ok(hres == S_OK, "Advise failed: %08x\n", hres);
2485     }
2486
2487     IConnectionPoint_Release(cp);
2488 }
2489
2490 static void test_ConnectionPointContainer(IUnknown *unk)
2491 {
2492     IConnectionPointContainer *container;
2493     HRESULT hres;
2494
2495     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
2496     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
2497     if(FAILED(hres))
2498         return;
2499
2500     test_ConnectionPoint(container, &IID_IPropertyNotifySink);
2501     test_ConnectionPoint(container, &DIID_HTMLDocumentEvents);
2502     test_ConnectionPoint(container, &DIID_HTMLDocumentEvents2);
2503
2504     IConnectionPointContainer_Release(container);
2505 }
2506
2507 static void test_GetCurMoniker(IUnknown *unk, IMoniker *exmon, LPCWSTR exurl)
2508 {
2509     IHTMLDocument2 *doc;
2510     IPersistMoniker *permon;
2511     IMoniker *mon = (void*)0xdeadbeef;
2512     BSTR doc_url = (void*)0xdeadbeef;
2513     HRESULT hres;
2514
2515     hres = IUnknown_QueryInterface(unk, &IID_IPersistMoniker, (void**)&permon);
2516     ok(hres == S_OK, "QueryInterface(IID_IPersistMoniker) failed: %08x\n", hres);
2517     if(FAILED(hres))
2518         return;
2519
2520     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument2, (void**)&doc);
2521     ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument2) failed: %08x\n", hres);
2522
2523     hres = IHTMLDocument2_get_URL(doc, &doc_url);
2524     ok(hres == S_OK, "get_URL failed: %08x\n", hres);
2525
2526     hres = IPersistMoniker_GetCurMoniker(permon, &mon);
2527     IPersistMoniker_Release(permon);
2528
2529     if(exmon) {
2530         LPOLESTR url;
2531         BOOL exb = expect_GetDisplayName;
2532         BOOL clb = called_GetDisplayName;
2533
2534         ok(hres == S_OK, "GetCurrentMoniker failed: %08x\n", hres);
2535         ok(mon == exmon, "mon(%p) != exmon(%p)\n", mon, exmon);
2536
2537         SET_EXPECT(GetDisplayName);
2538         hres = IMoniker_GetDisplayName(mon, NULL, NULL, &url);
2539         ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
2540         CHECK_CALLED(GetDisplayName);
2541         expect_GetDisplayName = exb;
2542         called_GetDisplayName = clb;
2543
2544         ok(!lstrcmpW(url, doc_url), "url != doc_url\n");
2545         CoTaskMemFree(url);
2546     }else if(exurl) {
2547         LPOLESTR url;
2548
2549         ok(hres == S_OK, "GetCurrentMoniker failed: %08x\n", hres);
2550
2551         hres = IMoniker_GetDisplayName(mon, NULL, NULL, &url);
2552         ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
2553
2554         ok(!lstrcmpW(url, exurl), "unexpected url\n");
2555         ok(!lstrcmpW(url, doc_url), "url != doc_url\n");
2556
2557         CoTaskMemFree(url);
2558     }else {
2559         ok(hres == E_UNEXPECTED,
2560            "GetCurrentMoniker failed: %08x, expected E_UNEXPECTED\n", hres);
2561         ok(mon == (IMoniker*)0xdeadbeef, "mon=%p\n", mon);
2562         ok(!lstrcmpW(doc_url, about_blank_url), "doc_url is not about:blank\n");
2563     }
2564
2565     SysFreeString(doc_url);
2566     IHTMLDocument_Release(doc);
2567     if(mon && mon != (void*)0xdeadbeef)
2568         IMoniker_Release(mon);
2569 }
2570
2571 static void test_Load(IPersistMoniker *persist)
2572 {
2573     IBindCtx *bind;
2574     HRESULT hres;
2575     WCHAR sz_html_clientsite_objectparam[MAX_PATH];
2576
2577     lstrcpyW(sz_html_clientsite_objectparam, SZ_HTML_CLIENTSITE_OBJECTPARAM);
2578
2579     test_readyState((IUnknown*)persist);
2580
2581     CreateBindCtx(0, &bind);
2582     IBindCtx_RegisterObjectParam(bind, sz_html_clientsite_objectparam,
2583                                  (IUnknown*)&ClientSite);
2584
2585     SET_EXPECT(GetDisplayName);
2586     if(!set_clientsite) {
2587         SET_EXPECT(Invoke_AMBIENT_USERMODE);
2588         SET_EXPECT(GetHostInfo);
2589         SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
2590         SET_EXPECT(Invoke_AMBIENT_SILENT);
2591         SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
2592         SET_EXPECT(Invoke_AMBIENT_USERAGENT);
2593         SET_EXPECT(Invoke_AMBIENT_PALETTE);
2594         SET_EXPECT(GetOptionKeyPath);
2595         SET_EXPECT(GetOverrideKeyPath);
2596         SET_EXPECT(GetWindow);
2597         SET_EXPECT(QueryStatus_SETPROGRESSTEXT);
2598         SET_EXPECT(Exec_SETPROGRESSMAX);
2599         SET_EXPECT(Exec_SETPROGRESSPOS);
2600         SET_EXPECT(Exec_ShellDocView_37);
2601     }
2602     if(!container_locked) {
2603         SET_EXPECT(GetContainer);
2604         SET_EXPECT(LockContainer);
2605     }
2606     SET_EXPECT(OnChanged_READYSTATE);
2607     SET_EXPECT(Exec_ShellDocView_84);
2608     SET_EXPECT(BindToStorage);
2609     SET_EXPECT(SetActiveObject);
2610     if(set_clientsite) {
2611         SET_EXPECT(Invoke_AMBIENT_SILENT);
2612         SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
2613         SET_EXPECT(Exec_ShellDocView_37);
2614     }
2615     load_state = LD_DOLOAD;
2616     expect_LockContainer_fLock = TRUE;
2617     readystate_set_loading = TRUE;
2618
2619     hres = IPersistMoniker_Load(persist, FALSE, &Moniker, bind, 0x12);
2620     ok(hres == S_OK, "Load failed: %08x\n", hres);
2621
2622     CHECK_CALLED(GetDisplayName);
2623     if(!set_clientsite) {
2624         CHECK_CALLED(Invoke_AMBIENT_USERMODE);
2625         CHECK_CALLED(GetHostInfo);
2626         CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
2627         CHECK_CALLED(Invoke_AMBIENT_SILENT);
2628         CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
2629         CHECK_CALLED(Invoke_AMBIENT_USERAGENT);
2630         CHECK_CALLED(Invoke_AMBIENT_PALETTE);
2631         CHECK_CALLED(GetOptionKeyPath);
2632         CHECK_CALLED(GetOverrideKeyPath);
2633         CHECK_CALLED(GetWindow);
2634         CHECK_CALLED(QueryStatus_SETPROGRESSTEXT);
2635         CHECK_CALLED(Exec_SETPROGRESSMAX);
2636         CHECK_CALLED(Exec_SETPROGRESSPOS);
2637         CHECK_CALLED(Exec_ShellDocView_37);
2638     }
2639     if(!container_locked) {
2640         CHECK_CALLED(GetContainer);
2641         CHECK_CALLED(LockContainer);
2642         container_locked = TRUE;
2643     }
2644     CHECK_CALLED(OnChanged_READYSTATE);
2645     SET_CALLED(Exec_ShellDocView_84);
2646     CHECK_CALLED(BindToStorage);
2647     SET_CALLED(SetActiveObject); /* FIXME */
2648     if(set_clientsite) {
2649         CHECK_CALLED(Invoke_AMBIENT_SILENT);
2650         CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
2651         CHECK_CALLED(Exec_ShellDocView_37);
2652     }
2653
2654     set_clientsite = container_locked = TRUE;
2655
2656     test_GetCurMoniker((IUnknown*)persist, &Moniker, NULL);
2657
2658     IBindCtx_Release(bind);
2659
2660     test_readyState((IUnknown*)persist);
2661 }
2662
2663 static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl)
2664 {
2665     HWND hwnd;
2666     MSG msg;
2667
2668     hwnd = FindWindowA("Internet Explorer_Hidden", NULL);
2669     ok(hwnd != NULL, "Could not find hidden window\n");
2670
2671     test_readyState(NULL);
2672
2673     if(verb_done) {
2674         SET_EXPECT(Exec_SETPROGRESSMAX);
2675         if(!load_from_stream)
2676             SET_EXPECT(GetHostInfo);
2677     }
2678     SET_EXPECT(SetStatusText);
2679     SET_EXPECT(Exec_SETDOWNLOADSTATE_1);
2680     SET_EXPECT(GetDropTarget);
2681     if(css_try_dwl)
2682         SET_EXPECT(Exec_ShellDocView_84);
2683     if(css_dwl) {
2684         SET_EXPECT(CreateInstance);
2685         SET_EXPECT(Start);
2686         SET_EXPECT(LockRequest);
2687         SET_EXPECT(Terminate);
2688         SET_EXPECT(Protocol_Read);
2689         SET_EXPECT(UnlockRequest);
2690     }
2691     SET_EXPECT(OnChanged_1005);
2692     SET_EXPECT(OnChanged_READYSTATE);
2693     SET_EXPECT(Exec_SETPROGRESSPOS);
2694     SET_EXPECT(Exec_SETDOWNLOADSTATE_0);
2695     SET_EXPECT(Exec_MSHTML_PARSECOMPLETE);
2696     SET_EXPECT(Exec_HTTPEQUIV_DONE);
2697     expect_status_text = (LPWSTR)0xdeadbeef; /* TODO */
2698
2699     while(!called_Exec_HTTPEQUIV_DONE && GetMessage(&msg, NULL, 0, 0)) {
2700         TranslateMessage(&msg);
2701         DispatchMessage(&msg);
2702     }
2703
2704     if(verb_done) {
2705         CHECK_CALLED(Exec_SETPROGRESSMAX);
2706         if(!load_from_stream)
2707             CHECK_CALLED(GetHostInfo);
2708     }
2709     CHECK_CALLED(SetStatusText);
2710     CHECK_CALLED(Exec_SETDOWNLOADSTATE_1);
2711     CHECK_CALLED(GetDropTarget);
2712     if(css_try_dwl)
2713         SET_CALLED(Exec_ShellDocView_84);
2714     if(css_dwl) {
2715         if(called_CreateInstance) {
2716             CHECK_CALLED(CreateInstance);
2717             CHECK_CALLED(Start);
2718             CHECK_CALLED(LockRequest);
2719             CHECK_CALLED(Terminate);
2720             CHECK_CALLED(Protocol_Read);
2721             CHECK_CALLED(UnlockRequest);
2722         }else {
2723             skip("CreateInstance not called. Assuming no Gecko installed.\n");
2724
2725             SET_CALLED(Exec_ShellDocView_84);
2726             SET_CALLED(CreateInstance);
2727             SET_CALLED(Start);
2728             SET_CALLED(LockRequest);
2729             SET_CALLED(Terminate);
2730             SET_CALLED(Protocol_Read);
2731             SET_CALLED(UnlockRequest);
2732
2733             nogecko = TRUE;
2734         }
2735     }
2736     CHECK_CALLED(OnChanged_1005);
2737     CHECK_CALLED(OnChanged_READYSTATE);
2738     CHECK_CALLED(Exec_SETPROGRESSPOS);
2739     CHECK_CALLED(Exec_SETDOWNLOADSTATE_0);
2740     CHECK_CALLED(Exec_MSHTML_PARSECOMPLETE);
2741     CHECK_CALLED(Exec_HTTPEQUIV_DONE);
2742
2743     load_state = LD_COMPLETE;
2744
2745     test_readyState(NULL);
2746 }
2747
2748 static void test_Persist(IUnknown *unk)
2749 {
2750     IPersistMoniker *persist_mon;
2751     IPersistFile *persist_file;
2752     GUID guid;
2753     HRESULT hres;
2754
2755     hres = IUnknown_QueryInterface(unk, &IID_IPersistFile, (void**)&persist_file);
2756     ok(hres == S_OK, "QueryInterface(IID_IPersist) failed: %08x\n", hres);
2757     if(SUCCEEDED(hres)) {
2758         hres = IPersist_GetClassID(persist_file, NULL);
2759         ok(hres == E_INVALIDARG, "GetClassID returned: %08x, expected E_INVALIDARG\n", hres);
2760
2761         hres = IPersist_GetClassID(persist_file, &guid);
2762         ok(hres == S_OK, "GetClassID failed: %08x\n", hres);
2763         ok(IsEqualGUID(&CLSID_HTMLDocument, &guid), "guid != CLSID_HTMLDocument\n");
2764
2765         IPersist_Release(persist_file);
2766     }
2767
2768     hres = IUnknown_QueryInterface(unk, &IID_IPersistMoniker, (void**)&persist_mon);
2769     ok(hres == S_OK, "QueryInterface(IID_IPersistMoniker) failed: %08x\n", hres);
2770     if(SUCCEEDED(hres)) {
2771         hres = IPersistMoniker_GetClassID(persist_mon, NULL);
2772         ok(hres == E_INVALIDARG, "GetClassID returned: %08x, expected E_INVALIDARG\n", hres);
2773
2774         hres = IPersistMoniker_GetClassID(persist_mon, &guid);
2775         ok(hres == S_OK, "GetClassID failed: %08x\n", hres);
2776         ok(IsEqualGUID(&CLSID_HTMLDocument, &guid), "guid != CLSID_HTMLDocument\n");
2777
2778         if(load_state == LD_DOLOAD)
2779             test_Load(persist_mon);
2780
2781         test_readyState(unk);
2782
2783         IPersistMoniker_Release(persist_mon);
2784     }
2785 }
2786
2787 static const OLECMDF expect_cmds[OLECMDID_GETPRINTTEMPLATE+1] = {
2788     0,
2789     OLECMDF_SUPPORTED,                  /* OLECMDID_OPEN */
2790     OLECMDF_SUPPORTED,                  /* OLECMDID_NEW */
2791     OLECMDF_SUPPORTED,                  /* OLECMDID_SAVE */
2792     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_SAVEAS */
2793     OLECMDF_SUPPORTED,                  /* OLECMDID_SAVECOPYAS */
2794     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_PRINT */
2795     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_PRINTPREVIEW */
2796     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_PAGESETUP */
2797     OLECMDF_SUPPORTED,                  /* OLECMDID_SPELL */
2798     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_PROPERTIES */
2799     OLECMDF_SUPPORTED,                  /* OLECMDID_CUT */
2800     OLECMDF_SUPPORTED,                  /* OLECMDID_COPY */
2801     OLECMDF_SUPPORTED,                  /* OLECMDID_PASTE */
2802     OLECMDF_SUPPORTED,                  /* OLECMDID_PASTESPECIAL */
2803     OLECMDF_SUPPORTED,                  /* OLECMDID_UNDO */
2804     OLECMDF_SUPPORTED,                  /* OLECMDID_REDO */
2805     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_SELECTALL */
2806     OLECMDF_SUPPORTED,                  /* OLECMDID_CLEARSELECTION */
2807     OLECMDF_SUPPORTED,                  /* OLECMDID_ZOOM */
2808     OLECMDF_SUPPORTED,                  /* OLECMDID_GETZOOMRANGE */
2809     0,
2810     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_REFRESH */
2811     OLECMDF_SUPPORTED|OLECMDF_ENABLED,  /* OLECMDID_STOP */
2812     0,0,0,0,0,0,
2813     OLECMDF_SUPPORTED,                  /* OLECMDID_STOPDOWNLOAD */
2814     0,0,
2815     OLECMDF_SUPPORTED,                  /* OLECMDID_DELETE */
2816     0,0,
2817     OLECMDF_SUPPORTED,                  /* OLECMDID_ENABLE_INTERACTION */
2818     OLECMDF_SUPPORTED,                  /* OLECMDID_ONUNLOAD */
2819     0,0,0,0,0,
2820     OLECMDF_SUPPORTED,                  /* OLECMDID_SHOWPAGESETUP */
2821     OLECMDF_SUPPORTED,                  /* OLECMDID_SHOWPRINT */
2822     0,0,
2823     OLECMDF_SUPPORTED,                  /* OLECMDID_CLOSE */
2824     0,0,0,
2825     OLECMDF_SUPPORTED,                  /* OLECMDID_SETPRINTTEMPLATE */
2826     OLECMDF_SUPPORTED                   /* OLECMDID_GETPRINTTEMPLATE */
2827 };
2828
2829 #define test_QueryStatus(u,cgid,cmdid,cmdf) _test_QueryStatus(__LINE__,u,cgid,cmdid,cmdf)
2830 static void _test_QueryStatus(unsigned line, IUnknown *unk, REFIID cgid, ULONG cmdid, DWORD cmdf)
2831 {
2832     IOleCommandTarget *cmdtrg;
2833     OLECMD olecmd = {cmdid, 0};
2834     HRESULT hres;
2835
2836     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
2837     ok_(__FILE__,line) (hres == S_OK, "QueryInterface(IID_IOleCommandTarget failed: %08x\n", hres);
2838     if(FAILED(hres))
2839         return;
2840
2841     hres = IOleCommandTarget_QueryStatus(cmdtrg, cgid, 1, &olecmd, NULL);
2842     ok(hres == S_OK, "QueryStatus(%u) failed: %08x\n", cmdid, hres);
2843
2844     IOleCommandTarget_Release(cmdtrg);
2845
2846     ok_(__FILE__,line) (olecmd.cmdID == cmdid, "cmdID changed\n");
2847     ok_(__FILE__,line) (olecmd.cmdf == cmdf, "(%u) cmdf=%08x, expected %08x\n", cmdid, olecmd.cmdf, cmdf);
2848 }
2849
2850 static void test_MSHTML_QueryStatus(IUnknown *unk, DWORD cmdf)
2851 {
2852     if(!unk)
2853         unk = doc_unk;
2854
2855     test_QueryStatus(unk, &CGID_MSHTML, IDM_FONTNAME, cmdf);
2856     test_QueryStatus(unk, &CGID_MSHTML, IDM_FONTSIZE, cmdf);
2857     test_QueryStatus(unk, &CGID_MSHTML, IDM_SELECTALL, cmdf|OLECMDF_ENABLED);
2858     test_QueryStatus(unk, &CGID_MSHTML, IDM_BOLD, cmdf);
2859     test_QueryStatus(unk, &CGID_MSHTML, IDM_FORECOLOR, cmdf);
2860     test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYCENTER, cmdf);
2861     test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYLEFT, cmdf);
2862     test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYRIGHT, cmdf);
2863     test_QueryStatus(unk, &CGID_MSHTML, IDM_ITALIC, cmdf);
2864     test_QueryStatus(unk, &CGID_MSHTML, IDM_UNDERLINE, cmdf);
2865     test_QueryStatus(unk, &CGID_MSHTML, IDM_HORIZONTALLINE, cmdf);
2866     test_QueryStatus(unk, &CGID_MSHTML, IDM_ORDERLIST, cmdf);
2867     test_QueryStatus(unk, &CGID_MSHTML, IDM_UNORDERLIST, cmdf);
2868     test_QueryStatus(unk, &CGID_MSHTML, IDM_INDENT, cmdf);
2869     test_QueryStatus(unk, &CGID_MSHTML, IDM_OUTDENT, cmdf);
2870     test_QueryStatus(unk, &CGID_MSHTML, IDM_DELETE, cmdf);
2871 }
2872
2873 static void test_OleCommandTarget(IUnknown *unk)
2874 {
2875     IOleCommandTarget *cmdtrg;
2876     OLECMD cmds[OLECMDID_GETPRINTTEMPLATE];
2877     int i;
2878     HRESULT hres;
2879
2880     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
2881     ok(hres == S_OK, "QueryInterface(IID_IOleCommandTarget failed: %08x\n", hres);
2882     if(FAILED(hres))
2883         return;
2884
2885     for(i=0; i<OLECMDID_GETPRINTTEMPLATE; i++) {
2886         cmds[i].cmdID = i+1;
2887         cmds[i].cmdf = 0xf0f0;
2888     }
2889
2890     SET_EXPECT(QueryStatus_OPEN);
2891     SET_EXPECT(QueryStatus_NEW);
2892     hres = IOleCommandTarget_QueryStatus(cmdtrg, NULL, sizeof(cmds)/sizeof(cmds[0]), cmds, NULL);
2893     ok(hres == S_OK, "QueryStatus failed: %08x\n", hres);
2894     CHECK_CALLED(QueryStatus_OPEN);
2895     CHECK_CALLED(QueryStatus_NEW);
2896
2897     for(i=0; i<OLECMDID_GETPRINTTEMPLATE; i++) {
2898         ok(cmds[i].cmdID == i+1, "cmds[%d].cmdID canged to %x\n", i, cmds[i].cmdID);
2899         if(i+1 == OLECMDID_FIND)
2900             continue;
2901         ok(cmds[i].cmdf == expect_cmds[i+1], "cmds[%d].cmdf=%x, expected %x\n",
2902                 i+1, cmds[i].cmdf, expect_cmds[i+1]);
2903     }
2904
2905     ok(!cmds[OLECMDID_FIND-1].cmdf || cmds[OLECMDID_FIND-1].cmdf == (OLECMDF_SUPPORTED|OLECMDF_ENABLED),
2906        "cmds[OLECMDID_FIND].cmdf=%x\n", cmds[OLECMDID_FIND-1].cmdf);
2907
2908     IOleCommandTarget_Release(cmdtrg);
2909 }
2910
2911 static void test_OleCommandTarget_fail(IUnknown *unk)
2912 {
2913     IOleCommandTarget *cmdtrg;
2914     int i;
2915     HRESULT hres;
2916
2917     OLECMD cmd[2] = {
2918         {OLECMDID_OPEN, 0xf0f0},
2919         {OLECMDID_GETPRINTTEMPLATE+1, 0xf0f0}
2920     };
2921
2922     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
2923     ok(hres == S_OK, "QueryInterface(IIDIOleCommandTarget failed: %08x\n", hres);
2924     if(FAILED(hres))
2925         return;
2926
2927     hres = IOleCommandTarget_QueryStatus(cmdtrg, NULL, 0, NULL, NULL);
2928     ok(hres == S_OK, "QueryStatus failed: %08x\n", hres);
2929
2930     SET_EXPECT(QueryStatus_OPEN);
2931     hres = IOleCommandTarget_QueryStatus(cmdtrg, NULL, 2, cmd, NULL);
2932     CHECK_CALLED(QueryStatus_OPEN);
2933
2934     ok(hres == OLECMDERR_E_NOTSUPPORTED,
2935             "QueryStatus failed: %08x, expected OLECMDERR_E_NOTSUPPORTED\n", hres);
2936     ok(cmd[1].cmdID == OLECMDID_GETPRINTTEMPLATE+1,
2937             "cmd[0].cmdID=%d, expected OLECMDID_GETPRINTTEMPLATE+1\n", cmd[0].cmdID);
2938     ok(cmd[1].cmdf == 0, "cmd[0].cmdf=%x, expected 0\n", cmd[0].cmdf);
2939     ok(cmd[0].cmdf == OLECMDF_SUPPORTED,
2940             "cmd[1].cmdf=%x, expected OLECMDF_SUPPORTED\n", cmd[1].cmdf);
2941
2942     hres = IOleCommandTarget_QueryStatus(cmdtrg, &IID_IHTMLDocument2, 2, cmd, NULL);
2943     ok(hres == OLECMDERR_E_UNKNOWNGROUP,
2944             "QueryStatus failed: %08x, expected OLECMDERR_E_UNKNOWNGROUP\n", hres);
2945
2946     for(i=0; i<OLECMDID_GETPRINTTEMPLATE; i++) {
2947         if(!expect_cmds[i]) {
2948             hres = IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_UPDATECOMMANDS,
2949                     OLECMDEXECOPT_DODEFAULT, NULL, NULL);
2950             ok(hres == OLECMDERR_E_NOTSUPPORTED,
2951                     "Exec failed: %08x, expected OLECMDERR_E_NOTSUPPORTED\n", hres);
2952         }
2953     }
2954
2955     hres = IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_GETPRINTTEMPLATE+1,
2956             OLECMDEXECOPT_DODEFAULT, NULL, NULL);
2957     ok(hres == OLECMDERR_E_NOTSUPPORTED,
2958             "Exec failed: %08x, expected OLECMDERR_E_NOTSUPPORTED\n", hres);
2959
2960     IOleCommandTarget_Release(cmdtrg);
2961 }
2962
2963 static void test_exec_onunload(IUnknown *unk)
2964 {
2965     IOleCommandTarget *cmdtrg;
2966     VARIANT var;
2967     HRESULT hres;
2968
2969     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
2970     ok(hres == S_OK, "QueryInterface(IID_IOleCommandTarget) failed: %08x\n", hres);
2971     if(FAILED(hres))
2972         return;
2973
2974     memset(&var, 0x0a, sizeof(var));
2975     hres = IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_ONUNLOAD,
2976             OLECMDEXECOPT_DODEFAULT, NULL, &var);
2977     ok(hres == S_OK, "Exec(..., OLECMDID_ONUNLOAD, ...) failed: %08x\n", hres);
2978     ok(V_VT(&var) == VT_BOOL, "V_VT(var)=%d, expected VT_BOOL\n", V_VT(&var));
2979     ok(V_BOOL(&var) == VARIANT_TRUE, "V_BOOL(var)=%x, expected VARIANT_TRUE\n", V_BOOL(&var));
2980
2981     hres = IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_ONUNLOAD,
2982             OLECMDEXECOPT_DODEFAULT, NULL, NULL);
2983     ok(hres == S_OK, "Exec(..., OLECMDID_ONUNLOAD, ...) failed: %08x\n", hres);
2984
2985     IOleCommandTarget_Release(cmdtrg);
2986 }
2987
2988 static void test_exec_editmode(IUnknown *unk, BOOL loaded)
2989 {
2990     IOleCommandTarget *cmdtrg;
2991     HRESULT hres;
2992
2993     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
2994     ok(hres == S_OK, "QueryInterface(IID_IOleCommandTarget) failed: %08x\n", hres);
2995     if(FAILED(hres))
2996         return;
2997
2998     editmode = TRUE;
2999
3000     if(loaded)
3001         load_state = LD_DOLOAD;
3002
3003     if(loaded)
3004         SET_EXPECT(GetClassID);
3005     SET_EXPECT(SetStatusText);
3006     SET_EXPECT(Exec_ShellDocView_37);
3007     SET_EXPECT(GetHostInfo);
3008     if(loaded)
3009         SET_EXPECT(GetDisplayName);
3010     SET_EXPECT(Invoke_AMBIENT_SILENT);
3011     SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
3012     SET_EXPECT(OnChanged_READYSTATE);
3013     SET_EXPECT(Exec_ShellDocView_84);
3014     if(loaded)
3015         SET_EXPECT(BindToStorage);
3016     SET_EXPECT(InPlaceUIWindow_SetActiveObject);
3017     SET_EXPECT(HideUI);
3018     SET_EXPECT(ShowUI);
3019     SET_EXPECT(InPlaceFrame_SetBorderSpace);
3020
3021     expect_status_text = NULL;
3022     readystate_set_loading = TRUE;
3023
3024     hres = IOleCommandTarget_Exec(cmdtrg, &CGID_MSHTML, IDM_EDITMODE,
3025             OLECMDEXECOPT_DODEFAULT, NULL, NULL);
3026     ok(hres == S_OK, "Exec failed: %08x\n", hres);
3027
3028     if(loaded)
3029         CHECK_CALLED(GetClassID);
3030     CHECK_CALLED(SetStatusText);
3031     CHECK_CALLED(Exec_ShellDocView_37);
3032     CHECK_CALLED(GetHostInfo);
3033     if(loaded)
3034         CHECK_CALLED(GetDisplayName);
3035     CHECK_CALLED(Invoke_AMBIENT_SILENT);
3036     CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
3037     CHECK_CALLED(OnChanged_READYSTATE);
3038     SET_CALLED(Exec_ShellDocView_84);
3039     if(loaded)
3040         CHECK_CALLED(BindToStorage);
3041     CHECK_CALLED(InPlaceUIWindow_SetActiveObject);
3042     CHECK_CALLED(HideUI);
3043     CHECK_CALLED(ShowUI);
3044     CHECK_CALLED(InPlaceFrame_SetBorderSpace);
3045
3046     test_timer(EXPECT_UPDATEUI|EXPECT_SETTITLE);
3047
3048     IOleCommandTarget_Release(cmdtrg);
3049
3050     hres = IOleCommandTarget_Exec(cmdtrg, &CGID_MSHTML, IDM_EDITMODE,
3051             OLECMDEXECOPT_DODEFAULT, NULL, NULL);
3052     ok(hres == S_OK, "Exec failed: %08x\n", hres);
3053 }
3054
3055 static void test_exec_fontname(IUnknown *unk, LPCWSTR name, LPCWSTR exname)
3056 {
3057    IOleCommandTarget *cmdtrg;
3058    VARIANT *in = NULL, _in, *out = NULL, _out;
3059    HRESULT hres;
3060
3061    hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
3062    ok(hres == S_OK, "QueryInterface(IIDIOleM=CommandTarget failed: %08x\n", hres);
3063    if(FAILED(hres))
3064        return;
3065
3066    if(name) {
3067        in = &_in;
3068        V_VT(in) = VT_BSTR;
3069        V_BSTR(in) = SysAllocString(name);
3070    }
3071
3072    if(exname) {
3073        out = &_out;
3074        V_VT(out) = VT_I4;
3075        V_I4(out) = 0xdeadbeef;
3076    }
3077
3078    hres = IOleCommandTarget_Exec(cmdtrg, &CGID_MSHTML, IDM_FONTNAME, 0, in, out);
3079    if(!nogecko)
3080        ok(hres == S_OK, "Exec(IDM_FONTNAME) failed: %08x\n", hres);
3081
3082    if(in)
3083        VariantClear(in);
3084
3085    if(out && !nogecko) {
3086        ok(V_VT(out) == VT_BSTR, "V_VT(out) = %x\n", V_VT(out));
3087        if(V_VT(out) == VT_BSTR) {
3088            if(exname)
3089                ok(!lstrcmpW(V_BSTR(out), name ? name : exname),
3090                   "unexpected fontname \"%s\"\n", debugstr_w(name));
3091            else
3092                ok(V_BSTR(out) == NULL, "V_BSTR(out) != NULL\n");
3093        }
3094        VariantClear(out);
3095    }
3096
3097    IOleCommandTarget_Release(cmdtrg);
3098 }
3099
3100 static void test_exec_noargs(IUnknown *unk, DWORD cmdid)
3101 {
3102     IOleCommandTarget *cmdtrg;
3103     HRESULT hres;
3104
3105     hres = IUnknown_QueryInterface(unk, &IID_IOleCommandTarget, (void**)&cmdtrg);
3106     ok(hres == S_OK, "QueryInterface(IID_IOleCommandTarget) failed: %08x\n", hres);
3107     if(FAILED(hres))
3108         return;
3109
3110     hres = IOleCommandTarget_Exec(cmdtrg, &CGID_MSHTML, cmdid,
3111             OLECMDEXECOPT_DODEFAULT, NULL, NULL);
3112     ok(hres == S_OK, "Exec failed: %08x\n", hres);
3113
3114     IOleCommandTarget_Release(cmdtrg);
3115 }
3116
3117 static void test_IsDirty(IUnknown *unk, HRESULT exhres)
3118 {
3119     IPersistStreamInit *perinit;
3120     IPersistMoniker *permon;
3121     IPersistFile *perfile;
3122     HRESULT hres;
3123
3124     hres = IUnknown_QueryInterface(unk, &IID_IPersistStreamInit, (void**)&perinit);
3125     ok(hres == S_OK, "QueryInterface(IID_IPersistStreamInit failed: %08x\n", hres);
3126     if(SUCCEEDED(hres)) {
3127         hres = IPersistStreamInit_IsDirty(perinit);
3128         ok(hres == exhres, "IsDirty() = %08x, expected %08x\n", hres, exhres);
3129         IPersistStreamInit_Release(perinit);
3130     }
3131
3132     hres = IUnknown_QueryInterface(unk, &IID_IPersistMoniker, (void**)&permon);
3133     ok(hres == S_OK, "QueryInterface(IID_IPersistMoniker failed: %08x\n", hres);
3134     if(SUCCEEDED(hres)) {
3135         hres = IPersistMoniker_IsDirty(permon);
3136         ok(hres == exhres, "IsDirty() = %08x, expected %08x\n", hres, exhres);
3137         IPersistMoniker_Release(permon);
3138     }
3139
3140     hres = IUnknown_QueryInterface(unk, &IID_IPersistFile, (void**)&perfile);
3141     ok(hres == S_OK, "QueryInterface(IID_IPersistFile failed: %08x\n", hres);
3142     if(SUCCEEDED(hres)) {
3143         hres = IPersistFile_IsDirty(perfile);
3144         ok(hres == exhres, "IsDirty() = %08x, expected %08x\n", hres, exhres);
3145         IPersistFile_Release(perfile);
3146     }
3147 }
3148
3149 static HWND create_container_window(void)
3150 {
3151     static const WCHAR wszHTMLDocumentTest[] =
3152         {'H','T','M','L','D','o','c','u','m','e','n','t','T','e','s','t',0};
3153     static WNDCLASSEXW wndclass = {
3154         sizeof(WNDCLASSEXW),
3155         0,
3156         wnd_proc,
3157         0, 0, NULL, NULL, NULL, NULL, NULL,
3158         wszHTMLDocumentTest,
3159         NULL
3160     };
3161
3162     RegisterClassExW(&wndclass);
3163     return CreateWindowW(wszHTMLDocumentTest, wszHTMLDocumentTest,
3164             WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
3165             515, 530, NULL, NULL, NULL, NULL);
3166 }
3167
3168 static HRESULT test_DoVerb(IOleObject *oleobj)
3169 {
3170     RECT rect = {0,0,500,500};
3171     HRESULT hres;
3172
3173     if(!container_locked) {
3174         SET_EXPECT(GetContainer);
3175         SET_EXPECT(LockContainer);
3176     }
3177     SET_EXPECT(ActivateMe);
3178     expect_LockContainer_fLock = TRUE;
3179
3180     hres = IOleObject_DoVerb(oleobj, OLEIVERB_SHOW, NULL, &ClientSite, -1, container_hwnd, &rect);
3181     if(FAILED(hres))
3182         return hres;
3183     ok(hres == S_OK, "DoVerb failed: %08x\n", hres);
3184
3185     if(!container_locked) {
3186         CHECK_CALLED(GetContainer);
3187         CHECK_CALLED(LockContainer);
3188         container_locked = TRUE;
3189     }
3190     CHECK_CALLED(ActivateMe);
3191
3192     return hres;
3193 }
3194
3195 #define CLIENTSITE_EXPECTPATH 0x00000001
3196 #define CLIENTSITE_SETNULL    0x00000002
3197 #define CLIENTSITE_DONTSET    0x00000004
3198
3199 static void test_ClientSite(IOleObject *oleobj, DWORD flags)
3200 {
3201     IOleClientSite *clientsite;
3202     HRESULT hres;
3203
3204     if(flags & CLIENTSITE_SETNULL) {
3205         hres = IOleObject_GetClientSite(oleobj, &clientsite);
3206         ok(clientsite == &ClientSite, "clientsite=%p, expected %p\n", clientsite, &ClientSite);
3207
3208         hres = IOleObject_SetClientSite(oleobj, NULL);
3209         ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
3210
3211         set_clientsite = FALSE;
3212     }
3213
3214     if(flags & CLIENTSITE_DONTSET)
3215         return;
3216
3217     hres = IOleObject_GetClientSite(oleobj, &clientsite);
3218     ok(hres == S_OK, "GetClientSite failed: %08x\n", hres);
3219     ok(clientsite == (set_clientsite ? &ClientSite : NULL), "GetClientSite() = %p, expected %p\n",
3220             clientsite, set_clientsite ? &ClientSite : NULL);
3221
3222     if(!set_clientsite) {
3223         SET_EXPECT(GetHostInfo);
3224         if(flags & CLIENTSITE_EXPECTPATH) {
3225             SET_EXPECT(GetOptionKeyPath);
3226             SET_EXPECT(GetOverrideKeyPath);
3227         }
3228         SET_EXPECT(GetWindow);
3229         SET_EXPECT(QueryStatus_SETPROGRESSTEXT);
3230         SET_EXPECT(Exec_SETPROGRESSMAX);
3231         SET_EXPECT(Exec_SETPROGRESSPOS);
3232         SET_EXPECT(Invoke_AMBIENT_USERMODE);
3233         SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
3234         SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
3235         SET_EXPECT(Invoke_AMBIENT_SILENT);
3236         SET_EXPECT(Invoke_AMBIENT_USERAGENT);
3237         SET_EXPECT(Invoke_AMBIENT_PALETTE);
3238
3239         hres = IOleObject_SetClientSite(oleobj, &ClientSite);
3240         ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
3241
3242         CHECK_CALLED(GetHostInfo);
3243         if(flags & CLIENTSITE_EXPECTPATH) {
3244             CHECK_CALLED(GetOptionKeyPath);
3245             CHECK_CALLED(GetOverrideKeyPath);
3246         }
3247         CHECK_CALLED(GetWindow);
3248         CHECK_CALLED(QueryStatus_SETPROGRESSTEXT);
3249         CHECK_CALLED(Exec_SETPROGRESSMAX);
3250         CHECK_CALLED(Exec_SETPROGRESSPOS);
3251         CHECK_CALLED(Invoke_AMBIENT_USERMODE);
3252         CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
3253         CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED); 
3254         CHECK_CALLED(Invoke_AMBIENT_SILENT);
3255         CHECK_CALLED(Invoke_AMBIENT_USERAGENT);
3256         CHECK_CALLED(Invoke_AMBIENT_PALETTE);
3257
3258         set_clientsite = TRUE;
3259     }
3260
3261     hres = IOleObject_SetClientSite(oleobj, &ClientSite);
3262     ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
3263
3264     hres = IOleObject_GetClientSite(oleobj, &clientsite);
3265     ok(hres == S_OK, "GetClientSite failed: %08x\n", hres);
3266     ok(clientsite == &ClientSite, "GetClientSite() = %p, expected %p\n", clientsite, &ClientSite);
3267 }
3268
3269 static void test_OnAmbientPropertyChange(IUnknown *unk)
3270 {
3271     IOleControl *control = NULL;
3272     HRESULT hres;
3273
3274     hres = IUnknown_QueryInterface(unk, &IID_IOleControl, (void**)&control);
3275     ok(hres == S_OK, "QueryInterface(IID_IOleControl failed: %08x\n", hres);
3276     if(FAILED(hres))
3277         return;
3278
3279     SET_EXPECT(Invoke_AMBIENT_USERMODE);
3280     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_USERMODE);
3281     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
3282     CHECK_CALLED(Invoke_AMBIENT_USERMODE);
3283
3284     SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
3285     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_DLCONTROL);
3286     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
3287     CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
3288
3289     SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
3290     SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
3291     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_OFFLINEIFNOTCONNECTED);
3292     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
3293     CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
3294     CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
3295
3296     SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
3297     SET_EXPECT(Invoke_AMBIENT_SILENT);
3298     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_SILENT);
3299     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
3300     CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
3301     CHECK_CALLED(Invoke_AMBIENT_SILENT);
3302
3303     SET_EXPECT(Invoke_AMBIENT_USERAGENT);
3304     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_USERAGENT);
3305     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
3306     CHECK_CALLED(Invoke_AMBIENT_USERAGENT);
3307
3308     SET_EXPECT(Invoke_AMBIENT_PALETTE);
3309     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_PALETTE);
3310     ok(hres == S_OK, "OnAmbientChange failed: %08x\n", hres);
3311     CHECK_CALLED(Invoke_AMBIENT_PALETTE);
3312
3313     IOleControl_Release(control);
3314 }
3315
3316
3317
3318 static void test_OnAmbientPropertyChange2(IUnknown *unk)
3319 {
3320     IOleControl *control = NULL;
3321     HRESULT hres;
3322
3323     hres = IUnknown_QueryInterface(unk, &IID_IOleControl, (void**)&control);
3324     ok(hres == S_OK, "QueryInterface(IID_IOleControl failed: %08x\n", hres);
3325     if(FAILED(hres))
3326         return;
3327
3328     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_PALETTE);
3329     ok(hres == S_OK, "OnAmbientPropertyChange failed: %08x\n", hres);
3330
3331     IOleControl_Release(control);
3332 }
3333
3334 static void test_Close(IUnknown *unk, BOOL set_client)
3335 {
3336     IOleObject *oleobj = NULL;
3337     HRESULT hres;
3338
3339     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
3340     ok(hres == S_OK, "QueryInterface(IID_IOleObject) failed: %08x\n", hres);
3341     if(FAILED(hres))
3342         return;
3343
3344     SET_EXPECT(GetContainer);
3345     SET_EXPECT(LockContainer);
3346     expect_LockContainer_fLock = FALSE;
3347     hres = IOleObject_Close(oleobj, OLECLOSE_NOSAVE);
3348     ok(hres == S_OK, "Close failed: %08x\n", hres);
3349     CHECK_CALLED(GetContainer);
3350     CHECK_CALLED(LockContainer);
3351     container_locked = FALSE;
3352
3353     if(set_client)
3354         test_ClientSite(oleobj, CLIENTSITE_SETNULL|CLIENTSITE_DONTSET);
3355
3356     IOleObject_Release(oleobj);
3357 }
3358
3359 static void test_OnFrameWindowActivate(IUnknown *unk)
3360 {
3361     IOleInPlaceActiveObject *inplaceact;
3362     HRESULT hres;
3363
3364     hres = IUnknown_QueryInterface(unk, &IID_IOleInPlaceActiveObject, (void**)&inplaceact);
3365     ok(hres == S_OK, "QueryInterface(IID_IOleInPlaceActiveObject) failed: %08x\n", hres);
3366     if(FAILED(hres))
3367         return;
3368
3369     if(set_clientsite) {
3370         expect_OnFrameWindowActivate_fActivate = TRUE;
3371         SET_EXPECT(OnFrameWindowActivate);
3372         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, TRUE);
3373         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
3374         CHECK_CALLED(OnFrameWindowActivate);
3375
3376         SET_EXPECT(OnFrameWindowActivate);
3377         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, TRUE);
3378         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
3379         CHECK_CALLED(OnFrameWindowActivate);
3380
3381         expect_OnFrameWindowActivate_fActivate = FALSE;
3382         SET_EXPECT(OnFrameWindowActivate);
3383         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, FALSE);
3384         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
3385         CHECK_CALLED(OnFrameWindowActivate);
3386
3387         expect_OnFrameWindowActivate_fActivate = TRUE;
3388         SET_EXPECT(OnFrameWindowActivate);
3389         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, TRUE);
3390         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
3391         CHECK_CALLED(OnFrameWindowActivate);
3392     }else {
3393         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, FALSE);
3394         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
3395
3396         hres = IOleInPlaceActiveObject_OnFrameWindowActivate(inplaceact, TRUE);
3397         ok(hres == S_OK, "OnFrameWindowActivate failed: %08x\n", hres);
3398     }
3399
3400     IOleInPlaceActiveObject_Release(inplaceact);
3401 }
3402
3403 static void test_InPlaceDeactivate(IUnknown *unk, BOOL expect_call)
3404 {
3405     IOleInPlaceObjectWindowless *windowlessobj = NULL;
3406     HRESULT hres;
3407
3408     hres = IUnknown_QueryInterface(unk, &IID_IOleInPlaceObjectWindowless,
3409             (void**)&windowlessobj);
3410     ok(hres == S_OK, "QueryInterface(IID_IOleInPlaceObjectWindowless) failed: %08x\n", hres);
3411     if(FAILED(hres))
3412         return;
3413
3414     if(expect_call) {
3415         SET_EXPECT(OnFocus_FALSE);
3416         if(ipsex)
3417             SET_EXPECT(OnInPlaceDeactivateEx);
3418         else
3419             SET_EXPECT(OnInPlaceDeactivate);
3420     }
3421     hres = IOleInPlaceObjectWindowless_InPlaceDeactivate(windowlessobj);
3422     ok(hres == S_OK, "InPlaceDeactivate failed: %08x\n", hres);
3423     if(expect_call) {
3424         CHECK_CALLED(OnFocus_FALSE);
3425         if(ipsex)
3426             CHECK_CALLED(OnInPlaceDeactivateEx);
3427         else
3428             CHECK_CALLED(OnInPlaceDeactivate);
3429     }
3430
3431     IOleInPlaceObjectWindowless_Release(windowlessobj);
3432 }
3433
3434 static HRESULT test_Activate(IUnknown *unk, DWORD flags)
3435 {
3436     IOleObject *oleobj = NULL;
3437     IOleDocumentView *docview;
3438     GUID guid;
3439     HRESULT hres;
3440
3441     last_hwnd = hwnd;
3442
3443     if(view)
3444         IOleDocumentView_Release(view);
3445     view = NULL;
3446
3447     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
3448     ok(hres == S_OK, "QueryInterface(IID_IOleObject) failed: %08x\n", hres);
3449     if(FAILED(hres))
3450         return hres;
3451
3452     hres = IOleObject_GetUserClassID(oleobj, NULL);
3453     ok(hres == E_INVALIDARG, "GetUserClassID returned: %08x, expected E_INVALIDARG\n", hres);
3454
3455     hres = IOleObject_GetUserClassID(oleobj, &guid);
3456     ok(hres == S_OK, "GetUserClassID failed: %08x\n", hres);
3457     ok(IsEqualGUID(&guid, &CLSID_HTMLDocument), "guid != CLSID_HTMLDocument\n");
3458
3459     test_OnFrameWindowActivate(unk);
3460
3461     test_ClientSite(oleobj, flags);
3462     test_InPlaceDeactivate(unk, FALSE);
3463
3464     hres = test_DoVerb(oleobj);
3465
3466     if(call_UIActivate == CallUIActivate_AfterShow) {
3467         hres = IOleObject_QueryInterface(oleobj, &IID_IOleDocumentView, (void **)&docview);
3468         ok(hres == S_OK, "IOleObject_QueryInterface failed with error 0x%08x\n", hres);
3469
3470         SET_EXPECT(OnFocus_TRUE);
3471         SET_EXPECT(SetActiveObject);
3472         SET_EXPECT(ShowUI);
3473         SET_EXPECT(InPlaceUIWindow_SetActiveObject);
3474         SET_EXPECT(InPlaceFrame_SetBorderSpace);
3475         expect_status_text = NULL;
3476
3477         hres = IOleDocumentView_UIActivate(docview, TRUE);
3478         ok(hres == S_OK, "IOleDocumentView_UIActivate failed with error 0x%08x\n", hres);
3479
3480         CHECK_CALLED(OnFocus_TRUE);
3481         CHECK_CALLED(SetActiveObject);
3482         CHECK_CALLED(ShowUI);
3483         CHECK_CALLED(InPlaceUIWindow_SetActiveObject);
3484         CHECK_CALLED(InPlaceFrame_SetBorderSpace);
3485
3486         IOleDocumentView_Release(docview);
3487     }
3488
3489     IOleObject_Release(oleobj);
3490
3491     test_OnFrameWindowActivate(unk);
3492
3493     return hres;
3494 }
3495
3496 static void test_Window(IUnknown *unk, BOOL expect_success)
3497 {
3498     IOleInPlaceActiveObject *activeobject = NULL;
3499     HWND tmp_hwnd;
3500     HRESULT hres;
3501
3502     hres = IOleDocumentView_QueryInterface(view, &IID_IOleInPlaceActiveObject, (void**)&activeobject);
3503     ok(hres == S_OK, "Could not get IOleInPlaceActiveObject interface: %08x\n", hres);
3504     if(FAILED(hres))
3505         return;
3506
3507     hres = IOleInPlaceActiveObject_GetWindow(activeobject, &tmp_hwnd);
3508
3509     if(expect_success) {
3510         ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
3511         ok(tmp_hwnd == hwnd, "tmp_hwnd=%p, expected %p\n", tmp_hwnd, hwnd);
3512     }else {
3513         ok(hres == E_FAIL, "GetWindow returned %08x, expected E_FAIL\n", hres);
3514         ok(IsWindow(hwnd), "hwnd is destroyed\n");
3515     }
3516
3517     IOleInPlaceActiveObject_Release(activeobject);
3518 }
3519
3520 static void test_CloseView(void)
3521 {
3522     IOleInPlaceSite *inplacesite = (IOleInPlaceSite*)0xff00ff00;
3523     HRESULT hres;
3524
3525     if(!view)
3526         return;
3527
3528     hres = IOleDocumentView_Show(view, FALSE);
3529     ok(hres == S_OK, "Show failed: %08x\n", hres);
3530
3531     hres = IOleDocumentView_CloseView(view, 0);
3532     ok(hres == S_OK, "CloseView failed: %08x\n", hres);
3533
3534     hres = IOleDocumentView_SetInPlaceSite(view, NULL);
3535     ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
3536
3537     hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
3538     ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
3539     ok(inplacesite == NULL, "inplacesite=%p, expected NULL\n", inplacesite);
3540 }
3541
3542 static void test_UIDeactivate(void)
3543 {
3544     HRESULT hres;
3545
3546     if(call_UIActivate == CallUIActivate_AfterShow) {
3547         SET_EXPECT(InPlaceUIWindow_SetActiveObject);
3548     }
3549     if(call_UIActivate != CallUIActivate_None) {
3550         SET_EXPECT(SetActiveObject_null);
3551         SET_EXPECT(HideUI);
3552         SET_EXPECT(OnUIDeactivate);
3553     }
3554
3555     hres = IOleDocumentView_UIActivate(view, FALSE);
3556     ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
3557
3558     if(call_UIActivate != CallUIActivate_None) {
3559         CHECK_CALLED(SetActiveObject_null);
3560         CHECK_CALLED(HideUI);
3561         CHECK_CALLED(OnUIDeactivate);
3562     }
3563     if(call_UIActivate == CallUIActivate_AfterShow) {
3564         CHECK_CALLED(InPlaceUIWindow_SetActiveObject);
3565     }
3566 }
3567
3568 static void test_Hide(void)
3569 {
3570     HRESULT hres;
3571
3572     if(!view)
3573         return;
3574
3575     hres = IOleDocumentView_Show(view, FALSE);
3576     ok(hres == S_OK, "Show failed: %08x\n", hres);
3577 }
3578
3579 static HRESULT create_document(IUnknown **unk)
3580 {
3581     HRESULT hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
3582             &IID_IUnknown, (void**)unk);
3583     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
3584     return hres;
3585 }
3586
3587 static void test_Navigate(IUnknown *unk)
3588 {
3589     IHlinkTarget *hlink;
3590     HRESULT hres;
3591
3592     hres = IUnknown_QueryInterface(unk, &IID_IHlinkTarget, (void**)&hlink);
3593     ok(hres == S_OK, "QueryInterface(IID_IHlinkTarget) failed: %08x\n", hres);
3594
3595     SET_EXPECT(ActivateMe);
3596     hres = IHlinkTarget_Navigate(hlink, 0, NULL);
3597     ok(hres == S_OK, "Navigate failed: %08x\n", hres);
3598     CHECK_CALLED(ActivateMe);
3599
3600     IHlinkTarget_Release(hlink);
3601 }
3602
3603 static void test_external(IUnknown *unk, BOOL initialized)
3604 {
3605     IDispatch *external;
3606     IHTMLDocument2 *doc;
3607     IHTMLWindow2 *htmlwin;
3608     HRESULT hres;
3609
3610     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument2, (void**)&doc);
3611     ok(hres == S_OK, "QueryInterface(IID_IHTMLWindow2) failed: %08x\n", hres);
3612
3613     hres = IHTMLDocument2_get_parentWindow(doc, &htmlwin);
3614     IHTMLDocument2_Release(doc);
3615     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
3616
3617     if(initialized)
3618         SET_EXPECT(GetExternal);
3619     external = (void*)0xdeadbeef;
3620     hres = IHTMLWindow2_get_external(htmlwin, &external);
3621     if(initialized) {
3622         ok(hres == S_FALSE || hres == S_OK, "get_external failed: %08x\n", hres);
3623         CHECK_CALLED(GetExternal);
3624         ok(external != NULL, "external == NULL\n");
3625     }else {
3626         ok(hres == S_OK, "get_external failed: %08x\n", hres);
3627         ok(external == NULL, "external != NULL\n");
3628     }
3629
3630     IHTMLWindow2_Release(htmlwin);
3631 }
3632
3633 static void test_StreamLoad(IUnknown *unk)
3634 {
3635     IPersistStreamInit *init;
3636     HRESULT hres;
3637
3638     hres = IUnknown_QueryInterface(unk, &IID_IPersistStreamInit, (void**)&init);
3639     ok(hres == S_OK, "QueryInterface(IID_IPersistStreamInit) failed: %08x\n", hres);
3640     if(FAILED(hres))
3641         return;
3642
3643     SET_EXPECT(Invoke_AMBIENT_SILENT);
3644     SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
3645     SET_EXPECT(Exec_ShellDocView_37);
3646     SET_EXPECT(OnChanged_READYSTATE);
3647     SET_EXPECT(Read);
3648     readystate_set_loading = TRUE;
3649
3650     hres = IPersistStreamInit_Load(init, &Stream);
3651     ok(hres == S_OK, "Load failed: %08x\n", hres);
3652
3653     CHECK_CALLED(Invoke_AMBIENT_SILENT);
3654     CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
3655     CHECK_CALLED(Exec_ShellDocView_37);
3656     CHECK_CALLED(OnChanged_READYSTATE);
3657     CHECK_CALLED(Read);
3658
3659     test_timer(EXPECT_SETTITLE);
3660     test_GetCurMoniker(unk, NULL, about_blank_url);
3661
3662     IPersistStreamInit_Release(init);
3663 }
3664
3665 static void test_QueryInterface(IUnknown *unk)
3666 {
3667     IUnknown *qi;
3668     HRESULT hres;
3669
3670     qi = (void*)0xdeadbeef;
3671     hres = IUnknown_QueryInterface(unk, &IID_IRunnableObject, (void**)&qi);
3672     ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
3673     ok(qi == NULL, "runnable=%p, ezpected NULL\n", qi);
3674
3675     qi = (void*)0xdeadbeef;
3676     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode, (void**)&qi);
3677     ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
3678     ok(qi == NULL, "runnable=%p, ezpected NULL\n", qi);
3679
3680     qi = (void*)0xdeadbeef;
3681     hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode2, (void**)&qi);
3682     ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
3683     ok(qi == NULL, "runnable=%p, ezpected NULL\n", qi);
3684 }
3685
3686 static void init_test(enum load_state_t ls) {
3687     doc_unk = NULL;
3688     hwnd = last_hwnd = NULL;
3689     set_clientsite = FALSE;
3690     load_from_stream = FALSE;
3691     call_UIActivate = CallUIActivate_None;
3692     load_state = ls;
3693     editmode = FALSE;
3694     stream_read = 0;
3695     protocol_read = 0;
3696     ipsex = FALSE;
3697 }
3698
3699 static void test_HTMLDocument(BOOL do_load)
3700 {
3701     IUnknown *unk;
3702     HRESULT hres;
3703     ULONG ref;
3704
3705     trace("Testing HTMLDocument (%s)...\n", (do_load ? "load" : "no load"));
3706
3707     init_test(do_load ? LD_DOLOAD : LD_NO);
3708
3709     hres = create_document(&unk);
3710     if(FAILED(hres))
3711         return;
3712     doc_unk = unk;
3713
3714     test_QueryInterface(unk);
3715     test_IsDirty(unk, S_FALSE);
3716     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
3717     test_external(unk, FALSE);
3718     test_ConnectionPointContainer(unk);
3719     test_GetCurMoniker(unk, NULL, NULL);
3720     test_Persist(unk);
3721     if(!do_load)
3722         test_OnAmbientPropertyChange2(unk);
3723
3724     hres = test_Activate(unk, CLIENTSITE_EXPECTPATH);
3725     if(FAILED(hres)) {
3726         IUnknown_Release(unk);
3727         return;
3728     }
3729
3730     if(do_load) {
3731         test_download(FALSE, TRUE, TRUE);
3732         test_GetCurMoniker(unk, &Moniker, NULL);
3733     }
3734
3735     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
3736     test_OleCommandTarget_fail(unk);
3737     test_OleCommandTarget(unk);
3738     test_OnAmbientPropertyChange(unk);
3739     test_Window(unk, TRUE);
3740     test_external(unk, TRUE);
3741
3742     test_UIDeactivate();
3743     test_OleCommandTarget(unk);
3744     test_Window(unk, TRUE);
3745     test_InPlaceDeactivate(unk, TRUE);
3746
3747     /* Calling test_OleCommandTarget here causes Segmentation Fault with native
3748      * MSHTML. It doesn't with Wine. */
3749
3750     test_Window(unk, FALSE);
3751     test_Hide();
3752     test_InPlaceDeactivate(unk, FALSE);
3753     test_CloseView();
3754     test_Close(unk, FALSE);
3755
3756     /* Activate HTMLDocument again */
3757     test_Activate(unk, CLIENTSITE_SETNULL);
3758     test_Window(unk, TRUE);
3759     test_OleCommandTarget(unk);
3760     test_UIDeactivate();
3761     test_InPlaceDeactivate(unk, TRUE);
3762     test_Close(unk, FALSE);
3763
3764     /* Activate HTMLDocument again, this time without UIActivate */
3765     call_UIActivate = CallUIActivate_None;
3766     test_Activate(unk, CLIENTSITE_SETNULL);
3767     test_Window(unk, TRUE);
3768
3769     test_UIDeactivate();
3770     test_InPlaceDeactivate(unk, TRUE);
3771     test_CloseView();
3772     test_CloseView();
3773     test_Close(unk, TRUE);
3774     test_OnAmbientPropertyChange2(unk);
3775     test_GetCurMoniker(unk, do_load ? &Moniker : NULL, NULL);
3776
3777     if(!do_load) {
3778         /* Activate HTMLDocument again, calling UIActivate after showing the window */
3779         call_UIActivate = CallUIActivate_AfterShow;
3780         test_Activate(unk, 0);
3781         test_Window(unk, TRUE);
3782         test_OleCommandTarget(unk);
3783         test_UIDeactivate();
3784         test_InPlaceDeactivate(unk, TRUE);
3785         test_Close(unk, FALSE);
3786         call_UIActivate = CallUIActivate_None;
3787     }
3788
3789     if(view)
3790         IOleDocumentView_Release(view);
3791     view = NULL;
3792
3793     ok(IsWindow(hwnd), "hwnd is destroyed\n");
3794
3795     ref = IUnknown_Release(unk);
3796     ok(ref == 0, "ref=%d, expected 0\n", ref);
3797
3798     ok(!IsWindow(hwnd), "hwnd is not destroyed\n");
3799 }
3800
3801 static void test_HTMLDocument_hlink(void)
3802 {
3803     IUnknown *unk;
3804     HRESULT hres;
3805     ULONG ref;
3806
3807     trace("Testing HTMLDocument (hlink)...\n");
3808
3809     init_test(LD_DOLOAD);
3810     ipsex = TRUE;
3811
3812     hres = create_document(&unk);
3813     if(FAILED(hres))
3814         return;
3815     doc_unk = unk;
3816
3817     test_ConnectionPointContainer(unk);
3818     test_GetCurMoniker(unk, NULL, NULL);
3819     test_Persist(unk);
3820     test_Navigate(unk);
3821
3822     test_download(FALSE, TRUE, TRUE);
3823
3824     test_IsDirty(unk, S_FALSE);
3825     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
3826
3827     test_exec_onunload(unk);
3828     test_Window(unk, TRUE);
3829     test_InPlaceDeactivate(unk, TRUE);
3830     test_Close(unk, FALSE);
3831     test_IsDirty(unk, S_FALSE);
3832     test_GetCurMoniker(unk, &Moniker, NULL);
3833
3834     if(view)
3835         IOleDocumentView_Release(view);
3836     view = NULL;
3837
3838     ref = IUnknown_Release(unk);
3839     ok(ref == 0, "ref=%d, expected 0\n", ref);
3840 }
3841
3842 static void test_HTMLDocument_StreamLoad(void)
3843 {
3844     IOleObject *oleobj;
3845     IUnknown *unk;
3846     HRESULT hres;
3847     ULONG ref;
3848
3849     trace("Testing HTMLDocument (IPersistStreamInit)...\n");
3850
3851     init_test(LD_DOLOAD);
3852     load_from_stream = TRUE;
3853
3854     hres = create_document(&unk);
3855     if(FAILED(hres))
3856         return;
3857     doc_unk = unk;
3858
3859     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
3860     ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres);
3861
3862     test_readyState(unk);
3863     test_IsDirty(unk, S_FALSE);
3864     test_ConnectionPointContainer(unk);
3865     test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH);
3866     test_DoVerb(oleobj);
3867     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
3868
3869     IOleObject_Release(oleobj);
3870
3871     test_GetCurMoniker(unk, NULL, NULL);
3872     test_StreamLoad(unk);
3873     test_download(TRUE, FALSE, TRUE);
3874     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
3875
3876     test_UIDeactivate();
3877     test_InPlaceDeactivate(unk, TRUE);
3878     test_Close(unk, FALSE);
3879     test_IsDirty(unk, S_FALSE);
3880
3881     if(view) {
3882         IOleDocumentView_Release(view);
3883         view = NULL;
3884     }
3885
3886
3887     ref = IUnknown_Release(unk);
3888     ok(ref == 0, "ref=%d, expected 0\n", ref);
3889 }
3890
3891 static void test_edit_uiactivate(IOleObject *oleobj)
3892 {
3893     IOleDocumentView *docview;
3894     HRESULT hres;
3895
3896     hres = IOleObject_QueryInterface(oleobj, &IID_IOleDocumentView, (void **)&docview);
3897     ok(hres == S_OK, "IOleObject_QueryInterface failed with error 0x%08x\n", hres);
3898
3899     SET_EXPECT(OnFocus_TRUE);
3900     SET_EXPECT(SetActiveObject);
3901     SET_EXPECT(ShowUI);
3902     SET_EXPECT(InPlaceUIWindow_SetActiveObject);
3903     SET_EXPECT(InPlaceFrame_SetBorderSpace);
3904     expect_status_text = NULL;
3905
3906     hres = IOleDocumentView_UIActivate(docview, TRUE);
3907     ok(hres == S_OK, "IOleDocumentView_UIActivate failed with error 0x%08x\n", hres);
3908
3909     CHECK_CALLED(OnFocus_TRUE);
3910     CHECK_CALLED(SetActiveObject);
3911     CHECK_CALLED(ShowUI);
3912     CHECK_CALLED(InPlaceUIWindow_SetActiveObject);
3913     CHECK_CALLED(InPlaceFrame_SetBorderSpace);
3914
3915     IOleDocumentView_Release(docview);
3916 }
3917
3918 static void test_editing_mode(BOOL do_load)
3919 {
3920     IUnknown *unk;
3921     IOleObject *oleobj;
3922     HRESULT hres;
3923     ULONG ref;
3924
3925     trace("Testing HTMLDocument (edit%s)...\n", do_load ? " load" : "");
3926
3927     init_test(do_load ? LD_DOLOAD : LD_NO);
3928     call_UIActivate = CallUIActivate_AfterShow;
3929
3930     hres = create_document(&unk);
3931     if(FAILED(hres))
3932         return;
3933     doc_unk = unk;
3934
3935     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
3936     ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres);
3937
3938     test_readyState(unk);
3939     test_ConnectionPointContainer(unk);
3940     test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH);
3941     test_DoVerb(oleobj);
3942     test_edit_uiactivate(oleobj);
3943
3944     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
3945     if(do_load)
3946         test_Persist(unk);
3947     stream_read = protocol_read = 0;
3948     test_exec_editmode(unk, do_load);
3949     test_UIDeactivate();
3950     call_UIActivate = CallUIActivate_None;
3951     IOleObject_Release(oleobj);
3952
3953     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
3954     test_download(TRUE, do_load, do_load);
3955     test_timer(EXPECT_UPDATEUI);
3956     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED|OLECMDF_ENABLED);
3957
3958     if(!do_load) {
3959         test_exec_fontname(unk, NULL, wszTimesNewRoman);
3960         test_exec_fontname(unk, wszArial, wszTimesNewRoman);
3961         test_timer(EXPECT_UPDATEUI);
3962         test_exec_fontname(unk, NULL, wszArial);
3963
3964         test_exec_noargs(unk, IDM_JUSTIFYRIGHT);
3965         test_timer(EXPECT_UPDATEUI);
3966         if(!nogecko)
3967             test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYRIGHT,
3968                              OLECMDF_SUPPORTED|OLECMDF_ENABLED|OLECMDF_LATCHED);
3969
3970         test_exec_noargs(unk, IDM_JUSTIFYCENTER);
3971         test_timer(EXPECT_UPDATEUI);
3972         test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYRIGHT,
3973                          OLECMDF_SUPPORTED|OLECMDF_ENABLED);
3974         if(!nogecko)
3975             test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYCENTER,
3976                              OLECMDF_SUPPORTED|OLECMDF_ENABLED|OLECMDF_LATCHED);
3977
3978         test_exec_noargs(unk, IDM_HORIZONTALLINE);
3979         test_timer(EXPECT_UPDATEUI);
3980         test_QueryStatus(unk, &CGID_MSHTML, IDM_HORIZONTALLINE,
3981                          OLECMDF_SUPPORTED|OLECMDF_ENABLED);
3982     }
3983
3984     test_UIDeactivate();
3985     test_InPlaceDeactivate(unk, TRUE);
3986     test_Close(unk, FALSE);
3987
3988     if(view) {
3989         IOleDocumentView_Release(view);
3990         view = NULL;
3991     }
3992
3993     ref = IUnknown_Release(unk);
3994     ok(ref == 0, "ref=%d, expected 0\n", ref);
3995 }
3996
3997 static void register_protocol(void)
3998 {
3999     IInternetSession *session;
4000     HRESULT hres;
4001
4002     static const WCHAR wsz_winetest[] = {'w','i','n','e','t','e','s','t',0};
4003
4004     hres = CoInternetGetSession(0, &session, 0);
4005     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
4006
4007     hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL,
4008             wsz_winetest, 0, NULL, 0);
4009     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
4010
4011     IInternetSession_Release(session);
4012 }
4013
4014 static void gecko_installer_workaround(BOOL disable)
4015 {
4016     HKEY hkey;
4017     DWORD res;
4018
4019     static BOOL has_url = FALSE;
4020     static char url[2048];
4021
4022     if(!disable && !has_url)
4023         return;
4024
4025     res = RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\MSHTML", &hkey);
4026     if(res != ERROR_SUCCESS)
4027         return;
4028
4029     if(disable) {
4030         DWORD type, size = sizeof(url);
4031
4032         res = RegQueryValueEx(hkey, "GeckoUrl", NULL, &type, (PVOID)url, &size);
4033         if(res == ERROR_SUCCESS && type == REG_SZ)
4034             has_url = TRUE;
4035
4036         RegDeleteValue(hkey, "GeckoUrl");
4037     }else {
4038         RegSetValueEx(hkey, "GeckoUrl", 0, REG_SZ, (PVOID)url, lstrlenA(url)+1);
4039     }
4040
4041     RegCloseKey(hkey);
4042 }
4043
4044 START_TEST(htmldoc)
4045 {
4046     gecko_installer_workaround(TRUE);
4047
4048     CoInitialize(NULL);
4049     container_hwnd = create_container_window();
4050     register_protocol();
4051
4052     test_HTMLDocument(FALSE);
4053     test_HTMLDocument(TRUE);
4054     test_HTMLDocument_hlink();
4055     test_HTMLDocument_StreamLoad();
4056     test_editing_mode(FALSE);
4057     test_editing_mode(TRUE);
4058
4059     DestroyWindow(container_hwnd);
4060     CoUninitialize();
4061
4062     gecko_installer_workaround(FALSE);
4063 }