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.
53 #include "wine/obj_base.h"
54 #include "wine/obj_misc.h"
55 #include "wine/obj_storage.h"
56 #include "wine/obj_moniker.h"
57 #include "wine/obj_dataobject.h"
58 #include "wine/obj_oleview.h"
59 #include "wine/obj_cache.h"
60 #include "wine/unicode.h"
62 #include "wine/debug.h"
64 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
66 /****************************************************************************
67 * PresentationDataHeader
69 * This structure represents the header of the \002OlePresXXX stream in
70 * the OLE object strorage.
72 * Most fields are still unknown.
74 typedef struct PresentationDataHeader
76 DWORD unknown1
; /* -1 */
77 DWORD unknown2
; /* 3, possibly CF_METAFILEPICT */
78 DWORD unknown3
; /* 4, possibly TYMED_ISTREAM */
80 DWORD unknown5
; /* -1 */
83 DWORD unknown7
; /* 0 */
84 DWORD dwObjectExtentX
;
85 DWORD dwObjectExtentY
;
87 } PresentationDataHeader
;
89 /****************************************************************************
95 * List all interface VTables here
97 ICOM_VTABLE(IDataObject
)* lpvtbl1
;
98 ICOM_VTABLE(IUnknown
)* lpvtbl2
;
99 ICOM_VTABLE(IPersistStorage
)* lpvtbl3
;
100 ICOM_VTABLE(IViewObject2
)* lpvtbl4
;
101 ICOM_VTABLE(IOleCache2
)* lpvtbl5
;
102 ICOM_VTABLE(IOleCacheControl
)* lpvtbl6
;
105 * Reference count of this object
110 * IUnknown implementation of the outer object.
112 IUnknown
* outerUnknown
;
115 * This storage pointer is set through a call to
116 * IPersistStorage_Load. This is where the visual
117 * representation of the object is stored.
119 IStorage
* presentationStorage
;
122 * The user of this object can setup ONE advise sink
123 * connection with the object. These parameters describe
127 DWORD sinkAdviseFlag
;
128 IAdviseSink
* sinkInterface
;
132 typedef struct DataCache DataCache
;
135 * Here, I define utility macros to help with the casting of the
137 * There is a version to accomodate all of the VTables implemented
140 #define _ICOM_THIS_From_IDataObject(class,name) class* this = (class*)name;
141 #define _ICOM_THIS_From_NDIUnknown(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
142 #define _ICOM_THIS_From_IPersistStorage(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
143 #define _ICOM_THIS_From_IViewObject2(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
144 #define _ICOM_THIS_From_IOleCache2(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*));
145 #define _ICOM_THIS_From_IOleCacheControl(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*));
148 * Prototypes for the methods of the DataCache class.
150 static DataCache
* DataCache_Construct(REFCLSID clsid
,
151 LPUNKNOWN pUnkOuter
);
152 static void DataCache_Destroy(DataCache
* ptrToDestroy
);
153 static HRESULT
DataCache_ReadPresentationData(DataCache
* this,
155 PresentationDataHeader
* header
);
156 static HRESULT
DataCache_OpenPresStream(DataCache
*this,
159 static HMETAFILE
DataCache_ReadPresMetafile(DataCache
* this,
161 static void DataCache_FireOnViewChange(DataCache
* this,
166 * Prototypes for the methods of the DataCache class
167 * that implement non delegating IUnknown methods.
169 static HRESULT WINAPI
DataCache_NDIUnknown_QueryInterface(
173 static ULONG WINAPI
DataCache_NDIUnknown_AddRef(
175 static ULONG WINAPI
DataCache_NDIUnknown_Release(
179 * Prototypes for the methods of the DataCache class
180 * that implement IDataObject methods.
182 static HRESULT WINAPI
DataCache_IDataObject_QueryInterface(
186 static ULONG WINAPI
DataCache_IDataObject_AddRef(
188 static ULONG WINAPI
DataCache_IDataObject_Release(
190 static HRESULT WINAPI
DataCache_GetData(
192 LPFORMATETC pformatetcIn
,
194 static HRESULT WINAPI
DataCache_GetDataHere(
196 LPFORMATETC pformatetc
,
198 static HRESULT WINAPI
DataCache_QueryGetData(
200 LPFORMATETC pformatetc
);
201 static HRESULT WINAPI
DataCache_GetCanonicalFormatEtc(
203 LPFORMATETC pformatectIn
,
204 LPFORMATETC pformatetcOut
);
205 static HRESULT WINAPI
DataCache_IDataObject_SetData(
207 LPFORMATETC pformatetc
,
210 static HRESULT WINAPI
DataCache_EnumFormatEtc(
213 IEnumFORMATETC
** ppenumFormatEtc
);
214 static HRESULT WINAPI
DataCache_DAdvise(
216 FORMATETC
* pformatetc
,
218 IAdviseSink
* pAdvSink
,
219 DWORD
* pdwConnection
);
220 static HRESULT WINAPI
DataCache_DUnadvise(
223 static HRESULT WINAPI
DataCache_EnumDAdvise(
225 IEnumSTATDATA
** ppenumAdvise
);
228 * Prototypes for the methods of the DataCache class
229 * that implement IPersistStorage methods.
231 static HRESULT WINAPI
DataCache_IPersistStorage_QueryInterface(
232 IPersistStorage
* iface
,
235 static ULONG WINAPI
DataCache_IPersistStorage_AddRef(
236 IPersistStorage
* iface
);
237 static ULONG WINAPI
DataCache_IPersistStorage_Release(
238 IPersistStorage
* iface
);
239 static HRESULT WINAPI
DataCache_GetClassID(
240 IPersistStorage
* iface
,
242 static HRESULT WINAPI
DataCache_IsDirty(
243 IPersistStorage
* iface
);
244 static HRESULT WINAPI
DataCache_InitNew(
245 IPersistStorage
* iface
,
247 static HRESULT WINAPI
DataCache_Load(
248 IPersistStorage
* iface
,
250 static HRESULT WINAPI
DataCache_Save(
251 IPersistStorage
* iface
,
254 static HRESULT WINAPI
DataCache_SaveCompleted(
255 IPersistStorage
* iface
,
257 static HRESULT WINAPI
DataCache_HandsOffStorage(
258 IPersistStorage
* iface
);
261 * Prototypes for the methods of the DataCache class
262 * that implement IViewObject2 methods.
264 static HRESULT WINAPI
DataCache_IViewObject2_QueryInterface(
268 static ULONG WINAPI
DataCache_IViewObject2_AddRef(
269 IViewObject2
* iface
);
270 static ULONG WINAPI
DataCache_IViewObject2_Release(
271 IViewObject2
* iface
);
272 static HRESULT WINAPI
DataCache_Draw(
281 LPCRECTL lprcWBounds
,
282 IVO_ContCallback pfnContinue
,
284 static HRESULT WINAPI
DataCache_GetColorSet(
291 LOGPALETTE
** ppColorSet
);
292 static HRESULT WINAPI
DataCache_Freeze(
298 static HRESULT WINAPI
DataCache_Unfreeze(
301 static HRESULT WINAPI
DataCache_SetAdvise(
305 IAdviseSink
* pAdvSink
);
306 static HRESULT WINAPI
DataCache_GetAdvise(
310 IAdviseSink
** ppAdvSink
);
311 static HRESULT WINAPI
DataCache_GetExtent(
319 * Prototypes for the methods of the DataCache class
320 * that implement IOleCache2 methods.
322 static HRESULT WINAPI
DataCache_IOleCache2_QueryInterface(
326 static ULONG WINAPI
DataCache_IOleCache2_AddRef(
328 static ULONG WINAPI
DataCache_IOleCache2_Release(
330 static HRESULT WINAPI
DataCache_Cache(
332 FORMATETC
* pformatetc
,
334 DWORD
* pdwConnection
);
335 static HRESULT WINAPI
DataCache_Uncache(
338 static HRESULT WINAPI
DataCache_EnumCache(
340 IEnumSTATDATA
** ppenumSTATDATA
);
341 static HRESULT WINAPI
DataCache_InitCache(
343 IDataObject
* pDataObject
);
344 static HRESULT WINAPI
DataCache_IOleCache2_SetData(
346 FORMATETC
* pformatetc
,
349 static HRESULT WINAPI
DataCache_UpdateCache(
351 LPDATAOBJECT pDataObject
,
354 static HRESULT WINAPI
DataCache_DiscardCache(
356 DWORD dwDiscardOptions
);
359 * Prototypes for the methods of the DataCache class
360 * that implement IOleCacheControl methods.
362 static HRESULT WINAPI
DataCache_IOleCacheControl_QueryInterface(
363 IOleCacheControl
* iface
,
366 static ULONG WINAPI
DataCache_IOleCacheControl_AddRef(
367 IOleCacheControl
* iface
);
368 static ULONG WINAPI
DataCache_IOleCacheControl_Release(
369 IOleCacheControl
* iface
);
370 static HRESULT WINAPI
DataCache_OnRun(
371 IOleCacheControl
* iface
,
372 LPDATAOBJECT pDataObject
);
373 static HRESULT WINAPI
DataCache_OnStop(
374 IOleCacheControl
* iface
);
377 * Virtual function tables for the DataCache class.
379 static ICOM_VTABLE(IUnknown
) DataCache_NDIUnknown_VTable
=
381 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
382 DataCache_NDIUnknown_QueryInterface
,
383 DataCache_NDIUnknown_AddRef
,
384 DataCache_NDIUnknown_Release
387 static ICOM_VTABLE(IDataObject
) DataCache_IDataObject_VTable
=
389 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
390 DataCache_IDataObject_QueryInterface
,
391 DataCache_IDataObject_AddRef
,
392 DataCache_IDataObject_Release
,
394 DataCache_GetDataHere
,
395 DataCache_QueryGetData
,
396 DataCache_GetCanonicalFormatEtc
,
397 DataCache_IDataObject_SetData
,
398 DataCache_EnumFormatEtc
,
401 DataCache_EnumDAdvise
404 static ICOM_VTABLE(IPersistStorage
) DataCache_IPersistStorage_VTable
=
406 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
407 DataCache_IPersistStorage_QueryInterface
,
408 DataCache_IPersistStorage_AddRef
,
409 DataCache_IPersistStorage_Release
,
410 DataCache_GetClassID
,
415 DataCache_SaveCompleted
,
416 DataCache_HandsOffStorage
419 static ICOM_VTABLE(IViewObject2
) DataCache_IViewObject2_VTable
=
421 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
422 DataCache_IViewObject2_QueryInterface
,
423 DataCache_IViewObject2_AddRef
,
424 DataCache_IViewObject2_Release
,
426 DataCache_GetColorSet
,
434 static ICOM_VTABLE(IOleCache2
) DataCache_IOleCache2_VTable
=
436 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
437 DataCache_IOleCache2_QueryInterface
,
438 DataCache_IOleCache2_AddRef
,
439 DataCache_IOleCache2_Release
,
444 DataCache_IOleCache2_SetData
,
445 DataCache_UpdateCache
,
446 DataCache_DiscardCache
449 static ICOM_VTABLE(IOleCacheControl
) DataCache_IOleCacheControl_VTable
=
451 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
452 DataCache_IOleCacheControl_QueryInterface
,
453 DataCache_IOleCacheControl_AddRef
,
454 DataCache_IOleCacheControl_Release
,
459 /******************************************************************************
460 * CreateDataCache [OLE32.54]
462 HRESULT WINAPI
CreateDataCache(
468 DataCache
* newCache
= NULL
;
471 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(rclsid
), pUnkOuter
, debugstr_guid(riid
), ppvObj
);
482 * If this cache is constructed for aggregation, make sure
483 * the caller is requesting the IUnknown interface.
484 * This is necessary because it's the only time the non-delegating
485 * IUnknown pointer can be returned to the outside.
487 if ( (pUnkOuter
!=NULL
) &&
488 (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) != 0) )
489 return CLASS_E_NOAGGREGATION
;
492 * Try to construct a new instance of the class.
494 newCache
= DataCache_Construct(rclsid
,
498 return E_OUTOFMEMORY
;
501 * Make sure it supports the interface required by the caller.
503 hr
= IUnknown_QueryInterface((IUnknown
*)&(newCache
->lpvtbl2
), riid
, ppvObj
);
506 * Release the reference obtained in the constructor. If
507 * the QueryInterface was unsuccessful, it will free the class.
509 IUnknown_Release((IUnknown
*)&(newCache
->lpvtbl2
));
514 /*********************************************************
515 * Method implementation for DataCache class.
517 static DataCache
* DataCache_Construct(
521 DataCache
* newObject
= 0;
524 * Allocate space for the object.
526 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache
));
532 * Initialize the virtual function table.
534 newObject
->lpvtbl1
= &DataCache_IDataObject_VTable
;
535 newObject
->lpvtbl2
= &DataCache_NDIUnknown_VTable
;
536 newObject
->lpvtbl3
= &DataCache_IPersistStorage_VTable
;
537 newObject
->lpvtbl4
= &DataCache_IViewObject2_VTable
;
538 newObject
->lpvtbl5
= &DataCache_IOleCache2_VTable
;
539 newObject
->lpvtbl6
= &DataCache_IOleCacheControl_VTable
;
542 * Start with one reference count. The caller of this function
543 * must release the interface pointer when it is done.
548 * Initialize the outer unknown
549 * We don't keep a reference on the outer unknown since, the way
550 * aggregation works, our lifetime is at least as large as it's
554 pUnkOuter
= (IUnknown
*)&(newObject
->lpvtbl2
);
556 newObject
->outerUnknown
= pUnkOuter
;
559 * Initialize the other members of the structure.
561 newObject
->presentationStorage
= NULL
;
562 newObject
->sinkAspects
= 0;
563 newObject
->sinkAdviseFlag
= 0;
564 newObject
->sinkInterface
= 0;
569 static void DataCache_Destroy(
570 DataCache
* ptrToDestroy
)
574 if (ptrToDestroy
->sinkInterface
!= NULL
)
576 IAdviseSink_Release(ptrToDestroy
->sinkInterface
);
577 ptrToDestroy
->sinkInterface
= NULL
;
580 if (ptrToDestroy
->presentationStorage
!= NULL
)
582 IStorage_Release(ptrToDestroy
->presentationStorage
);
583 ptrToDestroy
->presentationStorage
= NULL
;
587 * Free the datacache pointer.
589 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
592 /************************************************************************
593 * DataCache_ReadPresentationData
595 * This method will read information for the requested presentation
596 * into the given structure.
599 * this - Pointer to the DataCache object
600 * drawAspect - The aspect of the object that we wish to draw.
601 * header - The structure containing information about this
602 * aspect of the object.
604 static HRESULT
DataCache_ReadPresentationData(
607 PresentationDataHeader
* header
)
609 IStream
* presStream
= NULL
;
613 * Open the presentation stream.
615 hres
= DataCache_OpenPresStream(
630 sizeof(PresentationDataHeader
),
636 IStream_Release(presStream
);
639 * We don't want to propagate any other error
640 * code than a failure.
648 /************************************************************************
649 * DataCache_FireOnViewChange
651 * This method will fire an OnViewChange notification to the advise
652 * sink registered with the datacache.
654 * See IAdviseSink::OnViewChange for more details.
656 static void DataCache_FireOnViewChange(
661 TRACE("(%p, %lx, %ld)\n", this, aspect
, lindex
);
664 * The sink supplies a filter when it registers
665 * we make sure we only send the notifications when that
668 if ((this->sinkAspects
& aspect
) != 0)
670 if (this->sinkInterface
!= NULL
)
672 IAdviseSink_OnViewChange(this->sinkInterface
,
677 * Some sinks want to be unregistered automatically when
678 * the first notification goes out.
680 if ( (this->sinkAdviseFlag
& ADVF_ONLYONCE
) != 0)
682 IAdviseSink_Release(this->sinkInterface
);
684 this->sinkInterface
= NULL
;
685 this->sinkAspects
= 0;
686 this->sinkAdviseFlag
= 0;
692 /* Helper for DataCache_OpenPresStream */
693 static BOOL
DataCache_IsPresentationStream(const STATSTG
*elem
)
695 /* The presentation streams have names of the form "\002OlePresXXX",
696 * where XXX goes from 000 to 999. */
697 static const WCHAR OlePres
[] = { 2,'O','l','e','P','r','e','s' };
699 LPCWSTR name
= elem
->pwcsName
;
701 return (elem
->type
== STGTY_STREAM
)
702 && (elem
->cbSize
.s
.LowPart
>= sizeof(PresentationDataHeader
))
703 && (strlenW(name
) == 11)
704 && (strncmpW(name
, OlePres
, 8) == 0)
705 && (name
[8] >= '0') && (name
[8] <= '9')
706 && (name
[9] >= '0') && (name
[9] <= '9')
707 && (name
[10] >= '0') && (name
[10] <= '9');
710 /************************************************************************
711 * DataCache_OpenPresStream
713 * This method will find the stream for the given presentation. It makes
714 * no attempt at fallback.
717 * this - Pointer to the DataCache object
718 * drawAspect - The aspect of the object that we wish to draw.
719 * pStm - A returned stream. It points to the beginning of the
720 * - presentation data, including the header.
723 * S_OK The requested stream has been opened.
724 * OLE_E_BLANK The requested stream could not be found.
725 * Quite a few others I'm too lazy to map correctly.
728 * Algorithm: Scan the elements of the presentation storage, looking
729 * for presentation streams. For each presentation stream,
730 * load the header and check to see if the aspect maches.
732 * If a fallback is desired, just opening the first presentation stream
735 static HRESULT
DataCache_OpenPresStream(
744 if (!ppStm
) return E_POINTER
;
746 hr
= IStorage_EnumElements(this->presentationStorage
, 0, NULL
, 0, &pEnum
);
747 if (FAILED(hr
)) return hr
;
749 while ((hr
= IEnumSTATSTG_Next(pEnum
, 1, &elem
, NULL
)) == S_OK
)
751 if (DataCache_IsPresentationStream(&elem
))
755 hr
= IStorage_OpenStream(this->presentationStorage
, elem
.pwcsName
,
756 NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0,
760 PresentationDataHeader header
;
763 hr
= IStream_Read(pStm
, &header
, sizeof(header
), &actual_read
);
765 /* can't use SUCCEEDED(hr): S_FALSE counts as an error */
766 if (hr
== S_OK
&& actual_read
== sizeof(header
)
767 && header
.dvAspect
== drawAspect
)
769 /* Rewind the stream before returning it. */
770 LARGE_INTEGER offset
;
771 offset
.s
.LowPart
= 0;
772 offset
.s
.HighPart
= 0;
773 IStream_Seek(pStm
, offset
, STREAM_SEEK_SET
, NULL
);
777 CoTaskMemFree(elem
.pwcsName
);
778 IEnumSTATSTG_Release(pEnum
);
783 IStream_Release(pStm
);
787 CoTaskMemFree(elem
.pwcsName
);
790 IEnumSTATSTG_Release(pEnum
);
792 return (hr
== S_FALSE
? OLE_E_BLANK
: hr
);
795 /************************************************************************
796 * DataCache_ReadPresentationData
798 * This method will read information for the requested presentation
799 * into the given structure.
802 * this - Pointer to the DataCache object
803 * drawAspect - The aspect of the object that we wish to draw.
806 * This method returns a metafile handle if it is successful.
807 * it will return 0 if not.
809 static HMETAFILE
DataCache_ReadPresMetafile(
813 LARGE_INTEGER offset
;
814 IStream
* presStream
= NULL
;
818 HMETAFILE newMetafile
= 0;
821 * Open the presentation stream.
823 hres
= DataCache_OpenPresStream(
832 * Get the size of the stream.
834 hres
= IStream_Stat(presStream
,
841 offset
.s
.HighPart
= 0;
842 offset
.s
.LowPart
= sizeof(PresentationDataHeader
);
850 streamInfo
.cbSize
.s
.LowPart
-= offset
.s
.LowPart
;
853 * Allocate a buffer for the metafile bits.
855 metafileBits
= HeapAlloc(GetProcessHeap(),
857 streamInfo
.cbSize
.s
.LowPart
);
860 * Read the metafile bits.
865 streamInfo
.cbSize
.s
.LowPart
,
869 * Create a metafile with those bits.
873 newMetafile
= SetMetaFileBitsEx(streamInfo
.cbSize
.s
.LowPart
, metafileBits
);
879 HeapFree(GetProcessHeap(), 0, metafileBits
);
880 IStream_Release(presStream
);
888 /*********************************************************
889 * Method implementation for the non delegating IUnknown
890 * part of the DataCache class.
893 /************************************************************************
894 * DataCache_NDIUnknown_QueryInterface (IUnknown)
896 * See Windows documentation for more details on IUnknown methods.
898 * This version of QueryInterface will not delegate it's implementation
899 * to the outer unknown.
901 static HRESULT WINAPI
DataCache_NDIUnknown_QueryInterface(
906 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
909 * Perform a sanity check on the parameters.
911 if ( (this==0) || (ppvObject
==0) )
915 * Initialize the return parameter.
920 * Compare the riid with the interface IDs implemented by this object.
922 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
926 else if (memcmp(&IID_IDataObject
, riid
, sizeof(IID_IDataObject
)) == 0)
928 *ppvObject
= (IDataObject
*)&(this->lpvtbl1
);
930 else if ( (memcmp(&IID_IPersistStorage
, riid
, sizeof(IID_IPersistStorage
)) == 0) ||
931 (memcmp(&IID_IPersist
, riid
, sizeof(IID_IPersist
)) == 0) )
933 *ppvObject
= (IPersistStorage
*)&(this->lpvtbl3
);
935 else if ( (memcmp(&IID_IViewObject
, riid
, sizeof(IID_IViewObject
)) == 0) ||
936 (memcmp(&IID_IViewObject2
, riid
, sizeof(IID_IViewObject2
)) == 0) )
938 *ppvObject
= (IViewObject2
*)&(this->lpvtbl4
);
940 else if ( (memcmp(&IID_IOleCache
, riid
, sizeof(IID_IOleCache
)) == 0) ||
941 (memcmp(&IID_IOleCache2
, riid
, sizeof(IID_IOleCache2
)) == 0) )
943 *ppvObject
= (IOleCache2
*)&(this->lpvtbl5
);
945 else if (memcmp(&IID_IOleCacheControl
, riid
, sizeof(IID_IOleCacheControl
)) == 0)
947 *ppvObject
= (IOleCacheControl
*)&(this->lpvtbl6
);
951 * Check that we obtained an interface.
955 WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid
));
956 return E_NOINTERFACE
;
960 * Query Interface always increases the reference count by one when it is
963 IUnknown_AddRef((IUnknown
*)*ppvObject
);
968 /************************************************************************
969 * DataCache_NDIUnknown_AddRef (IUnknown)
971 * See Windows documentation for more details on IUnknown methods.
973 * This version of QueryInterface will not delegate it's implementation
974 * to the outer unknown.
976 static ULONG WINAPI
DataCache_NDIUnknown_AddRef(
979 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
986 /************************************************************************
987 * DataCache_NDIUnknown_Release (IUnknown)
989 * See Windows documentation for more details on IUnknown methods.
991 * This version of QueryInterface will not delegate it's implementation
992 * to the outer unknown.
994 static ULONG WINAPI
DataCache_NDIUnknown_Release(
997 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
1000 * Decrease the reference count on this object.
1005 * If the reference count goes down to 0, perform suicide.
1009 DataCache_Destroy(this);
1017 /*********************************************************
1018 * Method implementation for the IDataObject
1019 * part of the DataCache class.
1022 /************************************************************************
1023 * DataCache_IDataObject_QueryInterface (IUnknown)
1025 * See Windows documentation for more details on IUnknown methods.
1027 static HRESULT WINAPI
DataCache_IDataObject_QueryInterface(
1032 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
1034 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1037 /************************************************************************
1038 * DataCache_IDataObject_AddRef (IUnknown)
1040 * See Windows documentation for more details on IUnknown methods.
1042 static ULONG WINAPI
DataCache_IDataObject_AddRef(
1045 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
1047 return IUnknown_AddRef(this->outerUnknown
);
1050 /************************************************************************
1051 * DataCache_IDataObject_Release (IUnknown)
1053 * See Windows documentation for more details on IUnknown methods.
1055 static ULONG WINAPI
DataCache_IDataObject_Release(
1058 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
1060 return IUnknown_Release(this->outerUnknown
);
1063 /************************************************************************
1066 * Get Data from a source dataobject using format pformatetcIn->cfFormat
1067 * See Windows documentation for more details on GetData.
1068 * TODO: Currently only CF_METAFILEPICT is implemented
1070 static HRESULT WINAPI
DataCache_GetData(
1072 LPFORMATETC pformatetcIn
,
1076 HRESULT hrRet
= E_UNEXPECTED
;
1077 IPersistStorage
*pPersistStorage
= 0;
1078 IStorage
*pStorage
= 0;
1079 IStream
*pStream
= 0;
1080 OLECHAR name
[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
1081 HGLOBAL hGlobalMF
= 0;
1083 PresentationDataHeader pdh
;
1084 METAFILEPICT
*mfPict
;
1085 HMETAFILE hMetaFile
= 0;
1087 if (pformatetcIn
->cfFormat
== CF_METAFILEPICT
)
1089 /* Get the Persist Storage */
1091 hr
= IDataObject_QueryInterface(iface
, &IID_IPersistStorage
, (void**)&pPersistStorage
);
1096 /* Create a doc file to copy the doc to a storage */
1098 hr
= StgCreateDocfile(NULL
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &pStorage
);
1103 /* Save it to storage */
1105 hr
= OleSave(pPersistStorage
, pStorage
, FALSE
);
1110 /* Open the Presentation data srteam */
1112 hr
= IStorage_OpenStream(pStorage
, name
, 0, STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &pStream
);
1117 /* Read the presentation header */
1119 hr
= IStream_Read(pStream
, &pdh
, sizeof(PresentationDataHeader
), NULL
);
1124 mfBits
= HeapAlloc(GetProcessHeap(), 0, pdh
.dwSize
);
1126 /* Read the Metafile bits */
1128 hr
= IStream_Read(pStream
, mfBits
, pdh
.dwSize
, NULL
);
1133 /* Create the metafile and place it in the STGMEDIUM structure */
1135 hMetaFile
= SetMetaFileBitsEx(pdh
.dwSize
, mfBits
);
1137 hGlobalMF
= GlobalAlloc(GMEM_SHARE
|GMEM_MOVEABLE
, sizeof(METAFILEPICT
));
1138 mfPict
= (METAFILEPICT
*)GlobalLock(hGlobalMF
);
1139 mfPict
->hMF
= hMetaFile
;
1141 GlobalUnlock(hGlobalMF
);
1143 pmedium
->u
.hGlobal
= hGlobalMF
;
1144 pmedium
->tymed
= TYMED_MFPICT
;
1150 HeapFree(GetProcessHeap(), 0, mfBits
);
1153 IStream_Release(pStream
);
1156 IStorage_Release(pStorage
);
1158 if (pPersistStorage
)
1159 IPersistStorage_Release(pPersistStorage
);
1164 /* TODO: Other formats are not implemented */
1169 static HRESULT WINAPI
DataCache_GetDataHere(
1171 LPFORMATETC pformatetc
,
1178 static HRESULT WINAPI
DataCache_QueryGetData(
1180 LPFORMATETC pformatetc
)
1186 /************************************************************************
1187 * DataCache_EnumFormatEtc (IDataObject)
1189 * The data cache doesn't implement this method.
1191 * See Windows documentation for more details on IDataObject methods.
1193 static HRESULT WINAPI
DataCache_GetCanonicalFormatEtc(
1195 LPFORMATETC pformatectIn
,
1196 LPFORMATETC pformatetcOut
)
1202 /************************************************************************
1203 * DataCache_IDataObject_SetData (IDataObject)
1205 * This method is delegated to the IOleCache2 implementation.
1207 * See Windows documentation for more details on IDataObject methods.
1209 static HRESULT WINAPI
DataCache_IDataObject_SetData(
1211 LPFORMATETC pformatetc
,
1215 IOleCache2
* oleCache
= NULL
;
1218 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1220 hres
= IDataObject_QueryInterface(iface
, &IID_IOleCache2
, (void**)&oleCache
);
1223 return E_UNEXPECTED
;
1225 hres
= IOleCache2_SetData(oleCache
, pformatetc
, pmedium
, fRelease
);
1227 IOleCache2_Release(oleCache
);
1232 /************************************************************************
1233 * DataCache_EnumFormatEtc (IDataObject)
1235 * The data cache doesn't implement this method.
1237 * See Windows documentation for more details on IDataObject methods.
1239 static HRESULT WINAPI
DataCache_EnumFormatEtc(
1242 IEnumFORMATETC
** ppenumFormatEtc
)
1248 /************************************************************************
1249 * DataCache_DAdvise (IDataObject)
1251 * The data cache doesn't support connections.
1253 * See Windows documentation for more details on IDataObject methods.
1255 static HRESULT WINAPI
DataCache_DAdvise(
1257 FORMATETC
* pformatetc
,
1259 IAdviseSink
* pAdvSink
,
1260 DWORD
* pdwConnection
)
1263 return OLE_E_ADVISENOTSUPPORTED
;
1266 /************************************************************************
1267 * DataCache_DUnadvise (IDataObject)
1269 * The data cache doesn't support connections.
1271 * See Windows documentation for more details on IDataObject methods.
1273 static HRESULT WINAPI
DataCache_DUnadvise(
1278 return OLE_E_NOCONNECTION
;
1281 /************************************************************************
1282 * DataCache_EnumDAdvise (IDataObject)
1284 * The data cache doesn't support connections.
1286 * See Windows documentation for more details on IDataObject methods.
1288 static HRESULT WINAPI
DataCache_EnumDAdvise(
1290 IEnumSTATDATA
** ppenumAdvise
)
1293 return OLE_E_ADVISENOTSUPPORTED
;
1296 /*********************************************************
1297 * Method implementation for the IDataObject
1298 * part of the DataCache class.
1301 /************************************************************************
1302 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1304 * See Windows documentation for more details on IUnknown methods.
1306 static HRESULT WINAPI
DataCache_IPersistStorage_QueryInterface(
1307 IPersistStorage
* iface
,
1311 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1313 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1316 /************************************************************************
1317 * DataCache_IPersistStorage_AddRef (IUnknown)
1319 * See Windows documentation for more details on IUnknown methods.
1321 static ULONG WINAPI
DataCache_IPersistStorage_AddRef(
1322 IPersistStorage
* iface
)
1324 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1326 return IUnknown_AddRef(this->outerUnknown
);
1329 /************************************************************************
1330 * DataCache_IPersistStorage_Release (IUnknown)
1332 * See Windows documentation for more details on IUnknown methods.
1334 static ULONG WINAPI
DataCache_IPersistStorage_Release(
1335 IPersistStorage
* iface
)
1337 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1339 return IUnknown_Release(this->outerUnknown
);
1342 /************************************************************************
1343 * DataCache_GetClassID (IPersistStorage)
1345 * The data cache doesn't implement this method.
1347 * See Windows documentation for more details on IPersistStorage methods.
1349 static HRESULT WINAPI
DataCache_GetClassID(
1350 IPersistStorage
* iface
,
1353 TRACE("(%p, %p)\n", iface
, pClassID
);
1357 /************************************************************************
1358 * DataCache_IsDirty (IPersistStorage)
1360 * Until we actully connect to a running object and retrieve new
1361 * information to it, we never get dirty.
1363 * See Windows documentation for more details on IPersistStorage methods.
1365 static HRESULT WINAPI
DataCache_IsDirty(
1366 IPersistStorage
* iface
)
1368 TRACE("(%p)\n", iface
);
1373 /************************************************************************
1374 * DataCache_InitNew (IPersistStorage)
1376 * The data cache implementation of IPersistStorage_InitNew simply stores
1377 * the storage pointer.
1379 * See Windows documentation for more details on IPersistStorage methods.
1381 static HRESULT WINAPI
DataCache_InitNew(
1382 IPersistStorage
* iface
,
1385 TRACE("(%p, %p)\n", iface
, pStg
);
1387 return DataCache_Load(iface
, pStg
);
1390 /************************************************************************
1391 * DataCache_Load (IPersistStorage)
1393 * The data cache implementation of IPersistStorage_Load doesn't
1394 * actually load anything. Instead, it holds on to the storage pointer
1395 * and it will load the presentation information when the
1396 * IDataObject_GetData or IViewObject2_Draw methods are called.
1398 * See Windows documentation for more details on IPersistStorage methods.
1400 static HRESULT WINAPI
DataCache_Load(
1401 IPersistStorage
* iface
,
1404 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1406 TRACE("(%p, %p)\n", iface
, pStg
);
1408 if (this->presentationStorage
!= NULL
)
1410 IStorage_Release(this->presentationStorage
);
1413 this->presentationStorage
= pStg
;
1415 if (this->presentationStorage
!= NULL
)
1417 IStorage_AddRef(this->presentationStorage
);
1422 /************************************************************************
1423 * DataCache_Save (IPersistStorage)
1425 * Until we actully connect to a running object and retrieve new
1426 * information to it, we never have to save anything. However, it is
1427 * our responsability to copy the information when saving to a new
1430 * See Windows documentation for more details on IPersistStorage methods.
1432 static HRESULT WINAPI
DataCache_Save(
1433 IPersistStorage
* iface
,
1437 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1439 TRACE("(%p, %p, %d)\n", iface
, pStg
, fSameAsLoad
);
1441 if ( (!fSameAsLoad
) &&
1442 (this->presentationStorage
!=NULL
) )
1444 return IStorage_CopyTo(this->presentationStorage
,
1454 /************************************************************************
1455 * DataCache_SaveCompleted (IPersistStorage)
1457 * This method is called to tell the cache to release the storage
1458 * pointer it's currentlu holding.
1460 * See Windows documentation for more details on IPersistStorage methods.
1462 static HRESULT WINAPI
DataCache_SaveCompleted(
1463 IPersistStorage
* iface
,
1466 TRACE("(%p, %p)\n", iface
, pStgNew
);
1471 * First, make sure we get our hands off any storage we have.
1474 DataCache_HandsOffStorage(iface
);
1477 * Then, attach to the new storage.
1480 DataCache_Load(iface
, pStgNew
);
1486 /************************************************************************
1487 * DataCache_HandsOffStorage (IPersistStorage)
1489 * This method is called to tell the cache to release the storage
1490 * pointer it's currentlu holding.
1492 * See Windows documentation for more details on IPersistStorage methods.
1494 static HRESULT WINAPI
DataCache_HandsOffStorage(
1495 IPersistStorage
* iface
)
1497 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1499 TRACE("(%p)\n", iface
);
1501 if (this->presentationStorage
!= NULL
)
1503 IStorage_Release(this->presentationStorage
);
1504 this->presentationStorage
= NULL
;
1510 /*********************************************************
1511 * Method implementation for the IViewObject2
1512 * part of the DataCache class.
1515 /************************************************************************
1516 * DataCache_IViewObject2_QueryInterface (IUnknown)
1518 * See Windows documentation for more details on IUnknown methods.
1520 static HRESULT WINAPI
DataCache_IViewObject2_QueryInterface(
1521 IViewObject2
* iface
,
1525 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1527 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1530 /************************************************************************
1531 * DataCache_IViewObject2_AddRef (IUnknown)
1533 * See Windows documentation for more details on IUnknown methods.
1535 static ULONG WINAPI
DataCache_IViewObject2_AddRef(
1536 IViewObject2
* iface
)
1538 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1540 return IUnknown_AddRef(this->outerUnknown
);
1543 /************************************************************************
1544 * DataCache_IViewObject2_Release (IUnknown)
1546 * See Windows documentation for more details on IUnknown methods.
1548 static ULONG WINAPI
DataCache_IViewObject2_Release(
1549 IViewObject2
* iface
)
1551 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1553 return IUnknown_Release(this->outerUnknown
);
1556 /************************************************************************
1557 * DataCache_Draw (IViewObject2)
1559 * This method will draw the cached representation of the object
1560 * to the given device context.
1562 * See Windows documentation for more details on IViewObject2 methods.
1564 static HRESULT WINAPI
DataCache_Draw(
1565 IViewObject2
* iface
,
1569 DVTARGETDEVICE
* ptd
,
1572 LPCRECTL lprcBounds
,
1573 LPCRECTL lprcWBounds
,
1574 IVO_ContCallback pfnContinue
,
1577 PresentationDataHeader presData
;
1578 HMETAFILE presMetafile
= 0;
1581 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1583 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1598 if (lprcBounds
==NULL
)
1599 return E_INVALIDARG
;
1602 * First, we need to retrieve the dimensions of the
1603 * image in the metafile.
1605 hres
= DataCache_ReadPresentationData(this,
1613 * Then, we can extract the metafile itself from the cached
1616 * FIXME Unless it isn't a metafile. I think it could be any CF_XXX type,
1617 * particularly CF_DIB.
1619 presMetafile
= DataCache_ReadPresMetafile(this,
1623 * If we have a metafile, just draw baby...
1624 * We have to be careful not to modify the state of the
1627 if (presMetafile
!=0)
1629 INT prevMapMode
= SetMapMode(hdcDraw
, MM_ANISOTROPIC
);
1631 SIZE oldViewportExt
;
1632 POINT oldViewportOrg
;
1634 SetWindowExtEx(hdcDraw
,
1635 presData
.dwObjectExtentX
,
1636 presData
.dwObjectExtentY
,
1639 SetViewportExtEx(hdcDraw
,
1640 lprcBounds
->right
- lprcBounds
->left
,
1641 lprcBounds
->bottom
- lprcBounds
->top
,
1644 SetViewportOrgEx(hdcDraw
,
1649 PlayMetaFile(hdcDraw
, presMetafile
);
1651 SetWindowExtEx(hdcDraw
,
1656 SetViewportExtEx(hdcDraw
,
1661 SetViewportOrgEx(hdcDraw
,
1666 SetMapMode(hdcDraw
, prevMapMode
);
1668 DeleteMetaFile(presMetafile
);
1674 static HRESULT WINAPI
DataCache_GetColorSet(
1675 IViewObject2
* iface
,
1679 DVTARGETDEVICE
* ptd
,
1680 HDC hicTargetDevice
,
1681 LOGPALETTE
** ppColorSet
)
1687 static HRESULT WINAPI
DataCache_Freeze(
1688 IViewObject2
* iface
,
1698 static HRESULT WINAPI
DataCache_Unfreeze(
1699 IViewObject2
* iface
,
1706 /************************************************************************
1707 * DataCache_SetAdvise (IViewObject2)
1709 * This sets-up an advisory sink with the data cache. When the object's
1710 * view changes, this sink is called.
1712 * See Windows documentation for more details on IViewObject2 methods.
1714 static HRESULT WINAPI
DataCache_SetAdvise(
1715 IViewObject2
* iface
,
1718 IAdviseSink
* pAdvSink
)
1720 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1722 TRACE("(%p, %lx, %lx, %p)\n", iface
, aspects
, advf
, pAdvSink
);
1725 * A call to this function removes the previous sink
1727 if (this->sinkInterface
!= NULL
)
1729 IAdviseSink_Release(this->sinkInterface
);
1730 this->sinkInterface
= NULL
;
1731 this->sinkAspects
= 0;
1732 this->sinkAdviseFlag
= 0;
1736 * Now, setup the new one.
1740 this->sinkInterface
= pAdvSink
;
1741 this->sinkAspects
= aspects
;
1742 this->sinkAdviseFlag
= advf
;
1744 IAdviseSink_AddRef(this->sinkInterface
);
1748 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1751 if (advf
& ADVF_PRIMEFIRST
)
1753 DataCache_FireOnViewChange(this,
1761 /************************************************************************
1762 * DataCache_GetAdvise (IViewObject2)
1764 * This method queries the current state of the advise sink
1765 * installed on the data cache.
1767 * See Windows documentation for more details on IViewObject2 methods.
1769 static HRESULT WINAPI
DataCache_GetAdvise(
1770 IViewObject2
* iface
,
1773 IAdviseSink
** ppAdvSink
)
1775 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1777 TRACE("(%p, %p, %p, %p)\n", iface
, pAspects
, pAdvf
, ppAdvSink
);
1780 * Just copy all the requested values.
1783 *pAspects
= this->sinkAspects
;
1786 *pAdvf
= this->sinkAdviseFlag
;
1788 if (ppAdvSink
!=NULL
)
1790 IAdviseSink_QueryInterface(this->sinkInterface
,
1798 /************************************************************************
1799 * DataCache_GetExtent (IViewObject2)
1801 * This method retrieves the "natural" size of this cached object.
1803 * See Windows documentation for more details on IViewObject2 methods.
1805 static HRESULT WINAPI
DataCache_GetExtent(
1806 IViewObject2
* iface
,
1809 DVTARGETDEVICE
* ptd
,
1812 PresentationDataHeader presData
;
1813 HRESULT hres
= E_FAIL
;
1815 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1817 TRACE("(%p, %lx, %ld, %p, %p)\n",
1818 iface
, dwDrawAspect
, lindex
, ptd
, lpsizel
);
1827 * Initialize the out parameter.
1833 * This flag should be set to -1.
1836 FIXME("Unimplemented flag lindex = %ld\n", lindex
);
1839 * Right now, we suport only the callback from
1840 * the default handler.
1843 FIXME("Unimplemented ptd = %p\n", ptd
);
1846 * Get the presentation information from the
1849 hres
= DataCache_ReadPresentationData(this,
1853 if (SUCCEEDED(hres
))
1855 lpsizel
->cx
= presData
.dwObjectExtentX
;
1856 lpsizel
->cy
= presData
.dwObjectExtentY
;
1860 * This method returns OLE_E_BLANK when it fails.
1869 /*********************************************************
1870 * Method implementation for the IOleCache2
1871 * part of the DataCache class.
1874 /************************************************************************
1875 * DataCache_IOleCache2_QueryInterface (IUnknown)
1877 * See Windows documentation for more details on IUnknown methods.
1879 static HRESULT WINAPI
DataCache_IOleCache2_QueryInterface(
1884 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1886 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1889 /************************************************************************
1890 * DataCache_IOleCache2_AddRef (IUnknown)
1892 * See Windows documentation for more details on IUnknown methods.
1894 static ULONG WINAPI
DataCache_IOleCache2_AddRef(
1897 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1899 return IUnknown_AddRef(this->outerUnknown
);
1902 /************************************************************************
1903 * DataCache_IOleCache2_Release (IUnknown)
1905 * See Windows documentation for more details on IUnknown methods.
1907 static ULONG WINAPI
DataCache_IOleCache2_Release(
1910 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1912 return IUnknown_Release(this->outerUnknown
);
1915 static HRESULT WINAPI
DataCache_Cache(
1917 FORMATETC
* pformatetc
,
1919 DWORD
* pdwConnection
)
1925 static HRESULT WINAPI
DataCache_Uncache(
1933 static HRESULT WINAPI
DataCache_EnumCache(
1935 IEnumSTATDATA
** ppenumSTATDATA
)
1941 static HRESULT WINAPI
DataCache_InitCache(
1943 IDataObject
* pDataObject
)
1949 static HRESULT WINAPI
DataCache_IOleCache2_SetData(
1951 FORMATETC
* pformatetc
,
1959 static HRESULT WINAPI
DataCache_UpdateCache(
1961 LPDATAOBJECT pDataObject
,
1969 static HRESULT WINAPI
DataCache_DiscardCache(
1971 DWORD dwDiscardOptions
)
1978 /*********************************************************
1979 * Method implementation for the IOleCacheControl
1980 * part of the DataCache class.
1983 /************************************************************************
1984 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1986 * See Windows documentation for more details on IUnknown methods.
1988 static HRESULT WINAPI
DataCache_IOleCacheControl_QueryInterface(
1989 IOleCacheControl
* iface
,
1993 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1995 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1998 /************************************************************************
1999 * DataCache_IOleCacheControl_AddRef (IUnknown)
2001 * See Windows documentation for more details on IUnknown methods.
2003 static ULONG WINAPI
DataCache_IOleCacheControl_AddRef(
2004 IOleCacheControl
* iface
)
2006 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
2008 return IUnknown_AddRef(this->outerUnknown
);
2011 /************************************************************************
2012 * DataCache_IOleCacheControl_Release (IUnknown)
2014 * See Windows documentation for more details on IUnknown methods.
2016 static ULONG WINAPI
DataCache_IOleCacheControl_Release(
2017 IOleCacheControl
* iface
)
2019 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
2021 return IUnknown_Release(this->outerUnknown
);
2024 static HRESULT WINAPI
DataCache_OnRun(
2025 IOleCacheControl
* iface
,
2026 LPDATAOBJECT pDataObject
)
2032 static HRESULT WINAPI
DataCache_OnStop(
2033 IOleCacheControl
* iface
)