Added stub for CoResumeClassObjects.
[wine.git] / dlls / ole32 / datacache.c
blob0458929efb115b1a546eb6ef7b85108fb4479903
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 "windef.h"
35 #include "winbase.h"
36 #include "wingdi.h"
37 #include "winerror.h"
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
54 DWORD unknown1;
55 DWORD unknown2;
56 DWORD unknown3;
57 DWORD unknown4;
58 DWORD unknown5;
60 DWORD unknown6;
61 DWORD unknown7;
62 DWORD objectExtentX;
63 DWORD objectExtentY;
64 DWORD unknown8;
65 } PresentationDataHeader;
67 /****************************************************************************
68 * DataCache
70 struct DataCache
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
85 ULONG ref;
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
102 * that connection.
104 DWORD sinkAspects;
105 DWORD sinkAdviseFlag;
106 IAdviseSink* sinkInterface;
110 typedef struct DataCache DataCache;
113 * Here, I define utility macros to help with the casting of the
114 * "this" parameter.
115 * There is a version to accomodate all of the VTables implemented
116 * by this object.
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,
132 DWORD drawAspect,
133 PresentationDataHeader* header);
134 static HRESULT DataCache_FindPresStreamName(DataCache* this,
135 DWORD drawAspect,
136 OLECHAR* buffer);
137 static HMETAFILE DataCache_ReadPresMetafile(DataCache* this,
138 DWORD drawAspect);
139 static void DataCache_FireOnViewChange(DataCache* this,
140 DWORD aspect,
141 LONG lindex);
144 * Prototypes for the methods of the DataCache class
145 * that implement non delegating IUnknown methods.
147 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
148 IUnknown* iface,
149 REFIID riid,
150 void** ppvObject);
151 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
152 IUnknown* iface);
153 static ULONG WINAPI DataCache_NDIUnknown_Release(
154 IUnknown* iface);
157 * Prototypes for the methods of the DataCache class
158 * that implement IDataObject methods.
160 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
161 IDataObject* iface,
162 REFIID riid,
163 void** ppvObject);
164 static ULONG WINAPI DataCache_IDataObject_AddRef(
165 IDataObject* iface);
166 static ULONG WINAPI DataCache_IDataObject_Release(
167 IDataObject* iface);
168 static HRESULT WINAPI DataCache_GetData(
169 IDataObject* iface,
170 LPFORMATETC pformatetcIn,
171 STGMEDIUM* pmedium);
172 static HRESULT WINAPI DataCache_GetDataHere(
173 IDataObject* iface,
174 LPFORMATETC pformatetc,
175 STGMEDIUM* pmedium);
176 static HRESULT WINAPI DataCache_QueryGetData(
177 IDataObject* iface,
178 LPFORMATETC pformatetc);
179 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
180 IDataObject* iface,
181 LPFORMATETC pformatectIn,
182 LPFORMATETC pformatetcOut);
183 static HRESULT WINAPI DataCache_IDataObject_SetData(
184 IDataObject* iface,
185 LPFORMATETC pformatetc,
186 STGMEDIUM* pmedium,
187 BOOL fRelease);
188 static HRESULT WINAPI DataCache_EnumFormatEtc(
189 IDataObject* iface,
190 DWORD dwDirection,
191 IEnumFORMATETC** ppenumFormatEtc);
192 static HRESULT WINAPI DataCache_DAdvise(
193 IDataObject* iface,
194 FORMATETC* pformatetc,
195 DWORD advf,
196 IAdviseSink* pAdvSink,
197 DWORD* pdwConnection);
198 static HRESULT WINAPI DataCache_DUnadvise(
199 IDataObject* iface,
200 DWORD dwConnection);
201 static HRESULT WINAPI DataCache_EnumDAdvise(
202 IDataObject* iface,
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,
211 REFIID riid,
212 void** ppvObject);
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,
219 CLSID* pClassID);
220 static HRESULT WINAPI DataCache_IsDirty(
221 IPersistStorage* iface);
222 static HRESULT WINAPI DataCache_InitNew(
223 IPersistStorage* iface,
224 IStorage* pStg);
225 static HRESULT WINAPI DataCache_Load(
226 IPersistStorage* iface,
227 IStorage* pStg);
228 static HRESULT WINAPI DataCache_Save(
229 IPersistStorage* iface,
230 IStorage* pStg,
231 BOOL fSameAsLoad);
232 static HRESULT WINAPI DataCache_SaveCompleted(
233 IPersistStorage* iface,
234 IStorage* pStgNew);
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(
243 IViewObject2* iface,
244 REFIID riid,
245 void** ppvObject);
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(
251 IViewObject2* iface,
252 DWORD dwDrawAspect,
253 LONG lindex,
254 void* pvAspect,
255 DVTARGETDEVICE* ptd,
256 HDC hdcTargetDev,
257 HDC hdcDraw,
258 LPCRECTL lprcBounds,
259 LPCRECTL lprcWBounds,
260 IVO_ContCallback pfnContinue,
261 DWORD dwContinue);
262 static HRESULT WINAPI DataCache_GetColorSet(
263 IViewObject2* iface,
264 DWORD dwDrawAspect,
265 LONG lindex,
266 void* pvAspect,
267 DVTARGETDEVICE* ptd,
268 HDC hicTargetDevice,
269 LOGPALETTE** ppColorSet);
270 static HRESULT WINAPI DataCache_Freeze(
271 IViewObject2* iface,
272 DWORD dwDrawAspect,
273 LONG lindex,
274 void* pvAspect,
275 DWORD* pdwFreeze);
276 static HRESULT WINAPI DataCache_Unfreeze(
277 IViewObject2* iface,
278 DWORD dwFreeze);
279 static HRESULT WINAPI DataCache_SetAdvise(
280 IViewObject2* iface,
281 DWORD aspects,
282 DWORD advf,
283 IAdviseSink* pAdvSink);
284 static HRESULT WINAPI DataCache_GetAdvise(
285 IViewObject2* iface,
286 DWORD* pAspects,
287 DWORD* pAdvf,
288 IAdviseSink** ppAdvSink);
289 static HRESULT WINAPI DataCache_GetExtent(
290 IViewObject2* iface,
291 DWORD dwDrawAspect,
292 LONG lindex,
293 DVTARGETDEVICE* ptd,
294 LPSIZEL lpsizel);
297 * Prototypes for the methods of the DataCache class
298 * that implement IOleCache2 methods.
300 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
301 IOleCache2* iface,
302 REFIID riid,
303 void** ppvObject);
304 static ULONG WINAPI DataCache_IOleCache2_AddRef(
305 IOleCache2* iface);
306 static ULONG WINAPI DataCache_IOleCache2_Release(
307 IOleCache2* iface);
308 static HRESULT WINAPI DataCache_Cache(
309 IOleCache2* iface,
310 FORMATETC* pformatetc,
311 DWORD advf,
312 DWORD* pdwConnection);
313 static HRESULT WINAPI DataCache_Uncache(
314 IOleCache2* iface,
315 DWORD dwConnection);
316 static HRESULT WINAPI DataCache_EnumCache(
317 IOleCache2* iface,
318 IEnumSTATDATA** ppenumSTATDATA);
319 static HRESULT WINAPI DataCache_InitCache(
320 IOleCache2* iface,
321 IDataObject* pDataObject);
322 static HRESULT WINAPI DataCache_IOleCache2_SetData(
323 IOleCache2* iface,
324 FORMATETC* pformatetc,
325 STGMEDIUM* pmedium,
326 BOOL fRelease);
327 static HRESULT WINAPI DataCache_UpdateCache(
328 IOleCache2* iface,
329 LPDATAOBJECT pDataObject,
330 DWORD grfUpdf,
331 LPVOID pReserved);
332 static HRESULT WINAPI DataCache_DiscardCache(
333 IOleCache2* iface,
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,
342 REFIID riid,
343 void** ppvObject);
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,
371 DataCache_GetData,
372 DataCache_GetDataHere,
373 DataCache_QueryGetData,
374 DataCache_GetCanonicalFormatEtc,
375 DataCache_IDataObject_SetData,
376 DataCache_EnumFormatEtc,
377 DataCache_DAdvise,
378 DataCache_DUnadvise,
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,
389 DataCache_IsDirty,
390 DataCache_InitNew,
391 DataCache_Load,
392 DataCache_Save,
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,
403 DataCache_Draw,
404 DataCache_GetColorSet,
405 DataCache_Freeze,
406 DataCache_Unfreeze,
407 DataCache_SetAdvise,
408 DataCache_GetAdvise,
409 DataCache_GetExtent
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,
418 DataCache_Cache,
419 DataCache_Uncache,
420 DataCache_EnumCache,
421 DataCache_InitCache,
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,
433 DataCache_OnRun,
434 DataCache_OnStop
437 /******************************************************************************
438 * CreateDataCache [OLE32.54]
440 HRESULT WINAPI CreateDataCache(
441 LPUNKNOWN pUnkOuter,
442 REFCLSID rclsid,
443 REFIID riid,
444 LPVOID* ppvObj)
446 DataCache* newCache = NULL;
447 HRESULT hr = S_OK;
449 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(rclsid), pUnkOuter, debugstr_guid(riid), ppvObj);
452 * Sanity check
454 if (ppvObj==0)
455 return E_POINTER;
457 *ppvObj = 0;
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,
473 pUnkOuter);
475 if (newCache == 0)
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));
489 return hr;
492 /*********************************************************
493 * Method implementation for DataCache class.
495 static DataCache* DataCache_Construct(
496 REFCLSID clsid,
497 LPUNKNOWN pUnkOuter)
499 DataCache* newObject = 0;
502 * Allocate space for the object.
504 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache));
506 if (newObject==0)
507 return newObject;
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.
523 newObject->ref = 1;
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
529 * lifetime.
531 if (pUnkOuter==NULL)
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;
544 return newObject;
547 static void DataCache_Destroy(
548 DataCache* ptrToDestroy)
550 TRACE("()\n");
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.
576 * Param:
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(
583 DataCache* this,
584 DWORD drawAspect,
585 PresentationDataHeader* header)
587 IStream* presStream = NULL;
588 OLECHAR streamName[20];
589 HRESULT hres;
592 * Get the name for the presentation stream.
594 hres = DataCache_FindPresStreamName(
595 this,
596 drawAspect,
597 streamName);
599 if (FAILED(hres))
600 return hres;
603 * Open the stream and read the header.
605 hres = IStorage_OpenStream(
606 this->presentationStorage,
607 streamName,
608 NULL,
609 STGM_READ | STGM_SHARE_EXCLUSIVE,
611 &presStream);
613 if (FAILED(hres))
614 return hres;
616 hres = IStream_Read(
617 presStream,
618 header,
619 sizeof(PresentationDataHeader),
620 NULL);
623 * Cleanup.
625 IStream_Release(presStream);
628 * We don't want to propagate any other error
629 * code than a failure.
631 if (hres!=S_OK)
632 hres = E_FAIL;
634 return hres;
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(
646 DataCache* this,
647 DWORD aspect,
648 LONG lindex)
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
655 * filter matches.
657 if ((this->sinkAspects & aspect) != 0)
659 if (this->sinkInterface != NULL)
661 IAdviseSink_OnViewChange(this->sinkInterface,
662 aspect,
663 lindex);
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.
687 * Param:
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.
693 * NOTE:
694 * This method only supports the DVASPECT_CONTENT aspect.
696 static HRESULT DataCache_FindPresStreamName(
697 DataCache* this,
698 DWORD drawAspect,
699 OLECHAR* buffer)
701 OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
703 if (drawAspect!=DVASPECT_CONTENT)
704 return E_FAIL;
706 memcpy(buffer, name, sizeof(name));
708 return S_OK;
711 /************************************************************************
712 * DataCache_ReadPresentationData
714 * This method will read information for the requested presentation
715 * into the given structure.
717 * Param:
718 * this - Pointer to the DataCache object
719 * drawAspect - The aspect of the object that we wish to draw.
721 * Returns:
722 * This method returns a metafile handle if it is successful.
723 * it will return 0 if not.
725 static HMETAFILE DataCache_ReadPresMetafile(
726 DataCache* this,
727 DWORD drawAspect)
729 LARGE_INTEGER offset;
730 IStream* presStream = NULL;
731 OLECHAR streamName[20];
732 HRESULT hres;
733 void* metafileBits;
734 STATSTG streamInfo;
735 HMETAFILE newMetafile = 0;
738 * Get the name for the presentation stream.
740 hres = DataCache_FindPresStreamName(
741 this,
742 drawAspect,
743 streamName);
745 if (FAILED(hres))
746 return hres;
749 * Open the stream and read the header.
751 hres = IStorage_OpenStream(
752 this->presentationStorage,
753 streamName,
754 NULL,
755 STGM_READ | STGM_SHARE_EXCLUSIVE,
757 &presStream);
759 if (FAILED(hres))
760 return hres;
763 * Get the size of the stream.
765 hres = IStream_Stat(presStream,
766 &streamInfo,
767 STATFLAG_NONAME);
770 * Skip the header
772 offset.s.HighPart = 0;
773 offset.s.LowPart = sizeof(PresentationDataHeader);
775 hres = IStream_Seek(
776 presStream,
777 offset,
778 STREAM_SEEK_SET,
779 NULL);
782 * Allocate a buffer for the metafile bits.
784 metafileBits = HeapAlloc(GetProcessHeap(),
786 streamInfo.cbSize.s.LowPart);
789 * Read the metafile bits.
791 hres = IStream_Read(
792 presStream,
793 metafileBits,
794 streamInfo.cbSize.s.LowPart,
795 NULL);
798 * Create a metafile with those bits.
800 if (SUCCEEDED(hres))
802 newMetafile = SetMetaFileBitsEx(streamInfo.cbSize.s.LowPart, metafileBits);
806 * Cleanup.
808 HeapFree(GetProcessHeap(), 0, metafileBits);
809 IStream_Release(presStream);
811 if (newMetafile==0)
812 hres = E_FAIL;
814 return newMetafile;
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(
831 IUnknown* iface,
832 REFIID riid,
833 void** ppvObject)
835 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
838 * Perform a sanity check on the parameters.
840 if ( (this==0) || (ppvObject==0) )
841 return E_INVALIDARG;
844 * Initialize the return parameter.
846 *ppvObject = 0;
849 * Compare the riid with the interface IDs implemented by this object.
851 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
853 *ppvObject = iface;
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.
882 if ((*ppvObject)==0)
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
890 * successful.
892 IUnknown_AddRef((IUnknown*)*ppvObject);
894 return S_OK;;
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(
906 IUnknown* iface)
908 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
910 this->ref++;
912 return this->ref;
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(
924 IUnknown* iface)
926 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
929 * Decrease the reference count on this object.
931 this->ref--;
934 * If the reference count goes down to 0, perform suicide.
936 if (this->ref==0)
938 DataCache_Destroy(this);
940 return 0;
943 return this->ref;
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(
957 IDataObject* iface,
958 REFIID riid,
959 void** ppvObject)
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(
972 IDataObject* iface)
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(
985 IDataObject* iface)
987 _ICOM_THIS_From_IDataObject(DataCache, iface);
989 return IUnknown_Release(this->outerUnknown);
992 static HRESULT WINAPI DataCache_GetData(
993 IDataObject* iface,
994 LPFORMATETC pformatetcIn,
995 STGMEDIUM* pmedium)
997 FIXME("stub\n");
998 return E_NOTIMPL;
1001 static HRESULT WINAPI DataCache_GetDataHere(
1002 IDataObject* iface,
1003 LPFORMATETC pformatetc,
1004 STGMEDIUM* pmedium)
1006 FIXME("stub\n");
1007 return E_NOTIMPL;
1010 static HRESULT WINAPI DataCache_QueryGetData(
1011 IDataObject* iface,
1012 LPFORMATETC pformatetc)
1014 FIXME("stub\n");
1015 return E_NOTIMPL;
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(
1026 IDataObject* iface,
1027 LPFORMATETC pformatectIn,
1028 LPFORMATETC pformatetcOut)
1030 TRACE("()\n");
1031 return E_NOTIMPL;
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(
1042 IDataObject* iface,
1043 LPFORMATETC pformatetc,
1044 STGMEDIUM* pmedium,
1045 BOOL fRelease)
1047 IOleCache2* oleCache = NULL;
1048 HRESULT hres;
1050 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1052 hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);
1054 if (FAILED(hres))
1055 return E_UNEXPECTED;
1057 hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);
1059 IOleCache2_Release(oleCache);
1061 return hres;;
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(
1072 IDataObject* iface,
1073 DWORD dwDirection,
1074 IEnumFORMATETC** ppenumFormatEtc)
1076 TRACE("()\n");
1077 return E_NOTIMPL;
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(
1088 IDataObject* iface,
1089 FORMATETC* pformatetc,
1090 DWORD advf,
1091 IAdviseSink* pAdvSink,
1092 DWORD* pdwConnection)
1094 TRACE("()\n");
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(
1106 IDataObject* iface,
1107 DWORD dwConnection)
1109 TRACE("()\n");
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(
1121 IDataObject* iface,
1122 IEnumSTATDATA** ppenumAdvise)
1124 TRACE("()\n");
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,
1140 REFIID riid,
1141 void** ppvObject)
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,
1183 CLSID* pClassID)
1185 TRACE("(%p, %p)\n", iface, pClassID);
1186 return E_NOTIMPL;
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);
1202 return S_FALSE;
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,
1215 IStorage* pStg)
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,
1234 IStorage* pStg)
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);
1252 return S_OK;
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
1261 * storage.
1263 * See Windows documentation for more details on IPersistStorage methods.
1265 static HRESULT WINAPI DataCache_Save(
1266 IPersistStorage* iface,
1267 IStorage* pStg,
1268 BOOL fSameAsLoad)
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,
1279 NULL,
1280 NULL,
1281 pStg);
1284 return S_OK;
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,
1297 IStorage* pStgNew)
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);
1311 return S_OK;
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;
1335 return S_OK;
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,
1350 REFIID riid,
1351 void** ppvObject)
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,
1394 DWORD dwDrawAspect,
1395 LONG lindex,
1396 void* pvAspect,
1397 DVTARGETDEVICE* ptd,
1398 HDC hdcTargetDev,
1399 HDC hdcDraw,
1400 LPCRECTL lprcBounds,
1401 LPCRECTL lprcWBounds,
1402 IVO_ContCallback pfnContinue,
1403 DWORD dwContinue)
1405 PresentationDataHeader presData;
1406 HMETAFILE presMetafile = 0;
1407 HRESULT hres;
1409 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1411 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1412 iface,
1413 dwDrawAspect,
1414 lindex,
1415 pvAspect,
1416 hdcTargetDev,
1417 hdcDraw,
1418 lprcBounds,
1419 lprcWBounds,
1420 pfnContinue,
1421 dwContinue);
1424 * Sanity check
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,
1434 dwDrawAspect,
1435 &presData);
1437 if (FAILED(hres))
1438 return hres;
1441 * Then, we can extract the metafile itself from the cached
1442 * data.
1444 presMetafile = DataCache_ReadPresMetafile(this,
1445 dwDrawAspect);
1448 * If we have a metafile, just draw baby...
1449 * We have to be careful not to modify the state of the
1450 * DC.
1452 if (presMetafile!=0)
1454 INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC);
1455 SIZE oldWindowExt;
1456 SIZE oldViewportExt;
1457 POINT oldViewportOrg;
1459 SetWindowExtEx(hdcDraw,
1460 presData.objectExtentX,
1461 presData.objectExtentY,
1462 &oldWindowExt);
1464 SetViewportExtEx(hdcDraw,
1465 lprcBounds->right - lprcBounds->left,
1466 lprcBounds->bottom - lprcBounds->top,
1467 &oldViewportExt);
1469 SetViewportOrgEx(hdcDraw,
1470 lprcBounds->left,
1471 lprcBounds->top,
1472 &oldViewportOrg);
1474 PlayMetaFile(hdcDraw, presMetafile);
1476 SetWindowExtEx(hdcDraw,
1477 oldWindowExt.cx,
1478 oldWindowExt.cy,
1479 NULL);
1481 SetViewportExtEx(hdcDraw,
1482 oldViewportExt.cx,
1483 oldViewportExt.cy,
1484 NULL);
1486 SetViewportOrgEx(hdcDraw,
1487 oldViewportOrg.x,
1488 oldViewportOrg.y,
1489 NULL);
1491 SetMapMode(hdcDraw, prevMapMode);
1493 DeleteMetaFile(presMetafile);
1496 return S_OK;
1499 static HRESULT WINAPI DataCache_GetColorSet(
1500 IViewObject2* iface,
1501 DWORD dwDrawAspect,
1502 LONG lindex,
1503 void* pvAspect,
1504 DVTARGETDEVICE* ptd,
1505 HDC hicTargetDevice,
1506 LOGPALETTE** ppColorSet)
1508 FIXME("stub\n");
1509 return E_NOTIMPL;
1512 static HRESULT WINAPI DataCache_Freeze(
1513 IViewObject2* iface,
1514 DWORD dwDrawAspect,
1515 LONG lindex,
1516 void* pvAspect,
1517 DWORD* pdwFreeze)
1519 FIXME("stub\n");
1520 return E_NOTIMPL;
1523 static HRESULT WINAPI DataCache_Unfreeze(
1524 IViewObject2* iface,
1525 DWORD dwFreeze)
1527 FIXME("stub\n");
1528 return E_NOTIMPL;
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,
1541 DWORD aspects,
1542 DWORD advf,
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.
1563 if (pAdvSink!=NULL)
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
1574 * sink immediately.
1576 if (advf & ADVF_PRIMEFIRST)
1578 DataCache_FireOnViewChange(this,
1579 DVASPECT_CONTENT,
1580 -1);
1583 return S_OK;
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,
1596 DWORD* pAspects,
1597 DWORD* pAdvf,
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.
1607 if (pAspects!=NULL)
1608 *pAspects = this->sinkAspects;
1610 if (pAdvf!=NULL)
1611 *pAdvf = this->sinkAdviseFlag;
1613 if (ppAdvSink!=NULL)
1615 IAdviseSink_QueryInterface(this->sinkInterface,
1616 &IID_IAdviseSink,
1617 (void**)ppAdvSink);
1620 return S_OK;
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,
1632 DWORD dwDrawAspect,
1633 LONG lindex,
1634 DVTARGETDEVICE* ptd,
1635 LPSIZEL lpsizel)
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);
1646 * Sanity check
1648 if (lpsizel==NULL)
1649 return E_POINTER;
1652 * Initialize the out parameter.
1654 lpsizel->cx = 0;
1655 lpsizel->cy = 0;
1658 * This flag should be set to -1.
1660 if (lindex!=-1)
1661 FIXME("Unimplemented flag lindex = %ld\n", lindex);
1664 * Right now, we suport only the callback from
1665 * the default handler.
1667 if (ptd!=NULL)
1668 FIXME("Unimplemented ptd = %p\n", ptd);
1671 * Get the presentation information from the
1672 * cache.
1674 hres = DataCache_ReadPresentationData(this,
1675 dwDrawAspect,
1676 &presData);
1678 if (SUCCEEDED(hres))
1680 lpsizel->cx = presData.objectExtentX;
1681 lpsizel->cy = presData.objectExtentY;
1685 * This method returns OLE_E_BLANK when it fails.
1687 if (FAILED(hres))
1688 hres = OLE_E_BLANK;
1690 return hres;
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(
1705 IOleCache2* iface,
1706 REFIID riid,
1707 void** ppvObject)
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(
1720 IOleCache2* iface)
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(
1733 IOleCache2* iface)
1735 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1737 return IUnknown_Release(this->outerUnknown);
1740 static HRESULT WINAPI DataCache_Cache(
1741 IOleCache2* iface,
1742 FORMATETC* pformatetc,
1743 DWORD advf,
1744 DWORD* pdwConnection)
1746 FIXME("stub\n");
1747 return E_NOTIMPL;
1750 static HRESULT WINAPI DataCache_Uncache(
1751 IOleCache2* iface,
1752 DWORD dwConnection)
1754 FIXME("stub\n");
1755 return E_NOTIMPL;
1758 static HRESULT WINAPI DataCache_EnumCache(
1759 IOleCache2* iface,
1760 IEnumSTATDATA** ppenumSTATDATA)
1762 FIXME("stub\n");
1763 return E_NOTIMPL;
1766 static HRESULT WINAPI DataCache_InitCache(
1767 IOleCache2* iface,
1768 IDataObject* pDataObject)
1770 FIXME("stub\n");
1771 return E_NOTIMPL;
1774 static HRESULT WINAPI DataCache_IOleCache2_SetData(
1775 IOleCache2* iface,
1776 FORMATETC* pformatetc,
1777 STGMEDIUM* pmedium,
1778 BOOL fRelease)
1780 FIXME("stub\n");
1781 return E_NOTIMPL;
1784 static HRESULT WINAPI DataCache_UpdateCache(
1785 IOleCache2* iface,
1786 LPDATAOBJECT pDataObject,
1787 DWORD grfUpdf,
1788 LPVOID pReserved)
1790 FIXME("stub\n");
1791 return E_NOTIMPL;
1794 static HRESULT WINAPI DataCache_DiscardCache(
1795 IOleCache2* iface,
1796 DWORD dwDiscardOptions)
1798 FIXME("stub\n");
1799 return E_NOTIMPL;
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,
1815 REFIID riid,
1816 void** ppvObject)
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)
1853 FIXME("stub\n");
1854 return E_NOTIMPL;
1857 static HRESULT WINAPI DataCache_OnStop(
1858 IOleCacheControl* iface)
1860 FIXME("stub\n");
1861 return E_NOTIMPL;