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