2 * Copyright 2010 Jacek Caban for CodeWeavers
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.
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.
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
22 #include <wine/test.h>
33 #include "mshtml_test.h"
35 #define DEFINE_EXPECT(func) \
36 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
38 #define SET_EXPECT(func) \
39 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
41 #define CHECK_EXPECT2(func) \
43 ok(expect_ ##func, "unexpected call " #func "\n"); \
44 called_ ## func = TRUE; \
47 #define CHECK_EXPECT(func) \
49 CHECK_EXPECT2(func); \
50 expect_ ## func = FALSE; \
53 #define CHECK_CALLED(func) \
55 ok(called_ ## func, "expected " #func "\n"); \
56 expect_ ## func = called_ ## func = FALSE; \
59 DEFINE_EXPECT(CreateInstance);
60 DEFINE_EXPECT(FreezeEvents_TRUE);
61 DEFINE_EXPECT(FreezeEvents_FALSE);
62 DEFINE_EXPECT(QuickActivate);
64 static HWND container_hwnd;
66 #define TESTACTIVEX_CLSID "{178fc163-f585-4e24-9c13-4bb7f6680746}"
68 static const GUID CLSID_TestActiveX =
69 {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xf6,0x68,0x07,0x46}};
71 static const char *debugstr_guid(REFIID riid)
75 sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
76 riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
77 riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
78 riid->Data4[5], riid->Data4[6], riid->Data4[7]);
83 static const char object_ax_str[] =
84 "<html><head></head><body>"
85 "<object classid=\"clsid:" TESTACTIVEX_CLSID "\" width=\"300\" height=\"200\" id=\"objid\">"
86 "<param name=\"param_name\" value=\"param_value\">"
90 static const REFIID pluginhost_iids[] = {
94 &IID_IPropertyNotifySink,
98 &IID_IOleInPlaceSiteEx,
101 &IID_IServiceProvider,
105 static const char *dbgstr_guid(REFIID riid)
109 sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
110 riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
111 riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
112 riid->Data4[5], riid->Data4[6], riid->Data4[7]);
117 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
119 IUnknown *unk1, *unk2;
124 IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
125 IUnknown_Release(unk1);
126 IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2);
127 IUnknown_Release(unk2);
132 #define test_ifaces(i,ids) _test_ifaces(__LINE__,i,ids)
133 static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids)
135 const IID * const *piid;
139 for(piid = iids; *piid; piid++) {
140 hres = IDispatch_QueryInterface(iface, *piid, (void**)&unk);
141 ok_(__FILE__,line) (hres == S_OK, "Could not get %s interface: %08x\n", dbgstr_guid(*piid), hres);
143 IUnknown_Release(unk);
147 static HRESULT ax_qi(REFIID,void**);
149 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
151 return ax_qi(riid, ppv);
154 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
159 static ULONG WINAPI OleControl_Release(IOleControl *iface)
164 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *pCI)
166 ok(0, "unexpected call\n");
170 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *mMsg)
172 ok(0, "unexpected call\n");
176 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
178 ok(0, "unexpected call\n");
182 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
185 CHECK_EXPECT2(FreezeEvents_TRUE);
187 CHECK_EXPECT2(FreezeEvents_FALSE);
191 static const IOleControlVtbl OleControlVtbl = {
192 OleControl_QueryInterface,
195 OleControl_GetControlInfo,
196 OleControl_OnMnemonic,
197 OleControl_OnAmbientPropertyChange,
198 OleControl_FreezeEvents
201 static IOleControl OleControl = { &OleControlVtbl };
203 static HRESULT WINAPI QuickActivate_QueryInterface(IQuickActivate *iface, REFIID riid, void **ppv)
205 return ax_qi(riid, ppv);
208 static ULONG WINAPI QuickActivate_AddRef(IQuickActivate *iface)
213 static ULONG WINAPI QuickActivate_Release(IQuickActivate *iface)
218 static HRESULT WINAPI QuickActivate_QuickActivate(IQuickActivate *iface, QACONTAINER *container, QACONTROL *control)
220 CHECK_EXPECT(QuickActivate);
222 ok(container != NULL, "container == NULL\n");
223 ok(container->cbSize == sizeof(*container), "container->cbSize = %d\n", container->cbSize);
224 ok(container->pClientSite != NULL, "container->pClientSite == NULL\n");
225 ok(container->pAdviseSink != NULL, "container->pAdviseSink == NULL\n");
226 ok(container->pPropertyNotifySink != NULL, "container->pPropertyNotifySink == NULL\n");
227 ok(!container->pUnkEventSink, "container->pUnkEventSink != NULL\n");
228 ok(container->dwAmbientFlags == (QACONTAINER_SUPPORTSMNEMONICS|QACONTAINER_MESSAGEREFLECT|QACONTAINER_USERMODE),
229 "container->dwAmbientFlags = %x\n", container->dwAmbientFlags);
230 ok(!container->colorFore, "container->colorFore == 0\n"); /* FIXME */
232 ok(container->colorBack, "container->colorBack == 0\n"); /* FIXME */
234 ok(container->pFont != NULL, "container->pFont == NULL\n");
236 ok(container->pUndoMgr != NULL, "container->pUndoMgr == NULL\n");
237 ok(!container->dwAppearance, "container->dwAppearance = %x\n", container->dwAppearance);
238 ok(!container->lcid, "container->lcid = %x\n", container->lcid);
239 ok(!container->hpal, "container->hpal = %p\n", container->hpal);
240 ok(!container->pBindHost, "container->pBindHost != NULL\n");
241 ok(!container->pOleControlSite, "container->pOleControlSite != NULL\n");
242 ok(!container->pServiceProvider, "container->pServiceProvider != NULL\n");
244 ok(control->cbSize == sizeof(*control), "control->cbSize = %d\n", control->cbSize);
245 ok(!control->dwMiscStatus, "control->dwMiscStatus = %x\n", control->dwMiscStatus);
246 ok(!control->dwViewStatus, "control->dwViewStatus = %x\n", control->dwViewStatus);
247 ok(!control->dwEventCookie, "control->dwEventCookie = %x\n", control->dwEventCookie);
248 ok(!control->dwPropNotifyCookie, "control->dwPropNotifyCookie = %x\n", control->dwPropNotifyCookie);
249 ok(!control->dwPointerActivationPolicy, "control->dwPointerActivationPolicy = %x\n", control->dwPointerActivationPolicy);
251 ok(iface_cmp((IUnknown*)container->pClientSite, (IUnknown*)container->pAdviseSink),
252 "container->pClientSite != container->pAdviseSink\n");
253 ok(iface_cmp((IUnknown*)container->pClientSite, (IUnknown*)container->pPropertyNotifySink),
254 "container->pClientSite != container->pPropertyNotifySink\n");
255 test_ifaces((IUnknown*)container->pClientSite, pluginhost_iids);
260 static HRESULT WINAPI QuickActivate_SetContentExtent(IQuickActivate *iface, LPSIZEL pSizel)
262 ok(0, "unexpected call\n");
266 static HRESULT WINAPI QuickActivate_GetContentExtent(IQuickActivate *iface, LPSIZEL pSizel)
268 ok(0, "unexpected call\n");
272 static const IQuickActivateVtbl QuickActivateVtbl = {
273 QuickActivate_QueryInterface,
274 QuickActivate_AddRef,
275 QuickActivate_Release,
276 QuickActivate_QuickActivate,
277 QuickActivate_GetContentExtent,
278 QuickActivate_SetContentExtent
281 static IQuickActivate QuickActivate = { &QuickActivateVtbl };
283 static HRESULT ax_qi(REFIID riid, void **ppv)
285 if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IOleControl)) {
290 if(IsEqualGUID(riid, &IID_IQuickActivate)) {
291 *ppv = &QuickActivate;
296 return E_NOINTERFACE;
299 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
303 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
308 if(IsEqualGUID(&IID_IMarshal, riid))
309 return E_NOINTERFACE;
310 if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
311 return E_NOINTERFACE;
312 if(IsEqualGUID(&IID_IClassFactoryEx, riid))
313 return E_NOINTERFACE; /* TODO */
315 ok(0, "unexpected riid %s\n", debugstr_guid(riid));
319 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
324 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
329 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
331 CHECK_EXPECT(CreateInstance);
333 ok(!outer, "outer = %p\n", outer);
334 ok(IsEqualGUID(riid, &IID_IUnknown), "riid = %s\n", debugstr_guid(riid));
340 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
342 ok(0, "unexpected call\n");
346 static const IClassFactoryVtbl ClassFactoryVtbl = {
347 ClassFactory_QueryInterface,
349 ClassFactory_Release,
350 ClassFactory_CreateInstance,
351 ClassFactory_LockServer
354 static HRESULT cs_qi(REFIID,void **);
355 static IOleDocumentView *view;
357 static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
359 static const GUID undocumented_frame_iid = {0xfbece6c9,0x48d7,0x4a37,{0x8f,0xe3,0x6a,0xd4,0x27,0x2f,0xdd,0xac}};
361 if(!IsEqualGUID(&undocumented_frame_iid, riid))
362 ok(0, "unexpected riid %s\n", debugstr_guid(riid));
365 return E_NOINTERFACE;
368 static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
373 static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
378 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
383 static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
388 static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
393 static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
394 LPCBORDERWIDTHS pborderwidths)
399 static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
400 LPCBORDERWIDTHS pborderwidths)
405 static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceFrame *iface,
406 IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
411 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
412 IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
417 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
418 LPOLEMENUGROUPWIDTHS lpMenuWidths)
423 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
424 HOLEMENU holemenu, HWND hwndActiveObject)
426 ok(0, "unexpected call\n");
430 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
432 ok(0, "unexpected call\n");
436 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
441 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
446 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
448 ok(0, "unexpected call\n");
452 static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
453 InPlaceFrame_QueryInterface,
455 InPlaceFrame_Release,
456 InPlaceFrame_GetWindow,
457 InPlaceFrame_ContextSensitiveHelp,
458 InPlaceFrame_GetBorder,
459 InPlaceFrame_RequestBorderSpace,
460 InPlaceFrame_SetBorderSpace,
461 InPlaceFrame_SetActiveObject,
462 InPlaceFrame_InsertMenus,
463 InPlaceFrame_SetMenu,
464 InPlaceFrame_RemoveMenus,
465 InPlaceFrame_SetStatusText,
466 InPlaceFrame_EnableModeless,
467 InPlaceFrame_TranslateAccelerator
470 static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
472 static const IOleInPlaceFrameVtbl InPlaceUIWindowVtbl = {
473 InPlaceFrame_QueryInterface,
475 InPlaceFrame_Release,
476 InPlaceFrame_GetWindow,
477 InPlaceFrame_ContextSensitiveHelp,
478 InPlaceFrame_GetBorder,
479 InPlaceFrame_RequestBorderSpace,
480 InPlaceFrame_SetBorderSpace,
481 InPlaceUIWindow_SetActiveObject,
484 static IOleInPlaceFrame InPlaceUIWindow = { &InPlaceUIWindowVtbl };
486 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv)
488 return cs_qi(riid, ppv);
491 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface)
496 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface)
501 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd)
503 *phwnd = container_hwnd;
507 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
509 ok(0, "unexpected call\n");
513 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface)
518 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface)
523 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface)
528 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface,
529 IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
530 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
532 static const RECT rect = {0,0,500,500};
534 *ppFrame = &InPlaceFrame;
535 *ppDoc = (IOleInPlaceUIWindow*)&InPlaceUIWindow;
537 *lprcClipRect = rect;
539 lpFrameInfo->cb = sizeof(*lpFrameInfo);
540 lpFrameInfo->fMDIApp = FALSE;
541 lpFrameInfo->hwndFrame = container_hwnd;
542 lpFrameInfo->haccel = NULL;
543 lpFrameInfo->cAccelEntries = 0;
548 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant)
553 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
558 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface)
563 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface)
568 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface)
573 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
578 static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = {
579 InPlaceSite_QueryInterface,
582 InPlaceSite_GetWindow,
583 InPlaceSite_ContextSensitiveHelp,
584 InPlaceSite_CanInPlaceActivate,
585 InPlaceSite_OnInPlaceActivate,
586 InPlaceSite_OnUIActivate,
587 InPlaceSite_GetWindowContext,
589 InPlaceSite_OnUIDeactivate,
590 InPlaceSite_OnInPlaceDeactivate,
591 InPlaceSite_DiscardUndoState,
592 InPlaceSite_DeactivateAndUndo,
593 InPlaceSite_OnPosRectChange,
596 static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl };
598 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
600 return cs_qi(riid, ppv);
603 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
608 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
613 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
615 ok(0, "unexpected call\n");
619 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker,
622 ok(0, "unexpected call\n");
626 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
631 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
633 ok(0, "unexpected call\n");
637 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
639 ok(0, "unexpected call\n");
643 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
645 ok(0, "unexpected call\n");
649 static const IOleClientSiteVtbl ClientSiteVtbl = {
650 ClientSite_QueryInterface,
653 ClientSite_SaveObject,
654 ClientSite_GetMoniker,
655 ClientSite_GetContainer,
656 ClientSite_ShowObject,
657 ClientSite_OnShowWindow,
658 ClientSite_RequestNewObjectLayout
661 static IOleClientSite ClientSite = { &ClientSiteVtbl };
663 static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv)
665 return cs_qi(riid, ppv);
668 static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface)
673 static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface)
678 static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate)
680 RECT rect = {0,0,400,500};
681 IOleDocument *document;
684 hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document);
685 ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
687 hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view);
688 IOleDocument_Release(document);
689 ok(hres == S_OK, "CreateView failed: %08x\n", hres);
691 hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite);
692 ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
694 hres = IOleDocumentView_UIActivate(view, TRUE);
695 ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
697 hres = IOleDocumentView_SetRect(view, &rect);
698 ok(hres == S_OK, "SetRect failed: %08x\n", hres);
700 hres = IOleDocumentView_Show(view, TRUE);
701 ok(hres == S_OK, "Show failed: %08x\n", hres);
706 static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
707 DocumentSite_QueryInterface,
709 DocumentSite_Release,
710 DocumentSite_ActivateMe
713 static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
715 static HRESULT cs_qi(REFIID riid, void **ppv)
719 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid))
721 else if(IsEqualGUID(&IID_IOleDocumentSite, riid))
722 *ppv = &DocumentSite;
723 else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
726 return *ppv ? S_OK : E_NOINTERFACE;
729 static IClassFactory activex_cf = { &ClassFactoryVtbl };
730 static IHTMLDocument2 *notif_doc;
731 static BOOL doc_complete;
733 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
734 REFIID riid, void**ppv)
736 if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
741 ok(0, "unexpected call\n");
742 return E_NOINTERFACE;
745 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
750 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
755 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
757 if(dispID == DISPID_READYSTATE){
761 static const WCHAR completeW[] = {'c','o','m','p','l','e','t','e',0};
763 hres = IHTMLDocument2_get_readyState(notif_doc, &state);
764 ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
766 if(!lstrcmpW(state, completeW))
769 SysFreeString(state);
775 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
777 ok(0, "unexpected call\n");
781 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
782 PropertyNotifySink_QueryInterface,
783 PropertyNotifySink_AddRef,
784 PropertyNotifySink_Release,
785 PropertyNotifySink_OnChanged,
786 PropertyNotifySink_OnRequestEdit
789 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
791 static void doc_load_string(IHTMLDocument2 *doc, const char *str)
793 IPersistStreamInit *init;
800 doc_complete = FALSE;
802 mem = GlobalAlloc(0, len);
803 memcpy(mem, str, len);
804 CreateStreamOnHGlobal(mem, TRUE, &stream);
806 IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
808 IPersistStreamInit_Load(init, stream);
809 IPersistStreamInit_Release(init);
810 IStream_Release(stream);
813 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
815 IConnectionPointContainer *container;
816 IConnectionPoint *cp;
820 hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
821 ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
823 hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
824 IConnectionPointContainer_Release(container);
825 ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
827 hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
828 IConnectionPoint_Release(cp);
829 ok(hres == S_OK, "Advise failed: %08x\n", hres);
832 static void set_client_site(IHTMLDocument2 *doc, BOOL set)
838 IOleDocumentView_Show(view, FALSE);
839 IOleDocumentView_CloseView(view, 0);
840 IOleDocumentView_SetInPlaceSite(view, NULL);
841 IOleDocumentView_Release(view);
845 hres = IHTMLDocument2_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj);
846 ok(hres == S_OK, "Could not et IOleObject: %08x\n", hres);
848 hres = IOleObject_SetClientSite(oleobj, set ? &ClientSite : NULL);
849 ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
854 hres = IOleObject_QueryInterface(oleobj, &IID_IHlinkTarget, (void**)&hlink);
855 ok(hres == S_OK, "Could not get IHlinkTarget iface: %08x\n", hres);
857 hres = IHlinkTarget_Navigate(hlink, 0, NULL);
858 ok(hres == S_OK, "Navgate failed: %08x\n", hres);
860 IHlinkTarget_Release(hlink);
863 IOleObject_Release(oleobj);
865 static IHTMLDocument2 *create_document(void)
870 hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
871 &IID_IHTMLDocument2, (void**)&doc);
872 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
877 static IHTMLDocument2 *create_doc(const char *str, BOOL *b)
882 doc = create_document();
883 set_client_site(doc, TRUE);
884 doc_load_string(doc, str);
885 do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
887 while((!doc_complete || (b && !*b)) && GetMessage(&msg, NULL, 0, 0)) {
888 TranslateMessage(&msg);
889 DispatchMessage(&msg);
895 static void release_doc(IHTMLDocument2 *doc)
899 set_client_site(doc, FALSE);
900 ref = IHTMLDocument2_Release(doc);
901 ok(!ref, "ref = %d\n", ref);
904 static void test_object_ax(void)
909 * We pump messages until both document is loaded and plugin instance is created.
910 * Pumping until document is loaded should be enough, but Gecko loads plugins
911 * asynchronously and until we'll work around it, we need this hack.
913 SET_EXPECT(CreateInstance);
914 SET_EXPECT(FreezeEvents_TRUE);
915 SET_EXPECT(QuickActivate);
916 SET_EXPECT(FreezeEvents_FALSE);
918 doc = create_doc(object_ax_str, &called_CreateInstance);
920 CHECK_CALLED(CreateInstance);
922 CHECK_CALLED(FreezeEvents_TRUE);
923 CHECK_CALLED(QuickActivate);
925 CHECK_CALLED(FreezeEvents_FALSE);
930 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
932 return DefWindowProc(hwnd, msg, wParam, lParam);
935 static HWND create_container_window(void)
937 static const WCHAR html_document_testW[] =
938 {'H','T','M','L','D','o','c','u','m','e','n','t','T','e','s','t',0};
939 static WNDCLASSEXW wndclass = {
943 0, 0, NULL, NULL, NULL, NULL, NULL,
948 RegisterClassExW(&wndclass);
949 return CreateWindowW(html_document_testW, html_document_testW,
950 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
951 515, 530, NULL, NULL, NULL, NULL);
954 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
960 RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
964 res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
965 if(res != ERROR_SUCCESS)
969 res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
973 return res == ERROR_SUCCESS;
976 static BOOL init_registry(BOOL init)
978 return init_key("TestActiveX\\CLSID", TESTACTIVEX_CLSID, init)
979 && init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95801-9882-11cf-9fa9-00aa006c42c4}",
981 && init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95802-9882-11cf-9fa9-00aa006c42c4}",
985 static BOOL register_activex(void)
990 if(!init_registry(TRUE)) {
991 init_registry(FALSE);
995 hres = CoRegisterClassObject(&CLSID_TestActiveX, (IUnknown*)&activex_cf,
996 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®id);
997 ok(hres == S_OK, "Could not register control: %08x\n", hres);
1002 static BOOL check_ie(void)
1004 IHTMLDocument5 *doc;
1007 static const WCHAR xW[] = {'x',0};
1008 static const WCHAR yW[] = {'y',0};
1010 if(!lstrcmpW(xW, yW))
1013 hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1014 &IID_IHTMLDocument5, (void**)&doc);
1018 IHTMLDocument5_Release(doc);
1028 win_skip("Too old IE\n");
1032 if(is_ie_hardened()) {
1034 win_skip("IE running in Enhanced Security Configuration\n");
1038 container_hwnd = create_container_window();
1039 ShowWindow(container_hwnd, SW_SHOW);
1041 if(register_activex()) {
1043 init_registry(FALSE);
1045 skip("Could not register ActiveX\n");
1048 DestroyWindow(container_hwnd);