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.
49 #define NONAMELESSUNION
50 #define NONAMELESSSTRUCT
56 #include "wine/unicode.h"
58 #include "wine/debug.h"
60 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
62 /****************************************************************************
63 * PresentationDataHeader
65 * This structure represents the header of the \002OlePresXXX stream in
66 * the OLE object strorage.
68 * Most fields are still unknown.
70 typedef struct PresentationDataHeader
72 DWORD unknown1
; /* -1 */
73 DWORD unknown2
; /* 3, possibly CF_METAFILEPICT */
74 DWORD unknown3
; /* 4, possibly TYMED_ISTREAM */
76 DWORD unknown5
; /* -1 */
79 DWORD unknown7
; /* 0 */
80 DWORD dwObjectExtentX
;
81 DWORD dwObjectExtentY
;
83 } PresentationDataHeader
;
85 /****************************************************************************
91 * List all interface VTables here
93 ICOM_VTABLE(IDataObject
)* lpvtbl1
;
94 ICOM_VTABLE(IUnknown
)* lpvtbl2
;
95 ICOM_VTABLE(IPersistStorage
)* lpvtbl3
;
96 ICOM_VTABLE(IViewObject2
)* lpvtbl4
;
97 ICOM_VTABLE(IOleCache2
)* lpvtbl5
;
98 ICOM_VTABLE(IOleCacheControl
)* lpvtbl6
;
101 * Reference count of this object
106 * IUnknown implementation of the outer object.
108 IUnknown
* outerUnknown
;
111 * This storage pointer is set through a call to
112 * IPersistStorage_Load. This is where the visual
113 * representation of the object is stored.
115 IStorage
* presentationStorage
;
118 * The user of this object can setup ONE advise sink
119 * connection with the object. These parameters describe
123 DWORD sinkAdviseFlag
;
124 IAdviseSink
* sinkInterface
;
128 typedef struct DataCache DataCache
;
131 * Here, I define utility macros to help with the casting of the
133 * There is a version to accomodate all of the VTables implemented
136 #define _ICOM_THIS_From_IDataObject(class,name) class* this = (class*)name;
137 #define _ICOM_THIS_From_NDIUnknown(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
138 #define _ICOM_THIS_From_IPersistStorage(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
139 #define _ICOM_THIS_From_IViewObject2(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
140 #define _ICOM_THIS_From_IOleCache2(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*));
141 #define _ICOM_THIS_From_IOleCacheControl(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*));
144 * Prototypes for the methods of the DataCache class.
146 static DataCache
* DataCache_Construct(REFCLSID clsid
,
147 LPUNKNOWN pUnkOuter
);
148 static void DataCache_Destroy(DataCache
* ptrToDestroy
);
149 static HRESULT
DataCache_ReadPresentationData(DataCache
* this,
151 PresentationDataHeader
* header
);
152 static HRESULT
DataCache_OpenPresStream(DataCache
*this,
155 static HMETAFILE
DataCache_ReadPresMetafile(DataCache
* this,
157 static void DataCache_FireOnViewChange(DataCache
* this,
162 * Prototypes for the methods of the DataCache class
163 * that implement non delegating IUnknown methods.
165 static HRESULT WINAPI
DataCache_NDIUnknown_QueryInterface(
169 static ULONG WINAPI
DataCache_NDIUnknown_AddRef(
171 static ULONG WINAPI
DataCache_NDIUnknown_Release(
175 * Prototypes for the methods of the DataCache class
176 * that implement IDataObject methods.
178 static HRESULT WINAPI
DataCache_IDataObject_QueryInterface(
182 static ULONG WINAPI
DataCache_IDataObject_AddRef(
184 static ULONG WINAPI
DataCache_IDataObject_Release(
186 static HRESULT WINAPI
DataCache_GetData(
188 LPFORMATETC pformatetcIn
,
190 static HRESULT WINAPI
DataCache_GetDataHere(
192 LPFORMATETC pformatetc
,
194 static HRESULT WINAPI
DataCache_QueryGetData(
196 LPFORMATETC pformatetc
);
197 static HRESULT WINAPI
DataCache_GetCanonicalFormatEtc(
199 LPFORMATETC pformatectIn
,
200 LPFORMATETC pformatetcOut
);
201 static HRESULT WINAPI
DataCache_IDataObject_SetData(
203 LPFORMATETC pformatetc
,
206 static HRESULT WINAPI
DataCache_EnumFormatEtc(
209 IEnumFORMATETC
** ppenumFormatEtc
);
210 static HRESULT WINAPI
DataCache_DAdvise(
212 FORMATETC
* pformatetc
,
214 IAdviseSink
* pAdvSink
,
215 DWORD
* pdwConnection
);
216 static HRESULT WINAPI
DataCache_DUnadvise(
219 static HRESULT WINAPI
DataCache_EnumDAdvise(
221 IEnumSTATDATA
** ppenumAdvise
);
224 * Prototypes for the methods of the DataCache class
225 * that implement IPersistStorage methods.
227 static HRESULT WINAPI
DataCache_IPersistStorage_QueryInterface(
228 IPersistStorage
* iface
,
231 static ULONG WINAPI
DataCache_IPersistStorage_AddRef(
232 IPersistStorage
* iface
);
233 static ULONG WINAPI
DataCache_IPersistStorage_Release(
234 IPersistStorage
* iface
);
235 static HRESULT WINAPI
DataCache_GetClassID(
236 IPersistStorage
* iface
,
238 static HRESULT WINAPI
DataCache_IsDirty(
239 IPersistStorage
* iface
);
240 static HRESULT WINAPI
DataCache_InitNew(
241 IPersistStorage
* iface
,
243 static HRESULT WINAPI
DataCache_Load(
244 IPersistStorage
* iface
,
246 static HRESULT WINAPI
DataCache_Save(
247 IPersistStorage
* iface
,
250 static HRESULT WINAPI
DataCache_SaveCompleted(
251 IPersistStorage
* iface
,
253 static HRESULT WINAPI
DataCache_HandsOffStorage(
254 IPersistStorage
* iface
);
257 * Prototypes for the methods of the DataCache class
258 * that implement IViewObject2 methods.
260 static HRESULT WINAPI
DataCache_IViewObject2_QueryInterface(
264 static ULONG WINAPI
DataCache_IViewObject2_AddRef(
265 IViewObject2
* iface
);
266 static ULONG WINAPI
DataCache_IViewObject2_Release(
267 IViewObject2
* iface
);
268 static HRESULT WINAPI
DataCache_Draw(
277 LPCRECTL lprcWBounds
,
278 IVO_ContCallback pfnContinue
,
280 static HRESULT WINAPI
DataCache_GetColorSet(
287 LOGPALETTE
** ppColorSet
);
288 static HRESULT WINAPI
DataCache_Freeze(
294 static HRESULT WINAPI
DataCache_Unfreeze(
297 static HRESULT WINAPI
DataCache_SetAdvise(
301 IAdviseSink
* pAdvSink
);
302 static HRESULT WINAPI
DataCache_GetAdvise(
306 IAdviseSink
** ppAdvSink
);
307 static HRESULT WINAPI
DataCache_GetExtent(
315 * Prototypes for the methods of the DataCache class
316 * that implement IOleCache2 methods.
318 static HRESULT WINAPI
DataCache_IOleCache2_QueryInterface(
322 static ULONG WINAPI
DataCache_IOleCache2_AddRef(
324 static ULONG WINAPI
DataCache_IOleCache2_Release(
326 static HRESULT WINAPI
DataCache_Cache(
328 FORMATETC
* pformatetc
,
330 DWORD
* pdwConnection
);
331 static HRESULT WINAPI
DataCache_Uncache(
334 static HRESULT WINAPI
DataCache_EnumCache(
336 IEnumSTATDATA
** ppenumSTATDATA
);
337 static HRESULT WINAPI
DataCache_InitCache(
339 IDataObject
* pDataObject
);
340 static HRESULT WINAPI
DataCache_IOleCache2_SetData(
342 FORMATETC
* pformatetc
,
345 static HRESULT WINAPI
DataCache_UpdateCache(
347 LPDATAOBJECT pDataObject
,
350 static HRESULT WINAPI
DataCache_DiscardCache(
352 DWORD dwDiscardOptions
);
355 * Prototypes for the methods of the DataCache class
356 * that implement IOleCacheControl methods.
358 static HRESULT WINAPI
DataCache_IOleCacheControl_QueryInterface(
359 IOleCacheControl
* iface
,
362 static ULONG WINAPI
DataCache_IOleCacheControl_AddRef(
363 IOleCacheControl
* iface
);
364 static ULONG WINAPI
DataCache_IOleCacheControl_Release(
365 IOleCacheControl
* iface
);
366 static HRESULT WINAPI
DataCache_OnRun(
367 IOleCacheControl
* iface
,
368 LPDATAOBJECT pDataObject
);
369 static HRESULT WINAPI
DataCache_OnStop(
370 IOleCacheControl
* iface
);
373 * Virtual function tables for the DataCache class.
375 static ICOM_VTABLE(IUnknown
) DataCache_NDIUnknown_VTable
=
377 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
378 DataCache_NDIUnknown_QueryInterface
,
379 DataCache_NDIUnknown_AddRef
,
380 DataCache_NDIUnknown_Release
383 static ICOM_VTABLE(IDataObject
) DataCache_IDataObject_VTable
=
385 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
386 DataCache_IDataObject_QueryInterface
,
387 DataCache_IDataObject_AddRef
,
388 DataCache_IDataObject_Release
,
390 DataCache_GetDataHere
,
391 DataCache_QueryGetData
,
392 DataCache_GetCanonicalFormatEtc
,
393 DataCache_IDataObject_SetData
,
394 DataCache_EnumFormatEtc
,
397 DataCache_EnumDAdvise
400 static ICOM_VTABLE(IPersistStorage
) DataCache_IPersistStorage_VTable
=
402 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
403 DataCache_IPersistStorage_QueryInterface
,
404 DataCache_IPersistStorage_AddRef
,
405 DataCache_IPersistStorage_Release
,
406 DataCache_GetClassID
,
411 DataCache_SaveCompleted
,
412 DataCache_HandsOffStorage
415 static ICOM_VTABLE(IViewObject2
) DataCache_IViewObject2_VTable
=
417 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
418 DataCache_IViewObject2_QueryInterface
,
419 DataCache_IViewObject2_AddRef
,
420 DataCache_IViewObject2_Release
,
422 DataCache_GetColorSet
,
430 static ICOM_VTABLE(IOleCache2
) DataCache_IOleCache2_VTable
=
432 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
433 DataCache_IOleCache2_QueryInterface
,
434 DataCache_IOleCache2_AddRef
,
435 DataCache_IOleCache2_Release
,
440 DataCache_IOleCache2_SetData
,
441 DataCache_UpdateCache
,
442 DataCache_DiscardCache
445 static ICOM_VTABLE(IOleCacheControl
) DataCache_IOleCacheControl_VTable
=
447 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
448 DataCache_IOleCacheControl_QueryInterface
,
449 DataCache_IOleCacheControl_AddRef
,
450 DataCache_IOleCacheControl_Release
,
455 /******************************************************************************
456 * CreateDataCache [OLE32.54]
458 HRESULT WINAPI
CreateDataCache(
464 DataCache
* newCache
= NULL
;
467 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(rclsid
), pUnkOuter
, debugstr_guid(riid
), ppvObj
);
478 * If this cache is constructed for aggregation, make sure
479 * the caller is requesting the IUnknown interface.
480 * This is necessary because it's the only time the non-delegating
481 * IUnknown pointer can be returned to the outside.
483 if ( (pUnkOuter
!=NULL
) &&
484 (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) != 0) )
485 return CLASS_E_NOAGGREGATION
;
488 * Try to construct a new instance of the class.
490 newCache
= DataCache_Construct(rclsid
,
494 return E_OUTOFMEMORY
;
497 * Make sure it supports the interface required by the caller.
499 hr
= IUnknown_QueryInterface((IUnknown
*)&(newCache
->lpvtbl2
), riid
, ppvObj
);
502 * Release the reference obtained in the constructor. If
503 * the QueryInterface was unsuccessful, it will free the class.
505 IUnknown_Release((IUnknown
*)&(newCache
->lpvtbl2
));
510 /*********************************************************
511 * Method implementation for DataCache class.
513 static DataCache
* DataCache_Construct(
517 DataCache
* newObject
= 0;
520 * Allocate space for the object.
522 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache
));
528 * Initialize the virtual function table.
530 newObject
->lpvtbl1
= &DataCache_IDataObject_VTable
;
531 newObject
->lpvtbl2
= &DataCache_NDIUnknown_VTable
;
532 newObject
->lpvtbl3
= &DataCache_IPersistStorage_VTable
;
533 newObject
->lpvtbl4
= &DataCache_IViewObject2_VTable
;
534 newObject
->lpvtbl5
= &DataCache_IOleCache2_VTable
;
535 newObject
->lpvtbl6
= &DataCache_IOleCacheControl_VTable
;
538 * Start with one reference count. The caller of this function
539 * must release the interface pointer when it is done.
544 * Initialize the outer unknown
545 * We don't keep a reference on the outer unknown since, the way
546 * aggregation works, our lifetime is at least as large as it's
550 pUnkOuter
= (IUnknown
*)&(newObject
->lpvtbl2
);
552 newObject
->outerUnknown
= pUnkOuter
;
555 * Initialize the other members of the structure.
557 newObject
->presentationStorage
= NULL
;
558 newObject
->sinkAspects
= 0;
559 newObject
->sinkAdviseFlag
= 0;
560 newObject
->sinkInterface
= 0;
565 static void DataCache_Destroy(
566 DataCache
* ptrToDestroy
)
570 if (ptrToDestroy
->sinkInterface
!= NULL
)
572 IAdviseSink_Release(ptrToDestroy
->sinkInterface
);
573 ptrToDestroy
->sinkInterface
= NULL
;
576 if (ptrToDestroy
->presentationStorage
!= NULL
)
578 IStorage_Release(ptrToDestroy
->presentationStorage
);
579 ptrToDestroy
->presentationStorage
= NULL
;
583 * Free the datacache pointer.
585 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
588 /************************************************************************
589 * DataCache_ReadPresentationData
591 * This method will read information for the requested presentation
592 * into the given structure.
595 * this - Pointer to the DataCache object
596 * drawAspect - The aspect of the object that we wish to draw.
597 * header - The structure containing information about this
598 * aspect of the object.
600 static HRESULT
DataCache_ReadPresentationData(
603 PresentationDataHeader
* header
)
605 IStream
* presStream
= NULL
;
609 * Open the presentation stream.
611 hres
= DataCache_OpenPresStream(
626 sizeof(PresentationDataHeader
),
632 IStream_Release(presStream
);
635 * We don't want to propagate any other error
636 * code than a failure.
644 /************************************************************************
645 * DataCache_FireOnViewChange
647 * This method will fire an OnViewChange notification to the advise
648 * sink registered with the datacache.
650 * See IAdviseSink::OnViewChange for more details.
652 static void DataCache_FireOnViewChange(
657 TRACE("(%p, %lx, %ld)\n", this, aspect
, lindex
);
660 * The sink supplies a filter when it registers
661 * we make sure we only send the notifications when that
664 if ((this->sinkAspects
& aspect
) != 0)
666 if (this->sinkInterface
!= NULL
)
668 IAdviseSink_OnViewChange(this->sinkInterface
,
673 * Some sinks want to be unregistered automatically when
674 * the first notification goes out.
676 if ( (this->sinkAdviseFlag
& ADVF_ONLYONCE
) != 0)
678 IAdviseSink_Release(this->sinkInterface
);
680 this->sinkInterface
= NULL
;
681 this->sinkAspects
= 0;
682 this->sinkAdviseFlag
= 0;
688 /* Helper for DataCache_OpenPresStream */
689 static BOOL
DataCache_IsPresentationStream(const STATSTG
*elem
)
691 /* The presentation streams have names of the form "\002OlePresXXX",
692 * where XXX goes from 000 to 999. */
693 static const WCHAR OlePres
[] = { 2,'O','l','e','P','r','e','s' };
695 LPCWSTR name
= elem
->pwcsName
;
697 return (elem
->type
== STGTY_STREAM
)
698 && (elem
->cbSize
.s
.LowPart
>= sizeof(PresentationDataHeader
))
699 && (strlenW(name
) == 11)
700 && (strncmpW(name
, OlePres
, 8) == 0)
701 && (name
[8] >= '0') && (name
[8] <= '9')
702 && (name
[9] >= '0') && (name
[9] <= '9')
703 && (name
[10] >= '0') && (name
[10] <= '9');
706 /************************************************************************
707 * DataCache_OpenPresStream
709 * This method will find the stream for the given presentation. It makes
710 * no attempt at fallback.
713 * this - Pointer to the DataCache object
714 * drawAspect - The aspect of the object that we wish to draw.
715 * pStm - A returned stream. It points to the beginning of the
716 * - presentation data, including the header.
719 * S_OK The requested stream has been opened.
720 * OLE_E_BLANK The requested stream could not be found.
721 * Quite a few others I'm too lazy to map correctly.
724 * Algorithm: Scan the elements of the presentation storage, looking
725 * for presentation streams. For each presentation stream,
726 * load the header and check to see if the aspect maches.
728 * If a fallback is desired, just opening the first presentation stream
731 static HRESULT
DataCache_OpenPresStream(
740 if (!ppStm
) return E_POINTER
;
742 hr
= IStorage_EnumElements(this->presentationStorage
, 0, NULL
, 0, &pEnum
);
743 if (FAILED(hr
)) return hr
;
745 while ((hr
= IEnumSTATSTG_Next(pEnum
, 1, &elem
, NULL
)) == S_OK
)
747 if (DataCache_IsPresentationStream(&elem
))
751 hr
= IStorage_OpenStream(this->presentationStorage
, elem
.pwcsName
,
752 NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0,
756 PresentationDataHeader header
;
759 hr
= IStream_Read(pStm
, &header
, sizeof(header
), &actual_read
);
761 /* can't use SUCCEEDED(hr): S_FALSE counts as an error */
762 if (hr
== S_OK
&& actual_read
== sizeof(header
)
763 && header
.dvAspect
== drawAspect
)
765 /* Rewind the stream before returning it. */
766 LARGE_INTEGER offset
;
767 offset
.s
.LowPart
= 0;
768 offset
.s
.HighPart
= 0;
769 IStream_Seek(pStm
, offset
, STREAM_SEEK_SET
, NULL
);
773 CoTaskMemFree(elem
.pwcsName
);
774 IEnumSTATSTG_Release(pEnum
);
779 IStream_Release(pStm
);
783 CoTaskMemFree(elem
.pwcsName
);
786 IEnumSTATSTG_Release(pEnum
);
788 return (hr
== S_FALSE
? OLE_E_BLANK
: hr
);
791 /************************************************************************
792 * DataCache_ReadPresentationData
794 * This method will read information for the requested presentation
795 * into the given structure.
798 * this - Pointer to the DataCache object
799 * drawAspect - The aspect of the object that we wish to draw.
802 * This method returns a metafile handle if it is successful.
803 * it will return 0 if not.
805 static HMETAFILE
DataCache_ReadPresMetafile(
809 LARGE_INTEGER offset
;
810 IStream
* presStream
= NULL
;
814 HMETAFILE newMetafile
= 0;
817 * Open the presentation stream.
819 hres
= DataCache_OpenPresStream(
825 return (HMETAFILE
)hres
;
828 * Get the size of the stream.
830 hres
= IStream_Stat(presStream
,
837 offset
.s
.HighPart
= 0;
838 offset
.s
.LowPart
= sizeof(PresentationDataHeader
);
846 streamInfo
.cbSize
.s
.LowPart
-= offset
.s
.LowPart
;
849 * Allocate a buffer for the metafile bits.
851 metafileBits
= HeapAlloc(GetProcessHeap(),
853 streamInfo
.cbSize
.s
.LowPart
);
856 * Read the metafile bits.
861 streamInfo
.cbSize
.s
.LowPart
,
865 * Create a metafile with those bits.
869 newMetafile
= SetMetaFileBitsEx(streamInfo
.cbSize
.s
.LowPart
, metafileBits
);
875 HeapFree(GetProcessHeap(), 0, metafileBits
);
876 IStream_Release(presStream
);
884 /*********************************************************
885 * Method implementation for the non delegating IUnknown
886 * part of the DataCache class.
889 /************************************************************************
890 * DataCache_NDIUnknown_QueryInterface (IUnknown)
892 * See Windows documentation for more details on IUnknown methods.
894 * This version of QueryInterface will not delegate it's implementation
895 * to the outer unknown.
897 static HRESULT WINAPI
DataCache_NDIUnknown_QueryInterface(
902 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
905 * Perform a sanity check on the parameters.
907 if ( (this==0) || (ppvObject
==0) )
911 * Initialize the return parameter.
916 * Compare the riid with the interface IDs implemented by this object.
918 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
922 else if (memcmp(&IID_IDataObject
, riid
, sizeof(IID_IDataObject
)) == 0)
924 *ppvObject
= (IDataObject
*)&(this->lpvtbl1
);
926 else if ( (memcmp(&IID_IPersistStorage
, riid
, sizeof(IID_IPersistStorage
)) == 0) ||
927 (memcmp(&IID_IPersist
, riid
, sizeof(IID_IPersist
)) == 0) )
929 *ppvObject
= (IPersistStorage
*)&(this->lpvtbl3
);
931 else if ( (memcmp(&IID_IViewObject
, riid
, sizeof(IID_IViewObject
)) == 0) ||
932 (memcmp(&IID_IViewObject2
, riid
, sizeof(IID_IViewObject2
)) == 0) )
934 *ppvObject
= (IViewObject2
*)&(this->lpvtbl4
);
936 else if ( (memcmp(&IID_IOleCache
, riid
, sizeof(IID_IOleCache
)) == 0) ||
937 (memcmp(&IID_IOleCache2
, riid
, sizeof(IID_IOleCache2
)) == 0) )
939 *ppvObject
= (IOleCache2
*)&(this->lpvtbl5
);
941 else if (memcmp(&IID_IOleCacheControl
, riid
, sizeof(IID_IOleCacheControl
)) == 0)
943 *ppvObject
= (IOleCacheControl
*)&(this->lpvtbl6
);
947 * Check that we obtained an interface.
951 WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid
));
952 return E_NOINTERFACE
;
956 * Query Interface always increases the reference count by one when it is
959 IUnknown_AddRef((IUnknown
*)*ppvObject
);
964 /************************************************************************
965 * DataCache_NDIUnknown_AddRef (IUnknown)
967 * See Windows documentation for more details on IUnknown methods.
969 * This version of QueryInterface will not delegate it's implementation
970 * to the outer unknown.
972 static ULONG WINAPI
DataCache_NDIUnknown_AddRef(
975 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
982 /************************************************************************
983 * DataCache_NDIUnknown_Release (IUnknown)
985 * See Windows documentation for more details on IUnknown methods.
987 * This version of QueryInterface will not delegate it's implementation
988 * to the outer unknown.
990 static ULONG WINAPI
DataCache_NDIUnknown_Release(
993 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
996 * Decrease the reference count on this object.
1001 * If the reference count goes down to 0, perform suicide.
1005 DataCache_Destroy(this);
1013 /*********************************************************
1014 * Method implementation for the IDataObject
1015 * part of the DataCache class.
1018 /************************************************************************
1019 * DataCache_IDataObject_QueryInterface (IUnknown)
1021 * See Windows documentation for more details on IUnknown methods.
1023 static HRESULT WINAPI
DataCache_IDataObject_QueryInterface(
1028 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
1030 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1033 /************************************************************************
1034 * DataCache_IDataObject_AddRef (IUnknown)
1036 * See Windows documentation for more details on IUnknown methods.
1038 static ULONG WINAPI
DataCache_IDataObject_AddRef(
1041 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
1043 return IUnknown_AddRef(this->outerUnknown
);
1046 /************************************************************************
1047 * DataCache_IDataObject_Release (IUnknown)
1049 * See Windows documentation for more details on IUnknown methods.
1051 static ULONG WINAPI
DataCache_IDataObject_Release(
1054 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
1056 return IUnknown_Release(this->outerUnknown
);
1059 /************************************************************************
1062 * Get Data from a source dataobject using format pformatetcIn->cfFormat
1063 * See Windows documentation for more details on GetData.
1064 * TODO: Currently only CF_METAFILEPICT is implemented
1066 static HRESULT WINAPI
DataCache_GetData(
1068 LPFORMATETC pformatetcIn
,
1072 HRESULT hrRet
= E_UNEXPECTED
;
1073 IPersistStorage
*pPersistStorage
= 0;
1074 IStorage
*pStorage
= 0;
1075 IStream
*pStream
= 0;
1076 OLECHAR name
[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
1077 HGLOBAL hGlobalMF
= 0;
1079 PresentationDataHeader pdh
;
1080 METAFILEPICT
*mfPict
;
1081 HMETAFILE hMetaFile
= 0;
1083 if (pformatetcIn
->cfFormat
== CF_METAFILEPICT
)
1085 /* Get the Persist Storage */
1087 hr
= IDataObject_QueryInterface(iface
, &IID_IPersistStorage
, (void**)&pPersistStorage
);
1092 /* Create a doc file to copy the doc to a storage */
1094 hr
= StgCreateDocfile(NULL
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &pStorage
);
1099 /* Save it to storage */
1101 hr
= OleSave(pPersistStorage
, pStorage
, FALSE
);
1106 /* Open the Presentation data srteam */
1108 hr
= IStorage_OpenStream(pStorage
, name
, 0, STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &pStream
);
1113 /* Read the presentation header */
1115 hr
= IStream_Read(pStream
, &pdh
, sizeof(PresentationDataHeader
), NULL
);
1120 mfBits
= HeapAlloc(GetProcessHeap(), 0, pdh
.dwSize
);
1122 /* Read the Metafile bits */
1124 hr
= IStream_Read(pStream
, mfBits
, pdh
.dwSize
, NULL
);
1129 /* Create the metafile and place it in the STGMEDIUM structure */
1131 hMetaFile
= SetMetaFileBitsEx(pdh
.dwSize
, mfBits
);
1133 hGlobalMF
= GlobalAlloc(GMEM_SHARE
|GMEM_MOVEABLE
, sizeof(METAFILEPICT
));
1134 mfPict
= (METAFILEPICT
*)GlobalLock(hGlobalMF
);
1135 mfPict
->hMF
= hMetaFile
;
1137 GlobalUnlock(hGlobalMF
);
1139 pmedium
->u
.hGlobal
= hGlobalMF
;
1140 pmedium
->tymed
= TYMED_MFPICT
;
1146 HeapFree(GetProcessHeap(), 0, mfBits
);
1149 IStream_Release(pStream
);
1152 IStorage_Release(pStorage
);
1154 if (pPersistStorage
)
1155 IPersistStorage_Release(pPersistStorage
);
1160 /* TODO: Other formats are not implemented */
1165 static HRESULT WINAPI
DataCache_GetDataHere(
1167 LPFORMATETC pformatetc
,
1174 static HRESULT WINAPI
DataCache_QueryGetData(
1176 LPFORMATETC pformatetc
)
1182 /************************************************************************
1183 * DataCache_EnumFormatEtc (IDataObject)
1185 * The data cache doesn't implement this method.
1187 * See Windows documentation for more details on IDataObject methods.
1189 static HRESULT WINAPI
DataCache_GetCanonicalFormatEtc(
1191 LPFORMATETC pformatectIn
,
1192 LPFORMATETC pformatetcOut
)
1198 /************************************************************************
1199 * DataCache_IDataObject_SetData (IDataObject)
1201 * This method is delegated to the IOleCache2 implementation.
1203 * See Windows documentation for more details on IDataObject methods.
1205 static HRESULT WINAPI
DataCache_IDataObject_SetData(
1207 LPFORMATETC pformatetc
,
1211 IOleCache2
* oleCache
= NULL
;
1214 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1216 hres
= IDataObject_QueryInterface(iface
, &IID_IOleCache2
, (void**)&oleCache
);
1219 return E_UNEXPECTED
;
1221 hres
= IOleCache2_SetData(oleCache
, pformatetc
, pmedium
, fRelease
);
1223 IOleCache2_Release(oleCache
);
1228 /************************************************************************
1229 * DataCache_EnumFormatEtc (IDataObject)
1231 * The data cache doesn't implement this method.
1233 * See Windows documentation for more details on IDataObject methods.
1235 static HRESULT WINAPI
DataCache_EnumFormatEtc(
1238 IEnumFORMATETC
** ppenumFormatEtc
)
1244 /************************************************************************
1245 * DataCache_DAdvise (IDataObject)
1247 * The data cache doesn't support connections.
1249 * See Windows documentation for more details on IDataObject methods.
1251 static HRESULT WINAPI
DataCache_DAdvise(
1253 FORMATETC
* pformatetc
,
1255 IAdviseSink
* pAdvSink
,
1256 DWORD
* pdwConnection
)
1259 return OLE_E_ADVISENOTSUPPORTED
;
1262 /************************************************************************
1263 * DataCache_DUnadvise (IDataObject)
1265 * The data cache doesn't support connections.
1267 * See Windows documentation for more details on IDataObject methods.
1269 static HRESULT WINAPI
DataCache_DUnadvise(
1274 return OLE_E_NOCONNECTION
;
1277 /************************************************************************
1278 * DataCache_EnumDAdvise (IDataObject)
1280 * The data cache doesn't support connections.
1282 * See Windows documentation for more details on IDataObject methods.
1284 static HRESULT WINAPI
DataCache_EnumDAdvise(
1286 IEnumSTATDATA
** ppenumAdvise
)
1289 return OLE_E_ADVISENOTSUPPORTED
;
1292 /*********************************************************
1293 * Method implementation for the IDataObject
1294 * part of the DataCache class.
1297 /************************************************************************
1298 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1300 * See Windows documentation for more details on IUnknown methods.
1302 static HRESULT WINAPI
DataCache_IPersistStorage_QueryInterface(
1303 IPersistStorage
* iface
,
1307 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1309 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1312 /************************************************************************
1313 * DataCache_IPersistStorage_AddRef (IUnknown)
1315 * See Windows documentation for more details on IUnknown methods.
1317 static ULONG WINAPI
DataCache_IPersistStorage_AddRef(
1318 IPersistStorage
* iface
)
1320 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1322 return IUnknown_AddRef(this->outerUnknown
);
1325 /************************************************************************
1326 * DataCache_IPersistStorage_Release (IUnknown)
1328 * See Windows documentation for more details on IUnknown methods.
1330 static ULONG WINAPI
DataCache_IPersistStorage_Release(
1331 IPersistStorage
* iface
)
1333 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1335 return IUnknown_Release(this->outerUnknown
);
1338 /************************************************************************
1339 * DataCache_GetClassID (IPersistStorage)
1341 * The data cache doesn't implement this method.
1343 * See Windows documentation for more details on IPersistStorage methods.
1345 static HRESULT WINAPI
DataCache_GetClassID(
1346 IPersistStorage
* iface
,
1349 TRACE("(%p, %p)\n", iface
, pClassID
);
1353 /************************************************************************
1354 * DataCache_IsDirty (IPersistStorage)
1356 * Until we actully connect to a running object and retrieve new
1357 * information to it, we never get dirty.
1359 * See Windows documentation for more details on IPersistStorage methods.
1361 static HRESULT WINAPI
DataCache_IsDirty(
1362 IPersistStorage
* iface
)
1364 TRACE("(%p)\n", iface
);
1369 /************************************************************************
1370 * DataCache_InitNew (IPersistStorage)
1372 * The data cache implementation of IPersistStorage_InitNew simply stores
1373 * the storage pointer.
1375 * See Windows documentation for more details on IPersistStorage methods.
1377 static HRESULT WINAPI
DataCache_InitNew(
1378 IPersistStorage
* iface
,
1381 TRACE("(%p, %p)\n", iface
, pStg
);
1383 return DataCache_Load(iface
, pStg
);
1386 /************************************************************************
1387 * DataCache_Load (IPersistStorage)
1389 * The data cache implementation of IPersistStorage_Load doesn't
1390 * actually load anything. Instead, it holds on to the storage pointer
1391 * and it will load the presentation information when the
1392 * IDataObject_GetData or IViewObject2_Draw methods are called.
1394 * See Windows documentation for more details on IPersistStorage methods.
1396 static HRESULT WINAPI
DataCache_Load(
1397 IPersistStorage
* iface
,
1400 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1402 TRACE("(%p, %p)\n", iface
, pStg
);
1404 if (this->presentationStorage
!= NULL
)
1406 IStorage_Release(this->presentationStorage
);
1409 this->presentationStorage
= pStg
;
1411 if (this->presentationStorage
!= NULL
)
1413 IStorage_AddRef(this->presentationStorage
);
1418 /************************************************************************
1419 * DataCache_Save (IPersistStorage)
1421 * Until we actully connect to a running object and retrieve new
1422 * information to it, we never have to save anything. However, it is
1423 * our responsability to copy the information when saving to a new
1426 * See Windows documentation for more details on IPersistStorage methods.
1428 static HRESULT WINAPI
DataCache_Save(
1429 IPersistStorage
* iface
,
1433 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1435 TRACE("(%p, %p, %d)\n", iface
, pStg
, fSameAsLoad
);
1437 if ( (!fSameAsLoad
) &&
1438 (this->presentationStorage
!=NULL
) )
1440 return IStorage_CopyTo(this->presentationStorage
,
1450 /************************************************************************
1451 * DataCache_SaveCompleted (IPersistStorage)
1453 * This method is called to tell the cache to release the storage
1454 * pointer it's currentlu holding.
1456 * See Windows documentation for more details on IPersistStorage methods.
1458 static HRESULT WINAPI
DataCache_SaveCompleted(
1459 IPersistStorage
* iface
,
1462 TRACE("(%p, %p)\n", iface
, pStgNew
);
1467 * First, make sure we get our hands off any storage we have.
1470 DataCache_HandsOffStorage(iface
);
1473 * Then, attach to the new storage.
1476 DataCache_Load(iface
, pStgNew
);
1482 /************************************************************************
1483 * DataCache_HandsOffStorage (IPersistStorage)
1485 * This method is called to tell the cache to release the storage
1486 * pointer it's currentlu holding.
1488 * See Windows documentation for more details on IPersistStorage methods.
1490 static HRESULT WINAPI
DataCache_HandsOffStorage(
1491 IPersistStorage
* iface
)
1493 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1495 TRACE("(%p)\n", iface
);
1497 if (this->presentationStorage
!= NULL
)
1499 IStorage_Release(this->presentationStorage
);
1500 this->presentationStorage
= NULL
;
1506 /*********************************************************
1507 * Method implementation for the IViewObject2
1508 * part of the DataCache class.
1511 /************************************************************************
1512 * DataCache_IViewObject2_QueryInterface (IUnknown)
1514 * See Windows documentation for more details on IUnknown methods.
1516 static HRESULT WINAPI
DataCache_IViewObject2_QueryInterface(
1517 IViewObject2
* iface
,
1521 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1523 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1526 /************************************************************************
1527 * DataCache_IViewObject2_AddRef (IUnknown)
1529 * See Windows documentation for more details on IUnknown methods.
1531 static ULONG WINAPI
DataCache_IViewObject2_AddRef(
1532 IViewObject2
* iface
)
1534 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1536 return IUnknown_AddRef(this->outerUnknown
);
1539 /************************************************************************
1540 * DataCache_IViewObject2_Release (IUnknown)
1542 * See Windows documentation for more details on IUnknown methods.
1544 static ULONG WINAPI
DataCache_IViewObject2_Release(
1545 IViewObject2
* iface
)
1547 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1549 return IUnknown_Release(this->outerUnknown
);
1552 /************************************************************************
1553 * DataCache_Draw (IViewObject2)
1555 * This method will draw the cached representation of the object
1556 * to the given device context.
1558 * See Windows documentation for more details on IViewObject2 methods.
1560 static HRESULT WINAPI
DataCache_Draw(
1561 IViewObject2
* iface
,
1565 DVTARGETDEVICE
* ptd
,
1568 LPCRECTL lprcBounds
,
1569 LPCRECTL lprcWBounds
,
1570 IVO_ContCallback pfnContinue
,
1573 PresentationDataHeader presData
;
1574 HMETAFILE presMetafile
= 0;
1577 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1579 TRACE("(%p, %lx, %ld, %p, %p, %p, %p, %p, %p, %lx)\n",
1594 if (lprcBounds
==NULL
)
1595 return E_INVALIDARG
;
1598 * First, we need to retrieve the dimensions of the
1599 * image in the metafile.
1601 hres
= DataCache_ReadPresentationData(this,
1609 * Then, we can extract the metafile itself from the cached
1612 * FIXME Unless it isn't a metafile. I think it could be any CF_XXX type,
1613 * particularly CF_DIB.
1615 presMetafile
= DataCache_ReadPresMetafile(this,
1619 * If we have a metafile, just draw baby...
1620 * We have to be careful not to modify the state of the
1623 if (presMetafile
!=0)
1625 INT prevMapMode
= SetMapMode(hdcDraw
, MM_ANISOTROPIC
);
1627 SIZE oldViewportExt
;
1628 POINT oldViewportOrg
;
1630 SetWindowExtEx(hdcDraw
,
1631 presData
.dwObjectExtentX
,
1632 presData
.dwObjectExtentY
,
1635 SetViewportExtEx(hdcDraw
,
1636 lprcBounds
->right
- lprcBounds
->left
,
1637 lprcBounds
->bottom
- lprcBounds
->top
,
1640 SetViewportOrgEx(hdcDraw
,
1645 PlayMetaFile(hdcDraw
, presMetafile
);
1647 SetWindowExtEx(hdcDraw
,
1652 SetViewportExtEx(hdcDraw
,
1657 SetViewportOrgEx(hdcDraw
,
1662 SetMapMode(hdcDraw
, prevMapMode
);
1664 DeleteMetaFile(presMetafile
);
1670 static HRESULT WINAPI
DataCache_GetColorSet(
1671 IViewObject2
* iface
,
1675 DVTARGETDEVICE
* ptd
,
1676 HDC hicTargetDevice
,
1677 LOGPALETTE
** ppColorSet
)
1683 static HRESULT WINAPI
DataCache_Freeze(
1684 IViewObject2
* iface
,
1694 static HRESULT WINAPI
DataCache_Unfreeze(
1695 IViewObject2
* iface
,
1702 /************************************************************************
1703 * DataCache_SetAdvise (IViewObject2)
1705 * This sets-up an advisory sink with the data cache. When the object's
1706 * view changes, this sink is called.
1708 * See Windows documentation for more details on IViewObject2 methods.
1710 static HRESULT WINAPI
DataCache_SetAdvise(
1711 IViewObject2
* iface
,
1714 IAdviseSink
* pAdvSink
)
1716 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1718 TRACE("(%p, %lx, %lx, %p)\n", iface
, aspects
, advf
, pAdvSink
);
1721 * A call to this function removes the previous sink
1723 if (this->sinkInterface
!= NULL
)
1725 IAdviseSink_Release(this->sinkInterface
);
1726 this->sinkInterface
= NULL
;
1727 this->sinkAspects
= 0;
1728 this->sinkAdviseFlag
= 0;
1732 * Now, setup the new one.
1736 this->sinkInterface
= pAdvSink
;
1737 this->sinkAspects
= aspects
;
1738 this->sinkAdviseFlag
= advf
;
1740 IAdviseSink_AddRef(this->sinkInterface
);
1744 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1747 if (advf
& ADVF_PRIMEFIRST
)
1749 DataCache_FireOnViewChange(this,
1757 /************************************************************************
1758 * DataCache_GetAdvise (IViewObject2)
1760 * This method queries the current state of the advise sink
1761 * installed on the data cache.
1763 * See Windows documentation for more details on IViewObject2 methods.
1765 static HRESULT WINAPI
DataCache_GetAdvise(
1766 IViewObject2
* iface
,
1769 IAdviseSink
** ppAdvSink
)
1771 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1773 TRACE("(%p, %p, %p, %p)\n", iface
, pAspects
, pAdvf
, ppAdvSink
);
1776 * Just copy all the requested values.
1779 *pAspects
= this->sinkAspects
;
1782 *pAdvf
= this->sinkAdviseFlag
;
1784 if (ppAdvSink
!=NULL
)
1786 IAdviseSink_QueryInterface(this->sinkInterface
,
1794 /************************************************************************
1795 * DataCache_GetExtent (IViewObject2)
1797 * This method retrieves the "natural" size of this cached object.
1799 * See Windows documentation for more details on IViewObject2 methods.
1801 static HRESULT WINAPI
DataCache_GetExtent(
1802 IViewObject2
* iface
,
1805 DVTARGETDEVICE
* ptd
,
1808 PresentationDataHeader presData
;
1809 HRESULT hres
= E_FAIL
;
1811 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1813 TRACE("(%p, %lx, %ld, %p, %p)\n",
1814 iface
, dwDrawAspect
, lindex
, ptd
, lpsizel
);
1823 * Initialize the out parameter.
1829 * This flag should be set to -1.
1832 FIXME("Unimplemented flag lindex = %ld\n", lindex
);
1835 * Right now, we suport only the callback from
1836 * the default handler.
1839 FIXME("Unimplemented ptd = %p\n", ptd
);
1842 * Get the presentation information from the
1845 hres
= DataCache_ReadPresentationData(this,
1849 if (SUCCEEDED(hres
))
1851 lpsizel
->cx
= presData
.dwObjectExtentX
;
1852 lpsizel
->cy
= presData
.dwObjectExtentY
;
1856 * This method returns OLE_E_BLANK when it fails.
1865 /*********************************************************
1866 * Method implementation for the IOleCache2
1867 * part of the DataCache class.
1870 /************************************************************************
1871 * DataCache_IOleCache2_QueryInterface (IUnknown)
1873 * See Windows documentation for more details on IUnknown methods.
1875 static HRESULT WINAPI
DataCache_IOleCache2_QueryInterface(
1880 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1882 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1885 /************************************************************************
1886 * DataCache_IOleCache2_AddRef (IUnknown)
1888 * See Windows documentation for more details on IUnknown methods.
1890 static ULONG WINAPI
DataCache_IOleCache2_AddRef(
1893 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1895 return IUnknown_AddRef(this->outerUnknown
);
1898 /************************************************************************
1899 * DataCache_IOleCache2_Release (IUnknown)
1901 * See Windows documentation for more details on IUnknown methods.
1903 static ULONG WINAPI
DataCache_IOleCache2_Release(
1906 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1908 return IUnknown_Release(this->outerUnknown
);
1911 static HRESULT WINAPI
DataCache_Cache(
1913 FORMATETC
* pformatetc
,
1915 DWORD
* pdwConnection
)
1921 static HRESULT WINAPI
DataCache_Uncache(
1929 static HRESULT WINAPI
DataCache_EnumCache(
1931 IEnumSTATDATA
** ppenumSTATDATA
)
1937 static HRESULT WINAPI
DataCache_InitCache(
1939 IDataObject
* pDataObject
)
1945 static HRESULT WINAPI
DataCache_IOleCache2_SetData(
1947 FORMATETC
* pformatetc
,
1955 static HRESULT WINAPI
DataCache_UpdateCache(
1957 LPDATAOBJECT pDataObject
,
1965 static HRESULT WINAPI
DataCache_DiscardCache(
1967 DWORD dwDiscardOptions
)
1974 /*********************************************************
1975 * Method implementation for the IOleCacheControl
1976 * part of the DataCache class.
1979 /************************************************************************
1980 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1982 * See Windows documentation for more details on IUnknown methods.
1984 static HRESULT WINAPI
DataCache_IOleCacheControl_QueryInterface(
1985 IOleCacheControl
* iface
,
1989 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1991 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1994 /************************************************************************
1995 * DataCache_IOleCacheControl_AddRef (IUnknown)
1997 * See Windows documentation for more details on IUnknown methods.
1999 static ULONG WINAPI
DataCache_IOleCacheControl_AddRef(
2000 IOleCacheControl
* iface
)
2002 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
2004 return IUnknown_AddRef(this->outerUnknown
);
2007 /************************************************************************
2008 * DataCache_IOleCacheControl_Release (IUnknown)
2010 * See Windows documentation for more details on IUnknown methods.
2012 static ULONG WINAPI
DataCache_IOleCacheControl_Release(
2013 IOleCacheControl
* iface
)
2015 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
2017 return IUnknown_Release(this->outerUnknown
);
2020 static HRESULT WINAPI
DataCache_OnRun(
2021 IOleCacheControl
* iface
,
2022 LPDATAOBJECT pDataObject
)
2028 static HRESULT WINAPI
DataCache_OnStop(
2029 IOleCacheControl
* iface
)