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 "debugtools.h"
40 DEFAULT_DEBUG_CHANNEL(ole
)
42 /****************************************************************************
43 * PresentationDataHeader
45 * This structure represents the header of the \002OlePresXXX stream in
46 * the OLE object strorage.
48 * Most fields are still unknown.
50 typedef struct PresentationDataHeader
63 } PresentationDataHeader
;
65 /****************************************************************************
71 * List all interface VTables here
73 ICOM_VTABLE(IDataObject
)* lpvtbl1
;
74 ICOM_VTABLE(IUnknown
)* lpvtbl2
;
75 ICOM_VTABLE(IPersistStorage
)* lpvtbl3
;
76 ICOM_VTABLE(IViewObject2
)* lpvtbl4
;
77 ICOM_VTABLE(IOleCache2
)* lpvtbl5
;
78 ICOM_VTABLE(IOleCacheControl
)* lpvtbl6
;
81 * Reference count of this object
86 * IUnknown implementation of the outer object.
88 IUnknown
* outerUnknown
;
91 * This storage pointer is set through a call to
92 * IPersistStorage_Load. This is where the visual
93 * representation of the object is stored.
95 IStorage
* presentationStorage
;
98 * The user of this object can setup ONE advise sink
99 * connection with the object. These parameters describe
103 DWORD sinkAdviseFlag
;
104 IAdviseSink
* sinkInterface
;
108 typedef struct DataCache DataCache
;
111 * Here, I define utility macros to help with the casting of the
113 * There is a version to accomodate all of the VTables implemented
116 #define _ICOM_THIS_From_IDataObject(class,name) class* this = (class*)name;
117 #define _ICOM_THIS_From_NDIUnknown(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
118 #define _ICOM_THIS_From_IPersistStorage(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
119 #define _ICOM_THIS_From_IViewObject2(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
120 #define _ICOM_THIS_From_IOleCache2(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*));
121 #define _ICOM_THIS_From_IOleCacheControl(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*));
124 * Prototypes for the methods of the DataCache class.
126 static DataCache
* DataCache_Construct(REFCLSID clsid
,
127 LPUNKNOWN pUnkOuter
);
128 static void DataCache_Destroy(DataCache
* ptrToDestroy
);
129 static HRESULT
DataCache_ReadPresentationData(DataCache
* this,
131 PresentationDataHeader
* header
);
132 static HRESULT
DataCache_FindPresStreamName(DataCache
* this,
135 static HMETAFILE
DataCache_ReadPresMetafile(DataCache
* this,
137 static void DataCache_FireOnViewChange(DataCache
* this,
142 * Prototypes for the methods of the DataCache class
143 * that implement non delegating IUnknown methods.
145 static HRESULT WINAPI
DataCache_NDIUnknown_QueryInterface(
149 static ULONG WINAPI
DataCache_NDIUnknown_AddRef(
151 static ULONG WINAPI
DataCache_NDIUnknown_Release(
155 * Prototypes for the methods of the DataCache class
156 * that implement IDataObject methods.
158 static HRESULT WINAPI
DataCache_IDataObject_QueryInterface(
162 static ULONG WINAPI
DataCache_IDataObject_AddRef(
164 static ULONG WINAPI
DataCache_IDataObject_Release(
166 static HRESULT WINAPI
DataCache_GetData(
168 LPFORMATETC pformatetcIn
,
170 static HRESULT WINAPI
DataCache_GetDataHere(
172 LPFORMATETC pformatetc
,
174 static HRESULT WINAPI
DataCache_QueryGetData(
176 LPFORMATETC pformatetc
);
177 static HRESULT WINAPI
DataCache_GetCanonicalFormatEtc(
179 LPFORMATETC pformatectIn
,
180 LPFORMATETC pformatetcOut
);
181 static HRESULT WINAPI
DataCache_IDataObject_SetData(
183 LPFORMATETC pformatetc
,
186 static HRESULT WINAPI
DataCache_EnumFormatEtc(
189 IEnumFORMATETC
** ppenumFormatEtc
);
190 static HRESULT WINAPI
DataCache_DAdvise(
192 FORMATETC
* pformatetc
,
194 IAdviseSink
* pAdvSink
,
195 DWORD
* pdwConnection
);
196 static HRESULT WINAPI
DataCache_DUnadvise(
199 static HRESULT WINAPI
DataCache_EnumDAdvise(
201 IEnumSTATDATA
** ppenumAdvise
);
204 * Prototypes for the methods of the DataCache class
205 * that implement IPersistStorage methods.
207 static HRESULT WINAPI
DataCache_IPersistStorage_QueryInterface(
208 IPersistStorage
* iface
,
211 static ULONG WINAPI
DataCache_IPersistStorage_AddRef(
212 IPersistStorage
* iface
);
213 static ULONG WINAPI
DataCache_IPersistStorage_Release(
214 IPersistStorage
* iface
);
215 static HRESULT WINAPI
DataCache_GetClassID(
216 IPersistStorage
* iface
,
218 static HRESULT WINAPI
DataCache_IsDirty(
219 IPersistStorage
* iface
);
220 static HRESULT WINAPI
DataCache_InitNew(
221 IPersistStorage
* iface
,
223 static HRESULT WINAPI
DataCache_Load(
224 IPersistStorage
* iface
,
226 static HRESULT WINAPI
DataCache_Save(
227 IPersistStorage
* iface
,
230 static HRESULT WINAPI
DataCache_SaveCompleted(
231 IPersistStorage
* iface
,
233 static HRESULT WINAPI
DataCache_HandsOffStorage(
234 IPersistStorage
* iface
);
237 * Prototypes for the methods of the DataCache class
238 * that implement IViewObject2 methods.
240 static HRESULT WINAPI
DataCache_IViewObject2_QueryInterface(
244 static ULONG WINAPI
DataCache_IViewObject2_AddRef(
245 IViewObject2
* iface
);
246 static ULONG WINAPI
DataCache_IViewObject2_Release(
247 IViewObject2
* iface
);
248 static HRESULT WINAPI
DataCache_Draw(
257 LPCRECTL lprcWBounds
,
258 IVO_ContCallback pfnContinue
,
260 static HRESULT WINAPI
DataCache_GetColorSet(
267 LOGPALETTE
** ppColorSet
);
268 static HRESULT WINAPI
DataCache_Freeze(
274 static HRESULT WINAPI
DataCache_Unfreeze(
277 static HRESULT WINAPI
DataCache_SetAdvise(
281 IAdviseSink
* pAdvSink
);
282 static HRESULT WINAPI
DataCache_GetAdvise(
286 IAdviseSink
** ppAdvSink
);
287 static HRESULT WINAPI
DataCache_GetExtent(
295 * Prototypes for the methods of the DataCache class
296 * that implement IOleCache2 methods.
298 static HRESULT WINAPI
DataCache_IOleCache2_QueryInterface(
302 static ULONG WINAPI
DataCache_IOleCache2_AddRef(
304 static ULONG WINAPI
DataCache_IOleCache2_Release(
306 static HRESULT WINAPI
DataCache_Cache(
308 FORMATETC
* pformatetc
,
310 DWORD
* pdwConnection
);
311 static HRESULT WINAPI
DataCache_Uncache(
314 static HRESULT WINAPI
DataCache_EnumCache(
316 IEnumSTATDATA
** ppenumSTATDATA
);
317 static HRESULT WINAPI
DataCache_InitCache(
319 IDataObject
* pDataObject
);
320 static HRESULT WINAPI
DataCache_IOleCache2_SetData(
322 FORMATETC
* pformatetc
,
325 static HRESULT WINAPI
DataCache_UpdateCache(
327 LPDATAOBJECT pDataObject
,
330 static HRESULT WINAPI
DataCache_DiscardCache(
332 DWORD dwDiscardOptions
);
335 * Prototypes for the methods of the DataCache class
336 * that implement IOleCacheControl methods.
338 static HRESULT WINAPI
DataCache_IOleCacheControl_QueryInterface(
339 IOleCacheControl
* iface
,
342 static ULONG WINAPI
DataCache_IOleCacheControl_AddRef(
343 IOleCacheControl
* iface
);
344 static ULONG WINAPI
DataCache_IOleCacheControl_Release(
345 IOleCacheControl
* iface
);
346 static HRESULT WINAPI
DataCache_OnRun(
347 IOleCacheControl
* iface
,
348 LPDATAOBJECT pDataObject
);
349 static HRESULT WINAPI
DataCache_OnStop(
350 IOleCacheControl
* iface
);
353 * Virtual function tables for the DataCache class.
355 static ICOM_VTABLE(IUnknown
) DataCache_NDIUnknown_VTable
=
357 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
358 DataCache_NDIUnknown_QueryInterface
,
359 DataCache_NDIUnknown_AddRef
,
360 DataCache_NDIUnknown_Release
363 static ICOM_VTABLE(IDataObject
) DataCache_IDataObject_VTable
=
365 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
366 DataCache_IDataObject_QueryInterface
,
367 DataCache_IDataObject_AddRef
,
368 DataCache_IDataObject_Release
,
370 DataCache_GetDataHere
,
371 DataCache_QueryGetData
,
372 DataCache_GetCanonicalFormatEtc
,
373 DataCache_IDataObject_SetData
,
374 DataCache_EnumFormatEtc
,
377 DataCache_EnumDAdvise
380 static ICOM_VTABLE(IPersistStorage
) DataCache_IPersistStorage_VTable
=
382 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
383 DataCache_IPersistStorage_QueryInterface
,
384 DataCache_IPersistStorage_AddRef
,
385 DataCache_IPersistStorage_Release
,
386 DataCache_GetClassID
,
391 DataCache_SaveCompleted
,
392 DataCache_HandsOffStorage
395 static ICOM_VTABLE(IViewObject2
) DataCache_IViewObject2_VTable
=
397 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
398 DataCache_IViewObject2_QueryInterface
,
399 DataCache_IViewObject2_AddRef
,
400 DataCache_IViewObject2_Release
,
402 DataCache_GetColorSet
,
410 static ICOM_VTABLE(IOleCache2
) DataCache_IOleCache2_VTable
=
412 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
413 DataCache_IOleCache2_QueryInterface
,
414 DataCache_IOleCache2_AddRef
,
415 DataCache_IOleCache2_Release
,
420 DataCache_IOleCache2_SetData
,
421 DataCache_UpdateCache
,
422 DataCache_DiscardCache
425 static ICOM_VTABLE(IOleCacheControl
) DataCache_IOleCacheControl_VTable
=
427 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
428 DataCache_IOleCacheControl_QueryInterface
,
429 DataCache_IOleCacheControl_AddRef
,
430 DataCache_IOleCacheControl_Release
,
435 /******************************************************************************
436 * CreateDataCache [OLE32.54]
438 HRESULT WINAPI
CreateDataCache(
444 DataCache
* newCache
= NULL
;
449 WINE_StringFromCLSID((LPCLSID
)rclsid
,xclsid
);
450 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
452 TRACE("(%s, %p, %s, %p)\n", xclsid
, pUnkOuter
, xriid
, ppvObj
);
463 * If this cache is constructed for aggregation, make sure
464 * the caller is requesting the IUnknown interface.
465 * This is necessary because it's the only time the non-delegating
466 * IUnknown pointer can be returned to the outside.
468 if ( (pUnkOuter
!=NULL
) &&
469 (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) != 0) )
470 return CLASS_E_NOAGGREGATION
;
473 * Try to construct a new instance of the class.
475 newCache
= DataCache_Construct(rclsid
,
479 return E_OUTOFMEMORY
;
482 * Make sure it supports the interface required by the caller.
484 hr
= IUnknown_QueryInterface((IUnknown
*)&(newCache
->lpvtbl2
), riid
, ppvObj
);
487 * Release the reference obtained in the constructor. If
488 * the QueryInterface was unsuccessful, it will free the class.
490 IUnknown_Release((IUnknown
*)&(newCache
->lpvtbl2
));
495 /*********************************************************
496 * Method implementation for DataCache class.
498 static DataCache
* DataCache_Construct(
502 DataCache
* newObject
= 0;
505 * Allocate space for the object.
507 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache
));
513 * Initialize the virtual function table.
515 newObject
->lpvtbl1
= &DataCache_IDataObject_VTable
;
516 newObject
->lpvtbl2
= &DataCache_NDIUnknown_VTable
;
517 newObject
->lpvtbl3
= &DataCache_IPersistStorage_VTable
;
518 newObject
->lpvtbl4
= &DataCache_IViewObject2_VTable
;
519 newObject
->lpvtbl5
= &DataCache_IOleCache2_VTable
;
520 newObject
->lpvtbl6
= &DataCache_IOleCacheControl_VTable
;
523 * Start with one reference count. The caller of this function
524 * must release the interface pointer when it is done.
529 * Initialize the outer unknown
530 * We don't keep a reference on the outer unknown since, the way
531 * aggregation works, our lifetime is at least as large as it's
535 pUnkOuter
= (IUnknown
*)&(newObject
->lpvtbl2
);
537 newObject
->outerUnknown
= pUnkOuter
;
540 * Initialize the other members of the structure.
542 newObject
->presentationStorage
= NULL
;
543 newObject
->sinkAspects
= 0;
544 newObject
->sinkAdviseFlag
= 0;
545 newObject
->sinkInterface
= 0;
550 static void DataCache_Destroy(
551 DataCache
* ptrToDestroy
)
555 if (ptrToDestroy
->sinkInterface
!= NULL
)
557 IAdviseSink_Release(ptrToDestroy
->sinkInterface
);
558 ptrToDestroy
->sinkInterface
= NULL
;
561 if (ptrToDestroy
->presentationStorage
!= NULL
)
563 IStorage_Release(ptrToDestroy
->presentationStorage
);
564 ptrToDestroy
->presentationStorage
= NULL
;
568 * Free the datacache pointer.
570 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
573 /************************************************************************
574 * DataCache_ReadPresentationData
576 * This method will read information for the requested presentation
577 * into the given structure.
580 * this - Pointer to the DataCache object
581 * drawAspect - The aspect of the object that we wish to draw.
582 * header - The structure containing information about this
583 * aspect of the object.
585 static HRESULT
DataCache_ReadPresentationData(
588 PresentationDataHeader
* header
)
590 IStream
* presStream
= NULL
;
591 OLECHAR streamName
[20];
595 * Get the name for the presentation stream.
597 hres
= DataCache_FindPresStreamName(
606 * Open the stream and read the header.
608 hres
= IStorage_OpenStream(
609 this->presentationStorage
,
612 STGM_READ
| STGM_SHARE_EXCLUSIVE
,
622 sizeof(PresentationDataHeader
),
628 IStream_Release(presStream
);
631 * We don't want to propagate any other error
632 * code than a failure.
640 /************************************************************************
641 * DataCache_FireOnViewChange
643 * This method will fire an OnViewChange notification to the advise
644 * sink registered with the datacache.
646 * See IAdviseSink::OnViewChange for more details.
648 static void DataCache_FireOnViewChange(
653 TRACE("(%p, %lx, %ld)\n", this, aspect
, lindex
);
656 * The sink supplies a filter when it registers
657 * we make sure we only send the notifications when that
660 if ((this->sinkAspects
& aspect
) != 0)
662 if (this->sinkInterface
!= NULL
)
664 IAdviseSink_OnViewChange(this->sinkInterface
,
669 * Some sinks want to be unregistered automatically when
670 * the first notification goes out.
672 if ( (this->sinkAdviseFlag
& ADVF_ONLYONCE
) != 0)
674 IAdviseSink_Release(this->sinkInterface
);
676 this->sinkInterface
= NULL
;
677 this->sinkAspects
= 0;
678 this->sinkAdviseFlag
= 0;
684 /************************************************************************
685 * DataCache_ReadPresentationData
687 * This method will read information for the requested presentation
688 * into the given structure.
691 * this - Pointer to the DataCache object
692 * drawAspect - The aspect of the object that we wish to draw.
693 * header - The structure containing information about this
694 * aspect of the object.
697 * This method only supports the DVASPECT_CONTENT aspect.
699 static HRESULT
DataCache_FindPresStreamName(
704 OLECHAR name
[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
706 if (drawAspect
!=DVASPECT_CONTENT
)
709 memcpy(buffer
, name
, sizeof(name
));
714 /************************************************************************
715 * DataCache_ReadPresentationData
717 * This method will read information for the requested presentation
718 * into the given structure.
721 * this - Pointer to the DataCache object
722 * drawAspect - The aspect of the object that we wish to draw.
725 * This method returns a metafile handle if it is successful.
726 * it will return 0 if not.
728 static HMETAFILE
DataCache_ReadPresMetafile(
732 LARGE_INTEGER offset
;
733 IStream
* presStream
= NULL
;
734 OLECHAR streamName
[20];
738 HMETAFILE newMetafile
= 0;
741 * Get the name for the presentation stream.
743 hres
= DataCache_FindPresStreamName(
752 * Open the stream and read the header.
754 hres
= IStorage_OpenStream(
755 this->presentationStorage
,
758 STGM_READ
| STGM_SHARE_EXCLUSIVE
,
766 * Get the size of the stream.
768 hres
= IStream_Stat(presStream
,
776 offset
.LowPart
= sizeof(PresentationDataHeader
);
785 * Allocate a buffer for the metafile bits.
787 metafileBits
= HeapAlloc(GetProcessHeap(),
789 streamInfo
.cbSize
.LowPart
);
792 * Read the metafile bits.
797 streamInfo
.cbSize
.LowPart
,
801 * Create a metafile with those bits.
805 newMetafile
= SetMetaFileBitsEx(streamInfo
.cbSize
.LowPart
, metafileBits
);
811 HeapFree(GetProcessHeap(), 0, metafileBits
);
812 IStream_Release(presStream
);
820 /*********************************************************
821 * Method implementation for the non delegating IUnknown
822 * part of the DataCache class.
825 /************************************************************************
826 * DataCache_NDIUnknown_QueryInterface (IUnknown)
828 * See Windows documentation for more details on IUnknown methods.
830 * This version of QueryInterface will not delegate it's implementation
831 * to the outer unknown.
833 static HRESULT WINAPI
DataCache_NDIUnknown_QueryInterface(
838 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
841 * Perform a sanity check on the parameters.
843 if ( (this==0) || (ppvObject
==0) )
847 * Initialize the return parameter.
852 * Compare the riid with the interface IDs implemented by this object.
854 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
858 else if (memcmp(&IID_IDataObject
, riid
, sizeof(IID_IDataObject
)) == 0)
860 *ppvObject
= (IDataObject
*)&(this->lpvtbl1
);
862 else if ( (memcmp(&IID_IPersistStorage
, riid
, sizeof(IID_IPersistStorage
)) == 0) ||
863 (memcmp(&IID_IPersist
, riid
, sizeof(IID_IPersist
)) == 0) )
865 *ppvObject
= (IPersistStorage
*)&(this->lpvtbl3
);
867 else if ( (memcmp(&IID_IViewObject
, riid
, sizeof(IID_IViewObject
)) == 0) ||
868 (memcmp(&IID_IViewObject2
, riid
, sizeof(IID_IViewObject2
)) == 0) )
870 *ppvObject
= (IViewObject2
*)&(this->lpvtbl4
);
872 else if ( (memcmp(&IID_IOleCache
, riid
, sizeof(IID_IOleCache
)) == 0) ||
873 (memcmp(&IID_IOleCache2
, riid
, sizeof(IID_IOleCache2
)) == 0) )
875 *ppvObject
= (IOleCache2
*)&(this->lpvtbl5
);
877 else if (memcmp(&IID_IOleCacheControl
, riid
, sizeof(IID_IOleCacheControl
)) == 0)
879 *ppvObject
= (IOleCacheControl
*)&(this->lpvtbl6
);
883 * Check that we obtained an interface.
889 WINE_StringFromCLSID((LPCLSID
)riid
,clsid
);
892 "() : asking for un supported interface %s\n",
895 return E_NOINTERFACE
;
899 * Query Interface always increases the reference count by one when it is
902 IUnknown_AddRef((IUnknown
*)*ppvObject
);
907 /************************************************************************
908 * DataCache_NDIUnknown_AddRef (IUnknown)
910 * See Windows documentation for more details on IUnknown methods.
912 * This version of QueryInterface will not delegate it's implementation
913 * to the outer unknown.
915 static ULONG WINAPI
DataCache_NDIUnknown_AddRef(
918 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
925 /************************************************************************
926 * DataCache_NDIUnknown_Release (IUnknown)
928 * See Windows documentation for more details on IUnknown methods.
930 * This version of QueryInterface will not delegate it's implementation
931 * to the outer unknown.
933 static ULONG WINAPI
DataCache_NDIUnknown_Release(
936 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
939 * Decrease the reference count on this object.
944 * If the reference count goes down to 0, perform suicide.
948 DataCache_Destroy(this);
956 /*********************************************************
957 * Method implementation for the IDataObject
958 * part of the DataCache class.
961 /************************************************************************
962 * DataCache_IDataObject_QueryInterface (IUnknown)
964 * See Windows documentation for more details on IUnknown methods.
966 static HRESULT WINAPI
DataCache_IDataObject_QueryInterface(
971 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
973 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
976 /************************************************************************
977 * DataCache_IDataObject_AddRef (IUnknown)
979 * See Windows documentation for more details on IUnknown methods.
981 static ULONG WINAPI
DataCache_IDataObject_AddRef(
984 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
986 return IUnknown_AddRef(this->outerUnknown
);
989 /************************************************************************
990 * DataCache_IDataObject_Release (IUnknown)
992 * See Windows documentation for more details on IUnknown methods.
994 static ULONG WINAPI
DataCache_IDataObject_Release(
997 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
999 return IUnknown_Release(this->outerUnknown
);
1002 static HRESULT WINAPI
DataCache_GetData(
1004 LPFORMATETC pformatetcIn
,
1011 static HRESULT WINAPI
DataCache_GetDataHere(
1013 LPFORMATETC pformatetc
,
1020 static HRESULT WINAPI
DataCache_QueryGetData(
1022 LPFORMATETC pformatetc
)
1028 /************************************************************************
1029 * DataCache_EnumFormatEtc (IDataObject)
1031 * The data cache doesn't implement this method.
1033 * See Windows documentation for more details on IDataObject methods.
1035 static HRESULT WINAPI
DataCache_GetCanonicalFormatEtc(
1037 LPFORMATETC pformatectIn
,
1038 LPFORMATETC pformatetcOut
)
1044 /************************************************************************
1045 * DataCache_IDataObject_SetData (IDataObject)
1047 * This method is delegated to the IOleCache2 implementation.
1049 * See Windows documentation for more details on IDataObject methods.
1051 static HRESULT WINAPI
DataCache_IDataObject_SetData(
1053 LPFORMATETC pformatetc
,
1057 IOleCache2
* oleCache
= NULL
;
1060 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1062 hres
= IDataObject_QueryInterface(iface
, &IID_IOleCache2
, (void**)&oleCache
);
1065 return E_UNEXPECTED
;
1067 hres
= IOleCache2_SetData(oleCache
, pformatetc
, pmedium
, fRelease
);
1069 IOleCache2_Release(oleCache
);
1074 /************************************************************************
1075 * DataCache_EnumFormatEtc (IDataObject)
1077 * The data cache doesn't implement this method.
1079 * See Windows documentation for more details on IDataObject methods.
1081 static HRESULT WINAPI
DataCache_EnumFormatEtc(
1084 IEnumFORMATETC
** ppenumFormatEtc
)
1090 /************************************************************************
1091 * DataCache_DAdvise (IDataObject)
1093 * The data cache doesn't support connections.
1095 * See Windows documentation for more details on IDataObject methods.
1097 static HRESULT WINAPI
DataCache_DAdvise(
1099 FORMATETC
* pformatetc
,
1101 IAdviseSink
* pAdvSink
,
1102 DWORD
* pdwConnection
)
1105 return OLE_E_ADVISENOTSUPPORTED
;
1108 /************************************************************************
1109 * DataCache_DUnadvise (IDataObject)
1111 * The data cache doesn't support connections.
1113 * See Windows documentation for more details on IDataObject methods.
1115 static HRESULT WINAPI
DataCache_DUnadvise(
1120 return OLE_E_NOCONNECTION
;
1123 /************************************************************************
1124 * DataCache_EnumDAdvise (IDataObject)
1126 * The data cache doesn't support connections.
1128 * See Windows documentation for more details on IDataObject methods.
1130 static HRESULT WINAPI
DataCache_EnumDAdvise(
1132 IEnumSTATDATA
** ppenumAdvise
)
1135 return OLE_E_ADVISENOTSUPPORTED
;
1138 /*********************************************************
1139 * Method implementation for the IDataObject
1140 * part of the DataCache class.
1143 /************************************************************************
1144 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1146 * See Windows documentation for more details on IUnknown methods.
1148 static HRESULT WINAPI
DataCache_IPersistStorage_QueryInterface(
1149 IPersistStorage
* iface
,
1153 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1155 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1158 /************************************************************************
1159 * DataCache_IPersistStorage_AddRef (IUnknown)
1161 * See Windows documentation for more details on IUnknown methods.
1163 static ULONG WINAPI
DataCache_IPersistStorage_AddRef(
1164 IPersistStorage
* iface
)
1166 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1168 return IUnknown_AddRef(this->outerUnknown
);
1171 /************************************************************************
1172 * DataCache_IPersistStorage_Release (IUnknown)
1174 * See Windows documentation for more details on IUnknown methods.
1176 static ULONG WINAPI
DataCache_IPersistStorage_Release(
1177 IPersistStorage
* iface
)
1179 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1181 return IUnknown_Release(this->outerUnknown
);
1184 /************************************************************************
1185 * DataCache_GetClassID (IPersistStorage)
1187 * The data cache doesn't implement this method.
1189 * See Windows documentation for more details on IPersistStorage methods.
1191 static HRESULT WINAPI
DataCache_GetClassID(
1192 IPersistStorage
* iface
,
1195 TRACE("(%p, %p)\n", iface
, pClassID
);
1199 /************************************************************************
1200 * DataCache_IsDirty (IPersistStorage)
1202 * Until we actully connect to a running object and retrieve new
1203 * information to it, we never get dirty.
1205 * See Windows documentation for more details on IPersistStorage methods.
1207 static HRESULT WINAPI
DataCache_IsDirty(
1208 IPersistStorage
* iface
)
1210 TRACE("(%p)\n", iface
);
1215 /************************************************************************
1216 * DataCache_InitNew (IPersistStorage)
1218 * The data cache implementation of IPersistStorage_InitNew simply stores
1219 * the storage pointer.
1221 * See Windows documentation for more details on IPersistStorage methods.
1223 static HRESULT WINAPI
DataCache_InitNew(
1224 IPersistStorage
* iface
,
1227 TRACE("(%p, %p)\n", iface
, pStg
);
1229 return DataCache_Load(iface
, pStg
);
1232 /************************************************************************
1233 * DataCache_Load (IPersistStorage)
1235 * The data cache implementation of IPersistStorage_Load doesn't
1236 * actually load anything. Instead, it holds on to the storage pointer
1237 * and it will load the presentation information when the
1238 * IDataObject_GetData or IViewObject2_Draw methods are called.
1240 * See Windows documentation for more details on IPersistStorage methods.
1242 static HRESULT WINAPI
DataCache_Load(
1243 IPersistStorage
* iface
,
1246 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1248 TRACE("(%p, %p)\n", iface
, pStg
);
1250 if (this->presentationStorage
!= NULL
)
1252 IStorage_Release(this->presentationStorage
);
1255 this->presentationStorage
= pStg
;
1257 if (this->presentationStorage
!= NULL
)
1259 IStorage_AddRef(this->presentationStorage
);
1265 /************************************************************************
1266 * DataCache_Save (IPersistStorage)
1268 * Until we actully connect to a running object and retrieve new
1269 * information to it, we never have to save anything. However, it is
1270 * our responsability to copy the information when saving to a new
1273 * See Windows documentation for more details on IPersistStorage methods.
1275 static HRESULT WINAPI
DataCache_Save(
1276 IPersistStorage
* iface
,
1280 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1282 TRACE("(%p, %p, %d)\n", iface
, pStg
, fSameAsLoad
);
1284 if ( (!fSameAsLoad
) &&
1285 (this->presentationStorage
!=NULL
) )
1287 return IStorage_CopyTo(this->presentationStorage
,
1297 /************************************************************************
1298 * DataCache_SaveCompleted (IPersistStorage)
1300 * This method is called to tell the cache to release the storage
1301 * pointer it's currentlu holding.
1303 * See Windows documentation for more details on IPersistStorage methods.
1305 static HRESULT WINAPI
DataCache_SaveCompleted(
1306 IPersistStorage
* iface
,
1309 TRACE("(%p, %p)\n", iface
, pStgNew
);
1312 * First, make sure we get our hands off any storage we have.
1314 DataCache_HandsOffStorage(iface
);
1317 * Then, attach to the new storage.
1319 DataCache_Load(iface
, pStgNew
);
1324 /************************************************************************
1325 * DataCache_HandsOffStorage (IPersistStorage)
1327 * This method is called to tell the cache to release the storage
1328 * pointer it's currentlu holding.
1330 * See Windows documentation for more details on IPersistStorage methods.
1332 static HRESULT WINAPI
DataCache_HandsOffStorage(
1333 IPersistStorage
* iface
)
1335 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1337 TRACE("(%p)\n", iface
);
1339 if (this->presentationStorage
!= NULL
)
1341 IStorage_Release(this->presentationStorage
);
1342 this->presentationStorage
= NULL
;
1348 /*********************************************************
1349 * Method implementation for the IViewObject2
1350 * part of the DataCache class.
1353 /************************************************************************
1354 * DataCache_IViewObject2_QueryInterface (IUnknown)
1356 * See Windows documentation for more details on IUnknown methods.
1358 static HRESULT WINAPI
DataCache_IViewObject2_QueryInterface(
1359 IViewObject2
* iface
,
1363 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1365 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1368 /************************************************************************
1369 * DataCache_IViewObject2_AddRef (IUnknown)
1371 * See Windows documentation for more details on IUnknown methods.
1373 static ULONG WINAPI
DataCache_IViewObject2_AddRef(
1374 IViewObject2
* iface
)
1376 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1378 return IUnknown_AddRef(this->outerUnknown
);
1381 /************************************************************************
1382 * DataCache_IViewObject2_Release (IUnknown)
1384 * See Windows documentation for more details on IUnknown methods.
1386 static ULONG WINAPI
DataCache_IViewObject2_Release(
1387 IViewObject2
* iface
)
1389 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1391 return IUnknown_Release(this->outerUnknown
);
1394 /************************************************************************
1395 * DataCache_Draw (IViewObject2)
1397 * This method will draw the cached representation of the object
1398 * to the given device context.
1400 * See Windows documentation for more details on IViewObject2 methods.
1402 static HRESULT WINAPI
DataCache_Draw(
1403 IViewObject2
* iface
,
1407 DVTARGETDEVICE
* ptd
,
1410 LPCRECTL lprcBounds
,
1411 LPCRECTL lprcWBounds
,
1412 IVO_ContCallback pfnContinue
,
1415 PresentationDataHeader presData
;
1416 HMETAFILE presMetafile
= 0;
1419 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1421 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1436 if (lprcBounds
==NULL
)
1437 return E_INVALIDARG
;
1440 * First, we need to retrieve the dimensions of the
1441 * image in the metafile.
1443 hres
= DataCache_ReadPresentationData(this,
1451 * Then, we can extract the metafile itself from the cached
1454 presMetafile
= DataCache_ReadPresMetafile(this,
1458 * If we have a metafile, just draw baby...
1459 * We have to be careful not to modify the state of the
1462 if (presMetafile
!=0)
1464 INT prevMapMode
= SetMapMode(hdcDraw
, MM_ANISOTROPIC
);
1466 SIZE oldViewportExt
;
1467 POINT oldViewportOrg
;
1469 SetWindowExtEx(hdcDraw
,
1470 presData
.objectExtentX
,
1471 presData
.objectExtentY
,
1474 SetViewportExtEx(hdcDraw
,
1475 lprcBounds
->right
- lprcBounds
->left
,
1476 lprcBounds
->bottom
- lprcBounds
->top
,
1479 SetViewportOrgEx(hdcDraw
,
1484 PlayMetaFile(hdcDraw
, presMetafile
);
1486 SetWindowExtEx(hdcDraw
,
1491 SetViewportExtEx(hdcDraw
,
1496 SetViewportOrgEx(hdcDraw
,
1501 SetMapMode(hdcDraw
, prevMapMode
);
1503 DeleteMetaFile(presMetafile
);
1509 static HRESULT WINAPI
DataCache_GetColorSet(
1510 IViewObject2
* iface
,
1514 DVTARGETDEVICE
* ptd
,
1515 HDC hicTargetDevice
,
1516 LOGPALETTE
** ppColorSet
)
1522 static HRESULT WINAPI
DataCache_Freeze(
1523 IViewObject2
* iface
,
1533 static HRESULT WINAPI
DataCache_Unfreeze(
1534 IViewObject2
* iface
,
1541 /************************************************************************
1542 * DataCache_SetAdvise (IViewObject2)
1544 * This sets-up an advisory sink with the data cache. When the object's
1545 * view changes, this sink is called.
1547 * See Windows documentation for more details on IViewObject2 methods.
1549 static HRESULT WINAPI
DataCache_SetAdvise(
1550 IViewObject2
* iface
,
1553 IAdviseSink
* pAdvSink
)
1555 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1557 TRACE("(%p, %lx, %lx, %p)\n", iface
, aspects
, advf
, pAdvSink
);
1560 * A call to this function removes the previous sink
1562 if (this->sinkInterface
!= NULL
)
1564 IAdviseSink_Release(this->sinkInterface
);
1565 this->sinkInterface
= NULL
;
1566 this->sinkAspects
= 0;
1567 this->sinkAdviseFlag
= 0;
1571 * Now, setup the new one.
1575 this->sinkInterface
= pAdvSink
;
1576 this->sinkAspects
= aspects
;
1577 this->sinkAdviseFlag
= advf
;
1579 IAdviseSink_AddRef(this->sinkInterface
);
1583 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1586 if (advf
& ADVF_PRIMEFIRST
)
1588 DataCache_FireOnViewChange(this,
1596 /************************************************************************
1597 * DataCache_GetAdvise (IViewObject2)
1599 * This method queries the current state of the advise sink
1600 * installed on the data cache.
1602 * See Windows documentation for more details on IViewObject2 methods.
1604 static HRESULT WINAPI
DataCache_GetAdvise(
1605 IViewObject2
* iface
,
1608 IAdviseSink
** ppAdvSink
)
1610 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1612 TRACE("(%p, %p, %p, %p)\n", iface
, pAspects
, pAdvf
, ppAdvSink
);
1615 * Just copy all the requested values.
1618 *pAspects
= this->sinkAspects
;
1621 *pAdvf
= this->sinkAdviseFlag
;
1623 if (ppAdvSink
!=NULL
)
1625 IAdviseSink_QueryInterface(this->sinkInterface
,
1633 /************************************************************************
1634 * DataCache_GetExtent (IViewObject2)
1636 * This method retrieves the "natural" size of this cached object.
1638 * See Windows documentation for more details on IViewObject2 methods.
1640 static HRESULT WINAPI
DataCache_GetExtent(
1641 IViewObject2
* iface
,
1644 DVTARGETDEVICE
* ptd
,
1647 PresentationDataHeader presData
;
1648 HRESULT hres
= E_FAIL
;
1650 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1652 TRACE("(%p, %lx, %ld, %p, %p)\n",
1653 iface
, dwDrawAspect
, lindex
, ptd
, lpsizel
);
1662 * Initialize the out parameter.
1668 * This flag should be set to -1.
1671 FIXME("Unimplemented flag lindex = %ld\n", lindex
);
1674 * Right now, we suport only the callback from
1675 * the default handler.
1678 FIXME("Unimplemented ptd = %p\n", ptd
);
1681 * Get the presentation information from the
1684 hres
= DataCache_ReadPresentationData(this,
1688 if (SUCCEEDED(hres
))
1690 lpsizel
->cx
= presData
.objectExtentX
;
1691 lpsizel
->cy
= presData
.objectExtentY
;
1695 * This method returns OLE_E_BLANK when it fails.
1704 /*********************************************************
1705 * Method implementation for the IOleCache2
1706 * part of the DataCache class.
1709 /************************************************************************
1710 * DataCache_IOleCache2_QueryInterface (IUnknown)
1712 * See Windows documentation for more details on IUnknown methods.
1714 static HRESULT WINAPI
DataCache_IOleCache2_QueryInterface(
1719 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1721 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1724 /************************************************************************
1725 * DataCache_IOleCache2_AddRef (IUnknown)
1727 * See Windows documentation for more details on IUnknown methods.
1729 static ULONG WINAPI
DataCache_IOleCache2_AddRef(
1732 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1734 return IUnknown_AddRef(this->outerUnknown
);
1737 /************************************************************************
1738 * DataCache_IOleCache2_Release (IUnknown)
1740 * See Windows documentation for more details on IUnknown methods.
1742 static ULONG WINAPI
DataCache_IOleCache2_Release(
1745 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1747 return IUnknown_Release(this->outerUnknown
);
1750 static HRESULT WINAPI
DataCache_Cache(
1752 FORMATETC
* pformatetc
,
1754 DWORD
* pdwConnection
)
1760 static HRESULT WINAPI
DataCache_Uncache(
1768 static HRESULT WINAPI
DataCache_EnumCache(
1770 IEnumSTATDATA
** ppenumSTATDATA
)
1776 static HRESULT WINAPI
DataCache_InitCache(
1778 IDataObject
* pDataObject
)
1784 static HRESULT WINAPI
DataCache_IOleCache2_SetData(
1786 FORMATETC
* pformatetc
,
1794 static HRESULT WINAPI
DataCache_UpdateCache(
1796 LPDATAOBJECT pDataObject
,
1804 static HRESULT WINAPI
DataCache_DiscardCache(
1806 DWORD dwDiscardOptions
)
1813 /*********************************************************
1814 * Method implementation for the IOleCacheControl
1815 * part of the DataCache class.
1818 /************************************************************************
1819 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1821 * See Windows documentation for more details on IUnknown methods.
1823 static HRESULT WINAPI
DataCache_IOleCacheControl_QueryInterface(
1824 IOleCacheControl
* iface
,
1828 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1830 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1833 /************************************************************************
1834 * DataCache_IOleCacheControl_AddRef (IUnknown)
1836 * See Windows documentation for more details on IUnknown methods.
1838 static ULONG WINAPI
DataCache_IOleCacheControl_AddRef(
1839 IOleCacheControl
* iface
)
1841 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1843 return IUnknown_AddRef(this->outerUnknown
);
1846 /************************************************************************
1847 * DataCache_IOleCacheControl_Release (IUnknown)
1849 * See Windows documentation for more details on IUnknown methods.
1851 static ULONG WINAPI
DataCache_IOleCacheControl_Release(
1852 IOleCacheControl
* iface
)
1854 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1856 return IUnknown_Release(this->outerUnknown
);
1859 static HRESULT WINAPI
DataCache_OnRun(
1860 IOleCacheControl
* iface
,
1861 LPDATAOBJECT pDataObject
)
1867 static HRESULT WINAPI
DataCache_OnStop(
1868 IOleCacheControl
* iface
)