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