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