source: trunk/src/ole32/datacache.cpp@ 1033

Last change on this file since 1033 was 1033, checked in by davidr, 26 years ago

Ported remaining files pertaining to OLE32 from WINE

File size: 49.1 KB
Line 
1/* $Id: datacache.cpp,v 1.1 1999-09-24 21:49:42 davidr Exp $ */
2/*
3 * OLE 2 Data cache
4 *
5 * 21/9/99
6 *
7 * Copyright 1999 David J. Raison
8 *
9 * Direct port of Wine Implementation
10 * Copyright 1999 Francis Beaudet
11 *
12 * NOTES:
13 * The OLE2 data cache supports a whole whack of
14 * interfaces including:
15 * IDataObject, IPersistStorage, IViewObject2,
16 * IOleCache2 and IOleCacheControl.
17 *
18 * Most of the implementation details are taken from: Inside OLE
19 * second edition by Kraig Brockschmidt,
20 *
21 * NOTES
22 * - This implementation of the datacache will let your application
23 * load documents that have embedded OLE objects in them and it will
24 * also retrieve the metafile representation of those objects.
25 * - This implementation of the datacache will also allow your
26 * application to save new documents with OLE objects in them.
27 * - The main thing that it doesn't do is allow you to activate
28 * or modify the OLE objects in any way.
29 * - I haven't found any good documentation on the real usage of
30 * the streams created by the data cache. In particular, How to
31 * determine what the XXX stands for in the stream name
32 * "\002OlePresXXX". I have an intuition that This is related to
33 * the cached aspect of the object but I'm not sure it could
34 * just be a counter.
35 * - Also, I don't know the real content of the presentation stream
36 * header. I was able to figure-out where the extent of the object
37 * was stored but that's about it.
38 */
39
40#include "ole32.h"
41#include "heapstring.h"
42#include "debugtools.h"
43
44#include <assert.h>
45
46DEFAULT_DEBUG_CHANNEL(ole)
47
48/****************************************************************************
49 * PresentationDataHeader
50 *
51 * This structure represents the header of the \002OlePresXXX stream in
52 * the OLE object strorage.
53 *
54 * Most fields are still unknown.
55 */
56typedef struct PresentationDataHeader
57{
58 DWORD unknown1;
59 DWORD unknown2;
60 DWORD unknown3;
61 DWORD unknown4;
62 DWORD unknown5;
63
64 DWORD unknown6;
65 DWORD unknown7;
66 DWORD objectExtentX;
67 DWORD objectExtentY;
68 DWORD unknown8;
69} PresentationDataHeader;
70
71/****************************************************************************
72 * DataCache
73 */
74struct DataCache
75{
76 /*
77 * List all interface VTables here
78 */
79 ICOM_VTABLE(IDataObject)* lpvtbl1;
80 ICOM_VTABLE(IUnknown)* lpvtbl2;
81 ICOM_VTABLE(IPersistStorage)* lpvtbl3;
82 ICOM_VTABLE(IViewObject2)* lpvtbl4;
83 ICOM_VTABLE(IOleCache2)* lpvtbl5;
84 ICOM_VTABLE(IOleCacheControl)* lpvtbl6;
85
86 /*
87 * Reference count of This object
88 */
89 ULONG ref;
90
91 /*
92 * IUnknown implementation of the outer object.
93 */
94 IUnknown* outerUnknown;
95
96 /*
97 * This storage pointer is set through a call to
98 * IPersistStorage_Load. This is where the visual
99 * representation of the object is stored.
100 */
101 IStorage* presentationStorage;
102
103 /*
104 * The user of This object can setup ONE advise sink
105 * connection with the object. These parameters describe
106 * that connection.
107 */
108 DWORD sinkAspects;
109 DWORD sinkAdviseFlag;
110 IAdviseSink* sinkInterface;
111
112};
113
114typedef struct DataCache DataCache;
115
116/*
117 * Here, I define utility macros to help with the casting of the
118 * "This" parameter.
119 * There is a version to accomodate all of the VTables implemented
120 * by This object.
121 */
122#define _ICOM_THIS_From_IDataObject(class,name) class* This = (class*)name;
123#define _ICOM_THIS_From_NDIUnknown(class, name) class* This = (class*)(((char*)name)-sizeof(void*));
124#define _ICOM_THIS_From_IPersistStorage(class, name) class* This = (class*)(((char*)name)-2*sizeof(void*));
125#define _ICOM_THIS_From_IViewObject2(class, name) class* This = (class*)(((char*)name)-3*sizeof(void*));
126#define _ICOM_THIS_From_IOleCache2(class, name) class* This = (class*)(((char*)name)-4*sizeof(void*));
127#define _ICOM_THIS_From_IOleCacheControl(class, name) class* This = (class*)(((char*)name)-5*sizeof(void*));
128
129/*
130 * Prototypes for the methods of the DataCache class.
131 */
132static DataCache* DataCache_Construct(REFCLSID clsid,
133 LPUNKNOWN pUnkOuter);
134static void DataCache_Destroy(DataCache* ptrToDestroy);
135static HRESULT DataCache_ReadPresentationData(DataCache* This,
136 DWORD drawAspect,
137 PresentationDataHeader* header);
138static HRESULT DataCache_FindPresStreamName(DataCache* This,
139 DWORD drawAspect,
140 OLECHAR* buffer);
141static HMETAFILE DataCache_ReadPresMetafile(DataCache* This,
142 DWORD drawAspect);
143static void DataCache_FireOnViewChange(DataCache* This,
144 DWORD aspect,
145 LONG lindex);
146
147/*
148 * Prototypes for the methods of the DataCache class
149 * that implement non delegating IUnknown methods.
150 */
151static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
152 IUnknown* iface,
153 REFIID riid,
154 void** ppvObject);
155static ULONG WINAPI DataCache_NDIUnknown_AddRef(
156 IUnknown* iface);
157static ULONG WINAPI DataCache_NDIUnknown_Release(
158 IUnknown* iface);
159
160/*
161 * Prototypes for the methods of the DataCache class
162 * that implement IDataObject methods.
163 */
164static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
165 IDataObject* iface,
166 REFIID riid,
167 void** ppvObject);
168static ULONG WINAPI DataCache_IDataObject_AddRef(
169 IDataObject* iface);
170static ULONG WINAPI DataCache_IDataObject_Release(
171 IDataObject* iface);
172static HRESULT WINAPI DataCache_GetData(
173 IDataObject* iface,
174 LPFORMATETC pformatetcIn,
175 STGMEDIUM* pmedium);
176static HRESULT WINAPI DataCache_GetDataHere(
177 IDataObject* iface,
178 LPFORMATETC pformatetc,
179 STGMEDIUM* pmedium);
180static HRESULT WINAPI DataCache_QueryGetData(
181 IDataObject* iface,
182 LPFORMATETC pformatetc);
183static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
184 IDataObject* iface,
185 LPFORMATETC pformatectIn,
186 LPFORMATETC pformatetcOut);
187static HRESULT WINAPI DataCache_IDataObject_SetData(
188 IDataObject* iface,
189 LPFORMATETC pformatetc,
190 STGMEDIUM* pmedium,
191 BOOL fRelease);
192static HRESULT WINAPI DataCache_EnumFormatEtc(
193 IDataObject* iface,
194 DWORD dwDirection,
195 IEnumFORMATETC** ppenumFormatEtc);
196static HRESULT WINAPI DataCache_DAdvise(
197 IDataObject* iface,
198 FORMATETC* pformatetc,
199 DWORD advf,
200 IAdviseSink* pAdvSink,
201 DWORD* pdwConnection);
202static HRESULT WINAPI DataCache_DUnadvise(
203 IDataObject* iface,
204 DWORD dwConnection);
205static HRESULT WINAPI DataCache_EnumDAdvise(
206 IDataObject* iface,
207 IEnumSTATDATA** ppenumAdvise);
208
209/*
210 * Prototypes for the methods of the DataCache class
211 * that implement IPersistStorage methods.
212 */
213static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
214 IPersistStorage* iface,
215 REFIID riid,
216 void** ppvObject);
217static ULONG WINAPI DataCache_IPersistStorage_AddRef(
218 IPersistStorage* iface);
219static ULONG WINAPI DataCache_IPersistStorage_Release(
220 IPersistStorage* iface);
221static HRESULT WINAPI DataCache_GetClassID(
222 IPersistStorage* iface,
223 CLSID* pClassID);
224static HRESULT WINAPI DataCache_IsDirty(
225 IPersistStorage* iface);
226static HRESULT WINAPI DataCache_InitNew(
227 IPersistStorage* iface,
228 IStorage* pStg);
229static HRESULT WINAPI DataCache_Load(
230 IPersistStorage* iface,
231 IStorage* pStg);
232static HRESULT WINAPI DataCache_Save(
233 IPersistStorage* iface,
234 IStorage* pStg,
235 BOOL fSameAsLoad);
236static HRESULT WINAPI DataCache_SaveCompleted(
237 IPersistStorage* iface,
238 IStorage* pStgNew);
239static HRESULT WINAPI DataCache_HandsOffStorage(
240 IPersistStorage* iface);
241
242/*
243 * Prototypes for the methods of the DataCache class
244 * that implement IViewObject2 methods.
245 */
246static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
247 IViewObject2* iface,
248 REFIID riid,
249 void** ppvObject);
250static ULONG WINAPI DataCache_IViewObject2_AddRef(
251 IViewObject2* iface);
252static ULONG WINAPI DataCache_IViewObject2_Release(
253 IViewObject2* iface);
254static HRESULT WINAPI DataCache_Draw(
255 IViewObject2* iface,
256 DWORD dwDrawAspect,
257 LONG lindex,
258 void* pvAspect,
259 DVTARGETDEVICE* ptd,
260 HDC hdcTargetDev,
261 HDC hdcDraw,
262 LPCRECTL lprcBounds,
263 LPCRECTL lprcWBounds,
264 IVO_ContCallback pfnContinue,
265 DWORD dwContinue);
266static HRESULT WINAPI DataCache_GetColorSet(
267 IViewObject2* iface,
268 DWORD dwDrawAspect,
269 LONG lindex,
270 void* pvAspect,
271 DVTARGETDEVICE* ptd,
272 HDC hicTargetDevice,
273 tagLOGPALETTE** ppColorSet);
274static HRESULT WINAPI DataCache_Freeze(
275 IViewObject2* iface,
276 DWORD dwDrawAspect,
277 LONG lindex,
278 void* pvAspect,
279 DWORD* pdwFreeze);
280static HRESULT WINAPI DataCache_Unfreeze(
281 IViewObject2* iface,
282 DWORD dwFreeze);
283static HRESULT WINAPI DataCache_SetAdvise(
284 IViewObject2* iface,
285 DWORD aspects,
286 DWORD advf,
287 IAdviseSink* pAdvSink);
288static HRESULT WINAPI DataCache_GetAdvise(
289 IViewObject2* iface,
290 DWORD* pAspects,
291 DWORD* pAdvf,
292 IAdviseSink** ppAdvSink);
293static HRESULT WINAPI DataCache_GetExtent(
294 IViewObject2* iface,
295 DWORD dwDrawAspect,
296 LONG lindex,
297 DVTARGETDEVICE* ptd,
298 LPSIZEL lpsizel);
299
300/*
301 * Prototypes for the methods of the DataCache class
302 * that implement IOleCache2 methods.
303 */
304static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
305 IOleCache2* iface,
306 REFIID riid,
307 void** ppvObject);
308static ULONG WINAPI DataCache_IOleCache2_AddRef(
309 IOleCache2* iface);
310static ULONG WINAPI DataCache_IOleCache2_Release(
311 IOleCache2* iface);
312static HRESULT WINAPI DataCache_Cache(
313 IOleCache2* iface,
314 FORMATETC* pformatetc,
315 DWORD advf,
316 DWORD* pdwConnection);
317static HRESULT WINAPI DataCache_Uncache(
318 IOleCache2* iface,
319 DWORD dwConnection);
320static HRESULT WINAPI DataCache_EnumCache(
321 IOleCache2* iface,
322 IEnumSTATDATA** ppenumSTATDATA);
323static HRESULT WINAPI DataCache_InitCache(
324 IOleCache2* iface,
325 IDataObject* pDataObject);
326static HRESULT WINAPI DataCache_IOleCache2_SetData(
327 IOleCache2* iface,
328 FORMATETC* pformatetc,
329 STGMEDIUM* pmedium,
330 BOOL fRelease);
331static HRESULT WINAPI DataCache_UpdateCache(
332 IOleCache2* iface,
333 LPDATAOBJECT pDataObject,
334 DWORD grfUpdf,
335 LPVOID pReserved);
336static HRESULT WINAPI DataCache_DiscardCache(
337 IOleCache2* iface,
338 DWORD dwDiscardOptions);
339
340/*
341 * Prototypes for the methods of the DataCache class
342 * that implement IOleCacheControl methods.
343 */
344static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
345 IOleCacheControl* iface,
346 REFIID riid,
347 void** ppvObject);
348static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
349 IOleCacheControl* iface);
350static ULONG WINAPI DataCache_IOleCacheControl_Release(
351 IOleCacheControl* iface);
352static HRESULT WINAPI DataCache_OnRun(
353 IOleCacheControl* iface,
354 LPDATAOBJECT pDataObject);
355static HRESULT WINAPI DataCache_OnStop(
356 IOleCacheControl* iface);
357
358/*
359 * Virtual function tables for the DataCache class.
360 */
361static ICOM_VTABLE(IUnknown) DataCache_NDIUnknown_VTable =
362{
363 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
364 DataCache_NDIUnknown_QueryInterface,
365 DataCache_NDIUnknown_AddRef,
366 DataCache_NDIUnknown_Release
367};
368
369static ICOM_VTABLE(IDataObject) DataCache_IDataObject_VTable =
370{
371 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
372 DataCache_IDataObject_QueryInterface,
373 DataCache_IDataObject_AddRef,
374 DataCache_IDataObject_Release,
375 DataCache_GetData,
376 DataCache_GetDataHere,
377 DataCache_QueryGetData,
378 DataCache_GetCanonicalFormatEtc,
379 DataCache_IDataObject_SetData,
380 DataCache_EnumFormatEtc,
381 DataCache_DAdvise,
382 DataCache_DUnadvise,
383 DataCache_EnumDAdvise
384};
385
386static ICOM_VTABLE(IPersistStorage) DataCache_IPersistStorage_VTable =
387{
388 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
389 DataCache_IPersistStorage_QueryInterface,
390 DataCache_IPersistStorage_AddRef,
391 DataCache_IPersistStorage_Release,
392 DataCache_GetClassID,
393 DataCache_IsDirty,
394 DataCache_InitNew,
395 DataCache_Load,
396 DataCache_Save,
397 DataCache_SaveCompleted,
398 DataCache_HandsOffStorage
399};
400
401static ICOM_VTABLE(IViewObject2) DataCache_IViewObject2_VTable =
402{
403 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
404 DataCache_IViewObject2_QueryInterface,
405 DataCache_IViewObject2_AddRef,
406 DataCache_IViewObject2_Release,
407 DataCache_Draw,
408 DataCache_GetColorSet,
409 DataCache_Freeze,
410 DataCache_Unfreeze,
411 DataCache_SetAdvise,
412 DataCache_GetAdvise,
413 DataCache_GetExtent
414};
415
416static ICOM_VTABLE(IOleCache2) DataCache_IOleCache2_VTable =
417{
418 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
419 DataCache_IOleCache2_QueryInterface,
420 DataCache_IOleCache2_AddRef,
421 DataCache_IOleCache2_Release,
422 DataCache_Cache,
423 DataCache_Uncache,
424 DataCache_EnumCache,
425 DataCache_InitCache,
426 DataCache_IOleCache2_SetData,
427 DataCache_UpdateCache,
428 DataCache_DiscardCache
429};
430
431static ICOM_VTABLE(IOleCacheControl) DataCache_IOleCacheControl_VTable =
432{
433 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
434 DataCache_IOleCacheControl_QueryInterface,
435 DataCache_IOleCacheControl_AddRef,
436 DataCache_IOleCacheControl_Release,
437 DataCache_OnRun,
438 DataCache_OnStop
439};
440
441/******************************************************************************
442 * CreateDataCache [OLE32.54]
443 */
444HRESULT WINAPI CreateDataCache(
445 LPUNKNOWN pUnkOuter,
446 REFCLSID rclsid,
447 REFIID riid,
448 LPVOID* ppvObj)
449{
450 DataCache* newCache = NULL;
451 HRESULT hr = S_OK;
452 char xclsid[50];
453 char xriid[50];
454
455 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
456 WINE_StringFromCLSID((LPCLSID)riid,xriid);
457
458 TRACE("(%s, %p, %s, %p)\n", xclsid, pUnkOuter, xriid, ppvObj);
459
460 /*
461 * Sanity check
462 */
463 if (ppvObj==0)
464 return E_POINTER;
465
466 *ppvObj = 0;
467
468 /*
469 * If This cache is constructed for aggregation, make sure
470 * the caller is requesting the IUnknown interface.
471 * This is necessary because it's the only time the non-delegating
472 * IUnknown pointer can be returned to the outside.
473 */
474 if ( (pUnkOuter!=NULL) &&
475 (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) != 0) )
476 return CLASS_E_NOAGGREGATION;
477
478 /*
479 * Try to construct a new instance of the class.
480 */
481 newCache = DataCache_Construct(rclsid,
482 pUnkOuter);
483
484 if (newCache == 0)
485 return E_OUTOFMEMORY;
486
487 /*
488 * Make sure it supports the interface required by the caller.
489 */
490 hr = IUnknown_QueryInterface((IUnknown*)&(newCache->lpvtbl2), riid, ppvObj);
491
492 /*
493 * Release the reference obtained in the constructor. If
494 * the QueryInterface was unsuccessful, it will free the class.
495 */
496 IUnknown_Release((IUnknown*)&(newCache->lpvtbl2));
497
498 return hr;
499}
500
501/*********************************************************
502 * Method implementation for DataCache class.
503 */
504static DataCache* DataCache_Construct(
505 REFCLSID clsid,
506 LPUNKNOWN pUnkOuter)
507{
508 DataCache* newObject = 0;
509
510 /*
511 * Allocate space for the object.
512 */
513 newObject = (DataCache *)HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache));
514
515 if (newObject==0)
516 return newObject;
517
518 /*
519 * Initialize the virtual function table.
520 */
521 newObject->lpvtbl1 = &DataCache_IDataObject_VTable;
522 newObject->lpvtbl2 = &DataCache_NDIUnknown_VTable;
523 newObject->lpvtbl3 = &DataCache_IPersistStorage_VTable;
524 newObject->lpvtbl4 = &DataCache_IViewObject2_VTable;
525 newObject->lpvtbl5 = &DataCache_IOleCache2_VTable;
526 newObject->lpvtbl6 = &DataCache_IOleCacheControl_VTable;
527
528 /*
529 * Start with one reference count. The caller of This function
530 * must release the interface pointer when it is done.
531 */
532 newObject->ref = 1;
533
534 /*
535 * Initialize the outer unknown
536 * We don't keep a reference on the outer unknown since, the way
537 * aggregation works, our lifetime is at least as large as it's
538 * lifetime.
539 */
540 if (pUnkOuter==NULL)
541 pUnkOuter = (IUnknown*)&(newObject->lpvtbl2);
542
543 newObject->outerUnknown = pUnkOuter;
544
545 /*
546 * Initialize the other members of the structure.
547 */
548 newObject->presentationStorage = NULL;
549 newObject->sinkAspects = 0;
550 newObject->sinkAdviseFlag = 0;
551 newObject->sinkInterface = 0;
552
553 return newObject;
554}
555
556static void DataCache_Destroy(
557 DataCache* ptrToDestroy)
558{
559 TRACE("()\n");
560
561 if (ptrToDestroy->sinkInterface != NULL)
562 {
563 IAdviseSink_Release(ptrToDestroy->sinkInterface);
564 ptrToDestroy->sinkInterface = NULL;
565 }
566
567 if (ptrToDestroy->presentationStorage != NULL)
568 {
569 IStorage_Release(ptrToDestroy->presentationStorage);
570 ptrToDestroy->presentationStorage = NULL;
571 }
572
573 /*
574 * Free the datacache pointer.
575 */
576 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
577}
578
579/************************************************************************
580 * DataCache_ReadPresentationData
581 *
582 * This method will read information for the requested presentation
583 * into the given structure.
584 *
585 * Param:
586 * This - Pointer to the DataCache object
587 * drawAspect - The aspect of the object that we wish to draw.
588 * header - The structure containing information about This
589 * aspect of the object.
590 */
591static HRESULT DataCache_ReadPresentationData(
592 DataCache* This,
593 DWORD drawAspect,
594 PresentationDataHeader* header)
595{
596 IStream* presStream = NULL;
597 OLECHAR streamName[20];
598 HRESULT hres;
599
600 /*
601 * Get the name for the presentation stream.
602 */
603 hres = DataCache_FindPresStreamName(
604 This,
605 drawAspect,
606 streamName);
607
608 if (FAILED(hres))
609 return hres;
610
611 /*
612 * Open the stream and read the header.
613 */
614 hres = IStorage_OpenStream(
615 This->presentationStorage,
616 streamName,
617 NULL,
618 STGM_READ | STGM_SHARE_EXCLUSIVE,
619 0,
620 &presStream);
621
622 if (FAILED(hres))
623 return hres;
624
625 hres = IStream_Read(
626 presStream,
627 header,
628 sizeof(PresentationDataHeader),
629 NULL);
630
631 /*
632 * Cleanup.
633 */
634 IStream_Release(presStream);
635
636 /*
637 * We don't want to propagate any other error
638 * code than a failure.
639 */
640 if (hres!=S_OK)
641 hres = E_FAIL;
642
643 return hres;
644}
645
646/************************************************************************
647 * DataCache_FireOnViewChange
648 *
649 * This method will fire an OnViewChange notification to the advise
650 * sink registered with the datacache.
651 *
652 * See IAdviseSink::OnViewChange for more details.
653 */
654static void DataCache_FireOnViewChange(
655 DataCache* This,
656 DWORD aspect,
657 LONG lindex)
658{
659 TRACE("(%p, %lx, %ld)\n", This, aspect, lindex);
660
661 /*
662 * The sink supplies a filter when it registers
663 * we make sure we only send the notifications when that
664 * filter matches.
665 */
666 if ((This->sinkAspects & aspect) != 0)
667 {
668 if (This->sinkInterface != NULL)
669 {
670 IAdviseSink_OnViewChange(This->sinkInterface,
671 aspect,
672 lindex);
673
674 /*
675 * Some sinks want to be unregistered automatically when
676 * the first notification goes out.
677 */
678 if ( (This->sinkAdviseFlag & ADVF_ONLYONCE) != 0)
679 {
680 IAdviseSink_Release(This->sinkInterface);
681
682 This->sinkInterface = NULL;
683 This->sinkAspects = 0;
684 This->sinkAdviseFlag = 0;
685 }
686 }
687 }
688}
689
690/************************************************************************
691 * DataCache_ReadPresentationData
692 *
693 * This method will read information for the requested presentation
694 * into the given structure.
695 *
696 * Param:
697 * This - Pointer to the DataCache object
698 * drawAspect - The aspect of the object that we wish to draw.
699 * header - The structure containing information about This
700 * aspect of the object.
701 *
702 * NOTE:
703 * This method only supports the DVASPECT_CONTENT aspect.
704 */
705static HRESULT DataCache_FindPresStreamName(
706 DataCache* This,
707 DWORD drawAspect,
708 OLECHAR* buffer)
709{
710 OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
711
712 if (drawAspect!=DVASPECT_CONTENT)
713 return E_FAIL;
714
715 memcpy(buffer, name, sizeof(name));
716
717 return S_OK;
718}
719
720/************************************************************************
721 * DataCache_ReadPresentationData
722 *
723 * This method will read information for the requested presentation
724 * into the given structure.
725 *
726 * Param:
727 * This - Pointer to the DataCache object
728 * drawAspect - The aspect of the object that we wish to draw.
729 *
730 * Returns:
731 * This method returns a metafile handle if it is successful.
732 * it will return 0 if not.
733 */
734static HMETAFILE DataCache_ReadPresMetafile(
735 DataCache* This,
736 DWORD drawAspect)
737{
738 LARGE_INTEGER offset;
739 IStream* presStream = NULL;
740 OLECHAR streamName[20];
741 HRESULT hres;
742 void* metafileBits;
743 STATSTG streamInfo;
744 HMETAFILE newMetafile = 0;
745
746 /*
747 * Get the name for the presentation stream.
748 */
749 hres = DataCache_FindPresStreamName(
750 This,
751 drawAspect,
752 streamName);
753
754 if (FAILED(hres))
755 return hres;
756
757 /*
758 * Open the stream and read the header.
759 */
760 hres = IStorage_OpenStream(
761 This->presentationStorage,
762 streamName,
763 NULL,
764 STGM_READ | STGM_SHARE_EXCLUSIVE,
765 0,
766 &presStream);
767
768 if (FAILED(hres))
769 return hres;
770
771 /*
772 * Get the size of the stream.
773 */
774 hres = IStream_Stat(presStream,
775 &streamInfo,
776 STATFLAG_NONAME);
777
778 /*
779 * Skip the header
780 */
781 offset.HighPart = 0;
782 offset.LowPart = sizeof(PresentationDataHeader);
783
784 hres = IStream_Seek(
785 presStream,
786 offset,
787 STREAM_SEEK_SET,
788 NULL);
789
790 /*
791 * Allocate a buffer for the metafile bits.
792 */
793 metafileBits = HeapAlloc(GetProcessHeap(),
794 0,
795 streamInfo.cbSize.LowPart);
796
797 /*
798 * Read the metafile bits.
799 */
800 hres = IStream_Read(
801 presStream,
802 metafileBits,
803 streamInfo.cbSize.LowPart,
804 NULL);
805
806 /*
807 * Create a metafile with those bits.
808 */
809 if (SUCCEEDED(hres))
810 {
811 newMetafile = SetMetaFileBitsEx(streamInfo.cbSize.LowPart, (const BYTE *)metafileBits);
812 }
813
814 /*
815 * Cleanup.
816 */
817 HeapFree(GetProcessHeap(), 0, metafileBits);
818 IStream_Release(presStream);
819
820 if (newMetafile==0)
821 hres = E_FAIL;
822
823 return newMetafile;
824}
825
826/*********************************************************
827 * Method implementation for the non delegating IUnknown
828 * part of the DataCache class.
829 */
830
831/************************************************************************
832 * DataCache_NDIUnknown_QueryInterface (IUnknown)
833 *
834 * See Windows documentation for more details on IUnknown methods.
835 *
836 * This version of QueryInterface will not delegate it's implementation
837 * to the outer unknown.
838 */
839static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
840 IUnknown* iface,
841 REFIID riid,
842 void** ppvObject)
843{
844 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
845
846 /*
847 * Perform a sanity check on the parameters.
848 */
849 if ( (This==0) || (ppvObject==0) )
850 return E_INVALIDARG;
851
852 /*
853 * Initialize the return parameter.
854 */
855 *ppvObject = 0;
856
857 /*
858 * Compare the riid with the interface IDs implemented by This object.
859 */
860 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
861 {
862 *ppvObject = iface;
863 }
864 else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0)
865 {
866 *ppvObject = (IDataObject*)&(This->lpvtbl1);
867 }
868 else if ( (memcmp(&IID_IPersistStorage, riid, sizeof(IID_IPersistStorage)) == 0) ||
869 (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0) )
870 {
871 *ppvObject = (IPersistStorage*)&(This->lpvtbl3);
872 }
873 else if ( (memcmp(&IID_IViewObject, riid, sizeof(IID_IViewObject)) == 0) ||
874 (memcmp(&IID_IViewObject2, riid, sizeof(IID_IViewObject2)) == 0) )
875 {
876 *ppvObject = (IViewObject2*)&(This->lpvtbl4);
877 }
878 else if ( (memcmp(&IID_IOleCache, riid, sizeof(IID_IOleCache)) == 0) ||
879 (memcmp(&IID_IOleCache2, riid, sizeof(IID_IOleCache2)) == 0) )
880 {
881 *ppvObject = (IOleCache2*)&(This->lpvtbl5);
882 }
883 else if (memcmp(&IID_IOleCacheControl, riid, sizeof(IID_IOleCacheControl)) == 0)
884 {
885 *ppvObject = (IOleCacheControl*)&(This->lpvtbl6);
886 }
887
888 /*
889 * Check that we obtained an interface.
890 */
891 if ((*ppvObject)==0)
892 {
893 char clsid[50];
894
895 WINE_StringFromCLSID((LPCLSID)riid,clsid);
896
897 WARN(
898 "() : asking for un supported interface %s\n",
899 clsid);
900
901 return E_NOINTERFACE;
902 }
903
904 /*
905 * Query Interface always increases the reference count by one when it is
906 * successful.
907 */
908 IUnknown_AddRef((IUnknown*)*ppvObject);
909
910 return S_OK;;
911}
912
913/************************************************************************
914 * DataCache_NDIUnknown_AddRef (IUnknown)
915 *
916 * See Windows documentation for more details on IUnknown methods.
917 *
918 * This version of QueryInterface will not delegate it's implementation
919 * to the outer unknown.
920 */
921static ULONG WINAPI DataCache_NDIUnknown_AddRef(
922 IUnknown* iface)
923{
924 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
925
926 This->ref++;
927
928 return This->ref;
929}
930
931/************************************************************************
932 * DataCache_NDIUnknown_Release (IUnknown)
933 *
934 * See Windows documentation for more details on IUnknown methods.
935 *
936 * This version of QueryInterface will not delegate it's implementation
937 * to the outer unknown.
938 */
939static ULONG WINAPI DataCache_NDIUnknown_Release(
940 IUnknown* iface)
941{
942 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
943
944 /*
945 * Decrease the reference count on This object.
946 */
947 This->ref--;
948
949 /*
950 * If the reference count goes down to 0, perform suicide.
951 */
952 if (This->ref==0)
953 {
954 DataCache_Destroy(This);
955
956 return 0;
957 }
958
959 return This->ref;
960}
961
962/*********************************************************
963 * Method implementation for the IDataObject
964 * part of the DataCache class.
965 */
966
967/************************************************************************
968 * DataCache_IDataObject_QueryInterface (IUnknown)
969 *
970 * See Windows documentation for more details on IUnknown methods.
971 */
972static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
973 IDataObject* iface,
974 REFIID riid,
975 void** ppvObject)
976{
977 _ICOM_THIS_From_IDataObject(DataCache, iface);
978
979 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
980}
981
982/************************************************************************
983 * DataCache_IDataObject_AddRef (IUnknown)
984 *
985 * See Windows documentation for more details on IUnknown methods.
986 */
987static ULONG WINAPI DataCache_IDataObject_AddRef(
988 IDataObject* iface)
989{
990 _ICOM_THIS_From_IDataObject(DataCache, iface);
991
992 return IUnknown_AddRef(This->outerUnknown);
993}
994
995/************************************************************************
996 * DataCache_IDataObject_Release (IUnknown)
997 *
998 * See Windows documentation for more details on IUnknown methods.
999 */
1000static ULONG WINAPI DataCache_IDataObject_Release(
1001 IDataObject* iface)
1002{
1003 _ICOM_THIS_From_IDataObject(DataCache, iface);
1004
1005 return IUnknown_Release(This->outerUnknown);
1006}
1007
1008static HRESULT WINAPI DataCache_GetData(
1009 IDataObject* iface,
1010 LPFORMATETC pformatetcIn,
1011 STGMEDIUM* pmedium)
1012{
1013 FIXME("stub\n");
1014 return E_NOTIMPL;
1015}
1016
1017static HRESULT WINAPI DataCache_GetDataHere(
1018 IDataObject* iface,
1019 LPFORMATETC pformatetc,
1020 STGMEDIUM* pmedium)
1021{
1022 FIXME("stub\n");
1023 return E_NOTIMPL;
1024}
1025
1026static HRESULT WINAPI DataCache_QueryGetData(
1027 IDataObject* iface,
1028 LPFORMATETC pformatetc)
1029{
1030 FIXME("stub\n");
1031 return E_NOTIMPL;
1032}
1033
1034/************************************************************************
1035 * DataCache_EnumFormatEtc (IDataObject)
1036 *
1037 * The data cache doesn't implement This method.
1038 *
1039 * See Windows documentation for more details on IDataObject methods.
1040 */
1041static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
1042 IDataObject* iface,
1043 LPFORMATETC pformatectIn,
1044 LPFORMATETC pformatetcOut)
1045{
1046 TRACE("()\n");
1047 return E_NOTIMPL;
1048}
1049
1050/************************************************************************
1051 * DataCache_IDataObject_SetData (IDataObject)
1052 *
1053 * This method is delegated to the IOleCache2 implementation.
1054 *
1055 * See Windows documentation for more details on IDataObject methods.
1056 */
1057static HRESULT WINAPI DataCache_IDataObject_SetData(
1058 IDataObject* iface,
1059 LPFORMATETC pformatetc,
1060 STGMEDIUM* pmedium,
1061 BOOL fRelease)
1062{
1063 IOleCache2* oleCache = NULL;
1064 HRESULT hres;
1065
1066 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1067
1068 hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);
1069
1070 if (FAILED(hres))
1071 return E_UNEXPECTED;
1072
1073 hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);
1074
1075 IOleCache2_Release(oleCache);
1076
1077 return hres;;
1078}
1079
1080/************************************************************************
1081 * DataCache_EnumFormatEtc (IDataObject)
1082 *
1083 * The data cache doesn't implement This method.
1084 *
1085 * See Windows documentation for more details on IDataObject methods.
1086 */
1087static HRESULT WINAPI DataCache_EnumFormatEtc(
1088 IDataObject* iface,
1089 DWORD dwDirection,
1090 IEnumFORMATETC** ppenumFormatEtc)
1091{
1092 TRACE("()\n");
1093 return E_NOTIMPL;
1094}
1095
1096/************************************************************************
1097 * DataCache_DAdvise (IDataObject)
1098 *
1099 * The data cache doesn't support connections.
1100 *
1101 * See Windows documentation for more details on IDataObject methods.
1102 */
1103static HRESULT WINAPI DataCache_DAdvise(
1104 IDataObject* iface,
1105 FORMATETC* pformatetc,
1106 DWORD advf,
1107 IAdviseSink* pAdvSink,
1108 DWORD* pdwConnection)
1109{
1110 TRACE("()\n");
1111 return OLE_E_ADVISENOTSUPPORTED;
1112}
1113
1114/************************************************************************
1115 * DataCache_DUnadvise (IDataObject)
1116 *
1117 * The data cache doesn't support connections.
1118 *
1119 * See Windows documentation for more details on IDataObject methods.
1120 */
1121static HRESULT WINAPI DataCache_DUnadvise(
1122 IDataObject* iface,
1123 DWORD dwConnection)
1124{
1125 TRACE("()\n");
1126 return OLE_E_NOCONNECTION;
1127}
1128
1129/************************************************************************
1130 * DataCache_EnumDAdvise (IDataObject)
1131 *
1132 * The data cache doesn't support connections.
1133 *
1134 * See Windows documentation for more details on IDataObject methods.
1135 */
1136static HRESULT WINAPI DataCache_EnumDAdvise(
1137 IDataObject* iface,
1138 IEnumSTATDATA** ppenumAdvise)
1139{
1140 TRACE("()\n");
1141 return OLE_E_ADVISENOTSUPPORTED;
1142}
1143
1144/*********************************************************
1145 * Method implementation for the IDataObject
1146 * part of the DataCache class.
1147 */
1148
1149/************************************************************************
1150 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1151 *
1152 * See Windows documentation for more details on IUnknown methods.
1153 */
1154static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
1155 IPersistStorage* iface,
1156 REFIID riid,
1157 void** ppvObject)
1158{
1159 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1160
1161 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1162}
1163
1164/************************************************************************
1165 * DataCache_IPersistStorage_AddRef (IUnknown)
1166 *
1167 * See Windows documentation for more details on IUnknown methods.
1168 */
1169static ULONG WINAPI DataCache_IPersistStorage_AddRef(
1170 IPersistStorage* iface)
1171{
1172 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1173
1174 return IUnknown_AddRef(This->outerUnknown);
1175}
1176
1177/************************************************************************
1178 * DataCache_IPersistStorage_Release (IUnknown)
1179 *
1180 * See Windows documentation for more details on IUnknown methods.
1181 */
1182static ULONG WINAPI DataCache_IPersistStorage_Release(
1183 IPersistStorage* iface)
1184{
1185 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1186
1187 return IUnknown_Release(This->outerUnknown);
1188}
1189
1190/************************************************************************
1191 * DataCache_GetClassID (IPersistStorage)
1192 *
1193 * The data cache doesn't implement This method.
1194 *
1195 * See Windows documentation for more details on IPersistStorage methods.
1196 */
1197static HRESULT WINAPI DataCache_GetClassID(
1198 IPersistStorage* iface,
1199 CLSID* pClassID)
1200{
1201 TRACE("(%p, %p)\n", iface, pClassID);
1202 return E_NOTIMPL;
1203}
1204
1205/************************************************************************
1206 * DataCache_IsDirty (IPersistStorage)
1207 *
1208 * Until we actully connect to a running object and retrieve new
1209 * information to it, we never get dirty.
1210 *
1211 * See Windows documentation for more details on IPersistStorage methods.
1212 */
1213static HRESULT WINAPI DataCache_IsDirty(
1214 IPersistStorage* iface)
1215{
1216 TRACE("(%p)\n", iface);
1217
1218 return S_FALSE;
1219}
1220
1221/************************************************************************
1222 * DataCache_InitNew (IPersistStorage)
1223 *
1224 * The data cache implementation of IPersistStorage_InitNew simply stores
1225 * the storage pointer.
1226 *
1227 * See Windows documentation for more details on IPersistStorage methods.
1228 */
1229static HRESULT WINAPI DataCache_InitNew(
1230 IPersistStorage* iface,
1231 IStorage* pStg)
1232{
1233 TRACE("(%p, %p)\n", iface, pStg);
1234
1235 return DataCache_Load(iface, pStg);
1236}
1237
1238/************************************************************************
1239 * DataCache_Load (IPersistStorage)
1240 *
1241 * The data cache implementation of IPersistStorage_Load doesn't
1242 * actually load anything. Instead, it holds on to the storage pointer
1243 * and it will load the presentation information when the
1244 * IDataObject_GetData or IViewObject2_Draw methods are called.
1245 *
1246 * See Windows documentation for more details on IPersistStorage methods.
1247 */
1248static HRESULT WINAPI DataCache_Load(
1249 IPersistStorage* iface,
1250 IStorage* pStg)
1251{
1252 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1253
1254 TRACE("(%p, %p)\n", iface, pStg);
1255
1256 if (This->presentationStorage != NULL)
1257 {
1258 IStorage_Release(This->presentationStorage);
1259 }
1260
1261 This->presentationStorage = pStg;
1262
1263 if (This->presentationStorage != NULL)
1264 {
1265 IStorage_AddRef(This->presentationStorage);
1266 }
1267
1268 return S_OK;
1269}
1270
1271/************************************************************************
1272 * DataCache_Save (IPersistStorage)
1273 *
1274 * Until we actully connect to a running object and retrieve new
1275 * information to it, we never have to save anything. However, it is
1276 * our responsability to copy the information when saving to a new
1277 * storage.
1278 *
1279 * See Windows documentation for more details on IPersistStorage methods.
1280 */
1281static HRESULT WINAPI DataCache_Save(
1282 IPersistStorage* iface,
1283 IStorage* pStg,
1284 BOOL fSameAsLoad)
1285{
1286 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1287
1288 TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad);
1289
1290 if ( (!fSameAsLoad) &&
1291 (This->presentationStorage!=NULL) )
1292 {
1293 return IStorage_CopyTo(This->presentationStorage,
1294 0,
1295 NULL,
1296 NULL,
1297 pStg);
1298 }
1299
1300 return S_OK;
1301}
1302
1303/************************************************************************
1304 * DataCache_SaveCompleted (IPersistStorage)
1305 *
1306 * This method is called to tell the cache to release the storage
1307 * pointer it's currentlu holding.
1308 *
1309 * See Windows documentation for more details on IPersistStorage methods.
1310 */
1311static HRESULT WINAPI DataCache_SaveCompleted(
1312 IPersistStorage* iface,
1313 IStorage* pStgNew)
1314{
1315 TRACE("(%p, %p)\n", iface, pStgNew);
1316
1317 /*
1318 * First, make sure we get our hands off any storage we have.
1319 */
1320 DataCache_HandsOffStorage(iface);
1321
1322 /*
1323 * Then, attach to the new storage.
1324 */
1325 DataCache_Load(iface, pStgNew);
1326
1327 return S_OK;
1328}
1329
1330/************************************************************************
1331 * DataCache_HandsOffStorage (IPersistStorage)
1332 *
1333 * This method is called to tell the cache to release the storage
1334 * pointer it's currentlu holding.
1335 *
1336 * See Windows documentation for more details on IPersistStorage methods.
1337 */
1338static HRESULT WINAPI DataCache_HandsOffStorage(
1339 IPersistStorage* iface)
1340{
1341 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1342
1343 TRACE("(%p)\n", iface);
1344
1345 if (This->presentationStorage != NULL)
1346 {
1347 IStorage_Release(This->presentationStorage);
1348 This->presentationStorage = NULL;
1349 }
1350
1351 return S_OK;
1352}
1353
1354/*********************************************************
1355 * Method implementation for the IViewObject2
1356 * part of the DataCache class.
1357 */
1358
1359/************************************************************************
1360 * DataCache_IViewObject2_QueryInterface (IUnknown)
1361 *
1362 * See Windows documentation for more details on IUnknown methods.
1363 */
1364static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
1365 IViewObject2* iface,
1366 REFIID riid,
1367 void** ppvObject)
1368{
1369 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1370
1371 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1372}
1373
1374/************************************************************************
1375 * DataCache_IViewObject2_AddRef (IUnknown)
1376 *
1377 * See Windows documentation for more details on IUnknown methods.
1378 */
1379static ULONG WINAPI DataCache_IViewObject2_AddRef(
1380 IViewObject2* iface)
1381{
1382 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1383
1384 return IUnknown_AddRef(This->outerUnknown);
1385}
1386
1387/************************************************************************
1388 * DataCache_IViewObject2_Release (IUnknown)
1389 *
1390 * See Windows documentation for more details on IUnknown methods.
1391 */
1392static ULONG WINAPI DataCache_IViewObject2_Release(
1393 IViewObject2* iface)
1394{
1395 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1396
1397 return IUnknown_Release(This->outerUnknown);
1398}
1399
1400/************************************************************************
1401 * DataCache_Draw (IViewObject2)
1402 *
1403 * This method will draw the cached representation of the object
1404 * to the given device context.
1405 *
1406 * See Windows documentation for more details on IViewObject2 methods.
1407 */
1408static HRESULT WINAPI DataCache_Draw(
1409 IViewObject2* iface,
1410 DWORD dwDrawAspect,
1411 LONG lindex,
1412 void* pvAspect,
1413 DVTARGETDEVICE* ptd,
1414 HDC hdcTargetDev,
1415 HDC hdcDraw,
1416 LPCRECTL lprcBounds,
1417 LPCRECTL lprcWBounds,
1418 IVO_ContCallback pfnContinue,
1419 DWORD dwContinue)
1420{
1421 PresentationDataHeader presData;
1422 HMETAFILE presMetafile = 0;
1423 HRESULT hres;
1424
1425 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1426
1427 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1428 iface,
1429 dwDrawAspect,
1430 lindex,
1431 pvAspect,
1432 hdcTargetDev,
1433 hdcDraw,
1434 lprcBounds,
1435 lprcWBounds,
1436 pfnContinue,
1437 dwContinue);
1438
1439 /*
1440 * Sanity check
1441 */
1442 if (lprcBounds==NULL)
1443 return E_INVALIDARG;
1444
1445 /*
1446 * First, we need to retrieve the dimensions of the
1447 * image in the metafile.
1448 */
1449 hres = DataCache_ReadPresentationData(This,
1450 dwDrawAspect,
1451 &presData);
1452
1453 if (FAILED(hres))
1454 return hres;
1455
1456 /*
1457 * Then, we can extract the metafile itself from the cached
1458 * data.
1459 */
1460 presMetafile = DataCache_ReadPresMetafile(This,
1461 dwDrawAspect);
1462
1463 /*
1464 * If we have a metafile, just draw baby...
1465 * We have to be careful not to modify the state of the
1466 * DC.
1467 */
1468 if (presMetafile!=0)
1469 {
1470 INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC);
1471 SIZE oldWindowExt;
1472 SIZE oldViewportExt;
1473 POINT oldViewportOrg;
1474
1475 SetWindowExtEx(hdcDraw,
1476 presData.objectExtentX,
1477 presData.objectExtentY,
1478 &oldWindowExt);
1479
1480 SetViewportExtEx(hdcDraw,
1481 lprcBounds->right - lprcBounds->left,
1482 lprcBounds->bottom - lprcBounds->top,
1483 &oldViewportExt);
1484
1485 SetViewportOrgEx(hdcDraw,
1486 lprcBounds->left,
1487 lprcBounds->top,
1488 &oldViewportOrg);
1489
1490 PlayMetaFile(hdcDraw, presMetafile);
1491
1492 SetWindowExtEx(hdcDraw,
1493 oldWindowExt.cx,
1494 oldWindowExt.cy,
1495 NULL);
1496
1497 SetViewportExtEx(hdcDraw,
1498 oldViewportExt.cx,
1499 oldViewportExt.cy,
1500 NULL);
1501
1502 SetViewportOrgEx(hdcDraw,
1503 oldViewportOrg.x,
1504 oldViewportOrg.y,
1505 NULL);
1506
1507 SetMapMode(hdcDraw, prevMapMode);
1508
1509 DeleteMetaFile(presMetafile);
1510 }
1511
1512 return S_OK;
1513}
1514
1515static HRESULT WINAPI DataCache_GetColorSet(
1516 IViewObject2* iface,
1517 DWORD dwDrawAspect,
1518 LONG lindex,
1519 void* pvAspect,
1520 DVTARGETDEVICE* ptd,
1521 HDC hicTargetDevice,
1522 tagLOGPALETTE** ppColorSet)
1523{
1524 FIXME("stub\n");
1525 return E_NOTIMPL;
1526}
1527
1528static HRESULT WINAPI DataCache_Freeze(
1529 IViewObject2* iface,
1530 DWORD dwDrawAspect,
1531 LONG lindex,
1532 void* pvAspect,
1533 DWORD* pdwFreeze)
1534{
1535 FIXME("stub\n");
1536 return E_NOTIMPL;
1537}
1538
1539static HRESULT WINAPI DataCache_Unfreeze(
1540 IViewObject2* iface,
1541 DWORD dwFreeze)
1542{
1543 FIXME("stub\n");
1544 return E_NOTIMPL;
1545}
1546
1547/************************************************************************
1548 * DataCache_SetAdvise (IViewObject2)
1549 *
1550 * This sets-up an advisory sink with the data cache. When the object's
1551 * view changes, This sink is called.
1552 *
1553 * See Windows documentation for more details on IViewObject2 methods.
1554 */
1555static HRESULT WINAPI DataCache_SetAdvise(
1556 IViewObject2* iface,
1557 DWORD aspects,
1558 DWORD advf,
1559 IAdviseSink* pAdvSink)
1560{
1561 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1562
1563 TRACE("(%p, %lx, %lx, %p)\n", iface, aspects, advf, pAdvSink);
1564
1565 /*
1566 * A call to This function removes the previous sink
1567 */
1568 if (This->sinkInterface != NULL)
1569 {
1570 IAdviseSink_Release(This->sinkInterface);
1571 This->sinkInterface = NULL;
1572 This->sinkAspects = 0;
1573 This->sinkAdviseFlag = 0;
1574 }
1575
1576 /*
1577 * Now, setup the new one.
1578 */
1579 if (pAdvSink!=NULL)
1580 {
1581 This->sinkInterface = pAdvSink;
1582 This->sinkAspects = aspects;
1583 This->sinkAdviseFlag = advf;
1584
1585 IAdviseSink_AddRef(This->sinkInterface);
1586 }
1587
1588 /*
1589 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1590 * sink immediately.
1591 */
1592 if (advf & ADVF_PRIMEFIRST)
1593 {
1594 DataCache_FireOnViewChange(This,
1595 DVASPECT_CONTENT,
1596 -1);
1597 }
1598
1599 return S_OK;
1600}
1601
1602/************************************************************************
1603 * DataCache_GetAdvise (IViewObject2)
1604 *
1605 * This method queries the current state of the advise sink
1606 * installed on the data cache.
1607 *
1608 * See Windows documentation for more details on IViewObject2 methods.
1609 */
1610static HRESULT WINAPI DataCache_GetAdvise(
1611 IViewObject2* iface,
1612 DWORD* pAspects,
1613 DWORD* pAdvf,
1614 IAdviseSink** ppAdvSink)
1615{
1616 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1617
1618 TRACE("(%p, %p, %p, %p)\n", iface, pAspects, pAdvf, ppAdvSink);
1619
1620 /*
1621 * Just copy all the requested values.
1622 */
1623 if (pAspects!=NULL)
1624 *pAspects = This->sinkAspects;
1625
1626 if (pAdvf!=NULL)
1627 *pAdvf = This->sinkAdviseFlag;
1628
1629 if (ppAdvSink!=NULL)
1630 {
1631 IAdviseSink_QueryInterface(This->sinkInterface,
1632 &IID_IAdviseSink,
1633 (void**)ppAdvSink);
1634 }
1635
1636 return S_OK;
1637}
1638
1639/************************************************************************
1640 * DataCache_GetExtent (IViewObject2)
1641 *
1642 * This method retrieves the "natural" size of This cached object.
1643 *
1644 * See Windows documentation for more details on IViewObject2 methods.
1645 */
1646static HRESULT WINAPI DataCache_GetExtent(
1647 IViewObject2* iface,
1648 DWORD dwDrawAspect,
1649 LONG lindex,
1650 DVTARGETDEVICE* ptd,
1651 LPSIZEL lpsizel)
1652{
1653 PresentationDataHeader presData;
1654 HRESULT hres = E_FAIL;
1655
1656 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1657
1658 TRACE("(%p, %lx, %ld, %p, %p)\n",
1659 iface, dwDrawAspect, lindex, ptd, lpsizel);
1660
1661 /*
1662 * Sanity check
1663 */
1664 if (lpsizel==NULL)
1665 return E_POINTER;
1666
1667 /*
1668 * Initialize the out parameter.
1669 */
1670 lpsizel->cx = 0;
1671 lpsizel->cy = 0;
1672
1673 /*
1674 * This flag should be set to -1.
1675 */
1676 if (lindex!=-1)
1677 FIXME("Unimplemented flag lindex = %ld\n", lindex);
1678
1679 /*
1680 * Right now, we suport only the callback from
1681 * the default handler.
1682 */
1683 if (ptd!=NULL)
1684 FIXME("Unimplemented ptd = %p\n", ptd);
1685
1686 /*
1687 * Get the presentation information from the
1688 * cache.
1689 */
1690 hres = DataCache_ReadPresentationData(This,
1691 dwDrawAspect,
1692 &presData);
1693
1694 if (SUCCEEDED(hres))
1695 {
1696 lpsizel->cx = presData.objectExtentX;
1697 lpsizel->cy = presData.objectExtentY;
1698 }
1699
1700 /*
1701 * This method returns OLE_E_BLANK when it fails.
1702 */
1703 if (FAILED(hres))
1704 hres = OLE_E_BLANK;
1705
1706 return hres;
1707}
1708
1709
1710/*********************************************************
1711 * Method implementation for the IOleCache2
1712 * part of the DataCache class.
1713 */
1714
1715/************************************************************************
1716 * DataCache_IOleCache2_QueryInterface (IUnknown)
1717 *
1718 * See Windows documentation for more details on IUnknown methods.
1719 */
1720static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
1721 IOleCache2* iface,
1722 REFIID riid,
1723 void** ppvObject)
1724{
1725 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1726
1727 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1728}
1729
1730/************************************************************************
1731 * DataCache_IOleCache2_AddRef (IUnknown)
1732 *
1733 * See Windows documentation for more details on IUnknown methods.
1734 */
1735static ULONG WINAPI DataCache_IOleCache2_AddRef(
1736 IOleCache2* iface)
1737{
1738 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1739
1740 return IUnknown_AddRef(This->outerUnknown);
1741}
1742
1743/************************************************************************
1744 * DataCache_IOleCache2_Release (IUnknown)
1745 *
1746 * See Windows documentation for more details on IUnknown methods.
1747 */
1748static ULONG WINAPI DataCache_IOleCache2_Release(
1749 IOleCache2* iface)
1750{
1751 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1752
1753 return IUnknown_Release(This->outerUnknown);
1754}
1755
1756static HRESULT WINAPI DataCache_Cache(
1757 IOleCache2* iface,
1758 FORMATETC* pformatetc,
1759 DWORD advf,
1760 DWORD* pdwConnection)
1761{
1762 FIXME("stub\n");
1763 return E_NOTIMPL;
1764}
1765
1766static HRESULT WINAPI DataCache_Uncache(
1767 IOleCache2* iface,
1768 DWORD dwConnection)
1769{
1770 FIXME("stub\n");
1771 return E_NOTIMPL;
1772}
1773
1774static HRESULT WINAPI DataCache_EnumCache(
1775 IOleCache2* iface,
1776 IEnumSTATDATA** ppenumSTATDATA)
1777{
1778 FIXME("stub\n");
1779 return E_NOTIMPL;
1780}
1781
1782static HRESULT WINAPI DataCache_InitCache(
1783 IOleCache2* iface,
1784 IDataObject* pDataObject)
1785{
1786 FIXME("stub\n");
1787 return E_NOTIMPL;
1788}
1789
1790static HRESULT WINAPI DataCache_IOleCache2_SetData(
1791 IOleCache2* iface,
1792 FORMATETC* pformatetc,
1793 STGMEDIUM* pmedium,
1794 BOOL fRelease)
1795{
1796 FIXME("stub\n");
1797 return E_NOTIMPL;
1798}
1799
1800static HRESULT WINAPI DataCache_UpdateCache(
1801 IOleCache2* iface,
1802 LPDATAOBJECT pDataObject,
1803 DWORD grfUpdf,
1804 LPVOID pReserved)
1805{
1806 FIXME("stub\n");
1807 return E_NOTIMPL;
1808}
1809
1810static HRESULT WINAPI DataCache_DiscardCache(
1811 IOleCache2* iface,
1812 DWORD dwDiscardOptions)
1813{
1814 FIXME("stub\n");
1815 return E_NOTIMPL;
1816}
1817
1818
1819/*********************************************************
1820 * Method implementation for the IOleCacheControl
1821 * part of the DataCache class.
1822 */
1823
1824/************************************************************************
1825 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1826 *
1827 * See Windows documentation for more details on IUnknown methods.
1828 */
1829static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
1830 IOleCacheControl* iface,
1831 REFIID riid,
1832 void** ppvObject)
1833{
1834 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1835
1836 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1837}
1838
1839/************************************************************************
1840 * DataCache_IOleCacheControl_AddRef (IUnknown)
1841 *
1842 * See Windows documentation for more details on IUnknown methods.
1843 */
1844static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
1845 IOleCacheControl* iface)
1846{
1847 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1848
1849 return IUnknown_AddRef(This->outerUnknown);
1850}
1851
1852/************************************************************************
1853 * DataCache_IOleCacheControl_Release (IUnknown)
1854 *
1855 * See Windows documentation for more details on IUnknown methods.
1856 */
1857static ULONG WINAPI DataCache_IOleCacheControl_Release(
1858 IOleCacheControl* iface)
1859{
1860 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1861
1862 return IUnknown_Release(This->outerUnknown);
1863}
1864
1865static HRESULT WINAPI DataCache_OnRun(
1866 IOleCacheControl* iface,
1867 LPDATAOBJECT pDataObject)
1868{
1869 FIXME("stub\n");
1870 return E_NOTIMPL;
1871}
1872
1873static HRESULT WINAPI DataCache_OnStop(
1874 IOleCacheControl* iface)
1875{
1876 FIXME("stub\n");
1877 return E_NOTIMPL;
1878}
1879
1880
Note: See TracBrowser for help on using the repository browser.