Removed old resource compiler.
[wine.git] / dlls / ole32 / datacache.c
blob6bbae9679209ca9b64298ddef69871055bea24ed
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". It appears to just be a counter.
27 * - Also, I don't know the real content of the presentation stream
28 * header. I was able to figure-out where the extent of the object
29 * was stored and the aspect, but that's about it.
31 #include <assert.h>
32 #include "windef.h"
33 #include "winbase.h"
34 #include "wingdi.h"
35 #include "winerror.h"
36 #include "crtdll.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; /* -1 */
54 DWORD unknown2; /* 3, possibly CF_METAFILEPICT */
55 DWORD unknown3; /* 4, possibly TYMED_ISTREAM */
56 DVASPECT dvAspect;
57 DWORD unknown5; /* -1 */
59 DWORD unknown6;
60 DWORD unknown7; /* 0 */
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_OpenPresStream(DataCache *this,
134 DWORD drawAspect,
135 IStream **pStm);
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;
448 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(rclsid), pUnkOuter, debugstr_guid(riid), ppvObj);
451 * Sanity check
453 if (ppvObj==0)
454 return E_POINTER;
456 *ppvObj = 0;
459 * If this cache is constructed for aggregation, make sure
460 * the caller is requesting the IUnknown interface.
461 * This is necessary because it's the only time the non-delegating
462 * IUnknown pointer can be returned to the outside.
464 if ( (pUnkOuter!=NULL) &&
465 (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) != 0) )
466 return CLASS_E_NOAGGREGATION;
469 * Try to construct a new instance of the class.
471 newCache = DataCache_Construct(rclsid,
472 pUnkOuter);
474 if (newCache == 0)
475 return E_OUTOFMEMORY;
478 * Make sure it supports the interface required by the caller.
480 hr = IUnknown_QueryInterface((IUnknown*)&(newCache->lpvtbl2), riid, ppvObj);
483 * Release the reference obtained in the constructor. If
484 * the QueryInterface was unsuccessful, it will free the class.
486 IUnknown_Release((IUnknown*)&(newCache->lpvtbl2));
488 return hr;
491 /*********************************************************
492 * Method implementation for DataCache class.
494 static DataCache* DataCache_Construct(
495 REFCLSID clsid,
496 LPUNKNOWN pUnkOuter)
498 DataCache* newObject = 0;
501 * Allocate space for the object.
503 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache));
505 if (newObject==0)
506 return newObject;
509 * Initialize the virtual function table.
511 newObject->lpvtbl1 = &DataCache_IDataObject_VTable;
512 newObject->lpvtbl2 = &DataCache_NDIUnknown_VTable;
513 newObject->lpvtbl3 = &DataCache_IPersistStorage_VTable;
514 newObject->lpvtbl4 = &DataCache_IViewObject2_VTable;
515 newObject->lpvtbl5 = &DataCache_IOleCache2_VTable;
516 newObject->lpvtbl6 = &DataCache_IOleCacheControl_VTable;
519 * Start with one reference count. The caller of this function
520 * must release the interface pointer when it is done.
522 newObject->ref = 1;
525 * Initialize the outer unknown
526 * We don't keep a reference on the outer unknown since, the way
527 * aggregation works, our lifetime is at least as large as it's
528 * lifetime.
530 if (pUnkOuter==NULL)
531 pUnkOuter = (IUnknown*)&(newObject->lpvtbl2);
533 newObject->outerUnknown = pUnkOuter;
536 * Initialize the other members of the structure.
538 newObject->presentationStorage = NULL;
539 newObject->sinkAspects = 0;
540 newObject->sinkAdviseFlag = 0;
541 newObject->sinkInterface = 0;
543 return newObject;
546 static void DataCache_Destroy(
547 DataCache* ptrToDestroy)
549 TRACE("()\n");
551 if (ptrToDestroy->sinkInterface != NULL)
553 IAdviseSink_Release(ptrToDestroy->sinkInterface);
554 ptrToDestroy->sinkInterface = NULL;
557 if (ptrToDestroy->presentationStorage != NULL)
559 IStorage_Release(ptrToDestroy->presentationStorage);
560 ptrToDestroy->presentationStorage = NULL;
564 * Free the datacache pointer.
566 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
569 /************************************************************************
570 * DataCache_ReadPresentationData
572 * This method will read information for the requested presentation
573 * into the given structure.
575 * Param:
576 * this - Pointer to the DataCache object
577 * drawAspect - The aspect of the object that we wish to draw.
578 * header - The structure containing information about this
579 * aspect of the object.
581 static HRESULT DataCache_ReadPresentationData(
582 DataCache* this,
583 DWORD drawAspect,
584 PresentationDataHeader* header)
586 IStream* presStream = NULL;
587 HRESULT hres;
590 * Open the presentation stream.
592 hres = DataCache_OpenPresStream(
593 this,
594 drawAspect,
595 &presStream);
597 if (FAILED(hres))
598 return hres;
601 * Read the header.
604 hres = IStream_Read(
605 presStream,
606 header,
607 sizeof(PresentationDataHeader),
608 NULL);
611 * Cleanup.
613 IStream_Release(presStream);
616 * We don't want to propagate any other error
617 * code than a failure.
619 if (hres!=S_OK)
620 hres = E_FAIL;
622 return hres;
625 /************************************************************************
626 * DataCache_FireOnViewChange
628 * This method will fire an OnViewChange notification to the advise
629 * sink registered with the datacache.
631 * See IAdviseSink::OnViewChange for more details.
633 static void DataCache_FireOnViewChange(
634 DataCache* this,
635 DWORD aspect,
636 LONG lindex)
638 TRACE("(%p, %lx, %ld)\n", this, aspect, lindex);
641 * The sink supplies a filter when it registers
642 * we make sure we only send the notifications when that
643 * filter matches.
645 if ((this->sinkAspects & aspect) != 0)
647 if (this->sinkInterface != NULL)
649 IAdviseSink_OnViewChange(this->sinkInterface,
650 aspect,
651 lindex);
654 * Some sinks want to be unregistered automatically when
655 * the first notification goes out.
657 if ( (this->sinkAdviseFlag & ADVF_ONLYONCE) != 0)
659 IAdviseSink_Release(this->sinkInterface);
661 this->sinkInterface = NULL;
662 this->sinkAspects = 0;
663 this->sinkAdviseFlag = 0;
669 /* Helper for DataCache_OpenPresStream */
670 static BOOL DataCache_IsPresentationStream(const STATSTG *elem)
672 /* The presentation streams have names of the form "\002OlePresXXX",
673 * where XXX goes from 000 to 999. */
674 static const WCHAR OlePres[] = { 2,'O','l','e','P','r','e','s' };
676 LPCWSTR name = elem->pwcsName;
678 return (elem->type == STGTY_STREAM)
679 && (elem->cbSize.s.LowPart >= sizeof(PresentationDataHeader))
680 && (CRTDLL_wcslen(name) == 11)
681 && (CRTDLL_wcsncmp(name, OlePres, 8) == 0)
682 && CRTDLL_iswdigit(name[8])
683 && CRTDLL_iswdigit(name[9])
684 && CRTDLL_iswdigit(name[10]);
687 /************************************************************************
688 * DataCache_OpenPresStream
690 * This method will find the stream for the given presentation. It makes
691 * no attempt at fallback.
693 * Param:
694 * this - Pointer to the DataCache object
695 * drawAspect - The aspect of the object that we wish to draw.
696 * pStm - A returned stream. It points to the beginning of the
697 * - presentation data, including the header.
699 * Errors:
700 * S_OK The requested stream has been opened.
701 * OLE_E_BLANK The requested stream could not be found.
702 * Quite a few others I'm too lazy to map correctly.
704 * Notes:
705 * Algorithm: Scan the elements of the presentation storage, looking
706 * for presentation streams. For each presentation stream,
707 * load the header and check to see if the aspect maches.
709 * If a fallback is desired, just opening the first presentation stream
710 * is a possibility.
712 static HRESULT DataCache_OpenPresStream(
713 DataCache *this,
714 DWORD drawAspect,
715 IStream **ppStm)
717 STATSTG elem;
718 IEnumSTATSTG *pEnum;
719 HRESULT hr;
721 if (!ppStm) return E_POINTER;
723 hr = IStorage_EnumElements(this->presentationStorage, 0, NULL, 0, &pEnum);
724 if (FAILED(hr)) return hr;
726 while ((hr = IEnumSTATSTG_Next(pEnum, 1, &elem, NULL)) == S_OK)
728 if (DataCache_IsPresentationStream(&elem))
730 IStream *pStm;
732 hr = IStorage_OpenStream(this->presentationStorage, elem.pwcsName,
733 NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0,
734 &pStm);
735 if (SUCCEEDED(hr))
737 PresentationDataHeader header;
738 ULONG actual_read;
740 hr = IStream_Read(pStm, &header, sizeof(header), &actual_read);
742 /* can't use SUCCEEDED(hr): S_FALSE counts as an error */
743 if (hr == S_OK && actual_read == sizeof(header)
744 && header.dvAspect == drawAspect)
746 /* Rewind the stream before returning it. */
747 LARGE_INTEGER offset;
748 offset.s.LowPart = 0;
749 offset.s.HighPart = 0;
750 IStream_Seek(pStm, offset, STREAM_SEEK_SET, NULL);
752 *ppStm = pStm;
754 CoTaskMemFree(elem.pwcsName);
755 IEnumSTATSTG_Release(pEnum);
757 return S_OK;
760 IStream_Release(pStm);
764 CoTaskMemFree(elem.pwcsName);
767 IEnumSTATSTG_Release(pEnum);
769 return (hr == S_FALSE ? OLE_E_BLANK : hr);
772 /************************************************************************
773 * DataCache_ReadPresentationData
775 * This method will read information for the requested presentation
776 * into the given structure.
778 * Param:
779 * this - Pointer to the DataCache object
780 * drawAspect - The aspect of the object that we wish to draw.
782 * Returns:
783 * This method returns a metafile handle if it is successful.
784 * it will return 0 if not.
786 static HMETAFILE DataCache_ReadPresMetafile(
787 DataCache* this,
788 DWORD drawAspect)
790 LARGE_INTEGER offset;
791 IStream* presStream = NULL;
792 HRESULT hres;
793 void* metafileBits;
794 STATSTG streamInfo;
795 HMETAFILE newMetafile = 0;
798 * Open the presentation stream.
800 hres = DataCache_OpenPresStream(
801 this,
802 drawAspect,
803 &presStream);
805 if (FAILED(hres))
806 return hres;
809 * Get the size of the stream.
811 hres = IStream_Stat(presStream,
812 &streamInfo,
813 STATFLAG_NONAME);
816 * Skip the header
818 offset.s.HighPart = 0;
819 offset.s.LowPart = sizeof(PresentationDataHeader);
821 hres = IStream_Seek(
822 presStream,
823 offset,
824 STREAM_SEEK_SET,
825 NULL);
827 streamInfo.cbSize.s.LowPart -= offset.s.LowPart;
830 * Allocate a buffer for the metafile bits.
832 metafileBits = HeapAlloc(GetProcessHeap(),
834 streamInfo.cbSize.s.LowPart);
837 * Read the metafile bits.
839 hres = IStream_Read(
840 presStream,
841 metafileBits,
842 streamInfo.cbSize.s.LowPart,
843 NULL);
846 * Create a metafile with those bits.
848 if (SUCCEEDED(hres))
850 newMetafile = SetMetaFileBitsEx(streamInfo.cbSize.s.LowPart, metafileBits);
854 * Cleanup.
856 HeapFree(GetProcessHeap(), 0, metafileBits);
857 IStream_Release(presStream);
859 if (newMetafile==0)
860 hres = E_FAIL;
862 return newMetafile;
865 /*********************************************************
866 * Method implementation for the non delegating IUnknown
867 * part of the DataCache class.
870 /************************************************************************
871 * DataCache_NDIUnknown_QueryInterface (IUnknown)
873 * See Windows documentation for more details on IUnknown methods.
875 * This version of QueryInterface will not delegate it's implementation
876 * to the outer unknown.
878 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
879 IUnknown* iface,
880 REFIID riid,
881 void** ppvObject)
883 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
886 * Perform a sanity check on the parameters.
888 if ( (this==0) || (ppvObject==0) )
889 return E_INVALIDARG;
892 * Initialize the return parameter.
894 *ppvObject = 0;
897 * Compare the riid with the interface IDs implemented by this object.
899 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
901 *ppvObject = iface;
903 else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0)
905 *ppvObject = (IDataObject*)&(this->lpvtbl1);
907 else if ( (memcmp(&IID_IPersistStorage, riid, sizeof(IID_IPersistStorage)) == 0) ||
908 (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0) )
910 *ppvObject = (IPersistStorage*)&(this->lpvtbl3);
912 else if ( (memcmp(&IID_IViewObject, riid, sizeof(IID_IViewObject)) == 0) ||
913 (memcmp(&IID_IViewObject2, riid, sizeof(IID_IViewObject2)) == 0) )
915 *ppvObject = (IViewObject2*)&(this->lpvtbl4);
917 else if ( (memcmp(&IID_IOleCache, riid, sizeof(IID_IOleCache)) == 0) ||
918 (memcmp(&IID_IOleCache2, riid, sizeof(IID_IOleCache2)) == 0) )
920 *ppvObject = (IOleCache2*)&(this->lpvtbl5);
922 else if (memcmp(&IID_IOleCacheControl, riid, sizeof(IID_IOleCacheControl)) == 0)
924 *ppvObject = (IOleCacheControl*)&(this->lpvtbl6);
928 * Check that we obtained an interface.
930 if ((*ppvObject)==0)
932 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
933 return E_NOINTERFACE;
937 * Query Interface always increases the reference count by one when it is
938 * successful.
940 IUnknown_AddRef((IUnknown*)*ppvObject);
942 return S_OK;;
945 /************************************************************************
946 * DataCache_NDIUnknown_AddRef (IUnknown)
948 * See Windows documentation for more details on IUnknown methods.
950 * This version of QueryInterface will not delegate it's implementation
951 * to the outer unknown.
953 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
954 IUnknown* iface)
956 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
958 this->ref++;
960 return this->ref;
963 /************************************************************************
964 * DataCache_NDIUnknown_Release (IUnknown)
966 * See Windows documentation for more details on IUnknown methods.
968 * This version of QueryInterface will not delegate it's implementation
969 * to the outer unknown.
971 static ULONG WINAPI DataCache_NDIUnknown_Release(
972 IUnknown* iface)
974 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
977 * Decrease the reference count on this object.
979 this->ref--;
982 * If the reference count goes down to 0, perform suicide.
984 if (this->ref==0)
986 DataCache_Destroy(this);
988 return 0;
991 return this->ref;
994 /*********************************************************
995 * Method implementation for the IDataObject
996 * part of the DataCache class.
999 /************************************************************************
1000 * DataCache_IDataObject_QueryInterface (IUnknown)
1002 * See Windows documentation for more details on IUnknown methods.
1004 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
1005 IDataObject* iface,
1006 REFIID riid,
1007 void** ppvObject)
1009 _ICOM_THIS_From_IDataObject(DataCache, iface);
1011 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1014 /************************************************************************
1015 * DataCache_IDataObject_AddRef (IUnknown)
1017 * See Windows documentation for more details on IUnknown methods.
1019 static ULONG WINAPI DataCache_IDataObject_AddRef(
1020 IDataObject* iface)
1022 _ICOM_THIS_From_IDataObject(DataCache, iface);
1024 return IUnknown_AddRef(this->outerUnknown);
1027 /************************************************************************
1028 * DataCache_IDataObject_Release (IUnknown)
1030 * See Windows documentation for more details on IUnknown methods.
1032 static ULONG WINAPI DataCache_IDataObject_Release(
1033 IDataObject* iface)
1035 _ICOM_THIS_From_IDataObject(DataCache, iface);
1037 return IUnknown_Release(this->outerUnknown);
1040 static HRESULT WINAPI DataCache_GetData(
1041 IDataObject* iface,
1042 LPFORMATETC pformatetcIn,
1043 STGMEDIUM* pmedium)
1045 FIXME("stub\n");
1046 return E_NOTIMPL;
1049 static HRESULT WINAPI DataCache_GetDataHere(
1050 IDataObject* iface,
1051 LPFORMATETC pformatetc,
1052 STGMEDIUM* pmedium)
1054 FIXME("stub\n");
1055 return E_NOTIMPL;
1058 static HRESULT WINAPI DataCache_QueryGetData(
1059 IDataObject* iface,
1060 LPFORMATETC pformatetc)
1062 FIXME("stub\n");
1063 return E_NOTIMPL;
1066 /************************************************************************
1067 * DataCache_EnumFormatEtc (IDataObject)
1069 * The data cache doesn't implement this method.
1071 * See Windows documentation for more details on IDataObject methods.
1073 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
1074 IDataObject* iface,
1075 LPFORMATETC pformatectIn,
1076 LPFORMATETC pformatetcOut)
1078 TRACE("()\n");
1079 return E_NOTIMPL;
1082 /************************************************************************
1083 * DataCache_IDataObject_SetData (IDataObject)
1085 * This method is delegated to the IOleCache2 implementation.
1087 * See Windows documentation for more details on IDataObject methods.
1089 static HRESULT WINAPI DataCache_IDataObject_SetData(
1090 IDataObject* iface,
1091 LPFORMATETC pformatetc,
1092 STGMEDIUM* pmedium,
1093 BOOL fRelease)
1095 IOleCache2* oleCache = NULL;
1096 HRESULT hres;
1098 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1100 hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);
1102 if (FAILED(hres))
1103 return E_UNEXPECTED;
1105 hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);
1107 IOleCache2_Release(oleCache);
1109 return hres;;
1112 /************************************************************************
1113 * DataCache_EnumFormatEtc (IDataObject)
1115 * The data cache doesn't implement this method.
1117 * See Windows documentation for more details on IDataObject methods.
1119 static HRESULT WINAPI DataCache_EnumFormatEtc(
1120 IDataObject* iface,
1121 DWORD dwDirection,
1122 IEnumFORMATETC** ppenumFormatEtc)
1124 TRACE("()\n");
1125 return E_NOTIMPL;
1128 /************************************************************************
1129 * DataCache_DAdvise (IDataObject)
1131 * The data cache doesn't support connections.
1133 * See Windows documentation for more details on IDataObject methods.
1135 static HRESULT WINAPI DataCache_DAdvise(
1136 IDataObject* iface,
1137 FORMATETC* pformatetc,
1138 DWORD advf,
1139 IAdviseSink* pAdvSink,
1140 DWORD* pdwConnection)
1142 TRACE("()\n");
1143 return OLE_E_ADVISENOTSUPPORTED;
1146 /************************************************************************
1147 * DataCache_DUnadvise (IDataObject)
1149 * The data cache doesn't support connections.
1151 * See Windows documentation for more details on IDataObject methods.
1153 static HRESULT WINAPI DataCache_DUnadvise(
1154 IDataObject* iface,
1155 DWORD dwConnection)
1157 TRACE("()\n");
1158 return OLE_E_NOCONNECTION;
1161 /************************************************************************
1162 * DataCache_EnumDAdvise (IDataObject)
1164 * The data cache doesn't support connections.
1166 * See Windows documentation for more details on IDataObject methods.
1168 static HRESULT WINAPI DataCache_EnumDAdvise(
1169 IDataObject* iface,
1170 IEnumSTATDATA** ppenumAdvise)
1172 TRACE("()\n");
1173 return OLE_E_ADVISENOTSUPPORTED;
1176 /*********************************************************
1177 * Method implementation for the IDataObject
1178 * part of the DataCache class.
1181 /************************************************************************
1182 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1184 * See Windows documentation for more details on IUnknown methods.
1186 static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
1187 IPersistStorage* iface,
1188 REFIID riid,
1189 void** ppvObject)
1191 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1193 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1196 /************************************************************************
1197 * DataCache_IPersistStorage_AddRef (IUnknown)
1199 * See Windows documentation for more details on IUnknown methods.
1201 static ULONG WINAPI DataCache_IPersistStorage_AddRef(
1202 IPersistStorage* iface)
1204 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1206 return IUnknown_AddRef(this->outerUnknown);
1209 /************************************************************************
1210 * DataCache_IPersistStorage_Release (IUnknown)
1212 * See Windows documentation for more details on IUnknown methods.
1214 static ULONG WINAPI DataCache_IPersistStorage_Release(
1215 IPersistStorage* iface)
1217 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1219 return IUnknown_Release(this->outerUnknown);
1222 /************************************************************************
1223 * DataCache_GetClassID (IPersistStorage)
1225 * The data cache doesn't implement this method.
1227 * See Windows documentation for more details on IPersistStorage methods.
1229 static HRESULT WINAPI DataCache_GetClassID(
1230 IPersistStorage* iface,
1231 CLSID* pClassID)
1233 TRACE("(%p, %p)\n", iface, pClassID);
1234 return E_NOTIMPL;
1237 /************************************************************************
1238 * DataCache_IsDirty (IPersistStorage)
1240 * Until we actully connect to a running object and retrieve new
1241 * information to it, we never get dirty.
1243 * See Windows documentation for more details on IPersistStorage methods.
1245 static HRESULT WINAPI DataCache_IsDirty(
1246 IPersistStorage* iface)
1248 TRACE("(%p)\n", iface);
1250 return S_FALSE;
1253 /************************************************************************
1254 * DataCache_InitNew (IPersistStorage)
1256 * The data cache implementation of IPersistStorage_InitNew simply stores
1257 * the storage pointer.
1259 * See Windows documentation for more details on IPersistStorage methods.
1261 static HRESULT WINAPI DataCache_InitNew(
1262 IPersistStorage* iface,
1263 IStorage* pStg)
1265 TRACE("(%p, %p)\n", iface, pStg);
1267 return DataCache_Load(iface, pStg);
1270 /************************************************************************
1271 * DataCache_Load (IPersistStorage)
1273 * The data cache implementation of IPersistStorage_Load doesn't
1274 * actually load anything. Instead, it holds on to the storage pointer
1275 * and it will load the presentation information when the
1276 * IDataObject_GetData or IViewObject2_Draw methods are called.
1278 * See Windows documentation for more details on IPersistStorage methods.
1280 static HRESULT WINAPI DataCache_Load(
1281 IPersistStorage* iface,
1282 IStorage* pStg)
1284 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1286 TRACE("(%p, %p)\n", iface, pStg);
1288 if (this->presentationStorage != NULL)
1290 IStorage_Release(this->presentationStorage);
1293 this->presentationStorage = pStg;
1295 if (this->presentationStorage != NULL)
1297 IStorage_AddRef(this->presentationStorage);
1299 return S_OK;
1302 /************************************************************************
1303 * DataCache_Save (IPersistStorage)
1305 * Until we actully connect to a running object and retrieve new
1306 * information to it, we never have to save anything. However, it is
1307 * our responsability to copy the information when saving to a new
1308 * storage.
1310 * See Windows documentation for more details on IPersistStorage methods.
1312 static HRESULT WINAPI DataCache_Save(
1313 IPersistStorage* iface,
1314 IStorage* pStg,
1315 BOOL fSameAsLoad)
1317 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1319 TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad);
1321 if ( (!fSameAsLoad) &&
1322 (this->presentationStorage!=NULL) )
1324 return IStorage_CopyTo(this->presentationStorage,
1326 NULL,
1327 NULL,
1328 pStg);
1331 return S_OK;
1334 /************************************************************************
1335 * DataCache_SaveCompleted (IPersistStorage)
1337 * This method is called to tell the cache to release the storage
1338 * pointer it's currentlu holding.
1340 * See Windows documentation for more details on IPersistStorage methods.
1342 static HRESULT WINAPI DataCache_SaveCompleted(
1343 IPersistStorage* iface,
1344 IStorage* pStgNew)
1346 TRACE("(%p, %p)\n", iface, pStgNew);
1348 if (pStgNew)
1351 * First, make sure we get our hands off any storage we have.
1354 DataCache_HandsOffStorage(iface);
1357 * Then, attach to the new storage.
1360 DataCache_Load(iface, pStgNew);
1363 return S_OK;
1366 /************************************************************************
1367 * DataCache_HandsOffStorage (IPersistStorage)
1369 * This method is called to tell the cache to release the storage
1370 * pointer it's currentlu holding.
1372 * See Windows documentation for more details on IPersistStorage methods.
1374 static HRESULT WINAPI DataCache_HandsOffStorage(
1375 IPersistStorage* iface)
1377 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1379 TRACE("(%p)\n", iface);
1381 if (this->presentationStorage != NULL)
1383 IStorage_Release(this->presentationStorage);
1384 this->presentationStorage = NULL;
1387 return S_OK;
1390 /*********************************************************
1391 * Method implementation for the IViewObject2
1392 * part of the DataCache class.
1395 /************************************************************************
1396 * DataCache_IViewObject2_QueryInterface (IUnknown)
1398 * See Windows documentation for more details on IUnknown methods.
1400 static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
1401 IViewObject2* iface,
1402 REFIID riid,
1403 void** ppvObject)
1405 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1407 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1410 /************************************************************************
1411 * DataCache_IViewObject2_AddRef (IUnknown)
1413 * See Windows documentation for more details on IUnknown methods.
1415 static ULONG WINAPI DataCache_IViewObject2_AddRef(
1416 IViewObject2* iface)
1418 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1420 return IUnknown_AddRef(this->outerUnknown);
1423 /************************************************************************
1424 * DataCache_IViewObject2_Release (IUnknown)
1426 * See Windows documentation for more details on IUnknown methods.
1428 static ULONG WINAPI DataCache_IViewObject2_Release(
1429 IViewObject2* iface)
1431 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1433 return IUnknown_Release(this->outerUnknown);
1436 /************************************************************************
1437 * DataCache_Draw (IViewObject2)
1439 * This method will draw the cached representation of the object
1440 * to the given device context.
1442 * See Windows documentation for more details on IViewObject2 methods.
1444 static HRESULT WINAPI DataCache_Draw(
1445 IViewObject2* iface,
1446 DWORD dwDrawAspect,
1447 LONG lindex,
1448 void* pvAspect,
1449 DVTARGETDEVICE* ptd,
1450 HDC hdcTargetDev,
1451 HDC hdcDraw,
1452 LPCRECTL lprcBounds,
1453 LPCRECTL lprcWBounds,
1454 IVO_ContCallback pfnContinue,
1455 DWORD dwContinue)
1457 PresentationDataHeader presData;
1458 HMETAFILE presMetafile = 0;
1459 HRESULT hres;
1461 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1463 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1464 iface,
1465 dwDrawAspect,
1466 lindex,
1467 pvAspect,
1468 hdcTargetDev,
1469 hdcDraw,
1470 lprcBounds,
1471 lprcWBounds,
1472 pfnContinue,
1473 dwContinue);
1476 * Sanity check
1478 if (lprcBounds==NULL)
1479 return E_INVALIDARG;
1482 * First, we need to retrieve the dimensions of the
1483 * image in the metafile.
1485 hres = DataCache_ReadPresentationData(this,
1486 dwDrawAspect,
1487 &presData);
1489 if (FAILED(hres))
1490 return hres;
1493 * Then, we can extract the metafile itself from the cached
1494 * data.
1496 * FIXME Unless it isn't a metafile. I think it could be any CF_XXX type,
1497 * particularly CF_DIB.
1499 presMetafile = DataCache_ReadPresMetafile(this,
1500 dwDrawAspect);
1503 * If we have a metafile, just draw baby...
1504 * We have to be careful not to modify the state of the
1505 * DC.
1507 if (presMetafile!=0)
1509 INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC);
1510 SIZE oldWindowExt;
1511 SIZE oldViewportExt;
1512 POINT oldViewportOrg;
1514 SetWindowExtEx(hdcDraw,
1515 presData.objectExtentX,
1516 presData.objectExtentY,
1517 &oldWindowExt);
1519 SetViewportExtEx(hdcDraw,
1520 lprcBounds->right - lprcBounds->left,
1521 lprcBounds->bottom - lprcBounds->top,
1522 &oldViewportExt);
1524 SetViewportOrgEx(hdcDraw,
1525 lprcBounds->left,
1526 lprcBounds->top,
1527 &oldViewportOrg);
1529 PlayMetaFile(hdcDraw, presMetafile);
1531 SetWindowExtEx(hdcDraw,
1532 oldWindowExt.cx,
1533 oldWindowExt.cy,
1534 NULL);
1536 SetViewportExtEx(hdcDraw,
1537 oldViewportExt.cx,
1538 oldViewportExt.cy,
1539 NULL);
1541 SetViewportOrgEx(hdcDraw,
1542 oldViewportOrg.x,
1543 oldViewportOrg.y,
1544 NULL);
1546 SetMapMode(hdcDraw, prevMapMode);
1548 DeleteMetaFile(presMetafile);
1551 return S_OK;
1554 static HRESULT WINAPI DataCache_GetColorSet(
1555 IViewObject2* iface,
1556 DWORD dwDrawAspect,
1557 LONG lindex,
1558 void* pvAspect,
1559 DVTARGETDEVICE* ptd,
1560 HDC hicTargetDevice,
1561 LOGPALETTE** ppColorSet)
1563 FIXME("stub\n");
1564 return E_NOTIMPL;
1567 static HRESULT WINAPI DataCache_Freeze(
1568 IViewObject2* iface,
1569 DWORD dwDrawAspect,
1570 LONG lindex,
1571 void* pvAspect,
1572 DWORD* pdwFreeze)
1574 FIXME("stub\n");
1575 return E_NOTIMPL;
1578 static HRESULT WINAPI DataCache_Unfreeze(
1579 IViewObject2* iface,
1580 DWORD dwFreeze)
1582 FIXME("stub\n");
1583 return E_NOTIMPL;
1586 /************************************************************************
1587 * DataCache_SetAdvise (IViewObject2)
1589 * This sets-up an advisory sink with the data cache. When the object's
1590 * view changes, this sink is called.
1592 * See Windows documentation for more details on IViewObject2 methods.
1594 static HRESULT WINAPI DataCache_SetAdvise(
1595 IViewObject2* iface,
1596 DWORD aspects,
1597 DWORD advf,
1598 IAdviseSink* pAdvSink)
1600 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1602 TRACE("(%p, %lx, %lx, %p)\n", iface, aspects, advf, pAdvSink);
1605 * A call to this function removes the previous sink
1607 if (this->sinkInterface != NULL)
1609 IAdviseSink_Release(this->sinkInterface);
1610 this->sinkInterface = NULL;
1611 this->sinkAspects = 0;
1612 this->sinkAdviseFlag = 0;
1616 * Now, setup the new one.
1618 if (pAdvSink!=NULL)
1620 this->sinkInterface = pAdvSink;
1621 this->sinkAspects = aspects;
1622 this->sinkAdviseFlag = advf;
1624 IAdviseSink_AddRef(this->sinkInterface);
1628 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1629 * sink immediately.
1631 if (advf & ADVF_PRIMEFIRST)
1633 DataCache_FireOnViewChange(this,
1634 DVASPECT_CONTENT,
1635 -1);
1638 return S_OK;
1641 /************************************************************************
1642 * DataCache_GetAdvise (IViewObject2)
1644 * This method queries the current state of the advise sink
1645 * installed on the data cache.
1647 * See Windows documentation for more details on IViewObject2 methods.
1649 static HRESULT WINAPI DataCache_GetAdvise(
1650 IViewObject2* iface,
1651 DWORD* pAspects,
1652 DWORD* pAdvf,
1653 IAdviseSink** ppAdvSink)
1655 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1657 TRACE("(%p, %p, %p, %p)\n", iface, pAspects, pAdvf, ppAdvSink);
1660 * Just copy all the requested values.
1662 if (pAspects!=NULL)
1663 *pAspects = this->sinkAspects;
1665 if (pAdvf!=NULL)
1666 *pAdvf = this->sinkAdviseFlag;
1668 if (ppAdvSink!=NULL)
1670 IAdviseSink_QueryInterface(this->sinkInterface,
1671 &IID_IAdviseSink,
1672 (void**)ppAdvSink);
1675 return S_OK;
1678 /************************************************************************
1679 * DataCache_GetExtent (IViewObject2)
1681 * This method retrieves the "natural" size of this cached object.
1683 * See Windows documentation for more details on IViewObject2 methods.
1685 static HRESULT WINAPI DataCache_GetExtent(
1686 IViewObject2* iface,
1687 DWORD dwDrawAspect,
1688 LONG lindex,
1689 DVTARGETDEVICE* ptd,
1690 LPSIZEL lpsizel)
1692 PresentationDataHeader presData;
1693 HRESULT hres = E_FAIL;
1695 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1697 TRACE("(%p, %lx, %ld, %p, %p)\n",
1698 iface, dwDrawAspect, lindex, ptd, lpsizel);
1701 * Sanity check
1703 if (lpsizel==NULL)
1704 return E_POINTER;
1707 * Initialize the out parameter.
1709 lpsizel->cx = 0;
1710 lpsizel->cy = 0;
1713 * This flag should be set to -1.
1715 if (lindex!=-1)
1716 FIXME("Unimplemented flag lindex = %ld\n", lindex);
1719 * Right now, we suport only the callback from
1720 * the default handler.
1722 if (ptd!=NULL)
1723 FIXME("Unimplemented ptd = %p\n", ptd);
1726 * Get the presentation information from the
1727 * cache.
1729 hres = DataCache_ReadPresentationData(this,
1730 dwDrawAspect,
1731 &presData);
1733 if (SUCCEEDED(hres))
1735 lpsizel->cx = presData.objectExtentX;
1736 lpsizel->cy = presData.objectExtentY;
1740 * This method returns OLE_E_BLANK when it fails.
1742 if (FAILED(hres))
1743 hres = OLE_E_BLANK;
1745 return hres;
1749 /*********************************************************
1750 * Method implementation for the IOleCache2
1751 * part of the DataCache class.
1754 /************************************************************************
1755 * DataCache_IOleCache2_QueryInterface (IUnknown)
1757 * See Windows documentation for more details on IUnknown methods.
1759 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
1760 IOleCache2* iface,
1761 REFIID riid,
1762 void** ppvObject)
1764 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1766 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1769 /************************************************************************
1770 * DataCache_IOleCache2_AddRef (IUnknown)
1772 * See Windows documentation for more details on IUnknown methods.
1774 static ULONG WINAPI DataCache_IOleCache2_AddRef(
1775 IOleCache2* iface)
1777 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1779 return IUnknown_AddRef(this->outerUnknown);
1782 /************************************************************************
1783 * DataCache_IOleCache2_Release (IUnknown)
1785 * See Windows documentation for more details on IUnknown methods.
1787 static ULONG WINAPI DataCache_IOleCache2_Release(
1788 IOleCache2* iface)
1790 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1792 return IUnknown_Release(this->outerUnknown);
1795 static HRESULT WINAPI DataCache_Cache(
1796 IOleCache2* iface,
1797 FORMATETC* pformatetc,
1798 DWORD advf,
1799 DWORD* pdwConnection)
1801 FIXME("stub\n");
1802 return E_NOTIMPL;
1805 static HRESULT WINAPI DataCache_Uncache(
1806 IOleCache2* iface,
1807 DWORD dwConnection)
1809 FIXME("stub\n");
1810 return E_NOTIMPL;
1813 static HRESULT WINAPI DataCache_EnumCache(
1814 IOleCache2* iface,
1815 IEnumSTATDATA** ppenumSTATDATA)
1817 FIXME("stub\n");
1818 return E_NOTIMPL;
1821 static HRESULT WINAPI DataCache_InitCache(
1822 IOleCache2* iface,
1823 IDataObject* pDataObject)
1825 FIXME("stub\n");
1826 return E_NOTIMPL;
1829 static HRESULT WINAPI DataCache_IOleCache2_SetData(
1830 IOleCache2* iface,
1831 FORMATETC* pformatetc,
1832 STGMEDIUM* pmedium,
1833 BOOL fRelease)
1835 FIXME("stub\n");
1836 return E_NOTIMPL;
1839 static HRESULT WINAPI DataCache_UpdateCache(
1840 IOleCache2* iface,
1841 LPDATAOBJECT pDataObject,
1842 DWORD grfUpdf,
1843 LPVOID pReserved)
1845 FIXME("stub\n");
1846 return E_NOTIMPL;
1849 static HRESULT WINAPI DataCache_DiscardCache(
1850 IOleCache2* iface,
1851 DWORD dwDiscardOptions)
1853 FIXME("stub\n");
1854 return E_NOTIMPL;
1858 /*********************************************************
1859 * Method implementation for the IOleCacheControl
1860 * part of the DataCache class.
1863 /************************************************************************
1864 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1866 * See Windows documentation for more details on IUnknown methods.
1868 static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
1869 IOleCacheControl* iface,
1870 REFIID riid,
1871 void** ppvObject)
1873 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1875 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1878 /************************************************************************
1879 * DataCache_IOleCacheControl_AddRef (IUnknown)
1881 * See Windows documentation for more details on IUnknown methods.
1883 static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
1884 IOleCacheControl* iface)
1886 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1888 return IUnknown_AddRef(this->outerUnknown);
1891 /************************************************************************
1892 * DataCache_IOleCacheControl_Release (IUnknown)
1894 * See Windows documentation for more details on IUnknown methods.
1896 static ULONG WINAPI DataCache_IOleCacheControl_Release(
1897 IOleCacheControl* iface)
1899 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1901 return IUnknown_Release(this->outerUnknown);
1904 static HRESULT WINAPI DataCache_OnRun(
1905 IOleCacheControl* iface,
1906 LPDATAOBJECT pDataObject)
1908 FIXME("stub\n");
1909 return E_NOTIMPL;
1912 static HRESULT WINAPI DataCache_OnStop(
1913 IOleCacheControl* iface)
1915 FIXME("stub\n");
1916 return E_NOTIMPL;