shdocvw: Return correct error from WebBrowser::Quit.
[wine] / dlls / shdocvw / tests / webbrowser.c
1 /*
2  * Copyright 2006 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
25 #include "windef.h"
26 #include "winbase.h"
27 #include "ole2.h"
28 #include "exdisp.h"
29 #include "htiframe.h"
30 #include "mshtmhst.h"
31 #include "idispids.h"
32 #include "olectl.h"
33 #include "mshtmdid.h"
34
35 #define DEFINE_EXPECT(func) \
36     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
37
38 #define SET_EXPECT(func) \
39     expect_ ## func = TRUE
40
41 #define CHECK_EXPECT(func) \
42     do { \
43         ok(expect_ ##func, "unexpected call " #func "\n"); \
44         expect_ ## func = FALSE; \
45         called_ ## func = TRUE; \
46     }while(0)
47
48 #define CHECK_EXPECT2(func) \
49     do { \
50         ok(expect_ ##func, "unexpected call " #func "\n"); \
51         called_ ## func = TRUE; \
52     }while(0)
53
54 #define CHECK_CALLED(func) \
55     do { \
56         ok(called_ ## func, "expected " #func "\n"); \
57         expect_ ## func = called_ ## func = FALSE; \
58     }while(0)
59
60 DEFINE_EXPECT(GetContainer);
61 DEFINE_EXPECT(Site_GetWindow);
62 DEFINE_EXPECT(ShowObject);
63 DEFINE_EXPECT(CanInPlaceActivate);
64 DEFINE_EXPECT(OnInPlaceActivate);
65 DEFINE_EXPECT(OnUIActivate);
66 DEFINE_EXPECT(GetWindowContext);
67 DEFINE_EXPECT(Frame_GetWindow);
68 DEFINE_EXPECT(Frame_SetActiveObject);
69 DEFINE_EXPECT(UIWindow_SetActiveObject);
70 DEFINE_EXPECT(SetMenu);
71 DEFINE_EXPECT(Invoke_AMBIENT_USERMODE);
72 DEFINE_EXPECT(Invoke_AMBIENT_DLCONTROL);
73 DEFINE_EXPECT(Invoke_AMBIENT_USERAGENT);
74 DEFINE_EXPECT(Invoke_AMBIENT_PALETTE);
75 DEFINE_EXPECT(Invoke_AMBIENT_SILENT);
76 DEFINE_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
77 DEFINE_EXPECT(EnableModeless_TRUE);
78 DEFINE_EXPECT(EnableModeless_FALSE);
79 DEFINE_EXPECT(GetHostInfo);
80 DEFINE_EXPECT(GetOptionKeyPath);
81 DEFINE_EXPECT(GetOverridesKeyPath);
82 DEFINE_EXPECT(SetStatusText);
83 DEFINE_EXPECT(UpdateUI);
84
85 static const WCHAR wszItem[] = {'i','t','e','m',0};
86
87 static HWND container_hwnd, shell_embedding_hwnd;
88
89 static HRESULT QueryInterface(REFIID,void**);
90
91 static HRESULT WINAPI OleContainer_QueryInterface(IOleContainer *iface, REFIID riid, void **ppv)
92 {
93     if(IsEqualGUID(&IID_ITargetContainer, riid))
94         return E_NOINTERFACE; /* TODO */
95     if(IsEqualGUID(&IID_IOleCommandTarget, riid))
96         return E_NOINTERFACE; /* TODO */
97
98     ok(0, "unexpected call\n");
99     return E_NOINTERFACE;
100 }
101
102 static ULONG WINAPI OleContainer_AddRef(IOleContainer *iface)
103 {
104     return 2;
105 }
106
107 static ULONG WINAPI OleContainer_Release(IOleContainer *iface)
108 {
109     return 1;
110 }
111
112 static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer *iface, IBindCtx *pbc,
113         LPOLESTR pszDiaplayName, ULONG *pchEaten, IMoniker **ppmkOut)
114 {
115     ok(0, "unexpected call\n");
116     return E_NOTIMPL;
117 }
118
119 static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer *iface, DWORD grfFlags,
120         IEnumUnknown **ppenum)
121 {
122     ok(0, "unexpected call\n");
123     return E_NOTIMPL;
124 }
125
126 static HRESULT WINAPI OleContainer_LockContainer(IOleContainer *iface, BOOL fLock)
127 {
128     ok(0, "unexpected call\n");
129     return E_NOTIMPL;
130 }
131
132 static const IOleContainerVtbl OleContainerVtbl = {
133     OleContainer_QueryInterface,
134     OleContainer_AddRef,
135     OleContainer_Release,
136     OleContainer_ParseDisplayName,
137     OleContainer_EnumObjects,
138     OleContainer_LockContainer
139 };
140
141 static IOleContainer OleContainer = { &OleContainerVtbl };
142
143 static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
144 {
145     return QueryInterface(riid, ppv);
146 }
147
148 static ULONG WINAPI Dispatch_AddRef(IDispatch *iface)
149 {
150     return 2;
151 }
152
153 static ULONG WINAPI Dispatch_Release(IDispatch *iface)
154 {
155     return 1;
156 }
157
158 static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
159 {
160     ok(0, "unexpected call\n");
161     return E_NOTIMPL;
162 }
163
164 static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid,
165         ITypeInfo **ppTInfo)
166 {
167     ok(0, "unexpected call\n");
168     return E_NOTIMPL;
169 }
170
171 static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
172         UINT cNames, LCID lcid, DISPID *rgDispId)
173 {
174     ok(0, "unexpected call\n");
175     return E_NOTIMPL;
176 }
177
178 static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
179         LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
180         EXCEPINFO *pExcepInfo, UINT *puArgErr)
181 {
182     ok(IsEqualGUID(&IID_NULL, riid), "riid != IID_NULL\n");
183     ok(pDispParams != NULL, "pDispParams == NULL\n");
184     ok(pExcepInfo == NULL, "pExcepInfo=%p, expected NULL\n", pExcepInfo);
185     ok(V_VT(pVarResult) == VT_EMPTY, "V_VT(pVarResult)=%d\n", V_VT(pVarResult));
186     ok(wFlags == DISPATCH_PROPERTYGET, "wFlags=%08x, expected DISPATCH_PROPERTYGET\n", wFlags);
187     ok(pDispParams->rgvarg == NULL, "pDispParams->rgvarg = %p\n", pDispParams->rgvarg);
188     ok(pDispParams->rgdispidNamedArgs == NULL,
189        "pDispParams->rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
190     ok(pDispParams->cArgs == 0, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
191     ok(pDispParams->cNamedArgs == 0, "pDispParams->cNamedArgs = %d\n", pDispParams->cNamedArgs);
192
193     switch(dispIdMember) {
194     case DISPID_AMBIENT_USERMODE:
195         CHECK_EXPECT2(Invoke_AMBIENT_USERMODE);
196         return E_FAIL;
197     case DISPID_AMBIENT_DLCONTROL:
198         CHECK_EXPECT(Invoke_AMBIENT_DLCONTROL);
199         ok(puArgErr != NULL, "puArgErr=%p\n", puArgErr);
200         return E_FAIL;
201     case DISPID_AMBIENT_USERAGENT:
202        CHECK_EXPECT(Invoke_AMBIENT_USERAGENT);
203         ok(puArgErr != NULL, "puArgErr=%p\n", puArgErr);
204         return E_FAIL;
205     case DISPID_AMBIENT_PALETTE:
206         CHECK_EXPECT(Invoke_AMBIENT_PALETTE);
207         ok(puArgErr != NULL, "puArgErr=%p\n", puArgErr);
208         return E_FAIL;
209     case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
210         CHECK_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
211         ok(puArgErr == NULL, "puArgErr=%p\n", puArgErr);
212         V_VT(pVarResult) = VT_BOOL;
213         V_BOOL(pVarResult) = VARIANT_FALSE;
214         return S_OK;
215     case DISPID_AMBIENT_SILENT:
216         CHECK_EXPECT(Invoke_AMBIENT_SILENT);
217         ok(puArgErr == NULL, "puArgErr=%p\n", puArgErr);
218         V_VT(pVarResult) = VT_BOOL;
219         V_BOOL(pVarResult) = VARIANT_FALSE;
220         return S_OK;
221     }
222
223     ok(0, "unexpected dispIdMember %d\n", dispIdMember);
224     return E_NOTIMPL;
225 }
226
227 static IDispatchVtbl DispatchVtbl = {
228     Dispatch_QueryInterface,
229     Dispatch_AddRef,
230     Dispatch_Release,
231     Dispatch_GetTypeInfoCount,
232     Dispatch_GetTypeInfo,
233     Dispatch_GetIDsOfNames,
234     Dispatch_Invoke
235 };
236
237 static IDispatch Dispatch = { &DispatchVtbl };
238
239 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
240 {
241     return QueryInterface(riid, ppv);
242 }
243
244 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
245 {
246     return 2;
247 }
248
249 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
250 {
251     return 1;
252 }
253
254 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
255 {
256     ok(0, "unexpected call\n");
257     return E_NOTIMPL;
258 }
259
260 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAsign, DWORD dwWhichMoniker,
261         IMoniker **ppmon)
262 {
263     ok(0, "unexpected call\n");
264     return E_NOTIMPL;
265 }
266
267 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
268 {
269     CHECK_EXPECT(GetContainer);
270
271     ok(ppContainer != NULL, "ppContainer == NULL\n");
272     if(ppContainer)
273         *ppContainer = &OleContainer;
274
275     return S_OK;
276 }
277
278 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
279 {
280     CHECK_EXPECT(ShowObject);
281     return S_OK;
282 }
283
284 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
285 {
286     ok(0, "unexpected call\n");
287     return E_NOTIMPL;
288 }
289
290 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
291 {
292     ok(0, "unexpected call\n");
293     return E_NOTIMPL;
294 }
295
296 static const IOleClientSiteVtbl ClientSiteVtbl = {
297     ClientSite_QueryInterface,
298     ClientSite_AddRef,
299     ClientSite_Release,
300     ClientSite_SaveObject,
301     ClientSite_GetMoniker,
302     ClientSite_GetContainer,
303     ClientSite_ShowObject,
304     ClientSite_OnShowWindow,
305     ClientSite_RequestNewObjectLayout
306 };
307
308 static IOleClientSite ClientSite = { &ClientSiteVtbl };
309
310 static HRESULT WINAPI InPlaceUIWindow_QueryInterface(IOleInPlaceFrame *iface,
311                                                      REFIID riid, void **ppv)
312 {
313     ok(0, "unexpected call\n");
314     return E_NOINTERFACE;
315 }
316
317 static ULONG WINAPI InPlaceUIWindow_AddRef(IOleInPlaceFrame *iface)
318 {
319     return 2;
320 }
321
322 static ULONG WINAPI InPlaceUIWindow_Release(IOleInPlaceFrame *iface)
323 {
324     return 1;
325 }
326
327 static HRESULT WINAPI InPlaceUIWindow_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
328 {
329     ok(0, "unexpected call\n");
330     return E_NOTIMPL;
331 }
332
333 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
334 {
335     CHECK_EXPECT(Frame_GetWindow);
336     ok(phwnd != NULL, "phwnd == NULL\n");
337     if(phwnd)
338         *phwnd = container_hwnd;
339     return S_OK;
340 }
341
342 static HRESULT WINAPI InPlaceUIWindow_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
343 {
344     ok(0, "unexpected call\n");
345     return E_NOTIMPL;
346 }
347
348 static HRESULT WINAPI InPlaceUIWindow_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
349 {
350     ok(0, "unexpected call\n");
351     return E_NOTIMPL;
352 }
353
354 static HRESULT WINAPI InPlaceUIWindow_RequestBorderSpace(IOleInPlaceFrame *iface,
355         LPCBORDERWIDTHS pborderwidths)
356 {
357     ok(0, "unexpected call\n");
358     return E_NOTIMPL;
359 }
360
361 static HRESULT WINAPI InPlaceUIWindow_SetBorderSpace(IOleInPlaceFrame *iface,
362         LPCBORDERWIDTHS pborderwidths)
363 {
364     ok(0, "unexpected call\n");
365     return E_NOTIMPL;
366 }
367
368 static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceFrame *iface,
369         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
370 {
371     CHECK_EXPECT(UIWindow_SetActiveObject);
372     ok(pActiveObject != NULL, "pActiveObject = NULL\n");
373     ok(!lstrcmpW(pszObjName, wszItem), "unexpected pszObjName\n");
374     return S_OK;
375 }
376
377 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
378         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
379 {
380     CHECK_EXPECT(Frame_SetActiveObject);
381     ok(pActiveObject != NULL, "pActiveObject = NULL\n");
382     ok(!lstrcmpW(pszObjName, wszItem), "unexpected pszObjName\n");
383     return S_OK;
384 }
385
386 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
387         LPOLEMENUGROUPWIDTHS lpMenuWidths)
388 {
389     ok(0, "unexpected call\n");
390     return E_NOTIMPL;
391 }
392
393 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
394         HOLEMENU holemenu, HWND hwndActiveObject)
395 {
396     CHECK_EXPECT(SetMenu);
397     ok(hmenuShared == NULL, "hmenuShared=%p\n", hmenuShared);
398     ok(holemenu == NULL, "holemenu=%p\n", holemenu);
399     ok(hwndActiveObject == shell_embedding_hwnd, "hwndActiveObject=%p, expected %p\n",
400        hwndActiveObject, shell_embedding_hwnd);
401     return S_OK;
402 }
403
404 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
405 {
406     ok(0, "unexpected call\n");
407     return E_NOTIMPL;
408 }
409
410 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
411 {
412     CHECK_EXPECT2(SetStatusText);
413     /* FIXME: Check pszStatusText */
414     return S_OK;
415 }
416
417 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
418 {
419     if(fEnable)
420         CHECK_EXPECT(EnableModeless_TRUE);
421     else
422         CHECK_EXPECT(EnableModeless_FALSE);
423     return S_OK;
424 }
425
426 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
427 {
428     ok(0, "unexpected call\n");
429     return E_NOTIMPL;
430 }
431
432 static const IOleInPlaceFrameVtbl InPlaceUIWindowVtbl = {
433     InPlaceUIWindow_QueryInterface,
434     InPlaceUIWindow_AddRef,
435     InPlaceUIWindow_Release,
436     InPlaceUIWindow_GetWindow,
437     InPlaceUIWindow_ContextSensitiveHelp,
438     InPlaceUIWindow_GetBorder,
439     InPlaceUIWindow_RequestBorderSpace,
440     InPlaceUIWindow_SetBorderSpace,
441     InPlaceUIWindow_SetActiveObject,
442 };
443
444 static IOleInPlaceUIWindow InPlaceUIWindow = { (IOleInPlaceUIWindowVtbl*)&InPlaceUIWindowVtbl };
445
446 static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
447     InPlaceUIWindow_QueryInterface,
448     InPlaceUIWindow_AddRef,
449     InPlaceUIWindow_Release,
450     InPlaceFrame_GetWindow,
451     InPlaceUIWindow_ContextSensitiveHelp,
452     InPlaceUIWindow_GetBorder,
453     InPlaceUIWindow_RequestBorderSpace,
454     InPlaceUIWindow_SetBorderSpace,
455     InPlaceFrame_SetActiveObject,
456     InPlaceFrame_InsertMenus,
457     InPlaceFrame_SetMenu,
458     InPlaceFrame_RemoveMenus,
459     InPlaceFrame_SetStatusText,
460     InPlaceFrame_EnableModeless,
461     InPlaceFrame_TranslateAccelerator
462 };
463
464 static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
465
466 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSiteEx *iface, REFIID riid, void **ppv)
467 {
468     return QueryInterface(riid, ppv);
469 }
470
471 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSiteEx *iface)
472 {
473     return 2;
474 }
475
476 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSiteEx *iface)
477 {
478     return 1;
479 }
480
481 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwnd)
482 {
483     CHECK_EXPECT(Site_GetWindow);
484     ok(phwnd != NULL, "phwnd == NULL\n");
485     if(phwnd)
486         *phwnd = container_hwnd;
487     return S_OK;
488 }
489
490 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx *iface, BOOL fEnterMode)
491 {
492     ok(0, "unexpected call\n");
493     return E_NOTIMPL;
494 }
495
496 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx *iface)
497 {
498     CHECK_EXPECT(CanInPlaceActivate);
499     return S_OK;
500 }
501
502 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx *iface)
503 {
504     CHECK_EXPECT(OnInPlaceActivate);
505     return S_OK;
506 }
507
508 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSiteEx *iface)
509 {
510     CHECK_EXPECT(OnUIActivate);
511     return S_OK;
512 }
513
514 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface,
515         IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
516         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
517 {
518     static const RECT pos_rect = {2,1,1002,901};
519     static const RECT clip_rect = {10,10,990,890};
520
521     CHECK_EXPECT(GetWindowContext);
522
523     ok(ppFrame != NULL, "ppFrame = NULL\n");
524     if(ppFrame)
525         *ppFrame = &InPlaceFrame;
526
527     ok(ppDoc != NULL, "ppDoc = NULL\n");
528     if(ppDoc)
529         *ppDoc = &InPlaceUIWindow;
530
531     ok(lprcPosRect != NULL, "lprcPosRect = NULL\n");
532     if(lprcPosRect)
533         memcpy(lprcPosRect, &pos_rect, sizeof(RECT));
534
535     ok(lprcClipRect != NULL, "lprcClipRect = NULL\n");
536     if(lprcClipRect)
537         memcpy(lprcClipRect, &clip_rect, sizeof(RECT));
538
539     ok(lpFrameInfo != NULL, "lpFrameInfo = NULL\n");
540     if(lpFrameInfo) {
541         lpFrameInfo->cb = sizeof(*lpFrameInfo);
542         lpFrameInfo->fMDIApp = FALSE;
543         lpFrameInfo->hwndFrame = container_hwnd;
544         lpFrameInfo->haccel = NULL;
545         lpFrameInfo->cAccelEntries = 0;
546     }
547
548     return S_OK;
549 }
550
551 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSiteEx *iface, SIZE scrollExtant)
552 {
553     ok(0, "unexpected call\n");
554     return E_NOTIMPL;
555 }
556
557 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx *iface, BOOL fUndoable)
558 {
559     ok(0, "unexpected call\n");
560     return E_NOTIMPL;
561 }
562
563 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx *iface)
564 {
565     ok(0, "unexpected call\n");
566     return E_NOTIMPL;
567 }
568
569 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSiteEx *iface)
570 {
571     ok(0, "unexpected call\n");
572     return E_NOTIMPL;
573 }
574
575 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx *iface)
576 {
577     ok(0, "unexpected call\n");
578     return E_NOTIMPL;
579 }
580
581 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSiteEx *iface, LPCRECT lprcPosRect)
582 {
583     ok(0, "unexpected call\n");
584     return E_NOTIMPL;
585 }
586
587 static HRESULT WINAPI InPlaceSite_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface,
588                                                       BOOL *pNoRedraw, DWORD dwFlags)
589 {
590     ok(0, "unexpected call\n");
591     return E_NOTIMPL;
592 }
593
594 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *iface,
595                                                         BOOL fNoRedraw)
596 {
597     ok(0, "unexpected call\n");
598     return E_NOTIMPL;
599 }
600
601 static HRESULT WINAPI InPlaceSite_RequestUIActivate(IOleInPlaceSiteEx *iface)
602 {
603     ok(0, "unexpected call\n");
604     return S_OK;
605 }
606
607 static const IOleInPlaceSiteExVtbl InPlaceSiteExVtbl = {
608     InPlaceSite_QueryInterface,
609     InPlaceSite_AddRef,
610     InPlaceSite_Release,
611     InPlaceSite_GetWindow,
612     InPlaceSite_ContextSensitiveHelp,
613     InPlaceSite_CanInPlaceActivate,
614     InPlaceSite_OnInPlaceActivate,
615     InPlaceSite_OnUIActivate,
616     InPlaceSite_GetWindowContext,
617     InPlaceSite_Scroll,
618     InPlaceSite_OnUIDeactivate,
619     InPlaceSite_OnInPlaceDeactivate,
620     InPlaceSite_DiscardUndoState,
621     InPlaceSite_DeactivateAndUndo,
622     InPlaceSite_OnPosRectChange,
623     InPlaceSite_OnInPlaceActivateEx,
624     InPlaceSite_OnInPlaceDeactivateEx,
625     InPlaceSite_RequestUIActivate
626 };
627
628 static IOleInPlaceSiteEx InPlaceSite = { &InPlaceSiteExVtbl };
629
630 static HRESULT WINAPI DocHostUIHandler_QueryInterface(IDocHostUIHandler2 *iface, REFIID riid, void **ppv)
631 {
632     return QueryInterface(riid, ppv);
633 }
634
635 static ULONG WINAPI DocHostUIHandler_AddRef(IDocHostUIHandler2 *iface)
636 {
637     return 2;
638 }
639
640 static ULONG WINAPI DocHostUIHandler_Release(IDocHostUIHandler2 *iface)
641 {
642     return 1;
643 }
644
645 static HRESULT WINAPI DocHostUIHandler_ShowContextMenu(IDocHostUIHandler2 *iface, DWORD dwID, POINT *ppt,
646         IUnknown *pcmdtReserved, IDispatch *pdicpReserved)
647 {
648     ok(0, "unexpected call %d %p %p %p\n", dwID, ppt, pcmdtReserved, pdicpReserved);
649     return S_FALSE;
650 }
651
652 static HRESULT WINAPI DocHostUIHandler_GetHostInfo(IDocHostUIHandler2 *iface, DOCHOSTUIINFO *pInfo)
653 {
654     CHECK_EXPECT(GetHostInfo);
655     ok(pInfo != NULL, "pInfo=NULL\n");
656     if(pInfo) {
657         ok(pInfo->cbSize == sizeof(DOCHOSTUIINFO), "pInfo->cbSize=%u\n", pInfo->cbSize);
658         ok(!pInfo->dwFlags, "pInfo->dwFlags=%08x, expected 0\n", pInfo->dwFlags);
659         ok(!pInfo->dwDoubleClick, "pInfo->dwDoubleClick=%08x, expected 0\n", pInfo->dwDoubleClick);
660         ok(!pInfo->pchHostCss, "pInfo->pchHostCss=%p, expected NULL\n", pInfo->pchHostCss);
661         ok(!pInfo->pchHostNS, "pInfo->pchhostNS=%p, expected NULL\n", pInfo->pchHostNS);
662     }
663     return E_FAIL;
664 }
665
666 static HRESULT WINAPI DocHostUIHandler_ShowUI(IDocHostUIHandler2 *iface, DWORD dwID,
667         IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget,
668         IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
669 {
670     ok(0, "unexpected call\n");
671     return E_NOTIMPL;
672 }
673
674 static HRESULT WINAPI DocHostUIHandler_HideUI(IDocHostUIHandler2 *iface)
675 {
676     ok(0, "unexpected call\n");
677     return E_NOTIMPL;
678 }
679
680 static HRESULT WINAPI DocHostUIHandler_UpdateUI(IDocHostUIHandler2 *iface)
681 {
682     CHECK_EXPECT(UpdateUI);
683     return E_NOTIMPL;
684 }
685
686 static HRESULT WINAPI DocHostUIHandler_EnableModeless(IDocHostUIHandler2 *iface, BOOL fEnable)
687 {
688     ok(0, "unexpected call\n");
689     return E_NOTIMPL;
690 }
691
692 static HRESULT WINAPI DocHostUIHandler_OnDocWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
693 {
694     ok(0, "unexpected call\n");
695     return E_NOTIMPL;
696 }
697
698 static HRESULT WINAPI DocHostUIHandler_OnFrameWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
699 {
700     ok(0, "unexpected call\n");
701     return E_NOTIMPL;
702 }
703
704 static HRESULT WINAPI DocHostUIHandler_ResizeBorder(IDocHostUIHandler2 *iface, LPCRECT prcBorder,
705         IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
706 {
707     ok(0, "unexpected call\n");
708     return E_NOTIMPL;
709 }
710
711 static HRESULT WINAPI DocHostUIHandler_TranslateAccelerator(IDocHostUIHandler2 *iface, LPMSG lpMsg,
712         const GUID *pguidCmdGroup, DWORD nCmdID)
713 {
714     ok(0, "unexpected call\n");
715     return E_NOTIMPL;
716 }
717
718 static HRESULT WINAPI DocHostUIHandler_GetOptionKeyPath(IDocHostUIHandler2 *iface,
719         LPOLESTR *pchKey, DWORD dw)
720 {
721     CHECK_EXPECT(GetOptionKeyPath);
722     ok(pchKey != NULL, "pchKey==NULL\n");
723     if(pchKey)
724         ok(*pchKey == NULL, "*pchKey=%p\n", *pchKey);
725     ok(!dw, "dw=%x\n", dw);
726     return E_NOTIMPL;
727 }
728
729 static HRESULT WINAPI DocHostUIHandler_GetDropTarget(IDocHostUIHandler2 *iface,
730         IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
731 {
732     ok(0, "unexpected call\n");
733     return E_NOTIMPL;
734 }
735
736 static HRESULT WINAPI DocHostUIHandler_GetExternal(IDocHostUIHandler2 *iface, IDispatch **ppDispatch)
737 {
738     ok(0, "unexpected call\n");
739     return E_NOTIMPL;
740 }
741
742 static HRESULT WINAPI DocHostUIHandler_TranslateUrl(IDocHostUIHandler2 *iface, DWORD dwTranslate,
743         OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
744 {
745     ok(0, "unexpected call\n");
746     return E_NOTIMPL;
747 }
748
749 static HRESULT WINAPI DocHostUIHandler_FilterDataObject(IDocHostUIHandler2 *iface, IDataObject *pDO,
750         IDataObject **ppPORet)
751 {
752     ok(0, "unexpected call\n");
753     return E_NOTIMPL;
754 }
755
756 static HRESULT WINAPI DocHostUIHandler_GetOverrideKeyPath(IDocHostUIHandler2 *iface,
757         LPOLESTR *pchKey, DWORD dw)
758 {
759     CHECK_EXPECT(GetOverridesKeyPath);
760     ok(pchKey != NULL, "pchKey==NULL\n");
761     if(pchKey)
762         ok(*pchKey == NULL, "*pchKey=%p\n", *pchKey);
763     ok(!dw, "dw=%x\n", dw);
764     return E_NOTIMPL;
765 }
766
767 static const IDocHostUIHandler2Vtbl DocHostUIHandlerVtbl = {
768     DocHostUIHandler_QueryInterface,
769     DocHostUIHandler_AddRef,
770     DocHostUIHandler_Release,
771     DocHostUIHandler_ShowContextMenu,
772     DocHostUIHandler_GetHostInfo,
773     DocHostUIHandler_ShowUI,
774     DocHostUIHandler_HideUI,
775     DocHostUIHandler_UpdateUI,
776     DocHostUIHandler_EnableModeless,
777     DocHostUIHandler_OnDocWindowActivate,
778     DocHostUIHandler_OnFrameWindowActivate,
779     DocHostUIHandler_ResizeBorder,
780     DocHostUIHandler_TranslateAccelerator,
781     DocHostUIHandler_GetOptionKeyPath,
782     DocHostUIHandler_GetDropTarget,
783     DocHostUIHandler_GetExternal,
784     DocHostUIHandler_TranslateUrl,
785     DocHostUIHandler_FilterDataObject,
786     DocHostUIHandler_GetOverrideKeyPath
787 };
788
789 static IDocHostUIHandler2 DocHostUIHandler = { &DocHostUIHandlerVtbl };
790
791 static HRESULT QueryInterface(REFIID riid, void **ppv)
792 {
793     *ppv = NULL;
794
795     if(IsEqualGUID(&IID_IUnknown, riid)
796             || IsEqualGUID(&IID_IOleClientSite, riid))
797         *ppv = &ClientSite;
798     else if(IsEqualGUID(&IID_IOleWindow, riid)
799             || IsEqualGUID(&IID_IOleInPlaceSite, riid)
800             || IsEqualGUID(&IID_IOleInPlaceSiteEx, riid))
801         *ppv = &InPlaceSite;
802     else if(IsEqualGUID(&IID_IDocHostUIHandler, riid)
803             || IsEqualGUID(&IID_IDocHostUIHandler2, riid))
804         *ppv = &DocHostUIHandler;
805     else if(IsEqualGUID(&IID_IDispatch, riid))
806         *ppv = &Dispatch;
807
808     if(*ppv)
809         return S_OK;
810
811     return E_NOINTERFACE;
812 }
813
814 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
815 {
816     return DefWindowProcW(hwnd, msg, wParam, lParam);
817 }
818
819 static HWND create_container_window(void)
820 {
821     static const WCHAR wszWebBrowserContainer[] =
822         {'W','e','b','B','r','o','w','s','e','r','C','o','n','t','a','i','n','e','r',0};
823     static WNDCLASSEXW wndclass = {
824         sizeof(WNDCLASSEXW),
825         0,
826         wnd_proc,
827         0, 0, NULL, NULL, NULL, NULL, NULL,
828         wszWebBrowserContainer,
829         NULL
830     };
831
832     RegisterClassExW(&wndclass);
833     return CreateWindowW(wszWebBrowserContainer, wszWebBrowserContainer,
834             WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
835             CW_USEDEFAULT, NULL, NULL, NULL, NULL);
836 }
837
838 static void test_DoVerb(IUnknown *unk)
839 {
840     IOleObject *oleobj;
841     RECT rect = {0,0,1000,1000};
842     HRESULT hres;
843
844     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
845     ok(hres == S_OK, "QueryInterface(IID_OleObject) failed: %08x\n", hres);
846     if(FAILED(hres))
847         return;
848
849     SET_EXPECT(CanInPlaceActivate);
850     SET_EXPECT(Site_GetWindow);
851     SET_EXPECT(OnInPlaceActivate);
852     SET_EXPECT(GetWindowContext);
853     SET_EXPECT(ShowObject);
854     SET_EXPECT(GetContainer);
855     SET_EXPECT(Frame_GetWindow);
856     SET_EXPECT(OnUIActivate);
857     SET_EXPECT(Frame_SetActiveObject);
858     SET_EXPECT(UIWindow_SetActiveObject);
859     SET_EXPECT(SetMenu);
860
861     hres = IOleObject_DoVerb(oleobj, OLEIVERB_SHOW, NULL, &ClientSite,
862                              0, (HWND)0xdeadbeef, &rect);
863     ok(hres == S_OK, "DoVerb failed: %08x\n", hres);
864
865     CHECK_CALLED(CanInPlaceActivate);
866     CHECK_CALLED(Site_GetWindow);
867     CHECK_CALLED(OnInPlaceActivate);
868     CHECK_CALLED(GetWindowContext);
869     CHECK_CALLED(ShowObject);
870     CHECK_CALLED(GetContainer);
871     CHECK_CALLED(Frame_GetWindow);
872     CHECK_CALLED(OnUIActivate);
873     CHECK_CALLED(Frame_SetActiveObject);
874     CHECK_CALLED(UIWindow_SetActiveObject);
875     CHECK_CALLED(SetMenu);
876
877     hres = IOleObject_DoVerb(oleobj, OLEIVERB_SHOW, NULL, &ClientSite,
878                            0, (HWND)0xdeadbeef, &rect);
879     ok(hres == S_OK, "DoVerb failed: %08x\n", hres);
880
881     IOleObject_Release(oleobj);
882 }
883
884 static void test_GetMiscStatus(IOleObject *oleobj)
885 {
886     DWORD st, i;
887     HRESULT hres;
888
889     for(i=0; i<10; i++) {
890         st = 0xdeadbeef;
891         hres = IOleObject_GetMiscStatus(oleobj, i, &st);
892         ok(hres == S_OK, "GetMiscStatus failed: %08x\n", hres);
893         ok(st == (OLEMISC_SETCLIENTSITEFIRST|OLEMISC_ACTIVATEWHENVISIBLE|OLEMISC_INSIDEOUT
894                   |OLEMISC_CANTLINKINSIDE|OLEMISC_RECOMPOSEONRESIZE),
895            "st=%08x, expected OLEMISC_SETCLIENTSITEFIRST|OLEMISC_ACTIVATEWHENVISIBLE|"
896            "OLEMISC_INSIDEOUT|OLEMISC_CANTLINKINSIDE|OLEMISC_RECOMPOSEONRESIZE)\n", st);
897     }
898 }
899
900 static void test_ClientSite(IUnknown *unk, IOleClientSite *client)
901 {
902     IOleObject *oleobj;
903     IOleInPlaceObject *inplace;
904     HWND hwnd;
905     HRESULT hres;
906
907     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
908     ok(hres == S_OK, "QueryInterface(IID_OleObject) failed: %08x\n", hres);
909     if(FAILED(hres))
910         return;
911
912     test_GetMiscStatus(oleobj);
913
914     hres = IUnknown_QueryInterface(unk, &IID_IOleInPlaceObject, (void**)&inplace);
915     ok(hres == S_OK, "QueryInterface(IID_OleInPlaceObject) failed: %08x\n", hres);
916     if(FAILED(hres)) {
917         IOleObject_Release(oleobj);
918         return;
919     }
920
921     hres = IOleInPlaceObject_GetWindow(inplace, &hwnd);
922     ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
923     ok((hwnd == NULL) ^ (client == NULL), "unexpected hwnd %p\n", hwnd);
924
925     if(client) {
926         SET_EXPECT(GetContainer);
927         SET_EXPECT(Site_GetWindow);
928         SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
929         SET_EXPECT(Invoke_AMBIENT_SILENT);
930     }
931
932     hres = IOleObject_SetClientSite(oleobj, client);
933     ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
934
935     if(client) {
936         CHECK_CALLED(GetContainer);
937         CHECK_CALLED(Site_GetWindow);
938         CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
939         CHECK_CALLED(Invoke_AMBIENT_SILENT);
940     }
941
942     hres = IOleInPlaceObject_GetWindow(inplace, &hwnd);
943     ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
944     ok((hwnd == NULL) == (client == NULL), "unexpected hwnd %p\n", hwnd);
945
946     shell_embedding_hwnd = hwnd;
947
948     IOleInPlaceObject_Release(inplace);
949     IOleObject_Release(oleobj);
950 }
951
952 static void test_ClassInfo(IUnknown *unk)
953 {
954     IProvideClassInfo2 *class_info;
955     GUID guid;
956     HRESULT hres;
957
958     hres = IUnknown_QueryInterface(unk, &IID_IProvideClassInfo2, (void**)&class_info);
959     ok(hres == S_OK, "QueryInterface(IID_IProvideClassInfo)  failed: %08x\n", hres);
960     if(FAILED(hres))
961         return;
962
963     hres = IProvideClassInfo2_GetGUID(class_info, GUIDKIND_DEFAULT_SOURCE_DISP_IID, &guid);
964     ok(hres == S_OK, "GetGUID failed: %08x\n", hres);
965     ok(IsEqualGUID(&DIID_DWebBrowserEvents2, &guid), "wrong guid\n");
966
967     hres = IProvideClassInfo2_GetGUID(class_info, 0, &guid);
968     ok(hres == E_FAIL, "GetGUID failed: %08x, expected E_FAIL\n", hres);
969     ok(IsEqualGUID(&IID_NULL, &guid), "wrong guid\n");
970
971     hres = IProvideClassInfo2_GetGUID(class_info, 2, &guid);
972     ok(hres == E_FAIL, "GetGUID failed: %08x, expected E_FAIL\n", hres);
973     ok(IsEqualGUID(&IID_NULL, &guid), "wrong guid\n");
974
975     hres = IProvideClassInfo2_GetGUID(class_info, GUIDKIND_DEFAULT_SOURCE_DISP_IID, NULL);
976     ok(hres == E_POINTER, "GetGUID failed: %08x, expected E_POINTER\n", hres);
977
978     hres = IProvideClassInfo2_GetGUID(class_info, 0, NULL);
979     ok(hres == E_POINTER, "GetGUID failed: %08x, expected E_POINTER\n", hres);
980
981     IProvideClassInfo2_Release(class_info);
982 }
983
984 static void test_ie_funcs(IUnknown *unk)
985 {
986     IWebBrowser2 *wb;
987     IDispatch *disp;
988     VARIANT_BOOL b;
989     int i;
990     long hwnd;
991     HRESULT hres;
992
993     hres = IUnknown_QueryInterface(unk, &IID_IWebBrowser2, (void**)&wb);
994     ok(hres == S_OK, "Could not get IWebBrowser2 interface: %08x\n", hres);
995     if(FAILED(hres))
996         return;
997
998     /* HWND */
999
1000     hwnd = 0xdeadbeef;
1001     hres = IWebBrowser2_get_HWND(wb, &hwnd);
1002     ok(hres == E_FAIL, "get_HWND failed: %08x, expected E_FAIL\n", hres);
1003     ok(hwnd == 0, "unexpected hwnd %lx\n", hwnd);
1004
1005     /* MenuBar */
1006
1007     hres = IWebBrowser2_get_MenuBar(wb, &b);
1008     ok(hres == S_OK, "get_MenuBar failed: %08x\n", hres);
1009     ok(b == VARIANT_TRUE, "b=%x\n", b);
1010
1011     hres = IWebBrowser2_put_MenuBar(wb, VARIANT_FALSE);
1012     ok(hres == S_OK, "put_MenuBar failed: %08x\n", hres);
1013
1014     hres = IWebBrowser2_get_MenuBar(wb, &b);
1015     ok(hres == S_OK, "get_MenuBar failed: %08x\n", hres);
1016     ok(b == VARIANT_FALSE, "b=%x\n", b);
1017
1018     hres = IWebBrowser2_put_MenuBar(wb, 100);
1019     ok(hres == S_OK, "put_MenuBar failed: %08x\n", hres);
1020
1021     hres = IWebBrowser2_get_MenuBar(wb, &b);
1022     ok(hres == S_OK, "get_MenuBar failed: %08x\n", hres);
1023     ok(b == VARIANT_TRUE, "b=%x\n", b);
1024
1025     /* AddressBar */
1026
1027     hres = IWebBrowser2_get_AddressBar(wb, &b);
1028     ok(hres == S_OK, "get_AddressBar failed: %08x\n", hres);
1029     ok(b == VARIANT_TRUE, "b=%x\n", b);
1030
1031     hres = IWebBrowser2_put_AddressBar(wb, VARIANT_FALSE);
1032     ok(hres == S_OK, "put_AddressBar failed: %08x\n", hres);
1033
1034     hres = IWebBrowser2_get_AddressBar(wb, &b);
1035     ok(hres == S_OK, "get_MenuBar failed: %08x\n", hres);
1036     ok(b == VARIANT_FALSE, "b=%x\n", b);
1037
1038     hres = IWebBrowser2_put_AddressBar(wb, 100);
1039     ok(hres == S_OK, "put_AddressBar failed: %08x\n", hres);
1040
1041     hres = IWebBrowser2_get_AddressBar(wb, &b);
1042     ok(hres == S_OK, "get_AddressBar failed: %08x\n", hres);
1043     ok(b == VARIANT_TRUE, "b=%x\n", b);
1044
1045     hres = IWebBrowser2_put_AddressBar(wb, VARIANT_TRUE);
1046     ok(hres == S_OK, "put_MenuBar failed: %08x\n", hres);
1047
1048     /* StatusBar */
1049
1050     hres = IWebBrowser2_get_StatusBar(wb, &b);
1051     ok(hres == S_OK, "get_StatusBar failed: %08x\n", hres);
1052     ok(b == VARIANT_TRUE, "b=%x\n", b);
1053
1054     hres = IWebBrowser2_put_StatusBar(wb, VARIANT_TRUE);
1055     ok(hres == S_OK, "put_StatusBar failed: %08x\n", hres);
1056
1057     hres = IWebBrowser2_get_StatusBar(wb, &b);
1058     ok(hres == S_OK, "get_StatusBar failed: %08x\n", hres);
1059     ok(b == VARIANT_TRUE, "b=%x\n", b);
1060
1061     hres = IWebBrowser2_put_StatusBar(wb, VARIANT_FALSE);
1062     ok(hres == S_OK, "put_StatusBar failed: %08x\n", hres);
1063
1064     hres = IWebBrowser2_get_StatusBar(wb, &b);
1065     ok(hres == S_OK, "get_StatusBar failed: %08x\n", hres);
1066     ok(b == VARIANT_FALSE, "b=%x\n", b);
1067
1068     hres = IWebBrowser2_put_StatusBar(wb, 100);
1069     ok(hres == S_OK, "put_StatusBar failed: %08x\n", hres);
1070
1071     hres = IWebBrowser2_get_StatusBar(wb, &b);
1072     ok(hres == S_OK, "get_StatusBar failed: %08x\n", hres);
1073     ok(b == VARIANT_TRUE, "b=%x\n", b);
1074
1075     /* ToolBar */
1076
1077     hres = IWebBrowser2_get_ToolBar(wb, &i);
1078     ok(hres == S_OK, "get_ToolBar failed: %08x\n", hres);
1079     ok(i, "i=%x\n", i);
1080
1081     hres = IWebBrowser2_put_ToolBar(wb, VARIANT_FALSE);
1082     ok(hres == S_OK, "put_ToolBar failed: %08x\n", hres);
1083
1084     hres = IWebBrowser2_get_ToolBar(wb, &i);
1085     ok(hres == S_OK, "get_ToolBar failed: %08x\n", hres);
1086     ok(i == VARIANT_FALSE, "b=%x\n", i);
1087
1088     hres = IWebBrowser2_put_ToolBar(wb, 100);
1089     ok(hres == S_OK, "put_ToolBar failed: %08x\n", hres);
1090
1091     hres = IWebBrowser2_get_ToolBar(wb, &i);
1092     ok(hres == S_OK, "get_ToolBar failed: %08x\n", hres);
1093     ok(i, "i=%x\n", i);
1094
1095     hres = IWebBrowser2_put_ToolBar(wb, VARIANT_TRUE);
1096     ok(hres == S_OK, "put_ToolBar failed: %08x\n", hres);
1097
1098     /* FullScreen */
1099
1100     hres = IWebBrowser2_get_FullScreen(wb, &b);
1101     ok(hres == S_OK, "get_FullScreen failed: %08x\n", hres);
1102     ok(b == VARIANT_FALSE, "b=%x\n", b);
1103
1104     hres = IWebBrowser2_put_FullScreen(wb, VARIANT_TRUE);
1105     ok(hres == S_OK, "put_FullScreen failed: %08x\n", hres);
1106
1107     hres = IWebBrowser2_get_FullScreen(wb, &b);
1108     ok(hres == S_OK, "get_FullScreen failed: %08x\n", hres);
1109     ok(b == VARIANT_TRUE, "b=%x\n", b);
1110
1111     hres = IWebBrowser2_put_FullScreen(wb, 100);
1112     ok(hres == S_OK, "put_FullScreen failed: %08x\n", hres);
1113
1114     hres = IWebBrowser2_get_FullScreen(wb, &b);
1115     ok(hres == S_OK, "get_FullScreen failed: %08x\n", hres);
1116     ok(b == VARIANT_TRUE, "b=%x\n", b);
1117
1118     hres = IWebBrowser2_put_FullScreen(wb, VARIANT_FALSE);
1119     ok(hres == S_OK, "put_FullScreen failed: %08x\n", hres);
1120
1121     /* Resizable */
1122
1123     b = 0x100;
1124     hres = IWebBrowser2_get_Resizable(wb, &b);
1125     ok(hres == E_NOTIMPL, "get_Resizable failed: %08x\n", hres);
1126     ok(b == 0x100, "b=%x\n", b);
1127
1128     hres = IWebBrowser2_put_Resizable(wb, VARIANT_TRUE);
1129     ok(hres == S_OK, "put_Resizable failed: %08x\n", hres);
1130
1131     hres = IWebBrowser2_put_Resizable(wb, VARIANT_FALSE);
1132     ok(hres == S_OK, "put_Resizable failed: %08x\n", hres);
1133
1134     hres = IWebBrowser2_get_Resizable(wb, &b);
1135     ok(hres == E_NOTIMPL, "get_Resizable failed: %08x\n", hres);
1136     ok(b == 0x100, "b=%x\n", b);
1137
1138     /* Application */
1139
1140     disp = NULL;
1141     hres = IWebBrowser2_get_Application(wb, &disp);
1142     ok(hres == S_OK, "get_Application failed: %08x\n", hres);
1143     ok(disp == (void*)wb, "disp=%p, expected %p\n", disp, wb);
1144     if(disp)
1145         IDispatch_Release(disp);
1146
1147     hres = IWebBrowser2_get_Application(wb, NULL);
1148     ok(hres == E_POINTER, "get_Application failed: %08x, expected E_POINTER\n", hres);
1149
1150     /* Quit */
1151
1152     hres = IWebBrowser2_Quit(wb);
1153     ok(hres == E_FAIL, "Quit failed: %08x, expected E_FAIL\n", hres);
1154
1155     IWebBrowser2_Release(wb);
1156 }
1157
1158 static void test_Silent(IWebBrowser2 *wb, IOleControl *control, BOOL is_clientsite)
1159 {
1160     VARIANT_BOOL b;
1161     HRESULT hres;
1162
1163     b = 100;
1164     hres = IWebBrowser2_get_Silent(wb, &b);
1165     ok(hres == S_OK, "get_Silent failed: %08x\n", hres);
1166     ok(b == VARIANT_FALSE, "b=%x\n", b);
1167
1168     hres = IWebBrowser2_put_Silent(wb, VARIANT_TRUE);
1169     ok(hres == S_OK, "set_Silent failed: %08x\n", hres);
1170
1171     b = 100;
1172     hres = IWebBrowser2_get_Silent(wb, &b);
1173     ok(hres == S_OK, "get_Silent failed: %08x\n", hres);
1174     ok(b == VARIANT_TRUE, "b=%x\n", b);
1175
1176     hres = IWebBrowser2_put_Silent(wb, 100);
1177     ok(hres == S_OK, "set_Silent failed: %08x\n", hres);
1178
1179     b = 100;
1180     hres = IWebBrowser2_get_Silent(wb, &b);
1181     ok(hres == S_OK, "get_Silent failed: %08x\n", hres);
1182     ok(b == VARIANT_TRUE, "b=%x\n", b);
1183
1184     hres = IWebBrowser2_put_Silent(wb, VARIANT_FALSE);
1185     ok(hres == S_OK, "set_Silent failed: %08x\n", hres);
1186
1187     b = 100;
1188     hres = IWebBrowser2_get_Silent(wb, &b);
1189     ok(hres == S_OK, "get_Silent failed: %08x\n", hres);
1190     ok(b == VARIANT_FALSE, "b=%x\n", b);
1191
1192     if(is_clientsite) {
1193         hres = IWebBrowser2_put_Silent(wb, VARIANT_TRUE);
1194         ok(hres == S_OK, "set_Silent failed: %08x\n", hres);
1195
1196         SET_EXPECT(Invoke_AMBIENT_SILENT);
1197     }
1198
1199     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_SILENT);
1200     ok(hres == S_OK, "OnAmbientPropertyChange failed %08x\n", hres);
1201
1202     if(is_clientsite)
1203         CHECK_CALLED(Invoke_AMBIENT_SILENT);
1204
1205     b = 100;
1206     hres = IWebBrowser2_get_Silent(wb, &b);
1207     ok(hres == S_OK, "get_Silent failed: %08x\n", hres);
1208     ok(b == VARIANT_FALSE, "b=%x\n", b);
1209 }
1210
1211 static void test_Offline(IWebBrowser2 *wb, IOleControl *control, BOOL is_clientsite)
1212 {
1213     VARIANT_BOOL b;
1214     HRESULT hres;
1215
1216     b = 100;
1217     hres = IWebBrowser2_get_Offline(wb, &b);
1218     ok(hres == S_OK, "get_Offline failed: %08x\n", hres);
1219     ok(b == VARIANT_FALSE, "b=%x\n", b);
1220
1221     hres = IWebBrowser2_put_Offline(wb, VARIANT_TRUE);
1222     ok(hres == S_OK, "set_Offline failed: %08x\n", hres);
1223
1224     b = 100;
1225     hres = IWebBrowser2_get_Offline(wb, &b);
1226     ok(hres == S_OK, "get_Offline failed: %08x\n", hres);
1227     ok(b == VARIANT_TRUE, "b=%x\n", b);
1228
1229     hres = IWebBrowser2_put_Offline(wb, 100);
1230     ok(hres == S_OK, "set_Offline failed: %08x\n", hres);
1231
1232     b = 100;
1233     hres = IWebBrowser2_get_Offline(wb, &b);
1234     ok(hres == S_OK, "get_Offline failed: %08x\n", hres);
1235     ok(b == VARIANT_TRUE, "b=%x\n", b);
1236
1237     hres = IWebBrowser2_put_Offline(wb, VARIANT_FALSE);
1238     ok(hres == S_OK, "set_Offline failed: %08x\n", hres);
1239
1240     b = 100;
1241     hres = IWebBrowser2_get_Offline(wb, &b);
1242     ok(hres == S_OK, "get_Offline failed: %08x\n", hres);
1243     ok(b == VARIANT_FALSE, "b=%x\n", b);
1244
1245     if(is_clientsite) {
1246         hres = IWebBrowser2_put_Offline(wb, VARIANT_TRUE);
1247         ok(hres == S_OK, "set_Offline failed: %08x\n", hres);
1248
1249         SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
1250     }
1251
1252     hres = IOleControl_OnAmbientPropertyChange(control, DISPID_AMBIENT_OFFLINEIFNOTCONNECTED);
1253     ok(hres == S_OK, "OnAmbientPropertyChange failed %08x\n", hres);
1254
1255     if(is_clientsite)
1256         CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
1257
1258     b = 100;
1259     hres = IWebBrowser2_get_Offline(wb, &b);
1260     ok(hres == S_OK, "get_Offline failed: %08x\n", hres);
1261     ok(b == VARIANT_FALSE, "b=%x\n", b);
1262 }
1263
1264 static void test_wb_funcs(IUnknown *unk, BOOL is_clientsite)
1265 {
1266     IWebBrowser2 *wb;
1267     IOleControl *control;
1268     HRESULT hres;
1269
1270     hres = IUnknown_QueryInterface(unk, &IID_IWebBrowser2, (void**)&wb);
1271     ok(hres == S_OK, "Could not get IWebBrowser2 interface: %08x\n", hres);
1272
1273     hres = IUnknown_QueryInterface(unk, &IID_IOleControl, (void**)&control);
1274     ok(hres == S_OK, "Could not get IOleControl interface: %08x\n", hres);
1275
1276     test_Silent(wb, control, is_clientsite);
1277     test_Offline(wb, control, is_clientsite);
1278
1279     IWebBrowser_Release(wb);
1280     IOleControl_Release(control);
1281 }
1282
1283 static void test_GetControlInfo(IUnknown *unk)
1284 {
1285     IOleControl *control;
1286     CONTROLINFO info;
1287     HRESULT hres;
1288
1289     hres = IUnknown_QueryInterface(unk, &IID_IOleControl, (void**)&control);
1290     ok(hres == S_OK, "Could not get IOleControl: %08x\n", hres);
1291     if(FAILED(hres))
1292         return;
1293
1294     hres = IOleControl_GetControlInfo(control, &info);
1295     ok(hres == E_NOTIMPL, "GetControlInfo failed: %08x, exxpected E_NOTIMPL\n", hres);
1296     hres = IOleControl_GetControlInfo(control, NULL);
1297     ok(hres == E_NOTIMPL, "GetControlInfo failed: %08x, exxpected E_NOTIMPL\n", hres);
1298
1299     IOleControl_Release(control);
1300 }
1301
1302 static void test_Extent(IUnknown *unk)
1303 {
1304     IOleObject *oleobj;
1305     SIZE size;
1306     HRESULT hres;
1307
1308     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
1309     ok(hres == S_OK, "Could not get IOleObkect: %08x\n", hres);
1310     if(FAILED(hres))
1311         return;
1312
1313     size.cx = size.cy = 0xdeadbeef;
1314     hres = IOleObject_GetExtent(oleobj, DVASPECT_CONTENT, &size);
1315     ok(hres == S_OK, "GetExtent failed: %08x\n", hres);
1316     ok(size.cx == 1323 && size.cy == 529, "size = {%d %d}\n", size.cx, size.cy);
1317
1318     size.cx = 800;
1319     size.cy = 700;
1320     hres = IOleObject_SetExtent(oleobj, DVASPECT_CONTENT, &size);
1321     ok(hres == S_OK, "SetExtent failed: %08x\n", hres);
1322
1323     size.cx = size.cy = 0xdeadbeef;
1324     hres = IOleObject_GetExtent(oleobj, DVASPECT_CONTENT, &size);
1325     ok(hres == S_OK, "GetExtent failed: %08x\n", hres);
1326     ok(size.cx == 800 && size.cy == 700, "size = {%d %d}\n", size.cx, size.cy);
1327
1328     size.cx = size.cy = 0xdeadbeef;
1329     hres = IOleObject_GetExtent(oleobj, 0, &size);
1330     ok(hres == S_OK, "GetExtent failed: %08x\n", hres);
1331     ok(size.cx == 800 && size.cy == 700, "size = {%d %d}\n", size.cx, size.cy);
1332
1333     size.cx = 900;
1334     size.cy = 800;
1335     hres = IOleObject_SetExtent(oleobj, 0, &size);
1336     ok(hres == S_OK, "SetExtent failed: %08x\n", hres);
1337
1338     size.cx = size.cy = 0xdeadbeef;
1339     hres = IOleObject_GetExtent(oleobj, 0, &size);
1340     ok(hres == S_OK, "GetExtent failed: %08x\n", hres);
1341     ok(size.cx == 900 && size.cy == 800, "size = {%d %d}\n", size.cx, size.cy);
1342
1343     size.cx = size.cy = 0xdeadbeef;
1344     hres = IOleObject_GetExtent(oleobj, 0xdeadbeef, &size);
1345     ok(hres == S_OK, "GetExtent failed: %08x\n", hres);
1346     ok(size.cx == 900 && size.cy == 800, "size = {%d %d}\n", size.cx, size.cy);
1347
1348     size.cx = 1000;
1349     size.cy = 900;
1350     hres = IOleObject_SetExtent(oleobj, 0xdeadbeef, &size);
1351     ok(hres == S_OK, "SetExtent failed: %08x\n", hres);
1352
1353     size.cx = size.cy = 0xdeadbeef;
1354     hres = IOleObject_GetExtent(oleobj, 0xdeadbeef, &size);
1355     ok(hres == S_OK, "GetExtent failed: %08x\n", hres);
1356     ok(size.cx == 1000 && size.cy == 900, "size = {%d %d}\n", size.cx, size.cy);
1357
1358     size.cx = size.cy = 0xdeadbeef;
1359     hres = IOleObject_GetExtent(oleobj, DVASPECT_CONTENT, &size);
1360     ok(hres == S_OK, "GetExtent failed: %08x\n", hres);
1361     ok(size.cx == 1000 && size.cy == 900, "size = {%d %d}\n", size.cx, size.cy);
1362
1363     IOleObject_Release(oleobj);
1364 }
1365
1366 static void test_Navigate2(IUnknown *unk)
1367 {
1368     IWebBrowser2 *webbrowser;
1369     VARIANT url;
1370     HRESULT hres;
1371
1372     static const WCHAR wszAboutBlank[] =
1373         {'a','b','o','u','t',':','b','l','a','n','k',0};
1374
1375     hres = IUnknown_QueryInterface(unk, &IID_IWebBrowser2, (void**)&webbrowser);
1376     ok(hres == S_OK, "QueryInterface(IID_IWebBrowser) failed: %08x\n", hres);
1377     if(FAILED(hres))
1378         return;
1379
1380     V_VT(&url) = VT_BSTR;
1381     V_BSTR(&url) = SysAllocString(wszAboutBlank);
1382
1383     SET_EXPECT(Invoke_AMBIENT_USERMODE);
1384     SET_EXPECT(EnableModeless_FALSE);
1385     SET_EXPECT(GetHostInfo);
1386     SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
1387     SET_EXPECT(Invoke_AMBIENT_USERAGENT);
1388     SET_EXPECT(Invoke_AMBIENT_PALETTE);
1389     SET_EXPECT(GetOptionKeyPath);
1390     SET_EXPECT(GetOverridesKeyPath);
1391     SET_EXPECT(SetStatusText);
1392     SET_EXPECT(EnableModeless_TRUE);
1393
1394     hres = IWebBrowser2_Navigate2(webbrowser, &url, NULL, NULL, NULL, NULL);
1395     ok(hres == S_OK, "Navigate2 failed: %08x\n", hres);
1396
1397     CHECK_CALLED(Invoke_AMBIENT_USERMODE);
1398     CHECK_CALLED(EnableModeless_FALSE);
1399     CHECK_CALLED(GetHostInfo);
1400     CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
1401     CHECK_CALLED(Invoke_AMBIENT_USERAGENT);
1402     CHECK_CALLED(Invoke_AMBIENT_PALETTE);
1403     CHECK_CALLED(GetOptionKeyPath);
1404     CHECK_CALLED(GetOverridesKeyPath);
1405     CHECK_CALLED(SetStatusText);
1406     CHECK_CALLED(EnableModeless_TRUE);
1407
1408     IWebBrowser2_Release(webbrowser);
1409 }
1410
1411 static void test_QueryInterface(IUnknown *unk)
1412 {
1413     IQuickActivate *qa = (IQuickActivate*)0xdeadbeef;
1414     IRunnableObject *runnable = (IRunnableObject*)0xdeadbeef;
1415     HRESULT hres;
1416
1417     hres = IUnknown_QueryInterface(unk, &IID_IQuickActivate, (void**)&qa);
1418     ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
1419     ok(qa == NULL, "qa=%p, ezpected NULL\n", qa);
1420
1421     hres = IUnknown_QueryInterface(unk, &IID_IRunnableObject, (void**)&runnable);
1422     ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
1423     ok(runnable == NULL, "runnable=%p, ezpected NULL\n", runnable);
1424 }
1425
1426 static void test_WebBrowser(void)
1427 {
1428     IUnknown *unk = NULL;
1429     ULONG ref;
1430     HRESULT hres;
1431
1432     hres = CoCreateInstance(&CLSID_WebBrowser, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1433             &IID_IUnknown, (void**)&unk);
1434     ok(hres == S_OK, "CoCreateInterface failed: %08x\n", hres);
1435     if(FAILED(hres))
1436         return;
1437
1438     test_QueryInterface(unk);
1439     test_ClassInfo(unk);
1440     test_ClientSite(unk, &ClientSite);
1441     test_Extent(unk);
1442     test_wb_funcs(unk, TRUE);
1443     test_DoVerb(unk);
1444     test_Navigate2(unk);
1445     test_ClientSite(unk, NULL);
1446     test_ie_funcs(unk);
1447     test_GetControlInfo(unk);
1448     test_wb_funcs(unk, FALSE);
1449
1450     ref = IUnknown_Release(unk);
1451     ok(ref == 0, "ref=%d, expected 0\n", ref);
1452 }
1453
1454 static void gecko_installer_workaround(BOOL disable)
1455 {
1456     HKEY hkey;
1457     DWORD res;
1458
1459     static BOOL has_url = FALSE;
1460     static char url[2048];
1461
1462     if(!disable && !has_url)
1463         return;
1464
1465     res = RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\MSHTML", &hkey);
1466     if(res != ERROR_SUCCESS)
1467         return;
1468
1469     if(disable) {
1470         DWORD type, size = sizeof(url);
1471
1472         res = RegQueryValueEx(hkey, "GeckoUrl", NULL, &type, (PVOID)url, &size);
1473         if(res == ERROR_SUCCESS && type == REG_SZ)
1474             has_url = TRUE;
1475
1476         RegDeleteValue(hkey, "GeckoUrl");
1477     }else {
1478         RegSetValueEx(hkey, "GeckoUrl", 0, REG_SZ, (PVOID)url, lstrlenA(url)+1);
1479     }
1480
1481     RegCloseKey(hkey);
1482 }
1483
1484 START_TEST(webbrowser)
1485 {
1486     gecko_installer_workaround(TRUE);
1487
1488     container_hwnd = create_container_window();
1489
1490     OleInitialize(NULL);
1491
1492     test_WebBrowser();
1493
1494     OleUninitialize();
1495
1496     gecko_installer_workaround(FALSE);
1497 }