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