dinput: Stub IDirectInputJoyConfig8 interface.
[wine] / dlls / mshtml / tests / activex.c
1 /*
2  * Copyright 2010 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "mshtml.h"
30 #include "docobj.h"
31 #include "hlink.h"
32 #include "dispex.h"
33 #include "mshtmhst.h"
34 #include "activscp.h"
35 #include "objsafe.h"
36 #include "mshtmdid.h"
37 #include "mshtml_test.h"
38
39 #define DEFINE_EXPECT(func) \
40     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
41
42 #define SET_EXPECT(func) \
43     do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
44
45 #define CHECK_EXPECT2(func) \
46     do { \
47         ok(expect_ ##func, "unexpected call " #func "\n"); \
48         called_ ## func = TRUE; \
49     }while(0)
50
51 #define CHECK_EXPECT(func) \
52     do { \
53         CHECK_EXPECT2(func); \
54         expect_ ## func = FALSE; \
55     }while(0)
56
57 #define CHECK_CALLED(func) \
58     do { \
59         ok(called_ ## func, "expected " #func "\n"); \
60         expect_ ## func = called_ ## func = FALSE; \
61     }while(0)
62
63 DEFINE_EXPECT(CreateInstance);
64 DEFINE_EXPECT(FreezeEvents_TRUE);
65 DEFINE_EXPECT(FreezeEvents_FALSE);
66 DEFINE_EXPECT(QuickActivate);
67 DEFINE_EXPECT(IPersistPropertyBag_InitNew);
68 DEFINE_EXPECT(IPersistPropertyBag_Load);
69 DEFINE_EXPECT(Invoke_READYSTATE);
70 DEFINE_EXPECT(Invoke_ENABLED);
71 DEFINE_EXPECT(Invoke_VALID);
72 DEFINE_EXPECT(Invoke_SECURITYCTX);
73 DEFINE_EXPECT(Invoke_SCRIPTPROP);
74 DEFINE_EXPECT(GetIDsOfNames_scriptprop);
75 DEFINE_EXPECT(DoVerb);
76 DEFINE_EXPECT(SetExtent);
77 DEFINE_EXPECT(GetExtent);
78 DEFINE_EXPECT(SetClientSite);
79 DEFINE_EXPECT(SetClientSite_NULL);
80 DEFINE_EXPECT(Close);
81 DEFINE_EXPECT(InPlaceObject_GetWindow);
82 DEFINE_EXPECT(SetObjectRects);
83 DEFINE_EXPECT(InPlaceDeactivate);
84 DEFINE_EXPECT(UIDeactivate);
85 DEFINE_EXPECT(QueryService_TestActiveX);
86 DEFINE_EXPECT(GetMiscStatus);
87 DEFINE_EXPECT(SetAdvise);
88 DEFINE_EXPECT(GetViewStatus);
89
90 #define DISPID_SCRIPTPROP 1000
91
92 enum {
93     TEST_FLASH,
94     TEST_NOQUICKACT
95 };
96
97 static HWND container_hwnd, plugin_hwnd;
98 static int plugin_behavior;
99
100 #define TESTACTIVEX_CLSID "{178fc163-f585-4e24-9c13-4bb7f6680746}"
101
102 static const GUID CLSID_TestActiveX =
103     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xf6,0x68,0x07,0x46}};
104
105 static const char object_ax_str[] =
106     "<html><head></head><body>"
107     "<object classid=\"clsid:" TESTACTIVEX_CLSID "\" width=\"300\" height=\"200\" id=\"objid\">"
108     "<param name=\"param_name\" value=\"param_value\">"
109     "<param name=\"num_param\" value=\"3\">"
110     "</object>"
111     "</body></html>";
112
113 static REFIID pluginhost_iids[] = {
114     &IID_IOleClientSite,
115     &IID_IAdviseSink,
116     &IID_IAdviseSinkEx,
117     &IID_IPropertyNotifySink,
118     &IID_IDispatch,
119     &IID_IOleWindow,
120     &IID_IOleInPlaceSite,
121     &IID_IOleInPlaceSiteEx,
122     &IID_IOleControlSite,
123     &IID_IBindHost,
124     &IID_IServiceProvider,
125     NULL
126 };
127
128 static const char *debugstr_guid(REFIID riid)
129 {
130     static char buf[50];
131
132     sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
133             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
134             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
135             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
136
137     return buf;
138 }
139
140 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
141 {
142     IUnknown *unk1, *unk2;
143
144     if(iface1 == iface2)
145         return TRUE;
146
147     IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
148     IUnknown_Release(unk1);
149     IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2);
150     IUnknown_Release(unk2);
151
152     return unk1 == unk2;
153 }
154
155 #define test_ifaces(i,ids) _test_ifaces(__LINE__,i,ids)
156 static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids)
157 {
158     const IID * const *piid;
159     IUnknown *unk;
160     HRESULT hres;
161
162      for(piid = iids; *piid; piid++) {
163         hres = IDispatch_QueryInterface(iface, *piid, (void**)&unk);
164         ok_(__FILE__,line) (hres == S_OK, "Could not get %s interface: %08x\n", debugstr_guid(*piid), hres);
165         if(SUCCEEDED(hres))
166             IUnknown_Release(unk);
167     }
168 }
169
170 static int strcmp_wa(LPCWSTR strw, const char *stra)
171 {
172     CHAR buf[512];
173     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
174     return lstrcmpA(stra, buf);
175 }
176
177 static BSTR a2bstr(const char *str)
178 {
179     BSTR ret;
180     int len;
181
182     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
183     ret = SysAllocStringLen(NULL, len);
184     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
185
186     return ret;
187 }
188
189 static IOleClientSite *client_site;
190 static READYSTATE plugin_readystate = READYSTATE_UNINITIALIZED;
191
192 static void set_plugin_readystate(READYSTATE state)
193 {
194     IPropertyNotifySink *prop_notif;
195     HRESULT hres;
196
197     plugin_readystate = state;
198
199     hres = IOleClientSite_QueryInterface(client_site, &IID_IPropertyNotifySink, (void**)&prop_notif);
200     ok(hres == S_OK, "Could not get IPropertyNotifySink iface: %08x\n", hres);
201
202     hres = IPropertyNotifySink_OnChanged(prop_notif, DISPID_READYSTATE);
203     ok(hres == S_OK, "OnChanged(DISPID_READYSTATE) failed: %08x\n", hres);
204
205     IPropertyNotifySink_Release(prop_notif);
206 }
207
208 static void test_mon_displayname(IMoniker *mon, const char *exname, const char *broken_name)
209 {
210     LPOLESTR display_name;
211     DWORD mksys;
212     HRESULT hres;
213
214     hres = IMoniker_GetDisplayName(mon, NULL, NULL, &display_name);
215     ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
216     ok(!strcmp_wa(display_name, exname) || broken(broken_name && !strcmp_wa(display_name, broken_name)),
217         "display_name = %s\n", wine_dbgstr_w(display_name));
218     CoTaskMemFree(display_name);
219
220     hres = IMoniker_IsSystemMoniker(mon, &mksys);
221     ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
222     ok(mksys == MKSYS_URLMONIKER, "mksys = %d\n", mksys);
223 }
224
225 static LRESULT WINAPI plugin_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
226 {
227     switch(msg) {
228     case WM_PAINT: {
229         PAINTSTRUCT ps;
230         HBRUSH brush;
231         RECT rect;
232         HDC dc;
233
234         GetClientRect(hwnd, &rect);
235
236         dc = BeginPaint(hwnd, &ps);
237         brush = CreateSolidBrush(RGB(255,0,0));
238         SelectObject(dc, brush);
239         Rectangle(dc, rect.left, rect.top, rect.right, rect.bottom);
240         DeleteObject(brush);
241         EndPaint(hwnd, &ps);
242         break;
243     }
244     }
245
246     return DefWindowProc(hwnd, msg, wParam, lParam);
247 }
248
249 static void create_plugin_window(HWND parent, const RECT *rect)
250 {
251     static const WCHAR plugin_testW[] =
252         {'p','l','u','g','i','n',' ','t','e','s','t',0};
253     static WNDCLASSEXW wndclass = {
254         sizeof(WNDCLASSEXW),
255         0,
256         plugin_proc,
257         0, 0, NULL, NULL, NULL, NULL, NULL,
258         plugin_testW,
259         NULL
260     };
261
262     RegisterClassExW(&wndclass);
263     plugin_hwnd = CreateWindowW(plugin_testW, plugin_testW,
264             WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, rect->left, rect->top,
265             rect->right-rect->left, rect->bottom-rect->top, parent, NULL, NULL, NULL);
266 }
267
268 static HRESULT ax_qi(REFIID,void**);
269
270 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
271 {
272     return ax_qi(riid, ppv);
273 }
274
275 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
276 {
277     return 2;
278 }
279
280 static ULONG WINAPI OleControl_Release(IOleControl *iface)
281 {
282     return 1;
283 }
284
285 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *pCI)
286 {
287     ok(0, "unexpected call\n");
288     return E_NOTIMPL;
289 }
290
291 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *mMsg)
292 {
293     ok(0, "unexpected call\n");
294     return E_NOTIMPL;
295 }
296
297 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
298 {
299     ok(0, "unexpected call\n");
300     return E_NOTIMPL;
301 }
302
303 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
304 {
305     if(bFreeze)
306         CHECK_EXPECT2(FreezeEvents_TRUE);
307     else
308         CHECK_EXPECT2(FreezeEvents_FALSE);
309     return S_OK;
310 }
311
312 static const IOleControlVtbl OleControlVtbl = {
313     OleControl_QueryInterface,
314     OleControl_AddRef,
315     OleControl_Release,
316     OleControl_GetControlInfo,
317     OleControl_OnMnemonic,
318     OleControl_OnAmbientPropertyChange,
319     OleControl_FreezeEvents
320 };
321
322 static IOleControl OleControl = { &OleControlVtbl };
323
324 static HRESULT WINAPI QuickActivate_QueryInterface(IQuickActivate *iface, REFIID riid, void **ppv)
325 {
326     return ax_qi(riid, ppv);
327 }
328
329 static ULONG WINAPI QuickActivate_AddRef(IQuickActivate *iface)
330 {
331     return 2;
332 }
333
334 static ULONG WINAPI QuickActivate_Release(IQuickActivate *iface)
335 {
336     return 1;
337 }
338
339 static HRESULT WINAPI QuickActivate_QuickActivate(IQuickActivate *iface, QACONTAINER *container, QACONTROL *control)
340 {
341     CHECK_EXPECT(QuickActivate);
342
343     ok(container != NULL, "container == NULL\n");
344     ok(container->cbSize == sizeof(*container), "container->cbSize = %d\n", container->cbSize);
345     ok(container->pClientSite != NULL, "container->pClientSite == NULL\n");
346     ok(container->pAdviseSink != NULL, "container->pAdviseSink == NULL\n");
347     ok(container->pPropertyNotifySink != NULL, "container->pPropertyNotifySink == NULL\n");
348     ok(!container->pUnkEventSink, "container->pUnkEventSink != NULL\n");
349     ok(container->dwAmbientFlags == (QACONTAINER_SUPPORTSMNEMONICS|QACONTAINER_MESSAGEREFLECT|QACONTAINER_USERMODE),
350        "container->dwAmbientFlags = %x\n", container->dwAmbientFlags);
351     ok(!container->colorFore, "container->colorFore == 0\n"); /* FIXME */
352     todo_wine
353     ok(container->colorBack, "container->colorBack == 0\n"); /* FIXME */
354     todo_wine
355     ok(container->pFont != NULL, "container->pFont == NULL\n");
356     todo_wine
357     ok(container->pUndoMgr != NULL, "container->pUndoMgr == NULL\n");
358     ok(!container->dwAppearance, "container->dwAppearance = %x\n", container->dwAppearance);
359     ok(!container->lcid, "container->lcid = %x\n", container->lcid);
360     ok(!container->hpal, "container->hpal = %p\n", container->hpal);
361     ok(!container->pBindHost, "container->pBindHost != NULL\n");
362     ok(!container->pOleControlSite, "container->pOleControlSite != NULL\n");
363     ok(!container->pServiceProvider, "container->pServiceProvider != NULL\n");
364
365     ok(control->cbSize == sizeof(*control), "control->cbSize = %d\n", control->cbSize);
366     ok(!control->dwMiscStatus, "control->dwMiscStatus = %x\n", control->dwMiscStatus);
367     ok(!control->dwViewStatus, "control->dwViewStatus = %x\n", control->dwViewStatus);
368     ok(!control->dwEventCookie, "control->dwEventCookie = %x\n", control->dwEventCookie);
369     ok(!control->dwPropNotifyCookie, "control->dwPropNotifyCookie = %x\n", control->dwPropNotifyCookie);
370     ok(!control->dwPointerActivationPolicy, "control->dwPointerActivationPolicy = %x\n", control->dwPointerActivationPolicy);
371
372     ok(iface_cmp((IUnknown*)container->pClientSite, (IUnknown*)container->pAdviseSink),
373        "container->pClientSite != container->pAdviseSink\n");
374     ok(iface_cmp((IUnknown*)container->pClientSite, (IUnknown*)container->pPropertyNotifySink),
375        "container->pClientSite != container->pPropertyNotifySink\n");
376     test_ifaces((IUnknown*)container->pClientSite, pluginhost_iids);
377
378     IOleClientSite_AddRef(container->pClientSite);
379     client_site = container->pClientSite;
380
381     control->dwMiscStatus = OLEMISC_SETCLIENTSITEFIRST|OLEMISC_ACTIVATEWHENVISIBLE|OLEMISC_INSIDEOUT
382         |OLEMISC_CANTLINKINSIDE|OLEMISC_RECOMPOSEONRESIZE;
383     control->dwViewStatus = 0x18;
384     control->dwPropNotifyCookie = 1;
385
386     return S_OK;
387 }
388
389 static HRESULT WINAPI QuickActivate_SetContentExtent(IQuickActivate *iface, LPSIZEL pSizel)
390 {
391     ok(0, "unexpected call\n");
392     return E_NOTIMPL;
393 }
394
395 static HRESULT WINAPI QuickActivate_GetContentExtent(IQuickActivate *iface, LPSIZEL pSizel)
396 {
397     ok(0, "unexpected call\n");
398     return E_NOTIMPL;
399 }
400
401 static const IQuickActivateVtbl QuickActivateVtbl = {
402     QuickActivate_QueryInterface,
403     QuickActivate_AddRef,
404     QuickActivate_Release,
405     QuickActivate_QuickActivate,
406     QuickActivate_GetContentExtent,
407     QuickActivate_SetContentExtent
408 };
409
410 static IQuickActivate QuickActivate = { &QuickActivateVtbl };
411
412 static HRESULT WINAPI PersistPropertyBag_QueryInterface(IPersistPropertyBag *iface, REFIID riid, void **ppv)
413 {
414     return ax_qi(riid, ppv);
415 }
416
417 static ULONG WINAPI PersistPropertyBag_AddRef(IPersistPropertyBag *iface)
418 {
419     return 2;
420 }
421
422 static ULONG WINAPI PersistPropertyBag_Release(IPersistPropertyBag *iface)
423 {
424     return 1;
425 }
426
427 static HRESULT WINAPI PersistPropertyBag_GetClassID(IPersistPropertyBag *face, CLSID *pClassID)
428 {
429     ok(0, "unexpected call\n");
430     return E_NOTIMPL;
431 }
432
433 static HRESULT WINAPI PersistPropertyBag_InitNew(IPersistPropertyBag *face)
434 {
435     CHECK_EXPECT(IPersistPropertyBag_InitNew);
436     return S_OK;
437 }
438
439 static HRESULT WINAPI PersistPropertyBag_Load(IPersistPropertyBag *face, IPropertyBag *pPropBag, IErrorLog *pErrorLog)
440 {
441     IBindHost *bind_host, *bind_host2;
442     IServiceProvider *sp;
443     IMoniker *mon;
444     VARIANT v;
445     HRESULT hres;
446
447     static const WCHAR param_nameW[] = {'p','a','r','a','m','_','n','a','m','e',0};
448     static const WCHAR num_paramW[] = {'n','u','m','_','p','a','r','a','m',0};
449     static const WCHAR no_paramW[] = {'n','o','_','p','a','r','a','m',0};
450     static WCHAR test_swfW[] = {'t','e','s','t','.','s','w','f',0};
451
452     static const IID *propbag_ifaces[] = {
453         &IID_IPropertyBag,
454         &IID_IPropertyBag2,
455         NULL
456     };
457
458     CHECK_EXPECT(IPersistPropertyBag_Load);
459
460     ok(pPropBag != NULL, "pPropBag == NULL\n");
461     ok(!pErrorLog, "pErrorLog != NULL\n");
462
463     test_ifaces((IUnknown*)pPropBag, propbag_ifaces);
464
465     V_VT(&v) = VT_BSTR;
466     hres = IPropertyBag_Read(pPropBag, param_nameW, &v, NULL);
467     ok(hres == S_OK, "Read failed: %08x\n", hres);
468     ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
469     ok(!strcmp_wa(V_BSTR(&v), "param_value"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
470
471     V_VT(&v) = VT_I4;
472     V_I4(&v) = 0xdeadbeef;
473     hres = IPropertyBag_Read(pPropBag, param_nameW, &v, NULL);
474     ok(hres == DISP_E_TYPEMISMATCH, "Read failed: %08x, expected DISP_E_TYPEMISMATCH\n", hres);
475     ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
476     ok(V_I4(&v) == 0xdeadbeef, "V_I4(v) = %x\n", V_I4(&v));
477
478     V_VT(&v) = VT_BSTR;
479     hres = IPropertyBag_Read(pPropBag, num_paramW, &v, NULL);
480     ok(hres == S_OK, "Read failed: %08x\n", hres);
481     ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
482     ok(!strcmp_wa(V_BSTR(&v), "3"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
483     SysFreeString(V_BSTR(&v));
484
485     V_VT(&v) = VT_I4;
486     V_I4(&v) = 0xdeadbeef;
487     hres = IPropertyBag_Read(pPropBag, num_paramW, &v, NULL);
488     ok(hres == S_OK, "Read failed: %08x\n", hres);
489     ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
490     ok(V_I4(&v) == 3, "V_I4(v) = %x\n", V_I4(&v));
491
492     V_VT(&v) = VT_BSTR;
493     V_BSTR(&v) = (BSTR)0xdeadbeef;
494     hres = IPropertyBag_Read(pPropBag, no_paramW, &v, NULL);
495     ok(hres == E_INVALIDARG, "Read failed: %08x\n", hres);
496     ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
497     ok(V_BSTR(&v) == (BSTR)0xdeadbeef, "V_BSTR(v) = %p\n", V_BSTR(&v));
498
499     set_plugin_readystate(READYSTATE_INTERACTIVE);
500
501     hres = IOleClientSite_QueryInterface(client_site, &IID_IBindHost, (void**)&bind_host);
502     ok(hres == S_OK, "Could not get IBindHost iface: %08x\n", hres);
503
504     hres = IOleClientSite_QueryInterface(client_site, &IID_IServiceProvider, (void**)&sp);
505     ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
506
507     hres = IServiceProvider_QueryService(sp, &SID_SBindHost, &IID_IBindHost, (void**)&bind_host2);
508     ok(hres == S_OK, "QueryService(SID_SBindHost) failed: %08x\n", hres);
509     IServiceProvider_Release(sp);
510
511     ok(iface_cmp((IUnknown*)bind_host, (IUnknown*)bind_host2), "bind_host != bind_host2\n");
512     IBindHost_Release(bind_host2);
513
514     mon = NULL;
515     hres = IBindHost_CreateMoniker(bind_host, test_swfW, NULL, &mon, 0);
516     ok(hres == S_OK, "CreateMoniker failed: %08x\n", hres);
517     ok(mon != NULL, "mon == NULL\n");
518     test_mon_displayname(mon, "about:test.swf", "about:blanktest.swf");
519     IMoniker_Release(mon);
520
521     IBindHost_Release(bind_host);
522
523     mon = NULL;
524     hres = IOleClientSite_GetMoniker(client_site, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &mon);
525     ok(hres == S_OK, "GetMoniker failed: %08x\n", hres);
526     ok(mon != NULL, "mon == NULL\n");
527     test_mon_displayname(mon, "about:blank", NULL);
528     IMoniker_Release(mon);
529
530     set_plugin_readystate(READYSTATE_COMPLETE);
531
532     return S_OK;
533 }
534
535 static HRESULT WINAPI PersistPropertyBag_Save(IPersistPropertyBag *face, IPropertyBag *pPropBag, BOOL fClearDisrty, BOOL fSaveAllProperties)
536 {
537     ok(0, "unexpected call\n");
538     return E_NOTIMPL;
539 }
540
541 static const IPersistPropertyBagVtbl PersistPropertyBagVtbl = {
542     PersistPropertyBag_QueryInterface,
543     PersistPropertyBag_AddRef,
544     PersistPropertyBag_Release,
545     PersistPropertyBag_GetClassID,
546     PersistPropertyBag_InitNew,
547     PersistPropertyBag_Load,
548     PersistPropertyBag_Save
549
550 };
551
552 static IPersistPropertyBag PersistPropertyBag = { &PersistPropertyBagVtbl };
553
554 static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
555 {
556     return ax_qi(riid, ppv);
557 }
558
559 static ULONG WINAPI Dispatch_AddRef(IDispatch *iface)
560 {
561     return 2;
562 }
563
564 static ULONG WINAPI Dispatch_Release(IDispatch *iface)
565 {
566     return 1;
567 }
568
569 static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
570 {
571     ok(0, "unexpected call\n");
572     return E_NOTIMPL;
573 }
574
575 static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid,
576         ITypeInfo **ppTInfo)
577 {
578     ok(0, "unexpected call\n");
579     return E_NOTIMPL;
580 }
581
582 static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
583         UINT cNames, LCID lcid, DISPID *rgDispId)
584 {
585     CHECK_EXPECT(GetIDsOfNames_scriptprop);
586     ok(IsEqualGUID(riid, &IID_NULL), "riid = %s\n", debugstr_guid(riid));
587     ok(cNames == 1, "cNames = %d\n", cNames);
588     ok(rgszNames != NULL, "rgszNames == NULL\n");
589     ok(!strcmp_wa(rgszNames[0], "scriptprop"), "rgszNames[0] = %s\n", wine_dbgstr_w(rgszNames[0]));
590     ok(rgDispId != NULL, "rgDispId == NULL\n");
591
592     *rgDispId = DISPID_SCRIPTPROP;
593     return S_OK;
594 }
595
596 static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
597         LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
598         EXCEPINFO *pExcepInfo, UINT *puArgErr)
599 {
600     ok(IsEqualGUID(riid, &IID_NULL), "riid = %s\n", debugstr_guid(riid));
601     ok(pDispParams != NULL, "pDispParams == NULL\n");
602     ok(!pDispParams->cNamedArgs, "pDispParams->cNamedArgs = %d\n", pDispParams->cNamedArgs);
603     ok(!pDispParams->rgdispidNamedArgs, "pDispParams->rgdispidNamedArgs != NULL\n");
604     ok(pVarResult != NULL, "pVarResult == NULL\n");
605
606     switch(dispIdMember) {
607     case DISPID_READYSTATE:
608         CHECK_EXPECT2(Invoke_READYSTATE);
609         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
610         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
611         ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
612         ok(!pExcepInfo, "pExcepInfo != NULL\n");
613         ok(puArgErr != NULL, "puArgErr == NULL\n");
614
615         V_VT(pVarResult) = VT_I4;
616         V_I4(pVarResult) = plugin_readystate;
617         return S_OK;
618      case DISPID_ENABLED:
619         CHECK_EXPECT2(Invoke_ENABLED);
620         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
621         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
622         ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
623         ok(!pExcepInfo, "pExcepInfo != NULL\n");
624         ok(puArgErr != NULL, "puArgErr == NULL\n");
625         return DISP_E_MEMBERNOTFOUND;
626     case DISPID_VALID:
627         CHECK_EXPECT(Invoke_VALID);
628         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
629         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
630         ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
631         ok(!pExcepInfo, "pExcepInfo != NULL\n");
632         ok(puArgErr != NULL, "puArgErr == NULL\n");
633         return DISP_E_MEMBERNOTFOUND;
634     case DISPID_SECURITYCTX:
635         CHECK_EXPECT(Invoke_SECURITYCTX);
636         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
637         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
638         ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
639         ok(!pExcepInfo, "pExcepInfo != NULL\n");
640         ok(puArgErr != NULL, "puArgErr == NULL\n");
641         return DISP_E_MEMBERNOTFOUND;
642     case DISPID_SCRIPTPROP:
643         CHECK_EXPECT(Invoke_SCRIPTPROP);
644         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
645         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
646         ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
647         ok(pExcepInfo != NULL, "pExcepInfo == NULL\n");
648         ok(!puArgErr, "puArgErr != NULL\n");
649
650         V_VT(pVarResult) = VT_I4;
651         V_I4(pVarResult) = 4;
652         return S_OK;
653     default:
654         ok(0, "unexpected call %d\n", dispIdMember);
655     }
656
657     return E_NOTIMPL;
658 }
659
660 static const IDispatchVtbl DispatchVtbl = {
661     Dispatch_QueryInterface,
662     Dispatch_AddRef,
663     Dispatch_Release,
664     Dispatch_GetTypeInfoCount,
665     Dispatch_GetTypeInfo,
666     Dispatch_GetIDsOfNames,
667     Dispatch_Invoke
668 };
669
670 static IDispatch Dispatch = { &DispatchVtbl };
671
672 static HRESULT WINAPI ViewObjectEx_QueryInterface(IViewObjectEx *iface, REFIID riid, void **ppv)
673 {
674     return ax_qi(riid, ppv);
675 }
676
677 static ULONG WINAPI ViewObjectEx_AddRef(IViewObjectEx *iface)
678 {
679     return 2;
680 }
681
682 static ULONG WINAPI ViewObjectEx_Release(IViewObjectEx *iface)
683 {
684     return 1;
685 }
686
687 static HRESULT WINAPI ViewObjectEx_Draw(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
688         HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBoungs, BOOL (WINAPI*pfnContinue)(ULONG_PTR), ULONG_PTR dwContinue)
689 {
690     ok(0, "unexpected call\n");
691     return E_NOTIMPL;
692 }
693
694 static HRESULT WINAPI ViewObjectEx_GetColorSet(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
695         HDC hicTargetDev, LOGPALETTE **ppColorSet)
696 {
697     ok(0, "unexpected call\n");
698     return E_NOTIMPL;
699 }
700
701 static HRESULT WINAPI ViewObjectEx_Freeze(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze)
702 {
703     ok(0, "unexpected call\n");
704     return E_NOTIMPL;
705 }
706
707 static HRESULT WINAPI ViewObjectEx_Unfreeze(IViewObjectEx *iface, DWORD dwFreeze)
708 {
709     ok(0, "unexpected call\n");
710     return E_NOTIMPL;
711 }
712
713 static HRESULT WINAPI ViewObjectEx_SetAdvise(IViewObjectEx *iface, DWORD aspects, DWORD advf, IAdviseSink *pAdvSink)
714 {
715     CHECK_EXPECT(SetAdvise);
716
717     ok(aspects == DVASPECT_CONTENT, "aspects = %x\n", aspects);
718     ok(!advf, "advf = %x\n", advf);
719     ok(pAdvSink != NULL, "pAdvSink = NULL\n");
720
721     return S_OK;
722 }
723
724 static HRESULT WINAPI ViewObjectEx_GetAdvise(IViewObjectEx *iface, DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink)
725 {
726     ok(0, "unexpected call\n");
727     return E_NOTIMPL;
728 }
729
730 static HRESULT WINAPI ViewObjectEx_GetExtent(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel)
731 {
732     ok(0, "unexpected call\n");
733     return E_NOTIMPL;
734 }
735
736 static HRESULT WINAPI ViewObjectEx_GetRect(IViewObjectEx *iface, DWORD dwAspect, LPRECTL pRect)
737 {
738     ok(0, "unexpected call\n");
739     return E_NOTIMPL;
740 }
741
742 static HRESULT WINAPI ViewObjectEx_GetViewStatus(IViewObjectEx *iface, DWORD *pdwStatus)
743 {
744     CHECK_EXPECT(GetViewStatus);
745
746     *pdwStatus = VIEWSTATUS_OPAQUE|VIEWSTATUS_SOLIDBKGND;
747     return S_OK;
748 }
749
750 static HRESULT WINAPI ViewObjectEx_QueryHitPoint(IViewObjectEx *iface, DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc,
751         LONG lCloseHint, DWORD *pHitResult)
752 {
753     ok(0, "unexpected call\n");
754     return E_NOTIMPL;
755 }
756
757 static HRESULT WINAPI ViewObjectEx_QueryHitRect(IViewObjectEx *iface, DWORD dwAspect, LPCRECT pRectBounds, LPCRECT pRectLoc,
758         LONG lCloseHint, DWORD *pHitResult)
759 {
760     ok(0, "unexpected call\n");
761     return E_NOTIMPL;
762 }
763
764 static HRESULT WINAPI ViewObjectEx_GetNaturalExtent(IViewObjectEx *iface, DWORD dwAspect, LONG lindex, DVTARGETDEVICE *ptd,
765         HDC hicTargetDev, DVEXTENTINFO *pExtentIngo, LPSIZEL pSizel)
766 {
767     ok(0, "unexpected call\n");
768     return E_NOTIMPL;
769 }
770
771 static const IViewObjectExVtbl ViewObjectExVtbl = {
772     ViewObjectEx_QueryInterface,
773     ViewObjectEx_AddRef,
774     ViewObjectEx_Release,
775     ViewObjectEx_Draw,
776     ViewObjectEx_GetColorSet,
777     ViewObjectEx_Freeze,
778     ViewObjectEx_Unfreeze,
779     ViewObjectEx_SetAdvise,
780     ViewObjectEx_GetAdvise,
781     ViewObjectEx_GetExtent,
782     ViewObjectEx_GetRect,
783     ViewObjectEx_GetViewStatus,
784     ViewObjectEx_QueryHitPoint,
785     ViewObjectEx_QueryHitRect,
786     ViewObjectEx_GetNaturalExtent
787 };
788
789 static IViewObjectEx ViewObjectEx = { &ViewObjectExVtbl };
790
791 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
792 {
793     return ax_qi(riid, ppv);
794 }
795
796 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
797 {
798     return 2;
799 }
800
801 static ULONG WINAPI OleObject_Release(IOleObject *iface)
802 {
803     return 1;
804 }
805
806 static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *pClientSite)
807 {
808     if(!pClientSite) {
809         CHECK_EXPECT(SetClientSite_NULL);
810         return S_OK;
811     }
812
813     CHECK_EXPECT(SetClientSite);
814
815     IOleClientSite_AddRef(pClientSite);
816     client_site = pClientSite;
817     return S_OK;
818 }
819
820 static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **ppClientSite)
821 {
822     ok(0, "unexpected call\n");
823     return E_NOTIMPL;
824 }
825
826 static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
827 {
828     ok(0, "unexpected call\n");
829     return E_NOTIMPL;
830 }
831
832 static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
833 {
834     CHECK_EXPECT(Close);
835
836     ok(dwSaveOption == OLECLOSE_NOSAVE, "dwSaveOption = %d\n", dwSaveOption);
837     return S_OK;
838 }
839
840 static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker *pmk)
841 {
842     ok(0, "unexpected call\n");
843     return E_NOTIMPL;
844 }
845
846 static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
847 {
848     ok(0, "unexpected call\n");
849     return E_NOTIMPL;
850 }
851
852 static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *pDataObject, BOOL fCreation,
853         DWORD dwReserved)
854 {
855     ok(0, "unexpected call\n");
856     return E_NOTIMPL;
857 }
858
859 static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved, IDataObject **ppDataObject)
860 {
861     ok(0, "unexpected call\n");
862     return E_NOTIMPL;
863 }
864
865 static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
866         LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
867 {
868     OLEINPLACEFRAMEINFO frame_info = {0xdeadbeef};
869     IOleInPlaceUIWindow *ip_uiwindow;
870     IOleInPlaceFrame *ip_frame;
871     IOleInPlaceSiteEx *ip_site;
872     RECT pos_rect, clip_rect;
873     BOOL no_redraw;
874     HWND hwnd;
875     HRESULT hres;
876
877     CHECK_EXPECT(DoVerb);
878
879     ok(iVerb == OLEIVERB_INPLACEACTIVATE, "iVerb = %d\n", iVerb);
880     ok(!lpmsg, "lpmsg != NULL\n");
881     ok(pActiveSite != NULL, "pActiveSite == NULL\n");
882     ok(!lindex, "lindex = %d\n", lindex);
883     ok(hwndParent != NULL, "hwndParent == NULL\n");
884     ok(lprcPosRect != NULL, "lprcPosRect == NULL\n");
885
886     hres = IOleClientSite_QueryInterface(pActiveSite, &IID_IOleInPlaceSiteEx, (void**)&ip_site);
887     ok(hres == S_OK, "Could not get IOleInPlaceSiteEx iface: %08x\n", hres);
888
889     SET_EXPECT(InPlaceObject_GetWindow);
890     no_redraw = 0xdeadbeef;
891     hres = IOleInPlaceSiteEx_OnInPlaceActivateEx(ip_site, &no_redraw, 0);
892     ok(hres == S_OK, "InPlaceActivateEx failed: %08x\n", hres);
893     ok(!no_redraw, "no_redraw = %x\n", no_redraw);
894     CHECK_CALLED(InPlaceObject_GetWindow);
895
896     no_redraw = 0xdeadbeef;
897     hres = IOleInPlaceSiteEx_OnInPlaceActivateEx(ip_site, &no_redraw, 0);
898     ok(hres == S_OK, "InPlaceActivateEx failed: %08x\n", hres);
899     ok(no_redraw == 0xdeadbeef, "no_redraw = %x\n", no_redraw);
900
901     hwnd = NULL;
902     hres = IOleInPlaceSiteEx_GetWindow(ip_site, &hwnd);
903     ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
904     ok(hwnd != NULL, "hwnd == NULL\n");
905     ok(hwnd == hwndParent, "hwnd != hwndParent\n");
906
907     create_plugin_window(hwnd, lprcPosRect);
908
909     ip_frame = NULL;
910     ip_uiwindow = NULL;
911     frame_info.cb = sizeof(OLEINPLACEFRAMEINFO);
912     hres = IOleInPlaceSiteEx_GetWindowContext(ip_site, &ip_frame, &ip_uiwindow, &pos_rect, &clip_rect, &frame_info);
913     ok(hres == S_OK, "GetWindowContext failed: %08x\n", hres);
914     ok(ip_frame != NULL, "ip_frame == NULL\n");
915     ok(ip_uiwindow != NULL, "ip_uiwindow == NULL\n");
916     ok((IOleInPlaceUIWindow*)ip_frame != ip_uiwindow, "ip_frame == ip_uiwindow\n");
917     ok(!memcmp(&pos_rect, lprcPosRect, sizeof(RECT)), "pos_rect != lpecPosRect\n");
918     ok(!memcmp(&clip_rect, lprcPosRect, sizeof(RECT)), "clip_rect != lpecPosRect\n");
919     ok(frame_info.cb == sizeof(frame_info), "frame_info.cb = %d\n", frame_info.cb);
920     ok(!frame_info.fMDIApp, "frame_info.fMDIApp = %x\n", frame_info.fMDIApp);
921     ok(frame_info.hwndFrame != NULL, "frame_info.hwnd == NULL\n");
922     ok(frame_info.hwndFrame == container_hwnd, "frame_info.hwnd != container_hwnd\n");
923     ok(!frame_info.haccel, "frame_info.haccel != 0\n");
924     ok(!frame_info.cAccelEntries, "frame_info.cAccelEntried != 0\n");
925
926     IOleInPlaceFrame_Release(ip_frame);
927     IOleInPlaceUIWindow_Release(ip_uiwindow);
928
929
930     IOleInPlaceSiteEx_Release(ip_site);
931
932     hres = IOleClientSite_ShowObject(client_site);
933     ok(hres == S_OK, "ShowObject failed: %08x\n", hres);
934
935     SET_EXPECT(InPlaceObject_GetWindow);
936     SET_EXPECT(SetObjectRects);
937
938     return S_OK;
939 }
940
941 static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
942 {
943     ok(0, "unexpected call\n");
944     return E_NOTIMPL;
945 }
946
947 static HRESULT WINAPI OleObject_Update(IOleObject *iface)
948 {
949     ok(0, "unexpected call\n");
950     return E_NOTIMPL;
951 }
952
953 static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
954 {
955     ok(0, "unexpected call\n");
956     return E_NOTIMPL;
957 }
958
959 static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *pClsid)
960 {
961     ok(0, "unexpected call\n");
962     return E_NOTIMPL;
963 }
964
965 static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType, LPOLESTR *pszUserType)
966 {
967     ok(0, "unexpected call\n");
968     return E_NOTIMPL;
969 }
970
971 static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
972 {
973     CHECK_EXPECT(SetExtent);
974     return E_NOTIMPL;
975 }
976
977 static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
978 {
979     CHECK_EXPECT(GetExtent);
980     return E_NOTIMPL;
981 }
982
983 static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection)
984 {
985     ok(0, "unexpected call\n");
986     return E_NOTIMPL;
987 }
988
989 static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
990 {
991     ok(0, "unexpected call\n");
992     return E_NOTIMPL;
993 }
994
995 static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
996 {
997     ok(0, "unexpected call\n");
998     return E_NOTIMPL;
999 }
1000
1001 static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
1002 {
1003     CHECK_EXPECT(GetMiscStatus);
1004     ok(dwAspect == DVASPECT_CONTENT, "dwAspect = %d\n", dwAspect);
1005     ok(pdwStatus != NULL, "pdwStatus == NULL\n");
1006     *pdwStatus = OLEMISC_SETCLIENTSITEFIRST|OLEMISC_ACTIVATEWHENVISIBLE
1007         |OLEMISC_INSIDEOUT|OLEMISC_CANTLINKINSIDE|OLEMISC_RECOMPOSEONRESIZE;
1008     return S_OK;
1009 }
1010
1011 static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *pLogpal)
1012 {
1013     ok(0, "unexpected call\n");
1014     return E_NOTIMPL;
1015 }
1016
1017 static const IOleObjectVtbl OleObjectVtbl = {
1018     OleObject_QueryInterface,
1019     OleObject_AddRef,
1020     OleObject_Release,
1021     OleObject_SetClientSite,
1022     OleObject_GetClientSite,
1023     OleObject_SetHostNames,
1024     OleObject_Close,
1025     OleObject_SetMoniker,
1026     OleObject_GetMoniker,
1027     OleObject_InitFromData,
1028     OleObject_GetClipboardData,
1029     OleObject_DoVerb,
1030     OleObject_EnumVerbs,
1031     OleObject_Update,
1032     OleObject_IsUpToDate,
1033     OleObject_GetUserClassID,
1034     OleObject_GetUserType,
1035     OleObject_SetExtent,
1036     OleObject_GetExtent,
1037     OleObject_Advise,
1038     OleObject_Unadvise,
1039     OleObject_EnumAdvise,
1040     OleObject_GetMiscStatus,
1041     OleObject_SetColorScheme
1042 };
1043
1044 static IOleObject OleObject = { &OleObjectVtbl };
1045
1046 static HRESULT WINAPI OleInPlaceObject_QueryInterface(IOleInPlaceObjectWindowless *iface,
1047         REFIID riid, void **ppv)
1048 {
1049     return ax_qi(riid, ppv);
1050 }
1051
1052 static ULONG WINAPI OleInPlaceObject_AddRef(IOleInPlaceObjectWindowless *iface)
1053 {
1054     return 2;
1055 }
1056
1057 static ULONG WINAPI OleInPlaceObject_Release(IOleInPlaceObjectWindowless *iface)
1058 {
1059     return 1;
1060 }
1061
1062 static HRESULT WINAPI OleInPlaceObject_GetWindow(IOleInPlaceObjectWindowless *iface,
1063         HWND *phwnd)
1064 {
1065     CHECK_EXPECT2(InPlaceObject_GetWindow);
1066
1067     ok(phwnd != NULL, "phwnd == NULL\n");
1068
1069     *phwnd = plugin_hwnd;
1070     return *phwnd ? S_OK : E_UNEXPECTED;
1071 }
1072
1073 static HRESULT WINAPI OleInPlaceObject_ContextSensitiveHelp(IOleInPlaceObjectWindowless *iface,
1074         BOOL fEnterMode)
1075 {
1076     ok(0, "unexpected call\n");
1077     return E_NOTIMPL;
1078 }
1079
1080 static HRESULT WINAPI OleInPlaceObject_InPlaceDeactivate(IOleInPlaceObjectWindowless *iface)
1081 {
1082     IOleInPlaceSite *ip_site;
1083     HRESULT hres;
1084
1085     CHECK_EXPECT(InPlaceDeactivate);
1086
1087     hres = IOleClientSite_QueryInterface(client_site, &IID_IOleInPlaceSite, (void**)&ip_site);
1088     ok(hres == S_OK, "Could not get IOleInPlaceSite iface: %08x\n", hres);
1089
1090     hres = IOleInPlaceSite_OnInPlaceDeactivate(ip_site);
1091     ok(hres == S_OK, "OnInPlaceDeactivate failed: %08x\n", hres);
1092
1093     IOleInPlaceSite_Release(ip_site);
1094     return S_OK;
1095 }
1096
1097 static HRESULT WINAPI OleInPlaceObject_UIDeactivate(IOleInPlaceObjectWindowless *iface)
1098 {
1099     CHECK_EXPECT2(UIDeactivate);
1100     return S_OK;
1101 }
1102
1103 static HRESULT WINAPI OleInPlaceObject_SetObjectRects(IOleInPlaceObjectWindowless *iface,
1104         LPCRECT lprcPosRect, LPCRECT lprcClipRect)
1105 {
1106     CHECK_EXPECT(SetObjectRects);
1107     return S_OK;
1108 }
1109
1110 static HRESULT WINAPI OleInPlaceObjectWindowless_ReactivateAndUndo(IOleInPlaceObjectWindowless *iface)
1111 {
1112     ok(0, "unexpected call\n");
1113     return E_NOTIMPL;
1114 }
1115
1116 static HRESULT WINAPI OleInPlaceObjectWindowless_OnWindowMessage(IOleInPlaceObjectWindowless *iface,
1117         UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *lpResult)
1118 {
1119     ok(0, "unexpected call\n");
1120     return E_NOTIMPL;
1121 }
1122
1123 static HRESULT WINAPI OleInPlaceObjectWindowless_GetDropTarget(IOleInPlaceObjectWindowless *iface,
1124         IDropTarget **ppDropTarget)
1125 {
1126     ok(0, "unexpected call\n");
1127     return E_NOTIMPL;
1128 }
1129
1130 static const IOleInPlaceObjectWindowlessVtbl OleInPlaceObjectWindowlessVtbl = {
1131     OleInPlaceObject_QueryInterface,
1132     OleInPlaceObject_AddRef,
1133     OleInPlaceObject_Release,
1134     OleInPlaceObject_GetWindow,
1135     OleInPlaceObject_ContextSensitiveHelp,
1136     OleInPlaceObject_InPlaceDeactivate,
1137     OleInPlaceObject_UIDeactivate,
1138     OleInPlaceObject_SetObjectRects,
1139     OleInPlaceObjectWindowless_ReactivateAndUndo,
1140     OleInPlaceObjectWindowless_OnWindowMessage,
1141     OleInPlaceObjectWindowless_GetDropTarget
1142 };
1143
1144 static IOleInPlaceObjectWindowless OleInPlaceObjectWindowless = { &OleInPlaceObjectWindowlessVtbl };
1145
1146 static HRESULT ax_qi(REFIID riid, void **ppv)
1147 {
1148     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IOleControl)) {
1149         *ppv = &OleControl;
1150     }else if(IsEqualGUID(riid, &IID_IQuickActivate)) {
1151         *ppv = plugin_behavior == TEST_NOQUICKACT ? NULL : &QuickActivate;
1152     }else if(IsEqualGUID(riid, &IID_IPersistPropertyBag)) {
1153         *ppv = plugin_behavior == TEST_NOQUICKACT ? NULL : &PersistPropertyBag;
1154     }else if(IsEqualGUID(riid, &IID_IDispatch)) {
1155         *ppv = &Dispatch;
1156     }else if(IsEqualGUID(riid, &IID_IViewObject) || IsEqualGUID(riid, &IID_IViewObject2)
1157             || IsEqualGUID(riid, &IID_IViewObjectEx)) {
1158         *ppv = &ViewObjectEx;
1159     }else if(IsEqualGUID(riid, &IID_IOleObject)) {
1160         *ppv = &OleObject;
1161     }else  if(IsEqualGUID(riid, &IID_IOleWindow) || IsEqualGUID(riid, &IID_IOleInPlaceObject)
1162        || IsEqualGUID(&IID_IOleInPlaceObjectWindowless, riid)) {
1163         *ppv = &OleInPlaceObjectWindowless;
1164     }else {
1165         trace("QI %s\n", debugstr_guid(riid));
1166         *ppv = NULL;
1167     }
1168
1169     return *ppv ? S_OK : E_NOINTERFACE;
1170 }
1171
1172 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
1173 {
1174     *ppv = NULL;
1175
1176     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
1177         *ppv = iface;
1178         return S_OK;
1179     }
1180
1181     if(IsEqualGUID(&IID_IMarshal, riid))
1182         return E_NOINTERFACE;
1183     if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
1184         return E_NOINTERFACE;
1185     if(IsEqualGUID(&IID_IClassFactoryEx, riid))
1186         return E_NOINTERFACE; /* TODO */
1187
1188     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1189     return E_NOTIMPL;
1190 }
1191
1192 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
1193 {
1194     return 2;
1195 }
1196
1197 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
1198 {
1199     return 1;
1200 }
1201
1202 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
1203 {
1204     CHECK_EXPECT(CreateInstance);
1205
1206     ok(!outer, "outer = %p\n", outer);
1207     ok(IsEqualGUID(riid, &IID_IUnknown), "riid = %s\n", debugstr_guid(riid));
1208
1209     *ppv = &OleControl;
1210     return S_OK;
1211 }
1212
1213 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
1214 {
1215     ok(0, "unexpected call\n");
1216     return S_OK;
1217 }
1218
1219 static const IClassFactoryVtbl ClassFactoryVtbl = {
1220     ClassFactory_QueryInterface,
1221     ClassFactory_AddRef,
1222     ClassFactory_Release,
1223     ClassFactory_CreateInstance,
1224     ClassFactory_LockServer
1225 };
1226
1227 static IClassFactory activex_cf = { &ClassFactoryVtbl };
1228
1229 static void test_elem_dispex(IDispatchEx *dispex)
1230 {
1231     DISPPARAMS dp;
1232     EXCEPINFO ei;
1233     VARIANT v;
1234     DISPID id;
1235     BSTR str;
1236     HRESULT hres;
1237
1238     str = a2bstr("scriptprop");
1239     SET_EXPECT(GetIDsOfNames_scriptprop);
1240     hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
1241     CHECK_CALLED(GetIDsOfNames_scriptprop);
1242     SysFreeString(str);
1243     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1244     todo_wine
1245     ok(id == DISPID_SCRIPTPROP, "id = %d\n", id);
1246
1247     SET_EXPECT(Invoke_SECURITYCTX);
1248     SET_EXPECT(Invoke_SCRIPTPROP);
1249     memset(&dp, 0, sizeof(dp));
1250     memset(&ei, 0, sizeof(ei));
1251     V_VT(&v) = VT_EMPTY;
1252     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
1253     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1254     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
1255     ok(V_I4(&v) == 4, "V_I4(v) = %d\n", V_I4(&v));
1256     CHECK_CALLED(Invoke_SECURITYCTX);
1257     CHECK_CALLED(Invoke_SCRIPTPROP);
1258 }
1259
1260 static void test_object_elem(IHTMLDocument2 *doc)
1261 {
1262     IHTMLObjectElement *objelem;
1263     IHTMLDocument3 *doc3;
1264     IDispatchEx *dispex;
1265     IHTMLElement *elem;
1266     IDispatch *disp;
1267     BSTR str;
1268     HRESULT hres;
1269
1270     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1271     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
1272
1273     str = a2bstr("objid");
1274     elem = (void*)0xdeadbeef;
1275     hres = IHTMLDocument3_getElementById(doc3, str, &elem);
1276     IHTMLDocument3_Release(doc3);
1277     SysFreeString(str);
1278     ok(hres == S_OK, "getElementById failed: %08x\n", hres);
1279     ok(elem != NULL, "elem == NULL\n");
1280
1281     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLObjectElement, (void**)&objelem);
1282     IHTMLElement_Release(elem);
1283     ok(hres == S_OK, "Could not get IHTMLObjectElement iface: %08x\n", hres);
1284
1285     SET_EXPECT(Invoke_SECURITYCTX);
1286     hres = IHTMLObjectElement_get_object(objelem, &disp);
1287     ok(hres == S_OK, "get_object failed: %08x\n", hres);
1288     ok(disp == &Dispatch, "disp != Dispatch\n");
1289     CHECK_CALLED(Invoke_SECURITYCTX);
1290
1291     hres = IHTMLObjectElement_QueryInterface(objelem, &IID_IDispatchEx, (void**)&dispex);
1292     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1293     test_elem_dispex(dispex);
1294     IDispatchEx_Release(dispex);
1295
1296     IHTMLObjectElement_Release(objelem);
1297 }
1298
1299 static void test_container(IHTMLDocument2 *doc_obj)
1300 {
1301     IHTMLWindow2 *parent_window, *html_window;
1302     IServiceProvider *serv_prov;
1303     IOleContainer *container;
1304     IHTMLDocument2 *doc;
1305     IUnknown *unk;
1306     HRESULT hres;
1307
1308     container = NULL;
1309     hres = IOleClientSite_GetContainer(client_site, &container);
1310     ok(hres == S_OK, "GetContainer failed: %08x\n", hres);
1311     ok(container != NULL, "container == NULL\n");
1312
1313     hres = IHTMLDocument2_get_parentWindow(doc_obj, &parent_window);
1314     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
1315     ok(parent_window != NULL, "parentWindow == NULL\n");
1316
1317     hres = IHTMLWindow2_get_document(parent_window, &doc);
1318     ok(hres == S_OK, "get_document failed: %08x\n", hres);
1319     ok(doc != NULL, "doc == NULL\n");
1320     ok(iface_cmp((IUnknown*)doc, (IUnknown*)container), "container != doc\n");
1321     IHTMLDocument2_Release(doc);
1322
1323     hres = IOleClientSite_QueryInterface(client_site, &IID_IServiceProvider, (void**)&serv_prov);
1324     ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
1325
1326     hres = IServiceProvider_QueryService(serv_prov, &IID_IHTMLWindow2, &IID_IHTMLWindow2, (void**)&html_window);
1327     ok(hres == S_OK, "Could not get IHTMLWindow2 service: %08x\n", hres);
1328     todo_wine
1329     ok(!iface_cmp((IUnknown*)html_window, (IUnknown*)parent_window), "html_window != parent_window\n");
1330     IHTMLWindow2_Release(html_window);
1331
1332     SET_EXPECT(QueryService_TestActiveX);
1333     hres = IServiceProvider_QueryService(serv_prov, &CLSID_TestActiveX, &IID_IUnknown, (void**)&unk);
1334     ok(hres == S_OK, "QueryService(CLSID_TestActiveX) failed: %08x\n", hres);
1335     ok(unk == (IUnknown*)&OleObject, "unexpected unk %p\n", unk);
1336     CHECK_CALLED(QueryService_TestActiveX);
1337
1338     IServiceProvider_Release(serv_prov);
1339
1340     IHTMLWindow2_Release(parent_window);
1341     IOleContainer_Release(container);
1342 }
1343
1344 static void test_ui_activate(void)
1345 {
1346     IOleInPlaceSite *ip_site;
1347     HRESULT hres;
1348
1349     hres = IOleClientSite_QueryInterface(client_site, &IID_IOleInPlaceSite, (void**)&ip_site);
1350     ok(hres == S_OK, "Could not get IOleInPlaceSite iface: %08x\n", hres);
1351
1352     SET_EXPECT(Invoke_ENABLED);
1353     hres = IOleInPlaceSite_OnUIActivate(ip_site);
1354     ok(hres == S_OK, "OnUIActivate failed: %08x\n", hres);
1355     CHECK_CALLED(Invoke_ENABLED);
1356
1357     IOleInPlaceSite_Release(ip_site);
1358 }
1359
1360 static HRESULT cs_qi(REFIID,void **);
1361 static IOleDocumentView *view;
1362
1363 static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
1364 {
1365     static const GUID undocumented_frame_iid = {0xfbece6c9,0x48d7,0x4a37,{0x8f,0xe3,0x6a,0xd4,0x27,0x2f,0xdd,0xac}};
1366
1367     if(!IsEqualGUID(&undocumented_frame_iid, riid))
1368         ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1369
1370     *ppv = NULL;
1371     return E_NOINTERFACE;
1372 }
1373
1374 static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
1375 {
1376     return 2;
1377 }
1378
1379 static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
1380 {
1381     return 1;
1382 }
1383
1384 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
1385 {
1386     return E_NOTIMPL;
1387 }
1388
1389 static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
1390 {
1391     return E_NOTIMPL;
1392 }
1393
1394 static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
1395 {
1396     return E_NOTIMPL;
1397 }
1398
1399 static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
1400         LPCBORDERWIDTHS pborderwidths)
1401 {
1402     return E_NOTIMPL;
1403 }
1404
1405 static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
1406         LPCBORDERWIDTHS pborderwidths)
1407 {
1408     return S_OK;
1409 }
1410
1411 static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceFrame *iface,
1412         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
1413 {
1414     return S_OK;
1415 }
1416
1417 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
1418         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
1419 {
1420     return S_OK;
1421 }
1422
1423 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
1424         LPOLEMENUGROUPWIDTHS lpMenuWidths)
1425 {
1426     return E_NOTIMPL;
1427 }
1428
1429 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
1430         HOLEMENU holemenu, HWND hwndActiveObject)
1431 {
1432     ok(0, "unexpected call\n");
1433     return E_NOTIMPL;
1434 }
1435
1436 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
1437 {
1438     ok(0, "unexpected call\n");
1439     return E_NOTIMPL;
1440 }
1441
1442 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
1443 {
1444     return S_OK;
1445 }
1446
1447 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
1448 {
1449     return E_NOTIMPL;
1450 }
1451
1452 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
1453 {
1454     ok(0, "unexpected call\n");
1455     return E_NOTIMPL;
1456 }
1457
1458 static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
1459     InPlaceFrame_QueryInterface,
1460     InPlaceFrame_AddRef,
1461     InPlaceFrame_Release,
1462     InPlaceFrame_GetWindow,
1463     InPlaceFrame_ContextSensitiveHelp,
1464     InPlaceFrame_GetBorder,
1465     InPlaceFrame_RequestBorderSpace,
1466     InPlaceFrame_SetBorderSpace,
1467     InPlaceFrame_SetActiveObject,
1468     InPlaceFrame_InsertMenus,
1469     InPlaceFrame_SetMenu,
1470     InPlaceFrame_RemoveMenus,
1471     InPlaceFrame_SetStatusText,
1472     InPlaceFrame_EnableModeless,
1473     InPlaceFrame_TranslateAccelerator
1474 };
1475
1476 static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
1477
1478 static const IOleInPlaceFrameVtbl InPlaceUIWindowVtbl = {
1479     InPlaceFrame_QueryInterface,
1480     InPlaceFrame_AddRef,
1481     InPlaceFrame_Release,
1482     InPlaceFrame_GetWindow,
1483     InPlaceFrame_ContextSensitiveHelp,
1484     InPlaceFrame_GetBorder,
1485     InPlaceFrame_RequestBorderSpace,
1486     InPlaceFrame_SetBorderSpace,
1487     InPlaceUIWindow_SetActiveObject,
1488 };
1489
1490 static IOleInPlaceFrame InPlaceUIWindow = { &InPlaceUIWindowVtbl };
1491
1492 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv)
1493 {
1494     return cs_qi(riid, ppv);
1495 }
1496
1497 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface)
1498 {
1499     return 2;
1500 }
1501
1502 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface)
1503 {
1504     return 1;
1505 }
1506
1507 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd)
1508 {
1509     *phwnd = container_hwnd;
1510     return S_OK;
1511 }
1512
1513 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1514 {
1515     ok(0, "unexpected call\n");
1516     return E_NOTIMPL;
1517 }
1518
1519 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface)
1520 {
1521     return S_OK;
1522 }
1523
1524 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface)
1525 {
1526     return S_OK;
1527 }
1528
1529 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface)
1530 {
1531     return S_OK;
1532 }
1533
1534 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface,
1535         IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1536         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1537 {
1538     static const RECT rect = {0,0,500,500};
1539
1540     *ppFrame = &InPlaceFrame;
1541     *ppDoc = (IOleInPlaceUIWindow*)&InPlaceUIWindow;
1542     *lprcPosRect = rect;
1543     *lprcClipRect = rect;
1544
1545     lpFrameInfo->fMDIApp = FALSE;
1546     lpFrameInfo->hwndFrame = container_hwnd;
1547     lpFrameInfo->haccel = NULL;
1548     lpFrameInfo->cAccelEntries = 0;
1549
1550     return S_OK;
1551 }
1552
1553 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant)
1554 {
1555     return E_NOTIMPL;
1556 }
1557
1558 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1559 {
1560     return S_OK;
1561 }
1562
1563 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface)
1564 {
1565     return S_OK;
1566 }
1567
1568 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface)
1569 {
1570     return E_NOTIMPL;
1571 }
1572
1573 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface)
1574 {
1575     return E_NOTIMPL;
1576 }
1577
1578 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1579 {
1580     return E_NOTIMPL;
1581 }
1582
1583 static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = {
1584     InPlaceSite_QueryInterface,
1585     InPlaceSite_AddRef,
1586     InPlaceSite_Release,
1587     InPlaceSite_GetWindow,
1588     InPlaceSite_ContextSensitiveHelp,
1589     InPlaceSite_CanInPlaceActivate,
1590     InPlaceSite_OnInPlaceActivate,
1591     InPlaceSite_OnUIActivate,
1592     InPlaceSite_GetWindowContext,
1593     InPlaceSite_Scroll,
1594     InPlaceSite_OnUIDeactivate,
1595     InPlaceSite_OnInPlaceDeactivate,
1596     InPlaceSite_DiscardUndoState,
1597     InPlaceSite_DeactivateAndUndo,
1598     InPlaceSite_OnPosRectChange,
1599 };
1600
1601 static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl };
1602
1603 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
1604 {
1605     return cs_qi(riid, ppv);
1606 }
1607
1608 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
1609 {
1610     return 2;
1611 }
1612
1613 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
1614 {
1615     return 1;
1616 }
1617
1618 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
1619 {
1620     ok(0, "unexpected call\n");
1621     return E_NOTIMPL;
1622 }
1623
1624 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker,
1625         IMoniker **ppmon)
1626 {
1627     ok(0, "unexpected call\n");
1628     return E_NOTIMPL;
1629 }
1630
1631 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
1632 {
1633     return E_NOTIMPL;
1634 }
1635
1636 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
1637 {
1638     ok(0, "unexpected call\n");
1639     return E_NOTIMPL;
1640 }
1641
1642 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
1643 {
1644     ok(0, "unexpected call\n");
1645     return E_NOTIMPL;
1646 }
1647
1648 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
1649 {
1650     ok(0, "unexpected call\n");
1651     return E_NOTIMPL;
1652 }
1653
1654 static const IOleClientSiteVtbl ClientSiteVtbl = {
1655     ClientSite_QueryInterface,
1656     ClientSite_AddRef,
1657     ClientSite_Release,
1658     ClientSite_SaveObject,
1659     ClientSite_GetMoniker,
1660     ClientSite_GetContainer,
1661     ClientSite_ShowObject,
1662     ClientSite_OnShowWindow,
1663     ClientSite_RequestNewObjectLayout
1664 };
1665
1666 static IOleClientSite ClientSite = { &ClientSiteVtbl };
1667
1668 static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv)
1669 {
1670     return cs_qi(riid, ppv);
1671 }
1672
1673 static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface)
1674 {
1675     return 2;
1676 }
1677
1678 static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface)
1679 {
1680     return 1;
1681 }
1682
1683 static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate)
1684 {
1685     RECT rect = {0,0,400,500};
1686     IOleDocument *document;
1687     HRESULT hres;
1688
1689     hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document);
1690     ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
1691
1692     hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view);
1693     IOleDocument_Release(document);
1694     ok(hres == S_OK, "CreateView failed: %08x\n", hres);
1695
1696     hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite);
1697     ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
1698
1699     hres = IOleDocumentView_UIActivate(view, TRUE);
1700     ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
1701
1702     hres = IOleDocumentView_SetRect(view, &rect);
1703     ok(hres == S_OK, "SetRect failed: %08x\n", hres);
1704
1705     hres = IOleDocumentView_Show(view, TRUE);
1706     ok(hres == S_OK, "Show failed: %08x\n", hres);
1707
1708     return S_OK;
1709 }
1710
1711 static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
1712     DocumentSite_QueryInterface,
1713     DocumentSite_AddRef,
1714     DocumentSite_Release,
1715     DocumentSite_ActivateMe
1716 };
1717
1718 static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
1719
1720 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface,
1721                                                      REFIID riid, void **ppv)
1722 {
1723     return cs_qi(riid, ppv);
1724 }
1725
1726 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
1727 {
1728     return 2;
1729 }
1730
1731 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
1732 {
1733     return 1;
1734 }
1735
1736 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
1737         REFIID riid, void **ppv)
1738 {
1739     if(IsEqualGUID(&CLSID_TestActiveX, guidService)) {
1740         CHECK_EXPECT(QueryService_TestActiveX);
1741         ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
1742         *ppv = &OleObject;
1743         return S_OK;
1744     }
1745
1746     *ppv = NULL;
1747     return E_NOINTERFACE;
1748 }
1749
1750 static const IServiceProviderVtbl ServiceProviderVtbl = {
1751     ServiceProvider_QueryInterface,
1752     ServiceProvider_AddRef,
1753     ServiceProvider_Release,
1754     ServiceProvider_QueryService
1755 };
1756
1757 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
1758
1759 static HRESULT cs_qi(REFIID riid, void **ppv)
1760 {
1761     *ppv = NULL;
1762
1763     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid))
1764         *ppv = &ClientSite;
1765     else if(IsEqualGUID(&IID_IOleDocumentSite, riid))
1766         *ppv = &DocumentSite;
1767     else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
1768         *ppv = &InPlaceSite;
1769     else if(IsEqualGUID(riid, &IID_IServiceProvider))
1770         *ppv = &ServiceProvider;
1771
1772     return *ppv ? S_OK : E_NOINTERFACE;
1773 }
1774
1775 static IHTMLDocument2 *notif_doc;
1776 static BOOL doc_complete;
1777
1778 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
1779         REFIID riid, void**ppv)
1780 {
1781     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
1782         *ppv = iface;
1783         return S_OK;
1784     }
1785
1786     ok(0, "unexpected call\n");
1787     return E_NOINTERFACE;
1788 }
1789
1790 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
1791 {
1792     return 2;
1793 }
1794
1795 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
1796 {
1797     return 1;
1798 }
1799
1800 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
1801 {
1802     if(dispID == DISPID_READYSTATE){
1803         BSTR state;
1804         HRESULT hres;
1805
1806         static const WCHAR completeW[] = {'c','o','m','p','l','e','t','e',0};
1807
1808         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
1809         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
1810
1811         if(!lstrcmpW(state, completeW))
1812             doc_complete = TRUE;
1813
1814         SysFreeString(state);
1815     }
1816
1817     return S_OK;
1818 }
1819
1820 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
1821 {
1822     ok(0, "unexpected call\n");
1823     return E_NOTIMPL;
1824 }
1825
1826 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
1827     PropertyNotifySink_QueryInterface,
1828     PropertyNotifySink_AddRef,
1829     PropertyNotifySink_Release,
1830     PropertyNotifySink_OnChanged,
1831     PropertyNotifySink_OnRequestEdit
1832 };
1833
1834 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
1835
1836 static void doc_load_string(IHTMLDocument2 *doc, const char *str)
1837 {
1838     IPersistStreamInit *init;
1839     IStream *stream;
1840     HGLOBAL mem;
1841     SIZE_T len;
1842
1843     notif_doc = doc;
1844
1845     doc_complete = FALSE;
1846     len = strlen(str);
1847     mem = GlobalAlloc(0, len);
1848     memcpy(mem, str, len);
1849     CreateStreamOnHGlobal(mem, TRUE, &stream);
1850
1851     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
1852
1853     IPersistStreamInit_Load(init, stream);
1854     IPersistStreamInit_Release(init);
1855     IStream_Release(stream);
1856 }
1857
1858 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
1859 {
1860     IConnectionPointContainer *container;
1861     IConnectionPoint *cp;
1862     DWORD cookie;
1863     HRESULT hres;
1864
1865     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
1866     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
1867
1868     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
1869     IConnectionPointContainer_Release(container);
1870     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
1871
1872     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
1873     IConnectionPoint_Release(cp);
1874     ok(hres == S_OK, "Advise failed: %08x\n", hres);
1875 }
1876
1877 static void set_client_site(IHTMLDocument2 *doc, BOOL set)
1878 {
1879     IOleObject *oleobj;
1880     HRESULT hres;
1881
1882     if(!set && view) {
1883         IOleDocumentView_Show(view, FALSE);
1884         IOleDocumentView_CloseView(view, 0);
1885         IOleDocumentView_SetInPlaceSite(view, NULL);
1886         IOleDocumentView_Release(view);
1887         view = NULL;
1888     }
1889
1890     hres = IHTMLDocument2_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj);
1891     ok(hres == S_OK, "Could not et IOleObject: %08x\n", hres);
1892
1893     hres = IOleObject_SetClientSite(oleobj, set ? &ClientSite : NULL);
1894     ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
1895
1896     if(set) {
1897         IHlinkTarget *hlink;
1898
1899         hres = IOleObject_QueryInterface(oleobj, &IID_IHlinkTarget, (void**)&hlink);
1900         ok(hres == S_OK, "Could not get IHlinkTarget iface: %08x\n", hres);
1901
1902         hres = IHlinkTarget_Navigate(hlink, 0, NULL);
1903         ok(hres == S_OK, "Navgate failed: %08x\n", hres);
1904
1905         IHlinkTarget_Release(hlink);
1906     }
1907
1908     IOleObject_Release(oleobj);
1909 }
1910 static IHTMLDocument2 *create_document(void)
1911 {
1912     IHTMLDocument2 *doc;
1913     HRESULT hres;
1914
1915     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1916             &IID_IHTMLDocument2, (void**)&doc);
1917     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1918
1919     return doc;
1920 }
1921
1922 static IHTMLDocument2 *create_doc(const char *str, BOOL *b)
1923 {
1924     IHTMLDocument2 *doc;
1925     MSG msg;
1926
1927     doc = create_document();
1928     set_client_site(doc, TRUE);
1929     doc_load_string(doc, str);
1930     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
1931
1932     while((!doc_complete || (b && !*b)) && GetMessage(&msg, NULL, 0, 0)) {
1933         TranslateMessage(&msg);
1934         DispatchMessage(&msg);
1935     }
1936
1937     return doc;
1938 }
1939
1940 static void release_doc(IHTMLDocument2 *doc)
1941 {
1942     ULONG ref;
1943
1944     set_client_site(doc, FALSE);
1945     ref = IHTMLDocument2_Release(doc);
1946     ok(!ref, "ref = %d\n", ref);
1947
1948     if(client_site) {
1949         IOleClientSite_Release(client_site);
1950         client_site = NULL;
1951     }
1952
1953     if(plugin_hwnd) {
1954         DestroyWindow(plugin_hwnd);
1955         plugin_hwnd = NULL;
1956     }
1957 }
1958
1959 static void test_flash_ax(void)
1960 {
1961     IHTMLDocument2 *doc;
1962
1963     plugin_behavior = TEST_FLASH;
1964
1965     /*
1966      * We pump messages until both document is loaded and plugin instance is created.
1967      * Pumping until document is loaded should be enough, but Gecko loads plugins
1968      * asynchronously and until we'll work around it, we need this hack.
1969      */
1970     SET_EXPECT(CreateInstance);
1971     SET_EXPECT(FreezeEvents_TRUE);
1972     SET_EXPECT(QuickActivate);
1973     SET_EXPECT(FreezeEvents_FALSE);
1974     SET_EXPECT(IPersistPropertyBag_Load);
1975     SET_EXPECT(Invoke_READYSTATE);
1976     SET_EXPECT(SetExtent);
1977     SET_EXPECT(GetExtent);
1978     SET_EXPECT(DoVerb);
1979
1980     doc = create_doc(object_ax_str, &called_CreateInstance);
1981
1982     CHECK_CALLED(CreateInstance);
1983     todo_wine
1984     CHECK_CALLED(FreezeEvents_TRUE);
1985     CHECK_CALLED(QuickActivate);
1986     todo_wine
1987     CHECK_CALLED(FreezeEvents_FALSE);
1988     CHECK_CALLED(IPersistPropertyBag_Load);
1989     CHECK_CALLED(Invoke_READYSTATE);
1990     todo_wine
1991     CHECK_CALLED(SetExtent);
1992     todo_wine
1993     CHECK_CALLED(GetExtent);
1994     CHECK_CALLED(DoVerb);
1995
1996     /* Set in DoVerb */
1997     CHECK_CALLED(InPlaceObject_GetWindow);
1998     CHECK_CALLED(SetObjectRects);
1999
2000     test_ui_activate();
2001     test_container(notif_doc);
2002     test_object_elem(notif_doc);
2003
2004     SET_EXPECT(UIDeactivate);
2005     SET_EXPECT(Invoke_ENABLED);
2006     SET_EXPECT(Invoke_VALID);
2007     SET_EXPECT(InPlaceDeactivate);
2008     SET_EXPECT(Close);
2009     SET_EXPECT(SetClientSite_NULL);
2010     release_doc(doc);
2011     CHECK_CALLED(UIDeactivate);
2012     todo_wine
2013     CHECK_CALLED(Invoke_ENABLED);
2014     todo_wine
2015     CHECK_CALLED(Invoke_VALID);
2016     CHECK_CALLED(InPlaceDeactivate);
2017     CHECK_CALLED(Close);
2018     CHECK_CALLED(SetClientSite_NULL);
2019 }
2020
2021 static void test_noquickact_ax(void)
2022 {
2023     IHTMLDocument2 *doc;
2024
2025     plugin_behavior = TEST_NOQUICKACT;
2026
2027     SET_EXPECT(CreateInstance);
2028     SET_EXPECT(FreezeEvents_TRUE);
2029     SET_EXPECT(GetMiscStatus);
2030     SET_EXPECT(SetClientSite);
2031     SET_EXPECT(SetAdvise);
2032     SET_EXPECT(GetViewStatus);
2033     SET_EXPECT(FreezeEvents_FALSE);
2034     SET_EXPECT(Invoke_READYSTATE);
2035     SET_EXPECT(SetExtent);
2036     SET_EXPECT(GetExtent);
2037     SET_EXPECT(DoVerb);
2038
2039     doc = create_doc(object_ax_str, &called_CreateInstance);
2040
2041     CHECK_CALLED(CreateInstance);
2042     todo_wine CHECK_CALLED(FreezeEvents_TRUE);
2043     CHECK_CALLED(GetMiscStatus);
2044     CHECK_CALLED(SetClientSite);
2045     CHECK_CALLED(SetAdvise);
2046     CHECK_CALLED(GetViewStatus);
2047     todo_wine CHECK_CALLED(FreezeEvents_FALSE);
2048     CHECK_CALLED(Invoke_READYSTATE);
2049     todo_wine CHECK_CALLED(SetExtent);
2050     todo_wine CHECK_CALLED(GetExtent);
2051     CHECK_CALLED(DoVerb);
2052
2053     /* Set in DoVerb */
2054     CHECK_CALLED(InPlaceObject_GetWindow);
2055     CHECK_CALLED(SetObjectRects);
2056
2057     SET_EXPECT(InPlaceDeactivate);
2058     SET_EXPECT(Close);
2059     SET_EXPECT(SetClientSite_NULL);
2060     release_doc(doc);
2061     CHECK_CALLED(InPlaceDeactivate);
2062     CHECK_CALLED(Close);
2063     CHECK_CALLED(SetClientSite_NULL);
2064 }
2065
2066 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2067 {
2068     return DefWindowProc(hwnd, msg, wParam, lParam);
2069 }
2070
2071 static HWND create_container_window(void)
2072 {
2073     static const WCHAR html_document_testW[] =
2074         {'H','T','M','L','D','o','c','u','m','e','n','t','T','e','s','t',0};
2075     static WNDCLASSEXW wndclass = {
2076         sizeof(WNDCLASSEXW),
2077         0,
2078         wnd_proc,
2079         0, 0, NULL, NULL, NULL, NULL, NULL,
2080         html_document_testW,
2081         NULL
2082     };
2083
2084     RegisterClassExW(&wndclass);
2085     return CreateWindowW(html_document_testW, html_document_testW,
2086             WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
2087             515, 530, NULL, NULL, NULL, NULL);
2088 }
2089
2090 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
2091 {
2092     HKEY hkey;
2093     DWORD res;
2094
2095     if(!init) {
2096         RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
2097         return TRUE;
2098     }
2099
2100     res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
2101     if(res != ERROR_SUCCESS)
2102         return FALSE;
2103
2104     if(def_value)
2105         res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
2106
2107     RegCloseKey(hkey);
2108
2109     return res == ERROR_SUCCESS;
2110 }
2111
2112 static BOOL init_registry(BOOL init)
2113 {
2114     return init_key("TestActiveX\\CLSID", TESTACTIVEX_CLSID, init)
2115         && init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95801-9882-11cf-9fa9-00aa006c42c4}",
2116                     NULL, init)
2117         && init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95802-9882-11cf-9fa9-00aa006c42c4}",
2118                     NULL, init);
2119 }
2120
2121 static BOOL register_activex(void)
2122 {
2123     DWORD regid;
2124     HRESULT hres;
2125
2126     if(!init_registry(TRUE)) {
2127         init_registry(FALSE);
2128         return FALSE;
2129     }
2130
2131     hres = CoRegisterClassObject(&CLSID_TestActiveX, (IUnknown*)&activex_cf,
2132             CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
2133     ok(hres == S_OK, "Could not register control: %08x\n", hres);
2134
2135     return TRUE;
2136 }
2137
2138 static BOOL check_ie(void)
2139 {
2140     IHTMLDocument5 *doc;
2141     HRESULT hres;
2142
2143     static const WCHAR xW[] = {'x',0};
2144     static const WCHAR yW[] = {'y',0};
2145
2146     if(!lstrcmpW(xW, yW))
2147         return FALSE;
2148
2149     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2150             &IID_IHTMLDocument5, (void**)&doc);
2151     if(FAILED(hres))
2152         return FALSE;
2153
2154     IHTMLDocument5_Release(doc);
2155     return TRUE;
2156 }
2157
2158 START_TEST(activex)
2159 {
2160     CoInitialize(NULL);
2161
2162     if(!check_ie()) {
2163         CoUninitialize();
2164         win_skip("Too old IE\n");
2165         return;
2166     }
2167
2168     if(is_ie_hardened()) {
2169         CoUninitialize();
2170         win_skip("IE running in Enhanced Security Configuration\n");
2171         return;
2172     }
2173
2174     container_hwnd = create_container_window();
2175     ShowWindow(container_hwnd, SW_SHOW);
2176
2177     if(register_activex()) {
2178         trace("Testing emulated flash embedding...\n");
2179         test_flash_ax();
2180         trace("Testing plugin without IQuickActivate iface...\n");
2181         test_noquickact_ax();
2182         init_registry(FALSE);
2183     }else {
2184         skip("Could not register ActiveX\n");
2185     }
2186
2187     DestroyWindow(container_hwnd);
2188     CoUninitialize();
2189 }