Documentation fixes.
[wine] / dlls / oleaut32 / olepicture.c
1 /*
2  * OLE Picture object
3  *
4  * Implementation of OLE IPicture and related interfaces
5  *
6  * Copyright 2000 Huw D M Davies for CodeWeavers.
7  *
8  *
9  * BUGS
10  *
11  * Only implements PICTYPE_BITMAP.
12  * Most methods are just stubs.
13  * Doesn't even expose IPersistStream, IConnectionPointContainer.
14  *
15  *
16  * NOTES (or things that msdn doesn't tell you)
17  *
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).
22  *
23  */
24
25 #include <string.h>
26 #include "winerror.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "ole2.h"
31 #include "olectl.h"
32 #include "wine/obj_picture.h"
33 #include "debugtools.h"
34
35 DEFAULT_DEBUG_CHANNEL(ole);
36
37 /*************************************************************************
38  *  Declaration of implementation class
39  */
40
41 typedef struct OLEPictureImpl {
42
43   /*
44    * IPicture handles IUnknown
45    */
46
47     ICOM_VTABLE(IPicture)       *lpvtbl1;
48     ICOM_VTABLE(IDispatch)      *lpvtbl2;
49     ICOM_VTABLE(IPersistStream) *lpvtbl3;
50
51   /* Object referenece count */
52     DWORD ref;
53
54   /* We own the object and must destroy it ourselves */
55     BOOL fOwn;
56   
57   /* Picture description */
58     PICTDESC desc;
59
60   /* These are the pixel size of a bitmap */
61     DWORD origWidth;
62     DWORD origHeight;
63
64   /* And these are the size of the picture converted into HIMETRIC units */
65     OLE_XSIZE_HIMETRIC himetricWidth;
66     OLE_YSIZE_HIMETRIC himetricHeight;
67
68 } OLEPictureImpl;
69
70 /*
71  * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables.
72  */
73 #define ICOM_THIS_From_IDispatch(impl, name) \
74     impl *This = (impl*)(((char*)name)-sizeof(void*));
75
76 #define ICOM_THIS_From_IPersistStream(impl, name) \
77     impl *This = (impl*)(((char*)name)-2*sizeof(void*));
78
79 /*
80  * Predeclare VTables.  They get initialized at the end.
81  */
82 static ICOM_VTABLE(IPicture) OLEPictureImpl_VTable;
83 static ICOM_VTABLE(IDispatch) OLEPictureImpl_IDispatch_VTable;
84 static ICOM_VTABLE(IPersistStream) OLEPictureImpl_IPersistStream_VTable;
85
86 /***********************************************************************
87  * Implementation of the OLEPictureImpl class.
88  */
89
90 /************************************************************************
91  * OLEPictureImpl_Construct
92  *
93  * This method will construct a new instance of the OLEPictureImpl
94  * class.
95  *
96  * The caller of this method must release the object when it's
97  * done with it.
98  */
99 static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
100 {
101   OLEPictureImpl* newObject = 0;
102   TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType);
103
104   /*
105    * Allocate space for the object.
106    */
107   newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEPictureImpl));
108
109   if (newObject==0)
110     return newObject;
111   
112   /*
113    * Initialize the virtual function table.
114    */
115   newObject->lpvtbl1 = &OLEPictureImpl_VTable;
116   newObject->lpvtbl2 = &OLEPictureImpl_IDispatch_VTable;
117   newObject->lpvtbl3 = &OLEPictureImpl_IPersistStream_VTable;
118   
119   /*
120    * Start with one reference count. The caller of this function 
121    * must release the interface pointer when it is done.
122    */
123   newObject->ref = 1;
124
125   newObject->fOwn = fOwn;
126
127   if(pictDesc->cbSizeofstruct != sizeof(PICTDESC)) {
128       FIXME("struct size = %d\n", pictDesc->cbSizeofstruct);
129   }
130   memcpy(&newObject->desc, pictDesc, sizeof(PICTDESC));
131
132   switch(pictDesc->picType) {
133   case PICTYPE_BITMAP:
134     {
135       BITMAP bm;
136       HDC hdcRef;
137
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");
141         break;
142       }
143
144       newObject->origWidth = bm.bmWidth;
145       newObject->origHeight = bm.bmHeight;
146
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 */
150
151       /* Should we use GetBitmapDimension if available? */
152
153       hdcRef = CreateCompatibleDC(0);
154
155       newObject->himetricWidth = (bm.bmWidth * 2540) /
156         GetDeviceCaps(hdcRef, LOGPIXELSX);
157       newObject->himetricHeight = (bm.bmHeight * 2540) / 
158         GetDeviceCaps(hdcRef, LOGPIXELSY);
159       DeleteDC(hdcRef);
160     }
161     break;
162
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;
167     break;
168
169   case PICTYPE_ICON:
170   case PICTYPE_ENHMETAFILE:
171   default:
172     FIXME("Unsupported type %d\n", pictDesc->picType);
173     newObject->himetricWidth = newObject->himetricHeight = 0;
174     break;
175   }
176     
177   TRACE("returning %p\n", newObject);
178   return newObject;
179 }
180
181 /************************************************************************
182  * OLEPictureImpl_Destroy
183  *
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
186  * this object.  */
187 static void OLEPictureImpl_Destroy(OLEPictureImpl* Obj)
188
189   TRACE("(%p)\n", Obj);
190
191   if(Obj->fOwn) { /* We need to destroy the picture */
192     switch(Obj->desc.picType) {
193     case PICTYPE_BITMAP:
194       DeleteObject(Obj->desc.u.bmp.hbitmap);
195       break;
196     case PICTYPE_METAFILE:
197       DeleteMetaFile(Obj->desc.u.wmf.hmeta);
198       break;
199     case PICTYPE_ICON:
200       DestroyIcon(Obj->desc.u.icon.hicon);
201       break;
202     case PICTYPE_ENHMETAFILE:
203       DeleteEnhMetaFile(Obj->desc.u.emf.hemf);
204       break;
205     default:
206       FIXME("Unsupported type %d - unable to delete\n", Obj->desc.picType);
207       break;
208     }
209   }
210   HeapFree(GetProcessHeap(), 0, Obj);
211 }
212
213 static ULONG WINAPI OLEPictureImpl_AddRef(IPicture* iface);
214
215 /************************************************************************
216  * OLEPictureImpl_QueryInterface (IUnknown)
217  *
218  * See Windows documentation for more details on IUnknown methods.
219  */
220 static HRESULT WINAPI OLEPictureImpl_QueryInterface(
221   IPicture*  iface,
222   REFIID  riid,
223   void**  ppvObject)
224 {
225   ICOM_THIS(OLEPictureImpl, iface);
226   TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
227
228   /*
229    * Perform a sanity check on the parameters.
230    */
231   if ( (This==0) || (ppvObject==0) )
232     return E_INVALIDARG;
233   
234   /*
235    * Initialize the return parameter.
236    */
237   *ppvObject = 0;
238   
239   /*
240    * Compare the riid with the interface IDs implemented by this object.
241    */
242   if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 
243   {
244     *ppvObject = (IPicture*)This;
245   }
246   else if (memcmp(&IID_IPicture, riid, sizeof(IID_IPicture)) == 0) 
247   {
248     *ppvObject = (IPicture*)This;
249   }
250   else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0) 
251   {
252     *ppvObject = (IDispatch*)&(This->lpvtbl2);
253   }
254   else if (memcmp(&IID_IPictureDisp, riid, sizeof(IID_IPictureDisp)) == 0) 
255   {
256     *ppvObject = (IDispatch*)&(This->lpvtbl2);
257   }
258   /*  else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0) 
259   {
260   *ppvObject = (IPersistStream*)&(This->lpvtbl3);
261   }*/
262   
263   /*
264    * Check that we obtained an interface.
265    */
266   if ((*ppvObject)==0)
267   {
268     FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
269     return E_NOINTERFACE;
270   }
271   
272   /*
273    * Query Interface always increases the reference count by one when it is
274    * successful
275    */
276   OLEPictureImpl_AddRef((IPicture*)This);
277
278   return S_OK;;
279 }
280         
281 /************************************************************************
282  * OLEPictureImpl_AddRef (IUnknown)
283  *
284  * See Windows documentation for more details on IUnknown methods.
285  */
286 static ULONG WINAPI OLEPictureImpl_AddRef( 
287   IPicture* iface)
288 {
289   ICOM_THIS(OLEPictureImpl, iface);
290   TRACE("(%p)->(ref=%ld)\n", This, This->ref);
291   This->ref++;
292
293   return This->ref;
294 }
295         
296 /************************************************************************
297  * OLEPictureImpl_Release (IUnknown)
298  *
299  * See Windows documentation for more details on IUnknown methods.
300  */
301 static ULONG WINAPI OLEPictureImpl_Release( 
302       IPicture* iface)
303 {
304   ICOM_THIS(OLEPictureImpl, iface);
305   TRACE("(%p)->(ref=%ld)\n", This, This->ref);
306
307   /*
308    * Decrease the reference count on this object.
309    */
310   This->ref--;
311
312   /*
313    * If the reference count goes down to 0, perform suicide.
314    */
315   if (This->ref==0)
316   {
317     OLEPictureImpl_Destroy(This);
318
319     return 0;
320   }
321   
322   return This->ref;
323 }
324
325
326 /************************************************************************
327  * OLEPictureImpl_get_Handle
328  */ 
329 static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface,
330                                                 OLE_HANDLE *phandle)
331 {
332   ICOM_THIS(OLEPictureImpl, iface);
333   TRACE("(%p)->(%p)\n", This, phandle);
334   switch(This->desc.picType) {
335   case PICTYPE_BITMAP:
336     *phandle = This->desc.u.bmp.hbitmap;
337     break;
338   case PICTYPE_METAFILE:
339     *phandle = This->desc.u.wmf.hmeta;
340     break;
341   case PICTYPE_ICON:
342     *phandle = This->desc.u.icon.hicon;
343     break;
344   case PICTYPE_ENHMETAFILE:
345     *phandle = This->desc.u.emf.hemf;
346     break;
347   default:
348     FIXME("Unimplemented type %d\n", This->desc.picType);
349     return E_NOTIMPL;
350   }
351   TRACE("returning handle %08x\n", *phandle);
352   return S_OK;
353 }
354
355 /************************************************************************
356  * OLEPictureImpl_get_hPal
357  */ 
358 static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
359                                               OLE_HANDLE *phandle)
360 {
361   ICOM_THIS(OLEPictureImpl, iface);
362   FIXME("(%p)->(%p): stub\n", This, phandle);
363   return E_NOTIMPL;
364 }
365
366 /************************************************************************
367  * OLEPictureImpl_get_Type
368  */ 
369 static HRESULT WINAPI OLEPictureImpl_get_Type(IPicture *iface,
370                                               short *ptype)
371 {
372   ICOM_THIS(OLEPictureImpl, iface);
373   TRACE("(%p)->(%p): type is %d\n", This, ptype, This->desc.picType);
374   *ptype = This->desc.picType;
375   return S_OK;
376 }
377
378 /************************************************************************
379  * OLEPictureImpl_get_Width
380  */ 
381 static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface,
382                                                OLE_XSIZE_HIMETRIC *pwidth)
383 {
384   ICOM_THIS(OLEPictureImpl, iface);
385   TRACE("(%p)->(%p): width is %ld\n", This, pwidth, This->himetricWidth);
386   *pwidth = This->himetricWidth;
387   return S_OK;
388 }
389
390 /************************************************************************
391  * OLEPictureImpl_get_Height
392  */ 
393 static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface,
394                                                 OLE_YSIZE_HIMETRIC *pheight)
395 {
396   ICOM_THIS(OLEPictureImpl, iface);
397   TRACE("(%p)->(%p): height is %ld\n", This, pheight, This->himetricHeight);
398   *pheight = This->himetricHeight;
399   return S_OK;
400 }
401
402 /************************************************************************
403  * OLEPictureImpl_Render
404  */ 
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,
411                                             LPCRECT prcWBounds)
412 {
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);
416   if(prcWBounds)
417     TRACE("prcWBounds (%d,%d) - (%d,%d)\n", prcWBounds->left, prcWBounds->top,
418           prcWBounds->right, prcWBounds->bottom);
419
420   switch(This->desc.picType) {
421   case PICTYPE_BITMAP:
422     {
423       HBITMAP hbmpOld;
424       HDC hdcBmp;
425
426       /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
427          NB y-axis gets flipped */
428
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);
435
436       hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap);
437
438       StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
439
440       SelectObject(hdcBmp, hbmpOld);
441       DeleteDC(hdcBmp);
442     }
443     break;
444
445   case PICTYPE_METAFILE:
446   case PICTYPE_ICON:
447   case PICTYPE_ENHMETAFILE:
448   default:
449     FIXME("type %d not implemented\n", This->desc.picType);
450     return E_NOTIMPL;
451   }
452
453   return S_OK;
454 }
455
456 /************************************************************************
457  * OLEPictureImpl_set_hPal
458  */ 
459 static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
460                                               OLE_HANDLE hpal)
461 {
462   ICOM_THIS(OLEPictureImpl, iface);
463   FIXME("(%p)->(%08x): stub\n", This, hpal);
464   return E_NOTIMPL;
465 }
466
467 /************************************************************************
468  * OLEPictureImpl_get_CurDC
469  */ 
470 static HRESULT WINAPI OLEPictureImpl_get_CurDC(IPicture *iface,
471                                                HDC *phdc)
472 {
473   ICOM_THIS(OLEPictureImpl, iface);
474   FIXME("(%p)->(%p): stub\n", This, phdc);
475   return E_NOTIMPL;
476 }
477
478 /************************************************************************
479  * OLEPictureImpl_SelectPicture
480  */ 
481 static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface,
482                                                    HDC hdcIn,
483                                                    HDC *phdcOut,
484                                                    OLE_HANDLE *phbmpOut)
485 {
486   ICOM_THIS(OLEPictureImpl, iface);
487   FIXME("(%p)->(%08x, %p, %p): stub\n", This, hdcIn, phdcOut, phbmpOut);
488   return E_NOTIMPL;
489 }
490
491 /************************************************************************
492  * OLEPictureImpl_get_KeepOriginalFormat
493  */ 
494 static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface,
495                                                             BOOL *pfKeep)
496 {
497   ICOM_THIS(OLEPictureImpl, iface);
498   FIXME("(%p)->(%p): stub\n", This, pfKeep);
499   return E_NOTIMPL;
500 }
501
502 /************************************************************************
503  * OLEPictureImpl_put_KeepOriginalFormat
504  */ 
505 static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface,
506                                                             BOOL keep)
507 {
508   ICOM_THIS(OLEPictureImpl, iface);
509   FIXME("(%p)->(%d): stub\n", This, keep);
510   return E_NOTIMPL;
511 }
512
513 /************************************************************************
514  * OLEPictureImpl_PictureChanged
515  */ 
516 static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface)
517 {
518   ICOM_THIS(OLEPictureImpl, iface);
519   FIXME("(%p)->(): stub\n", This);
520   return E_NOTIMPL;
521 }
522
523 /************************************************************************
524  * OLEPictureImpl_SaveAsFile
525  */ 
526 static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
527                                                 IStream *pstream,
528                                                 BOOL SaveMemCopy,
529                                                 LONG *pcbSize)
530 {
531   ICOM_THIS(OLEPictureImpl, iface);
532   FIXME("(%p)->(%p, %d, %p): stub\n", This, pstream, SaveMemCopy, pcbSize);
533   return E_NOTIMPL;
534 }
535
536 /************************************************************************
537  * OLEPictureImpl_get_Attributes
538  */ 
539 static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
540                                                     DWORD *pdwAttr)
541 {
542   ICOM_THIS(OLEPictureImpl, iface);
543   FIXME("(%p)->(%p): stub\n", This, pdwAttr);
544   return E_NOTIMPL;
545 }
546
547
548
549 /************************************************************************
550  *    IDispatch
551  */
552 /************************************************************************
553  * OLEPictureImpl_IDispatch_QueryInterface (IUnknown)
554  *
555  * See Windows documentation for more details on IUnknown methods.
556  */
557 static HRESULT WINAPI OLEPictureImpl_IDispatch_QueryInterface(
558   IDispatch* iface,
559   REFIID     riid,
560   VOID**     ppvoid)
561 {
562   ICOM_THIS_From_IDispatch(IPicture, iface);
563
564   return IPicture_QueryInterface(This, riid, ppvoid);
565 }
566
567 /************************************************************************
568  * OLEPictureImpl_IDispatch_AddRef (IUnknown)
569  *
570  * See Windows documentation for more details on IUnknown methods.
571  */
572 static ULONG WINAPI OLEPictureImpl_IDispatch_AddRef(
573   IDispatch* iface)
574 {
575   ICOM_THIS_From_IDispatch(IPicture, iface);
576
577   return IPicture_AddRef(This);
578 }
579
580 /************************************************************************
581  * OLEPictureImpl_IDispatch_Release (IUnknown)
582  *
583  * See Windows documentation for more details on IUnknown methods.
584  */
585 static ULONG WINAPI OLEPictureImpl_IDispatch_Release(
586   IDispatch* iface)
587 {
588   ICOM_THIS_From_IDispatch(IPicture, iface);
589
590   return IPicture_Release(This);
591 }
592
593 /************************************************************************
594  * OLEPictureImpl_GetTypeInfoCount (IDispatch)
595  *
596  * See Windows documentation for more details on IDispatch methods.
597  */
598 static HRESULT WINAPI OLEPictureImpl_GetTypeInfoCount(
599   IDispatch*    iface, 
600   unsigned int* pctinfo)
601 {
602   FIXME("():Stub\n");
603
604   return E_NOTIMPL;
605 }
606
607 /************************************************************************
608  * OLEPictureImpl_GetTypeInfo (IDispatch)
609  *
610  * See Windows documentation for more details on IDispatch methods.
611  */
612 static HRESULT WINAPI OLEPictureImpl_GetTypeInfo(
613   IDispatch*  iface, 
614   UINT      iTInfo,
615   LCID        lcid, 
616   ITypeInfo** ppTInfo)
617 {
618   FIXME("():Stub\n");
619
620   return E_NOTIMPL;
621 }
622
623 /************************************************************************
624  * OLEPictureImpl_GetIDsOfNames (IDispatch)
625  *
626  * See Windows documentation for more details on IDispatch methods.
627  */
628 static HRESULT WINAPI OLEPictureImpl_GetIDsOfNames(
629   IDispatch*  iface,
630   REFIID      riid, 
631   LPOLESTR* rgszNames, 
632   UINT      cNames, 
633   LCID        lcid,
634   DISPID*     rgDispId)
635 {
636   FIXME("():Stub\n");
637
638   return E_NOTIMPL;
639 }
640
641 /************************************************************************
642  * OLEPictureImpl_Invoke (IDispatch)
643  *
644  * See Windows documentation for more details on IDispatch methods.
645  */
646 static HRESULT WINAPI OLEPictureImpl_Invoke(
647   IDispatch*  iface,
648   DISPID      dispIdMember, 
649   REFIID      riid, 
650   LCID        lcid, 
651   WORD        wFlags,
652   DISPPARAMS* pDispParams,
653   VARIANT*    pVarResult, 
654   EXCEPINFO*  pExepInfo,
655   UINT*     puArgErr)
656 {
657   FIXME("():Stub\n");
658
659   return E_NOTIMPL;
660 }
661
662
663 static ICOM_VTABLE(IPicture) OLEPictureImpl_VTable =
664 {
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
683 };
684
685 static ICOM_VTABLE(IDispatch) OLEPictureImpl_IDispatch_VTable =
686 {
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
695 };
696
697 /***********************************************************************
698  * OleCreatePictureIndirect (OLEAUT32.419)
699  */
700 HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid,
701                             BOOL fOwn, LPVOID *ppvObj )
702 {
703   OLEPictureImpl* newPict = NULL;
704   HRESULT      hr         = S_OK;
705
706   TRACE("(%p,%p,%d,%p)\n", lpPictDesc, riid, fOwn, ppvObj);
707
708   /*
709    * Sanity check
710    */
711   if (ppvObj==0)
712     return E_POINTER;
713
714   *ppvObj = NULL;
715
716   /*
717    * Try to construct a new instance of the class.
718    */
719   newPict = OLEPictureImpl_Construct(lpPictDesc, fOwn);
720
721   if (newPict == NULL)
722     return E_OUTOFMEMORY;
723
724   /*
725    * Make sure it supports the interface required by the caller.
726    */
727   hr = IPicture_QueryInterface((IPicture*)newPict, riid, ppvObj);
728
729   /*
730    * Release the reference obtained in the constructor. If
731    * the QueryInterface was unsuccessful, it will free the class.
732    */
733   IPicture_Release((IPicture*)newPict);
734
735   return hr;
736 }
737
738
739 /***********************************************************************
740  * OleLoadPicture (OLEAUT32.418)
741  */
742 HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
743                             REFIID reed, LPVOID *ppvObj )
744 {
745   FIXME("(%p,%ld,%d,%p,%p), not implemented\n",
746         lpstream, lSize, fRunmode, reed, ppvObj);
747   return S_OK;
748 }
749
750 /***********************************************************************
751  * OleLoadPictureEx (OLEAUT32.425)
752  */
753 HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
754                             REFIID reed, DWORD xsiz, DWORD ysiz, DWORD flags, LPVOID *ppvObj )
755 {
756   FIXME("(%p,%ld,%d,%p,%lx,%lx,%lx,%p), not implemented\n",
757         lpstream, lSize, fRunmode, reed, xsiz, ysiz, flags, ppvObj);
758   return S_OK;
759 }
760