Fixed GMEM_ZEROINIT in GlobalRealloc (thanks to Gerard Patel).
[wine/multimedia.git] / ole / datacache.c
blob1a9e386b600c1aa492eddcef2c873e156b0fd2d2
1 /*
2 * OLE 2 Data cache
4 * Copyright 1999 Francis Beaudet
6 * NOTES:
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,
15 * NOTES
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
28 * just be a counter.
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.
33 #include <assert.h>
34 #include "wingdi.h"
35 #include "winbase.h"
36 #include "winerror.h"
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
53 DWORD unknown1;
54 DWORD unknown2;
55 DWORD unknown3;
56 DWORD unknown4;
57 DWORD unknown5;
59 DWORD unknown6;
60 DWORD unknown7;
61 DWORD objectExtentX;
62 DWORD objectExtentY;
63 DWORD unknown8;
64 } PresentationDataHeader;
66 /****************************************************************************
67 * DataCache
69 struct DataCache
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
84 ULONG ref;
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
101 * that connection.
103 DWORD sinkAspects;
104 DWORD sinkAdviseFlag;
105 IAdviseSink* sinkInterface;
109 typedef struct DataCache DataCache;
112 * Here, I define utility macros to help with the casting of the
113 * "this" parameter.
114 * There is a version to accomodate all of the VTables implemented
115 * by this object.
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,
131 DWORD drawAspect,
132 PresentationDataHeader* header);
133 static HRESULT DataCache_FindPresStreamName(DataCache* this,
134 DWORD drawAspect,
135 OLECHAR* buffer);
136 static HMETAFILE DataCache_ReadPresMetafile(DataCache* this,
137 DWORD drawAspect);
138 static void DataCache_FireOnViewChange(DataCache* this,
139 DWORD aspect,
140 LONG lindex);
143 * Prototypes for the methods of the DataCache class
144 * that implement non delegating IUnknown methods.
146 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
147 IUnknown* iface,
148 REFIID riid,
149 void** ppvObject);
150 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
151 IUnknown* iface);
152 static ULONG WINAPI DataCache_NDIUnknown_Release(
153 IUnknown* iface);
156 * Prototypes for the methods of the DataCache class
157 * that implement IDataObject methods.
159 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
160 IDataObject* iface,
161 REFIID riid,
162 void** ppvObject);
163 static ULONG WINAPI DataCache_IDataObject_AddRef(
164 IDataObject* iface);
165 static ULONG WINAPI DataCache_IDataObject_Release(
166 IDataObject* iface);
167 static HRESULT WINAPI DataCache_GetData(
168 IDataObject* iface,
169 LPFORMATETC pformatetcIn,
170 STGMEDIUM* pmedium);
171 static HRESULT WINAPI DataCache_GetDataHere(
172 IDataObject* iface,
173 LPFORMATETC pformatetc,
174 STGMEDIUM* pmedium);
175 static HRESULT WINAPI DataCache_QueryGetData(
176 IDataObject* iface,
177 LPFORMATETC pformatetc);
178 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
179 IDataObject* iface,
180 LPFORMATETC pformatectIn,
181 LPFORMATETC pformatetcOut);
182 static HRESULT WINAPI DataCache_IDataObject_SetData(
183 IDataObject* iface,
184 LPFORMATETC pformatetc,
185 STGMEDIUM* pmedium,
186 BOOL fRelease);
187 static HRESULT WINAPI DataCache_EnumFormatEtc(
188 IDataObject* iface,
189 DWORD dwDirection,
190 IEnumFORMATETC** ppenumFormatEtc);
191 static HRESULT WINAPI DataCache_DAdvise(
192 IDataObject* iface,
193 FORMATETC* pformatetc,
194 DWORD advf,
195 IAdviseSink* pAdvSink,
196 DWORD* pdwConnection);
197 static HRESULT WINAPI DataCache_DUnadvise(
198 IDataObject* iface,
199 DWORD dwConnection);
200 static HRESULT WINAPI DataCache_EnumDAdvise(
201 IDataObject* iface,
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,
210 REFIID riid,
211 void** ppvObject);
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,
218 CLSID* pClassID);
219 static HRESULT WINAPI DataCache_IsDirty(
220 IPersistStorage* iface);
221 static HRESULT WINAPI DataCache_InitNew(
222 IPersistStorage* iface,
223 IStorage* pStg);
224 static HRESULT WINAPI DataCache_Load(
225 IPersistStorage* iface,
226 IStorage* pStg);
227 static HRESULT WINAPI DataCache_Save(
228 IPersistStorage* iface,
229 IStorage* pStg,
230 BOOL fSameAsLoad);
231 static HRESULT WINAPI DataCache_SaveCompleted(
232 IPersistStorage* iface,
233 IStorage* pStgNew);
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(
242 IViewObject2* iface,
243 REFIID riid,
244 void** ppvObject);
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(
250 IViewObject2* iface,
251 DWORD dwDrawAspect,
252 LONG lindex,
253 void* pvAspect,
254 DVTARGETDEVICE* ptd,
255 HDC hdcTargetDev,
256 HDC hdcDraw,
257 LPCRECTL lprcBounds,
258 LPCRECTL lprcWBounds,
259 IVO_ContCallback pfnContinue,
260 DWORD dwContinue);
261 static HRESULT WINAPI DataCache_GetColorSet(
262 IViewObject2* iface,
263 DWORD dwDrawAspect,
264 LONG lindex,
265 void* pvAspect,
266 DVTARGETDEVICE* ptd,
267 HDC hicTargetDevice,
268 LOGPALETTE** ppColorSet);
269 static HRESULT WINAPI DataCache_Freeze(
270 IViewObject2* iface,
271 DWORD dwDrawAspect,
272 LONG lindex,
273 void* pvAspect,
274 DWORD* pdwFreeze);
275 static HRESULT WINAPI DataCache_Unfreeze(
276 IViewObject2* iface,
277 DWORD dwFreeze);
278 static HRESULT WINAPI DataCache_SetAdvise(
279 IViewObject2* iface,
280 DWORD aspects,
281 DWORD advf,
282 IAdviseSink* pAdvSink);
283 static HRESULT WINAPI DataCache_GetAdvise(
284 IViewObject2* iface,
285 DWORD* pAspects,
286 DWORD* pAdvf,
287 IAdviseSink** ppAdvSink);
288 static HRESULT WINAPI DataCache_GetExtent(
289 IViewObject2* iface,
290 DWORD dwDrawAspect,
291 LONG lindex,
292 DVTARGETDEVICE* ptd,
293 LPSIZEL lpsizel);
296 * Prototypes for the methods of the DataCache class
297 * that implement IOleCache2 methods.
299 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
300 IOleCache2* iface,
301 REFIID riid,
302 void** ppvObject);
303 static ULONG WINAPI DataCache_IOleCache2_AddRef(
304 IOleCache2* iface);
305 static ULONG WINAPI DataCache_IOleCache2_Release(
306 IOleCache2* iface);
307 static HRESULT WINAPI DataCache_Cache(
308 IOleCache2* iface,
309 FORMATETC* pformatetc,
310 DWORD advf,
311 DWORD* pdwConnection);
312 static HRESULT WINAPI DataCache_Uncache(
313 IOleCache2* iface,
314 DWORD dwConnection);
315 static HRESULT WINAPI DataCache_EnumCache(
316 IOleCache2* iface,
317 IEnumSTATDATA** ppenumSTATDATA);
318 static HRESULT WINAPI DataCache_InitCache(
319 IOleCache2* iface,
320 IDataObject* pDataObject);
321 static HRESULT WINAPI DataCache_IOleCache2_SetData(
322 IOleCache2* iface,
323 FORMATETC* pformatetc,
324 STGMEDIUM* pmedium,
325 BOOL fRelease);
326 static HRESULT WINAPI DataCache_UpdateCache(
327 IOleCache2* iface,
328 LPDATAOBJECT pDataObject,
329 DWORD grfUpdf,
330 LPVOID pReserved);
331 static HRESULT WINAPI DataCache_DiscardCache(
332 IOleCache2* iface,
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,
341 REFIID riid,
342 void** ppvObject);
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,
370 DataCache_GetData,
371 DataCache_GetDataHere,
372 DataCache_QueryGetData,
373 DataCache_GetCanonicalFormatEtc,
374 DataCache_IDataObject_SetData,
375 DataCache_EnumFormatEtc,
376 DataCache_DAdvise,
377 DataCache_DUnadvise,
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,
388 DataCache_IsDirty,
389 DataCache_InitNew,
390 DataCache_Load,
391 DataCache_Save,
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,
402 DataCache_Draw,
403 DataCache_GetColorSet,
404 DataCache_Freeze,
405 DataCache_Unfreeze,
406 DataCache_SetAdvise,
407 DataCache_GetAdvise,
408 DataCache_GetExtent
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,
417 DataCache_Cache,
418 DataCache_Uncache,
419 DataCache_EnumCache,
420 DataCache_InitCache,
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,
432 DataCache_OnRun,
433 DataCache_OnStop
436 /******************************************************************************
437 * CreateDataCache [OLE32.54]
439 HRESULT WINAPI CreateDataCache(
440 LPUNKNOWN pUnkOuter,
441 REFCLSID rclsid,
442 REFIID riid,
443 LPVOID* ppvObj)
445 DataCache* newCache = NULL;
446 HRESULT hr = S_OK;
447 char xclsid[50];
448 char xriid[50];
450 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
451 WINE_StringFromCLSID((LPCLSID)riid,xriid);
453 TRACE("(%s, %p, %s, %p)\n", xclsid, pUnkOuter, xriid, ppvObj);
456 * Sanity check
458 if (ppvObj==0)
459 return E_POINTER;
461 *ppvObj = 0;
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,
477 pUnkOuter);
479 if (newCache == 0)
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));
493 return hr;
496 /*********************************************************
497 * Method implementation for DataCache class.
499 static DataCache* DataCache_Construct(
500 REFCLSID clsid,
501 LPUNKNOWN pUnkOuter)
503 DataCache* newObject = 0;
506 * Allocate space for the object.
508 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache));
510 if (newObject==0)
511 return newObject;
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.
527 newObject->ref = 1;
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
533 * lifetime.
535 if (pUnkOuter==NULL)
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;
548 return newObject;
551 static void DataCache_Destroy(
552 DataCache* ptrToDestroy)
554 TRACE("()\n");
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.
580 * Param:
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(
587 DataCache* this,
588 DWORD drawAspect,
589 PresentationDataHeader* header)
591 IStream* presStream = NULL;
592 OLECHAR streamName[20];
593 HRESULT hres;
596 * Get the name for the presentation stream.
598 hres = DataCache_FindPresStreamName(
599 this,
600 drawAspect,
601 streamName);
603 if (FAILED(hres))
604 return hres;
607 * Open the stream and read the header.
609 hres = IStorage_OpenStream(
610 this->presentationStorage,
611 streamName,
612 NULL,
613 STGM_READ | STGM_SHARE_EXCLUSIVE,
615 &presStream);
617 if (FAILED(hres))
618 return hres;
620 hres = IStream_Read(
621 presStream,
622 header,
623 sizeof(PresentationDataHeader),
624 NULL);
627 * Cleanup.
629 IStream_Release(presStream);
632 * We don't want to propagate any other error
633 * code than a failure.
635 if (hres!=S_OK)
636 hres = E_FAIL;
638 return hres;
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(
650 DataCache* this,
651 DWORD aspect,
652 LONG lindex)
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
659 * filter matches.
661 if ((this->sinkAspects & aspect) != 0)
663 if (this->sinkInterface != NULL)
665 IAdviseSink_OnViewChange(this->sinkInterface,
666 aspect,
667 lindex);
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.
691 * Param:
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.
697 * NOTE:
698 * This method only supports the DVASPECT_CONTENT aspect.
700 static HRESULT DataCache_FindPresStreamName(
701 DataCache* this,
702 DWORD drawAspect,
703 OLECHAR* buffer)
705 OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
707 if (drawAspect!=DVASPECT_CONTENT)
708 return E_FAIL;
710 memcpy(buffer, name, sizeof(name));
712 return S_OK;
715 /************************************************************************
716 * DataCache_ReadPresentationData
718 * This method will read information for the requested presentation
719 * into the given structure.
721 * Param:
722 * this - Pointer to the DataCache object
723 * drawAspect - The aspect of the object that we wish to draw.
725 * Returns:
726 * This method returns a metafile handle if it is successful.
727 * it will return 0 if not.
729 static HMETAFILE DataCache_ReadPresMetafile(
730 DataCache* this,
731 DWORD drawAspect)
733 LARGE_INTEGER offset;
734 IStream* presStream = NULL;
735 OLECHAR streamName[20];
736 HRESULT hres;
737 void* metafileBits;
738 STATSTG streamInfo;
739 HMETAFILE newMetafile = 0;
742 * Get the name for the presentation stream.
744 hres = DataCache_FindPresStreamName(
745 this,
746 drawAspect,
747 streamName);
749 if (FAILED(hres))
750 return hres;
753 * Open the stream and read the header.
755 hres = IStorage_OpenStream(
756 this->presentationStorage,
757 streamName,
758 NULL,
759 STGM_READ | STGM_SHARE_EXCLUSIVE,
761 &presStream);
763 if (FAILED(hres))
764 return hres;
767 * Get the size of the stream.
769 hres = IStream_Stat(presStream,
770 &streamInfo,
771 STATFLAG_NONAME);
774 * Skip the header
776 offset.HighPart = 0;
777 offset.LowPart = sizeof(PresentationDataHeader);
779 hres = IStream_Seek(
780 presStream,
781 offset,
782 STREAM_SEEK_SET,
783 NULL);
786 * Allocate a buffer for the metafile bits.
788 metafileBits = HeapAlloc(GetProcessHeap(),
790 streamInfo.cbSize.LowPart);
793 * Read the metafile bits.
795 hres = IStream_Read(
796 presStream,
797 metafileBits,
798 streamInfo.cbSize.LowPart,
799 NULL);
802 * Create a metafile with those bits.
804 if (SUCCEEDED(hres))
806 newMetafile = SetMetaFileBitsEx(streamInfo.cbSize.LowPart, metafileBits);
810 * Cleanup.
812 HeapFree(GetProcessHeap(), 0, metafileBits);
813 IStream_Release(presStream);
815 if (newMetafile==0)
816 hres = E_FAIL;
818 return newMetafile;
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(
835 IUnknown* iface,
836 REFIID riid,
837 void** ppvObject)
839 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
842 * Perform a sanity check on the parameters.
844 if ( (this==0) || (ppvObject==0) )
845 return E_INVALIDARG;
848 * Initialize the return parameter.
850 *ppvObject = 0;
853 * Compare the riid with the interface IDs implemented by this object.
855 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
857 *ppvObject = iface;
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.
886 if ((*ppvObject)==0)
888 char clsid[50];
890 WINE_StringFromCLSID((LPCLSID)riid,clsid);
892 WARN(
893 "() : asking for un supported interface %s\n",
894 clsid);
896 return E_NOINTERFACE;
900 * Query Interface always increases the reference count by one when it is
901 * successful.
903 IUnknown_AddRef((IUnknown*)*ppvObject);
905 return S_OK;;
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(
917 IUnknown* iface)
919 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
921 this->ref++;
923 return this->ref;
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(
935 IUnknown* iface)
937 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
940 * Decrease the reference count on this object.
942 this->ref--;
945 * If the reference count goes down to 0, perform suicide.
947 if (this->ref==0)
949 DataCache_Destroy(this);
951 return 0;
954 return this->ref;
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(
968 IDataObject* iface,
969 REFIID riid,
970 void** ppvObject)
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(
983 IDataObject* iface)
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(
996 IDataObject* iface)
998 _ICOM_THIS_From_IDataObject(DataCache, iface);
1000 return IUnknown_Release(this->outerUnknown);
1003 static HRESULT WINAPI DataCache_GetData(
1004 IDataObject* iface,
1005 LPFORMATETC pformatetcIn,
1006 STGMEDIUM* pmedium)
1008 FIXME("stub\n");
1009 return E_NOTIMPL;
1012 static HRESULT WINAPI DataCache_GetDataHere(
1013 IDataObject* iface,
1014 LPFORMATETC pformatetc,
1015 STGMEDIUM* pmedium)
1017 FIXME("stub\n");
1018 return E_NOTIMPL;
1021 static HRESULT WINAPI DataCache_QueryGetData(
1022 IDataObject* iface,
1023 LPFORMATETC pformatetc)
1025 FIXME("stub\n");
1026 return E_NOTIMPL;
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(
1037 IDataObject* iface,
1038 LPFORMATETC pformatectIn,
1039 LPFORMATETC pformatetcOut)
1041 TRACE("()\n");
1042 return E_NOTIMPL;
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(
1053 IDataObject* iface,
1054 LPFORMATETC pformatetc,
1055 STGMEDIUM* pmedium,
1056 BOOL fRelease)
1058 IOleCache2* oleCache = NULL;
1059 HRESULT hres;
1061 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1063 hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);
1065 if (FAILED(hres))
1066 return E_UNEXPECTED;
1068 hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);
1070 IOleCache2_Release(oleCache);
1072 return hres;;
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(
1083 IDataObject* iface,
1084 DWORD dwDirection,
1085 IEnumFORMATETC** ppenumFormatEtc)
1087 TRACE("()\n");
1088 return E_NOTIMPL;
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(
1099 IDataObject* iface,
1100 FORMATETC* pformatetc,
1101 DWORD advf,
1102 IAdviseSink* pAdvSink,
1103 DWORD* pdwConnection)
1105 TRACE("()\n");
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(
1117 IDataObject* iface,
1118 DWORD dwConnection)
1120 TRACE("()\n");
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(
1132 IDataObject* iface,
1133 IEnumSTATDATA** ppenumAdvise)
1135 TRACE("()\n");
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,
1151 REFIID riid,
1152 void** ppvObject)
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,
1194 CLSID* pClassID)
1196 TRACE("(%p, %p)\n", iface, pClassID);
1197 return E_NOTIMPL;
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);
1213 return S_FALSE;
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,
1226 IStorage* pStg)
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,
1245 IStorage* pStg)
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);
1263 return S_OK;
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
1272 * storage.
1274 * See Windows documentation for more details on IPersistStorage methods.
1276 static HRESULT WINAPI DataCache_Save(
1277 IPersistStorage* iface,
1278 IStorage* pStg,
1279 BOOL fSameAsLoad)
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,
1290 NULL,
1291 NULL,
1292 pStg);
1295 return S_OK;
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,
1308 IStorage* pStgNew)
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);
1322 return S_OK;
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;
1346 return S_OK;
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,
1361 REFIID riid,
1362 void** ppvObject)
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,
1405 DWORD dwDrawAspect,
1406 LONG lindex,
1407 void* pvAspect,
1408 DVTARGETDEVICE* ptd,
1409 HDC hdcTargetDev,
1410 HDC hdcDraw,
1411 LPCRECTL lprcBounds,
1412 LPCRECTL lprcWBounds,
1413 IVO_ContCallback pfnContinue,
1414 DWORD dwContinue)
1416 PresentationDataHeader presData;
1417 HMETAFILE presMetafile = 0;
1418 HRESULT hres;
1420 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1422 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1423 iface,
1424 dwDrawAspect,
1425 lindex,
1426 pvAspect,
1427 hdcTargetDev,
1428 hdcDraw,
1429 lprcBounds,
1430 lprcWBounds,
1431 pfnContinue,
1432 dwContinue);
1435 * Sanity check
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,
1445 dwDrawAspect,
1446 &presData);
1448 if (FAILED(hres))
1449 return hres;
1452 * Then, we can extract the metafile itself from the cached
1453 * data.
1455 presMetafile = DataCache_ReadPresMetafile(this,
1456 dwDrawAspect);
1459 * If we have a metafile, just draw baby...
1460 * We have to be careful not to modify the state of the
1461 * DC.
1463 if (presMetafile!=0)
1465 INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC);
1466 SIZE oldWindowExt;
1467 SIZE oldViewportExt;
1468 POINT oldViewportOrg;
1470 SetWindowExtEx(hdcDraw,
1471 presData.objectExtentX,
1472 presData.objectExtentY,
1473 &oldWindowExt);
1475 SetViewportExtEx(hdcDraw,
1476 lprcBounds->right - lprcBounds->left,
1477 lprcBounds->bottom - lprcBounds->top,
1478 &oldViewportExt);
1480 SetViewportOrgEx(hdcDraw,
1481 lprcBounds->left,
1482 lprcBounds->top,
1483 &oldViewportOrg);
1485 PlayMetaFile(hdcDraw, presMetafile);
1487 SetWindowExtEx(hdcDraw,
1488 oldWindowExt.cx,
1489 oldWindowExt.cy,
1490 NULL);
1492 SetViewportExtEx(hdcDraw,
1493 oldViewportExt.cx,
1494 oldViewportExt.cy,
1495 NULL);
1497 SetViewportOrgEx(hdcDraw,
1498 oldViewportOrg.x,
1499 oldViewportOrg.y,
1500 NULL);
1502 SetMapMode(hdcDraw, prevMapMode);
1504 DeleteMetaFile(presMetafile);
1507 return S_OK;
1510 static HRESULT WINAPI DataCache_GetColorSet(
1511 IViewObject2* iface,
1512 DWORD dwDrawAspect,
1513 LONG lindex,
1514 void* pvAspect,
1515 DVTARGETDEVICE* ptd,
1516 HDC hicTargetDevice,
1517 LOGPALETTE** ppColorSet)
1519 FIXME("stub\n");
1520 return E_NOTIMPL;
1523 static HRESULT WINAPI DataCache_Freeze(
1524 IViewObject2* iface,
1525 DWORD dwDrawAspect,
1526 LONG lindex,
1527 void* pvAspect,
1528 DWORD* pdwFreeze)
1530 FIXME("stub\n");
1531 return E_NOTIMPL;
1534 static HRESULT WINAPI DataCache_Unfreeze(
1535 IViewObject2* iface,
1536 DWORD dwFreeze)
1538 FIXME("stub\n");
1539 return E_NOTIMPL;
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,
1552 DWORD aspects,
1553 DWORD advf,
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.
1574 if (pAdvSink!=NULL)
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
1585 * sink immediately.
1587 if (advf & ADVF_PRIMEFIRST)
1589 DataCache_FireOnViewChange(this,
1590 DVASPECT_CONTENT,
1591 -1);
1594 return S_OK;
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,
1607 DWORD* pAspects,
1608 DWORD* pAdvf,
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.
1618 if (pAspects!=NULL)
1619 *pAspects = this->sinkAspects;
1621 if (pAdvf!=NULL)
1622 *pAdvf = this->sinkAdviseFlag;
1624 if (ppAdvSink!=NULL)
1626 IAdviseSink_QueryInterface(this->sinkInterface,
1627 &IID_IAdviseSink,
1628 (void**)ppAdvSink);
1631 return S_OK;
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,
1643 DWORD dwDrawAspect,
1644 LONG lindex,
1645 DVTARGETDEVICE* ptd,
1646 LPSIZEL lpsizel)
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);
1657 * Sanity check
1659 if (lpsizel==NULL)
1660 return E_POINTER;
1663 * Initialize the out parameter.
1665 lpsizel->cx = 0;
1666 lpsizel->cy = 0;
1669 * This flag should be set to -1.
1671 if (lindex!=-1)
1672 FIXME("Unimplemented flag lindex = %ld\n", lindex);
1675 * Right now, we suport only the callback from
1676 * the default handler.
1678 if (ptd!=NULL)
1679 FIXME("Unimplemented ptd = %p\n", ptd);
1682 * Get the presentation information from the
1683 * cache.
1685 hres = DataCache_ReadPresentationData(this,
1686 dwDrawAspect,
1687 &presData);
1689 if (SUCCEEDED(hres))
1691 lpsizel->cx = presData.objectExtentX;
1692 lpsizel->cy = presData.objectExtentY;
1696 * This method returns OLE_E_BLANK when it fails.
1698 if (FAILED(hres))
1699 hres = OLE_E_BLANK;
1701 return hres;
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(
1716 IOleCache2* iface,
1717 REFIID riid,
1718 void** ppvObject)
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(
1731 IOleCache2* iface)
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(
1744 IOleCache2* iface)
1746 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1748 return IUnknown_Release(this->outerUnknown);
1751 static HRESULT WINAPI DataCache_Cache(
1752 IOleCache2* iface,
1753 FORMATETC* pformatetc,
1754 DWORD advf,
1755 DWORD* pdwConnection)
1757 FIXME("stub\n");
1758 return E_NOTIMPL;
1761 static HRESULT WINAPI DataCache_Uncache(
1762 IOleCache2* iface,
1763 DWORD dwConnection)
1765 FIXME("stub\n");
1766 return E_NOTIMPL;
1769 static HRESULT WINAPI DataCache_EnumCache(
1770 IOleCache2* iface,
1771 IEnumSTATDATA** ppenumSTATDATA)
1773 FIXME("stub\n");
1774 return E_NOTIMPL;
1777 static HRESULT WINAPI DataCache_InitCache(
1778 IOleCache2* iface,
1779 IDataObject* pDataObject)
1781 FIXME("stub\n");
1782 return E_NOTIMPL;
1785 static HRESULT WINAPI DataCache_IOleCache2_SetData(
1786 IOleCache2* iface,
1787 FORMATETC* pformatetc,
1788 STGMEDIUM* pmedium,
1789 BOOL fRelease)
1791 FIXME("stub\n");
1792 return E_NOTIMPL;
1795 static HRESULT WINAPI DataCache_UpdateCache(
1796 IOleCache2* iface,
1797 LPDATAOBJECT pDataObject,
1798 DWORD grfUpdf,
1799 LPVOID pReserved)
1801 FIXME("stub\n");
1802 return E_NOTIMPL;
1805 static HRESULT WINAPI DataCache_DiscardCache(
1806 IOleCache2* iface,
1807 DWORD dwDiscardOptions)
1809 FIXME("stub\n");
1810 return E_NOTIMPL;
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,
1826 REFIID riid,
1827 void** ppvObject)
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)
1864 FIXME("stub\n");
1865 return E_NOTIMPL;
1868 static HRESULT WINAPI DataCache_OnStop(
1869 IOleCacheControl* iface)
1871 FIXME("stub\n");
1872 return E_NOTIMPL;