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
;
450 WINE_StringFromCLSID((LPCLSID
)rclsid
,xclsid
);
451 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
453 TRACE("(%s, %p, %s, %p)\n", xclsid
, pUnkOuter
, xriid
, ppvObj
);
464 * If this cache is constructed for aggregation, make sure
465 * the caller is requesting the IUnknown interface.
466 * This is necessary because it's the only time the non-delegating
467 * IUnknown pointer can be returned to the outside.
469 if ( (pUnkOuter
!=NULL
) &&
470 (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) != 0) )
471 return CLASS_E_NOAGGREGATION
;
474 * Try to construct a new instance of the class.
476 newCache
= DataCache_Construct(rclsid
,
480 return E_OUTOFMEMORY
;
483 * Make sure it supports the interface required by the caller.
485 hr
= IUnknown_QueryInterface((IUnknown
*)&(newCache
->lpvtbl2
), riid
, ppvObj
);
488 * Release the reference obtained in the constructor. If
489 * the QueryInterface was unsuccessful, it will free the class.
491 IUnknown_Release((IUnknown
*)&(newCache
->lpvtbl2
));
496 /*********************************************************
497 * Method implementation for DataCache class.
499 static DataCache
* DataCache_Construct(
503 DataCache
* newObject
= 0;
506 * Allocate space for the object.
508 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache
));
514 * Initialize the virtual function table.
516 newObject
->lpvtbl1
= &DataCache_IDataObject_VTable
;
517 newObject
->lpvtbl2
= &DataCache_NDIUnknown_VTable
;
518 newObject
->lpvtbl3
= &DataCache_IPersistStorage_VTable
;
519 newObject
->lpvtbl4
= &DataCache_IViewObject2_VTable
;
520 newObject
->lpvtbl5
= &DataCache_IOleCache2_VTable
;
521 newObject
->lpvtbl6
= &DataCache_IOleCacheControl_VTable
;
524 * Start with one reference count. The caller of this function
525 * must release the interface pointer when it is done.
530 * Initialize the outer unknown
531 * We don't keep a reference on the outer unknown since, the way
532 * aggregation works, our lifetime is at least as large as it's
536 pUnkOuter
= (IUnknown
*)&(newObject
->lpvtbl2
);
538 newObject
->outerUnknown
= pUnkOuter
;
541 * Initialize the other members of the structure.
543 newObject
->presentationStorage
= NULL
;
544 newObject
->sinkAspects
= 0;
545 newObject
->sinkAdviseFlag
= 0;
546 newObject
->sinkInterface
= 0;
551 static void DataCache_Destroy(
552 DataCache
* ptrToDestroy
)
556 if (ptrToDestroy
->sinkInterface
!= NULL
)
558 IAdviseSink_Release(ptrToDestroy
->sinkInterface
);
559 ptrToDestroy
->sinkInterface
= NULL
;
562 if (ptrToDestroy
->presentationStorage
!= NULL
)
564 IStorage_Release(ptrToDestroy
->presentationStorage
);
565 ptrToDestroy
->presentationStorage
= NULL
;
569 * Free the datacache pointer.
571 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
574 /************************************************************************
575 * DataCache_ReadPresentationData
577 * This method will read information for the requested presentation
578 * into the given structure.
581 * this - Pointer to the DataCache object
582 * drawAspect - The aspect of the object that we wish to draw.
583 * header - The structure containing information about this
584 * aspect of the object.
586 static HRESULT
DataCache_ReadPresentationData(
589 PresentationDataHeader
* header
)
591 IStream
* presStream
= NULL
;
592 OLECHAR streamName
[20];
596 * Get the name for the presentation stream.
598 hres
= DataCache_FindPresStreamName(
607 * Open the stream and read the header.
609 hres
= IStorage_OpenStream(
610 this->presentationStorage
,
613 STGM_READ
| STGM_SHARE_EXCLUSIVE
,
623 sizeof(PresentationDataHeader
),
629 IStream_Release(presStream
);
632 * We don't want to propagate any other error
633 * code than a failure.
641 /************************************************************************
642 * DataCache_FireOnViewChange
644 * This method will fire an OnViewChange notification to the advise
645 * sink registered with the datacache.
647 * See IAdviseSink::OnViewChange for more details.
649 static void DataCache_FireOnViewChange(
654 TRACE("(%p, %lx, %ld)\n", this, aspect
, lindex
);
657 * The sink supplies a filter when it registers
658 * we make sure we only send the notifications when that
661 if ((this->sinkAspects
& aspect
) != 0)
663 if (this->sinkInterface
!= NULL
)
665 IAdviseSink_OnViewChange(this->sinkInterface
,
670 * Some sinks want to be unregistered automatically when
671 * the first notification goes out.
673 if ( (this->sinkAdviseFlag
& ADVF_ONLYONCE
) != 0)
675 IAdviseSink_Release(this->sinkInterface
);
677 this->sinkInterface
= NULL
;
678 this->sinkAspects
= 0;
679 this->sinkAdviseFlag
= 0;
685 /************************************************************************
686 * DataCache_ReadPresentationData
688 * This method will read information for the requested presentation
689 * into the given structure.
692 * this - Pointer to the DataCache object
693 * drawAspect - The aspect of the object that we wish to draw.
694 * header - The structure containing information about this
695 * aspect of the object.
698 * This method only supports the DVASPECT_CONTENT aspect.
700 static HRESULT
DataCache_FindPresStreamName(
705 OLECHAR name
[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
707 if (drawAspect
!=DVASPECT_CONTENT
)
710 memcpy(buffer
, name
, sizeof(name
));
715 /************************************************************************
716 * DataCache_ReadPresentationData
718 * This method will read information for the requested presentation
719 * into the given structure.
722 * this - Pointer to the DataCache object
723 * drawAspect - The aspect of the object that we wish to draw.
726 * This method returns a metafile handle if it is successful.
727 * it will return 0 if not.
729 static HMETAFILE
DataCache_ReadPresMetafile(
733 LARGE_INTEGER offset
;
734 IStream
* presStream
= NULL
;
735 OLECHAR streamName
[20];
739 HMETAFILE newMetafile
= 0;
742 * Get the name for the presentation stream.
744 hres
= DataCache_FindPresStreamName(
753 * Open the stream and read the header.
755 hres
= IStorage_OpenStream(
756 this->presentationStorage
,
759 STGM_READ
| STGM_SHARE_EXCLUSIVE
,
767 * Get the size of the stream.
769 hres
= IStream_Stat(presStream
,
777 offset
.LowPart
= sizeof(PresentationDataHeader
);
786 * Allocate a buffer for the metafile bits.
788 metafileBits
= HeapAlloc(GetProcessHeap(),
790 streamInfo
.cbSize
.LowPart
);
793 * Read the metafile bits.
798 streamInfo
.cbSize
.LowPart
,
802 * Create a metafile with those bits.
806 newMetafile
= SetMetaFileBitsEx(streamInfo
.cbSize
.LowPart
, metafileBits
);
812 HeapFree(GetProcessHeap(), 0, metafileBits
);
813 IStream_Release(presStream
);
821 /*********************************************************
822 * Method implementation for the non delegating IUnknown
823 * part of the DataCache class.
826 /************************************************************************
827 * DataCache_NDIUnknown_QueryInterface (IUnknown)
829 * See Windows documentation for more details on IUnknown methods.
831 * This version of QueryInterface will not delegate it's implementation
832 * to the outer unknown.
834 static HRESULT WINAPI
DataCache_NDIUnknown_QueryInterface(
839 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
842 * Perform a sanity check on the parameters.
844 if ( (this==0) || (ppvObject
==0) )
848 * Initialize the return parameter.
853 * Compare the riid with the interface IDs implemented by this object.
855 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
859 else if (memcmp(&IID_IDataObject
, riid
, sizeof(IID_IDataObject
)) == 0)
861 *ppvObject
= (IDataObject
*)&(this->lpvtbl1
);
863 else if ( (memcmp(&IID_IPersistStorage
, riid
, sizeof(IID_IPersistStorage
)) == 0) ||
864 (memcmp(&IID_IPersist
, riid
, sizeof(IID_IPersist
)) == 0) )
866 *ppvObject
= (IPersistStorage
*)&(this->lpvtbl3
);
868 else if ( (memcmp(&IID_IViewObject
, riid
, sizeof(IID_IViewObject
)) == 0) ||
869 (memcmp(&IID_IViewObject2
, riid
, sizeof(IID_IViewObject2
)) == 0) )
871 *ppvObject
= (IViewObject2
*)&(this->lpvtbl4
);
873 else if ( (memcmp(&IID_IOleCache
, riid
, sizeof(IID_IOleCache
)) == 0) ||
874 (memcmp(&IID_IOleCache2
, riid
, sizeof(IID_IOleCache2
)) == 0) )
876 *ppvObject
= (IOleCache2
*)&(this->lpvtbl5
);
878 else if (memcmp(&IID_IOleCacheControl
, riid
, sizeof(IID_IOleCacheControl
)) == 0)
880 *ppvObject
= (IOleCacheControl
*)&(this->lpvtbl6
);
884 * Check that we obtained an interface.
890 WINE_StringFromCLSID((LPCLSID
)riid
,clsid
);
893 "() : asking for un supported interface %s\n",
896 return E_NOINTERFACE
;
900 * Query Interface always increases the reference count by one when it is
903 IUnknown_AddRef((IUnknown
*)*ppvObject
);
908 /************************************************************************
909 * DataCache_NDIUnknown_AddRef (IUnknown)
911 * See Windows documentation for more details on IUnknown methods.
913 * This version of QueryInterface will not delegate it's implementation
914 * to the outer unknown.
916 static ULONG WINAPI
DataCache_NDIUnknown_AddRef(
919 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
926 /************************************************************************
927 * DataCache_NDIUnknown_Release (IUnknown)
929 * See Windows documentation for more details on IUnknown methods.
931 * This version of QueryInterface will not delegate it's implementation
932 * to the outer unknown.
934 static ULONG WINAPI
DataCache_NDIUnknown_Release(
937 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
940 * Decrease the reference count on this object.
945 * If the reference count goes down to 0, perform suicide.
949 DataCache_Destroy(this);
957 /*********************************************************
958 * Method implementation for the IDataObject
959 * part of the DataCache class.
962 /************************************************************************
963 * DataCache_IDataObject_QueryInterface (IUnknown)
965 * See Windows documentation for more details on IUnknown methods.
967 static HRESULT WINAPI
DataCache_IDataObject_QueryInterface(
972 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
974 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
977 /************************************************************************
978 * DataCache_IDataObject_AddRef (IUnknown)
980 * See Windows documentation for more details on IUnknown methods.
982 static ULONG WINAPI
DataCache_IDataObject_AddRef(
985 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
987 return IUnknown_AddRef(this->outerUnknown
);
990 /************************************************************************
991 * DataCache_IDataObject_Release (IUnknown)
993 * See Windows documentation for more details on IUnknown methods.
995 static ULONG WINAPI
DataCache_IDataObject_Release(
998 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
1000 return IUnknown_Release(this->outerUnknown
);
1003 static HRESULT WINAPI
DataCache_GetData(
1005 LPFORMATETC pformatetcIn
,
1012 static HRESULT WINAPI
DataCache_GetDataHere(
1014 LPFORMATETC pformatetc
,
1021 static HRESULT WINAPI
DataCache_QueryGetData(
1023 LPFORMATETC pformatetc
)
1029 /************************************************************************
1030 * DataCache_EnumFormatEtc (IDataObject)
1032 * The data cache doesn't implement this method.
1034 * See Windows documentation for more details on IDataObject methods.
1036 static HRESULT WINAPI
DataCache_GetCanonicalFormatEtc(
1038 LPFORMATETC pformatectIn
,
1039 LPFORMATETC pformatetcOut
)
1045 /************************************************************************
1046 * DataCache_IDataObject_SetData (IDataObject)
1048 * This method is delegated to the IOleCache2 implementation.
1050 * See Windows documentation for more details on IDataObject methods.
1052 static HRESULT WINAPI
DataCache_IDataObject_SetData(
1054 LPFORMATETC pformatetc
,
1058 IOleCache2
* oleCache
= NULL
;
1061 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1063 hres
= IDataObject_QueryInterface(iface
, &IID_IOleCache2
, (void**)&oleCache
);
1066 return E_UNEXPECTED
;
1068 hres
= IOleCache2_SetData(oleCache
, pformatetc
, pmedium
, fRelease
);
1070 IOleCache2_Release(oleCache
);
1075 /************************************************************************
1076 * DataCache_EnumFormatEtc (IDataObject)
1078 * The data cache doesn't implement this method.
1080 * See Windows documentation for more details on IDataObject methods.
1082 static HRESULT WINAPI
DataCache_EnumFormatEtc(
1085 IEnumFORMATETC
** ppenumFormatEtc
)
1091 /************************************************************************
1092 * DataCache_DAdvise (IDataObject)
1094 * The data cache doesn't support connections.
1096 * See Windows documentation for more details on IDataObject methods.
1098 static HRESULT WINAPI
DataCache_DAdvise(
1100 FORMATETC
* pformatetc
,
1102 IAdviseSink
* pAdvSink
,
1103 DWORD
* pdwConnection
)
1106 return OLE_E_ADVISENOTSUPPORTED
;
1109 /************************************************************************
1110 * DataCache_DUnadvise (IDataObject)
1112 * The data cache doesn't support connections.
1114 * See Windows documentation for more details on IDataObject methods.
1116 static HRESULT WINAPI
DataCache_DUnadvise(
1121 return OLE_E_NOCONNECTION
;
1124 /************************************************************************
1125 * DataCache_EnumDAdvise (IDataObject)
1127 * The data cache doesn't support connections.
1129 * See Windows documentation for more details on IDataObject methods.
1131 static HRESULT WINAPI
DataCache_EnumDAdvise(
1133 IEnumSTATDATA
** ppenumAdvise
)
1136 return OLE_E_ADVISENOTSUPPORTED
;
1139 /*********************************************************
1140 * Method implementation for the IDataObject
1141 * part of the DataCache class.
1144 /************************************************************************
1145 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1147 * See Windows documentation for more details on IUnknown methods.
1149 static HRESULT WINAPI
DataCache_IPersistStorage_QueryInterface(
1150 IPersistStorage
* iface
,
1154 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1156 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1159 /************************************************************************
1160 * DataCache_IPersistStorage_AddRef (IUnknown)
1162 * See Windows documentation for more details on IUnknown methods.
1164 static ULONG WINAPI
DataCache_IPersistStorage_AddRef(
1165 IPersistStorage
* iface
)
1167 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1169 return IUnknown_AddRef(this->outerUnknown
);
1172 /************************************************************************
1173 * DataCache_IPersistStorage_Release (IUnknown)
1175 * See Windows documentation for more details on IUnknown methods.
1177 static ULONG WINAPI
DataCache_IPersistStorage_Release(
1178 IPersistStorage
* iface
)
1180 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1182 return IUnknown_Release(this->outerUnknown
);
1185 /************************************************************************
1186 * DataCache_GetClassID (IPersistStorage)
1188 * The data cache doesn't implement this method.
1190 * See Windows documentation for more details on IPersistStorage methods.
1192 static HRESULT WINAPI
DataCache_GetClassID(
1193 IPersistStorage
* iface
,
1196 TRACE("(%p, %p)\n", iface
, pClassID
);
1200 /************************************************************************
1201 * DataCache_IsDirty (IPersistStorage)
1203 * Until we actully connect to a running object and retrieve new
1204 * information to it, we never get dirty.
1206 * See Windows documentation for more details on IPersistStorage methods.
1208 static HRESULT WINAPI
DataCache_IsDirty(
1209 IPersistStorage
* iface
)
1211 TRACE("(%p)\n", iface
);
1216 /************************************************************************
1217 * DataCache_InitNew (IPersistStorage)
1219 * The data cache implementation of IPersistStorage_InitNew simply stores
1220 * the storage pointer.
1222 * See Windows documentation for more details on IPersistStorage methods.
1224 static HRESULT WINAPI
DataCache_InitNew(
1225 IPersistStorage
* iface
,
1228 TRACE("(%p, %p)\n", iface
, pStg
);
1230 return DataCache_Load(iface
, pStg
);
1233 /************************************************************************
1234 * DataCache_Load (IPersistStorage)
1236 * The data cache implementation of IPersistStorage_Load doesn't
1237 * actually load anything. Instead, it holds on to the storage pointer
1238 * and it will load the presentation information when the
1239 * IDataObject_GetData or IViewObject2_Draw methods are called.
1241 * See Windows documentation for more details on IPersistStorage methods.
1243 static HRESULT WINAPI
DataCache_Load(
1244 IPersistStorage
* iface
,
1247 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1249 TRACE("(%p, %p)\n", iface
, pStg
);
1251 if (this->presentationStorage
!= NULL
)
1253 IStorage_Release(this->presentationStorage
);
1256 this->presentationStorage
= pStg
;
1258 if (this->presentationStorage
!= NULL
)
1260 IStorage_AddRef(this->presentationStorage
);
1266 /************************************************************************
1267 * DataCache_Save (IPersistStorage)
1269 * Until we actully connect to a running object and retrieve new
1270 * information to it, we never have to save anything. However, it is
1271 * our responsability to copy the information when saving to a new
1274 * See Windows documentation for more details on IPersistStorage methods.
1276 static HRESULT WINAPI
DataCache_Save(
1277 IPersistStorage
* iface
,
1281 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1283 TRACE("(%p, %p, %d)\n", iface
, pStg
, fSameAsLoad
);
1285 if ( (!fSameAsLoad
) &&
1286 (this->presentationStorage
!=NULL
) )
1288 return IStorage_CopyTo(this->presentationStorage
,
1298 /************************************************************************
1299 * DataCache_SaveCompleted (IPersistStorage)
1301 * This method is called to tell the cache to release the storage
1302 * pointer it's currentlu holding.
1304 * See Windows documentation for more details on IPersistStorage methods.
1306 static HRESULT WINAPI
DataCache_SaveCompleted(
1307 IPersistStorage
* iface
,
1310 TRACE("(%p, %p)\n", iface
, pStgNew
);
1313 * First, make sure we get our hands off any storage we have.
1315 DataCache_HandsOffStorage(iface
);
1318 * Then, attach to the new storage.
1320 DataCache_Load(iface
, pStgNew
);
1325 /************************************************************************
1326 * DataCache_HandsOffStorage (IPersistStorage)
1328 * This method is called to tell the cache to release the storage
1329 * pointer it's currentlu holding.
1331 * See Windows documentation for more details on IPersistStorage methods.
1333 static HRESULT WINAPI
DataCache_HandsOffStorage(
1334 IPersistStorage
* iface
)
1336 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1338 TRACE("(%p)\n", iface
);
1340 if (this->presentationStorage
!= NULL
)
1342 IStorage_Release(this->presentationStorage
);
1343 this->presentationStorage
= NULL
;
1349 /*********************************************************
1350 * Method implementation for the IViewObject2
1351 * part of the DataCache class.
1354 /************************************************************************
1355 * DataCache_IViewObject2_QueryInterface (IUnknown)
1357 * See Windows documentation for more details on IUnknown methods.
1359 static HRESULT WINAPI
DataCache_IViewObject2_QueryInterface(
1360 IViewObject2
* iface
,
1364 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1366 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1369 /************************************************************************
1370 * DataCache_IViewObject2_AddRef (IUnknown)
1372 * See Windows documentation for more details on IUnknown methods.
1374 static ULONG WINAPI
DataCache_IViewObject2_AddRef(
1375 IViewObject2
* iface
)
1377 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1379 return IUnknown_AddRef(this->outerUnknown
);
1382 /************************************************************************
1383 * DataCache_IViewObject2_Release (IUnknown)
1385 * See Windows documentation for more details on IUnknown methods.
1387 static ULONG WINAPI
DataCache_IViewObject2_Release(
1388 IViewObject2
* iface
)
1390 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1392 return IUnknown_Release(this->outerUnknown
);
1395 /************************************************************************
1396 * DataCache_Draw (IViewObject2)
1398 * This method will draw the cached representation of the object
1399 * to the given device context.
1401 * See Windows documentation for more details on IViewObject2 methods.
1403 static HRESULT WINAPI
DataCache_Draw(
1404 IViewObject2
* iface
,
1408 DVTARGETDEVICE
* ptd
,
1411 LPCRECTL lprcBounds
,
1412 LPCRECTL lprcWBounds
,
1413 IVO_ContCallback pfnContinue
,
1416 PresentationDataHeader presData
;
1417 HMETAFILE presMetafile
= 0;
1420 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1422 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1437 if (lprcBounds
==NULL
)
1438 return E_INVALIDARG
;
1441 * First, we need to retrieve the dimensions of the
1442 * image in the metafile.
1444 hres
= DataCache_ReadPresentationData(this,
1452 * Then, we can extract the metafile itself from the cached
1455 presMetafile
= DataCache_ReadPresMetafile(this,
1459 * If we have a metafile, just draw baby...
1460 * We have to be careful not to modify the state of the
1463 if (presMetafile
!=0)
1465 INT prevMapMode
= SetMapMode(hdcDraw
, MM_ANISOTROPIC
);
1467 SIZE oldViewportExt
;
1468 POINT oldViewportOrg
;
1470 SetWindowExtEx(hdcDraw
,
1471 presData
.objectExtentX
,
1472 presData
.objectExtentY
,
1475 SetViewportExtEx(hdcDraw
,
1476 lprcBounds
->right
- lprcBounds
->left
,
1477 lprcBounds
->bottom
- lprcBounds
->top
,
1480 SetViewportOrgEx(hdcDraw
,
1485 PlayMetaFile(hdcDraw
, presMetafile
);
1487 SetWindowExtEx(hdcDraw
,
1492 SetViewportExtEx(hdcDraw
,
1497 SetViewportOrgEx(hdcDraw
,
1502 SetMapMode(hdcDraw
, prevMapMode
);
1504 DeleteMetaFile(presMetafile
);
1510 static HRESULT WINAPI
DataCache_GetColorSet(
1511 IViewObject2
* iface
,
1515 DVTARGETDEVICE
* ptd
,
1516 HDC hicTargetDevice
,
1517 LOGPALETTE
** ppColorSet
)
1523 static HRESULT WINAPI
DataCache_Freeze(
1524 IViewObject2
* iface
,
1534 static HRESULT WINAPI
DataCache_Unfreeze(
1535 IViewObject2
* iface
,
1542 /************************************************************************
1543 * DataCache_SetAdvise (IViewObject2)
1545 * This sets-up an advisory sink with the data cache. When the object's
1546 * view changes, this sink is called.
1548 * See Windows documentation for more details on IViewObject2 methods.
1550 static HRESULT WINAPI
DataCache_SetAdvise(
1551 IViewObject2
* iface
,
1554 IAdviseSink
* pAdvSink
)
1556 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1558 TRACE("(%p, %lx, %lx, %p)\n", iface
, aspects
, advf
, pAdvSink
);
1561 * A call to this function removes the previous sink
1563 if (this->sinkInterface
!= NULL
)
1565 IAdviseSink_Release(this->sinkInterface
);
1566 this->sinkInterface
= NULL
;
1567 this->sinkAspects
= 0;
1568 this->sinkAdviseFlag
= 0;
1572 * Now, setup the new one.
1576 this->sinkInterface
= pAdvSink
;
1577 this->sinkAspects
= aspects
;
1578 this->sinkAdviseFlag
= advf
;
1580 IAdviseSink_AddRef(this->sinkInterface
);
1584 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1587 if (advf
& ADVF_PRIMEFIRST
)
1589 DataCache_FireOnViewChange(this,
1597 /************************************************************************
1598 * DataCache_GetAdvise (IViewObject2)
1600 * This method queries the current state of the advise sink
1601 * installed on the data cache.
1603 * See Windows documentation for more details on IViewObject2 methods.
1605 static HRESULT WINAPI
DataCache_GetAdvise(
1606 IViewObject2
* iface
,
1609 IAdviseSink
** ppAdvSink
)
1611 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1613 TRACE("(%p, %p, %p, %p)\n", iface
, pAspects
, pAdvf
, ppAdvSink
);
1616 * Just copy all the requested values.
1619 *pAspects
= this->sinkAspects
;
1622 *pAdvf
= this->sinkAdviseFlag
;
1624 if (ppAdvSink
!=NULL
)
1626 IAdviseSink_QueryInterface(this->sinkInterface
,
1634 /************************************************************************
1635 * DataCache_GetExtent (IViewObject2)
1637 * This method retrieves the "natural" size of this cached object.
1639 * See Windows documentation for more details on IViewObject2 methods.
1641 static HRESULT WINAPI
DataCache_GetExtent(
1642 IViewObject2
* iface
,
1645 DVTARGETDEVICE
* ptd
,
1648 PresentationDataHeader presData
;
1649 HRESULT hres
= E_FAIL
;
1651 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1653 TRACE("(%p, %lx, %ld, %p, %p)\n",
1654 iface
, dwDrawAspect
, lindex
, ptd
, lpsizel
);
1663 * Initialize the out parameter.
1669 * This flag should be set to -1.
1672 FIXME("Unimplemented flag lindex = %ld\n", lindex
);
1675 * Right now, we suport only the callback from
1676 * the default handler.
1679 FIXME("Unimplemented ptd = %p\n", ptd
);
1682 * Get the presentation information from the
1685 hres
= DataCache_ReadPresentationData(this,
1689 if (SUCCEEDED(hres
))
1691 lpsizel
->cx
= presData
.objectExtentX
;
1692 lpsizel
->cy
= presData
.objectExtentY
;
1696 * This method returns OLE_E_BLANK when it fails.
1705 /*********************************************************
1706 * Method implementation for the IOleCache2
1707 * part of the DataCache class.
1710 /************************************************************************
1711 * DataCache_IOleCache2_QueryInterface (IUnknown)
1713 * See Windows documentation for more details on IUnknown methods.
1715 static HRESULT WINAPI
DataCache_IOleCache2_QueryInterface(
1720 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1722 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1725 /************************************************************************
1726 * DataCache_IOleCache2_AddRef (IUnknown)
1728 * See Windows documentation for more details on IUnknown methods.
1730 static ULONG WINAPI
DataCache_IOleCache2_AddRef(
1733 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1735 return IUnknown_AddRef(this->outerUnknown
);
1738 /************************************************************************
1739 * DataCache_IOleCache2_Release (IUnknown)
1741 * See Windows documentation for more details on IUnknown methods.
1743 static ULONG WINAPI
DataCache_IOleCache2_Release(
1746 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1748 return IUnknown_Release(this->outerUnknown
);
1751 static HRESULT WINAPI
DataCache_Cache(
1753 FORMATETC
* pformatetc
,
1755 DWORD
* pdwConnection
)
1761 static HRESULT WINAPI
DataCache_Uncache(
1769 static HRESULT WINAPI
DataCache_EnumCache(
1771 IEnumSTATDATA
** ppenumSTATDATA
)
1777 static HRESULT WINAPI
DataCache_InitCache(
1779 IDataObject
* pDataObject
)
1785 static HRESULT WINAPI
DataCache_IOleCache2_SetData(
1787 FORMATETC
* pformatetc
,
1795 static HRESULT WINAPI
DataCache_UpdateCache(
1797 LPDATAOBJECT pDataObject
,
1805 static HRESULT WINAPI
DataCache_DiscardCache(
1807 DWORD dwDiscardOptions
)
1814 /*********************************************************
1815 * Method implementation for the IOleCacheControl
1816 * part of the DataCache class.
1819 /************************************************************************
1820 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1822 * See Windows documentation for more details on IUnknown methods.
1824 static HRESULT WINAPI
DataCache_IOleCacheControl_QueryInterface(
1825 IOleCacheControl
* iface
,
1829 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1831 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1834 /************************************************************************
1835 * DataCache_IOleCacheControl_AddRef (IUnknown)
1837 * See Windows documentation for more details on IUnknown methods.
1839 static ULONG WINAPI
DataCache_IOleCacheControl_AddRef(
1840 IOleCacheControl
* iface
)
1842 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1844 return IUnknown_AddRef(this->outerUnknown
);
1847 /************************************************************************
1848 * DataCache_IOleCacheControl_Release (IUnknown)
1850 * See Windows documentation for more details on IUnknown methods.
1852 static ULONG WINAPI
DataCache_IOleCacheControl_Release(
1853 IOleCacheControl
* iface
)
1855 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1857 return IUnknown_Release(this->outerUnknown
);
1860 static HRESULT WINAPI
DataCache_OnRun(
1861 IOleCacheControl
* iface
,
1862 LPDATAOBJECT pDataObject
)
1868 static HRESULT WINAPI
DataCache_OnStop(
1869 IOleCacheControl
* iface
)