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.
606 hres = IStorage_OpenStream(
607 this->presentationStorage,
610 STGM_READ | STGM_SHARE_EXCLUSIVE,
620 sizeof(PresentationDataHeader),
626 IStream_Release(presStream);
629 * We don't want to propagate any other error
630 * code than a failure.
638 /************************************************************************
639 * DataCache_FireOnViewChange
641 * This method will fire an OnViewChange notification to the advise
642 * sink registered with the datacache.
644 * See IAdviseSink::OnViewChange for more details.
646 static void DataCache_FireOnViewChange(
651 TRACE("(%p, %lx, %ld)\n", this, aspect, lindex);
654 * The sink supplies a filter when it registers
655 * we make sure we only send the notifications when that
658 if ((this->sinkAspects & aspect) != 0)
660 if (this->sinkInterface != NULL)
662 IAdviseSink_OnViewChange(this->sinkInterface,
667 * Some sinks want to be unregistered automatically when
668 * the first notification goes out.
670 if ( (this->sinkAdviseFlag & ADVF_ONLYONCE) != 0)
672 IAdviseSink_Release(this->sinkInterface);
674 this->sinkInterface = NULL;
675 this->sinkAspects = 0;
676 this->sinkAdviseFlag = 0;
682 /************************************************************************
683 * DataCache_ReadPresentationData
685 * This method will read information for the requested presentation
686 * into the given structure.
689 * this - Pointer to the DataCache object
690 * drawAspect - The aspect of the object that we wish to draw.
691 * header - The structure containing information about this
692 * aspect of the object.
695 * This method only supports the DVASPECT_CONTENT aspect.
697 static HRESULT DataCache_FindPresStreamName(
702 OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
704 if (drawAspect!=DVASPECT_CONTENT)
707 memcpy(buffer, name, sizeof(name));
712 /************************************************************************
713 * DataCache_ReadPresentationData
715 * This method will read information for the requested presentation
716 * into the given structure.
719 * this - Pointer to the DataCache object
720 * drawAspect - The aspect of the object that we wish to draw.
723 * This method returns a metafile handle if it is successful.
724 * it will return 0 if not.
726 static HMETAFILE DataCache_ReadPresMetafile(
730 LARGE_INTEGER offset;
731 IStream* presStream = NULL;
732 OLECHAR streamName[20];
736 HMETAFILE newMetafile = 0;
739 * Get the name for the presentation stream.
741 hres = DataCache_FindPresStreamName(
750 * Open the stream and read the header.
752 hres = IStorage_OpenStream(
753 this->presentationStorage,
756 STGM_READ | STGM_SHARE_EXCLUSIVE,
764 * Get the size of the stream.
766 hres = IStream_Stat(presStream,
773 offset.s.HighPart = 0;
774 offset.s.LowPart = sizeof(PresentationDataHeader);
783 * Allocate a buffer for the metafile bits.
785 metafileBits = HeapAlloc(GetProcessHeap(),
787 streamInfo.cbSize.s.LowPart);
790 * Read the metafile bits.
795 streamInfo.cbSize.s.LowPart,
799 * Create a metafile with those bits.
803 newMetafile = SetMetaFileBitsEx(streamInfo.cbSize.s.LowPart, metafileBits);
809 HeapFree(GetProcessHeap(), 0, metafileBits);
810 IStream_Release(presStream);
818 /*********************************************************
819 * Method implementation for the non delegating IUnknown
820 * part of the DataCache class.
823 /************************************************************************
824 * DataCache_NDIUnknown_QueryInterface (IUnknown)
826 * See Windows documentation for more details on IUnknown methods.
828 * This version of QueryInterface will not delegate it's implementation
829 * to the outer unknown.
831 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
836 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
839 * Perform a sanity check on the parameters.
841 if ( (this==0) || (ppvObject==0) )
845 * Initialize the return parameter.
850 * Compare the riid with the interface IDs implemented by this object.
852 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
856 else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0)
858 *ppvObject = (IDataObject*)&(this->lpvtbl1);
860 else if ( (memcmp(&IID_IPersistStorage, riid, sizeof(IID_IPersistStorage)) == 0) ||
861 (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0) )
863 *ppvObject = (IPersistStorage*)&(this->lpvtbl3);
865 else if ( (memcmp(&IID_IViewObject, riid, sizeof(IID_IViewObject)) == 0) ||
866 (memcmp(&IID_IViewObject2, riid, sizeof(IID_IViewObject2)) == 0) )
868 *ppvObject = (IViewObject2*)&(this->lpvtbl4);
870 else if ( (memcmp(&IID_IOleCache, riid, sizeof(IID_IOleCache)) == 0) ||
871 (memcmp(&IID_IOleCache2, riid, sizeof(IID_IOleCache2)) == 0) )
873 *ppvObject = (IOleCache2*)&(this->lpvtbl5);
875 else if (memcmp(&IID_IOleCacheControl, riid, sizeof(IID_IOleCacheControl)) == 0)
877 *ppvObject = (IOleCacheControl*)&(this->lpvtbl6);
881 * Check that we obtained an interface.
885 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
886 return E_NOINTERFACE;
890 * Query Interface always increases the reference count by one when it is
893 IUnknown_AddRef((IUnknown*)*ppvObject);
898 /************************************************************************
899 * DataCache_NDIUnknown_AddRef (IUnknown)
901 * See Windows documentation for more details on IUnknown methods.
903 * This version of QueryInterface will not delegate it's implementation
904 * to the outer unknown.
906 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
909 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
916 /************************************************************************
917 * DataCache_NDIUnknown_Release (IUnknown)
919 * See Windows documentation for more details on IUnknown methods.
921 * This version of QueryInterface will not delegate it's implementation
922 * to the outer unknown.
924 static ULONG WINAPI DataCache_NDIUnknown_Release(
927 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
930 * Decrease the reference count on this object.
935 * If the reference count goes down to 0, perform suicide.
939 DataCache_Destroy(this);
947 /*********************************************************
948 * Method implementation for the IDataObject
949 * part of the DataCache class.
952 /************************************************************************
953 * DataCache_IDataObject_QueryInterface (IUnknown)
955 * See Windows documentation for more details on IUnknown methods.
957 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
962 _ICOM_THIS_From_IDataObject(DataCache, iface);
964 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
967 /************************************************************************
968 * DataCache_IDataObject_AddRef (IUnknown)
970 * See Windows documentation for more details on IUnknown methods.
972 static ULONG WINAPI DataCache_IDataObject_AddRef(
975 _ICOM_THIS_From_IDataObject(DataCache, iface);
977 return IUnknown_AddRef(this->outerUnknown);
980 /************************************************************************
981 * DataCache_IDataObject_Release (IUnknown)
983 * See Windows documentation for more details on IUnknown methods.
985 static ULONG WINAPI DataCache_IDataObject_Release(
988 _ICOM_THIS_From_IDataObject(DataCache, iface);
990 return IUnknown_Release(this->outerUnknown);
993 static HRESULT WINAPI DataCache_GetData(
995 LPFORMATETC pformatetcIn,
1002 static HRESULT WINAPI DataCache_GetDataHere(
1004 LPFORMATETC pformatetc,
1011 static HRESULT WINAPI DataCache_QueryGetData(
1013 LPFORMATETC pformatetc)
1019 /************************************************************************
1020 * DataCache_EnumFormatEtc (IDataObject)
1022 * The data cache doesn't implement this method.
1024 * See Windows documentation for more details on IDataObject methods.
1026 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
1028 LPFORMATETC pformatectIn,
1029 LPFORMATETC pformatetcOut)
1035 /************************************************************************
1036 * DataCache_IDataObject_SetData (IDataObject)
1038 * This method is delegated to the IOleCache2 implementation.
1040 * See Windows documentation for more details on IDataObject methods.
1042 static HRESULT WINAPI DataCache_IDataObject_SetData(
1044 LPFORMATETC pformatetc,
1048 IOleCache2* oleCache = NULL;
1051 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1053 hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);
1056 return E_UNEXPECTED;
1058 hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);
1060 IOleCache2_Release(oleCache);
1065 /************************************************************************
1066 * DataCache_EnumFormatEtc (IDataObject)
1068 * The data cache doesn't implement this method.
1070 * See Windows documentation for more details on IDataObject methods.
1072 static HRESULT WINAPI DataCache_EnumFormatEtc(
1075 IEnumFORMATETC** ppenumFormatEtc)
1081 /************************************************************************
1082 * DataCache_DAdvise (IDataObject)
1084 * The data cache doesn't support connections.
1086 * See Windows documentation for more details on IDataObject methods.
1088 static HRESULT WINAPI DataCache_DAdvise(
1090 FORMATETC* pformatetc,
1092 IAdviseSink* pAdvSink,
1093 DWORD* pdwConnection)
1096 return OLE_E_ADVISENOTSUPPORTED;
1099 /************************************************************************
1100 * DataCache_DUnadvise (IDataObject)
1102 * The data cache doesn't support connections.
1104 * See Windows documentation for more details on IDataObject methods.
1106 static HRESULT WINAPI DataCache_DUnadvise(
1111 return OLE_E_NOCONNECTION;
1114 /************************************************************************
1115 * DataCache_EnumDAdvise (IDataObject)
1117 * The data cache doesn't support connections.
1119 * See Windows documentation for more details on IDataObject methods.
1121 static HRESULT WINAPI DataCache_EnumDAdvise(
1123 IEnumSTATDATA** ppenumAdvise)
1126 return OLE_E_ADVISENOTSUPPORTED;
1129 /*********************************************************
1130 * Method implementation for the IDataObject
1131 * part of the DataCache class.
1134 /************************************************************************
1135 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1137 * See Windows documentation for more details on IUnknown methods.
1139 static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
1140 IPersistStorage* iface,
1144 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1146 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1149 /************************************************************************
1150 * DataCache_IPersistStorage_AddRef (IUnknown)
1152 * See Windows documentation for more details on IUnknown methods.
1154 static ULONG WINAPI DataCache_IPersistStorage_AddRef(
1155 IPersistStorage* iface)
1157 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1159 return IUnknown_AddRef(this->outerUnknown);
1162 /************************************************************************
1163 * DataCache_IPersistStorage_Release (IUnknown)
1165 * See Windows documentation for more details on IUnknown methods.
1167 static ULONG WINAPI DataCache_IPersistStorage_Release(
1168 IPersistStorage* iface)
1170 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1172 return IUnknown_Release(this->outerUnknown);
1175 /************************************************************************
1176 * DataCache_GetClassID (IPersistStorage)
1178 * The data cache doesn't implement this method.
1180 * See Windows documentation for more details on IPersistStorage methods.
1182 static HRESULT WINAPI DataCache_GetClassID(
1183 IPersistStorage* iface,
1186 TRACE("(%p, %p)\n", iface, pClassID);
1190 /************************************************************************
1191 * DataCache_IsDirty (IPersistStorage)
1193 * Until we actully connect to a running object and retrieve new
1194 * information to it, we never get dirty.
1196 * See Windows documentation for more details on IPersistStorage methods.
1198 static HRESULT WINAPI DataCache_IsDirty(
1199 IPersistStorage* iface)
1201 TRACE("(%p)\n", iface);
1206 /************************************************************************
1207 * DataCache_InitNew (IPersistStorage)
1209 * The data cache implementation of IPersistStorage_InitNew simply stores
1210 * the storage pointer.
1212 * See Windows documentation for more details on IPersistStorage methods.
1214 static HRESULT WINAPI DataCache_InitNew(
1215 IPersistStorage* iface,
1218 TRACE("(%p, %p)\n", iface, pStg);
1220 return DataCache_Load(iface, pStg);
1223 /************************************************************************
1224 * DataCache_Load (IPersistStorage)
1226 * The data cache implementation of IPersistStorage_Load doesn't
1227 * actually load anything. Instead, it holds on to the storage pointer
1228 * and it will load the presentation information when the
1229 * IDataObject_GetData or IViewObject2_Draw methods are called.
1231 * See Windows documentation for more details on IPersistStorage methods.
1233 static HRESULT WINAPI DataCache_Load(
1234 IPersistStorage* iface,
1237 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1239 TRACE("(%p, %p)\n", iface, pStg);
1241 if (this->presentationStorage != NULL)
1243 IStorage_Release(this->presentationStorage);
1246 this->presentationStorage = pStg;
1248 if (this->presentationStorage != NULL)
1250 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);
1304 * First, make sure we get our hands off any storage we have.
1307 DataCache_HandsOffStorage(iface);
1310 * Then, attach to the new storage.
1313 DataCache_Load(iface, pStgNew);
1319 /************************************************************************
1320 * DataCache_HandsOffStorage (IPersistStorage)
1322 * This method is called to tell the cache to release the storage
1323 * pointer it's currentlu holding.
1325 * See Windows documentation for more details on IPersistStorage methods.
1327 static HRESULT WINAPI DataCache_HandsOffStorage(
1328 IPersistStorage* iface)
1330 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1332 TRACE("(%p)\n", iface);
1334 if (this->presentationStorage != NULL)
1336 IStorage_Release(this->presentationStorage);
1337 this->presentationStorage = NULL;
1343 /*********************************************************
1344 * Method implementation for the IViewObject2
1345 * part of the DataCache class.
1348 /************************************************************************
1349 * DataCache_IViewObject2_QueryInterface (IUnknown)
1351 * See Windows documentation for more details on IUnknown methods.
1353 static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
1354 IViewObject2* iface,
1358 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1360 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1363 /************************************************************************
1364 * DataCache_IViewObject2_AddRef (IUnknown)
1366 * See Windows documentation for more details on IUnknown methods.
1368 static ULONG WINAPI DataCache_IViewObject2_AddRef(
1369 IViewObject2* iface)
1371 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1373 return IUnknown_AddRef(this->outerUnknown);
1376 /************************************************************************
1377 * DataCache_IViewObject2_Release (IUnknown)
1379 * See Windows documentation for more details on IUnknown methods.
1381 static ULONG WINAPI DataCache_IViewObject2_Release(
1382 IViewObject2* iface)
1384 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1386 return IUnknown_Release(this->outerUnknown);
1389 /************************************************************************
1390 * DataCache_Draw (IViewObject2)
1392 * This method will draw the cached representation of the object
1393 * to the given device context.
1395 * See Windows documentation for more details on IViewObject2 methods.
1397 static HRESULT WINAPI DataCache_Draw(
1398 IViewObject2* iface,
1402 DVTARGETDEVICE* ptd,
1405 LPCRECTL lprcBounds,
1406 LPCRECTL lprcWBounds,
1407 IVO_ContCallback pfnContinue,
1410 PresentationDataHeader presData;
1411 HMETAFILE presMetafile = 0;
1414 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1416 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1431 if (lprcBounds==NULL)
1432 return E_INVALIDARG;
1435 * First, we need to retrieve the dimensions of the
1436 * image in the metafile.
1438 hres = DataCache_ReadPresentationData(this,
1446 * Then, we can extract the metafile itself from the cached
1449 presMetafile = DataCache_ReadPresMetafile(this,
1453 * If we have a metafile, just draw baby...
1454 * We have to be careful not to modify the state of the
1457 if (presMetafile!=0)
1459 INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC);
1461 SIZE oldViewportExt;
1462 POINT oldViewportOrg;
1464 SetWindowExtEx(hdcDraw,
1465 presData.objectExtentX,
1466 presData.objectExtentY,
1469 SetViewportExtEx(hdcDraw,
1470 lprcBounds->right - lprcBounds->left,
1471 lprcBounds->bottom - lprcBounds->top,
1474 SetViewportOrgEx(hdcDraw,
1479 PlayMetaFile(hdcDraw, presMetafile);
1481 SetWindowExtEx(hdcDraw,
1486 SetViewportExtEx(hdcDraw,
1491 SetViewportOrgEx(hdcDraw,
1496 SetMapMode(hdcDraw, prevMapMode);
1498 DeleteMetaFile(presMetafile);
1504 static HRESULT WINAPI DataCache_GetColorSet(
1505 IViewObject2* iface,
1509 DVTARGETDEVICE* ptd,
1510 HDC hicTargetDevice,
1511 LOGPALETTE** ppColorSet)
1517 static HRESULT WINAPI DataCache_Freeze(
1518 IViewObject2* iface,
1528 static HRESULT WINAPI DataCache_Unfreeze(
1529 IViewObject2* iface,
1536 /************************************************************************
1537 * DataCache_SetAdvise (IViewObject2)
1539 * This sets-up an advisory sink with the data cache. When the object's
1540 * view changes, this sink is called.
1542 * See Windows documentation for more details on IViewObject2 methods.
1544 static HRESULT WINAPI DataCache_SetAdvise(
1545 IViewObject2* iface,
1548 IAdviseSink* pAdvSink)
1550 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1552 TRACE("(%p, %lx, %lx, %p)\n", iface, aspects, advf, pAdvSink);
1555 * A call to this function removes the previous sink
1557 if (this->sinkInterface != NULL)
1559 IAdviseSink_Release(this->sinkInterface);
1560 this->sinkInterface = NULL;
1561 this->sinkAspects = 0;
1562 this->sinkAdviseFlag = 0;
1566 * Now, setup the new one.
1570 this->sinkInterface = pAdvSink;
1571 this->sinkAspects = aspects;
1572 this->sinkAdviseFlag = advf;
1574 IAdviseSink_AddRef(this->sinkInterface);
1578 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1581 if (advf & ADVF_PRIMEFIRST)
1583 DataCache_FireOnViewChange(this,
1591 /************************************************************************
1592 * DataCache_GetAdvise (IViewObject2)
1594 * This method queries the current state of the advise sink
1595 * installed on the data cache.
1597 * See Windows documentation for more details on IViewObject2 methods.
1599 static HRESULT WINAPI DataCache_GetAdvise(
1600 IViewObject2* iface,
1603 IAdviseSink** ppAdvSink)
1605 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1607 TRACE("(%p, %p, %p, %p)\n", iface, pAspects, pAdvf, ppAdvSink);
1610 * Just copy all the requested values.
1613 *pAspects = this->sinkAspects;
1616 *pAdvf = this->sinkAdviseFlag;
1618 if (ppAdvSink!=NULL)
1620 IAdviseSink_QueryInterface(this->sinkInterface,
1628 /************************************************************************
1629 * DataCache_GetExtent (IViewObject2)
1631 * This method retrieves the "natural" size of this cached object.
1633 * See Windows documentation for more details on IViewObject2 methods.
1635 static HRESULT WINAPI DataCache_GetExtent(
1636 IViewObject2* iface,
1639 DVTARGETDEVICE* ptd,
1642 PresentationDataHeader presData;
1643 HRESULT hres = E_FAIL;
1645 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1647 TRACE("(%p, %lx, %ld, %p, %p)\n",
1648 iface, dwDrawAspect, lindex, ptd, lpsizel);
1657 * Initialize the out parameter.
1663 * This flag should be set to -1.
1666 FIXME("Unimplemented flag lindex = %ld\n", lindex);
1669 * Right now, we suport only the callback from
1670 * the default handler.
1673 FIXME("Unimplemented ptd = %p\n", ptd);
1676 * Get the presentation information from the
1679 hres = DataCache_ReadPresentationData(this,
1683 if (SUCCEEDED(hres))
1685 lpsizel->cx = presData.objectExtentX;
1686 lpsizel->cy = presData.objectExtentY;
1690 * This method returns OLE_E_BLANK when it fails.
1699 /*********************************************************
1700 * Method implementation for the IOleCache2
1701 * part of the DataCache class.
1704 /************************************************************************
1705 * DataCache_IOleCache2_QueryInterface (IUnknown)
1707 * See Windows documentation for more details on IUnknown methods.
1709 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
1714 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1716 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1719 /************************************************************************
1720 * DataCache_IOleCache2_AddRef (IUnknown)
1722 * See Windows documentation for more details on IUnknown methods.
1724 static ULONG WINAPI DataCache_IOleCache2_AddRef(
1727 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1729 return IUnknown_AddRef(this->outerUnknown);
1732 /************************************************************************
1733 * DataCache_IOleCache2_Release (IUnknown)
1735 * See Windows documentation for more details on IUnknown methods.
1737 static ULONG WINAPI DataCache_IOleCache2_Release(
1740 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1742 return IUnknown_Release(this->outerUnknown);
1745 static HRESULT WINAPI DataCache_Cache(
1747 FORMATETC* pformatetc,
1749 DWORD* pdwConnection)
1755 static HRESULT WINAPI DataCache_Uncache(
1763 static HRESULT WINAPI DataCache_EnumCache(
1765 IEnumSTATDATA** ppenumSTATDATA)
1771 static HRESULT WINAPI DataCache_InitCache(
1773 IDataObject* pDataObject)
1779 static HRESULT WINAPI DataCache_IOleCache2_SetData(
1781 FORMATETC* pformatetc,
1789 static HRESULT WINAPI DataCache_UpdateCache(
1791 LPDATAOBJECT pDataObject,
1799 static HRESULT WINAPI DataCache_DiscardCache(
1801 DWORD dwDiscardOptions)
1808 /*********************************************************
1809 * Method implementation for the IOleCacheControl
1810 * part of the DataCache class.
1813 /************************************************************************
1814 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1816 * See Windows documentation for more details on IUnknown methods.
1818 static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
1819 IOleCacheControl* iface,
1823 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1825 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1828 /************************************************************************
1829 * DataCache_IOleCacheControl_AddRef (IUnknown)
1831 * See Windows documentation for more details on IUnknown methods.
1833 static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
1834 IOleCacheControl* iface)
1836 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1838 return IUnknown_AddRef(this->outerUnknown);
1841 /************************************************************************
1842 * DataCache_IOleCacheControl_Release (IUnknown)
1844 * See Windows documentation for more details on IUnknown methods.
1846 static ULONG WINAPI DataCache_IOleCacheControl_Release(
1847 IOleCacheControl* iface)
1849 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1851 return IUnknown_Release(this->outerUnknown);
1854 static HRESULT WINAPI DataCache_OnRun(
1855 IOleCacheControl* iface,
1856 LPDATAOBJECT pDataObject)
1862 static HRESULT WINAPI DataCache_OnStop(
1863 IOleCacheControl* iface)