From 5b9a7cbf3aeec80404d857539cb18df4ee8ee801 Mon Sep 17 00:00:00 2001 From: Huw D M Davies Date: Sat, 8 Jul 2000 11:46:54 +0000 Subject: [PATCH] Implement IDataAdviseHolder. --- dlls/ole32/compobj.c | 2 +- dlls/ole32/oleobj.c | 198 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 171 insertions(+), 29 deletions(-) diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 1ea9d139fad..00ef5f84998 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -1384,7 +1384,7 @@ HRESULT WINAPI CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, return REGDB_E_READREGDB; TRACE("found InprocServer32 dll %s\n", debugstr_w(dllName)); - /* open dll, call DllGetClassFactory */ + /* open dll, call DllGetClassObject */ hLibrary = CoLoadLibrary(dllName, TRUE); if (hLibrary == 0) { FIXME("couldn't load InprocServer32 dll %s\n", debugstr_w(dllName)); diff --git a/dlls/ole32/oleobj.c b/dlls/ole32/oleobj.c index 870a450cb37..06c13398962 100644 --- a/dlls/ole32/oleobj.c +++ b/dlls/ole32/oleobj.c @@ -14,6 +14,7 @@ DEFAULT_DEBUG_CHANNEL(ole) +#define INITIAL_SINKS 10 /************************************************************************** * OleAdviseHolderImpl Implementation @@ -74,7 +75,7 @@ static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor() ICOM_VTBL(lpoah) = &oahvt; lpoah->ref = 1; - lpoah->maxSinks = 10; + lpoah->maxSinks = INITIAL_SINKS; lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(), 0, lpoah->maxSinks * sizeof(IAdviseSink*)); @@ -82,6 +83,7 @@ static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor() for (index = 0; index < lpoah->maxSinks; index++) lpoah->arrayOfSinks[index]=0; + TRACE("returning %p\n", lpoah); return (LPOLEADVISEHOLDER)lpoah; } @@ -92,6 +94,7 @@ static void OleAdviseHolderImpl_Destructor( OleAdviseHolderImpl* ptrToDestroy) { DWORD index; + TRACE("%p\n", ptrToDestroy); for (index = 0; index < ptrToDestroy->maxSinks; index++) { @@ -121,7 +124,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface( LPVOID* ppvObj) { ICOM_THIS(OleAdviseHolderImpl, iface); - + TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObj); /* * Sanity check */ @@ -159,7 +162,7 @@ static ULONG WINAPI OleAdviseHolderImpl_AddRef( LPOLEADVISEHOLDER iface) { ICOM_THIS(OleAdviseHolderImpl, iface); - + TRACE("(%p)->(ref=%ld)\n", This, This->ref); return ++(This->ref); } @@ -170,7 +173,7 @@ static ULONG WINAPI OleAdviseHolderImpl_Release( LPOLEADVISEHOLDER iface) { ICOM_THIS(OleAdviseHolderImpl, iface); - + TRACE("(%p)->(ref=%ld)\n", This, This->ref); This->ref--; if (This->ref == 0) @@ -195,7 +198,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_Advise( ICOM_THIS(OleAdviseHolderImpl, iface); - TRACE("(%p, %p, %p)\n", This, pAdvise, pdwConnection); + TRACE("(%p)->(%p, %p)\n", This, pAdvise, pdwConnection); /* * Sanity check @@ -221,7 +224,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_Advise( { DWORD i; - This->maxSinks+=10; + This->maxSinks+=INITIAL_SINKS; This->arrayOfSinks = HeapReAlloc(GetProcessHeap(), 0, @@ -259,7 +262,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_Unadvise( { ICOM_THIS(OleAdviseHolderImpl, iface); - TRACE("(%p, %lu)\n", This, dwConnection); + TRACE("(%p)->(%lu)\n", This, dwConnection); /* * So we don't return 0 as a cookie, the index was @@ -293,7 +296,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_Unadvise( static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise) { - ICOM_THIS(OleAdviseHolderImpl, iface); + ICOM_THIS(OleAdviseHolderImpl, iface); FIXME("(%p)->(%p)\n", This, ppenumAdvise); *ppenumAdvise = NULL; @@ -307,7 +310,7 @@ OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumA static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk) { - ICOM_THIS(OleAdviseHolderImpl, iface); + ICOM_THIS(OleAdviseHolderImpl, iface); FIXME("(%p)->(%p)\n", This, pmk); @@ -320,10 +323,9 @@ OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk) static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface) { - ICOM_THIS(OleAdviseHolderImpl, iface); + ICOM_THIS(OleAdviseHolderImpl, iface); FIXME("(%p)\n", This); - return S_OK; } @@ -333,7 +335,7 @@ OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface) static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface) { - ICOM_THIS(OleAdviseHolderImpl, iface); + ICOM_THIS(OleAdviseHolderImpl, iface); FIXME("(%p)\n", This); @@ -343,11 +345,19 @@ OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface) /************************************************************************** * DataAdviseHolder Implementation */ +typedef struct DataAdviseConnection { + IAdviseSink *sink; + FORMATETC fmat; + DWORD advf; +} DataAdviseConnection; + typedef struct DataAdviseHolder { ICOM_VFIELD(IDataAdviseHolder); - DWORD ref; + DWORD ref; + DWORD maxCons; + DataAdviseConnection* Connections; } DataAdviseHolder; /************************************************************************** @@ -410,19 +420,35 @@ static IDataAdviseHolder* DataAdviseHolder_Constructor() ICOM_VTBL(newHolder) = &DataAdviseHolderImpl_VTable; newHolder->ref = 1; + newHolder->maxCons = INITIAL_SINKS; + newHolder->Connections = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + newHolder->maxCons * + sizeof(DataAdviseConnection)); + TRACE("returning %p\n", newHolder); return (IDataAdviseHolder*)newHolder; } /****************************************************************************** * DataAdviseHolder_Destructor */ -static void DataAdviseHolder_Destructor( - DataAdviseHolder* ptrToDestroy) +static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy) { - HeapFree(GetProcessHeap(), - 0, - ptrToDestroy); + DWORD index; + TRACE("%p\n", ptrToDestroy); + + for (index = 0; index < ptrToDestroy->maxCons; index++) + { + if (ptrToDestroy->Connections[index].sink != NULL) + { + IAdviseSink_Release(ptrToDestroy->Connections[index].sink); + ptrToDestroy->Connections[index].sink = NULL; + } + } + + HeapFree(GetProcessHeap(), 0, ptrToDestroy->Connections); + HeapFree(GetProcessHeap(), 0, ptrToDestroy); } /************************************************************************ @@ -436,7 +462,7 @@ static HRESULT WINAPI DataAdviseHolder_QueryInterface( void** ppvObject) { ICOM_THIS(DataAdviseHolder, iface); - + TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject); /* * Perform a sanity check on the parameters. */ @@ -483,7 +509,7 @@ static ULONG WINAPI DataAdviseHolder_AddRef( IDataAdviseHolder* iface) { ICOM_THIS(DataAdviseHolder, iface); - + TRACE("(%p) (ref=%ld)\n", This, This->ref); This->ref++; return This->ref; @@ -497,7 +523,8 @@ static ULONG WINAPI DataAdviseHolder_AddRef( static ULONG WINAPI DataAdviseHolder_Release( IDataAdviseHolder* iface) { - ICOM_THIS(DataAdviseHolder, iface); + ICOM_THIS(DataAdviseHolder, iface); + TRACE("(%p) (ref=%ld)\n", This, This->ref); /* * Decrease the reference count on this object. @@ -517,6 +544,10 @@ static ULONG WINAPI DataAdviseHolder_Release( return This->ref; } +/************************************************************************ + * DataAdviseHolder_Advise + * + */ static HRESULT WINAPI DataAdviseHolder_Advise( IDataAdviseHolder* iface, IDataObject* pDataObject, @@ -525,34 +556,145 @@ static HRESULT WINAPI DataAdviseHolder_Advise( IAdviseSink* pAdvise, DWORD* pdwConnection) { - FIXME("(): stub\n"); - return E_NOTIMPL; + DWORD index; + + ICOM_THIS(DataAdviseHolder, iface); + + TRACE("(%p)->(%p, %p, %08lx, %p, %p)\n", This, pDataObject, pFetc, advf, + pAdvise, pdwConnection); + /* + * Sanity check + */ + if (pdwConnection==NULL) + return E_POINTER; + + *pdwConnection = 0; + + /* + * Find a free spot in the array. + */ + for (index = 0; index < This->maxCons; index++) + { + if (This->Connections[index].sink == NULL) + break; + } + + /* + * If the array is full, we need to grow it. + */ + if (index == This->maxCons) + { + This->maxCons+=INITIAL_SINKS; + This->Connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + This->Connections, + This->maxCons*sizeof(DataAdviseConnection)); + } + /* + * Store the new sink + */ + This->Connections[index].sink = pAdvise; + memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC)); + This->Connections[index].advf = advf; + + if (This->Connections[index].sink != NULL) { + IAdviseSink_AddRef(This->Connections[index].sink); + if(advf & ADVF_PRIMEFIRST) { + DataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf); + } + } + /* + * Return the index as the cookie. + * Since 0 is not a valid cookie, we will increment by + * 1 the index in the table. + */ + *pdwConnection = index+1; + + return S_OK; } +/****************************************************************************** + * DataAdviseHolder_Unadvise + */ static HRESULT WINAPI DataAdviseHolder_Unadvise( IDataAdviseHolder* iface, DWORD dwConnection) { - FIXME("(): stub\n"); - return E_NOTIMPL; + ICOM_THIS(DataAdviseHolder, iface); + + TRACE("(%p)->(%lu)\n", This, dwConnection); + + /* + * So we don't return 0 as a cookie, the index was + * incremented by 1 in OleAdviseHolderImpl_Advise + * we have to compensate. + */ + dwConnection--; + + /* + * Check for invalid cookies. + */ + if ( (dwConnection < 0) || + (dwConnection >= This->maxCons) ) + return OLE_E_NOCONNECTION; + + if (This->Connections[dwConnection].sink == NULL) + return OLE_E_NOCONNECTION; + + /* + * Release the sink and mark the spot in the list as free. + */ + IAdviseSink_Release(This->Connections[dwConnection].sink); + memset(&(This->Connections[dwConnection]), 0, sizeof(DataAdviseConnection)); + return S_OK; } static HRESULT WINAPI DataAdviseHolder_EnumAdvise( IDataAdviseHolder* iface, IEnumSTATDATA** ppenumAdvise) { - FIXME("(): stub\n"); + ICOM_THIS(DataAdviseHolder, iface); + + FIXME("(%p)->(%p)\n", This, ppenumAdvise); return E_NOTIMPL; } +/****************************************************************************** + * DataAdviseHolder_SendOnDataChange + */ static HRESULT WINAPI DataAdviseHolder_SendOnDataChange( IDataAdviseHolder* iface, IDataObject* pDataObject, DWORD dwReserved, DWORD advf) { - FIXME("(): stub\n"); - return E_NOTIMPL; + ICOM_THIS(DataAdviseHolder, iface); + DWORD index; + STGMEDIUM stg; + HRESULT res; + + TRACE("(%p)->(%p,%08lx,%08lx)\n", This, pDataObject, dwReserved, advf); + + for(index = 0; index < This->maxCons; index++) { + if(This->Connections[index].sink != NULL) { + if(!(This->Connections[index].advf & ADVF_NODATA)) { + TRACE("Calling IDataObject_GetData\n"); + res = IDataObject_GetData(pDataObject, + &(This->Connections[index].fmat), + &stg); + TRACE("returns %08lx\n", res); + } + TRACE("Calling IAdviseSink_OnDataChange\n"); + IAdviseSink_OnDataChange(This->Connections[index].sink, + &(This->Connections[index].fmat), + &stg); + TRACE("Done IAdviseSink_OnDataChange\n"); + if(This->Connections[index].advf & ADVF_ONLYONCE) { + TRACE("Removing connection\n"); + DataAdviseHolder_Unadvise(iface, index+1); + } + } + } + return S_OK; } /*********************************************************************** -- 2.11.4.GIT