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).
32 #include "wine/obj_picture.h"
33 #include "debugtools.h"
35 DEFAULT_DEBUG_CHANNEL(ole
);
37 /*************************************************************************
38 * Declaration of implementation class
41 typedef struct OLEPictureImpl
{
44 * IPicture handles IUnknown
47 ICOM_VTABLE(IPicture
) *lpvtbl1
;
48 ICOM_VTABLE(IDispatch
) *lpvtbl2
;
49 ICOM_VTABLE(IPersistStream
) *lpvtbl3
;
51 /* Object referenece count */
54 /* We own the object and must destroy it ourselves */
57 /* Picture description */
60 /* These are the pixel size of a bitmap */
64 /* And these are the size of the picture converted into HIMETRIC units */
65 OLE_XSIZE_HIMETRIC himetricWidth
;
66 OLE_YSIZE_HIMETRIC himetricHeight
;
71 * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables.
73 #define ICOM_THIS_From_IDispatch(impl, name) \
74 impl *This = (impl*)(((char*)name)-sizeof(void*));
76 #define ICOM_THIS_From_IPersistStream(impl, name) \
77 impl *This = (impl*)(((char*)name)-2*sizeof(void*));
80 * Predeclare VTables. They get initialized at the end.
82 static ICOM_VTABLE(IPicture
) OLEPictureImpl_VTable
;
83 static ICOM_VTABLE(IDispatch
) OLEPictureImpl_IDispatch_VTable
;
84 static ICOM_VTABLE(IPersistStream
) OLEPictureImpl_IPersistStream_VTable
;
86 /***********************************************************************
87 * Implementation of the OLEPictureImpl class.
90 /************************************************************************
91 * OLEPictureImpl_Construct
93 * This method will construct a new instance of the OLEPictureImpl
96 * The caller of this method must release the object when it's
99 static OLEPictureImpl
* OLEPictureImpl_Construct(LPPICTDESC pictDesc
, BOOL fOwn
)
101 OLEPictureImpl
* newObject
= 0;
102 TRACE("(%p) type = %d\n", pictDesc
, pictDesc
->picType
);
105 * Allocate space for the object.
107 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(OLEPictureImpl
));
113 * Initialize the virtual function table.
115 newObject
->lpvtbl1
= &OLEPictureImpl_VTable
;
116 newObject
->lpvtbl2
= &OLEPictureImpl_IDispatch_VTable
;
117 newObject
->lpvtbl3
= &OLEPictureImpl_IPersistStream_VTable
;
120 * Start with one reference count. The caller of this function
121 * must release the interface pointer when it is done.
125 newObject
->fOwn
= fOwn
;
127 if(pictDesc
->cbSizeofstruct
!= sizeof(PICTDESC
)) {
128 FIXME("struct size = %d\n", pictDesc
->cbSizeofstruct
);
130 memcpy(&newObject
->desc
, pictDesc
, sizeof(PICTDESC
));
132 switch(pictDesc
->picType
) {
138 TRACE("bitmap handle %08x\n", pictDesc
->u
.bmp
.hbitmap
);
139 if(GetObjectA(pictDesc
->u
.bmp
.hbitmap
, sizeof(bm
), &bm
) != sizeof(bm
)) {
140 ERR("GetObject fails\n");
144 newObject
->origWidth
= bm
.bmWidth
;
145 newObject
->origHeight
= bm
.bmHeight
;
147 /* The width and height are stored in HIMETRIC units (0.01 mm),
148 so we take our pixel width divide by pixels per inch and
149 multiply by 25.4 * 100 */
151 /* Should we use GetBitmapDimension if available? */
153 hdcRef
= CreateCompatibleDC(0);
155 newObject
->himetricWidth
= (bm
.bmWidth
* 2540) /
156 GetDeviceCaps(hdcRef
, LOGPIXELSX
);
157 newObject
->himetricHeight
= (bm
.bmHeight
* 2540) /
158 GetDeviceCaps(hdcRef
, LOGPIXELSY
);
163 case PICTYPE_METAFILE
:
164 TRACE("metafile handle %08x\n", pictDesc
->u
.wmf
.hmeta
);
165 newObject
->himetricWidth
= pictDesc
->u
.wmf
.xExt
;
166 newObject
->himetricHeight
= pictDesc
->u
.wmf
.yExt
;
170 case PICTYPE_ENHMETAFILE
:
172 FIXME("Unsupported type %d\n", pictDesc
->picType
);
173 newObject
->himetricWidth
= newObject
->himetricHeight
= 0;
177 TRACE("returning %p\n", newObject
);
181 /************************************************************************
182 * OLEPictureImpl_Destroy
184 * This method is called by the Release method when the reference
185 * count goes down to 0. It will free all resources used by
187 static void OLEPictureImpl_Destroy(OLEPictureImpl
* Obj
)
189 TRACE("(%p)\n", Obj
);
191 if(Obj
->fOwn
) { /* We need to destroy the picture */
192 switch(Obj
->desc
.picType
) {
194 DeleteObject(Obj
->desc
.u
.bmp
.hbitmap
);
196 case PICTYPE_METAFILE
:
197 DeleteMetaFile(Obj
->desc
.u
.wmf
.hmeta
);
200 DestroyIcon(Obj
->desc
.u
.icon
.hicon
);
202 case PICTYPE_ENHMETAFILE
:
203 DeleteEnhMetaFile(Obj
->desc
.u
.emf
.hemf
);
206 FIXME("Unsupported type %d - unable to delete\n", Obj
->desc
.picType
);
210 HeapFree(GetProcessHeap(), 0, Obj
);
213 static ULONG WINAPI
OLEPictureImpl_AddRef(IPicture
* iface
);
215 /************************************************************************
216 * OLEPictureImpl_QueryInterface (IUnknown)
218 * See Windows documentation for more details on IUnknown methods.
220 static HRESULT WINAPI
OLEPictureImpl_QueryInterface(
225 ICOM_THIS(OLEPictureImpl
, iface
);
226 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
229 * Perform a sanity check on the parameters.
231 if ( (This
==0) || (ppvObject
==0) )
235 * Initialize the return parameter.
240 * Compare the riid with the interface IDs implemented by this object.
242 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
244 *ppvObject
= (IPicture
*)This
;
246 else if (memcmp(&IID_IPicture
, riid
, sizeof(IID_IPicture
)) == 0)
248 *ppvObject
= (IPicture
*)This
;
250 else if (memcmp(&IID_IDispatch
, riid
, sizeof(IID_IDispatch
)) == 0)
252 *ppvObject
= (IDispatch
*)&(This
->lpvtbl2
);
254 else if (memcmp(&IID_IPictureDisp
, riid
, sizeof(IID_IPictureDisp
)) == 0)
256 *ppvObject
= (IDispatch
*)&(This
->lpvtbl2
);
258 /* else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
260 *ppvObject = (IPersistStream*)&(This->lpvtbl3);
264 * Check that we obtained an interface.
268 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid
));
269 return E_NOINTERFACE
;
273 * Query Interface always increases the reference count by one when it is
276 OLEPictureImpl_AddRef((IPicture
*)This
);
281 /************************************************************************
282 * OLEPictureImpl_AddRef (IUnknown)
284 * See Windows documentation for more details on IUnknown methods.
286 static ULONG WINAPI
OLEPictureImpl_AddRef(
289 ICOM_THIS(OLEPictureImpl
, iface
);
290 TRACE("(%p)->(ref=%ld)\n", This
, This
->ref
);
296 /************************************************************************
297 * OLEPictureImpl_Release (IUnknown)
299 * See Windows documentation for more details on IUnknown methods.
301 static ULONG WINAPI
OLEPictureImpl_Release(
304 ICOM_THIS(OLEPictureImpl
, iface
);
305 TRACE("(%p)->(ref=%ld)\n", This
, This
->ref
);
308 * Decrease the reference count on this object.
313 * If the reference count goes down to 0, perform suicide.
317 OLEPictureImpl_Destroy(This
);
326 /************************************************************************
327 * OLEPictureImpl_get_Handle
329 static HRESULT WINAPI
OLEPictureImpl_get_Handle(IPicture
*iface
,
332 ICOM_THIS(OLEPictureImpl
, iface
);
333 TRACE("(%p)->(%p)\n", This
, phandle
);
334 switch(This
->desc
.picType
) {
336 *phandle
= This
->desc
.u
.bmp
.hbitmap
;
338 case PICTYPE_METAFILE
:
339 *phandle
= This
->desc
.u
.wmf
.hmeta
;
342 *phandle
= This
->desc
.u
.icon
.hicon
;
344 case PICTYPE_ENHMETAFILE
:
345 *phandle
= This
->desc
.u
.emf
.hemf
;
348 FIXME("Unimplemented type %d\n", This
->desc
.picType
);
351 TRACE("returning handle %08x\n", *phandle
);
355 /************************************************************************
356 * OLEPictureImpl_get_hPal
358 static HRESULT WINAPI
OLEPictureImpl_get_hPal(IPicture
*iface
,
361 ICOM_THIS(OLEPictureImpl
, iface
);
362 FIXME("(%p)->(%p): stub\n", This
, phandle
);
366 /************************************************************************
367 * OLEPictureImpl_get_Type
369 static HRESULT WINAPI
OLEPictureImpl_get_Type(IPicture
*iface
,
372 ICOM_THIS(OLEPictureImpl
, iface
);
373 TRACE("(%p)->(%p): type is %d\n", This
, ptype
, This
->desc
.picType
);
374 *ptype
= This
->desc
.picType
;
378 /************************************************************************
379 * OLEPictureImpl_get_Width
381 static HRESULT WINAPI
OLEPictureImpl_get_Width(IPicture
*iface
,
382 OLE_XSIZE_HIMETRIC
*pwidth
)
384 ICOM_THIS(OLEPictureImpl
, iface
);
385 TRACE("(%p)->(%p): width is %ld\n", This
, pwidth
, This
->himetricWidth
);
386 *pwidth
= This
->himetricWidth
;
390 /************************************************************************
391 * OLEPictureImpl_get_Height
393 static HRESULT WINAPI
OLEPictureImpl_get_Height(IPicture
*iface
,
394 OLE_YSIZE_HIMETRIC
*pheight
)
396 ICOM_THIS(OLEPictureImpl
, iface
);
397 TRACE("(%p)->(%p): height is %ld\n", This
, pheight
, This
->himetricHeight
);
398 *pheight
= This
->himetricHeight
;
402 /************************************************************************
403 * OLEPictureImpl_Render
405 static HRESULT WINAPI
OLEPictureImpl_Render(IPicture
*iface
, HDC hdc
,
406 long x
, long y
, long cx
, long cy
,
407 OLE_XPOS_HIMETRIC xSrc
,
408 OLE_YPOS_HIMETRIC ySrc
,
409 OLE_XSIZE_HIMETRIC cxSrc
,
410 OLE_YSIZE_HIMETRIC cySrc
,
413 ICOM_THIS(OLEPictureImpl
, iface
);
414 TRACE("(%p)->(%08x, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n",
415 This
, hdc
, x
, y
, cx
, cy
, xSrc
, ySrc
, cxSrc
, cySrc
, prcWBounds
);
417 TRACE("prcWBounds (%d,%d) - (%d,%d)\n", prcWBounds
->left
, prcWBounds
->top
,
418 prcWBounds
->right
, prcWBounds
->bottom
);
420 switch(This
->desc
.picType
) {
426 /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
427 NB y-axis gets flipped */
429 hdcBmp
= CreateCompatibleDC(0);
430 SetMapMode(hdcBmp
, MM_ANISOTROPIC
);
431 SetWindowOrgEx(hdcBmp
, 0, 0, NULL
);
432 SetWindowExtEx(hdcBmp
, This
->himetricWidth
, This
->himetricHeight
, NULL
);
433 SetViewportOrgEx(hdcBmp
, 0, This
->origHeight
, NULL
);
434 SetViewportExtEx(hdcBmp
, This
->origWidth
, -This
->origHeight
, NULL
);
436 hbmpOld
= SelectObject(hdcBmp
, This
->desc
.u
.bmp
.hbitmap
);
438 StretchBlt(hdc
, x
, y
, cx
, cy
, hdcBmp
, xSrc
, ySrc
, cxSrc
, cySrc
, SRCCOPY
);
440 SelectObject(hdcBmp
, hbmpOld
);
445 case PICTYPE_METAFILE
:
447 case PICTYPE_ENHMETAFILE
:
449 FIXME("type %d not implemented\n", This
->desc
.picType
);
456 /************************************************************************
457 * OLEPictureImpl_set_hPal
459 static HRESULT WINAPI
OLEPictureImpl_set_hPal(IPicture
*iface
,
462 ICOM_THIS(OLEPictureImpl
, iface
);
463 FIXME("(%p)->(%08x): stub\n", This
, hpal
);
467 /************************************************************************
468 * OLEPictureImpl_get_CurDC
470 static HRESULT WINAPI
OLEPictureImpl_get_CurDC(IPicture
*iface
,
473 ICOM_THIS(OLEPictureImpl
, iface
);
474 FIXME("(%p)->(%p): stub\n", This
, phdc
);
478 /************************************************************************
479 * OLEPictureImpl_SelectPicture
481 static HRESULT WINAPI
OLEPictureImpl_SelectPicture(IPicture
*iface
,
484 OLE_HANDLE
*phbmpOut
)
486 ICOM_THIS(OLEPictureImpl
, iface
);
487 FIXME("(%p)->(%08x, %p, %p): stub\n", This
, hdcIn
, phdcOut
, phbmpOut
);
491 /************************************************************************
492 * OLEPictureImpl_get_KeepOriginalFormat
494 static HRESULT WINAPI
OLEPictureImpl_get_KeepOriginalFormat(IPicture
*iface
,
497 ICOM_THIS(OLEPictureImpl
, iface
);
498 FIXME("(%p)->(%p): stub\n", This
, pfKeep
);
502 /************************************************************************
503 * OLEPictureImpl_put_KeepOriginalFormat
505 static HRESULT WINAPI
OLEPictureImpl_put_KeepOriginalFormat(IPicture
*iface
,
508 ICOM_THIS(OLEPictureImpl
, iface
);
509 FIXME("(%p)->(%d): stub\n", This
, keep
);
513 /************************************************************************
514 * OLEPictureImpl_PictureChanged
516 static HRESULT WINAPI
OLEPictureImpl_PictureChanged(IPicture
*iface
)
518 ICOM_THIS(OLEPictureImpl
, iface
);
519 FIXME("(%p)->(): stub\n", This
);
523 /************************************************************************
524 * OLEPictureImpl_SaveAsFile
526 static HRESULT WINAPI
OLEPictureImpl_SaveAsFile(IPicture
*iface
,
531 ICOM_THIS(OLEPictureImpl
, iface
);
532 FIXME("(%p)->(%p, %d, %p): stub\n", This
, pstream
, SaveMemCopy
, pcbSize
);
536 /************************************************************************
537 * OLEPictureImpl_get_Attributes
539 static HRESULT WINAPI
OLEPictureImpl_get_Attributes(IPicture
*iface
,
542 ICOM_THIS(OLEPictureImpl
, iface
);
543 FIXME("(%p)->(%p): stub\n", This
, pdwAttr
);
549 /************************************************************************
552 /************************************************************************
553 * OLEPictureImpl_IDispatch_QueryInterface (IUnknown)
555 * See Windows documentation for more details on IUnknown methods.
557 static HRESULT WINAPI
OLEPictureImpl_IDispatch_QueryInterface(
562 ICOM_THIS_From_IDispatch(IPicture
, iface
);
564 return IPicture_QueryInterface(This
, riid
, ppvoid
);
567 /************************************************************************
568 * OLEPictureImpl_IDispatch_AddRef (IUnknown)
570 * See Windows documentation for more details on IUnknown methods.
572 static ULONG WINAPI
OLEPictureImpl_IDispatch_AddRef(
575 ICOM_THIS_From_IDispatch(IPicture
, iface
);
577 return IPicture_AddRef(This
);
580 /************************************************************************
581 * OLEPictureImpl_IDispatch_Release (IUnknown)
583 * See Windows documentation for more details on IUnknown methods.
585 static ULONG WINAPI
OLEPictureImpl_IDispatch_Release(
588 ICOM_THIS_From_IDispatch(IPicture
, iface
);
590 return IPicture_Release(This
);
593 /************************************************************************
594 * OLEPictureImpl_GetTypeInfoCount (IDispatch)
596 * See Windows documentation for more details on IDispatch methods.
598 static HRESULT WINAPI
OLEPictureImpl_GetTypeInfoCount(
600 unsigned int* pctinfo
)
607 /************************************************************************
608 * OLEPictureImpl_GetTypeInfo (IDispatch)
610 * See Windows documentation for more details on IDispatch methods.
612 static HRESULT WINAPI
OLEPictureImpl_GetTypeInfo(
623 /************************************************************************
624 * OLEPictureImpl_GetIDsOfNames (IDispatch)
626 * See Windows documentation for more details on IDispatch methods.
628 static HRESULT WINAPI
OLEPictureImpl_GetIDsOfNames(
641 /************************************************************************
642 * OLEPictureImpl_Invoke (IDispatch)
644 * See Windows documentation for more details on IDispatch methods.
646 static HRESULT WINAPI
OLEPictureImpl_Invoke(
652 DISPPARAMS
* pDispParams
,
654 EXCEPINFO
* pExepInfo
,
663 static ICOM_VTABLE(IPicture
) OLEPictureImpl_VTable
=
665 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
666 OLEPictureImpl_QueryInterface
,
667 OLEPictureImpl_AddRef
,
668 OLEPictureImpl_Release
,
669 OLEPictureImpl_get_Handle
,
670 OLEPictureImpl_get_hPal
,
671 OLEPictureImpl_get_Type
,
672 OLEPictureImpl_get_Width
,
673 OLEPictureImpl_get_Height
,
674 OLEPictureImpl_Render
,
675 OLEPictureImpl_set_hPal
,
676 OLEPictureImpl_get_CurDC
,
677 OLEPictureImpl_SelectPicture
,
678 OLEPictureImpl_get_KeepOriginalFormat
,
679 OLEPictureImpl_put_KeepOriginalFormat
,
680 OLEPictureImpl_PictureChanged
,
681 OLEPictureImpl_SaveAsFile
,
682 OLEPictureImpl_get_Attributes
685 static ICOM_VTABLE(IDispatch
) OLEPictureImpl_IDispatch_VTable
=
687 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
688 OLEPictureImpl_IDispatch_QueryInterface
,
689 OLEPictureImpl_IDispatch_AddRef
,
690 OLEPictureImpl_IDispatch_Release
,
691 OLEPictureImpl_GetTypeInfoCount
,
692 OLEPictureImpl_GetTypeInfo
,
693 OLEPictureImpl_GetIDsOfNames
,
694 OLEPictureImpl_Invoke
697 /***********************************************************************
698 * OleCreatePictureIndirect
700 HRESULT WINAPI
OleCreatePictureIndirect(LPPICTDESC lpPictDesc
, REFIID riid
,
701 BOOL fOwn
, LPVOID
*ppvObj
)
703 OLEPictureImpl
* newPict
= NULL
;
706 TRACE("(%p,%p,%d,%p)\n", lpPictDesc
, riid
, fOwn
, ppvObj
);
717 * Try to construct a new instance of the class.
719 newPict
= OLEPictureImpl_Construct(lpPictDesc
, fOwn
);
722 return E_OUTOFMEMORY
;
725 * Make sure it supports the interface required by the caller.
727 hr
= IPicture_QueryInterface((IPicture
*)newPict
, riid
, ppvObj
);
730 * Release the reference obtained in the constructor. If
731 * the QueryInterface was unsuccessful, it will free the class.
733 IPicture_Release((IPicture
*)newPict
);
739 /***********************************************************************
742 HRESULT WINAPI
OleLoadPicture( LPSTREAM lpstream
, LONG lSize
, BOOL fRunmode
,
743 REFIID reed
, LPVOID
*ppvObj
)
745 FIXME("(%p,%ld,%d,%p,%p), not implemented\n",
746 lpstream
, lSize
, fRunmode
, reed
, ppvObj
);
750 /***********************************************************************
753 HRESULT WINAPI
OleLoadPictureEx( LPSTREAM lpstream
, LONG lSize
, BOOL fRunmode
,
754 REFIID reed
, DWORD xsiz
, DWORD ysiz
, DWORD flags
, LPVOID
*ppvObj
)
756 FIXME("(%p,%ld,%d,%p,%lx,%lx,%lx,%p), not implemented\n",
757 lpstream
, lSize
, fRunmode
, reed
, xsiz
, ysiz
, flags
, ppvObj
);