[PATCH] msscript: Implement FindConnectionPoint()

Nikolay Sivov nsivov at codeweavers.com
Thu Jun 16 14:20:32 CDT 2016


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/msscript.ocx/msscript.c       | 148 ++++++++++++++++++++++++++++++++++++-
 dlls/msscript.ocx/tests/msscript.c |   9 +++
 2 files changed, 155 insertions(+), 2 deletions(-)

diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c
index 6465104..d0f23dd 100644
--- a/dlls/msscript.ocx/msscript.c
+++ b/dlls/msscript.ocx/msscript.c
@@ -29,6 +29,17 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(msscript);
 
+struct ScriptControl;
+typedef struct ConnectionPoint ConnectionPoint;
+
+struct ConnectionPoint {
+    IConnectionPoint IConnectionPoint_iface;
+    ScriptControl *control;
+    IConnectionPointContainer *container;
+    const IID *riid;
+    ConnectionPoint *next;
+};
+
 struct ScriptControl {
     IScriptControl IScriptControl_iface;
     IPersistStreamInit IPersistStreamInit_iface;
@@ -38,6 +49,11 @@ struct ScriptControl {
     LONG ref;
     IOleClientSite *site;
     SIZEL extent;
+
+    /* connection points */
+    ConnectionPoint *cp_list;
+    ConnectionPoint cp_scsource;
+    ConnectionPoint cp_propnotif;
 };
 
 static HINSTANCE msscript_instance;
@@ -146,6 +162,11 @@ static inline ScriptControl *impl_from_IConnectionPointContainer(IConnectionPoin
     return CONTAINING_RECORD(iface, ScriptControl, IConnectionPointContainer_iface);
 }
 
+static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface)
+{
+    return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface);
+}
+
 static HRESULT WINAPI ScriptControl_QueryInterface(IScriptControl *iface, REFIID riid, void **ppv)
 {
     ScriptControl *This = impl_from_IScriptControl(iface);
@@ -895,10 +916,24 @@ static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionP
 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, REFIID riid, IConnectionPoint **cp)
 {
     ScriptControl *This = impl_from_IConnectionPointContainer(iface);
+    ConnectionPoint *iter;
 
-    FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), cp);
+    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), cp);
 
-    return E_NOTIMPL;
+    *cp = NULL;
+
+    for (iter = This->cp_list; iter; iter = iter->next) {
+        if (IsEqualIID(iter->riid, riid))
+            *cp = &iter->IConnectionPoint_iface;
+    }
+
+    if (*cp) {
+        IConnectionPoint_AddRef(*cp);
+        return S_OK;
+    }
+
+    FIXME("unsupported connection point %s\n", debugstr_guid(riid));
+    return CONNECT_E_NOCONNECTION;
 }
 
 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
@@ -909,6 +944,111 @@ static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
     ConnectionPointContainer_FindConnectionPoint
 };
 
+static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface,
+        REFIID riid, void **ppv)
+{
+    ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+
+    if(IsEqualGUID(&IID_IUnknown, riid)) {
+        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+        *ppv = &This->IConnectionPoint_iface;
+    }else if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
+        TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
+        *ppv = &This->IConnectionPoint_iface;
+    }else {
+        FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
+{
+    ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+    return IConnectionPointContainer_AddRef(This->container);
+}
+
+static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
+{
+    ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+    return IConnectionPointContainer_Release(This->container);
+}
+
+static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *iid)
+{
+    ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+
+    FIXME("(%p)->(%p)\n", This, iid);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
+        IConnectionPointContainer **container)
+{
+    ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+
+    FIXME("(%p)->(%p)\n", This, container);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *unk_sink,
+        DWORD *cookie)
+{
+    ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+
+    FIXME("(%p)->(%p %p)\n", This, unk_sink, cookie);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD cookie)
+{
+    ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+
+    FIXME("(%p)->(%d)\n", This, cookie);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
+        IEnumConnections **ppEnum)
+{
+    ConnectionPoint *This = impl_from_IConnectionPoint(iface);
+
+    FIXME("(%p)->(%p): stub\n", This, ppEnum);
+
+    return E_NOTIMPL;
+}
+
+static const IConnectionPointVtbl ConnectionPointVtbl =
+{
+    ConnectionPoint_QueryInterface,
+    ConnectionPoint_AddRef,
+    ConnectionPoint_Release,
+    ConnectionPoint_GetConnectionInterface,
+    ConnectionPoint_GetConnectionPointContainer,
+    ConnectionPoint_Advise,
+    ConnectionPoint_Unadvise,
+    ConnectionPoint_EnumConnections
+};
+
+static void ConnectionPoint_Init(ConnectionPoint *cp, ScriptControl *sc, REFIID riid)
+{
+    cp->IConnectionPoint_iface.lpVtbl = &ConnectionPointVtbl;
+    cp->control = sc;
+    cp->riid = riid;
+
+    cp->next = sc->cp_list;
+    sc->cp_list = cp;
+
+    cp->container = &sc->IConnectionPointContainer_iface;
+}
+
 static HRESULT WINAPI ScriptControl_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
 {
     ScriptControl *script_control;
@@ -929,6 +1069,10 @@ static HRESULT WINAPI ScriptControl_CreateInstance(IClassFactory *iface, IUnknow
     script_control->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl;
     script_control->ref = 1;
     script_control->site = NULL;
+    script_control->cp_list = NULL;
+
+    ConnectionPoint_Init(&script_control->cp_scsource, script_control, &DIID_DScriptControlSource);
+    ConnectionPoint_Init(&script_control->cp_propnotif, script_control, &IID_IPropertyNotifySink);
 
     hdc = GetDC(0);
     dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
diff --git a/dlls/msscript.ocx/tests/msscript.c b/dlls/msscript.ocx/tests/msscript.c
index be5fee2..89fd197 100644
--- a/dlls/msscript.ocx/tests/msscript.c
+++ b/dlls/msscript.ocx/tests/msscript.c
@@ -783,6 +783,7 @@ if (hr == S_OK)
 static void test_connectionpoints(void)
 {
     IConnectionPointContainer *container;
+    IConnectionPoint *cp;
     IScriptControl *sc;
     HRESULT hr;
 
@@ -796,6 +797,14 @@ static void test_connectionpoints(void)
     EXPECT_REF(sc, 2);
     EXPECT_REF(container, 2);
 
+    hr = IConnectionPointContainer_FindConnectionPoint(container, &IID_IPropertyNotifySink, &cp);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    IConnectionPoint_Release(cp);
+
+    hr = IConnectionPointContainer_FindConnectionPoint(container, &DIID_DScriptControlSource, &cp);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    IConnectionPoint_Release(cp);
+
     IConnectionPointContainer_Release(container);
     IScriptControl_Release(sc);
 }
-- 
2.8.1




More information about the wine-patches mailing list