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