4 * Implementation of OLE IPicture and related interfaces
6 * Copyright 2000 Huw D M Davies for CodeWeavers.
11 * Only implements PICTYPE_BITMAP.
12 * Most methods are just stubs.
13 * Doesn't even expose IPersistStream, IConnectionPointContainer.
16 * NOTES (or things that msdn doesn't tell you)
18 * The width and height properties are returned in HIMETRIC units (0.01mm)
19 * IPicture::Render also uses these to select a region of the src picture.
20 * A bitmap's size is converted into these units by using the screen resolution
21 * thus an 8x8 bitmap on a 96dpi screen has a size of 212x212 (8/96 * 2540).
27 #include "wine/obj_picture.h"
28 #include "debugtools.h"
30 DEFAULT_DEBUG_CHANNEL(ole
)
32 /*************************************************************************
33 * Declaration of implementation class
36 typedef struct OLEPictureImpl
{
39 * IPicture handles IUnknown
42 ICOM_VTABLE(IPicture
) *lpvtbl1
;
43 ICOM_VTABLE(IDispatch
) *lpvtbl2
;
44 ICOM_VTABLE(IPersistStream
) *lpvtbl3
;
46 /* Object referenece count */
49 /* We own the object and must destroy it ourselves */
52 /* Picture description */
55 /* These are the pixel size of a bitmap */
59 /* And these are the size of the picture converted into HIMETRIC units */
60 OLE_XSIZE_HIMETRIC himetricWidth
;
61 OLE_YSIZE_HIMETRIC himetricHeight
;
66 * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables.
68 #define ICOM_THIS_From_IDispatch(impl, name) \
69 impl *This = (impl*)(((char*)name)-sizeof(void*));
71 #define ICOM_THIS_From_IPersistStream(impl, name) \
72 impl *This = (impl*)(((char*)name)-2*sizeof(void*));
75 * Predeclare VTables. They get initialized at the end.
77 static ICOM_VTABLE(IPicture
) OLEPictureImpl_VTable
;
78 static ICOM_VTABLE(IDispatch
) OLEPictureImpl_IDispatch_VTable
;
79 static ICOM_VTABLE(IPersistStream
) OLEPictureImpl_IPersistStream_VTable
;
81 /***********************************************************************
82 * Implementation of the OLEPictureImpl class.
85 /************************************************************************
86 * OLEPictureImpl_Construct
88 * This method will construct a new instance of the OLEPictureImpl
91 * The caller of this method must release the object when it's
94 static OLEPictureImpl
* OLEPictureImpl_Construct(LPPICTDESC pictDesc
, BOOL fOwn
)
96 OLEPictureImpl
* newObject
= 0;
97 TRACE("(%p) type = %d\n", pictDesc
, pictDesc
->picType
);
100 * Allocate space for the object.
102 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(OLEPictureImpl
));
108 * Initialize the virtual function table.
110 newObject
->lpvtbl1
= &OLEPictureImpl_VTable
;
111 newObject
->lpvtbl2
= &OLEPictureImpl_IDispatch_VTable
;
112 newObject
->lpvtbl3
= &OLEPictureImpl_IPersistStream_VTable
;
115 * Start with one reference count. The caller of this function
116 * must release the interface pointer when it is done.
120 newObject
->fOwn
= fOwn
;
122 if(pictDesc
->cbSizeofstruct
!= sizeof(PICTDESC
)) {
123 FIXME("struct size = %d\n", pictDesc
->cbSizeofstruct
);
125 memcpy(&newObject
->desc
, pictDesc
, sizeof(PICTDESC
));
127 switch(pictDesc
->picType
) {
133 TRACE("bitmap handle %08x\n", pictDesc
->u
.bmp
.hbitmap
);
134 if(GetObjectA(pictDesc
->u
.bmp
.hbitmap
, sizeof(bm
), &bm
) != sizeof(bm
)) {
135 ERR("GetObject fails\n");
139 newObject
->origWidth
= bm
.bmWidth
;
140 newObject
->origHeight
= bm
.bmHeight
;
142 /* The width and height are stored in HIMETRIC units (0.01 mm),
143 so we take our pixel width divide by pixels per inch and
144 multiply by 25.4 * 100 */
146 /* Should we use GetBitmapDimension if available? */
148 hdcRef
= CreateCompatibleDC(0);
150 newObject
->himetricWidth
= (bm
.bmWidth
* 2540) /
151 GetDeviceCaps(hdcRef
, LOGPIXELSX
);
152 newObject
->himetricHeight
= (bm
.bmHeight
* 2540) /
153 GetDeviceCaps(hdcRef
, LOGPIXELSY
);
158 case PICTYPE_METAFILE
:
159 TRACE("metafile handle %08x\n", pictDesc
->u
.wmf
.hmeta
);
160 newObject
->himetricWidth
= pictDesc
->u
.wmf
.xExt
;
161 newObject
->himetricHeight
= pictDesc
->u
.wmf
.yExt
;
165 case PICTYPE_ENHMETAFILE
:
167 FIXME("Unsupported type %d\n", pictDesc
->picType
);
168 newObject
->himetricWidth
= newObject
->himetricHeight
= 0;
172 TRACE("returning %p\n", newObject
);
176 /************************************************************************
177 * OLEPictureImpl_Destroy
179 * This method is called by the Release method when the reference
180 * count goes down to 0. It will free all resources used by
182 static void OLEPictureImpl_Destroy(OLEPictureImpl
* Obj
)
184 TRACE("(%p)\n", Obj
);
186 if(Obj
->fOwn
) { /* We need to destroy the picture */
187 switch(Obj
->desc
.picType
) {
189 DeleteObject(Obj
->desc
.u
.bmp
.hbitmap
);
191 case PICTYPE_METAFILE
:
192 DeleteMetaFile(Obj
->desc
.u
.wmf
.hmeta
);
195 DestroyIcon(Obj
->desc
.u
.icon
.hicon
);
197 case PICTYPE_ENHMETAFILE
:
198 DeleteEnhMetaFile(Obj
->desc
.u
.emf
.hemf
);
201 FIXME("Unsupported type %d - unable to delete\n", Obj
->desc
.picType
);
205 HeapFree(GetProcessHeap(), 0, Obj
);
208 static ULONG WINAPI
OLEPictureImpl_AddRef(IPicture
* iface
);
210 /************************************************************************
211 * OLEPictureImpl_QueryInterface (IUnknown)
213 * See Windows documentation for more details on IUnknown methods.
215 static HRESULT WINAPI
OLEPictureImpl_QueryInterface(
220 ICOM_THIS(OLEPictureImpl
, iface
);
221 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
224 * Perform a sanity check on the parameters.
226 if ( (This
==0) || (ppvObject
==0) )
230 * Initialize the return parameter.
235 * Compare the riid with the interface IDs implemented by this object.
237 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
239 *ppvObject
= (IPicture
*)This
;
241 else if (memcmp(&IID_IPicture
, riid
, sizeof(IID_IPicture
)) == 0)
243 *ppvObject
= (IPicture
*)This
;
245 else if (memcmp(&IID_IDispatch
, riid
, sizeof(IID_IDispatch
)) == 0)
247 *ppvObject
= (IDispatch
*)&(This
->lpvtbl2
);
249 else if (memcmp(&IID_IPictureDisp
, riid
, sizeof(IID_IPictureDisp
)) == 0)
251 *ppvObject
= (IDispatch
*)&(This
->lpvtbl2
);
253 /* else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
255 *ppvObject = (IPersistStream*)&(This->lpvtbl3);
259 * Check that we obtained an interface.
263 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid
));
264 return E_NOINTERFACE
;
268 * Query Interface always increases the reference count by one when it is
271 OLEPictureImpl_AddRef((IPicture
*)This
);
276 /************************************************************************
277 * OLEPictureImpl_AddRef (IUnknown)
279 * See Windows documentation for more details on IUnknown methods.
281 static ULONG WINAPI
OLEPictureImpl_AddRef(
284 ICOM_THIS(OLEPictureImpl
, iface
);
285 TRACE("(%p)->(ref=%ld)\n", This
, This
->ref
);
291 /************************************************************************
292 * OLEPictureImpl_Release (IUnknown)
294 * See Windows documentation for more details on IUnknown methods.
296 static ULONG WINAPI
OLEPictureImpl_Release(
299 ICOM_THIS(OLEPictureImpl
, iface
);
300 TRACE("(%p)->(ref=%ld)\n", This
, This
->ref
);
303 * Decrease the reference count on this object.
308 * If the reference count goes down to 0, perform suicide.
312 OLEPictureImpl_Destroy(This
);
321 /************************************************************************
322 * OLEPictureImpl_get_Handle
324 static HRESULT WINAPI
OLEPictureImpl_get_Handle(IPicture
*iface
,
327 ICOM_THIS(OLEPictureImpl
, iface
);
328 TRACE("(%p)->(%p)\n", This
, phandle
);
329 switch(This
->desc
.picType
) {
331 *phandle
= This
->desc
.u
.bmp
.hbitmap
;
333 case PICTYPE_METAFILE
:
334 *phandle
= This
->desc
.u
.wmf
.hmeta
;
337 *phandle
= This
->desc
.u
.icon
.hicon
;
339 case PICTYPE_ENHMETAFILE
:
340 *phandle
= This
->desc
.u
.emf
.hemf
;
343 FIXME("Unimplemented type %d\n", This
->desc
.picType
);
346 TRACE("returning handle %08x\n", *phandle
);
350 /************************************************************************
351 * OLEPictureImpl_get_hPal
353 static HRESULT WINAPI
OLEPictureImpl_get_hPal(IPicture
*iface
,
356 ICOM_THIS(OLEPictureImpl
, iface
);
357 FIXME("(%p)->(%p): stub\n", This
, phandle
);
361 /************************************************************************
362 * OLEPictureImpl_get_Type
364 static HRESULT WINAPI
OLEPictureImpl_get_Type(IPicture
*iface
,
367 ICOM_THIS(OLEPictureImpl
, iface
);
368 TRACE("(%p)->(%p): type is %d\n", This
, ptype
, This
->desc
.picType
);
369 *ptype
= This
->desc
.picType
;
373 /************************************************************************
374 * OLEPictureImpl_get_Width
376 static HRESULT WINAPI
OLEPictureImpl_get_Width(IPicture
*iface
,
377 OLE_XSIZE_HIMETRIC
*pwidth
)
379 ICOM_THIS(OLEPictureImpl
, iface
);
380 TRACE("(%p)->(%p): width is %ld\n", This
, pwidth
, This
->himetricWidth
);
381 *pwidth
= This
->himetricWidth
;
385 /************************************************************************
386 * OLEPictureImpl_get_Height
388 static HRESULT WINAPI
OLEPictureImpl_get_Height(IPicture
*iface
,
389 OLE_YSIZE_HIMETRIC
*pheight
)
391 ICOM_THIS(OLEPictureImpl
, iface
);
392 TRACE("(%p)->(%p): height is %ld\n", This
, pheight
, This
->himetricHeight
);
393 *pheight
= This
->himetricHeight
;
397 /************************************************************************
398 * OLEPictureImpl_Render
400 static HRESULT WINAPI
OLEPictureImpl_Render(IPicture
*iface
, HDC hdc
,
401 long x
, long y
, long cx
, long cy
,
402 OLE_XPOS_HIMETRIC xSrc
,
403 OLE_YPOS_HIMETRIC ySrc
,
404 OLE_XSIZE_HIMETRIC cxSrc
,
405 OLE_YSIZE_HIMETRIC cySrc
,
408 ICOM_THIS(OLEPictureImpl
, iface
);
409 TRACE("(%p)->(%08x, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n",
410 This
, hdc
, x
, y
, cx
, cy
, xSrc
, ySrc
, cxSrc
, cySrc
, prcWBounds
);
412 TRACE("prcWBounds (%d,%d) - (%d,%d)\n", prcWBounds
->left
, prcWBounds
->top
,
413 prcWBounds
->right
, prcWBounds
->bottom
);
415 switch(This
->desc
.picType
) {
421 /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
422 NB y-axis gets flipped */
424 hdcBmp
= CreateCompatibleDC(0);
425 SetMapMode(hdcBmp
, MM_ANISOTROPIC
);
426 SetWindowOrgEx(hdcBmp
, 0, 0, NULL
);
427 SetWindowExtEx(hdcBmp
, This
->himetricWidth
, This
->himetricHeight
, NULL
);
428 SetViewportOrgEx(hdcBmp
, 0, This
->origHeight
, NULL
);
429 SetViewportExtEx(hdcBmp
, This
->origWidth
, -This
->origHeight
, NULL
);
431 hbmpOld
= SelectObject(hdcBmp
, This
->desc
.u
.bmp
.hbitmap
);
433 StretchBlt(hdc
, x
, y
, cx
, cy
, hdcBmp
, xSrc
, ySrc
, cxSrc
, cySrc
, SRCCOPY
);
435 SelectObject(hdcBmp
, hbmpOld
);
440 case PICTYPE_METAFILE
:
442 case PICTYPE_ENHMETAFILE
:
444 FIXME("type %d not implemented\n", This
->desc
.picType
);
451 /************************************************************************
452 * OLEPictureImpl_set_hPal
454 static HRESULT WINAPI
OLEPictureImpl_set_hPal(IPicture
*iface
,
457 ICOM_THIS(OLEPictureImpl
, iface
);
458 FIXME("(%p)->(%08x): stub\n", This
, hpal
);
462 /************************************************************************
463 * OLEPictureImpl_get_CurDC
465 static HRESULT WINAPI
OLEPictureImpl_get_CurDC(IPicture
*iface
,
468 ICOM_THIS(OLEPictureImpl
, iface
);
469 FIXME("(%p)->(%p): stub\n", This
, phdc
);
473 /************************************************************************
474 * OLEPictureImpl_SelectPicture
476 static HRESULT WINAPI
OLEPictureImpl_SelectPicture(IPicture
*iface
,
479 OLE_HANDLE
*phbmpOut
)
481 ICOM_THIS(OLEPictureImpl
, iface
);
482 FIXME("(%p)->(%08x, %p, %p): stub\n", This
, hdcIn
, phdcOut
, phbmpOut
);
486 /************************************************************************
487 * OLEPictureImpl_get_KeepOriginalFormat
489 static HRESULT WINAPI
OLEPictureImpl_get_KeepOriginalFormat(IPicture
*iface
,
492 ICOM_THIS(OLEPictureImpl
, iface
);
493 FIXME("(%p)->(%p): stub\n", This
, pfKeep
);
497 /************************************************************************
498 * OLEPictureImpl_put_KeepOriginalFormat
500 static HRESULT WINAPI
OLEPictureImpl_put_KeepOriginalFormat(IPicture
*iface
,
503 ICOM_THIS(OLEPictureImpl
, iface
);
504 FIXME("(%p)->(%d): stub\n", This
, keep
);
508 /************************************************************************
509 * OLEPictureImpl_PictureChanged
511 static HRESULT WINAPI
OLEPictureImpl_PictureChanged(IPicture
*iface
)
513 ICOM_THIS(OLEPictureImpl
, iface
);
514 FIXME("(%p)->(): stub\n", This
);
518 /************************************************************************
519 * OLEPictureImpl_SaveAsFile
521 static HRESULT WINAPI
OLEPictureImpl_SaveAsFile(IPicture
*iface
,
526 ICOM_THIS(OLEPictureImpl
, iface
);
527 FIXME("(%p)->(%p, %d, %p): stub\n", This
, pstream
, SaveMemCopy
, pcbSize
);
531 /************************************************************************
532 * OLEPictureImpl_get_Attributes
534 static HRESULT WINAPI
OLEPictureImpl_get_Attributes(IPicture
*iface
,
537 ICOM_THIS(OLEPictureImpl
, iface
);
538 FIXME("(%p)->(%p): stub\n", This
, pdwAttr
);
544 /************************************************************************
547 /************************************************************************
548 * OLEPictureImpl_IDispatch_QueryInterface (IUnknown)
550 * See Windows documentation for more details on IUnknown methods.
552 static HRESULT WINAPI
OLEPictureImpl_IDispatch_QueryInterface(
557 ICOM_THIS_From_IDispatch(IPicture
, iface
);
559 return IPicture_QueryInterface(This
, riid
, ppvoid
);
562 /************************************************************************
563 * OLEPictureImpl_IDispatch_AddRef (IUnknown)
565 * See Windows documentation for more details on IUnknown methods.
567 static ULONG WINAPI
OLEPictureImpl_IDispatch_AddRef(
570 ICOM_THIS_From_IDispatch(IPicture
, iface
);
572 return IPicture_AddRef(This
);
575 /************************************************************************
576 * OLEPictureImpl_IDispatch_Release (IUnknown)
578 * See Windows documentation for more details on IUnknown methods.
580 static ULONG WINAPI
OLEPictureImpl_IDispatch_Release(
583 ICOM_THIS_From_IDispatch(IPicture
, iface
);
585 return IPicture_Release(This
);
588 /************************************************************************
589 * OLEPictureImpl_GetTypeInfoCount (IDispatch)
591 * See Windows documentation for more details on IDispatch methods.
593 static HRESULT WINAPI
OLEPictureImpl_GetTypeInfoCount(
595 unsigned int* pctinfo
)
602 /************************************************************************
603 * OLEPictureImpl_GetTypeInfo (IDispatch)
605 * See Windows documentation for more details on IDispatch methods.
607 static HRESULT WINAPI
OLEPictureImpl_GetTypeInfo(
618 /************************************************************************
619 * OLEPictureImpl_GetIDsOfNames (IDispatch)
621 * See Windows documentation for more details on IDispatch methods.
623 static HRESULT WINAPI
OLEPictureImpl_GetIDsOfNames(
636 /************************************************************************
637 * OLEPictureImpl_Invoke (IDispatch)
639 * See Windows documentation for more details on IDispatch methods.
641 static HRESULT WINAPI
OLEPictureImpl_Invoke(
647 DISPPARAMS
* pDispParams
,
649 EXCEPINFO
* pExepInfo
,
658 static ICOM_VTABLE(IPicture
) OLEPictureImpl_VTable
=
660 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
661 OLEPictureImpl_QueryInterface
,
662 OLEPictureImpl_AddRef
,
663 OLEPictureImpl_Release
,
664 OLEPictureImpl_get_Handle
,
665 OLEPictureImpl_get_hPal
,
666 OLEPictureImpl_get_Type
,
667 OLEPictureImpl_get_Width
,
668 OLEPictureImpl_get_Height
,
669 OLEPictureImpl_Render
,
670 OLEPictureImpl_set_hPal
,
671 OLEPictureImpl_get_CurDC
,
672 OLEPictureImpl_SelectPicture
,
673 OLEPictureImpl_get_KeepOriginalFormat
,
674 OLEPictureImpl_put_KeepOriginalFormat
,
675 OLEPictureImpl_PictureChanged
,
676 OLEPictureImpl_SaveAsFile
,
677 OLEPictureImpl_get_Attributes
680 static ICOM_VTABLE(IDispatch
) OLEPictureImpl_IDispatch_VTable
=
682 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
683 OLEPictureImpl_IDispatch_QueryInterface
,
684 OLEPictureImpl_IDispatch_AddRef
,
685 OLEPictureImpl_IDispatch_Release
,
686 OLEPictureImpl_GetTypeInfoCount
,
687 OLEPictureImpl_GetTypeInfo
,
688 OLEPictureImpl_GetIDsOfNames
,
689 OLEPictureImpl_Invoke
692 /***********************************************************************
693 * OleCreatePictureIndirect
695 HRESULT WINAPI
OleCreatePictureIndirect(LPPICTDESC lpPictDesc
, REFIID riid
,
696 BOOL fOwn
, LPVOID
*ppvObj
)
698 OLEPictureImpl
* newPict
= NULL
;
701 TRACE("(%p,%p,%d,%p)\n", lpPictDesc
, riid
, fOwn
, ppvObj
);
712 * Try to construct a new instance of the class.
714 newPict
= OLEPictureImpl_Construct(lpPictDesc
, fOwn
);
717 return E_OUTOFMEMORY
;
720 * Make sure it supports the interface required by the caller.
722 hr
= IPicture_QueryInterface((IPicture
*)newPict
, riid
, ppvObj
);
725 * Release the reference obtained in the constructor. If
726 * the QueryInterface was unsuccessful, it will free the class.
728 IPicture_Release((IPicture
*)newPict
);
734 /***********************************************************************
737 HRESULT WINAPI
OleLoadPicture( LPSTREAM lpstream
, LONG lSize
, BOOL fRunmode
,
738 REFIID reed
, LPVOID
*ppvObj
)
740 FIXME("(%p,%ld,%d,%p,%p), not implemented\n",
741 lpstream
, lSize
, fRunmode
, reed
, ppvObj
);