4 * Implementation of OLE IPicture and related interfaces
6 * Copyright 2000 Huw D M Davies for CodeWeavers.
7 * Copyright 2001 Marcus Meissner
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * Support PICTYPE_BITMAP and PICTYPE_ICON, altough only bitmaps very well..
26 * Lots of methods are just stubs.
29 * NOTES (or things that msdn doesn't tell you)
31 * The width and height properties are returned in HIMETRIC units (0.01mm)
32 * IPicture::Render also uses these to select a region of the src picture.
33 * A bitmap's size is converted into these units by using the screen resolution
34 * thus an 8x8 bitmap on a 96dpi screen has a size of 212x212 (8/96 * 2540).
39 #include "wine/port.h"
48 /* Must be before wine includes, the header has things conflicting with
53 #ifndef SONAME_LIBUNGIF
54 #define SONAME_LIBUNGIF "libungif.so"
58 #define NONAMELESSUNION
59 #define NONAMELESSSTRUCT
69 #include "wine/debug.h"
71 #include "wine/wingdi16.h"
72 #include "cursoricon.h"
75 /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
77 #define UINT8 JPEG_UINT8
78 #define UINT16 JPEG_UINT16
82 #ifndef SONAME_LIBJPEG
83 #define SONAME_LIBJPEG "libjpeg.so"
87 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
89 /*************************************************************************
90 * Declaration of implementation class
93 typedef struct OLEPictureImpl
{
96 * IPicture handles IUnknown
99 IPictureVtbl
*lpvtbl1
;
100 IDispatchVtbl
*lpvtbl2
;
101 IPersistStreamVtbl
*lpvtbl3
;
102 IConnectionPointContainerVtbl
*lpvtbl4
;
104 /* Object referenece count */
107 /* We own the object and must destroy it ourselves */
110 /* Picture description */
113 /* These are the pixel size of a bitmap */
117 /* And these are the size of the picture converted into HIMETRIC units */
118 OLE_XSIZE_HIMETRIC himetricWidth
;
119 OLE_YSIZE_HIMETRIC himetricHeight
;
121 IConnectionPoint
*pCP
;
126 /* Bitmap transparency mask */
136 * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables.
138 #define ICOM_THIS_From_IDispatch(impl, name) \
139 impl *This = (impl*)(((char*)name)-sizeof(void*));
140 #define ICOM_THIS_From_IPersistStream(impl, name) \
141 impl *This = (impl*)(((char*)name)-2*sizeof(void*));
142 #define ICOM_THIS_From_IConnectionPointContainer(impl, name) \
143 impl *This = (impl*)(((char*)name)-3*sizeof(void*));
146 * Predeclare VTables. They get initialized at the end.
148 static IPictureVtbl OLEPictureImpl_VTable
;
149 static IDispatchVtbl OLEPictureImpl_IDispatch_VTable
;
150 static IPersistStreamVtbl OLEPictureImpl_IPersistStream_VTable
;
151 static IConnectionPointContainerVtbl OLEPictureImpl_IConnectionPointContainer_VTable
;
153 /***********************************************************************
154 * Implementation of the OLEPictureImpl class.
157 static void OLEPictureImpl_SetBitmap(OLEPictureImpl
*This
) {
161 TRACE("bitmap handle %p\n", This
->desc
.u
.bmp
.hbitmap
);
162 if(GetObjectA(This
->desc
.u
.bmp
.hbitmap
, sizeof(bm
), &bm
) != sizeof(bm
)) {
163 ERR("GetObject fails\n");
166 This
->origWidth
= bm
.bmWidth
;
167 This
->origHeight
= bm
.bmHeight
;
168 /* The width and height are stored in HIMETRIC units (0.01 mm),
169 so we take our pixel width divide by pixels per inch and
170 multiply by 25.4 * 100 */
171 /* Should we use GetBitmapDimension if available? */
172 hdcRef
= CreateCompatibleDC(0);
173 This
->himetricWidth
=(bm
.bmWidth
*2540)/GetDeviceCaps(hdcRef
, LOGPIXELSX
);
174 This
->himetricHeight
=(bm
.bmHeight
*2540)/GetDeviceCaps(hdcRef
, LOGPIXELSY
);
178 /************************************************************************
179 * OLEPictureImpl_Construct
181 * This method will construct a new instance of the OLEPictureImpl
184 * The caller of this method must release the object when it's
187 static OLEPictureImpl
* OLEPictureImpl_Construct(LPPICTDESC pictDesc
, BOOL fOwn
)
189 OLEPictureImpl
* newObject
= 0;
192 TRACE("(%p) type = %d\n", pictDesc
, pictDesc
->picType
);
195 * Allocate space for the object.
197 newObject
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(OLEPictureImpl
));
203 * Initialize the virtual function table.
205 newObject
->lpvtbl1
= &OLEPictureImpl_VTable
;
206 newObject
->lpvtbl2
= &OLEPictureImpl_IDispatch_VTable
;
207 newObject
->lpvtbl3
= &OLEPictureImpl_IPersistStream_VTable
;
208 newObject
->lpvtbl4
= &OLEPictureImpl_IConnectionPointContainer_VTable
;
210 CreateConnectionPoint((IUnknown
*)newObject
,&IID_IPropertyNotifySink
,&newObject
->pCP
);
213 * Start with one reference count. The caller of this function
214 * must release the interface pointer when it is done.
217 newObject
->hDCCur
= 0;
219 newObject
->fOwn
= fOwn
;
221 /* dunno about original value */
222 newObject
->keepOrigFormat
= TRUE
;
224 newObject
->hbmMask
= NULL
;
227 if(pictDesc
->cbSizeofstruct
!= sizeof(PICTDESC
)) {
228 FIXME("struct size = %d\n", pictDesc
->cbSizeofstruct
);
230 memcpy(&newObject
->desc
, pictDesc
, sizeof(PICTDESC
));
233 switch(pictDesc
->picType
) {
235 OLEPictureImpl_SetBitmap(newObject
);
238 case PICTYPE_METAFILE
:
239 TRACE("metafile handle %p\n", pictDesc
->u
.wmf
.hmeta
);
240 newObject
->himetricWidth
= pictDesc
->u
.wmf
.xExt
;
241 newObject
->himetricHeight
= pictDesc
->u
.wmf
.yExt
;
245 /* not sure what to do here */
246 newObject
->himetricWidth
= newObject
->himetricHeight
= 0;
250 case PICTYPE_ENHMETAFILE
:
252 FIXME("Unsupported type %d\n", pictDesc
->picType
);
253 newObject
->himetricWidth
= newObject
->himetricHeight
= 0;
257 newObject
->desc
.picType
= PICTYPE_UNINITIALIZED
;
260 TRACE("returning %p\n", newObject
);
264 /************************************************************************
265 * OLEPictureImpl_Destroy
267 * This method is called by the Release method when the reference
268 * count goes down to 0. It will free all resources used by
270 static void OLEPictureImpl_Destroy(OLEPictureImpl
* Obj
)
272 TRACE("(%p)\n", Obj
);
274 if(Obj
->fOwn
) { /* We need to destroy the picture */
275 switch(Obj
->desc
.picType
) {
277 DeleteObject(Obj
->desc
.u
.bmp
.hbitmap
);
279 case PICTYPE_METAFILE
:
280 DeleteMetaFile(Obj
->desc
.u
.wmf
.hmeta
);
283 DestroyIcon(Obj
->desc
.u
.icon
.hicon
);
285 case PICTYPE_ENHMETAFILE
:
286 DeleteEnhMetaFile(Obj
->desc
.u
.emf
.hemf
);
289 FIXME("Unsupported type %d - unable to delete\n", Obj
->desc
.picType
);
293 if (Obj
->data
) HeapFree(GetProcessHeap(), 0, Obj
->data
);
294 HeapFree(GetProcessHeap(), 0, Obj
);
297 static ULONG WINAPI
OLEPictureImpl_AddRef(IPicture
* iface
);
299 /************************************************************************
300 * OLEPictureImpl_QueryInterface (IUnknown)
302 * See Windows documentation for more details on IUnknown methods.
304 static HRESULT WINAPI
OLEPictureImpl_QueryInterface(
309 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
310 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
313 * Perform a sanity check on the parameters.
315 if ( (This
==0) || (ppvObject
==0) )
319 * Initialize the return parameter.
324 * Compare the riid with the interface IDs implemented by this object.
326 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
328 *ppvObject
= (IPicture
*)This
;
330 else if (memcmp(&IID_IPicture
, riid
, sizeof(IID_IPicture
)) == 0)
332 *ppvObject
= (IPicture
*)This
;
334 else if (memcmp(&IID_IDispatch
, riid
, sizeof(IID_IDispatch
)) == 0)
336 *ppvObject
= (IDispatch
*)&(This
->lpvtbl2
);
338 else if (memcmp(&IID_IPictureDisp
, riid
, sizeof(IID_IPictureDisp
)) == 0)
340 *ppvObject
= (IDispatch
*)&(This
->lpvtbl2
);
342 else if (memcmp(&IID_IPersistStream
, riid
, sizeof(IID_IPersistStream
)) == 0)
344 *ppvObject
= (IPersistStream
*)&(This
->lpvtbl3
);
346 else if (memcmp(&IID_IConnectionPointContainer
, riid
, sizeof(IID_IConnectionPointContainer
)) == 0)
348 *ppvObject
= (IConnectionPointContainer
*)&(This
->lpvtbl4
);
351 * Check that we obtained an interface.
355 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid
));
356 return E_NOINTERFACE
;
360 * Query Interface always increases the reference count by one when it is
363 OLEPictureImpl_AddRef((IPicture
*)This
);
367 /***********************************************************************
368 * OLEPicture_SendNotify (internal)
370 * Sends notification messages of changed properties to any interested
373 static void OLEPicture_SendNotify(OLEPictureImpl
* this, DISPID dispID
)
375 IEnumConnections
*pEnum
;
378 if (IConnectionPoint_EnumConnections(this->pCP
, &pEnum
))
380 while(IEnumConnections_Next(pEnum
, 1, &CD
, NULL
) == S_OK
) {
381 IPropertyNotifySink
*sink
;
383 IUnknown_QueryInterface(CD
.pUnk
, &IID_IPropertyNotifySink
, (LPVOID
)&sink
);
384 IPropertyNotifySink_OnChanged(sink
, dispID
);
385 IPropertyNotifySink_Release(sink
);
386 IUnknown_Release(CD
.pUnk
);
388 IEnumConnections_Release(pEnum
);
392 /************************************************************************
393 * OLEPictureImpl_AddRef (IUnknown)
395 * See Windows documentation for more details on IUnknown methods.
397 static ULONG WINAPI
OLEPictureImpl_AddRef(
400 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
401 TRACE("(%p)->(ref=%ld)\n", This
, This
->ref
);
407 /************************************************************************
408 * OLEPictureImpl_Release (IUnknown)
410 * See Windows documentation for more details on IUnknown methods.
412 static ULONG WINAPI
OLEPictureImpl_Release(
415 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
416 TRACE("(%p)->(ref=%ld)\n", This
, This
->ref
);
419 * Decrease the reference count on this object.
424 * If the reference count goes down to 0, perform suicide.
428 OLEPictureImpl_Destroy(This
);
437 /************************************************************************
438 * OLEPictureImpl_get_Handle
440 static HRESULT WINAPI
OLEPictureImpl_get_Handle(IPicture
*iface
,
443 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
444 TRACE("(%p)->(%p)\n", This
, phandle
);
445 switch(This
->desc
.picType
) {
447 *phandle
= (OLE_HANDLE
)This
->desc
.u
.bmp
.hbitmap
;
449 case PICTYPE_METAFILE
:
450 *phandle
= (OLE_HANDLE
)This
->desc
.u
.wmf
.hmeta
;
453 *phandle
= (OLE_HANDLE
)This
->desc
.u
.icon
.hicon
;
455 case PICTYPE_ENHMETAFILE
:
456 *phandle
= (OLE_HANDLE
)This
->desc
.u
.emf
.hemf
;
459 FIXME("Unimplemented type %d\n", This
->desc
.picType
);
462 TRACE("returning handle %08x\n", *phandle
);
466 /************************************************************************
467 * OLEPictureImpl_get_hPal
469 static HRESULT WINAPI
OLEPictureImpl_get_hPal(IPicture
*iface
,
472 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
473 FIXME("(%p)->(%p): stub\n", This
, phandle
);
477 /************************************************************************
478 * OLEPictureImpl_get_Type
480 static HRESULT WINAPI
OLEPictureImpl_get_Type(IPicture
*iface
,
483 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
484 TRACE("(%p)->(%p): type is %d\n", This
, ptype
, This
->desc
.picType
);
485 *ptype
= This
->desc
.picType
;
489 /************************************************************************
490 * OLEPictureImpl_get_Width
492 static HRESULT WINAPI
OLEPictureImpl_get_Width(IPicture
*iface
,
493 OLE_XSIZE_HIMETRIC
*pwidth
)
495 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
496 TRACE("(%p)->(%p): width is %ld\n", This
, pwidth
, This
->himetricWidth
);
497 *pwidth
= This
->himetricWidth
;
501 /************************************************************************
502 * OLEPictureImpl_get_Height
504 static HRESULT WINAPI
OLEPictureImpl_get_Height(IPicture
*iface
,
505 OLE_YSIZE_HIMETRIC
*pheight
)
507 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
508 TRACE("(%p)->(%p): height is %ld\n", This
, pheight
, This
->himetricHeight
);
509 *pheight
= This
->himetricHeight
;
513 /************************************************************************
514 * OLEPictureImpl_Render
516 static HRESULT WINAPI
OLEPictureImpl_Render(IPicture
*iface
, HDC hdc
,
517 long x
, long y
, long cx
, long cy
,
518 OLE_XPOS_HIMETRIC xSrc
,
519 OLE_YPOS_HIMETRIC ySrc
,
520 OLE_XSIZE_HIMETRIC cxSrc
,
521 OLE_YSIZE_HIMETRIC cySrc
,
524 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
525 TRACE("(%p)->(%p, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n",
526 This
, hdc
, x
, y
, cx
, cy
, xSrc
, ySrc
, cxSrc
, cySrc
, prcWBounds
);
528 TRACE("prcWBounds (%ld,%ld) - (%ld,%ld)\n", prcWBounds
->left
, prcWBounds
->top
,
529 prcWBounds
->right
, prcWBounds
->bottom
);
532 * While the documentation suggests this to be here (or after rendering?)
533 * it does cause an endless recursion in my sample app. -MM 20010804
534 OLEPicture_SendNotify(This,DISPID_PICT_RENDER);
537 switch(This
->desc
.picType
) {
543 /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
544 NB y-axis gets flipped */
546 hdcBmp
= CreateCompatibleDC(0);
547 SetMapMode(hdcBmp
, MM_ANISOTROPIC
);
548 SetWindowOrgEx(hdcBmp
, 0, 0, NULL
);
549 SetWindowExtEx(hdcBmp
, This
->himetricWidth
, This
->himetricHeight
, NULL
);
550 SetViewportOrgEx(hdcBmp
, 0, This
->origHeight
, NULL
);
551 SetViewportExtEx(hdcBmp
, This
->origWidth
, -This
->origHeight
, NULL
);
553 hbmpOld
= SelectObject(hdcBmp
, This
->desc
.u
.bmp
.hbitmap
);
556 HDC hdcMask
= CreateCompatibleDC(0);
557 HBITMAP hOldbm
= SelectObject(hdcMask
, This
->hbmMask
);
559 SetMapMode(hdcMask
, MM_ANISOTROPIC
);
560 SetWindowOrgEx(hdcMask
, 0, 0, NULL
);
561 SetWindowExtEx(hdcMask
, This
->himetricWidth
, This
->himetricHeight
, NULL
);
562 SetViewportOrgEx(hdcMask
, 0, This
->origHeight
, NULL
);
563 SetViewportExtEx(hdcMask
, This
->origWidth
, -This
->origHeight
, NULL
);
565 SetBkColor(hdc
, RGB(255, 255, 255));
566 SetTextColor(hdc
, RGB(0, 0, 0));
567 StretchBlt(hdc
, x
, y
, cx
, cy
, hdcMask
, xSrc
, ySrc
, cxSrc
, cySrc
, SRCAND
);
568 StretchBlt(hdc
, x
, y
, cx
, cy
, hdcBmp
, xSrc
, ySrc
, cxSrc
, cySrc
, SRCPAINT
);
570 SelectObject(hdcMask
, hOldbm
);
573 StretchBlt(hdc
, x
, y
, cx
, cy
, hdcBmp
, xSrc
, ySrc
, cxSrc
, cySrc
, SRCCOPY
);
575 SelectObject(hdcBmp
, hbmpOld
);
580 FIXME("Not quite correct implementation of rendering icons...\n");
581 DrawIcon(hdc
,x
,y
,This
->desc
.u
.icon
.hicon
);
584 case PICTYPE_METAFILE
:
585 case PICTYPE_ENHMETAFILE
:
587 FIXME("type %d not implemented\n", This
->desc
.picType
);
593 /************************************************************************
594 * OLEPictureImpl_set_hPal
596 static HRESULT WINAPI
OLEPictureImpl_set_hPal(IPicture
*iface
,
599 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
600 FIXME("(%p)->(%08x): stub\n", This
, hpal
);
601 OLEPicture_SendNotify(This
,DISPID_PICT_HPAL
);
605 /************************************************************************
606 * OLEPictureImpl_get_CurDC
608 static HRESULT WINAPI
OLEPictureImpl_get_CurDC(IPicture
*iface
,
611 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
612 TRACE("(%p), returning %p\n", This
, This
->hDCCur
);
613 if (phdc
) *phdc
= This
->hDCCur
;
617 /************************************************************************
618 * OLEPictureImpl_SelectPicture
620 static HRESULT WINAPI
OLEPictureImpl_SelectPicture(IPicture
*iface
,
623 OLE_HANDLE
*phbmpOut
)
625 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
626 TRACE("(%p)->(%p, %p, %p)\n", This
, hdcIn
, phdcOut
, phbmpOut
);
627 if (This
->desc
.picType
== PICTYPE_BITMAP
) {
628 SelectObject(hdcIn
,This
->desc
.u
.bmp
.hbitmap
);
631 *phdcOut
= This
->hDCCur
;
632 This
->hDCCur
= hdcIn
;
634 *phbmpOut
= (OLE_HANDLE
)This
->desc
.u
.bmp
.hbitmap
;
637 FIXME("Don't know how to select picture type %d\n",This
->desc
.picType
);
642 /************************************************************************
643 * OLEPictureImpl_get_KeepOriginalFormat
645 static HRESULT WINAPI
OLEPictureImpl_get_KeepOriginalFormat(IPicture
*iface
,
648 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
649 TRACE("(%p)->(%p)\n", This
, pfKeep
);
652 *pfKeep
= This
->keepOrigFormat
;
656 /************************************************************************
657 * OLEPictureImpl_put_KeepOriginalFormat
659 static HRESULT WINAPI
OLEPictureImpl_put_KeepOriginalFormat(IPicture
*iface
,
662 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
663 TRACE("(%p)->(%d)\n", This
, keep
);
664 This
->keepOrigFormat
= keep
;
665 /* FIXME: what DISPID notification here? */
669 /************************************************************************
670 * OLEPictureImpl_PictureChanged
672 static HRESULT WINAPI
OLEPictureImpl_PictureChanged(IPicture
*iface
)
674 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
675 TRACE("(%p)->()\n", This
);
676 OLEPicture_SendNotify(This
,DISPID_PICT_HANDLE
);
680 /************************************************************************
681 * OLEPictureImpl_SaveAsFile
683 static HRESULT WINAPI
OLEPictureImpl_SaveAsFile(IPicture
*iface
,
688 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
689 FIXME("(%p)->(%p, %d, %p), hacked stub.\n", This
, pstream
, SaveMemCopy
, pcbSize
);
690 return IStream_Write(pstream
,This
->data
,This
->datalen
,(ULONG
*)pcbSize
);
693 /************************************************************************
694 * OLEPictureImpl_get_Attributes
696 static HRESULT WINAPI
OLEPictureImpl_get_Attributes(IPicture
*iface
,
699 OLEPictureImpl
*This
= (OLEPictureImpl
*)iface
;
700 TRACE("(%p)->(%p).\n", This
, pdwAttr
);
702 switch (This
->desc
.picType
) {
703 case PICTYPE_BITMAP
: break; /* not 'truely' scalable, see MSDN. */
704 case PICTYPE_ICON
: *pdwAttr
= PICTURE_TRANSPARENT
;break;
705 case PICTYPE_METAFILE
: *pdwAttr
= PICTURE_TRANSPARENT
|PICTURE_SCALABLE
;break;
706 default:FIXME("Unknown pictype %d\n",This
->desc
.picType
);break;
712 /************************************************************************
713 * IConnectionPointContainer
716 static HRESULT WINAPI
OLEPictureImpl_IConnectionPointContainer_QueryInterface(
717 IConnectionPointContainer
* iface
,
721 ICOM_THIS_From_IConnectionPointContainer(IPicture
,iface
);
723 return IPicture_QueryInterface(This
,riid
,ppvoid
);
726 static ULONG WINAPI
OLEPictureImpl_IConnectionPointContainer_AddRef(
727 IConnectionPointContainer
* iface
)
729 ICOM_THIS_From_IConnectionPointContainer(IPicture
, iface
);
731 return IPicture_AddRef(This
);
734 static ULONG WINAPI
OLEPictureImpl_IConnectionPointContainer_Release(
735 IConnectionPointContainer
* iface
)
737 ICOM_THIS_From_IConnectionPointContainer(IPicture
, iface
);
739 return IPicture_Release(This
);
742 static HRESULT WINAPI
OLEPictureImpl_EnumConnectionPoints(
743 IConnectionPointContainer
* iface
,
744 IEnumConnectionPoints
** ppEnum
746 ICOM_THIS_From_IConnectionPointContainer(IPicture
, iface
);
748 FIXME("(%p,%p), stub!\n",This
,ppEnum
);
752 static HRESULT WINAPI
OLEPictureImpl_FindConnectionPoint(
753 IConnectionPointContainer
* iface
,
755 IConnectionPoint
**ppCP
757 ICOM_THIS_From_IConnectionPointContainer(OLEPictureImpl
, iface
);
758 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppCP
);
762 if (IsEqualGUID(riid
,&IID_IPropertyNotifySink
))
763 return IConnectionPoint_QueryInterface(This
->pCP
,&IID_IConnectionPoint
,(LPVOID
)ppCP
);
764 FIXME("tried to find connection point on %s?\n",debugstr_guid(riid
));
767 /************************************************************************
770 /************************************************************************
771 * OLEPictureImpl_IPersistStream_QueryInterface (IUnknown)
773 * See Windows documentation for more details on IUnknown methods.
775 static HRESULT WINAPI
OLEPictureImpl_IPersistStream_QueryInterface(
776 IPersistStream
* iface
,
780 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
782 return IPicture_QueryInterface(This
, riid
, ppvoid
);
785 /************************************************************************
786 * OLEPictureImpl_IPersistStream_AddRef (IUnknown)
788 * See Windows documentation for more details on IUnknown methods.
790 static ULONG WINAPI
OLEPictureImpl_IPersistStream_AddRef(
791 IPersistStream
* iface
)
793 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
795 return IPicture_AddRef(This
);
798 /************************************************************************
799 * OLEPictureImpl_IPersistStream_Release (IUnknown)
801 * See Windows documentation for more details on IUnknown methods.
803 static ULONG WINAPI
OLEPictureImpl_IPersistStream_Release(
804 IPersistStream
* iface
)
806 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
808 return IPicture_Release(This
);
811 /************************************************************************
812 * OLEPictureImpl_IPersistStream_GetClassID
814 static HRESULT WINAPI
OLEPictureImpl_GetClassID(
815 IPersistStream
* iface
,CLSID
* pClassID
)
817 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
818 FIXME("(%p),stub!\n",This
);
822 /************************************************************************
823 * OLEPictureImpl_IPersistStream_IsDirty
825 static HRESULT WINAPI
OLEPictureImpl_IsDirty(
826 IPersistStream
* iface
)
828 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
829 FIXME("(%p),stub!\n",This
);
833 #ifdef HAVE_JPEGLIB_H
835 static void *libjpeg_handle
;
836 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
837 MAKE_FUNCPTR(jpeg_std_error
);
838 MAKE_FUNCPTR(jpeg_CreateDecompress
);
839 MAKE_FUNCPTR(jpeg_read_header
);
840 MAKE_FUNCPTR(jpeg_start_decompress
);
841 MAKE_FUNCPTR(jpeg_read_scanlines
);
842 MAKE_FUNCPTR(jpeg_finish_decompress
);
843 MAKE_FUNCPTR(jpeg_destroy_decompress
);
846 static void *load_libjpeg(void)
848 if((libjpeg_handle
= wine_dlopen(SONAME_LIBJPEG
, RTLD_NOW
, NULL
, 0)) != NULL
) {
850 #define LOAD_FUNCPTR(f) \
851 if((p##f = wine_dlsym(libjpeg_handle, #f, NULL, 0)) == NULL) { \
852 libjpeg_handle = NULL; \
856 LOAD_FUNCPTR(jpeg_std_error
);
857 LOAD_FUNCPTR(jpeg_CreateDecompress
);
858 LOAD_FUNCPTR(jpeg_read_header
);
859 LOAD_FUNCPTR(jpeg_start_decompress
);
860 LOAD_FUNCPTR(jpeg_read_scanlines
);
861 LOAD_FUNCPTR(jpeg_finish_decompress
);
862 LOAD_FUNCPTR(jpeg_destroy_decompress
);
865 return libjpeg_handle
;
868 /* for the jpeg decompressor source manager. */
869 static void _jpeg_init_source(j_decompress_ptr cinfo
) { }
871 static boolean
_jpeg_fill_input_buffer(j_decompress_ptr cinfo
) {
872 ERR("(), should not get here.\n");
876 static void _jpeg_skip_input_data(j_decompress_ptr cinfo
,long num_bytes
) {
877 TRACE("Skipping %ld bytes...\n", num_bytes
);
878 cinfo
->src
->next_input_byte
+= num_bytes
;
879 cinfo
->src
->bytes_in_buffer
-= num_bytes
;
882 static boolean
_jpeg_resync_to_restart(j_decompress_ptr cinfo
, int desired
) {
883 ERR("(desired=%d), should not get here.\n",desired
);
886 static void _jpeg_term_source(j_decompress_ptr cinfo
) { }
887 #endif /* HAVE_JPEGLIB_H */
889 #ifdef HAVE_GIF_LIB_H
891 static void *libungif_handle
;
892 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
893 MAKE_FUNCPTR(DGifOpen
);
894 MAKE_FUNCPTR(DGifSlurp
);
895 MAKE_FUNCPTR(DGifCloseFile
);
904 static void *load_libungif(void)
906 if((libungif_handle
= wine_dlopen(SONAME_LIBUNGIF
, RTLD_NOW
, NULL
, 0)) != NULL
) {
908 #define LOAD_FUNCPTR(f) \
909 if((p##f = wine_dlsym(libungif_handle, #f, NULL, 0)) == NULL) { \
910 libungif_handle = NULL; \
914 LOAD_FUNCPTR(DGifOpen
);
915 LOAD_FUNCPTR(DGifSlurp
);
916 LOAD_FUNCPTR(DGifCloseFile
);
919 return libungif_handle
;
922 static int _gif_inputfunc(GifFileType
*gif
, GifByteType
*data
, int len
) {
923 struct gifdata
*gd
= (struct gifdata
*)gif
->UserData
;
925 if (len
+gd
->curoff
> gd
->len
) {
926 FIXME("Trying to read %d bytes, but only %d available.\n",len
, gd
->len
-gd
->curoff
);
927 len
= gd
->len
- gd
->curoff
;
929 memcpy(data
, gd
->data
+gd
->curoff
, len
);
934 #endif /* HAVE_GIF_LIB_H */
936 /************************************************************************
937 * OLEPictureImpl_IPersistStream_Load (IUnknown)
939 * Loads the binary data from the IStream. Starts at current position.
940 * There appears to be an 2 DWORD header:
944 * Currently implemented: BITMAP, ICON, JPEG, GIF
946 static HRESULT WINAPI
OLEPictureImpl_Load(IPersistStream
* iface
,IStream
*pStm
) {
953 ICOM_THIS_From_IPersistStream(OLEPictureImpl
, iface
);
955 TRACE("(%p,%p)\n",This
,pStm
);
957 /* Sometimes we have a header, sometimes we don't. Apply some guesses to find
960 * UPDATE: the IStream can be mapped to a plain file instead of a stream in a
961 * compound file. This may explain most, if not all, of the cases of "no header",
962 * and the header validation should take this into account. At least in Visual Basic 6,
963 * resource streams, valid headers are
964 * header[0] == "lt\0\0",
965 * header[1] == length_of_stream.
967 hr
=IStream_Stat(pStm
,&statstg
,STATFLAG_NONAME
);
969 FIXME("Stat failed with hres %lx\n",hr
);
970 hr
=IStream_Read(pStm
,header
,8,&xread
);
971 if (hr
|| xread
!=8) {
972 FIXME("Failure while reading picture header (hr is %lx, nread is %ld).\n",hr
,xread
);
975 if (!memcmp(&(header
[0]), "GIF8", 4) || /* GIF header */
976 !memcmp(&(header
[0]), "BM", 2) || /* BMP header */
977 !memcmp(&(header
[0]), "\xff\xd8", 2) || /* JPEG header */
978 header
[1] > statstg
.cbSize
.QuadPart
|| (header
[1]==0)) {/* Incorrect header, assume none. */
980 xbuf
= This
->data
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,statstg
.cbSize
.QuadPart
);
981 memcpy(xbuf
,&header
,8);
982 This
->datalen
= statstg
.cbSize
.QuadPart
;
983 while (xread
< This
->datalen
) {
985 hr
= IStream_Read(pStm
,xbuf
+xread
,This
->datalen
-xread
,&nread
);
990 if (xread
!= This
->datalen
)
991 FIXME("Could only read %ld of %d bytes in no-header case?\n",xread
,This
->datalen
);
994 xbuf
= This
->data
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,header
[1]);
995 This
->datalen
= header
[1];
996 while (xread
< header
[1]) {
998 hr
= IStream_Read(pStm
,xbuf
+xread
,header
[1]-xread
,&nread
);
1003 if (xread
!= header
[1])
1004 FIXME("Could only read %ld of %ld bytes?\n",xread
,header
[1]);
1006 magic
= xbuf
[0] + (xbuf
[1]<<8);
1008 case 0x4947: { /* GIF */
1009 #ifdef HAVE_GIF_LIB_H
1019 int transparent
= -1;
1023 if(!libungif_handle
) {
1024 if(!load_libungif()) {
1025 FIXME("Failed reading GIF because unable to find %s\n", SONAME_LIBUNGIF
);
1033 gif
= pDGifOpen((void*)&gd
, _gif_inputfunc
);
1034 ret
= pDGifSlurp(gif
);
1035 if (ret
== GIF_ERROR
) {
1036 FIXME("Failed reading GIF using libgif.\n");
1039 TRACE("screen height %d, width %d\n", gif
->SWidth
, gif
->SHeight
);
1040 TRACE("color res %d, backgcolor %d\n", gif
->SColorResolution
, gif
->SBackGroundColor
);
1041 TRACE("imgcnt %d\n", gif
->ImageCount
);
1042 if (gif
->ImageCount
<1) {
1043 FIXME("GIF stream does not have images inside?\n");
1046 TRACE("curimage: %d x %d, on %dx%d, interlace %d\n",
1047 gif
->Image
.Width
, gif
->Image
.Height
,
1048 gif
->Image
.Left
, gif
->Image
.Top
,
1049 gif
->Image
.Interlace
1052 padding
= (gif
->SWidth
+3) & ~3;
1053 bmi
= HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER
)+(1<<gif
->SColorResolution
)*sizeof(RGBQUAD
));
1054 bytes
= HeapAlloc(GetProcessHeap(),0,padding
*gif
->SHeight
);
1055 si
= gif
->SavedImages
+0;
1056 gid
= &(si
->ImageDesc
);
1058 if (!cm
) cm
= gif
->SColorMap
;
1060 /* look for the transparent color extension */
1061 for (i
= 0; i
< si
->ExtensionBlockCount
; ++i
) {
1062 eb
= si
->ExtensionBlocks
+ i
;
1063 if (eb
->Function
== 0xF9 && eb
->ByteCount
== 4) {
1064 if ((eb
->Bytes
[0] & 1) == 1) {
1065 transparent
= eb
->Bytes
[3];
1070 for (i
=0;i
<(1<<gif
->SColorResolution
);i
++) {
1071 bmi
->bmiColors
[i
].rgbRed
= cm
->Colors
[i
].Red
;
1072 bmi
->bmiColors
[i
].rgbGreen
= cm
->Colors
[i
].Green
;
1073 bmi
->bmiColors
[i
].rgbBlue
= cm
->Colors
[i
].Blue
;
1074 if (i
== transparent
) {
1075 This
->rgbTrans
= RGB(bmi
->bmiColors
[i
].rgbRed
,
1076 bmi
->bmiColors
[i
].rgbGreen
,
1077 bmi
->bmiColors
[i
].rgbBlue
);
1081 /* Map to in picture coordinates */
1082 for (i
=0;i
<gid
->Height
;i
++)
1083 for (j
=0;j
<gid
->Width
;j
++)
1084 bytes
[(gid
->Top
+i
)*(padding
)+gid
->Left
+j
]=si
->RasterBits
[i
*gid
->Width
+j
];
1086 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
1087 bmi
->bmiHeader
.biWidth
= gif
->SWidth
;
1088 bmi
->bmiHeader
.biHeight
= -gif
->SHeight
;
1089 bmi
->bmiHeader
.biPlanes
= 1;
1090 bmi
->bmiHeader
.biBitCount
= 8;
1091 bmi
->bmiHeader
.biCompression
= BI_RGB
;
1092 bmi
->bmiHeader
.biSizeImage
= padding
*gif
->SHeight
;
1093 bmi
->bmiHeader
.biXPelsPerMeter
= 0;
1094 bmi
->bmiHeader
.biYPelsPerMeter
= 0;
1095 bmi
->bmiHeader
.biClrUsed
= 1 << gif
->SColorResolution
;
1096 bmi
->bmiHeader
.biClrImportant
= 0;
1099 This
->desc
.u
.bmp
.hbitmap
=CreateDIBitmap(
1108 if (transparent
> -1) {
1109 /* Create the Mask */
1110 HDC hdc
= CreateCompatibleDC(0);
1111 HDC hdcMask
= CreateCompatibleDC(0);
1113 HBITMAP hOldbitmapmask
;
1115 This
->hbmMask
= CreateBitmap(bmi
->bmiHeader
.biWidth
, bmi
->bmiHeader
.biHeight
, 1, 1, NULL
);
1117 hOldbitmap
= SelectObject(hdc
,This
->desc
.u
.bmp
.hbitmap
);
1118 hOldbitmapmask
= SelectObject(hdcMask
, This
->hbmMask
);
1119 SetBkColor(hdc
, This
->rgbTrans
);
1120 BitBlt(hdcMask
, 0, 0, bmi
->bmiHeader
.biWidth
, bmi
->bmiHeader
.biHeight
, hdc
, 0, 0, SRCCOPY
);
1122 /* We no longer need the original bitmap, so we apply the first
1123 transformation with the mask to speed up the rendering */
1124 SetBkColor(hdc
, RGB(0,0,0));
1125 SetTextColor(hdc
, RGB(255,255,255));
1126 BitBlt(hdc
, 0, 0, bmi
->bmiHeader
.biWidth
, bmi
->bmiHeader
.biHeight
,
1127 hdcMask
, 0, 0, SRCAND
);
1129 SelectObject(hdc
, hOldbitmap
);
1130 SelectObject(hdcMask
, hOldbitmapmask
);
1136 This
->desc
.picType
= PICTYPE_BITMAP
;
1137 OLEPictureImpl_SetBitmap(This
);
1138 pDGifCloseFile(gif
);
1139 HeapFree(GetProcessHeap(),0,bytes
);
1142 FIXME("Trying to load GIF, but no support for libgif/libungif compiled in.\n");
1147 case 0xd8ff: { /* JPEG */
1148 #ifdef HAVE_JPEGLIB_H
1149 struct jpeg_decompress_struct jd
;
1150 struct jpeg_error_mgr jerr
;
1153 JSAMPROW samprow
,oldsamprow
;
1154 BITMAPINFOHEADER bmi
;
1157 struct jpeg_source_mgr xjsm
;
1161 if(!libjpeg_handle
) {
1162 if(!load_libjpeg()) {
1163 FIXME("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG
);
1168 /* This is basically so we can use in-memory data for jpeg decompression.
1169 * We need to have all the functions.
1171 xjsm
.next_input_byte
= xbuf
;
1172 xjsm
.bytes_in_buffer
= xread
;
1173 xjsm
.init_source
= _jpeg_init_source
;
1174 xjsm
.fill_input_buffer
= _jpeg_fill_input_buffer
;
1175 xjsm
.skip_input_data
= _jpeg_skip_input_data
;
1176 xjsm
.resync_to_restart
= _jpeg_resync_to_restart
;
1177 xjsm
.term_source
= _jpeg_term_source
;
1179 jd
.err
= pjpeg_std_error(&jerr
);
1180 /* jpeg_create_decompress is a macro that expands to jpeg_CreateDecompress - see jpeglib.h
1181 * jpeg_create_decompress(&jd); */
1182 pjpeg_CreateDecompress(&jd
, JPEG_LIB_VERSION
, (size_t) sizeof(struct jpeg_decompress_struct
));
1184 ret
=pjpeg_read_header(&jd
,TRUE
);
1185 jd
.out_color_space
= JCS_RGB
;
1186 pjpeg_start_decompress(&jd
);
1187 if (ret
!= JPEG_HEADER_OK
) {
1188 ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret
);
1189 HeapFree(GetProcessHeap(),0,xbuf
);
1193 bits
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
1194 (jd
.output_height
+1) * ((jd
.output_width
*jd
.output_components
+ 3) & ~3) );
1195 samprow
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,jd
.output_width
*jd
.output_components
);
1198 oldsamprow
= samprow
;
1199 while ( jd
.output_scanline
<jd
.output_height
) {
1200 x
= pjpeg_read_scanlines(&jd
,&samprow
,1);
1202 FIXME("failed to read current scanline?\n");
1205 /* We have to convert from RGB to BGR, see MSDN/ BITMAPINFOHEADER */
1206 for(i
=0;i
<jd
.output_width
;i
++,samprow
+=jd
.output_components
) {
1207 *(bits
++) = *(samprow
+2);
1208 *(bits
++) = *(samprow
+1);
1209 *(bits
++) = *(samprow
);
1211 bits
= (LPBYTE
)(((UINT_PTR
)bits
+ 3) & ~3);
1212 samprow
= oldsamprow
;
1216 bmi
.biSize
= sizeof(bmi
);
1217 bmi
.biWidth
= jd
.output_width
;
1218 bmi
.biHeight
= -jd
.output_height
;
1220 bmi
.biBitCount
= jd
.output_components
<<3;
1221 bmi
.biCompression
= BI_RGB
;
1222 bmi
.biSizeImage
= jd
.output_height
*jd
.output_width
*jd
.output_components
;
1223 bmi
.biXPelsPerMeter
= 0;
1224 bmi
.biYPelsPerMeter
= 0;
1226 bmi
.biClrImportant
= 0;
1228 HeapFree(GetProcessHeap(),0,samprow
);
1229 pjpeg_finish_decompress(&jd
);
1230 pjpeg_destroy_decompress(&jd
);
1232 This
->desc
.u
.bmp
.hbitmap
=CreateDIBitmap(
1241 This
->desc
.picType
= PICTYPE_BITMAP
;
1242 OLEPictureImpl_SetBitmap(This
);
1244 HeapFree(GetProcessHeap(),0,bits
);
1246 ERR("Trying to load JPEG picture, but JPEG supported not compiled in.\n");
1251 case 0x4d42: { /* Bitmap */
1252 BITMAPFILEHEADER
*bfh
= (BITMAPFILEHEADER
*)xbuf
;
1253 BITMAPINFO
*bi
= (BITMAPINFO
*)(bfh
+1);
1256 /* Does not matter whether this is a coreheader or not, we only use
1257 * components which are in both
1260 This
->desc
.u
.bmp
.hbitmap
= CreateDIBitmap(
1264 xbuf
+bfh
->bfOffBits
,
1266 (bi
->bmiHeader
.biBitCount
<=8)?DIB_PAL_COLORS
:DIB_RGB_COLORS
1269 This
->desc
.picType
= PICTYPE_BITMAP
;
1270 OLEPictureImpl_SetBitmap(This
);
1274 case 0x0000: { /* ICON , first word is dwReserved */
1276 CURSORICONFILEDIR
*cifd
= (CURSORICONFILEDIR
*)xbuf
;
1281 FIXME("icon.idReserved=%d\n",cifd->idReserved);
1282 FIXME("icon.idType=%d\n",cifd->idType);
1283 FIXME("icon.idCount=%d\n",cifd->idCount);
1285 for (i=0;i<cifd->idCount;i++) {
1286 FIXME("[%d] width %d\n",i,cifd->idEntries[i].bWidth);
1287 FIXME("[%d] height %d\n",i,cifd->idEntries[i].bHeight);
1288 FIXME("[%d] bColorCount %d\n",i,cifd->idEntries[i].bColorCount);
1289 FIXME("[%d] bReserved %d\n",i,cifd->idEntries[i].bReserved);
1290 FIXME("[%d] xHotspot %d\n",i,cifd->idEntries[i].xHotspot);
1291 FIXME("[%d] yHotspot %d\n",i,cifd->idEntries[i].yHotspot);
1292 FIXME("[%d] dwDIBSize %d\n",i,cifd->idEntries[i].dwDIBSize);
1293 FIXME("[%d] dwDIBOffset %d\n",i,cifd->idEntries[i].dwDIBOffset);
1297 /* If we have more than one icon, try to find the best.
1298 * this currently means '32 pixel wide'.
1300 if (cifd
->idCount
!=1) {
1301 for (i
=0;i
<cifd
->idCount
;i
++) {
1302 if (cifd
->idEntries
[i
].bWidth
== 32)
1305 if (i
==cifd
->idCount
) i
=0;
1308 hicon
= CreateIconFromResourceEx(
1309 xbuf
+cifd
->idEntries
[i
].dwDIBOffset
,
1310 cifd
->idEntries
[i
].dwDIBSize
,
1313 cifd
->idEntries
[i
].bWidth
,
1314 cifd
->idEntries
[i
].bHeight
,
1318 FIXME("CreateIcon failed.\n");
1321 This
->desc
.picType
= PICTYPE_ICON
;
1322 This
->desc
.u
.icon
.hicon
= hicon
;
1323 This
->origWidth
= cifd
->idEntries
[i
].bWidth
;
1324 This
->origHeight
= cifd
->idEntries
[i
].bHeight
;
1325 hdcRef
= CreateCompatibleDC(0);
1326 This
->himetricWidth
=(cifd
->idEntries
[i
].bWidth
*2540)/GetDeviceCaps(hdcRef
, LOGPIXELSX
);
1327 This
->himetricHeight
=(cifd
->idEntries
[i
].bHeight
*2540)/GetDeviceCaps(hdcRef
, LOGPIXELSY
);
1336 FIXME("Unknown magic %04x, %ld read bytes:\n",magic
,xread
);
1338 for (i
=0;i
<xread
+8;i
++) {
1339 if (i
<8) MESSAGE("%02x ",((unsigned char*)&header
)[i
]);
1340 else MESSAGE("%02x ",xbuf
[i
-8]);
1341 if (i
% 10 == 9) MESSAGE("\n");
1348 /* FIXME: this notify is not really documented */
1350 OLEPicture_SendNotify(This
,DISPID_PICT_TYPE
);
1354 static HRESULT WINAPI
OLEPictureImpl_Save(
1355 IPersistStream
* iface
,IStream
*pStm
,BOOL fClearDirty
)
1357 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
1358 FIXME("(%p,%p,%d),stub!\n",This
,pStm
,fClearDirty
);
1362 static HRESULT WINAPI
OLEPictureImpl_GetSizeMax(
1363 IPersistStream
* iface
,ULARGE_INTEGER
*pcbSize
)
1365 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
1366 FIXME("(%p,%p),stub!\n",This
,pcbSize
);
1370 /************************************************************************
1373 /************************************************************************
1374 * OLEPictureImpl_IDispatch_QueryInterface (IUnknown)
1376 * See Windows documentation for more details on IUnknown methods.
1378 static HRESULT WINAPI
OLEPictureImpl_IDispatch_QueryInterface(
1383 ICOM_THIS_From_IDispatch(IPicture
, iface
);
1385 return IPicture_QueryInterface(This
, riid
, ppvoid
);
1388 /************************************************************************
1389 * OLEPictureImpl_IDispatch_AddRef (IUnknown)
1391 * See Windows documentation for more details on IUnknown methods.
1393 static ULONG WINAPI
OLEPictureImpl_IDispatch_AddRef(
1396 ICOM_THIS_From_IDispatch(IPicture
, iface
);
1398 return IPicture_AddRef(This
);
1401 /************************************************************************
1402 * OLEPictureImpl_IDispatch_Release (IUnknown)
1404 * See Windows documentation for more details on IUnknown methods.
1406 static ULONG WINAPI
OLEPictureImpl_IDispatch_Release(
1409 ICOM_THIS_From_IDispatch(IPicture
, iface
);
1411 return IPicture_Release(This
);
1414 /************************************************************************
1415 * OLEPictureImpl_GetTypeInfoCount (IDispatch)
1417 * See Windows documentation for more details on IDispatch methods.
1419 static HRESULT WINAPI
OLEPictureImpl_GetTypeInfoCount(
1421 unsigned int* pctinfo
)
1428 /************************************************************************
1429 * OLEPictureImpl_GetTypeInfo (IDispatch)
1431 * See Windows documentation for more details on IDispatch methods.
1433 static HRESULT WINAPI
OLEPictureImpl_GetTypeInfo(
1437 ITypeInfo
** ppTInfo
)
1444 /************************************************************************
1445 * OLEPictureImpl_GetIDsOfNames (IDispatch)
1447 * See Windows documentation for more details on IDispatch methods.
1449 static HRESULT WINAPI
OLEPictureImpl_GetIDsOfNames(
1452 LPOLESTR
* rgszNames
,
1462 /************************************************************************
1463 * OLEPictureImpl_Invoke (IDispatch)
1465 * See Windows documentation for more details on IDispatch methods.
1467 static HRESULT WINAPI
OLEPictureImpl_Invoke(
1469 DISPID dispIdMember
,
1473 DISPPARAMS
* pDispParams
,
1474 VARIANT
* pVarResult
,
1475 EXCEPINFO
* pExepInfo
,
1478 FIXME("(dispid: %ld):Stub\n",dispIdMember
);
1480 VariantInit(pVarResult
);
1481 V_VT(pVarResult
) = VT_BOOL
;
1482 V_UNION(pVarResult
,boolVal
) = FALSE
;
1487 static IPictureVtbl OLEPictureImpl_VTable
=
1489 OLEPictureImpl_QueryInterface
,
1490 OLEPictureImpl_AddRef
,
1491 OLEPictureImpl_Release
,
1492 OLEPictureImpl_get_Handle
,
1493 OLEPictureImpl_get_hPal
,
1494 OLEPictureImpl_get_Type
,
1495 OLEPictureImpl_get_Width
,
1496 OLEPictureImpl_get_Height
,
1497 OLEPictureImpl_Render
,
1498 OLEPictureImpl_set_hPal
,
1499 OLEPictureImpl_get_CurDC
,
1500 OLEPictureImpl_SelectPicture
,
1501 OLEPictureImpl_get_KeepOriginalFormat
,
1502 OLEPictureImpl_put_KeepOriginalFormat
,
1503 OLEPictureImpl_PictureChanged
,
1504 OLEPictureImpl_SaveAsFile
,
1505 OLEPictureImpl_get_Attributes
1508 static IDispatchVtbl OLEPictureImpl_IDispatch_VTable
=
1510 OLEPictureImpl_IDispatch_QueryInterface
,
1511 OLEPictureImpl_IDispatch_AddRef
,
1512 OLEPictureImpl_IDispatch_Release
,
1513 OLEPictureImpl_GetTypeInfoCount
,
1514 OLEPictureImpl_GetTypeInfo
,
1515 OLEPictureImpl_GetIDsOfNames
,
1516 OLEPictureImpl_Invoke
1519 static IPersistStreamVtbl OLEPictureImpl_IPersistStream_VTable
=
1521 OLEPictureImpl_IPersistStream_QueryInterface
,
1522 OLEPictureImpl_IPersistStream_AddRef
,
1523 OLEPictureImpl_IPersistStream_Release
,
1524 OLEPictureImpl_GetClassID
,
1525 OLEPictureImpl_IsDirty
,
1526 OLEPictureImpl_Load
,
1527 OLEPictureImpl_Save
,
1528 OLEPictureImpl_GetSizeMax
1531 static IConnectionPointContainerVtbl OLEPictureImpl_IConnectionPointContainer_VTable
=
1533 OLEPictureImpl_IConnectionPointContainer_QueryInterface
,
1534 OLEPictureImpl_IConnectionPointContainer_AddRef
,
1535 OLEPictureImpl_IConnectionPointContainer_Release
,
1536 OLEPictureImpl_EnumConnectionPoints
,
1537 OLEPictureImpl_FindConnectionPoint
1540 /***********************************************************************
1541 * OleCreatePictureIndirect (OLEAUT32.419)
1543 HRESULT WINAPI
OleCreatePictureIndirect(LPPICTDESC lpPictDesc
, REFIID riid
,
1544 BOOL fOwn
, LPVOID
*ppvObj
)
1546 OLEPictureImpl
* newPict
= NULL
;
1549 TRACE("(%p,%p,%d,%p)\n", lpPictDesc
, riid
, fOwn
, ppvObj
);
1560 * Try to construct a new instance of the class.
1562 newPict
= OLEPictureImpl_Construct(lpPictDesc
, fOwn
);
1564 if (newPict
== NULL
)
1565 return E_OUTOFMEMORY
;
1568 * Make sure it supports the interface required by the caller.
1570 hr
= IPicture_QueryInterface((IPicture
*)newPict
, riid
, ppvObj
);
1573 * Release the reference obtained in the constructor. If
1574 * the QueryInterface was unsuccessful, it will free the class.
1576 IPicture_Release((IPicture
*)newPict
);
1582 /***********************************************************************
1583 * OleLoadPicture (OLEAUT32.418)
1585 HRESULT WINAPI
OleLoadPicture( LPSTREAM lpstream
, LONG lSize
, BOOL fRunmode
,
1586 REFIID riid
, LPVOID
*ppvObj
)
1592 TRACE("(%p,%ld,%d,%s,%p), partially implemented.\n",
1593 lpstream
, lSize
, fRunmode
, debugstr_guid(riid
), ppvObj
);
1595 hr
= OleCreatePictureIndirect(NULL
,riid
,!fRunmode
,(LPVOID
*)&newpic
);
1598 hr
= IPicture_QueryInterface(newpic
,&IID_IPersistStream
, (LPVOID
*)&ps
);
1600 FIXME("Could not get IPersistStream iface from Ole Picture?\n");
1601 IPicture_Release(newpic
);
1605 IPersistStream_Load(ps
,lpstream
);
1606 IPersistStream_Release(ps
);
1607 hr
= IPicture_QueryInterface(newpic
,riid
,ppvObj
);
1609 FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid
));
1610 IPicture_Release(newpic
);
1614 /***********************************************************************
1615 * OleLoadPictureEx (OLEAUT32.401)
1617 HRESULT WINAPI
OleLoadPictureEx( LPSTREAM lpstream
, LONG lSize
, BOOL fRunmode
,
1618 REFIID riid
, DWORD xsiz
, DWORD ysiz
, DWORD flags
, LPVOID
*ppvObj
)
1624 FIXME("(%p,%ld,%d,%s,x=%ld,y=%ld,f=%lx,%p), partially implemented.\n",
1625 lpstream
, lSize
, fRunmode
, debugstr_guid(riid
), xsiz
, ysiz
, flags
, ppvObj
);
1627 hr
= OleCreatePictureIndirect(NULL
,riid
,!fRunmode
,(LPVOID
*)&newpic
);
1630 hr
= IPicture_QueryInterface(newpic
,&IID_IPersistStream
, (LPVOID
*)&ps
);
1632 FIXME("Could not get IPersistStream iface from Ole Picture?\n");
1633 IPicture_Release(newpic
);
1637 IPersistStream_Load(ps
,lpstream
);
1638 IPersistStream_Release(ps
);
1639 hr
= IPicture_QueryInterface(newpic
,riid
,ppvObj
);
1641 FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid
));
1642 IPicture_Release(newpic
);
1646 /*******************************************************************************
1647 * StdPic ClassFactory
1651 /* IUnknown fields */
1652 IClassFactoryVtbl
*lpVtbl
;
1654 } IClassFactoryImpl
;
1656 static HRESULT WINAPI
1657 SPCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
) {
1658 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1660 FIXME("(%p)->(%s,%p),stub!\n",This
,debugstr_guid(riid
),ppobj
);
1661 return E_NOINTERFACE
;
1665 SPCF_AddRef(LPCLASSFACTORY iface
) {
1666 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1667 return ++(This
->ref
);
1670 static ULONG WINAPI
SPCF_Release(LPCLASSFACTORY iface
) {
1671 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1672 /* static class, won't be freed */
1673 return --(This
->ref
);
1676 static HRESULT WINAPI
SPCF_CreateInstance(
1677 LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
1681 FIXME("(%p,%p,%s,%p), creating stdpic with PICTYPE_NONE.\n",iface
,pOuter
,debugstr_guid(riid
),ppobj
);
1682 pd
.cbSizeofstruct
= sizeof(pd
);
1683 pd
.picType
= PICTYPE_NONE
;
1684 return OleCreatePictureIndirect(&pd
,riid
,TRUE
,ppobj
);
1688 static HRESULT WINAPI
SPCF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
) {
1689 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1690 FIXME("(%p)->(%d),stub!\n",This
,dolock
);
1694 static IClassFactoryVtbl SPCF_Vtbl
= {
1695 SPCF_QueryInterface
,
1698 SPCF_CreateInstance
,
1701 static IClassFactoryImpl STDPIC_CF
= {&SPCF_Vtbl
, 1 };
1703 void _get_STDPIC_CF(LPVOID
*ppv
) { *ppv
= (LPVOID
)&STDPIC_CF
; }