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.
37 #include "wine/obj_oleview.h"
38 #include "wine/obj_cache.h"
39 #include "debugtools.h"
41 DEFAULT_DEBUG_CHANNEL(ole)
43 /****************************************************************************
44 * PresentationDataHeader
46 * This structure represents the header of the \002OlePresXXX stream in
47 * the OLE object strorage.
49 * Most fields are still unknown.
51 typedef struct PresentationDataHeader
64 } PresentationDataHeader;
66 /****************************************************************************
72 * List all interface VTables here
74 ICOM_VTABLE(IDataObject)* lpvtbl1;
75 ICOM_VTABLE(IUnknown)* lpvtbl2;
76 ICOM_VTABLE(IPersistStorage)* lpvtbl3;
77 ICOM_VTABLE(IViewObject2)* lpvtbl4;
78 ICOM_VTABLE(IOleCache2)* lpvtbl5;
79 ICOM_VTABLE(IOleCacheControl)* lpvtbl6;
82 * Reference count of this object
87 * IUnknown implementation of the outer object.
89 IUnknown* outerUnknown;
92 * This storage pointer is set through a call to
93 * IPersistStorage_Load. This is where the visual
94 * representation of the object is stored.
96 IStorage* presentationStorage;
99 * The user of this object can setup ONE advise sink
100 * connection with the object. These parameters describe
104 DWORD sinkAdviseFlag;
105 IAdviseSink* sinkInterface;
109 typedef struct DataCache DataCache;
112 * Here, I define utility macros to help with the casting of the
114 * There is a version to accomodate all of the VTables implemented
117 #define _ICOM_THIS_From_IDataObject(class,name) class* this = (class*)name;
118 #define _ICOM_THIS_From_NDIUnknown(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
119 #define _ICOM_THIS_From_IPersistStorage(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
120 #define _ICOM_THIS_From_IViewObject2(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
121 #define _ICOM_THIS_From_IOleCache2(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*));
122 #define _ICOM_THIS_From_IOleCacheControl(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*));
125 * Prototypes for the methods of the DataCache class.
127 static DataCache* DataCache_Construct(REFCLSID clsid,
128 LPUNKNOWN pUnkOuter);
129 static void DataCache_Destroy(DataCache* ptrToDestroy);
130 static HRESULT DataCache_ReadPresentationData(DataCache* this,
132 PresentationDataHeader* header);
133 static HRESULT DataCache_FindPresStreamName(DataCache* this,
136 static HMETAFILE DataCache_ReadPresMetafile(DataCache* this,
138 static void DataCache_FireOnViewChange(DataCache* this,
143 * Prototypes for the methods of the DataCache class
144 * that implement non delegating IUnknown methods.
146 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
150 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
152 static ULONG WINAPI DataCache_NDIUnknown_Release(
156 * Prototypes for the methods of the DataCache class
157 * that implement IDataObject methods.
159 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
163 static ULONG WINAPI DataCache_IDataObject_AddRef(
165 static ULONG WINAPI DataCache_IDataObject_Release(
167 static HRESULT WINAPI DataCache_GetData(
169 LPFORMATETC pformatetcIn,
171 static HRESULT WINAPI DataCache_GetDataHere(
173 LPFORMATETC pformatetc,
175 static HRESULT WINAPI DataCache_QueryGetData(
177 LPFORMATETC pformatetc);
178 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
180 LPFORMATETC pformatectIn,
181 LPFORMATETC pformatetcOut);
182 static HRESULT WINAPI DataCache_IDataObject_SetData(
184 LPFORMATETC pformatetc,
187 static HRESULT WINAPI DataCache_EnumFormatEtc(
190 IEnumFORMATETC** ppenumFormatEtc);
191 static HRESULT WINAPI DataCache_DAdvise(
193 FORMATETC* pformatetc,
195 IAdviseSink* pAdvSink,
196 DWORD* pdwConnection);
197 static HRESULT WINAPI DataCache_DUnadvise(
200 static HRESULT WINAPI DataCache_EnumDAdvise(
202 IEnumSTATDATA** ppenumAdvise);
205 * Prototypes for the methods of the DataCache class
206 * that implement IPersistStorage methods.
208 static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
209 IPersistStorage* iface,
212 static ULONG WINAPI DataCache_IPersistStorage_AddRef(
213 IPersistStorage* iface);
214 static ULONG WINAPI DataCache_IPersistStorage_Release(
215 IPersistStorage* iface);
216 static HRESULT WINAPI DataCache_GetClassID(
217 IPersistStorage* iface,
219 static HRESULT WINAPI DataCache_IsDirty(
220 IPersistStorage* iface);
221 static HRESULT WINAPI DataCache_InitNew(
222 IPersistStorage* iface,
224 static HRESULT WINAPI DataCache_Load(
225 IPersistStorage* iface,
227 static HRESULT WINAPI DataCache_Save(
228 IPersistStorage* iface,
231 static HRESULT WINAPI DataCache_SaveCompleted(
232 IPersistStorage* iface,
234 static HRESULT WINAPI DataCache_HandsOffStorage(
235 IPersistStorage* iface);
238 * Prototypes for the methods of the DataCache class
239 * that implement IViewObject2 methods.
241 static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
245 static ULONG WINAPI DataCache_IViewObject2_AddRef(
246 IViewObject2* iface);
247 static ULONG WINAPI DataCache_IViewObject2_Release(
248 IViewObject2* iface);
249 static HRESULT WINAPI DataCache_Draw(
258 LPCRECTL lprcWBounds,
259 IVO_ContCallback pfnContinue,
261 static HRESULT WINAPI DataCache_GetColorSet(
268 LOGPALETTE** ppColorSet);
269 static HRESULT WINAPI DataCache_Freeze(
275 static HRESULT WINAPI DataCache_Unfreeze(
278 static HRESULT WINAPI DataCache_SetAdvise(
282 IAdviseSink* pAdvSink);
283 static HRESULT WINAPI DataCache_GetAdvise(
287 IAdviseSink** ppAdvSink);
288 static HRESULT WINAPI DataCache_GetExtent(
296 * Prototypes for the methods of the DataCache class
297 * that implement IOleCache2 methods.
299 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
303 static ULONG WINAPI DataCache_IOleCache2_AddRef(
305 static ULONG WINAPI DataCache_IOleCache2_Release(
307 static HRESULT WINAPI DataCache_Cache(
309 FORMATETC* pformatetc,
311 DWORD* pdwConnection);
312 static HRESULT WINAPI DataCache_Uncache(
315 static HRESULT WINAPI DataCache_EnumCache(
317 IEnumSTATDATA** ppenumSTATDATA);
318 static HRESULT WINAPI DataCache_InitCache(
320 IDataObject* pDataObject);
321 static HRESULT WINAPI DataCache_IOleCache2_SetData(
323 FORMATETC* pformatetc,
326 static HRESULT WINAPI DataCache_UpdateCache(
328 LPDATAOBJECT pDataObject,
331 static HRESULT WINAPI DataCache_DiscardCache(
333 DWORD dwDiscardOptions);
336 * Prototypes for the methods of the DataCache class
337 * that implement IOleCacheControl methods.
339 static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
340 IOleCacheControl* iface,
343 static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
344 IOleCacheControl* iface);
345 static ULONG WINAPI DataCache_IOleCacheControl_Release(
346 IOleCacheControl* iface);
347 static HRESULT WINAPI DataCache_OnRun(
348 IOleCacheControl* iface,
349 LPDATAOBJECT pDataObject);
350 static HRESULT WINAPI DataCache_OnStop(
351 IOleCacheControl* iface);
354 * Virtual function tables for the DataCache class.
356 static ICOM_VTABLE(IUnknown) DataCache_NDIUnknown_VTable =
358 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
359 DataCache_NDIUnknown_QueryInterface,
360 DataCache_NDIUnknown_AddRef,
361 DataCache_NDIUnknown_Release
364 static ICOM_VTABLE(IDataObject) DataCache_IDataObject_VTable =
366 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
367 DataCache_IDataObject_QueryInterface,
368 DataCache_IDataObject_AddRef,
369 DataCache_IDataObject_Release,
371 DataCache_GetDataHere,
372 DataCache_QueryGetData,
373 DataCache_GetCanonicalFormatEtc,
374 DataCache_IDataObject_SetData,
375 DataCache_EnumFormatEtc,
378 DataCache_EnumDAdvise
381 static ICOM_VTABLE(IPersistStorage) DataCache_IPersistStorage_VTable =
383 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
384 DataCache_IPersistStorage_QueryInterface,
385 DataCache_IPersistStorage_AddRef,
386 DataCache_IPersistStorage_Release,
387 DataCache_GetClassID,
392 DataCache_SaveCompleted,
393 DataCache_HandsOffStorage
396 static ICOM_VTABLE(IViewObject2) DataCache_IViewObject2_VTable =
398 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
399 DataCache_IViewObject2_QueryInterface,
400 DataCache_IViewObject2_AddRef,
401 DataCache_IViewObject2_Release,
403 DataCache_GetColorSet,
411 static ICOM_VTABLE(IOleCache2) DataCache_IOleCache2_VTable =
413 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
414 DataCache_IOleCache2_QueryInterface,
415 DataCache_IOleCache2_AddRef,
416 DataCache_IOleCache2_Release,
421 DataCache_IOleCache2_SetData,
422 DataCache_UpdateCache,
423 DataCache_DiscardCache
426 static ICOM_VTABLE(IOleCacheControl) DataCache_IOleCacheControl_VTable =
428 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
429 DataCache_IOleCacheControl_QueryInterface,
430 DataCache_IOleCacheControl_AddRef,
431 DataCache_IOleCacheControl_Release,
436 /******************************************************************************
437 * CreateDataCache [OLE32.54]
439 HRESULT WINAPI CreateDataCache(
445 DataCache* newCache = NULL;
448 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(rclsid), pUnkOuter, debugstr_guid(riid), ppvObj);
459 * If this cache is constructed for aggregation, make sure
460 * the caller is requesting the IUnknown interface.
461 * This is necessary because it's the only time the non-delegating
462 * IUnknown pointer can be returned to the outside.
464 if ( (pUnkOuter!=NULL) &&
465 (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) != 0) )
466 return CLASS_E_NOAGGREGATION;
469 * Try to construct a new instance of the class.
471 newCache = DataCache_Construct(rclsid,
475 return E_OUTOFMEMORY;
478 * Make sure it supports the interface required by the caller.
480 hr = IUnknown_QueryInterface((IUnknown*)&(newCache->lpvtbl2), riid, ppvObj);
483 * Release the reference obtained in the constructor. If
484 * the QueryInterface was unsuccessful, it will free the class.
486 IUnknown_Release((IUnknown*)&(newCache->lpvtbl2));
491 /*********************************************************
492 * Method implementation for DataCache class.
494 static DataCache* DataCache_Construct(
498 DataCache* newObject = 0;
501 * Allocate space for the object.
503 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache));
509 * Initialize the virtual function table.
511 newObject->lpvtbl1 = &DataCache_IDataObject_VTable;
512 newObject->lpvtbl2 = &DataCache_NDIUnknown_VTable;
513 newObject->lpvtbl3 = &DataCache_IPersistStorage_VTable;
514 newObject->lpvtbl4 = &DataCache_IViewObject2_VTable;
515 newObject->lpvtbl5 = &DataCache_IOleCache2_VTable;
516 newObject->lpvtbl6 = &DataCache_IOleCacheControl_VTable;
519 * Start with one reference count. The caller of this function
520 * must release the interface pointer when it is done.
525 * Initialize the outer unknown
526 * We don't keep a reference on the outer unknown since, the way
527 * aggregation works, our lifetime is at least as large as it's
531 pUnkOuter = (IUnknown*)&(newObject->lpvtbl2);
533 newObject->outerUnknown = pUnkOuter;
536 * Initialize the other members of the structure.
538 newObject->presentationStorage = NULL;
539 newObject->sinkAspects = 0;
540 newObject->sinkAdviseFlag = 0;
541 newObject->sinkInterface = 0;
546 static void DataCache_Destroy(
547 DataCache* ptrToDestroy)
551 if (ptrToDestroy->sinkInterface != NULL)
553 IAdviseSink_Release(ptrToDestroy->sinkInterface);
554 ptrToDestroy->sinkInterface = NULL;
557 if (ptrToDestroy->presentationStorage != NULL)
559 IStorage_Release(ptrToDestroy->presentationStorage);
560 ptrToDestroy->presentationStorage = NULL;
564 * Free the datacache pointer.
566 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
569 /************************************************************************
570 * DataCache_ReadPresentationData
572 * This method will read information for the requested presentation
573 * into the given structure.
576 * this - Pointer to the DataCache object
577 * drawAspect - The aspect of the object that we wish to draw.
578 * header - The structure containing information about this
579 * aspect of the object.
581 static HRESULT DataCache_ReadPresentationData(
584 PresentationDataHeader* header)
586 IStream* presStream = NULL;
587 OLECHAR streamName[20];
591 * Get the name for the presentation stream.
593 hres = DataCache_FindPresStreamName(
602 * Open the stream and read the header.
604 hres = IStorage_OpenStream(
605 this->presentationStorage,
608 STGM_READ | STGM_SHARE_EXCLUSIVE,
618 sizeof(PresentationDataHeader),
624 IStream_Release(presStream);
627 * We don't want to propagate any other error
628 * code than a failure.
636 /************************************************************************
637 * DataCache_FireOnViewChange
639 * This method will fire an OnViewChange notification to the advise
640 * sink registered with the datacache.
642 * See IAdviseSink::OnViewChange for more details.
644 static void DataCache_FireOnViewChange(
649 TRACE("(%p, %lx, %ld)\n", this, aspect, lindex);
652 * The sink supplies a filter when it registers
653 * we make sure we only send the notifications when that
656 if ((this->sinkAspects & aspect) != 0)
658 if (this->sinkInterface != NULL)
660 IAdviseSink_OnViewChange(this->sinkInterface,
665 * Some sinks want to be unregistered automatically when
666 * the first notification goes out.
668 if ( (this->sinkAdviseFlag & ADVF_ONLYONCE) != 0)
670 IAdviseSink_Release(this->sinkInterface);
672 this->sinkInterface = NULL;
673 this->sinkAspects = 0;
674 this->sinkAdviseFlag = 0;
680 /************************************************************************
681 * DataCache_ReadPresentationData
683 * This method will read information for the requested presentation
684 * into the given structure.
687 * this - Pointer to the DataCache object
688 * drawAspect - The aspect of the object that we wish to draw.
689 * header - The structure containing information about this
690 * aspect of the object.
693 * This method only supports the DVASPECT_CONTENT aspect.
695 static HRESULT DataCache_FindPresStreamName(
700 OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
702 if (drawAspect!=DVASPECT_CONTENT)
705 memcpy(buffer, name, sizeof(name));
710 /************************************************************************
711 * DataCache_ReadPresentationData
713 * This method will read information for the requested presentation
714 * into the given structure.
717 * this - Pointer to the DataCache object
718 * drawAspect - The aspect of the object that we wish to draw.
721 * This method returns a metafile handle if it is successful.
722 * it will return 0 if not.
724 static HMETAFILE DataCache_ReadPresMetafile(
728 LARGE_INTEGER offset;
729 IStream* presStream = NULL;
730 OLECHAR streamName[20];
734 HMETAFILE newMetafile = 0;
737 * Get the name for the presentation stream.
739 hres = DataCache_FindPresStreamName(
748 * Open the stream and read the header.
750 hres = IStorage_OpenStream(
751 this->presentationStorage,
754 STGM_READ | STGM_SHARE_EXCLUSIVE,
762 * Get the size of the stream.
764 hres = IStream_Stat(presStream,
771 offset.s.HighPart = 0;
772 offset.s.LowPart = sizeof(PresentationDataHeader);
781 * Allocate a buffer for the metafile bits.
783 metafileBits = HeapAlloc(GetProcessHeap(),
785 streamInfo.cbSize.s.LowPart);
788 * Read the metafile bits.
793 streamInfo.cbSize.s.LowPart,
797 * Create a metafile with those bits.
801 newMetafile = SetMetaFileBitsEx(streamInfo.cbSize.s.LowPart, metafileBits);
807 HeapFree(GetProcessHeap(), 0, metafileBits);
808 IStream_Release(presStream);
816 /*********************************************************
817 * Method implementation for the non delegating IUnknown
818 * part of the DataCache class.
821 /************************************************************************
822 * DataCache_NDIUnknown_QueryInterface (IUnknown)
824 * See Windows documentation for more details on IUnknown methods.
826 * This version of QueryInterface will not delegate it's implementation
827 * to the outer unknown.
829 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
834 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
837 * Perform a sanity check on the parameters.
839 if ( (this==0) || (ppvObject==0) )
843 * Initialize the return parameter.
848 * Compare the riid with the interface IDs implemented by this object.
850 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
854 else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0)
856 *ppvObject = (IDataObject*)&(this->lpvtbl1);
858 else if ( (memcmp(&IID_IPersistStorage, riid, sizeof(IID_IPersistStorage)) == 0) ||
859 (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0) )
861 *ppvObject = (IPersistStorage*)&(this->lpvtbl3);
863 else if ( (memcmp(&IID_IViewObject, riid, sizeof(IID_IViewObject)) == 0) ||
864 (memcmp(&IID_IViewObject2, riid, sizeof(IID_IViewObject2)) == 0) )
866 *ppvObject = (IViewObject2*)&(this->lpvtbl4);
868 else if ( (memcmp(&IID_IOleCache, riid, sizeof(IID_IOleCache)) == 0) ||
869 (memcmp(&IID_IOleCache2, riid, sizeof(IID_IOleCache2)) == 0) )
871 *ppvObject = (IOleCache2*)&(this->lpvtbl5);
873 else if (memcmp(&IID_IOleCacheControl, riid, sizeof(IID_IOleCacheControl)) == 0)
875 *ppvObject = (IOleCacheControl*)&(this->lpvtbl6);
879 * Check that we obtained an interface.
883 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
884 return E_NOINTERFACE;
888 * Query Interface always increases the reference count by one when it is
891 IUnknown_AddRef((IUnknown*)*ppvObject);
896 /************************************************************************
897 * DataCache_NDIUnknown_AddRef (IUnknown)
899 * See Windows documentation for more details on IUnknown methods.
901 * This version of QueryInterface will not delegate it's implementation
902 * to the outer unknown.
904 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
907 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
914 /************************************************************************
915 * DataCache_NDIUnknown_Release (IUnknown)
917 * See Windows documentation for more details on IUnknown methods.
919 * This version of QueryInterface will not delegate it's implementation
920 * to the outer unknown.
922 static ULONG WINAPI DataCache_NDIUnknown_Release(
925 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
928 * Decrease the reference count on this object.
933 * If the reference count goes down to 0, perform suicide.
937 DataCache_Destroy(this);
945 /*********************************************************
946 * Method implementation for the IDataObject
947 * part of the DataCache class.
950 /************************************************************************
951 * DataCache_IDataObject_QueryInterface (IUnknown)
953 * See Windows documentation for more details on IUnknown methods.
955 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
960 _ICOM_THIS_From_IDataObject(DataCache, iface);
962 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
965 /************************************************************************
966 * DataCache_IDataObject_AddRef (IUnknown)
968 * See Windows documentation for more details on IUnknown methods.
970 static ULONG WINAPI DataCache_IDataObject_AddRef(
973 _ICOM_THIS_From_IDataObject(DataCache, iface);
975 return IUnknown_AddRef(this->outerUnknown);
978 /************************************************************************
979 * DataCache_IDataObject_Release (IUnknown)
981 * See Windows documentation for more details on IUnknown methods.
983 static ULONG WINAPI DataCache_IDataObject_Release(
986 _ICOM_THIS_From_IDataObject(DataCache, iface);
988 return IUnknown_Release(this->outerUnknown);
991 static HRESULT WINAPI DataCache_GetData(
993 LPFORMATETC pformatetcIn,
1000 static HRESULT WINAPI DataCache_GetDataHere(
1002 LPFORMATETC pformatetc,
1009 static HRESULT WINAPI DataCache_QueryGetData(
1011 LPFORMATETC pformatetc)
1017 /************************************************************************
1018 * DataCache_EnumFormatEtc (IDataObject)
1020 * The data cache doesn't implement this method.
1022 * See Windows documentation for more details on IDataObject methods.
1024 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
1026 LPFORMATETC pformatectIn,
1027 LPFORMATETC pformatetcOut)
1033 /************************************************************************
1034 * DataCache_IDataObject_SetData (IDataObject)
1036 * This method is delegated to the IOleCache2 implementation.
1038 * See Windows documentation for more details on IDataObject methods.
1040 static HRESULT WINAPI DataCache_IDataObject_SetData(
1042 LPFORMATETC pformatetc,
1046 IOleCache2* oleCache = NULL;
1049 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1051 hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);
1054 return E_UNEXPECTED;
1056 hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);
1058 IOleCache2_Release(oleCache);
1063 /************************************************************************
1064 * DataCache_EnumFormatEtc (IDataObject)
1066 * The data cache doesn't implement this method.
1068 * See Windows documentation for more details on IDataObject methods.
1070 static HRESULT WINAPI DataCache_EnumFormatEtc(
1073 IEnumFORMATETC** ppenumFormatEtc)
1079 /************************************************************************
1080 * DataCache_DAdvise (IDataObject)
1082 * The data cache doesn't support connections.
1084 * See Windows documentation for more details on IDataObject methods.
1086 static HRESULT WINAPI DataCache_DAdvise(
1088 FORMATETC* pformatetc,
1090 IAdviseSink* pAdvSink,
1091 DWORD* pdwConnection)
1094 return OLE_E_ADVISENOTSUPPORTED;
1097 /************************************************************************
1098 * DataCache_DUnadvise (IDataObject)
1100 * The data cache doesn't support connections.
1102 * See Windows documentation for more details on IDataObject methods.
1104 static HRESULT WINAPI DataCache_DUnadvise(
1109 return OLE_E_NOCONNECTION;
1112 /************************************************************************
1113 * DataCache_EnumDAdvise (IDataObject)
1115 * The data cache doesn't support connections.
1117 * See Windows documentation for more details on IDataObject methods.
1119 static HRESULT WINAPI DataCache_EnumDAdvise(
1121 IEnumSTATDATA** ppenumAdvise)
1124 return OLE_E_ADVISENOTSUPPORTED;
1127 /*********************************************************
1128 * Method implementation for the IDataObject
1129 * part of the DataCache class.
1132 /************************************************************************
1133 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1135 * See Windows documentation for more details on IUnknown methods.
1137 static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
1138 IPersistStorage* iface,
1142 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1144 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1147 /************************************************************************
1148 * DataCache_IPersistStorage_AddRef (IUnknown)
1150 * See Windows documentation for more details on IUnknown methods.
1152 static ULONG WINAPI DataCache_IPersistStorage_AddRef(
1153 IPersistStorage* iface)
1155 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1157 return IUnknown_AddRef(this->outerUnknown);
1160 /************************************************************************
1161 * DataCache_IPersistStorage_Release (IUnknown)
1163 * See Windows documentation for more details on IUnknown methods.
1165 static ULONG WINAPI DataCache_IPersistStorage_Release(
1166 IPersistStorage* iface)
1168 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1170 return IUnknown_Release(this->outerUnknown);
1173 /************************************************************************
1174 * DataCache_GetClassID (IPersistStorage)
1176 * The data cache doesn't implement this method.
1178 * See Windows documentation for more details on IPersistStorage methods.
1180 static HRESULT WINAPI DataCache_GetClassID(
1181 IPersistStorage* iface,
1184 TRACE("(%p, %p)\n", iface, pClassID);
1188 /************************************************************************
1189 * DataCache_IsDirty (IPersistStorage)
1191 * Until we actully connect to a running object and retrieve new
1192 * information to it, we never get dirty.
1194 * See Windows documentation for more details on IPersistStorage methods.
1196 static HRESULT WINAPI DataCache_IsDirty(
1197 IPersistStorage* iface)
1199 TRACE("(%p)\n", iface);
1204 /************************************************************************
1205 * DataCache_InitNew (IPersistStorage)
1207 * The data cache implementation of IPersistStorage_InitNew simply stores
1208 * the storage pointer.
1210 * See Windows documentation for more details on IPersistStorage methods.
1212 static HRESULT WINAPI DataCache_InitNew(
1213 IPersistStorage* iface,
1216 TRACE("(%p, %p)\n", iface, pStg);
1218 return DataCache_Load(iface, pStg);
1221 /************************************************************************
1222 * DataCache_Load (IPersistStorage)
1224 * The data cache implementation of IPersistStorage_Load doesn't
1225 * actually load anything. Instead, it holds on to the storage pointer
1226 * and it will load the presentation information when the
1227 * IDataObject_GetData or IViewObject2_Draw methods are called.
1229 * See Windows documentation for more details on IPersistStorage methods.
1231 static HRESULT WINAPI DataCache_Load(
1232 IPersistStorage* iface,
1235 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1237 TRACE("(%p, %p)\n", iface, pStg);
1239 if (this->presentationStorage != NULL)
1241 IStorage_Release(this->presentationStorage);
1244 this->presentationStorage = pStg;
1246 if (this->presentationStorage != NULL)
1248 IStorage_AddRef(this->presentationStorage);
1254 /************************************************************************
1255 * DataCache_Save (IPersistStorage)
1257 * Until we actully connect to a running object and retrieve new
1258 * information to it, we never have to save anything. However, it is
1259 * our responsability to copy the information when saving to a new
1262 * See Windows documentation for more details on IPersistStorage methods.
1264 static HRESULT WINAPI DataCache_Save(
1265 IPersistStorage* iface,
1269 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1271 TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad);
1273 if ( (!fSameAsLoad) &&
1274 (this->presentationStorage!=NULL) )
1276 return IStorage_CopyTo(this->presentationStorage,
1286 /************************************************************************
1287 * DataCache_SaveCompleted (IPersistStorage)
1289 * This method is called to tell the cache to release the storage
1290 * pointer it's currentlu holding.
1292 * See Windows documentation for more details on IPersistStorage methods.
1294 static HRESULT WINAPI DataCache_SaveCompleted(
1295 IPersistStorage* iface,
1298 TRACE("(%p, %p)\n", iface, pStgNew);
1301 * First, make sure we get our hands off any storage we have.
1303 DataCache_HandsOffStorage(iface);
1306 * Then, attach to the new storage.
1308 DataCache_Load(iface, pStgNew);
1313 /************************************************************************
1314 * DataCache_HandsOffStorage (IPersistStorage)
1316 * This method is called to tell the cache to release the storage
1317 * pointer it's currentlu holding.
1319 * See Windows documentation for more details on IPersistStorage methods.
1321 static HRESULT WINAPI DataCache_HandsOffStorage(
1322 IPersistStorage* iface)
1324 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1326 TRACE("(%p)\n", iface);
1328 if (this->presentationStorage != NULL)
1330 IStorage_Release(this->presentationStorage);
1331 this->presentationStorage = NULL;
1337 /*********************************************************
1338 * Method implementation for the IViewObject2
1339 * part of the DataCache class.
1342 /************************************************************************
1343 * DataCache_IViewObject2_QueryInterface (IUnknown)
1345 * See Windows documentation for more details on IUnknown methods.
1347 static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
1348 IViewObject2* iface,
1352 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1354 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1357 /************************************************************************
1358 * DataCache_IViewObject2_AddRef (IUnknown)
1360 * See Windows documentation for more details on IUnknown methods.
1362 static ULONG WINAPI DataCache_IViewObject2_AddRef(
1363 IViewObject2* iface)
1365 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1367 return IUnknown_AddRef(this->outerUnknown);
1370 /************************************************************************
1371 * DataCache_IViewObject2_Release (IUnknown)
1373 * See Windows documentation for more details on IUnknown methods.
1375 static ULONG WINAPI DataCache_IViewObject2_Release(
1376 IViewObject2* iface)
1378 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1380 return IUnknown_Release(this->outerUnknown);
1383 /************************************************************************
1384 * DataCache_Draw (IViewObject2)
1386 * This method will draw the cached representation of the object
1387 * to the given device context.
1389 * See Windows documentation for more details on IViewObject2 methods.
1391 static HRESULT WINAPI DataCache_Draw(
1392 IViewObject2* iface,
1396 DVTARGETDEVICE* ptd,
1399 LPCRECTL lprcBounds,
1400 LPCRECTL lprcWBounds,
1401 IVO_ContCallback pfnContinue,
1404 PresentationDataHeader presData;
1405 HMETAFILE presMetafile = 0;
1408 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1410 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1425 if (lprcBounds==NULL)
1426 return E_INVALIDARG;
1429 * First, we need to retrieve the dimensions of the
1430 * image in the metafile.
1432 hres = DataCache_ReadPresentationData(this,
1440 * Then, we can extract the metafile itself from the cached
1443 presMetafile = DataCache_ReadPresMetafile(this,
1447 * If we have a metafile, just draw baby...
1448 * We have to be careful not to modify the state of the
1451 if (presMetafile!=0)
1453 INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC);
1455 SIZE oldViewportExt;
1456 POINT oldViewportOrg;
1458 SetWindowExtEx(hdcDraw,
1459 presData.objectExtentX,
1460 presData.objectExtentY,
1463 SetViewportExtEx(hdcDraw,
1464 lprcBounds->right - lprcBounds->left,
1465 lprcBounds->bottom - lprcBounds->top,
1468 SetViewportOrgEx(hdcDraw,
1473 PlayMetaFile(hdcDraw, presMetafile);
1475 SetWindowExtEx(hdcDraw,
1480 SetViewportExtEx(hdcDraw,
1485 SetViewportOrgEx(hdcDraw,
1490 SetMapMode(hdcDraw, prevMapMode);
1492 DeleteMetaFile(presMetafile);
1498 static HRESULT WINAPI DataCache_GetColorSet(
1499 IViewObject2* iface,
1503 DVTARGETDEVICE* ptd,
1504 HDC hicTargetDevice,
1505 LOGPALETTE** ppColorSet)
1511 static HRESULT WINAPI DataCache_Freeze(
1512 IViewObject2* iface,
1522 static HRESULT WINAPI DataCache_Unfreeze(
1523 IViewObject2* iface,
1530 /************************************************************************
1531 * DataCache_SetAdvise (IViewObject2)
1533 * This sets-up an advisory sink with the data cache. When the object's
1534 * view changes, this sink is called.
1536 * See Windows documentation for more details on IViewObject2 methods.
1538 static HRESULT WINAPI DataCache_SetAdvise(
1539 IViewObject2* iface,
1542 IAdviseSink* pAdvSink)
1544 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1546 TRACE("(%p, %lx, %lx, %p)\n", iface, aspects, advf, pAdvSink);
1549 * A call to this function removes the previous sink
1551 if (this->sinkInterface != NULL)
1553 IAdviseSink_Release(this->sinkInterface);
1554 this->sinkInterface = NULL;
1555 this->sinkAspects = 0;
1556 this->sinkAdviseFlag = 0;
1560 * Now, setup the new one.
1564 this->sinkInterface = pAdvSink;
1565 this->sinkAspects = aspects;
1566 this->sinkAdviseFlag = advf;
1568 IAdviseSink_AddRef(this->sinkInterface);
1572 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1575 if (advf & ADVF_PRIMEFIRST)
1577 DataCache_FireOnViewChange(this,
1585 /************************************************************************
1586 * DataCache_GetAdvise (IViewObject2)
1588 * This method queries the current state of the advise sink
1589 * installed on the data cache.
1591 * See Windows documentation for more details on IViewObject2 methods.
1593 static HRESULT WINAPI DataCache_GetAdvise(
1594 IViewObject2* iface,
1597 IAdviseSink** ppAdvSink)
1599 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1601 TRACE("(%p, %p, %p, %p)\n", iface, pAspects, pAdvf, ppAdvSink);
1604 * Just copy all the requested values.
1607 *pAspects = this->sinkAspects;
1610 *pAdvf = this->sinkAdviseFlag;
1612 if (ppAdvSink!=NULL)
1614 IAdviseSink_QueryInterface(this->sinkInterface,
1622 /************************************************************************
1623 * DataCache_GetExtent (IViewObject2)
1625 * This method retrieves the "natural" size of this cached object.
1627 * See Windows documentation for more details on IViewObject2 methods.
1629 static HRESULT WINAPI DataCache_GetExtent(
1630 IViewObject2* iface,
1633 DVTARGETDEVICE* ptd,
1636 PresentationDataHeader presData;
1637 HRESULT hres = E_FAIL;
1639 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1641 TRACE("(%p, %lx, %ld, %p, %p)\n",
1642 iface, dwDrawAspect, lindex, ptd, lpsizel);
1651 * Initialize the out parameter.
1657 * This flag should be set to -1.
1660 FIXME("Unimplemented flag lindex = %ld\n", lindex);
1663 * Right now, we suport only the callback from
1664 * the default handler.
1667 FIXME("Unimplemented ptd = %p\n", ptd);
1670 * Get the presentation information from the
1673 hres = DataCache_ReadPresentationData(this,
1677 if (SUCCEEDED(hres))
1679 lpsizel->cx = presData.objectExtentX;
1680 lpsizel->cy = presData.objectExtentY;
1684 * This method returns OLE_E_BLANK when it fails.
1693 /*********************************************************
1694 * Method implementation for the IOleCache2
1695 * part of the DataCache class.
1698 /************************************************************************
1699 * DataCache_IOleCache2_QueryInterface (IUnknown)
1701 * See Windows documentation for more details on IUnknown methods.
1703 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
1708 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1710 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1713 /************************************************************************
1714 * DataCache_IOleCache2_AddRef (IUnknown)
1716 * See Windows documentation for more details on IUnknown methods.
1718 static ULONG WINAPI DataCache_IOleCache2_AddRef(
1721 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1723 return IUnknown_AddRef(this->outerUnknown);
1726 /************************************************************************
1727 * DataCache_IOleCache2_Release (IUnknown)
1729 * See Windows documentation for more details on IUnknown methods.
1731 static ULONG WINAPI DataCache_IOleCache2_Release(
1734 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1736 return IUnknown_Release(this->outerUnknown);
1739 static HRESULT WINAPI DataCache_Cache(
1741 FORMATETC* pformatetc,
1743 DWORD* pdwConnection)
1749 static HRESULT WINAPI DataCache_Uncache(
1757 static HRESULT WINAPI DataCache_EnumCache(
1759 IEnumSTATDATA** ppenumSTATDATA)
1765 static HRESULT WINAPI DataCache_InitCache(
1767 IDataObject* pDataObject)
1773 static HRESULT WINAPI DataCache_IOleCache2_SetData(
1775 FORMATETC* pformatetc,
1783 static HRESULT WINAPI DataCache_UpdateCache(
1785 LPDATAOBJECT pDataObject,
1793 static HRESULT WINAPI DataCache_DiscardCache(
1795 DWORD dwDiscardOptions)
1802 /*********************************************************
1803 * Method implementation for the IOleCacheControl
1804 * part of the DataCache class.
1807 /************************************************************************
1808 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1810 * See Windows documentation for more details on IUnknown methods.
1812 static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
1813 IOleCacheControl* iface,
1817 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1819 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1822 /************************************************************************
1823 * DataCache_IOleCacheControl_AddRef (IUnknown)
1825 * See Windows documentation for more details on IUnknown methods.
1827 static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
1828 IOleCacheControl* iface)
1830 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1832 return IUnknown_AddRef(this->outerUnknown);
1835 /************************************************************************
1836 * DataCache_IOleCacheControl_Release (IUnknown)
1838 * See Windows documentation for more details on IUnknown methods.
1840 static ULONG WINAPI DataCache_IOleCacheControl_Release(
1841 IOleCacheControl* iface)
1843 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1845 return IUnknown_Release(this->outerUnknown);
1848 static HRESULT WINAPI DataCache_OnRun(
1849 IOleCacheControl* iface,
1850 LPDATAOBJECT pDataObject)
1856 static HRESULT WINAPI DataCache_OnStop(
1857 IOleCacheControl* iface)