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

Last change on this file since 3832 was 3167, checked in by davidr, 25 years ago

Ported changes from wine/corel sources

File size: 49.4 KB
Line 
1/* $Id: datacache.cpp,v 1.2 2000-03-19 15:33:05 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 if (pStgNew)
1318 {
1319 /*
1320 * First, make sure we get our hands off any storage we have.
1321 */
1322 DataCache_HandsOffStorage(iface);
1323
1324 /*
1325 * Then, attach to the new storage.
1326 */
1327 DataCache_Load(iface, pStgNew);
1328 }
1329
1330 return S_OK;
1331}
1332
1333/************************************************************************
1334 * DataCache_HandsOffStorage (IPersistStorage)
1335 *
1336 * This method is called to tell the cache to release the storage
1337 * pointer it's currentlu holding.
1338 *
1339 * See Windows documentation for more details on IPersistStorage methods.
1340 */
1341static HRESULT WINAPI DataCache_HandsOffStorage(
1342 IPersistStorage* iface)
1343{
1344 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1345
1346 TRACE("(%p)\n", iface);
1347
1348 if (This->presentationStorage != NULL)
1349 {
1350 IStorage_Release(This->presentationStorage);
1351 This->presentationStorage = NULL;
1352 }
1353
1354 return S_OK;
1355}
1356
1357/*********************************************************
1358 * Method implementation for the IViewObject2
1359 * part of the DataCache class.
1360 */
1361
1362/************************************************************************
1363 * DataCache_IViewObject2_QueryInterface (IUnknown)
1364 *
1365 * See Windows documentation for more details on IUnknown methods.
1366 */
1367static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
1368 IViewObject2* iface,
1369 REFIID riid,
1370 void** ppvObject)
1371{
1372 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1373
1374 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1375}
1376
1377/************************************************************************
1378 * DataCache_IViewObject2_AddRef (IUnknown)
1379 *
1380 * See Windows documentation for more details on IUnknown methods.
1381 */
1382static ULONG WINAPI DataCache_IViewObject2_AddRef(
1383 IViewObject2* iface)
1384{
1385 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1386
1387 return IUnknown_AddRef(This->outerUnknown);
1388}
1389
1390/************************************************************************
1391 * DataCache_IViewObject2_Release (IUnknown)
1392 *
1393 * See Windows documentation for more details on IUnknown methods.
1394 */
1395static ULONG WINAPI DataCache_IViewObject2_Release(
1396 IViewObject2* iface)
1397{
1398 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1399
1400 return IUnknown_Release(This->outerUnknown);
1401}
1402
1403/************************************************************************
1404 * DataCache_Draw (IViewObject2)
1405 *
1406 * This method will draw the cached representation of the object
1407 * to the given device context.
1408 *
1409 * See Windows documentation for more details on IViewObject2 methods.
1410 */
1411static HRESULT WINAPI DataCache_Draw(
1412 IViewObject2* iface,
1413 DWORD dwDrawAspect,
1414 LONG lindex,
1415 void* pvAspect,
1416 DVTARGETDEVICE* ptd,
1417 HDC hdcTargetDev,
1418 HDC hdcDraw,
1419 LPCRECTL lprcBounds,
1420 LPCRECTL lprcWBounds,
1421 IVO_ContCallback pfnContinue,
1422 DWORD dwContinue)
1423{
1424 PresentationDataHeader presData;
1425 HMETAFILE presMetafile = 0;
1426 HRESULT hres;
1427
1428 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1429
1430 TRACE("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1431 iface,
1432 dwDrawAspect,
1433 lindex,
1434 pvAspect,
1435 hdcTargetDev,
1436 hdcDraw,
1437 lprcBounds,
1438 lprcWBounds,
1439 pfnContinue,
1440 dwContinue);
1441
1442 /*
1443 * Sanity check
1444 */
1445 if (lprcBounds==NULL)
1446 return E_INVALIDARG;
1447
1448/** Hack for WPO2000 release. */
1449 if (dwDrawAspect != DVASPECT_CONTENT)
1450 {
1451 FIXME("only CONTENT aspect implemented\n");
1452 dwDrawAspect = DVASPECT_CONTENT;
1453 }
1454/***/
1455
1456 /*
1457 * First, we need to retrieve the dimensions of the
1458 * image in the metafile.
1459 */
1460 hres = DataCache_ReadPresentationData(This,
1461 dwDrawAspect,
1462 &presData);
1463
1464 if (FAILED(hres))
1465 return hres;
1466
1467 /*
1468 * Then, we can extract the metafile itself from the cached
1469 * data.
1470 */
1471 presMetafile = DataCache_ReadPresMetafile(This,
1472 dwDrawAspect);
1473
1474 /*
1475 * If we have a metafile, just draw baby...
1476 * We have to be careful not to modify the state of the
1477 * DC.
1478 */
1479 if (presMetafile!=0)
1480 {
1481 INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC);
1482 SIZE oldWindowExt;
1483 SIZE oldViewportExt;
1484 POINT oldViewportOrg;
1485
1486 SetWindowExtEx(hdcDraw,
1487 presData.objectExtentX,
1488 presData.objectExtentY,
1489 &oldWindowExt);
1490
1491 SetViewportExtEx(hdcDraw,
1492 lprcBounds->right - lprcBounds->left,
1493 lprcBounds->bottom - lprcBounds->top,
1494 &oldViewportExt);
1495
1496 SetViewportOrgEx(hdcDraw,
1497 lprcBounds->left,
1498 lprcBounds->top,
1499 &oldViewportOrg);
1500
1501 PlayMetaFile(hdcDraw, presMetafile);
1502
1503 SetWindowExtEx(hdcDraw,
1504 oldWindowExt.cx,
1505 oldWindowExt.cy,
1506 NULL);
1507
1508 SetViewportExtEx(hdcDraw,
1509 oldViewportExt.cx,
1510 oldViewportExt.cy,
1511 NULL);
1512
1513 SetViewportOrgEx(hdcDraw,
1514 oldViewportOrg.x,
1515 oldViewportOrg.y,
1516 NULL);
1517
1518 SetMapMode(hdcDraw, prevMapMode);
1519
1520 DeleteMetaFile(presMetafile);
1521 }
1522
1523 return S_OK;
1524}
1525
1526static HRESULT WINAPI DataCache_GetColorSet(
1527 IViewObject2* iface,
1528 DWORD dwDrawAspect,
1529 LONG lindex,
1530 void* pvAspect,
1531 DVTARGETDEVICE* ptd,
1532 HDC hicTargetDevice,
1533 tagLOGPALETTE** ppColorSet)
1534{
1535 FIXME("stub\n");
1536 return E_NOTIMPL;
1537}
1538
1539static HRESULT WINAPI DataCache_Freeze(
1540 IViewObject2* iface,
1541 DWORD dwDrawAspect,
1542 LONG lindex,
1543 void* pvAspect,
1544 DWORD* pdwFreeze)
1545{
1546 FIXME("stub\n");
1547 return E_NOTIMPL;
1548}
1549
1550static HRESULT WINAPI DataCache_Unfreeze(
1551 IViewObject2* iface,
1552 DWORD dwFreeze)
1553{
1554 FIXME("stub\n");
1555 return E_NOTIMPL;
1556}
1557
1558/************************************************************************
1559 * DataCache_SetAdvise (IViewObject2)
1560 *
1561 * This sets-up an advisory sink with the data cache. When the object's
1562 * view changes, This sink is called.
1563 *
1564 * See Windows documentation for more details on IViewObject2 methods.
1565 */
1566static HRESULT WINAPI DataCache_SetAdvise(
1567 IViewObject2* iface,
1568 DWORD aspects,
1569 DWORD advf,
1570 IAdviseSink* pAdvSink)
1571{
1572 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1573
1574 TRACE("(%p, %lx, %lx, %p)\n", iface, aspects, advf, pAdvSink);
1575
1576 /*
1577 * A call to This function removes the previous sink
1578 */
1579 if (This->sinkInterface != NULL)
1580 {
1581 IAdviseSink_Release(This->sinkInterface);
1582 This->sinkInterface = NULL;
1583 This->sinkAspects = 0;
1584 This->sinkAdviseFlag = 0;
1585 }
1586
1587 /*
1588 * Now, setup the new one.
1589 */
1590 if (pAdvSink!=NULL)
1591 {
1592 This->sinkInterface = pAdvSink;
1593 This->sinkAspects = aspects;
1594 This->sinkAdviseFlag = advf;
1595
1596 IAdviseSink_AddRef(This->sinkInterface);
1597 }
1598
1599 /*
1600 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1601 * sink immediately.
1602 */
1603 if (advf & ADVF_PRIMEFIRST)
1604 {
1605 DataCache_FireOnViewChange(This,
1606 DVASPECT_CONTENT,
1607 -1);
1608 }
1609
1610 return S_OK;
1611}
1612
1613/************************************************************************
1614 * DataCache_GetAdvise (IViewObject2)
1615 *
1616 * This method queries the current state of the advise sink
1617 * installed on the data cache.
1618 *
1619 * See Windows documentation for more details on IViewObject2 methods.
1620 */
1621static HRESULT WINAPI DataCache_GetAdvise(
1622 IViewObject2* iface,
1623 DWORD* pAspects,
1624 DWORD* pAdvf,
1625 IAdviseSink** ppAdvSink)
1626{
1627 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1628
1629 TRACE("(%p, %p, %p, %p)\n", iface, pAspects, pAdvf, ppAdvSink);
1630
1631 /*
1632 * Just copy all the requested values.
1633 */
1634 if (pAspects!=NULL)
1635 *pAspects = This->sinkAspects;
1636
1637 if (pAdvf!=NULL)
1638 *pAdvf = This->sinkAdviseFlag;
1639
1640 if (ppAdvSink!=NULL)
1641 {
1642 IAdviseSink_QueryInterface(This->sinkInterface,
1643 &IID_IAdviseSink,
1644 (void**)ppAdvSink);
1645 }
1646
1647 return S_OK;
1648}
1649
1650/************************************************************************
1651 * DataCache_GetExtent (IViewObject2)
1652 *
1653 * This method retrieves the "natural" size of This cached object.
1654 *
1655 * See Windows documentation for more details on IViewObject2 methods.
1656 */
1657static HRESULT WINAPI DataCache_GetExtent(
1658 IViewObject2* iface,
1659 DWORD dwDrawAspect,
1660 LONG lindex,
1661 DVTARGETDEVICE* ptd,
1662 LPSIZEL lpsizel)
1663{
1664 PresentationDataHeader presData;
1665 HRESULT hres = E_FAIL;
1666
1667 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1668
1669 TRACE("(%p, %lx, %ld, %p, %p)\n",
1670 iface, dwDrawAspect, lindex, ptd, lpsizel);
1671
1672 /*
1673 * Sanity check
1674 */
1675 if (lpsizel==NULL)
1676 return E_POINTER;
1677
1678 /*
1679 * Initialize the out parameter.
1680 */
1681 lpsizel->cx = 0;
1682 lpsizel->cy = 0;
1683
1684 /*
1685 * This flag should be set to -1.
1686 */
1687 if (lindex!=-1)
1688 FIXME("Unimplemented flag lindex = %ld\n", lindex);
1689
1690 /*
1691 * Right now, we suport only the callback from
1692 * the default handler.
1693 */
1694 if (ptd!=NULL)
1695 FIXME("Unimplemented ptd = %p\n", ptd);
1696
1697 /*
1698 * Get the presentation information from the
1699 * cache.
1700 */
1701 hres = DataCache_ReadPresentationData(This,
1702 dwDrawAspect,
1703 &presData);
1704
1705 if (SUCCEEDED(hres))
1706 {
1707 lpsizel->cx = presData.objectExtentX;
1708 lpsizel->cy = presData.objectExtentY;
1709 }
1710
1711 /*
1712 * This method returns OLE_E_BLANK when it fails.
1713 */
1714 if (FAILED(hres))
1715 hres = OLE_E_BLANK;
1716
1717 return hres;
1718}
1719
1720
1721/*********************************************************
1722 * Method implementation for the IOleCache2
1723 * part of the DataCache class.
1724 */
1725
1726/************************************************************************
1727 * DataCache_IOleCache2_QueryInterface (IUnknown)
1728 *
1729 * See Windows documentation for more details on IUnknown methods.
1730 */
1731static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
1732 IOleCache2* iface,
1733 REFIID riid,
1734 void** ppvObject)
1735{
1736 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1737
1738 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1739}
1740
1741/************************************************************************
1742 * DataCache_IOleCache2_AddRef (IUnknown)
1743 *
1744 * See Windows documentation for more details on IUnknown methods.
1745 */
1746static ULONG WINAPI DataCache_IOleCache2_AddRef(
1747 IOleCache2* iface)
1748{
1749 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1750
1751 return IUnknown_AddRef(This->outerUnknown);
1752}
1753
1754/************************************************************************
1755 * DataCache_IOleCache2_Release (IUnknown)
1756 *
1757 * See Windows documentation for more details on IUnknown methods.
1758 */
1759static ULONG WINAPI DataCache_IOleCache2_Release(
1760 IOleCache2* iface)
1761{
1762 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1763
1764 return IUnknown_Release(This->outerUnknown);
1765}
1766
1767static HRESULT WINAPI DataCache_Cache(
1768 IOleCache2* iface,
1769 FORMATETC* pformatetc,
1770 DWORD advf,
1771 DWORD* pdwConnection)
1772{
1773 FIXME("stub\n");
1774 return E_NOTIMPL;
1775}
1776
1777static HRESULT WINAPI DataCache_Uncache(
1778 IOleCache2* iface,
1779 DWORD dwConnection)
1780{
1781 FIXME("stub\n");
1782 return E_NOTIMPL;
1783}
1784
1785static HRESULT WINAPI DataCache_EnumCache(
1786 IOleCache2* iface,
1787 IEnumSTATDATA** ppenumSTATDATA)
1788{
1789 FIXME("stub\n");
1790 return E_NOTIMPL;
1791}
1792
1793static HRESULT WINAPI DataCache_InitCache(
1794 IOleCache2* iface,
1795 IDataObject* pDataObject)
1796{
1797 FIXME("stub\n");
1798 return E_NOTIMPL;
1799}
1800
1801static HRESULT WINAPI DataCache_IOleCache2_SetData(
1802 IOleCache2* iface,
1803 FORMATETC* pformatetc,
1804 STGMEDIUM* pmedium,
1805 BOOL fRelease)
1806{
1807 FIXME("stub\n");
1808 return E_NOTIMPL;
1809}
1810
1811static HRESULT WINAPI DataCache_UpdateCache(
1812 IOleCache2* iface,
1813 LPDATAOBJECT pDataObject,
1814 DWORD grfUpdf,
1815 LPVOID pReserved)
1816{
1817 FIXME("stub\n");
1818 return E_NOTIMPL;
1819}
1820
1821static HRESULT WINAPI DataCache_DiscardCache(
1822 IOleCache2* iface,
1823 DWORD dwDiscardOptions)
1824{
1825 FIXME("stub\n");
1826 return E_NOTIMPL;
1827}
1828
1829
1830/*********************************************************
1831 * Method implementation for the IOleCacheControl
1832 * part of the DataCache class.
1833 */
1834
1835/************************************************************************
1836 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1837 *
1838 * See Windows documentation for more details on IUnknown methods.
1839 */
1840static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
1841 IOleCacheControl* iface,
1842 REFIID riid,
1843 void** ppvObject)
1844{
1845 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1846
1847 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1848}
1849
1850/************************************************************************
1851 * DataCache_IOleCacheControl_AddRef (IUnknown)
1852 *
1853 * See Windows documentation for more details on IUnknown methods.
1854 */
1855static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
1856 IOleCacheControl* iface)
1857{
1858 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1859
1860 return IUnknown_AddRef(This->outerUnknown);
1861}
1862
1863/************************************************************************
1864 * DataCache_IOleCacheControl_Release (IUnknown)
1865 *
1866 * See Windows documentation for more details on IUnknown methods.
1867 */
1868static ULONG WINAPI DataCache_IOleCacheControl_Release(
1869 IOleCacheControl* iface)
1870{
1871 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1872
1873 return IUnknown_Release(This->outerUnknown);
1874}
1875
1876static HRESULT WINAPI DataCache_OnRun(
1877 IOleCacheControl* iface,
1878 LPDATAOBJECT pDataObject)
1879{
1880 FIXME("stub\n");
1881 return E_NOTIMPL;
1882}
1883
1884static HRESULT WINAPI DataCache_OnStop(
1885 IOleCacheControl* iface)
1886{
1887 FIXME("stub\n");
1888 return E_NOTIMPL;
1889}
1890
1891
Note: See TracBrowser for help on using the repository browser.