4 * Copyright 1999 Francis Beaudet
7 * The OLE2 data cache supports a whole whack of
8 * interfaces including:
9 * IDataObject, IPersistStorage, IViewObject2,
10 * IOleCache2 and IOleCacheControl.
12 * Most of the implementation details are taken from: Inside OLE
13 * second edition by Kraig Brockschmidt,
16 * - This implementation of the datacache will let your application
17 * load documents that have embedded OLE objects in them and it will
18 * also retrieve the metafile representation of those objects.
19 * - This implementation of the datacache will also allow your
20 * application to save new documents with OLE objects in them.
21 * - The main thing that it doesn't do is allow you to activate
22 * or modify the OLE objects in any way.
23 * - I haven't found any good documentation on the real usage of
24 * the streams created by the data cache. In particular, How to
25 * determine what the XXX stands for in the stream name
26 * "\002OlePresXXX". I have an intuition that this is related to
27 * the cached aspect of the object but I'm not sure it could
29 * - Also, I don't know the real content of the presentation stream
30 * header. I was able to figure-out where the extent of the object
31 * was stored but that's about it.
38 #include "wine/obj_oleview.h"
39 #include "wine/obj_cache.h"
40 #include "debugtools.h"
42 DEFAULT_DEBUG_CHANNEL(ole);
44 /****************************************************************************
45 * PresentationDataHeader
47 * This structure represents the header of the \002OlePresXXX stream in
48 * the OLE object strorage.
50 * Most fields are still unknown.
52 typedef struct PresentationDataHeader
65 } PresentationDataHeader;
67 /****************************************************************************
73 * List all interface VTables here
75 ICOM_VTABLE(IDataObject)* lpvtbl1;
76 ICOM_VTABLE(IUnknown)* lpvtbl2;
77 ICOM_VTABLE(IPersistStorage)* lpvtbl3;
78 ICOM_VTABLE(IViewObject2)* lpvtbl4;
79 ICOM_VTABLE(IOleCache2)* lpvtbl5;
80 ICOM_VTABLE(IOleCacheControl)* lpvtbl6;
83 * Reference count of this object
88 * IUnknown implementation of the outer object.
90 IUnknown* outerUnknown;
93 * This storage pointer is set through a call to
94 * IPersistStorage_Load. This is where the visual
95 * representation of the object is stored.
97 IStorage* presentationStorage;
100 * The user of this object can setup ONE advise sink
101 * connection with the object. These parameters describe
105 DWORD sinkAdviseFlag;
106 IAdviseSink* sinkInterface;
110 typedef struct DataCache DataCache;
113 * Here, I define utility macros to help with the casting of the
115 * There is a version to accomodate all of the VTables implemented
118 #define _ICOM_THIS_From_IDataObject(class,name) class* this = (class*)name;
119 #define _ICOM_THIS_From_NDIUnknown(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
120 #define _ICOM_THIS_From_IPersistStorage(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
121 #define _ICOM_THIS_From_IViewObject2(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
122 #define _ICOM_THIS_From_IOleCache2(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*));
123 #define _ICOM_THIS_From_IOleCacheControl(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*));
126 * Prototypes for the methods of the DataCache class.
128 static DataCache* DataCache_Construct(REFCLSID clsid,
129 LPUNKNOWN pUnkOuter);
130 static void DataCache_Destroy(DataCache* ptrToDestroy);
131 static HRESULT DataCache_ReadPresentationData(DataCache* this,
133 PresentationDataHeader* header);
134 static HRESULT DataCache_FindPresStreamName(DataCache* this,
137 static HMETAFILE DataCache_ReadPresMetafile(DataCache* this,
139 static void DataCache_FireOnViewChange(DataCache* this,
144 * Prototypes for the methods of the DataCache class
145 * that implement non delegating IUnknown methods.
147 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
151 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
153 static ULONG WINAPI DataCache_NDIUnknown_Release(
157 * Prototypes for the methods of the DataCache class
158 * that implement IDataObject methods.
160 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
164 static ULONG WINAPI DataCache_IDataObject_AddRef(
166 static ULONG WINAPI DataCache_IDataObject_Release(
168 static HRESULT WINAPI DataCache_GetData(
170 LPFORMATETC pformatetcIn,
172 static HRESULT WINAPI DataCache_GetDataHere(
174 LPFORMATETC pformatetc,
176 static HRESULT WINAPI DataCache_QueryGetData(
178 LPFORMATETC pformatetc);
179 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
181 LPFORMATETC pformatectIn,
182 LPFORMATETC pformatetcOut);
183 static HRESULT WINAPI DataCache_IDataObject_SetData(
185 LPFORMATETC pformatetc,
188 static HRESULT WINAPI DataCache_EnumFormatEtc(
191 IEnumFORMATETC** ppenumFormatEtc);
192 static HRESULT WINAPI DataCache_DAdvise(
194 FORMATETC* pformatetc,
196 IAdviseSink* pAdvSink,
197 DWORD* pdwConnection);
198 static HRESULT WINAPI DataCache_DUnadvise(
201 static HRESULT WINAPI DataCache_EnumDAdvise(
203 IEnumSTATDATA** ppenumAdvise);
206 * Prototypes for the methods of the DataCache class
207 * that implement IPersistStorage methods.
209 static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
210 IPersistStorage* iface,
213 static ULONG WINAPI DataCache_IPersistStorage_AddRef(
214 IPersistStorage* iface);
215 static ULONG WINAPI DataCache_IPersistStorage_Release(
216 IPersistStorage* iface);
217 static HRESULT WINAPI DataCache_GetClassID(
218 IPersistStorage* iface,
220 static HRESULT WINAPI DataCache_IsDirty(
221 IPersistStorage* iface);
222 static HRESULT WINAPI DataCache_InitNew(
223 IPersistStorage* iface,
225 static HRESULT WINAPI DataCache_Load(
226 IPersistStorage* iface,
228 static HRESULT WINAPI DataCache_Save(
229 IPersistStorage* iface,
232 static HRESULT WINAPI DataCache_SaveCompleted(
233 IPersistStorage* iface,
235 static HRESULT WINAPI DataCache_HandsOffStorage(
236 IPersistStorage* iface);
239 * Prototypes for the methods of the DataCache class
240 * that implement IViewObject2 methods.
242 static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
246 static ULONG WINAPI DataCache_IViewObject2_AddRef(
247 IViewObject2* iface);
248 static ULONG WINAPI DataCache_IViewObject2_Release(
249 IViewObject2* iface);
250 static HRESULT WINAPI DataCache_Draw(
259 LPCRECTL lprcWBounds,
260 IVO_ContCallback pfnContinue,
262 static HRESULT WINAPI DataCache_GetColorSet(
269 LOGPALETTE** ppColorSet);
270 static HRESULT WINAPI DataCache_Freeze(
276 static HRESULT WINAPI DataCache_Unfreeze(
279 static HRESULT WINAPI DataCache_SetAdvise(
283 IAdviseSink* pAdvSink);
284 static HRESULT WINAPI DataCache_GetAdvise(
288 IAdviseSink** ppAdvSink);
289 static HRESULT WINAPI DataCache_GetExtent(
297 * Prototypes for the methods of the DataCache class
298 * that implement IOleCache2 methods.
300 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
304 static ULONG WINAPI DataCache_IOleCache2_AddRef(
306 static ULONG WINAPI DataCache_IOleCache2_Release(
308 static HRESULT WINAPI DataCache_Cache(
310 FORMATETC* pformatetc,
312 DWORD* pdwConnection);
313 static HRESULT WINAPI DataCache_Uncache(
316 static HRESULT WINAPI DataCache_EnumCache(
318 IEnumSTATDATA** ppenumSTATDATA);
319 static HRESULT WINAPI DataCache_InitCache(
321 IDataObject* pDataObject);
322 static HRESULT WINAPI DataCache_IOleCache2_SetData(
324 FORMATETC* pformatetc,
327 static HRESULT WINAPI DataCache_UpdateCache(
329 LPDATAOBJECT pDataObject,
332 static HRESULT WINAPI DataCache_DiscardCache(
334 DWORD dwDiscardOptions);
337 * Prototypes for the methods of the DataCache class
338 * that implement IOleCacheControl methods.
340 static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
341 IOleCacheControl* iface,
344 static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
345 IOleCacheControl* iface);
346 static ULONG WINAPI DataCache_IOleCacheControl_Release(
347 IOleCacheControl* iface);
348 static HRESULT WINAPI DataCache_OnRun(
349 IOleCacheControl* iface,
350 LPDATAOBJECT pDataObject);
351 static HRESULT WINAPI DataCache_OnStop(
352 IOleCacheControl* iface);
355 * Virtual function tables for the DataCache class.
357 static ICOM_VTABLE(IUnknown) DataCache_NDIUnknown_VTable =
359 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
360 DataCache_NDIUnknown_QueryInterface,
361 DataCache_NDIUnknown_AddRef,
362 DataCache_NDIUnknown_Release
365 static ICOM_VTABLE(IDataObject) DataCache_IDataObject_VTable =
367 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
368 DataCache_IDataObject_QueryInterface,
369 DataCache_IDataObject_AddRef,
370 DataCache_IDataObject_Release,
372 DataCache_GetDataHere,
373 DataCache_QueryGetData,
374 DataCache_GetCanonicalFormatEtc,
375 DataCache_IDataObject_SetData,
376 DataCache_EnumFormatEtc,
379 DataCache_EnumDAdvise
382 static ICOM_VTABLE(IPersistStorage) DataCache_IPersistStorage_VTable =
384 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
385 DataCache_IPersistStorage_QueryInterface,
386 DataCache_IPersistStorage_AddRef,
387 DataCache_IPersistStorage_Release,
388 DataCache_GetClassID,
393 DataCache_SaveCompleted,
394 DataCache_HandsOffStorage
397 static ICOM_VTABLE(IViewObject2) DataCache_IViewObject2_VTable =
399 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
400 DataCache_IViewObject2_QueryInterface,
401 DataCache_IViewObject2_AddRef,
402 DataCache_IViewObject2_Release,
404 DataCache_GetColorSet,
412 static ICOM_VTABLE(IOleCache2) DataCache_IOleCache2_VTable =
414 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
415 DataCache_IOleCache2_QueryInterface,
416 DataCache_IOleCache2_AddRef,
417 DataCache_IOleCache2_Release,
422 DataCache_IOleCache2_SetData,
423 DataCache_UpdateCache,
424 DataCache_DiscardCache
427 static ICOM_VTABLE(IOleCacheControl) DataCache_IOleCacheControl_VTable =
429 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
430 DataCache_IOleCacheControl_QueryInterface,
431 DataCache_IOleCacheControl_AddRef,
432 DataCache_IOleCacheControl_Release,
437 /******************************************************************************
438 * CreateDataCache [OLE32.54]
440 HRESULT WINAPI CreateDataCache(
446 DataCache* newCache = NULL;
449 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(rclsid), pUnkOuter, debugstr_guid(riid), ppvObj);
460 * If this cache is constructed for aggregation, make sure
461 * the caller is requesting the IUnknown interface.
462 * This is necessary because it's the only time the non-delegating
463 * IUnknown pointer can be returned to the outside.
465 if ( (pUnkOuter!=NULL) &&
466 (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) != 0) )
467 return CLASS_E_NOAGGREGATION;
470 * Try to construct a new instance of the class.
472 newCache = DataCache_Construct(rclsid,
476 return E_OUTOFMEMORY;
479 * Make sure it supports the interface required by the caller.
481 hr = IUnknown_QueryInterface((IUnknown*)&(newCache->lpvtbl2), riid, ppvObj);
484 * Release the reference obtained in the constructor. If
485 * the QueryInterface was unsuccessful, it will free the class.
487 IUnknown_Release((IUnknown*)&(newCache->lpvtbl2));
492 /*********************************************************
493 * Method implementation for DataCache class.
495 static DataCache* DataCache_Construct(
499 DataCache* newObject = 0;
502 * Allocate space for the object.
504 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache));
510 * Initialize the virtual function table.
512 newObject->lpvtbl1 = &DataCache_IDataObject_VTable;
513 newObject->lpvtbl2 = &DataCache_NDIUnknown_VTable;
514 newObject->lpvtbl3 = &DataCache_IPersistStorage_VTable;
515 newObject->lpvtbl4 = &DataCache_IViewObject2_VTable;
516 newObject->lpvtbl5 = &DataCache_IOleCache2_VTable;
517 newObject->lpvtbl6 = &DataCache_IOleCacheControl_VTable;
520 * Start with one reference count. The caller of this function
521 * must release the interface pointer when it is done.
526 * Initialize the outer unknown
527 * We don't keep a reference on the outer unknown since, the way
528 * aggregation works, our lifetime is at least as large as it's
532 pUnkOuter = (IUnknown*)&(newObject->lpvtbl2);
534 newObject->outerUnknown = pUnkOuter;
537 * Initialize the other members of the structure.
539 newObject->presentationStorage = NULL;
540 newObject->sinkAspects = 0;
541 newObject->sinkAdviseFlag = 0;
542 newObject->sinkInterface = 0;
547 static void DataCache_Destroy(
548 DataCache* ptrToDestroy)
552 if (ptrToDestroy->sinkInterface != NULL)
554 IAdviseSink_Release(ptrToDestroy->sinkInterface);
555 ptrToDestroy->sinkInterface = NULL;
558 if (ptrToDestroy->presentationStorage != NULL)
560 IStorage_Release(ptrToDestroy->presentationStorage);
561 ptrToDestroy->presentationStorage = NULL;
565 * Free the datacache pointer.
567 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
570 /************************************************************************
571 * DataCache_ReadPresentationData
573 * This method will read information for the requested presentation
574 * into the given structure.
577 * this - Pointer to the DataCache object
578 * drawAspect - The aspect of the object that we wish to draw.
579 * header - The structure containing information about this
580 * aspect of the object.
582 static HRESULT DataCache_ReadPresentationData(
585 PresentationDataHeader* header)
587 IStream* presStream = NULL;
588 OLECHAR streamName[20];
592 * Get the name for the presentation stream.
594 hres = DataCache_FindPresStreamName(
603 * Open the stream and read the header.
605 hres = IStorage_OpenStream(
606 this->presentationStorage,
609 STGM_READ | STGM_SHARE_EXCLUSIVE,
619 sizeof(PresentationDataHeader),
625 IStream_Release(presStream);
628 * We don't want to propagate any other error
629 * code than a failure.
637 /************************************************************************
638 * DataCache_FireOnViewChange
640 * This method will fire an OnViewChange notification to the advise
641 * sink registered with the datacache.
643 * See IAdviseSink::OnViewChange for more details.
645 static void DataCache_FireOnViewChange(
650 TRACE("(%p, %lx, %ld)\n", this, aspect, lindex);
653 * The sink supplies a filter when it registers
654 * we make sure we only send the notifications when that
657 if ((this->sinkAspects & aspect) != 0)
659 if (this->sinkInterface != NULL)
661 IAdviseSink_OnViewChange(this->sinkInterface,
666 * Some sinks want to be unregistered automatically when
667 * the first notification goes out.
669 if ( (this->sinkAdviseFlag & ADVF_ONLYONCE) != 0)
671 IAdviseSink_Release(this->sinkInterface);
673 this->sinkInterface = NULL;
674 this->sinkAspects = 0;
675 this->sinkAdviseFlag = 0;
681 /************************************************************************
682 * DataCache_ReadPresentationData
684 * This method will read information for the requested presentation
685 * into the given structure.
688 * this - Pointer to the DataCache object
689 * drawAspect - The aspect of the object that we wish to draw.
690 * header - The structure containing information about this
691 * aspect of the object.
694 * This method only supports the DVASPECT_CONTENT aspect.
696 static HRESULT DataCache_FindPresStreamName(
701 OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
703 if (drawAspect!=DVASPECT_CONTENT)
706 memcpy(buffer, name, sizeof(name));
711 /************************************************************************
712 * DataCache_ReadPresentationData
714 * This method will read information for the requested presentation
715 * into the given structure.
718 * this - Pointer to the DataCache object
719 * drawAspect - The aspect of the object that we wish to draw.
722 * This method returns a metafile handle if it is successful.
723 * it will return 0 if not.
725 static HMETAFILE DataCache_ReadPresMetafile(
729 LARGE_INTEGER offset;
730 IStream* presStream = NULL;
731 OLECHAR streamName[20];
735 HMETAFILE newMetafile = 0;
738 * Get the name for the presentation stream.
740 hres = DataCache_FindPresStreamName(
749 * Open the stream and read the header.
751 hres = IStorage_OpenStream(
752 this->presentationStorage,
755 STGM_READ | STGM_SHARE_EXCLUSIVE,
763 * Get the size of the stream.
765 hres = IStream_Stat(presStream,
772 offset.s.HighPart = 0;
773 offset.s.LowPart = sizeof(PresentationDataHeader);
782 * Allocate a buffer for the metafile bits.
784 metafileBits = HeapAlloc(GetProcessHeap(),
786 streamInfo.cbSize.s.LowPart);
789 * Read the metafile bits.
794 streamInfo.cbSize.s.LowPart,
798 * Create a metafile with those bits.
802 newMetafile = SetMetaFileBitsEx(streamInfo.cbSize.s.LowPart, metafileBits);
808 HeapFree(GetProcessHeap(), 0, metafileBits);
809 IStream_Release(presStream);
817 /*********************************************************
818 * Method implementation for the non delegating IUnknown
819 * part of the DataCache class.
822 /************************************************************************
823 * DataCache_NDIUnknown_QueryInterface (IUnknown)
825 * See Windows documentation for more details on IUnknown methods.
827 * This version of QueryInterface will not delegate it's implementation
828 * to the outer unknown.
830 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
835 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
838 * Perform a sanity check on the parameters.
840 if ( (this==0) || (ppvObject==0) )
844 * Initialize the return parameter.
849 * Compare the riid with the interface IDs implemented by this object.
851 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
855 else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0)
857 *ppvObject = (IDataObject*)&(this->lpvtbl1);
859 else if ( (memcmp(&IID_IPersistStorage, riid, sizeof(IID_IPersistStorage)) == 0) ||
860 (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0) )
862 *ppvObject = (IPersistStorage*)&(this->lpvtbl3);
864 else if ( (memcmp(&IID_IViewObject, riid, sizeof(IID_IViewObject)) == 0) ||
865 (memcmp(&IID_IViewObject2, riid, sizeof(IID_IViewObject2)) == 0) )
867 *ppvObject = (IViewObject2*)&(this->lpvtbl4);
869 else if ( (memcmp(&IID_IOleCache, riid, sizeof(IID_IOleCache)) == 0) ||
870 (memcmp(&IID_IOleCache2, riid, sizeof(IID_IOleCache2)) == 0) )
872 *ppvObject = (IOleCache2*)&(this->lpvtbl5);
874 else if (memcmp(&IID_IOleCacheControl, riid, sizeof(IID_IOleCacheControl)) == 0)
876 *ppvObject = (IOleCacheControl*)&(this->lpvtbl6);
880 * Check that we obtained an interface.
884 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
885 return E_NOINTERFACE;
889 * Query Interface always increases the reference count by one when it is
892 IUnknown_AddRef((IUnknown*)*ppvObject);
897 /************************************************************************
898 * DataCache_NDIUnknown_AddRef (IUnknown)
900 * See Windows documentation for more details on IUnknown methods.
902 * This version of QueryInterface will not delegate it's implementation
903 * to the outer unknown.
905 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
908 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
915 /************************************************************************
916 * DataCache_NDIUnknown_Release (IUnknown)
918 * See Windows documentation for more details on IUnknown methods.
920 * This version of QueryInterface will not delegate it's implementation
921 * to the outer unknown.
923 static ULONG WINAPI DataCache_NDIUnknown_Release(
926 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
929 * Decrease the reference count on this object.
934 * If the reference count goes down to 0, perform suicide.
938 DataCache_Destroy(this);
946 /*********************************************************
947 * Method implementation for the IDataObject
948 * part of the DataCache class.
951 /************************************************************************
952 * DataCache_IDataObject_QueryInterface (IUnknown)
954 * See Windows documentation for more details on IUnknown methods.
956 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
961 _ICOM_THIS_From_IDataObject(DataCache, iface);
963 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
966 /************************************************************************
967 * DataCache_IDataObject_AddRef (IUnknown)
969 * See Windows documentation for more details on IUnknown methods.
971 static ULONG WINAPI DataCache_IDataObject_AddRef(
974 _ICOM_THIS_From_IDataObject(DataCache, iface);
976 return IUnknown_AddRef(this->outerUnknown);
979 /************************************************************************
980 * DataCache_IDataObject_Release (IUnknown)
982 * See Windows documentation for more details on IUnknown methods.
984 static ULONG WINAPI DataCache_IDataObject_Release(
987 _ICOM_THIS_From_IDataObject(DataCache, iface);
989 return IUnknown_Release(this->outerUnknown);
992 static HRESULT WINAPI DataCache_GetData(
994 LPFORMATETC pformatetcIn,
1001 static HRESULT WINAPI DataCache_GetDataHere(
1003 LPFORMATETC pformatetc,
1010 static HRESULT WINAPI DataCache_QueryGetData(
1012 LPFORMATETC pformatetc)
1018 /************************************************************************
1019 * DataCache_EnumFormatEtc (IDataObject)
1021 * The data cache doesn't implement this method.
1023 * See Windows documentation for more details on IDataObject methods.
1025 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
1027 LPFORMATETC pformatectIn,
1028 LPFORMATETC pformatetcOut)
1034 /************************************************************************
1035 * DataCache_IDataObject_SetData (IDataObject)
1037 * This method is delegated to the IOleCache2 implementation.
1039 * See Windows documentation for more details on IDataObject methods.
1041 static HRESULT WINAPI DataCache_IDataObject_SetData(
1043 LPFORMATETC pformatetc,
1047 IOleCache2* oleCache = NULL;
1050 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1052 hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);
1055 return E_UNEXPECTED;
1057 hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);
1059 IOleCache2_Release(oleCache);
1064 /************************************************************************
1065 * DataCache_EnumFormatEtc (IDataObject)
1067 * The data cache doesn't implement this method.
1069 * See Windows documentation for more details on IDataObject methods.
1071 static HRESULT WINAPI DataCache_EnumFormatEtc(
1074 IEnumFORMATETC** ppenumFormatEtc)
1080 /************************************************************************
1081 * DataCache_DAdvise (IDataObject)
1083 * The data cache doesn't support connections.
1085 * See Windows documentation for more details on IDataObject methods.
1087 static HRESULT WINAPI DataCache_DAdvise(
1089 FORMATETC* pformatetc,
1091 IAdviseSink* pAdvSink,
1092 DWORD* pdwConnection)
1095 return OLE_E_ADVISENOTSUPPORTED;
1098 /************************************************************************
1099 * DataCache_DUnadvise (IDataObject)
1101 * The data cache doesn't support connections.
1103 * See Windows documentation for more details on IDataObject methods.
1105 static HRESULT WINAPI DataCache_DUnadvise(
1110 return OLE_E_NOCONNECTION;
1113 /************************************************************************
1114 * DataCache_EnumDAdvise (IDataObject)
1116 * The data cache doesn't support connections.
1118 * See Windows documentation for more details on IDataObject methods.
1120 static HRESULT WINAPI DataCache_EnumDAdvise(
1122 IEnumSTATDATA** ppenumAdvise)
1125 return OLE_E_ADVISENOTSUPPORTED;
1128 /*********************************************************
1129 * Method implementation for the IDataObject
1130 * part of the DataCache class.
1133 /************************************************************************
1134 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1136 * See Windows documentation for more details on IUnknown methods.
1138 static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
1139 IPersistStorage* iface,
1143 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1145 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1148 /************************************************************************
1149 * DataCache_IPersistStorage_AddRef (IUnknown)
1151 * See Windows documentation for more details on IUnknown methods.
1153 static ULONG WINAPI DataCache_IPersistStorage_AddRef(
1154 IPersistStorage* iface)
1156 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1158 return IUnknown_AddRef(this->outerUnknown);
1161 /************************************************************************
1162 * DataCache_IPersistStorage_Release (IUnknown)
1164 * See Windows documentation for more details on IUnknown methods.
1166 static ULONG WINAPI DataCache_IPersistStorage_Release(
1167 IPersistStorage* iface)
1169 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1171 return IUnknown_Release(this->outerUnknown);
1174 /************************************************************************
1175 * DataCache_GetClassID (IPersistStorage)
1177 * The data cache doesn't implement this method.
1179 * See Windows documentation for more details on IPersistStorage methods.
1181 static HRESULT WINAPI DataCache_GetClassID(
1182 IPersistStorage* iface,
1185 TRACE("(%p, %p)\n", iface, pClassID);
1189 /************************************************************************
1190 * DataCache_IsDirty (IPersistStorage)
1192 * Until we actully connect to a running object and retrieve new
1193 * information to it, we never get dirty.
1195 * See Windows documentation for more details on IPersistStorage methods.
1197 static HRESULT WINAPI DataCache_IsDirty(
1198 IPersistStorage* iface)
1200 TRACE("(%p)\n", iface);
1205 /************************************************************************
1206 * DataCache_InitNew (IPersistStorage)
1208 * The data cache implementation of IPersistStorage_InitNew simply stores
1209 * the storage pointer.
1211 * See Windows documentation for more details on IPersistStorage methods.
1213 static HRESULT WINAPI DataCache_InitNew(
1214 IPersistStorage* iface,
1217 TRACE("(%p, %p)\n", iface, pStg);
1219 return DataCache_Load(iface, pStg);
1222 /************************************************************************
1223 * DataCache_Load (IPersistStorage)
1225 * The data cache implementation of IPersistStorage_Load doesn't
1226 * actually load anything. Instead, it holds on to the storage pointer
1227 * and it will load the presentation information when the
1228 * IDataObject_GetData or IViewObject2_Draw methods are called.
1230 * See Windows documentation for more details on IPersistStorage methods.
1232 static HRESULT WINAPI DataCache_Load(
1233 IPersistStorage* iface,
1236 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1238 TRACE("(%p, %p)\n", iface, pStg);
1240 if (this->presentationStorage != NULL)
1242 IStorage_Release(this->presentationStorage);
1245 this->presentationStorage = pStg;
1247 if (this->presentationStorage != NULL)
1249 IStorage_AddRef(this->presentationStorage);
1255 /************************************************************************
1256 * DataCache_Save (IPersistStorage)
1258 * Until we actully connect to a running object and retrieve new
1259 * information to it, we never have to save anything. However, it is
1260 * our responsability to copy the information when saving to a new
1263 * See Windows documentation for more details on IPersistStorage methods.
1265 static HRESULT WINAPI DataCache_Save(
1266 IPersistStorage* iface,
1270 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1272 TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad);
1274 if ( (!fSameAsLoad) &&
1275 (this->presentationStorage!=NULL) )
1277 return IStorage_CopyTo(this->presentationStorage,
1287 /************************************************************************
1288 * DataCache_SaveCompleted (IPersistStorage)
1290 * This method is called to tell the cache to release the storage
1291 * pointer it's currentlu holding.
1293 * See Windows documentation for more details on IPersistStorage methods.
1295 static HRESULT WINAPI DataCache_SaveCompleted(
1296 IPersistStorage* iface,
1299 TRACE("(%p, %p)\n", iface, pStgNew);
1302 * First, make sure we get our hands off any storage we have.
1304 DataCache_HandsOffStorage(iface);
1307 * Then, attach to the new storage.
1309 DataCache_Load(iface, pStgNew);
1314 /************************************************************************
1315 * DataCache_HandsOffStorage (IPersistStorage)
1317 * This method is called to tell the cache to release the storage
1318 * pointer it's currentlu holding.
1320 * See Windows documentation for more details on IPersistStorage methods.
1322 static HRESULT WINAPI DataCache_HandsOffStorage(
1323 IPersistStorage* iface)
1325 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1327 TRACE("(%p)\n", iface);
1329 if (this->presentationStorage != NULL)
1331 IStorage_Release(this->presentationStorage);
1332 this->presentationStorage = NULL;
1338 /*********************************************************
1339 * Method implementation for the IViewObject2
1340 * part of the DataCache class.
1343 /************************************************************************
1344 * DataCache_IViewObject2_QueryInterface (IUnknown)
1346 * See Windows documentation for more details on IUnknown methods.
1348 static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
1349 IViewObject2* iface,
1353 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1355 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1358 /************************************************************************
1359 * DataCache_IViewObject2_AddRef (IUnknown)
1361 * See Windows documentation for more details on IUnknown methods.
1363 static ULONG WINAPI DataCache_IViewObject2_AddRef(
1364 IViewObject2* iface)
1366 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1368 return IUnknown_AddRef(this->outerUnknown);
1371 /************************************************************************
1372 * DataCache_IViewObject2_Release (IUnknown)
1374 * See Windows documentation for more details on IUnknown methods.
1376 static ULONG WINAPI DataCache_IViewObject2_Release(
1377 IViewObject2* iface)
1379 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1381 return IUnknown_Release(this->outerUnknown);
1384 /************************************************************************
1385 * DataCache_Draw (IViewObject2)
1387 * This method will draw the cached representation of the object
1388 * to the given device context.
1390 * See Windows documentation for more details on IViewObject2 methods.
1392 static HRESULT WINAPI DataCache_Draw(
1393 IViewObject2* iface,
1397 DVTARGETDEVICE* ptd,
1400 LPCRECTL lprcBounds,
1401 LPCRECTL lprcWBounds,
1402 IVO_ContCallback pfnContinue,
1405 PresentationDataHeader presData;
1406 HMETAFILE presMetafile = 0;
1409 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1411 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1426 if (lprcBounds==NULL)
1427 return E_INVALIDARG;
1430 * First, we need to retrieve the dimensions of the
1431 * image in the metafile.
1433 hres = DataCache_ReadPresentationData(this,
1441 * Then, we can extract the metafile itself from the cached
1444 presMetafile = DataCache_ReadPresMetafile(this,
1448 * If we have a metafile, just draw baby...
1449 * We have to be careful not to modify the state of the
1452 if (presMetafile!=0)
1454 INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC);
1456 SIZE oldViewportExt;
1457 POINT oldViewportOrg;
1459 SetWindowExtEx(hdcDraw,
1460 presData.objectExtentX,
1461 presData.objectExtentY,
1464 SetViewportExtEx(hdcDraw,
1465 lprcBounds->right - lprcBounds->left,
1466 lprcBounds->bottom - lprcBounds->top,
1469 SetViewportOrgEx(hdcDraw,
1474 PlayMetaFile(hdcDraw, presMetafile);
1476 SetWindowExtEx(hdcDraw,
1481 SetViewportExtEx(hdcDraw,
1486 SetViewportOrgEx(hdcDraw,
1491 SetMapMode(hdcDraw, prevMapMode);
1493 DeleteMetaFile(presMetafile);
1499 static HRESULT WINAPI DataCache_GetColorSet(
1500 IViewObject2* iface,
1504 DVTARGETDEVICE* ptd,
1505 HDC hicTargetDevice,
1506 LOGPALETTE** ppColorSet)
1512 static HRESULT WINAPI DataCache_Freeze(
1513 IViewObject2* iface,
1523 static HRESULT WINAPI DataCache_Unfreeze(
1524 IViewObject2* iface,
1531 /************************************************************************
1532 * DataCache_SetAdvise (IViewObject2)
1534 * This sets-up an advisory sink with the data cache. When the object's
1535 * view changes, this sink is called.
1537 * See Windows documentation for more details on IViewObject2 methods.
1539 static HRESULT WINAPI DataCache_SetAdvise(
1540 IViewObject2* iface,
1543 IAdviseSink* pAdvSink)
1545 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1547 TRACE("(%p, %lx, %lx, %p)\n", iface, aspects, advf, pAdvSink);
1550 * A call to this function removes the previous sink
1552 if (this->sinkInterface != NULL)
1554 IAdviseSink_Release(this->sinkInterface);
1555 this->sinkInterface = NULL;
1556 this->sinkAspects = 0;
1557 this->sinkAdviseFlag = 0;
1561 * Now, setup the new one.
1565 this->sinkInterface = pAdvSink;
1566 this->sinkAspects = aspects;
1567 this->sinkAdviseFlag = advf;
1569 IAdviseSink_AddRef(this->sinkInterface);
1573 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1576 if (advf & ADVF_PRIMEFIRST)
1578 DataCache_FireOnViewChange(this,
1586 /************************************************************************
1587 * DataCache_GetAdvise (IViewObject2)
1589 * This method queries the current state of the advise sink
1590 * installed on the data cache.
1592 * See Windows documentation for more details on IViewObject2 methods.
1594 static HRESULT WINAPI DataCache_GetAdvise(
1595 IViewObject2* iface,
1598 IAdviseSink** ppAdvSink)
1600 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1602 TRACE("(%p, %p, %p, %p)\n", iface, pAspects, pAdvf, ppAdvSink);
1605 * Just copy all the requested values.
1608 *pAspects = this->sinkAspects;
1611 *pAdvf = this->sinkAdviseFlag;
1613 if (ppAdvSink!=NULL)
1615 IAdviseSink_QueryInterface(this->sinkInterface,
1623 /************************************************************************
1624 * DataCache_GetExtent (IViewObject2)
1626 * This method retrieves the "natural" size of this cached object.
1628 * See Windows documentation for more details on IViewObject2 methods.
1630 static HRESULT WINAPI DataCache_GetExtent(
1631 IViewObject2* iface,
1634 DVTARGETDEVICE* ptd,
1637 PresentationDataHeader presData;
1638 HRESULT hres = E_FAIL;
1640 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1642 TRACE("(%p, %lx, %ld, %p, %p)\n",
1643 iface, dwDrawAspect, lindex, ptd, lpsizel);
1652 * Initialize the out parameter.
1658 * This flag should be set to -1.
1661 FIXME("Unimplemented flag lindex = %ld\n", lindex);
1664 * Right now, we suport only the callback from
1665 * the default handler.
1668 FIXME("Unimplemented ptd = %p\n", ptd);
1671 * Get the presentation information from the
1674 hres = DataCache_ReadPresentationData(this,
1678 if (SUCCEEDED(hres))
1680 lpsizel->cx = presData.objectExtentX;
1681 lpsizel->cy = presData.objectExtentY;
1685 * This method returns OLE_E_BLANK when it fails.
1694 /*********************************************************
1695 * Method implementation for the IOleCache2
1696 * part of the DataCache class.
1699 /************************************************************************
1700 * DataCache_IOleCache2_QueryInterface (IUnknown)
1702 * See Windows documentation for more details on IUnknown methods.
1704 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
1709 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1711 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1714 /************************************************************************
1715 * DataCache_IOleCache2_AddRef (IUnknown)
1717 * See Windows documentation for more details on IUnknown methods.
1719 static ULONG WINAPI DataCache_IOleCache2_AddRef(
1722 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1724 return IUnknown_AddRef(this->outerUnknown);
1727 /************************************************************************
1728 * DataCache_IOleCache2_Release (IUnknown)
1730 * See Windows documentation for more details on IUnknown methods.
1732 static ULONG WINAPI DataCache_IOleCache2_Release(
1735 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1737 return IUnknown_Release(this->outerUnknown);
1740 static HRESULT WINAPI DataCache_Cache(
1742 FORMATETC* pformatetc,
1744 DWORD* pdwConnection)
1750 static HRESULT WINAPI DataCache_Uncache(
1758 static HRESULT WINAPI DataCache_EnumCache(
1760 IEnumSTATDATA** ppenumSTATDATA)
1766 static HRESULT WINAPI DataCache_InitCache(
1768 IDataObject* pDataObject)
1774 static HRESULT WINAPI DataCache_IOleCache2_SetData(
1776 FORMATETC* pformatetc,
1784 static HRESULT WINAPI DataCache_UpdateCache(
1786 LPDATAOBJECT pDataObject,
1794 static HRESULT WINAPI DataCache_DiscardCache(
1796 DWORD dwDiscardOptions)
1803 /*********************************************************
1804 * Method implementation for the IOleCacheControl
1805 * part of the DataCache class.
1808 /************************************************************************
1809 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1811 * See Windows documentation for more details on IUnknown methods.
1813 static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
1814 IOleCacheControl* iface,
1818 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1820 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1823 /************************************************************************
1824 * DataCache_IOleCacheControl_AddRef (IUnknown)
1826 * See Windows documentation for more details on IUnknown methods.
1828 static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
1829 IOleCacheControl* iface)
1831 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1833 return IUnknown_AddRef(this->outerUnknown);
1836 /************************************************************************
1837 * DataCache_IOleCacheControl_Release (IUnknown)
1839 * See Windows documentation for more details on IUnknown methods.
1841 static ULONG WINAPI DataCache_IOleCacheControl_Release(
1842 IOleCacheControl* iface)
1844 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1846 return IUnknown_Release(this->outerUnknown);
1849 static HRESULT WINAPI DataCache_OnRun(
1850 IOleCacheControl* iface,
1851 LPDATAOBJECT pDataObject)
1857 static HRESULT WINAPI DataCache_OnStop(
1858 IOleCacheControl* iface)