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.
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 const 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 DataCache_NDIUnknown_QueryInterface
,
358 DataCache_NDIUnknown_AddRef
,
359 DataCache_NDIUnknown_Release
362 static ICOM_VTABLE(IDataObject
) DataCache_IDataObject_VTable
=
364 DataCache_IDataObject_QueryInterface
,
365 DataCache_IDataObject_AddRef
,
366 DataCache_IDataObject_Release
,
368 DataCache_GetDataHere
,
369 DataCache_QueryGetData
,
370 DataCache_GetCanonicalFormatEtc
,
371 DataCache_IDataObject_SetData
,
372 DataCache_EnumFormatEtc
,
375 DataCache_EnumDAdvise
378 static ICOM_VTABLE(IPersistStorage
) DataCache_IPersistStorage_VTable
=
380 DataCache_IPersistStorage_QueryInterface
,
381 DataCache_IPersistStorage_AddRef
,
382 DataCache_IPersistStorage_Release
,
383 DataCache_GetClassID
,
388 DataCache_SaveCompleted
,
389 DataCache_HandsOffStorage
392 static ICOM_VTABLE(IViewObject2
) DataCache_IViewObject2_VTable
=
394 DataCache_IViewObject2_QueryInterface
,
395 DataCache_IViewObject2_AddRef
,
396 DataCache_IViewObject2_Release
,
398 DataCache_GetColorSet
,
406 static ICOM_VTABLE(IOleCache2
) DataCache_IOleCache2_VTable
=
408 DataCache_IOleCache2_QueryInterface
,
409 DataCache_IOleCache2_AddRef
,
410 DataCache_IOleCache2_Release
,
415 DataCache_IOleCache2_SetData
,
416 DataCache_UpdateCache
,
417 DataCache_DiscardCache
420 static ICOM_VTABLE(IOleCacheControl
) DataCache_IOleCacheControl_VTable
=
422 DataCache_IOleCacheControl_QueryInterface
,
423 DataCache_IOleCacheControl_AddRef
,
424 DataCache_IOleCacheControl_Release
,
429 /******************************************************************************
430 * CreateDataCache [OLE32.54]
432 HRESULT WINAPI
CreateDataCache(
438 DataCache
* newCache
= NULL
;
443 WINE_StringFromCLSID((LPCLSID
)rclsid
,xclsid
);
444 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
446 TRACE(ole
, "(%s, %p, %s, %p)\n", xclsid
, pUnkOuter
, xriid
, ppvObj
);
457 * If this cache is constructed for aggregation, make sure
458 * the caller is requesting the IUnknown interface.
459 * This is necessary because it's the only time the non-delegating
460 * IUnknown pointer can be returned to the outside.
462 if ( (pUnkOuter
!=NULL
) &&
463 (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) != 0) )
464 return CLASS_E_NOAGGREGATION
;
467 * Try to construct a new instance of the class.
469 newCache
= DataCache_Construct(rclsid
,
473 return E_OUTOFMEMORY
;
476 * Make sure it supports the interface required by the caller.
478 hr
= IUnknown_QueryInterface((IUnknown
*)&(newCache
->lpvtbl2
), riid
, ppvObj
);
481 * Release the reference obtained in the constructor. If
482 * the QueryInterface was unsuccessful, it will free the class.
484 IUnknown_Release((IUnknown
*)&(newCache
->lpvtbl2
));
489 /*********************************************************
490 * Method implementation for DataCache class.
492 static DataCache
* DataCache_Construct(
496 DataCache
* newObject
= 0;
499 * Allocate space for the object.
501 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache
));
507 * Initialize the virtual function table.
509 newObject
->lpvtbl1
= &DataCache_IDataObject_VTable
;
510 newObject
->lpvtbl2
= &DataCache_NDIUnknown_VTable
;
511 newObject
->lpvtbl3
= &DataCache_IPersistStorage_VTable
;
512 newObject
->lpvtbl4
= &DataCache_IViewObject2_VTable
;
513 newObject
->lpvtbl5
= &DataCache_IOleCache2_VTable
;
514 newObject
->lpvtbl6
= &DataCache_IOleCacheControl_VTable
;
517 * Start with one reference count. The caller of this function
518 * must release the interface pointer when it is done.
523 * Initialize the outer unknown
524 * We don't keep a reference on the outer unknown since, the way
525 * aggregation works, our lifetime is at least as large as it's
529 pUnkOuter
= (IUnknown
*)&(newObject
->lpvtbl2
);
531 newObject
->outerUnknown
= pUnkOuter
;
534 * Initialize the other members of the structure.
536 newObject
->presentationStorage
= NULL
;
537 newObject
->sinkAspects
= 0;
538 newObject
->sinkAdviseFlag
= 0;
539 newObject
->sinkInterface
= 0;
544 static void DataCache_Destroy(
545 DataCache
* ptrToDestroy
)
549 if (ptrToDestroy
->sinkInterface
!= NULL
)
551 IAdviseSink_Release(ptrToDestroy
->sinkInterface
);
552 ptrToDestroy
->sinkInterface
= NULL
;
555 if (ptrToDestroy
->presentationStorage
!= NULL
)
557 IStorage_Release(ptrToDestroy
->presentationStorage
);
558 ptrToDestroy
->presentationStorage
= NULL
;
562 * Free the datacache pointer.
564 HeapFree(GetProcessHeap(), 0, ptrToDestroy
);
567 /************************************************************************
568 * DataCache_ReadPresentationData
570 * This method will read information for the requested presentation
571 * into the given structure.
574 * this - Pointer to the DataCache object
575 * drawAspect - The aspect of the object that we wish to draw.
576 * header - The structure containing information about this
577 * aspect of the object.
579 static HRESULT
DataCache_ReadPresentationData(
582 PresentationDataHeader
* header
)
584 IStream
* presStream
= NULL
;
585 OLECHAR streamName
[20];
589 * Get the name for the presentation stream.
591 hres
= DataCache_FindPresStreamName(
600 * Open the stream and read the header.
602 hres
= IStorage_OpenStream(
603 this->presentationStorage
,
606 STGM_READ
| STGM_SHARE_EXCLUSIVE
,
616 sizeof(PresentationDataHeader
),
622 IStream_Release(presStream
);
625 * We don't want to propagate any other error
626 * code than a failure.
634 /************************************************************************
635 * DataCache_FireOnViewChange
637 * This method will fire an OnViewChange notification to the advise
638 * sink registered with the datacache.
640 * See IAdviseSink::OnViewChange for more details.
642 static void DataCache_FireOnViewChange(
647 TRACE(ole
, "(%p, %lx, %ld)\n", this, aspect
, lindex
);
650 * The sink supplies a filter when it registers
651 * we make sure we only send the notifications when that
654 if ((this->sinkAspects
& aspect
) != 0)
656 if (this->sinkInterface
!= NULL
)
658 IAdviseSink_OnViewChange(this->sinkInterface
,
663 * Some sinks want to be unregistered automatically when
664 * the first notification goes out.
666 if ( (this->sinkAdviseFlag
& ADVF_ONLYONCE
) != 0)
668 IAdviseSink_Release(this->sinkInterface
);
670 this->sinkInterface
= NULL
;
671 this->sinkAspects
= 0;
672 this->sinkAdviseFlag
= 0;
678 /************************************************************************
679 * DataCache_ReadPresentationData
681 * This method will read information for the requested presentation
682 * into the given structure.
685 * this - Pointer to the DataCache object
686 * drawAspect - The aspect of the object that we wish to draw.
687 * header - The structure containing information about this
688 * aspect of the object.
691 * This method only supports the DVASPECT_CONTENT aspect.
693 static HRESULT
DataCache_FindPresStreamName(
698 OLECHAR name
[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
700 if (drawAspect
!=DVASPECT_CONTENT
)
703 memcpy(buffer
, name
, sizeof(name
));
708 /************************************************************************
709 * DataCache_ReadPresentationData
711 * This method will read information for the requested presentation
712 * into the given structure.
715 * this - Pointer to the DataCache object
716 * drawAspect - The aspect of the object that we wish to draw.
719 * This method returns a metafile handle if it is successful.
720 * it will return 0 if not.
722 static HMETAFILE
DataCache_ReadPresMetafile(
726 LARGE_INTEGER offset
;
727 IStream
* presStream
= NULL
;
728 OLECHAR streamName
[20];
732 HMETAFILE newMetafile
= 0;
735 * Get the name for the presentation stream.
737 hres
= DataCache_FindPresStreamName(
746 * Open the stream and read the header.
748 hres
= IStorage_OpenStream(
749 this->presentationStorage
,
752 STGM_READ
| STGM_SHARE_EXCLUSIVE
,
760 * Get the size of the stream.
762 hres
= IStream_Stat(presStream
,
770 offset
.LowPart
= sizeof(PresentationDataHeader
);
779 * Allocate a buffer for the metafile bits.
781 metafileBits
= HeapAlloc(GetProcessHeap(),
783 streamInfo
.cbSize
.LowPart
);
786 * Read the metafile bits.
791 streamInfo
.cbSize
.LowPart
,
795 * Create a metafile with those bits.
799 newMetafile
= SetMetaFileBitsEx(streamInfo
.cbSize
.LowPart
, metafileBits
);
805 HeapFree(GetProcessHeap(), 0, metafileBits
);
806 IStream_Release(presStream
);
814 /*********************************************************
815 * Method implementation for the non delegating IUnknown
816 * part of the DataCache class.
819 /************************************************************************
820 * DataCache_NDIUnknown_QueryInterface (IUnknown)
822 * See Windows documentation for more details on IUnknown methods.
824 * This version of QueryInterface will not delegate it's implementation
825 * to the outer unknown.
827 static HRESULT WINAPI
DataCache_NDIUnknown_QueryInterface(
832 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
835 * Perform a sanity check on the parameters.
837 if ( (this==0) || (ppvObject
==0) )
841 * Initialize the return parameter.
846 * Compare the riid with the interface IDs implemented by this object.
848 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
852 else if (memcmp(&IID_IDataObject
, riid
, sizeof(IID_IDataObject
)) == 0)
854 *ppvObject
= (IDataObject
*)&(this->lpvtbl1
);
856 else if ( (memcmp(&IID_IPersistStorage
, riid
, sizeof(IID_IPersistStorage
)) == 0) ||
857 (memcmp(&IID_IPersist
, riid
, sizeof(IID_IPersist
)) == 0) )
859 *ppvObject
= (IPersistStorage
*)&(this->lpvtbl3
);
861 else if ( (memcmp(&IID_IViewObject
, riid
, sizeof(IID_IViewObject
)) == 0) ||
862 (memcmp(&IID_IViewObject2
, riid
, sizeof(IID_IViewObject2
)) == 0) )
864 *ppvObject
= (IViewObject2
*)&(this->lpvtbl4
);
866 else if ( (memcmp(&IID_IOleCache
, riid
, sizeof(IID_IOleCache
)) == 0) ||
867 (memcmp(&IID_IOleCache2
, riid
, sizeof(IID_IOleCache2
)) == 0) )
869 *ppvObject
= (IOleCache2
*)&(this->lpvtbl5
);
871 else if (memcmp(&IID_IOleCacheControl
, riid
, sizeof(IID_IOleCacheControl
)) == 0)
873 *ppvObject
= (IOleCacheControl
*)&(this->lpvtbl6
);
877 * Check that we obtained an interface.
883 WINE_StringFromCLSID((LPCLSID
)riid
,clsid
);
886 "() : asking for un supported interface %s\n",
889 return E_NOINTERFACE
;
893 * Query Interface always increases the reference count by one when it is
896 IUnknown_AddRef((IUnknown
*)*ppvObject
);
901 /************************************************************************
902 * DataCache_NDIUnknown_AddRef (IUnknown)
904 * See Windows documentation for more details on IUnknown methods.
906 * This version of QueryInterface will not delegate it's implementation
907 * to the outer unknown.
909 static ULONG WINAPI
DataCache_NDIUnknown_AddRef(
912 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
919 /************************************************************************
920 * DataCache_NDIUnknown_Release (IUnknown)
922 * See Windows documentation for more details on IUnknown methods.
924 * This version of QueryInterface will not delegate it's implementation
925 * to the outer unknown.
927 static ULONG WINAPI
DataCache_NDIUnknown_Release(
930 _ICOM_THIS_From_NDIUnknown(DataCache
, iface
);
933 * Decrease the reference count on this object.
938 * If the reference count goes down to 0, perform suicide.
942 DataCache_Destroy(this);
950 /*********************************************************
951 * Method implementation for the IDataObject
952 * part of the DataCache class.
955 /************************************************************************
956 * DataCache_IDataObject_QueryInterface (IUnknown)
958 * See Windows documentation for more details on IUnknown methods.
960 static HRESULT WINAPI
DataCache_IDataObject_QueryInterface(
965 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
967 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
970 /************************************************************************
971 * DataCache_IDataObject_AddRef (IUnknown)
973 * See Windows documentation for more details on IUnknown methods.
975 static ULONG WINAPI
DataCache_IDataObject_AddRef(
978 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
980 return IUnknown_AddRef(this->outerUnknown
);
983 /************************************************************************
984 * DataCache_IDataObject_Release (IUnknown)
986 * See Windows documentation for more details on IUnknown methods.
988 static ULONG WINAPI
DataCache_IDataObject_Release(
991 _ICOM_THIS_From_IDataObject(DataCache
, iface
);
993 return IUnknown_Release(this->outerUnknown
);
996 static HRESULT WINAPI
DataCache_GetData(
998 LPFORMATETC pformatetcIn
,
1001 FIXME(ole
,"stub\n");
1005 static HRESULT WINAPI
DataCache_GetDataHere(
1007 LPFORMATETC pformatetc
,
1010 FIXME(ole
,"stub\n");
1014 static HRESULT WINAPI
DataCache_QueryGetData(
1016 LPFORMATETC pformatetc
)
1018 FIXME(ole
,"stub\n");
1022 /************************************************************************
1023 * DataCache_EnumFormatEtc (IDataObject)
1025 * The data cache doesn't implement this method.
1027 * See Windows documentation for more details on IDataObject methods.
1029 static HRESULT WINAPI
DataCache_GetCanonicalFormatEtc(
1031 LPFORMATETC pformatectIn
,
1032 LPFORMATETC pformatetcOut
)
1038 /************************************************************************
1039 * DataCache_IDataObject_SetData (IDataObject)
1041 * This method is delegated to the IOleCache2 implementation.
1043 * See Windows documentation for more details on IDataObject methods.
1045 static HRESULT WINAPI
DataCache_IDataObject_SetData(
1047 LPFORMATETC pformatetc
,
1051 IOleCache2
* oleCache
= NULL
;
1054 TRACE(ole
,"(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1056 hres
= IDataObject_QueryInterface(iface
, &IID_IOleCache2
, (void**)&oleCache
);
1059 return E_UNEXPECTED
;
1061 hres
= IOleCache2_SetData(oleCache
, pformatetc
, pmedium
, fRelease
);
1063 IOleCache2_Release(oleCache
);
1068 /************************************************************************
1069 * DataCache_EnumFormatEtc (IDataObject)
1071 * The data cache doesn't implement this method.
1073 * See Windows documentation for more details on IDataObject methods.
1075 static HRESULT WINAPI
DataCache_EnumFormatEtc(
1078 IEnumFORMATETC
** ppenumFormatEtc
)
1084 /************************************************************************
1085 * DataCache_DAdvise (IDataObject)
1087 * The data cache doesn't support connections.
1089 * See Windows documentation for more details on IDataObject methods.
1091 static HRESULT WINAPI
DataCache_DAdvise(
1093 FORMATETC
* pformatetc
,
1095 IAdviseSink
* pAdvSink
,
1096 DWORD
* pdwConnection
)
1099 return OLE_E_ADVISENOTSUPPORTED
;
1102 /************************************************************************
1103 * DataCache_DUnadvise (IDataObject)
1105 * The data cache doesn't support connections.
1107 * See Windows documentation for more details on IDataObject methods.
1109 static HRESULT WINAPI
DataCache_DUnadvise(
1114 return OLE_E_NOCONNECTION
;
1117 /************************************************************************
1118 * DataCache_EnumDAdvise (IDataObject)
1120 * The data cache doesn't support connections.
1122 * See Windows documentation for more details on IDataObject methods.
1124 static HRESULT WINAPI
DataCache_EnumDAdvise(
1126 IEnumSTATDATA
** ppenumAdvise
)
1129 return OLE_E_ADVISENOTSUPPORTED
;
1132 /*********************************************************
1133 * Method implementation for the IDataObject
1134 * part of the DataCache class.
1137 /************************************************************************
1138 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1140 * See Windows documentation for more details on IUnknown methods.
1142 static HRESULT WINAPI
DataCache_IPersistStorage_QueryInterface(
1143 IPersistStorage
* iface
,
1147 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1149 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1152 /************************************************************************
1153 * DataCache_IPersistStorage_AddRef (IUnknown)
1155 * See Windows documentation for more details on IUnknown methods.
1157 static ULONG WINAPI
DataCache_IPersistStorage_AddRef(
1158 IPersistStorage
* iface
)
1160 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1162 return IUnknown_AddRef(this->outerUnknown
);
1165 /************************************************************************
1166 * DataCache_IPersistStorage_Release (IUnknown)
1168 * See Windows documentation for more details on IUnknown methods.
1170 static ULONG WINAPI
DataCache_IPersistStorage_Release(
1171 IPersistStorage
* iface
)
1173 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1175 return IUnknown_Release(this->outerUnknown
);
1178 /************************************************************************
1179 * DataCache_GetClassID (IPersistStorage)
1181 * The data cache doesn't implement this method.
1183 * See Windows documentation for more details on IPersistStorage methods.
1185 static HRESULT WINAPI
DataCache_GetClassID(
1186 const IPersistStorage
* iface
,
1189 TRACE(ole
,"(%p, %p)\n", iface
, pClassID
);
1193 /************************************************************************
1194 * DataCache_IsDirty (IPersistStorage)
1196 * Until we actully connect to a running object and retrieve new
1197 * information to it, we never get dirty.
1199 * See Windows documentation for more details on IPersistStorage methods.
1201 static HRESULT WINAPI
DataCache_IsDirty(
1202 IPersistStorage
* iface
)
1204 TRACE(ole
,"(%p)\n", iface
);
1209 /************************************************************************
1210 * DataCache_InitNew (IPersistStorage)
1212 * The data cache implementation of IPersistStorage_InitNew simply stores
1213 * the storage pointer.
1215 * See Windows documentation for more details on IPersistStorage methods.
1217 static HRESULT WINAPI
DataCache_InitNew(
1218 IPersistStorage
* iface
,
1221 TRACE(ole
, "(%p, %p)\n", iface
, pStg
);
1223 return DataCache_Load(iface
, pStg
);
1226 /************************************************************************
1227 * DataCache_Load (IPersistStorage)
1229 * The data cache implementation of IPersistStorage_Load doesn't
1230 * actually load anything. Instead, it holds on to the storage pointer
1231 * and it will load the presentation information when the
1232 * IDataObject_GetData or IViewObject2_Draw methods are called.
1234 * See Windows documentation for more details on IPersistStorage methods.
1236 static HRESULT WINAPI
DataCache_Load(
1237 IPersistStorage
* iface
,
1240 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1242 TRACE(ole
, "(%p, %p)\n", iface
, pStg
);
1244 if (this->presentationStorage
!= NULL
)
1246 IStorage_Release(this->presentationStorage
);
1249 this->presentationStorage
= pStg
;
1251 if (this->presentationStorage
!= NULL
)
1253 IStorage_AddRef(this->presentationStorage
);
1259 /************************************************************************
1260 * DataCache_Save (IPersistStorage)
1262 * Until we actully connect to a running object and retrieve new
1263 * information to it, we never have to save anything. However, it is
1264 * our responsability to copy the information when saving to a new
1267 * See Windows documentation for more details on IPersistStorage methods.
1269 static HRESULT WINAPI
DataCache_Save(
1270 IPersistStorage
* iface
,
1274 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1276 TRACE(ole
, "(%p, %p, %d)\n", iface
, pStg
, fSameAsLoad
);
1278 if ( (!fSameAsLoad
) &&
1279 (this->presentationStorage
!=NULL
) )
1281 return IStorage_CopyTo(this->presentationStorage
,
1291 /************************************************************************
1292 * DataCache_SaveCompleted (IPersistStorage)
1294 * This method is called to tell the cache to release the storage
1295 * pointer it's currentlu holding.
1297 * See Windows documentation for more details on IPersistStorage methods.
1299 static HRESULT WINAPI
DataCache_SaveCompleted(
1300 IPersistStorage
* iface
,
1303 TRACE(ole
, "(%p, %p)\n", iface
, pStgNew
);
1306 * First, make sure we get our hands off any storage we have.
1308 DataCache_HandsOffStorage(iface
);
1311 * Then, attach to the new storage.
1313 DataCache_Load(iface
, pStgNew
);
1318 /************************************************************************
1319 * DataCache_HandsOffStorage (IPersistStorage)
1321 * This method is called to tell the cache to release the storage
1322 * pointer it's currentlu holding.
1324 * See Windows documentation for more details on IPersistStorage methods.
1326 static HRESULT WINAPI
DataCache_HandsOffStorage(
1327 IPersistStorage
* iface
)
1329 _ICOM_THIS_From_IPersistStorage(DataCache
, iface
);
1331 TRACE(ole
,"(%p)\n", iface
);
1333 if (this->presentationStorage
!= NULL
)
1335 IStorage_Release(this->presentationStorage
);
1336 this->presentationStorage
= NULL
;
1342 /*********************************************************
1343 * Method implementation for the IViewObject2
1344 * part of the DataCache class.
1347 /************************************************************************
1348 * DataCache_IViewObject2_QueryInterface (IUnknown)
1350 * See Windows documentation for more details on IUnknown methods.
1352 static HRESULT WINAPI
DataCache_IViewObject2_QueryInterface(
1353 IViewObject2
* iface
,
1357 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1359 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1362 /************************************************************************
1363 * DataCache_IViewObject2_AddRef (IUnknown)
1365 * See Windows documentation for more details on IUnknown methods.
1367 static ULONG WINAPI
DataCache_IViewObject2_AddRef(
1368 IViewObject2
* iface
)
1370 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1372 return IUnknown_AddRef(this->outerUnknown
);
1375 /************************************************************************
1376 * DataCache_IViewObject2_Release (IUnknown)
1378 * See Windows documentation for more details on IUnknown methods.
1380 static ULONG WINAPI
DataCache_IViewObject2_Release(
1381 IViewObject2
* iface
)
1383 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1385 return IUnknown_Release(this->outerUnknown
);
1388 /************************************************************************
1389 * DataCache_Draw (IViewObject2)
1391 * This method will draw the cached representation of the object
1392 * to the given device context.
1394 * See Windows documentation for more details on IViewObject2 methods.
1396 static HRESULT WINAPI
DataCache_Draw(
1397 IViewObject2
* iface
,
1401 DVTARGETDEVICE
* ptd
,
1404 LPCRECTL lprcBounds
,
1405 LPCRECTL lprcWBounds
,
1406 IVO_ContCallback pfnContinue
,
1409 PresentationDataHeader presData
;
1410 HMETAFILE presMetafile
= 0;
1413 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1415 TRACE(ole
,"(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1430 if (lprcBounds
==NULL
)
1431 return E_INVALIDARG
;
1434 * First, we need to retrieve the dimensions of the
1435 * image in the metafile.
1437 hres
= DataCache_ReadPresentationData(this,
1445 * Then, we can extract the metafile itself from the cached
1448 presMetafile
= DataCache_ReadPresMetafile(this,
1452 * If we have a metafile, just draw baby...
1453 * We have to be careful not to modify the state of the
1456 if (presMetafile
!=0)
1458 INT prevMapMode
= SetMapMode(hdcDraw
, MM_ANISOTROPIC
);
1460 SIZE oldViewportExt
;
1461 POINT oldViewportOrg
;
1463 SetWindowExtEx(hdcDraw
,
1464 presData
.objectExtentX
,
1465 presData
.objectExtentY
,
1468 SetViewportExtEx(hdcDraw
,
1469 lprcBounds
->right
- lprcBounds
->left
,
1470 lprcBounds
->bottom
- lprcBounds
->top
,
1473 SetViewportOrgEx(hdcDraw
,
1478 PlayMetaFile(hdcDraw
, presMetafile
);
1480 SetWindowExtEx(hdcDraw
,
1485 SetViewportExtEx(hdcDraw
,
1490 SetViewportOrgEx(hdcDraw
,
1495 SetMapMode(hdcDraw
, prevMapMode
);
1497 DeleteMetaFile(presMetafile
);
1503 static HRESULT WINAPI
DataCache_GetColorSet(
1504 IViewObject2
* iface
,
1508 DVTARGETDEVICE
* ptd
,
1509 HDC hicTargetDevice
,
1510 LOGPALETTE
** ppColorSet
)
1512 FIXME(ole
,"stub\n");
1516 static HRESULT WINAPI
DataCache_Freeze(
1517 IViewObject2
* iface
,
1523 FIXME(ole
,"stub\n");
1527 static HRESULT WINAPI
DataCache_Unfreeze(
1528 IViewObject2
* iface
,
1531 FIXME(ole
,"stub\n");
1535 /************************************************************************
1536 * DataCache_SetAdvise (IViewObject2)
1538 * This sets-up an advisory sink with the data cache. When the object's
1539 * view changes, this sink is called.
1541 * See Windows documentation for more details on IViewObject2 methods.
1543 static HRESULT WINAPI
DataCache_SetAdvise(
1544 IViewObject2
* iface
,
1547 IAdviseSink
* pAdvSink
)
1549 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1551 TRACE(ole
,"(%p, %lx, %lx, %p)\n", iface
, aspects
, advf
, pAdvSink
);
1554 * A call to this function removes the previous sink
1556 if (this->sinkInterface
!= NULL
)
1558 IAdviseSink_Release(this->sinkInterface
);
1559 this->sinkInterface
= NULL
;
1560 this->sinkAspects
= 0;
1561 this->sinkAdviseFlag
= 0;
1565 * Now, setup the new one.
1569 this->sinkInterface
= pAdvSink
;
1570 this->sinkAspects
= aspects
;
1571 this->sinkAdviseFlag
= advf
;
1573 IAdviseSink_AddRef(this->sinkInterface
);
1577 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1580 if (advf
& ADVF_PRIMEFIRST
)
1582 DataCache_FireOnViewChange(this,
1590 /************************************************************************
1591 * DataCache_GetAdvise (IViewObject2)
1593 * This method queries the current state of the advise sink
1594 * installed on the data cache.
1596 * See Windows documentation for more details on IViewObject2 methods.
1598 static HRESULT WINAPI
DataCache_GetAdvise(
1599 IViewObject2
* iface
,
1602 IAdviseSink
** ppAdvSink
)
1604 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1606 TRACE(ole
,"(%p, %p, %p, %p)\n", iface
, pAspects
, pAdvf
, ppAdvSink
);
1609 * Just copy all the requested values.
1612 *pAspects
= this->sinkAspects
;
1615 *pAdvf
= this->sinkAdviseFlag
;
1617 if (ppAdvSink
!=NULL
)
1619 IAdviseSink_QueryInterface(this->sinkInterface
,
1627 /************************************************************************
1628 * DataCache_GetExtent (IViewObject2)
1630 * This method retrieves the "natural" size of this cached object.
1632 * See Windows documentation for more details on IViewObject2 methods.
1634 static HRESULT WINAPI
DataCache_GetExtent(
1635 IViewObject2
* iface
,
1638 DVTARGETDEVICE
* ptd
,
1641 PresentationDataHeader presData
;
1642 HRESULT hres
= E_FAIL
;
1644 _ICOM_THIS_From_IViewObject2(DataCache
, iface
);
1646 TRACE(ole
, "(%p, %lx, %ld, %p, %p)\n",
1647 iface
, dwDrawAspect
, lindex
, ptd
, lpsizel
);
1656 * Initialize the out parameter.
1662 * This flag should be set to -1.
1665 FIXME(ole
, "Unimplemented flag lindex = %ld\n", lindex
);
1668 * Right now, we suport only the callback from
1669 * the default handler.
1672 FIXME(ole
, "Unimplemented ptd = %p\n", ptd
);
1675 * Get the presentation information from the
1678 hres
= DataCache_ReadPresentationData(this,
1682 if (SUCCEEDED(hres
))
1684 lpsizel
->cx
= presData
.objectExtentX
;
1685 lpsizel
->cy
= presData
.objectExtentY
;
1689 * This method returns OLE_E_BLANK when it fails.
1698 /*********************************************************
1699 * Method implementation for the IOleCache2
1700 * part of the DataCache class.
1703 /************************************************************************
1704 * DataCache_IOleCache2_QueryInterface (IUnknown)
1706 * See Windows documentation for more details on IUnknown methods.
1708 static HRESULT WINAPI
DataCache_IOleCache2_QueryInterface(
1713 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1715 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1718 /************************************************************************
1719 * DataCache_IOleCache2_AddRef (IUnknown)
1721 * See Windows documentation for more details on IUnknown methods.
1723 static ULONG WINAPI
DataCache_IOleCache2_AddRef(
1726 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1728 return IUnknown_AddRef(this->outerUnknown
);
1731 /************************************************************************
1732 * DataCache_IOleCache2_Release (IUnknown)
1734 * See Windows documentation for more details on IUnknown methods.
1736 static ULONG WINAPI
DataCache_IOleCache2_Release(
1739 _ICOM_THIS_From_IOleCache2(DataCache
, iface
);
1741 return IUnknown_Release(this->outerUnknown
);
1744 static HRESULT WINAPI
DataCache_Cache(
1746 FORMATETC
* pformatetc
,
1748 DWORD
* pdwConnection
)
1750 FIXME(ole
,"stub\n");
1754 static HRESULT WINAPI
DataCache_Uncache(
1758 FIXME(ole
,"stub\n");
1762 static HRESULT WINAPI
DataCache_EnumCache(
1764 IEnumSTATDATA
** ppenumSTATDATA
)
1766 FIXME(ole
,"stub\n");
1770 static HRESULT WINAPI
DataCache_InitCache(
1772 IDataObject
* pDataObject
)
1774 FIXME(ole
,"stub\n");
1778 static HRESULT WINAPI
DataCache_IOleCache2_SetData(
1780 FORMATETC
* pformatetc
,
1784 FIXME(ole
,"stub\n");
1788 static HRESULT WINAPI
DataCache_UpdateCache(
1790 LPDATAOBJECT pDataObject
,
1794 FIXME(ole
,"stub\n");
1798 static HRESULT WINAPI
DataCache_DiscardCache(
1800 DWORD dwDiscardOptions
)
1802 FIXME(ole
,"stub\n");
1807 /*********************************************************
1808 * Method implementation for the IOleCacheControl
1809 * part of the DataCache class.
1812 /************************************************************************
1813 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1815 * See Windows documentation for more details on IUnknown methods.
1817 static HRESULT WINAPI
DataCache_IOleCacheControl_QueryInterface(
1818 IOleCacheControl
* iface
,
1822 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1824 return IUnknown_QueryInterface(this->outerUnknown
, riid
, ppvObject
);
1827 /************************************************************************
1828 * DataCache_IOleCacheControl_AddRef (IUnknown)
1830 * See Windows documentation for more details on IUnknown methods.
1832 static ULONG WINAPI
DataCache_IOleCacheControl_AddRef(
1833 IOleCacheControl
* iface
)
1835 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1837 return IUnknown_AddRef(this->outerUnknown
);
1840 /************************************************************************
1841 * DataCache_IOleCacheControl_Release (IUnknown)
1843 * See Windows documentation for more details on IUnknown methods.
1845 static ULONG WINAPI
DataCache_IOleCacheControl_Release(
1846 IOleCacheControl
* iface
)
1848 _ICOM_THIS_From_IOleCacheControl(DataCache
, iface
);
1850 return IUnknown_Release(this->outerUnknown
);
1853 static HRESULT WINAPI
DataCache_OnRun(
1854 IOleCacheControl
* iface
,
1855 LPDATAOBJECT pDataObject
)
1857 FIXME(ole
,"stub\n");
1861 static HRESULT WINAPI
DataCache_OnStop(
1862 IOleCacheControl
* iface
)
1864 FIXME(ole
,"stub\n");