ChangeSet ID: 21618 CVSROOT: /opt/cvs-commit Module name: wine Changes by: julliard@winehq.org 2005/12/02 04:30:19
Modified files: dlls/shdocvw : events.c shdocvw.h
Log message: Jacek Caban jacek@codeweavers.com Added implementation of IConnectionPoint::Advise and Unadvise.
Patch: http://cvs.winehq.org/patch.py?id=21618
Old revision New revision Changes Path 1.18 1.19 +83 -14 wine/dlls/shdocvw/events.c 1.37 1.38 +7 -3 wine/dlls/shdocvw/shdocvw.h
Index: wine/dlls/shdocvw/events.c diff -u -p wine/dlls/shdocvw/events.c:1.18 wine/dlls/shdocvw/events.c:1.19 --- wine/dlls/shdocvw/events.c:1.18 2 Dec 2005 10:30:19 -0000 +++ wine/dlls/shdocvw/events.c 2 Dec 2005 10:30:19 -0000 @@ -27,13 +27,16 @@
WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
-typedef struct { +struct ConnectionPoint { const IConnectionPointVtbl *lpConnectionPointVtbl;
WebBrowser *webbrowser;
+ IDispatch **sinks; + DWORD sinks_size; + IID iid; -} ConnectionPoint; +};
#define CONPOINT(x) ((IConnectionPoint*) &(x)->lpConnectionPointVtbl)
@@ -84,13 +87,13 @@ static HRESULT WINAPI ConnectionPointCon
if(IsEqualGUID(&DIID_DWebBrowserEvents2, riid)) { TRACE("(%p)->(DIID_DWebBrowserEvents2 %p)\n", This, ppCP); - *ppCP = This->cp_wbe2; + *ppCP = CONPOINT(This->cp_wbe2); }else if(IsEqualGUID(&DIID_DWebBrowserEvents, riid)) { TRACE("(%p)->(DIID_DWebBrowserEvents %p)\n", This, ppCP); - *ppCP = This->cp_wbe; + *ppCP = CONPOINT(This->cp_wbe); }else if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) { TRACE("(%p)->(IID_IPropertyNotifySink %p)\n", This, ppCP); - *ppCP = This->cp_pns; + *ppCP = CONPOINT(This->cp_pns); }
if(*ppCP) { @@ -181,15 +184,53 @@ static HRESULT WINAPI ConnectionPoint_Ad DWORD *pdwCookie) { ConnectionPoint *This = CONPOINT_THIS(iface); - FIXME("(%p)->(%p %p)\n", This, pUnkSink, pdwCookie); - return E_NOTIMPL; + IDispatch *disp; + DWORD i; + HRESULT hres; + + TRACE("(%p)->(%p %p)\n", This, pUnkSink, pdwCookie); + + hres = IUnknown_QueryInterface(pUnkSink, &This->iid, (void**)&disp); + if(FAILED(hres)) { + hres = IUnknown_QueryInterface(pUnkSink, &IID_IDispatch, (void**)&disp); + if(FAILED(hres)) + return CONNECT_E_CANNOTCONNECT; + } + + if(This->sinks) { + for(i=0; i<This->sinks_size; i++) { + if(!This->sinks[i]) + break; + } + + if(i == This->sinks_size) + This->sinks = HeapReAlloc(GetProcessHeap(), 0, This->sinks, + (++This->sinks_size)*sizeof(*This->sinks)); + }else { + This->sinks = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->sinks)); + This->sinks_size = 1; + i = 0; + } + + This->sinks[i] = disp; + *pdwCookie = i+1; + + return S_OK; }
static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie) { ConnectionPoint *This = CONPOINT_THIS(iface); - FIXME("(%p)->(%ld)\n", This, dwCookie); - return E_NOTIMPL; + + TRACE("(%p)->(%ld)\n", This, dwCookie); + + if(!dwCookie || dwCookie > This->sinks_size || !This->sinks[dwCookie-1]) + return CONNECT_E_NOCONNECTION; + + IDispatch_Release(This->sinks[dwCookie-1]); + This->sinks[dwCookie-1] = NULL; + + return S_OK; }
static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface, @@ -214,15 +255,43 @@ static const IConnectionPointVtbl Connec ConnectionPoint_EnumConnections };
-static void ConnectionPoint_Create(WebBrowser *wb, REFIID riid, IConnectionPoint **cp) +void call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams) +{ + DWORD i; + + for(i=0; i<This->sinks_size; i++) { + if(This->sinks[i]) + IDispatch_Invoke(This->sinks[i], dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT, + DISPATCH_METHOD, dispparams, NULL, NULL, NULL); + } +} + +static void ConnectionPoint_Create(WebBrowser *wb, REFIID riid, ConnectionPoint **cp) { ConnectionPoint *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ConnectionPoint));
ret->lpConnectionPointVtbl = &ConnectionPointVtbl; ret->webbrowser = wb; + + ret->sinks = NULL; + ret->sinks_size = 0; + memcpy(&ret->iid, riid, sizeof(IID));
- *cp = CONPOINT(ret); + *cp = ret; +} + +static void ConnectionPoint_Destroy(ConnectionPoint *This) +{ + int i; + + for(i=0; i<This->sinks_size; i++) { + if(This->sinks[i]) + IDispatch_Release(This->sinks[i]); + } + + HeapFree(GetProcessHeap(), 0, This->sinks); + HeapFree(GetProcessHeap(), 0, This); }
void WebBrowser_Events_Init(WebBrowser *This) @@ -236,7 +305,7 @@ void WebBrowser_Events_Init(WebBrowser *
void WebBrowser_Events_Destroy(WebBrowser *This) { - HeapFree(GetProcessHeap(), 0, This->cp_wbe2); - HeapFree(GetProcessHeap(), 0, This->cp_wbe); - HeapFree(GetProcessHeap(), 0, This->cp_pns); + ConnectionPoint_Destroy(This->cp_wbe2); + ConnectionPoint_Destroy(This->cp_wbe); + ConnectionPoint_Destroy(This->cp_pns); } Index: wine/dlls/shdocvw/shdocvw.h diff -u -p wine/dlls/shdocvw/shdocvw.h:1.37 wine/dlls/shdocvw/shdocvw.h:1.38 --- wine/dlls/shdocvw/shdocvw.h:1.37 2 Dec 2005 10:30:19 -0000 +++ wine/dlls/shdocvw/shdocvw.h 2 Dec 2005 10:30:19 -0000 @@ -58,6 +58,9 @@ extern HRESULT SHDOCVW_GetShellInstanceO /********************************************************************** * WebBrowser declaration for SHDOCVW.DLL */ + +typedef struct ConnectionPoint ConnectionPoint; + typedef struct { /* Interfaces available via WebBrowser object */
@@ -109,9 +112,9 @@ typedef struct {
/* Connection points */
- IConnectionPoint *cp_wbe2; - IConnectionPoint *cp_wbe; - IConnectionPoint *cp_pns; + ConnectionPoint *cp_wbe2; + ConnectionPoint *cp_wbe; + ConnectionPoint *cp_pns; } WebBrowser;
#define WEBBROWSER(x) ((IWebBrowser*) &(x)->lpWebBrowser2Vtbl) @@ -155,6 +158,7 @@ void WebBrowser_ClientSite_Destroy(WebBr HRESULT WebBrowser_Create(IUnknown*,REFIID,void**);
void create_doc_view_hwnd(WebBrowser *This); +void call_sink(ConnectionPoint*,DISPID,DISPPARAMS*);
#define WB_WM_NAVIGATE2 (WM_USER+100)