4 * Copyright 1999 Francis Beaudet
5 * Copyright 2000 Abey George
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * The OLE2 data cache supports a whole whack of
23 * interfaces including:
24 * IDataObject, IPersistStorage, IViewObject2,
25 * IOleCache2 and IOleCacheControl.
27 * Most of the implementation details are taken from: Inside OLE
28 * second edition by Kraig Brockschmidt,
31 * - This implementation of the datacache will let your application
32 * load documents that have embedded OLE objects in them and it will
33 * also retrieve the metafile representation of those objects.
34 * - This implementation of the datacache will also allow your
35 * application to save new documents with OLE objects in them.
36 * - The main thing that it doesn't do is allow you to activate
37 * or modify the OLE objects in any way.
38 * - I haven't found any good documentation on the real usage of
39 * the streams created by the data cache. In particular, How to
40 * determine what the XXX stands for in the stream name
41 * "\002OlePresXXX". It appears to just be a counter.
42 * - Also, I don't know the real content of the presentation stream
43 * header. I was able to figure-out where the extent of the object
44 * was stored and the aspect, but that's about it.
50 #define NONAMELESSUNION
51 #define NONAMELESSSTRUCT
57 #include "wine/unicode.h"
59 #include "wine/debug.h"
61 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
63 /****************************************************************************
64 * PresentationDataHeader
66 * This structure represents the header of the \002OlePresXXX stream in
67 * the OLE object strorage.
69 * Most fields are still unknown.
71 typedef struct PresentationDataHeader
73 DWORD unknown1
; /* -1 */
74 DWORD unknown2
; /* 3, possibly CF_METAFILEPICT */
75 DWORD unknown3
; /* 4, possibly TYMED_ISTREAM */
77 DWORD unknown5
; /* -1 */
80 DWORD unknown7
; /* 0 */
81 DWORD dwObjectExtentX
;
82 DWORD dwObjectExtentY
;
84 } PresentationDataHeader
;
86 /****************************************************************************
92 * List all interface VTables here
94 ICOM_VTABLE(IDataObject
)* lpvtbl1
;
95 ICOM_VTABLE(IUnknown
)* lpvtbl2
;
96 ICOM_VTABLE(IPersistStorage
)* lpvtbl3
;
97 ICOM_VTABLE(IViewObject2
)* lpvtbl4
;
98 ICOM_VTABLE(IOleCache2
)* lpvtbl5
;
99 ICOM_VTABLE(IOleCacheControl
)* lpvtbl6
;
102 * Reference count of this object
107 * IUnknown implementation of the outer object.
109 IUnknown
* outerUnknown
;
112 * This storage pointer is set through a call to
113 * IPersistStorage_Load. This is where the visual
114 * representation of the object is stored.
116 IStorage
* presentationStorage
;
119 * The user of this object can setup ONE advise sink
120 * connection with the object. These parameters describe
124 DWORD sinkAdviseFlag
;
125 IAdviseSink
* sinkInterface
;
129 typedef struct DataCache DataCache
;
132 * Here, I define utility macros to help with the casting of the
134 * There is a version to accomodate all of the VTables implemented
137 #define _ICOM_THIS_From_IDataObject(class,name) class* this = (class*)name;
138 #define _ICOM_THIS_From_NDIUnknown(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
139 #define _ICOM_THIS_From_IPersistStorage(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
140 #define _ICOM_THIS_From_IViewObject2(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
141 #define _ICOM_THIS_From_IOleCache2(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*));
142 #define _ICOM_THIS_From_IOleCacheControl(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*));
145 * Prototypes for the methods of the DataCache class.
147 static DataCache
* DataCache_Construct(REFCLSID clsid
,
148 LPUNKNOWN pUnkOuter
);
149 static void DataCache_Destroy(DataCache
* ptrToDestroy
);
150 static HRESULT
DataCache_ReadPresentationData(DataCache
* this,
152 PresentationDataHeader
* header
);
153 static HRESULT
DataCache_OpenPresStream(DataCache
*this,
156 static HMETAFILE
DataCache_ReadPresMetafile(DataCache
* this,
158 static void DataCache_FireOnViewChange(DataCache
* this,
163 * Prototypes for the methods of the DataCache class
164 * that implement non delegating IUnknown methods.
166 static HRESULT WINAPI
DataCache_NDIUnknown_QueryInterface(
170 static ULONG WINAPI
DataCache_NDIUnknown_AddRef(
172 static ULONG WINAPI
DataCache_NDIUnknown_Release(
176 * Prototypes for the methods of the DataCache class
177 * that implement IDataObject methods.
179 static HRESULT WINAPI
DataCache_IDataObject_QueryInterface(
183 static ULONG WINAPI
DataCache_IDataObject_AddRef(
185 static ULONG WINAPI
DataCache_IDataObject_Release(
187 static HRESULT WINAPI
DataCache_GetData(
189 LPFORMATETC pformatetcIn
,
191 static HRESULT WINAPI
DataCache_GetDataHere(
193 LPFORMATETC pformatetc
,
195 static HRESULT WINAPI
DataCache_QueryGetData(
197 LPFORMATETC pformatetc
);
198 static HRESULT WINAPI
DataCache_GetCanonicalFormatEtc(
200 LPFORMATETC pformatectIn
,
201 LPFORMATETC pformatetcOut
);
202 static HRESULT WINAPI
DataCache_IDataObject_SetData(
204 LPFORMATETC pformatetc
,
207 static HRESULT WINAPI
DataCache_EnumFormatEtc(
210 IEnumFORMATETC
** ppenumFormatEtc
);
211 static HRESULT WINAPI
DataCache_DAdvise(
213 FORMATETC
* pformatetc
,
215 IAdviseSink
* pAdvSink
,
216 DWORD
* pdwConnection
);
217 static HRESULT WINAPI
DataCache_DUnadvise(
220 static HRESULT WINAPI
DataCache_EnumDAdvise(
222 IEnumSTATDATA
** ppenumAdvise
);
225 * Prototypes for the methods of the DataCache class
226 * that implement IPersistStorage methods.
228 static HRESULT WINAPI
DataCache_IPersistStorage_QueryInterface(
229 IPersistStorage
* iface
,
232 static ULONG WINAPI
DataCache_IPersistStorage_AddRef(
233 IPersistStorage
* iface
);
234 static ULONG WINAPI
DataCache_IPersistStorage_Release(
235 IPersistStorage
* iface
);
236 static HRESULT WINAPI
DataCache_GetClassID(
237 IPersistStorage
* iface
,
239 static HRESULT WINAPI
DataCache_IsDirty(
240 IPersistStorage
* iface
);
241 static HRESULT WINAPI
DataCache_InitNew(
242 IPersistStorage
* iface
,
244 static HRESULT WINAPI
DataCache_Load(
245 IPersistStorage
* iface
,
247 static HRESULT WINAPI
DataCache_Save(
248 IPersistStorage
* iface
,
251 static HRESULT WINAPI
DataCache_SaveCompleted(
252 IPersistStorage
* iface
,
254 static HRESULT WINAPI
DataCache_HandsOffStorage(
255 IPersistStorage
* iface
);
258 * Prototypes for the methods of the DataCache class
259 * that implement IViewObject2 methods.
261 static HRESULT WINAPI
DataCache_IViewObject2_QueryInterface(
265 static ULONG WINAPI
DataCache_IViewObject2_AddRef(
266 IViewObject2
* iface
);
267 static ULONG WINAPI
DataCache_IViewObject2_Release(
268 IViewObject2
* iface
);
269 static HRESULT WINAPI
DataCache_Draw(
278 LPCRECTL lprcWBounds
,
279 BOOL (CALLBACK
*pfnContinue
)(ULONG_PTR dwContinue
),
281 static HRESULT WINAPI
DataCache_GetColorSet(
288 LOGPALETTE
** ppColorSet
);
289 static HRESULT WINAPI
DataCache_Freeze(
295 static HRESULT WINAPI
DataCache_Unfreeze(
298 static HRESULT WINAPI
DataCache_SetAdvise(
302 IAdviseSink
* pAdvSink
);
303 static HRESULT WINAPI
DataCache_GetAdvise(
307 IAdviseSink
** ppAdvSink
);
308 static HRESULT WINAPI
DataCache_GetExtent(
316 * Prototypes for the methods of the DataCache class
317 * that implement IOleCache2 methods.
319 static HRESULT WINAPI
DataCache_IOleCache2_QueryInterface(
323 static ULONG WINAPI
DataCache_IOleCache2_AddRef(
325 static ULONG WINAPI
DataCache_IOleCache2_Release(
327 static HRESULT WINAPI
DataCache_Cache(
329 FORMATETC
* pformatetc
,
331 DWORD
* pdwConnection
);
332 static HRESULT WINAPI
DataCache_Uncache(
335 static HRESULT WINAPI
DataCache_EnumCache(
337 IEnumSTATDATA
** ppenumSTATDATA
);
338 static HRESULT WINAPI
DataCache_InitCache(
340 IDataObject
* pDataObject
);
341 static HRESULT WINAPI
DataCache_IOleCache2_SetData(
343 FORMATETC
* pformatetc
,
346 static HRESULT WINAPI
DataCache_UpdateCache(
348 LPDATAOBJECT pDataObject
,
351 static HRESULT WINAPI
DataCache_DiscardCache(
353 DWORD dwDiscardOptions
);
356 * Prototypes for the methods of the DataCache class
357 * that implement IOleCacheControl methods.
359 static HRESULT WINAPI
DataCache_IOleCacheControl_QueryInterface(
360 IOleCacheControl
* iface
,
363 static ULONG WINAPI
DataCache_IOleCacheControl_AddRef(
364 IOleCacheControl
* iface
);
365 static ULONG WINAPI
DataCache_IOleCacheControl_Release(
366 IOleCacheControl
* iface
);
367 static HRESULT WINAPI
DataCache_OnRun(
368 IOleCacheControl
* iface
,
369 LPDATAOBJECT pDataObject
);
370 static HRESULT WINAPI
DataCache_OnStop(
371 IOleCacheControl
* iface
);
374 * Virtual function tables for the DataCache class.
376 static ICOM_VTABLE(IUnknown
) DataCache_NDIUnknown_VTable
=
378 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
379 DataCache_NDIUnknown_QueryInterface
,
380 DataCache_NDIUnknown_AddRef
,
381 DataCache_NDIUnknown_Release
384 static ICOM_VTABLE(IDataObject
) DataCache_IDataObject_VTable
=
386 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
387 DataCache_IDataObject_QueryInterface
,
388 DataCache_IDataObject_AddRef
,
389 DataCache_IDataObject_Release
,
391 DataCache_GetDataHere
,
392 DataCache_QueryGetData
,
393 DataCache_GetCanonicalFormatEtc
,
394 DataCache_IDataObject_SetData
,
395 DataCache_EnumFormatEtc
,
398 DataCache_EnumDAdvise
401 static ICOM_VTABLE(IPersistStorage
) DataCache_IPersistStorage_VTable
=
403 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
404 DataCache_IPersistStorage_QueryInterface
,
405 DataCache_IPersistStorage_AddRef
,
406 DataCache_IPersistStorage_Release
,
407 DataCache_GetClassID
,
412 DataCache_SaveCompleted
,
413 DataCache_HandsOffStorage
416 static ICOM_VTABLE(IViewObject2
) DataCache_IViewObject2_VTable
=
418 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
419 DataCache_IViewObject2_QueryInterface
,
420 DataCache_IViewObject2_AddRef
,
421 DataCache_IViewObject2_Release
,
423 DataCache_GetColorSet
,
431 static ICOM_VTABLE(IOleCache2
) DataCache_IOleCache2_VTable
=
433 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
434 DataCache_IOleCache2_QueryInterface
,
435 DataCache_IOleCache2_AddRef
,
436 DataCache_IOleCache2_Release
,
441 DataCache_IOleCache2_SetData
,
442 DataCache_UpdateCache
,
443 DataCache_DiscardCache
446 static ICOM_VTABLE(IOleCacheControl
) DataCache_IOleCacheControl_VTable
=
448 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
449 DataCache_IOleCacheControl_QueryInterface
,
450 DataCache_IOleCacheControl_AddRef
,
451 DataCache_IOleCacheControl_Release
,
456 /******************************************************************************
457 * CreateDataCache [OLE32.@]
459 HRESULT WINAPI
CreateDataCache(
465 DataCache
* newCache
= NULL
;
468 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(rclsid
), pUnkOuter
, debugstr_guid(riid
), ppvObj
);
479 * If this cache is constructed for aggregation, make sure
480 * the caller is requesting the IUnknown interface.
481 * This is necessary because it's the only time the non-delegating
482 * IUnknown pointer can be returned to the outside.
484 if ( (pUnkOuter
!=NULL
) &&
485 (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) != 0) )
486 return CLASS_E_NOAGGREGATION
;
489 * Try to construct a new instance of the class.
491 newCache
= DataCache_Construct(rclsid
,
495 return E_OUTOFMEMORY
;
498 * Make sure it supports the interface required by the caller.
500 hr
= IUnknown_QueryInterface((IUnknown
*)&(newCache
->lpvtbl2
), riid
, ppvObj
);
503 * Release the reference obtained in the constructor. If
504 * the QueryInterface was unsuccessful, it will free the class.
506 IUnknown_Release((IUnknown
*)&(newCache
->lpvtbl2
));
511 /*********************************************************
512 * Method implementation for DataCache class.
514 static DataCache
* DataCache_Construct(
518 DataCache
* newObject
= 0;
521 * Allocate space for the object.
523 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache
));
529 * Initialize the virtual function table.
531 newObject
->lpvtbl1
= &DataCache_IDataObject_VTable
;
532 newObject
->lpvtbl2
= &DataCache_NDIUnknown_VTable
;
533 newObject
->lpvtbl3
= &DataCache_IPersistStorage_VTable
;
534 newObject
->lpvtbl4
= &DataCache_IViewObject2_VTable
;
535 newObject
->lpvtbl5
= &DataCache_IOleCache2_VTable
;
536 newObject
->lpvtbl6
= &DataCache_IOleCacheControl_VTable
;
539 * Start with one reference count. The caller of this function
540 * must release the interface pointer when it is done.
545 * Initialize the outer unknown
546 * We don't keep a reference on the outer unknown since, the way
547 * aggregation works, our lifetime is at least as large as it's
551 pUnkOuter
= (IUnknown
*)&(newObject
->lpvtbl2
);
553 newObject
->outerUnknown
= pUnkOuter
;
556 * Initialize the other members of the structure.
558 newObject
->presentationStorage
= NULL
;
559 newObject
->sinkAspects
= 0;
560 newObject
->sinkAdviseFlag
= 0;
561 newObject
->sinkInterface
= 0;
566 static void DataCache_Destroy(
567 DataCache
* ptrToDestroy
)
571 if (ptrToDestroy
->sinkInterface
!= NULL
)
573 IAdviseSink_Release(ptrToDestroy
->sinkInterface
);
574 ptrToDestroy
->sinkInterface
= NULL
;
577 if (ptrToDestroy
->presentationStorage
!= NULL
)
579 IStorage_Release(ptrToDestroy
->presentationStorage
);
580 ptrToDestroy
->presentationStorage
= NULL
;
584 * Free the datacache pointer.
586 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
589 /************************************************************************
590 * DataCache_ReadPresentationData
592 * This method will read information for the requested presentation
593 * into the given structure.
596 * this - Pointer to the DataCache object
597 * drawAspect - The aspect of the object that we wish to draw.
598 * header - The structure containing information about this
599 * aspect of the object.
601 static HRESULT
DataCache_ReadPresentationData(
604 PresentationDataHeader
* header
)
606 IStream
* presStream
= NULL
;
610 * Open the presentation stream.
612 hres
= DataCache_OpenPresStream(
627 sizeof(PresentationDataHeader
),
633 IStream_Release(presStream
);
636 * We don't want to propagate any other error
637 * code than a failure.
645 /************************************************************************
646 * DataCache_FireOnViewChange
648 * This method will fire an OnViewChange notification to the advise
649 * sink registered with the datacache.
651 * See IAdviseSink::OnViewChange for more details.
653 static void DataCache_FireOnViewChange(
658 TRACE("(%p, %lx, %ld)\n", this, aspect
, lindex
);
661 * The sink supplies a filter when it registers
662 * we make sure we only send the notifications when that
665 if ((this->sinkAspects
& aspect
) != 0)
667 if (this->sinkInterface
!= NULL
)
669 IAdviseSink_OnViewChange(this->sinkInterface
,
674 * Some sinks want to be unregistered automatically when
675 * the first notification goes out.
677 if ( (this->sinkAdviseFlag
& ADVF_ONLYONCE
) != 0)
679 IAdviseSink_Release(this->sinkInterface
);
681 this->sinkInterface
= NULL
;
682 this->sinkAspects
= 0;
683 this->sinkAdviseFlag
= 0;
689 /* Helper for DataCache_OpenPresStream */
690 static BOOL
DataCache_IsPresentationStream(const STATSTG
*elem
)
692 /* The presentation streams have names of the form "\002OlePresXXX",
693 * where XXX goes from 000 to 999. */
694 static const WCHAR OlePres
[] = { 2,'O','l','e','P','r','e','s' };
696 LPCWSTR name
= elem
->pwcsName
;
698 return (elem
->type
== STGTY_STREAM
)
699 && (elem
->cbSize
.s
.LowPart
>= sizeof(PresentationDataHeader
))
700 && (strlenW(name
) == 11)
701 && (strncmpW(name
, OlePres
, 8) == 0)
702 && (name
[8] >= '0') && (name
[8] <= '9')
703 && (name
[9] >= '0') && (name
[9] <= '9')
704 && (name
[10] >= '0') && (name
[10] <= '9');
707 /************************************************************************
708 * DataCache_OpenPresStream
710 * This method will find the stream for the given presentation. It makes
711 * no attempt at fallback.
714 * this - Pointer to the DataCache object
715 * drawAspect - The aspect of the object that we wish to draw.
716 * pStm - A returned stream. It points to the beginning of the
717 * - presentation data, including the header.
720 * S_OK The requested stream has been opened.
721 * OLE_E_BLANK The requested stream could not be found.
722 * Quite a few others I'm too lazy to map correctly.
725 * Algorithm: Scan the elements of the presentation storage, looking
726 * for presentation streams. For each presentation stream,
727 * load the header and check to see if the aspect maches.
729 * If a fallback is desired, just opening the first presentation stream
732 static HRESULT
DataCache_OpenPresStream(
741 if (!ppStm
) return E_POINTER
;
743 hr
= IStorage_EnumElements(this->presentationStorage
, 0, NULL
, 0, &pEnum
);
744 if (FAILED(hr
)) return hr
;
746 while ((hr
= IEnumSTATSTG_Next(pEnum
, 1, &elem
, NULL
)) == S_OK
)
748 if (DataCache_IsPresentationStream(&elem
))
752 hr
= IStorage_OpenStream(this->presentationStorage
, elem
.pwcsName
,
753 NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0,
757 PresentationDataHeader header
;
760 hr
= IStream_Read(pStm
, &header
, sizeof(header
), &actual_read
);
762 /* can't use SUCCEEDED(hr): S_FALSE counts as an error */
763 if (hr
== S_OK
&& actual_read
== sizeof(header
)
764 && header
.dvAspect
== drawAspect
)
766 /* Rewind the stream before returning it. */
767 LARGE_INTEGER offset
;
768 offset
.s
.LowPart
= 0;
769 offset
.s
.HighPart
= 0;
770 IStream_Seek(pStm
, offset
, STREAM_SEEK_SET
, NULL
);
774 CoTaskMemFree(elem
.pwcsName
);
775 IEnumSTATSTG_Release(pEnum
);
780 IStream_Release(pStm
);
784 CoTaskMemFree(elem
.pwcsName
);
787 IEnumSTATSTG_Release(pEnum
);
789 return (hr
== S_FALSE
? OLE_E_BLANK
: hr
);
792 /************************************************************************
793 * DataCache_ReadPresentationData
795 * This method will read information for the requested presentation
796 * into the given structure.
799 * this - Pointer to the DataCache object
800 * drawAspect - The aspect of the object that we wish to draw.
803 * This method returns a metafile handle if it is successful.
804 * it will return 0 if not.
806 static HMETAFILE
DataCache_ReadPresMetafile(
810 LARGE_INTEGER offset
;
811 IStream
* presStream
= NULL
;
815 HMETAFILE newMetafile
= 0;
818 * Open the presentation stream.
820 hres
= DataCache_OpenPresStream(
826 return (HMETAFILE
)hres
;
829 * Get the size of the stream.
831 hres
= IStream_Stat(presStream
,
838 offset
.s
.HighPart
= 0;
839 offset
.s
.LowPart
= sizeof(PresentationDataHeader
);
847 streamInfo
.cbSize
.s
.LowPart
-= offset
.s
.LowPart
;
850 * Allocate a buffer for the metafile bits.
852 metafileBits
= HeapAlloc(GetProcessHeap(),
854 streamInfo
.cbSize
.s
.LowPart
);
857 * Read the metafile bits.
862 streamInfo
.cbSize
.s
.LowPart
,
866 * Create a metafile with those bits.
870 newMetafile
= SetMetaFileBitsEx(streamInfo
.cbSize
.s
.LowPart
, metafileBits
);
876 HeapFree(GetProcessHeap(), 0, metafileBits
);
877 IStream_Release(presStream
);
885 /*********************************************************
886 * Method implementation for the non delegating IUnknown
887 * part of the DataCache class.
890 /************************************************************************
891 * DataCache_NDIUnknown_QueryInterface (IUnknown)
893 * See Windows documentation for more details on IUnknown methods.
895 * This version of QueryInterface will not delegate it's implementation
896 * to the outer unknown.
898 static HRESULT WINAPI
DataCache_NDIUnknown_QueryInterface(
903 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
906 * Perform a sanity check on the parameters.
908 if ( (this==0) || (ppvObject
==0) )
912 * Initialize the return parameter.
917 * Compare the riid with the interface IDs implemented by this object.
919 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
923 else if (memcmp(&IID_IDataObject
, riid
, sizeof(IID_IDataObject
)) == 0)
925 *ppvObject
= (IDataObject
*)&(this->lpvtbl1
);
927 else if ( (memcmp(&IID_IPersistStorage
, riid
, sizeof(IID_IPersistStorage
)) == 0) ||
928 (memcmp(&IID_IPersist
, riid
, sizeof(IID_IPersist
)) == 0) )
930 *ppvObject
= (IPersistStorage
*)&(this->lpvtbl3
);
932 else if ( (memcmp(&IID_IViewObject
, riid
, sizeof(IID_IViewObject
)) == 0) ||
933 (memcmp(&IID_IViewObject2
, riid
, sizeof(IID_IViewObject2
)) == 0) )
935 *ppvObject
= (IViewObject2
*)&(this->lpvtbl4
);
937 else if ( (memcmp(&IID_IOleCache
, riid
, sizeof(IID_IOleCache
)) == 0) ||
938 (memcmp(&IID_IOleCache2
, riid
, sizeof(IID_IOleCache2
)) == 0) )
940 *ppvObject
= (IOleCache2
*)&(this->lpvtbl5
);
942 else if (memcmp(&IID_IOleCacheControl
, riid
, sizeof(IID_IOleCacheControl
)) == 0)
944 *ppvObject
= (IOleCacheControl
*)&(this->lpvtbl6
);
948 * Check that we obtained an interface.
952 WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid
));
953 return E_NOINTERFACE
;
957 * Query Interface always increases the reference count by one when it is
960 IUnknown_AddRef((IUnknown
*)*ppvObject
);
965 /************************************************************************
966 * DataCache_NDIUnknown_AddRef (IUnknown)
968 * See Windows documentation for more details on IUnknown methods.
970 * This version of QueryInterface will not delegate it's implementation
971 * to the outer unknown.
973 static ULONG WINAPI
DataCache_NDIUnknown_AddRef(
976 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
983 /************************************************************************
984 * DataCache_NDIUnknown_Release (IUnknown)
986 * See Windows documentation for more details on IUnknown methods.
988 * This version of QueryInterface will not delegate it's implementation
989 * to the outer unknown.
991 static ULONG WINAPI
DataCache_NDIUnknown_Release(
994 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
997 * Decrease the reference count on this object.
1002 * If the reference count goes down to 0, perform suicide.
1006 DataCache_Destroy(this);
1014 /*********************************************************
1015 * Method implementation for the IDataObject
1016 * part of the DataCache class.
1019 /************************************************************************
1020 * DataCache_IDataObject_QueryInterface (IUnknown)
1022 * See Windows documentation for more details on IUnknown methods.
1024 static HRESULT WINAPI
DataCache_IDataObject_QueryInterface(
1029 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
1031 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1034 /************************************************************************
1035 * DataCache_IDataObject_AddRef (IUnknown)
1037 * See Windows documentation for more details on IUnknown methods.
1039 static ULONG WINAPI
DataCache_IDataObject_AddRef(
1042 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
1044 return IUnknown_AddRef(this->outerUnknown
);
1047 /************************************************************************
1048 * DataCache_IDataObject_Release (IUnknown)
1050 * See Windows documentation for more details on IUnknown methods.
1052 static ULONG WINAPI
DataCache_IDataObject_Release(
1055 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
1057 return IUnknown_Release(this->outerUnknown
);
1060 /************************************************************************
1063 * Get Data from a source dataobject using format pformatetcIn->cfFormat
1064 * See Windows documentation for more details on GetData.
1065 * TODO: Currently only CF_METAFILEPICT is implemented
1067 static HRESULT WINAPI
DataCache_GetData(
1069 LPFORMATETC pformatetcIn
,
1073 HRESULT hrRet
= E_UNEXPECTED
;
1074 IPersistStorage
*pPersistStorage
= 0;
1075 IStorage
*pStorage
= 0;
1076 IStream
*pStream
= 0;
1077 OLECHAR name
[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
1078 HGLOBAL hGlobalMF
= 0;
1080 PresentationDataHeader pdh
;
1081 METAFILEPICT
*mfPict
;
1082 HMETAFILE hMetaFile
= 0;
1084 if (pformatetcIn
->cfFormat
== CF_METAFILEPICT
)
1086 /* Get the Persist Storage */
1088 hr
= IDataObject_QueryInterface(iface
, &IID_IPersistStorage
, (void**)&pPersistStorage
);
1093 /* Create a doc file to copy the doc to a storage */
1095 hr
= StgCreateDocfile(NULL
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &pStorage
);
1100 /* Save it to storage */
1102 hr
= OleSave(pPersistStorage
, pStorage
, FALSE
);
1107 /* Open the Presentation data srteam */
1109 hr
= IStorage_OpenStream(pStorage
, name
, 0, STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &pStream
);
1114 /* Read the presentation header */
1116 hr
= IStream_Read(pStream
, &pdh
, sizeof(PresentationDataHeader
), NULL
);
1121 mfBits
= HeapAlloc(GetProcessHeap(), 0, pdh
.dwSize
);
1123 /* Read the Metafile bits */
1125 hr
= IStream_Read(pStream
, mfBits
, pdh
.dwSize
, NULL
);
1130 /* Create the metafile and place it in the STGMEDIUM structure */
1132 hMetaFile
= SetMetaFileBitsEx(pdh
.dwSize
, mfBits
);
1134 hGlobalMF
= GlobalAlloc(GMEM_SHARE
|GMEM_MOVEABLE
, sizeof(METAFILEPICT
));
1135 mfPict
= (METAFILEPICT
*)GlobalLock(hGlobalMF
);
1136 mfPict
->hMF
= hMetaFile
;
1138 GlobalUnlock(hGlobalMF
);
1140 pmedium
->u
.hGlobal
= hGlobalMF
;
1141 pmedium
->tymed
= TYMED_MFPICT
;
1147 HeapFree(GetProcessHeap(), 0, mfBits
);
1150 IStream_Release(pStream
);
1153 IStorage_Release(pStorage
);
1155 if (pPersistStorage
)
1156 IPersistStorage_Release(pPersistStorage
);
1161 /* TODO: Other formats are not implemented */
1166 static HRESULT WINAPI
DataCache_GetDataHere(
1168 LPFORMATETC pformatetc
,
1175 static HRESULT WINAPI
DataCache_QueryGetData(
1177 LPFORMATETC pformatetc
)
1183 /************************************************************************
1184 * DataCache_EnumFormatEtc (IDataObject)
1186 * The data cache doesn't implement this method.
1188 * See Windows documentation for more details on IDataObject methods.
1190 static HRESULT WINAPI
DataCache_GetCanonicalFormatEtc(
1192 LPFORMATETC pformatectIn
,
1193 LPFORMATETC pformatetcOut
)
1199 /************************************************************************
1200 * DataCache_IDataObject_SetData (IDataObject)
1202 * This method is delegated to the IOleCache2 implementation.
1204 * See Windows documentation for more details on IDataObject methods.
1206 static HRESULT WINAPI
DataCache_IDataObject_SetData(
1208 LPFORMATETC pformatetc
,
1212 IOleCache2
* oleCache
= NULL
;
1215 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1217 hres
= IDataObject_QueryInterface(iface
, &IID_IOleCache2
, (void**)&oleCache
);
1220 return E_UNEXPECTED
;
1222 hres
= IOleCache2_SetData(oleCache
, pformatetc
, pmedium
, fRelease
);
1224 IOleCache2_Release(oleCache
);
1229 /************************************************************************
1230 * DataCache_EnumFormatEtc (IDataObject)
1232 * The data cache doesn't implement this method.
1234 * See Windows documentation for more details on IDataObject methods.
1236 static HRESULT WINAPI
DataCache_EnumFormatEtc(
1239 IEnumFORMATETC
** ppenumFormatEtc
)
1245 /************************************************************************
1246 * DataCache_DAdvise (IDataObject)
1248 * The data cache doesn't support connections.
1250 * See Windows documentation for more details on IDataObject methods.
1252 static HRESULT WINAPI
DataCache_DAdvise(
1254 FORMATETC
* pformatetc
,
1256 IAdviseSink
* pAdvSink
,
1257 DWORD
* pdwConnection
)
1260 return OLE_E_ADVISENOTSUPPORTED
;
1263 /************************************************************************
1264 * DataCache_DUnadvise (IDataObject)
1266 * The data cache doesn't support connections.
1268 * See Windows documentation for more details on IDataObject methods.
1270 static HRESULT WINAPI
DataCache_DUnadvise(
1275 return OLE_E_NOCONNECTION
;
1278 /************************************************************************
1279 * DataCache_EnumDAdvise (IDataObject)
1281 * The data cache doesn't support connections.
1283 * See Windows documentation for more details on IDataObject methods.
1285 static HRESULT WINAPI
DataCache_EnumDAdvise(
1287 IEnumSTATDATA
** ppenumAdvise
)
1290 return OLE_E_ADVISENOTSUPPORTED
;
1293 /*********************************************************
1294 * Method implementation for the IDataObject
1295 * part of the DataCache class.
1298 /************************************************************************
1299 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1301 * See Windows documentation for more details on IUnknown methods.
1303 static HRESULT WINAPI
DataCache_IPersistStorage_QueryInterface(
1304 IPersistStorage
* iface
,
1308 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1310 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1313 /************************************************************************
1314 * DataCache_IPersistStorage_AddRef (IUnknown)
1316 * See Windows documentation for more details on IUnknown methods.
1318 static ULONG WINAPI
DataCache_IPersistStorage_AddRef(
1319 IPersistStorage
* iface
)
1321 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1323 return IUnknown_AddRef(this->outerUnknown
);
1326 /************************************************************************
1327 * DataCache_IPersistStorage_Release (IUnknown)
1329 * See Windows documentation for more details on IUnknown methods.
1331 static ULONG WINAPI
DataCache_IPersistStorage_Release(
1332 IPersistStorage
* iface
)
1334 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1336 return IUnknown_Release(this->outerUnknown
);
1339 /************************************************************************
1340 * DataCache_GetClassID (IPersistStorage)
1342 * The data cache doesn't implement this method.
1344 * See Windows documentation for more details on IPersistStorage methods.
1346 static HRESULT WINAPI
DataCache_GetClassID(
1347 IPersistStorage
* iface
,
1350 TRACE("(%p, %p)\n", iface
, pClassID
);
1354 /************************************************************************
1355 * DataCache_IsDirty (IPersistStorage)
1357 * Until we actully connect to a running object and retrieve new
1358 * information to it, we never get dirty.
1360 * See Windows documentation for more details on IPersistStorage methods.
1362 static HRESULT WINAPI
DataCache_IsDirty(
1363 IPersistStorage
* iface
)
1365 TRACE("(%p)\n", iface
);
1370 /************************************************************************
1371 * DataCache_InitNew (IPersistStorage)
1373 * The data cache implementation of IPersistStorage_InitNew simply stores
1374 * the storage pointer.
1376 * See Windows documentation for more details on IPersistStorage methods.
1378 static HRESULT WINAPI
DataCache_InitNew(
1379 IPersistStorage
* iface
,
1382 TRACE("(%p, %p)\n", iface
, pStg
);
1384 return DataCache_Load(iface
, pStg
);
1387 /************************************************************************
1388 * DataCache_Load (IPersistStorage)
1390 * The data cache implementation of IPersistStorage_Load doesn't
1391 * actually load anything. Instead, it holds on to the storage pointer
1392 * and it will load the presentation information when the
1393 * IDataObject_GetData or IViewObject2_Draw methods are called.
1395 * See Windows documentation for more details on IPersistStorage methods.
1397 static HRESULT WINAPI
DataCache_Load(
1398 IPersistStorage
* iface
,
1401 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1403 TRACE("(%p, %p)\n", iface
, pStg
);
1405 if (this->presentationStorage
!= NULL
)
1407 IStorage_Release(this->presentationStorage
);
1410 this->presentationStorage
= pStg
;
1412 if (this->presentationStorage
!= NULL
)
1414 IStorage_AddRef(this->presentationStorage
);
1419 /************************************************************************
1420 * DataCache_Save (IPersistStorage)
1422 * Until we actully connect to a running object and retrieve new
1423 * information to it, we never have to save anything. However, it is
1424 * our responsability to copy the information when saving to a new
1427 * See Windows documentation for more details on IPersistStorage methods.
1429 static HRESULT WINAPI
DataCache_Save(
1430 IPersistStorage
* iface
,
1434 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1436 TRACE("(%p, %p, %d)\n", iface
, pStg
, fSameAsLoad
);
1438 if ( (!fSameAsLoad
) &&
1439 (this->presentationStorage
!=NULL
) )
1441 return IStorage_CopyTo(this->presentationStorage
,
1451 /************************************************************************
1452 * DataCache_SaveCompleted (IPersistStorage)
1454 * This method is called to tell the cache to release the storage
1455 * pointer it's currentlu holding.
1457 * See Windows documentation for more details on IPersistStorage methods.
1459 static HRESULT WINAPI
DataCache_SaveCompleted(
1460 IPersistStorage
* iface
,
1463 TRACE("(%p, %p)\n", iface
, pStgNew
);
1468 * First, make sure we get our hands off any storage we have.
1471 DataCache_HandsOffStorage(iface
);
1474 * Then, attach to the new storage.
1477 DataCache_Load(iface
, pStgNew
);
1483 /************************************************************************
1484 * DataCache_HandsOffStorage (IPersistStorage)
1486 * This method is called to tell the cache to release the storage
1487 * pointer it's currentlu holding.
1489 * See Windows documentation for more details on IPersistStorage methods.
1491 static HRESULT WINAPI
DataCache_HandsOffStorage(
1492 IPersistStorage
* iface
)
1494 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1496 TRACE("(%p)\n", iface
);
1498 if (this->presentationStorage
!= NULL
)
1500 IStorage_Release(this->presentationStorage
);
1501 this->presentationStorage
= NULL
;
1507 /*********************************************************
1508 * Method implementation for the IViewObject2
1509 * part of the DataCache class.
1512 /************************************************************************
1513 * DataCache_IViewObject2_QueryInterface (IUnknown)
1515 * See Windows documentation for more details on IUnknown methods.
1517 static HRESULT WINAPI
DataCache_IViewObject2_QueryInterface(
1518 IViewObject2
* iface
,
1522 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1524 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1527 /************************************************************************
1528 * DataCache_IViewObject2_AddRef (IUnknown)
1530 * See Windows documentation for more details on IUnknown methods.
1532 static ULONG WINAPI
DataCache_IViewObject2_AddRef(
1533 IViewObject2
* iface
)
1535 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1537 return IUnknown_AddRef(this->outerUnknown
);
1540 /************************************************************************
1541 * DataCache_IViewObject2_Release (IUnknown)
1543 * See Windows documentation for more details on IUnknown methods.
1545 static ULONG WINAPI
DataCache_IViewObject2_Release(
1546 IViewObject2
* iface
)
1548 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1550 return IUnknown_Release(this->outerUnknown
);
1553 /************************************************************************
1554 * DataCache_Draw (IViewObject2)
1556 * This method will draw the cached representation of the object
1557 * to the given device context.
1559 * See Windows documentation for more details on IViewObject2 methods.
1561 static HRESULT WINAPI
DataCache_Draw(
1562 IViewObject2
* iface
,
1566 DVTARGETDEVICE
* ptd
,
1569 LPCRECTL lprcBounds
,
1570 LPCRECTL lprcWBounds
,
1571 BOOL (CALLBACK
*pfnContinue
)(ULONG_PTR dwContinue
),
1574 PresentationDataHeader presData
;
1575 HMETAFILE presMetafile
= 0;
1578 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1580 TRACE("(%p, %lx, %ld, %p, %p, %p, %p, %p, %p, %lx)\n",
1595 if (lprcBounds
==NULL
)
1596 return E_INVALIDARG
;
1599 * First, we need to retrieve the dimensions of the
1600 * image in the metafile.
1602 hres
= DataCache_ReadPresentationData(this,
1610 * Then, we can extract the metafile itself from the cached
1613 * FIXME Unless it isn't a metafile. I think it could be any CF_XXX type,
1614 * particularly CF_DIB.
1616 presMetafile
= DataCache_ReadPresMetafile(this,
1620 * If we have a metafile, just draw baby...
1621 * We have to be careful not to modify the state of the
1624 if (presMetafile
!=0)
1626 INT prevMapMode
= SetMapMode(hdcDraw
, MM_ANISOTROPIC
);
1628 SIZE oldViewportExt
;
1629 POINT oldViewportOrg
;
1631 SetWindowExtEx(hdcDraw
,
1632 presData
.dwObjectExtentX
,
1633 presData
.dwObjectExtentY
,
1636 SetViewportExtEx(hdcDraw
,
1637 lprcBounds
->right
- lprcBounds
->left
,
1638 lprcBounds
->bottom
- lprcBounds
->top
,
1641 SetViewportOrgEx(hdcDraw
,
1646 PlayMetaFile(hdcDraw
, presMetafile
);
1648 SetWindowExtEx(hdcDraw
,
1653 SetViewportExtEx(hdcDraw
,
1658 SetViewportOrgEx(hdcDraw
,
1663 SetMapMode(hdcDraw
, prevMapMode
);
1665 DeleteMetaFile(presMetafile
);
1671 static HRESULT WINAPI
DataCache_GetColorSet(
1672 IViewObject2
* iface
,
1676 DVTARGETDEVICE
* ptd
,
1677 HDC hicTargetDevice
,
1678 LOGPALETTE
** ppColorSet
)
1684 static HRESULT WINAPI
DataCache_Freeze(
1685 IViewObject2
* iface
,
1695 static HRESULT WINAPI
DataCache_Unfreeze(
1696 IViewObject2
* iface
,
1703 /************************************************************************
1704 * DataCache_SetAdvise (IViewObject2)
1706 * This sets-up an advisory sink with the data cache. When the object's
1707 * view changes, this sink is called.
1709 * See Windows documentation for more details on IViewObject2 methods.
1711 static HRESULT WINAPI
DataCache_SetAdvise(
1712 IViewObject2
* iface
,
1715 IAdviseSink
* pAdvSink
)
1717 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1719 TRACE("(%p, %lx, %lx, %p)\n", iface
, aspects
, advf
, pAdvSink
);
1722 * A call to this function removes the previous sink
1724 if (this->sinkInterface
!= NULL
)
1726 IAdviseSink_Release(this->sinkInterface
);
1727 this->sinkInterface
= NULL
;
1728 this->sinkAspects
= 0;
1729 this->sinkAdviseFlag
= 0;
1733 * Now, setup the new one.
1737 this->sinkInterface
= pAdvSink
;
1738 this->sinkAspects
= aspects
;
1739 this->sinkAdviseFlag
= advf
;
1741 IAdviseSink_AddRef(this->sinkInterface
);
1745 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1748 if (advf
& ADVF_PRIMEFIRST
)
1750 DataCache_FireOnViewChange(this,
1758 /************************************************************************
1759 * DataCache_GetAdvise (IViewObject2)
1761 * This method queries the current state of the advise sink
1762 * installed on the data cache.
1764 * See Windows documentation for more details on IViewObject2 methods.
1766 static HRESULT WINAPI
DataCache_GetAdvise(
1767 IViewObject2
* iface
,
1770 IAdviseSink
** ppAdvSink
)
1772 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1774 TRACE("(%p, %p, %p, %p)\n", iface
, pAspects
, pAdvf
, ppAdvSink
);
1777 * Just copy all the requested values.
1780 *pAspects
= this->sinkAspects
;
1783 *pAdvf
= this->sinkAdviseFlag
;
1785 if (ppAdvSink
!=NULL
)
1787 IAdviseSink_QueryInterface(this->sinkInterface
,
1795 /************************************************************************
1796 * DataCache_GetExtent (IViewObject2)
1798 * This method retrieves the "natural" size of this cached object.
1800 * See Windows documentation for more details on IViewObject2 methods.
1802 static HRESULT WINAPI
DataCache_GetExtent(
1803 IViewObject2
* iface
,
1806 DVTARGETDEVICE
* ptd
,
1809 PresentationDataHeader presData
;
1810 HRESULT hres
= E_FAIL
;
1812 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1814 TRACE("(%p, %lx, %ld, %p, %p)\n",
1815 iface
, dwDrawAspect
, lindex
, ptd
, lpsizel
);
1824 * Initialize the out parameter.
1830 * This flag should be set to -1.
1833 FIXME("Unimplemented flag lindex = %ld\n", lindex
);
1836 * Right now, we support only the callback from
1837 * the default handler.
1840 FIXME("Unimplemented ptd = %p\n", ptd
);
1843 * Get the presentation information from the
1846 hres
= DataCache_ReadPresentationData(this,
1850 if (SUCCEEDED(hres
))
1852 lpsizel
->cx
= presData
.dwObjectExtentX
;
1853 lpsizel
->cy
= presData
.dwObjectExtentY
;
1857 * This method returns OLE_E_BLANK when it fails.
1866 /*********************************************************
1867 * Method implementation for the IOleCache2
1868 * part of the DataCache class.
1871 /************************************************************************
1872 * DataCache_IOleCache2_QueryInterface (IUnknown)
1874 * See Windows documentation for more details on IUnknown methods.
1876 static HRESULT WINAPI
DataCache_IOleCache2_QueryInterface(
1881 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1883 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1886 /************************************************************************
1887 * DataCache_IOleCache2_AddRef (IUnknown)
1889 * See Windows documentation for more details on IUnknown methods.
1891 static ULONG WINAPI
DataCache_IOleCache2_AddRef(
1894 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1896 return IUnknown_AddRef(this->outerUnknown
);
1899 /************************************************************************
1900 * DataCache_IOleCache2_Release (IUnknown)
1902 * See Windows documentation for more details on IUnknown methods.
1904 static ULONG WINAPI
DataCache_IOleCache2_Release(
1907 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1909 return IUnknown_Release(this->outerUnknown
);
1912 static HRESULT WINAPI
DataCache_Cache(
1914 FORMATETC
* pformatetc
,
1916 DWORD
* pdwConnection
)
1922 static HRESULT WINAPI
DataCache_Uncache(
1930 static HRESULT WINAPI
DataCache_EnumCache(
1932 IEnumSTATDATA
** ppenumSTATDATA
)
1938 static HRESULT WINAPI
DataCache_InitCache(
1940 IDataObject
* pDataObject
)
1946 static HRESULT WINAPI
DataCache_IOleCache2_SetData(
1948 FORMATETC
* pformatetc
,
1956 static HRESULT WINAPI
DataCache_UpdateCache(
1958 LPDATAOBJECT pDataObject
,
1966 static HRESULT WINAPI
DataCache_DiscardCache(
1968 DWORD dwDiscardOptions
)
1975 /*********************************************************
1976 * Method implementation for the IOleCacheControl
1977 * part of the DataCache class.
1980 /************************************************************************
1981 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1983 * See Windows documentation for more details on IUnknown methods.
1985 static HRESULT WINAPI
DataCache_IOleCacheControl_QueryInterface(
1986 IOleCacheControl
* iface
,
1990 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1992 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1995 /************************************************************************
1996 * DataCache_IOleCacheControl_AddRef (IUnknown)
1998 * See Windows documentation for more details on IUnknown methods.
2000 static ULONG WINAPI
DataCache_IOleCacheControl_AddRef(
2001 IOleCacheControl
* iface
)
2003 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
2005 return IUnknown_AddRef(this->outerUnknown
);
2008 /************************************************************************
2009 * DataCache_IOleCacheControl_Release (IUnknown)
2011 * See Windows documentation for more details on IUnknown methods.
2013 static ULONG WINAPI
DataCache_IOleCacheControl_Release(
2014 IOleCacheControl
* iface
)
2016 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
2018 return IUnknown_Release(this->outerUnknown
);
2021 static HRESULT WINAPI
DataCache_OnRun(
2022 IOleCacheControl
* iface
,
2023 LPDATAOBJECT pDataObject
)
2029 static HRESULT WINAPI
DataCache_OnStop(
2030 IOleCacheControl
* iface
)