strmbase: Have BaseControlWindow use BaseDispatch.
[wine] / dlls / mshtml / htmlimg.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27
28 #include "wine/debug.h"
29
30 #include "mshtml_private.h"
31 #include "htmlevent.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
34
35 typedef struct {
36     HTMLElement element;
37
38     IHTMLImgElement IHTMLImgElement_iface;
39
40     nsIDOMHTMLImageElement *nsimg;
41 } HTMLImgElement;
42
43 static inline HTMLImgElement *impl_from_IHTMLImgElement(IHTMLImgElement *iface)
44 {
45     return CONTAINING_RECORD(iface, HTMLImgElement, IHTMLImgElement_iface);
46 }
47
48 static HRESULT WINAPI HTMLImgElement_QueryInterface(IHTMLImgElement *iface, REFIID riid, void **ppv)
49 {
50     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
51
52     return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
53 }
54
55 static ULONG WINAPI HTMLImgElement_AddRef(IHTMLImgElement *iface)
56 {
57     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
58
59     return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
60 }
61
62 static ULONG WINAPI HTMLImgElement_Release(IHTMLImgElement *iface)
63 {
64     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
65
66     return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
67 }
68
69 static HRESULT WINAPI HTMLImgElement_GetTypeInfoCount(IHTMLImgElement *iface, UINT *pctinfo)
70 {
71     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
72     return IDispatchEx_GetTypeInfoCount(&This->element.node.dispex.IDispatchEx_iface, pctinfo);
73 }
74
75 static HRESULT WINAPI HTMLImgElement_GetTypeInfo(IHTMLImgElement *iface, UINT iTInfo,
76                                               LCID lcid, ITypeInfo **ppTInfo)
77 {
78     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
79     return IDispatchEx_GetTypeInfo(&This->element.node.dispex.IDispatchEx_iface, iTInfo, lcid,
80             ppTInfo);
81 }
82
83 static HRESULT WINAPI HTMLImgElement_GetIDsOfNames(IHTMLImgElement *iface, REFIID riid,
84                                                 LPOLESTR *rgszNames, UINT cNames,
85                                                 LCID lcid, DISPID *rgDispId)
86 {
87     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
88     return IDispatchEx_GetIDsOfNames(&This->element.node.dispex.IDispatchEx_iface, riid, rgszNames,
89             cNames, lcid, rgDispId);
90 }
91
92 static HRESULT WINAPI HTMLImgElement_Invoke(IHTMLImgElement *iface, DISPID dispIdMember,
93                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
94                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
95 {
96     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
97     return IDispatchEx_Invoke(&This->element.node.dispex.IDispatchEx_iface, dispIdMember, riid,
98             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
99 }
100
101 static HRESULT WINAPI HTMLImgElement_put_isMap(IHTMLImgElement *iface, VARIANT_BOOL v)
102 {
103     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
104     FIXME("(%p)->(%x)\n", This, v);
105     return E_NOTIMPL;
106 }
107
108 static HRESULT WINAPI HTMLImgElement_get_isMap(IHTMLImgElement *iface, VARIANT_BOOL *p)
109 {
110     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
111     FIXME("(%p)->(%p)\n", This, p);
112     return E_NOTIMPL;
113 }
114
115 static HRESULT WINAPI HTMLImgElement_put_useMap(IHTMLImgElement *iface, BSTR v)
116 {
117     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
118     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
119     return E_NOTIMPL;
120 }
121
122 static HRESULT WINAPI HTMLImgElement_get_useMap(IHTMLImgElement *iface, BSTR *p)
123 {
124     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
125     FIXME("(%p)->(%p)\n", This, p);
126     return E_NOTIMPL;
127 }
128
129 static HRESULT WINAPI HTMLImgElement_get_mimeType(IHTMLImgElement *iface, BSTR *p)
130 {
131     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
132     FIXME("(%p)->(%p)\n", This, p);
133     return E_NOTIMPL;
134 }
135
136 static HRESULT WINAPI HTMLImgElement_get_fileSize(IHTMLImgElement *iface, BSTR *p)
137 {
138     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
139     FIXME("(%p)->(%p)\n", This, p);
140     return E_NOTIMPL;
141 }
142
143 static HRESULT WINAPI HTMLImgElement_get_fileCreatedDate(IHTMLImgElement *iface, BSTR *p)
144 {
145     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
146     FIXME("(%p)->(%p)\n", This, p);
147     return E_NOTIMPL;
148 }
149
150 static HRESULT WINAPI HTMLImgElement_get_fileModifiedDate(IHTMLImgElement *iface, BSTR *p)
151 {
152     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
153     FIXME("(%p)->(%p)\n", This, p);
154     return E_NOTIMPL;
155 }
156
157 static HRESULT WINAPI HTMLImgElement_get_fileUpdatedDate(IHTMLImgElement *iface, BSTR *p)
158 {
159     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
160     FIXME("(%p)->(%p)\n", This, p);
161     return E_NOTIMPL;
162 }
163
164 static HRESULT WINAPI HTMLImgElement_get_protocol(IHTMLImgElement *iface, BSTR *p)
165 {
166     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
167     FIXME("(%p)->(%p)\n", This, p);
168     return E_NOTIMPL;
169 }
170
171 static HRESULT WINAPI HTMLImgElement_get_href(IHTMLImgElement *iface, BSTR *p)
172 {
173     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
174     FIXME("(%p)->(%p)\n", This, p);
175     return E_NOTIMPL;
176 }
177
178 static HRESULT WINAPI HTMLImgElement_get_nameProp(IHTMLImgElement *iface, BSTR *p)
179 {
180     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
181     FIXME("(%p)->(%p)\n", This, p);
182     return E_NOTIMPL;
183 }
184
185 static HRESULT WINAPI HTMLImgElement_put_border(IHTMLImgElement *iface, VARIANT v)
186 {
187     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
188     FIXME("(%p)->()\n", This);
189     return E_NOTIMPL;
190 }
191
192 static HRESULT WINAPI HTMLImgElement_get_border(IHTMLImgElement *iface, VARIANT *p)
193 {
194     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
195     FIXME("(%p)->(%p)\n", This, p);
196     return E_NOTIMPL;
197 }
198
199 static HRESULT WINAPI HTMLImgElement_put_vspace(IHTMLImgElement *iface, LONG v)
200 {
201     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
202     FIXME("(%p)->(%d)\n", This, v);
203     return E_NOTIMPL;
204 }
205
206 static HRESULT WINAPI HTMLImgElement_get_vspace(IHTMLImgElement *iface, LONG *p)
207 {
208     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
209     FIXME("(%p)->(%p)\n", This, p);
210     return E_NOTIMPL;
211 }
212
213 static HRESULT WINAPI HTMLImgElement_put_hspace(IHTMLImgElement *iface, LONG v)
214 {
215     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
216     FIXME("(%p)->(%d)\n", This, v);
217     return E_NOTIMPL;
218 }
219
220 static HRESULT WINAPI HTMLImgElement_get_hspace(IHTMLImgElement *iface, LONG *p)
221 {
222     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
223     FIXME("(%p)->(%p)\n", This, p);
224     return E_NOTIMPL;
225 }
226
227 static HRESULT WINAPI HTMLImgElement_put_alt(IHTMLImgElement *iface, BSTR v)
228 {
229     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
230     nsAString alt_str;
231     nsresult nsres;
232
233     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
234
235     nsAString_InitDepend(&alt_str, v);
236     nsres = nsIDOMHTMLImageElement_SetAlt(This->nsimg, &alt_str);
237     nsAString_Finish(&alt_str);
238     if(NS_FAILED(nsres))
239         ERR("SetAlt failed: %08x\n", nsres);
240
241     return S_OK;
242 }
243
244 static HRESULT WINAPI HTMLImgElement_get_alt(IHTMLImgElement *iface, BSTR *p)
245 {
246     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
247     nsAString alt_str;
248     nsresult nsres;
249
250     TRACE("(%p)->(%p)\n", This, p);
251
252     nsAString_Init(&alt_str, NULL);
253     nsres = nsIDOMHTMLImageElement_GetAlt(This->nsimg, &alt_str);
254     return return_nsstr(nsres, &alt_str, p);
255 }
256
257 static HRESULT WINAPI HTMLImgElement_put_src(IHTMLImgElement *iface, BSTR v)
258 {
259     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
260     nsAString src_str;
261     nsresult nsres;
262
263     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
264
265     nsAString_InitDepend(&src_str, v);
266     nsres = nsIDOMHTMLImageElement_SetSrc(This->nsimg, &src_str);
267     nsAString_Finish(&src_str);
268     if(NS_FAILED(nsres))
269         ERR("SetSrc failed: %08x\n", nsres);
270
271     return NS_OK;
272 }
273
274 static HRESULT WINAPI HTMLImgElement_get_src(IHTMLImgElement *iface, BSTR *p)
275 {
276     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
277     const PRUnichar *src;
278     nsAString src_str;
279     nsresult nsres;
280     HRESULT hres = S_OK;
281
282     static const WCHAR blockedW[] = {'B','L','O','C','K','E','D',':',':',0};
283
284     TRACE("(%p)->(%p)\n", This, p);
285
286     nsAString_Init(&src_str, NULL);
287     nsres = nsIDOMHTMLImageElement_GetSrc(This->nsimg, &src_str);
288     if(NS_SUCCEEDED(nsres)) {
289         nsAString_GetData(&src_str, &src);
290
291         if(!strncmpiW(src, blockedW, sizeof(blockedW)/sizeof(WCHAR)-1)) {
292             TRACE("returning BLOCKED::\n");
293             *p = SysAllocString(blockedW);
294             if(!*p)
295                 hres = E_OUTOFMEMORY;
296         }else {
297             hres = nsuri_to_url(src, TRUE, p);
298         }
299     }else {
300         ERR("GetSrc failed: %08x\n", nsres);
301         hres = E_FAIL;
302     }
303
304     nsAString_Finish(&src_str);
305     return hres;
306 }
307
308 static HRESULT WINAPI HTMLImgElement_put_lowsrc(IHTMLImgElement *iface, BSTR v)
309 {
310     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
311     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
312     return E_NOTIMPL;
313 }
314
315 static HRESULT WINAPI HTMLImgElement_get_lowsrc(IHTMLImgElement *iface, BSTR *p)
316 {
317     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
318     FIXME("(%p)->(%p)\n", This, p);
319     return E_NOTIMPL;
320 }
321
322 static HRESULT WINAPI HTMLImgElement_put_vrml(IHTMLImgElement *iface, BSTR v)
323 {
324     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
325     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
326     return E_NOTIMPL;
327 }
328
329 static HRESULT WINAPI HTMLImgElement_get_vrml(IHTMLImgElement *iface, BSTR *p)
330 {
331     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
332     FIXME("(%p)->(%p)\n", This, p);
333     return E_NOTIMPL;
334 }
335
336 static HRESULT WINAPI HTMLImgElement_put_dynsrc(IHTMLImgElement *iface, BSTR v)
337 {
338     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
339     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
340     return E_NOTIMPL;
341 }
342
343 static HRESULT WINAPI HTMLImgElement_get_dynsrc(IHTMLImgElement *iface, BSTR *p)
344 {
345     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
346     FIXME("(%p)->(%p)\n", This, p);
347     return E_NOTIMPL;
348 }
349
350 static HRESULT WINAPI HTMLImgElement_get_readyState(IHTMLImgElement *iface, BSTR *p)
351 {
352     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
353     FIXME("(%p)->(%p)\n", This, p);
354     return E_NOTIMPL;
355 }
356
357 static HRESULT WINAPI HTMLImgElement_get_complete(IHTMLImgElement *iface, VARIANT_BOOL *p)
358 {
359     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
360     FIXME("(%p)->(%p)\n", This, p);
361     return E_NOTIMPL;
362 }
363
364 static HRESULT WINAPI HTMLImgElement_put_loop(IHTMLImgElement *iface, VARIANT v)
365 {
366     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
367     FIXME("(%p)->()\n", This);
368     return E_NOTIMPL;
369 }
370
371 static HRESULT WINAPI HTMLImgElement_get_loop(IHTMLImgElement *iface, VARIANT *p)
372 {
373     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
374     FIXME("(%p)->(%p)\n", This, p);
375     return E_NOTIMPL;
376 }
377
378 static HRESULT WINAPI HTMLImgElement_put_align(IHTMLImgElement *iface, BSTR v)
379 {
380     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
381     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
382     return E_NOTIMPL;
383 }
384
385 static HRESULT WINAPI HTMLImgElement_get_align(IHTMLImgElement *iface, BSTR *p)
386 {
387     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
388     FIXME("(%p)->(%p)\n", This, p);
389     return E_NOTIMPL;
390 }
391
392 static HRESULT WINAPI HTMLImgElement_put_onload(IHTMLImgElement *iface, VARIANT v)
393 {
394     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
395
396     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
397
398     return set_node_event(&This->element.node, EVENTID_LOAD, &v);
399 }
400
401 static HRESULT WINAPI HTMLImgElement_get_onload(IHTMLImgElement *iface, VARIANT *p)
402 {
403     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
404
405     TRACE("(%p)->(%p)\n", This, p);
406
407     return get_node_event(&This->element.node, EVENTID_LOAD, p);
408 }
409
410 static HRESULT WINAPI HTMLImgElement_put_onerror(IHTMLImgElement *iface, VARIANT v)
411 {
412     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
413
414     TRACE("(%p)->()\n", This);
415
416     return set_node_event(&This->element.node, EVENTID_ERROR, &v);
417 }
418
419 static HRESULT WINAPI HTMLImgElement_get_onerror(IHTMLImgElement *iface, VARIANT *p)
420 {
421     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
422
423     TRACE("(%p)->(%p)\n", This, p);
424
425     return get_node_event(&This->element.node, EVENTID_ERROR, p);
426 }
427
428 static HRESULT WINAPI HTMLImgElement_put_onabort(IHTMLImgElement *iface, VARIANT v)
429 {
430     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
431     FIXME("(%p)->()\n", This);
432     return E_NOTIMPL;
433 }
434
435 static HRESULT WINAPI HTMLImgElement_get_onabort(IHTMLImgElement *iface, VARIANT *p)
436 {
437     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
438     FIXME("(%p)->(%p)\n", This, p);
439     return E_NOTIMPL;
440 }
441
442 static HRESULT WINAPI HTMLImgElement_put_name(IHTMLImgElement *iface, BSTR v)
443 {
444     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
445     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
446     return E_NOTIMPL;
447 }
448
449 static HRESULT WINAPI HTMLImgElement_get_name(IHTMLImgElement *iface, BSTR *p)
450 {
451     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
452     nsAString name;
453     nsresult nsres;
454
455     TRACE("(%p)->(%p)\n", This, p);
456
457     nsAString_Init(&name, NULL);
458     nsres = nsIDOMHTMLImageElement_GetName(This->nsimg, &name);
459     return return_nsstr(nsres, &name, p);
460 }
461
462 static HRESULT WINAPI HTMLImgElement_put_width(IHTMLImgElement *iface, LONG v)
463 {
464     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
465     nsresult nsres;
466
467     TRACE("(%p)->(%d)\n", This, v);
468
469     nsres = nsIDOMHTMLImageElement_SetWidth(This->nsimg, v);
470     if(NS_FAILED(nsres)) {
471         ERR("SetWidth failed: %08x\n", nsres);
472         return E_FAIL;
473     }
474
475     return S_OK;
476 }
477
478 static HRESULT WINAPI HTMLImgElement_get_width(IHTMLImgElement *iface, LONG *p)
479 {
480     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
481     PRUint32 width;
482     nsresult nsres;
483
484     TRACE("(%p)->(%p)\n", This, p);
485
486     nsres = nsIDOMHTMLImageElement_GetWidth(This->nsimg, &width);
487     if(NS_FAILED(nsres)) {
488         ERR("GetWidth failed: %08x\n", nsres);
489         return E_FAIL;
490     }
491
492     *p = width;
493     return S_OK;
494 }
495
496 static HRESULT WINAPI HTMLImgElement_put_height(IHTMLImgElement *iface, LONG v)
497 {
498     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
499     nsresult nsres;
500
501     TRACE("(%p)->(%d)\n", This, v);
502
503     nsres = nsIDOMHTMLImageElement_SetHeight(This->nsimg, v);
504     if(NS_FAILED(nsres)) {
505         ERR("SetHeight failed: %08x\n", nsres);
506         return E_FAIL;
507     }
508
509     return S_OK;
510 }
511
512 static HRESULT WINAPI HTMLImgElement_get_height(IHTMLImgElement *iface, LONG *p)
513 {
514     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
515     PRUint32 height;
516     nsresult nsres;
517
518     TRACE("(%p)->(%p)\n", This, p);
519
520     nsres = nsIDOMHTMLImageElement_GetHeight(This->nsimg, &height);
521     if(NS_FAILED(nsres)) {
522         ERR("GetHeight failed: %08x\n", nsres);
523         return E_FAIL;
524     }
525
526     *p = height;
527     return S_OK;
528 }
529
530 static HRESULT WINAPI HTMLImgElement_put_start(IHTMLImgElement *iface, BSTR v)
531 {
532     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
533     FIXME("(%p)->()\n", This);
534     return E_NOTIMPL;
535 }
536
537 static HRESULT WINAPI HTMLImgElement_get_start(IHTMLImgElement *iface, BSTR *p)
538 {
539     HTMLImgElement *This = impl_from_IHTMLImgElement(iface);
540     FIXME("(%p)->(%p)\n", This, p);
541     return E_NOTIMPL;
542 }
543
544 static const IHTMLImgElementVtbl HTMLImgElementVtbl = {
545     HTMLImgElement_QueryInterface,
546     HTMLImgElement_AddRef,
547     HTMLImgElement_Release,
548     HTMLImgElement_GetTypeInfoCount,
549     HTMLImgElement_GetTypeInfo,
550     HTMLImgElement_GetIDsOfNames,
551     HTMLImgElement_Invoke,
552     HTMLImgElement_put_isMap,
553     HTMLImgElement_get_isMap,
554     HTMLImgElement_put_useMap,
555     HTMLImgElement_get_useMap,
556     HTMLImgElement_get_mimeType,
557     HTMLImgElement_get_fileSize,
558     HTMLImgElement_get_fileCreatedDate,
559     HTMLImgElement_get_fileModifiedDate,
560     HTMLImgElement_get_fileUpdatedDate,
561     HTMLImgElement_get_protocol,
562     HTMLImgElement_get_href,
563     HTMLImgElement_get_nameProp,
564     HTMLImgElement_put_border,
565     HTMLImgElement_get_border,
566     HTMLImgElement_put_vspace,
567     HTMLImgElement_get_vspace,
568     HTMLImgElement_put_hspace,
569     HTMLImgElement_get_hspace,
570     HTMLImgElement_put_alt,
571     HTMLImgElement_get_alt,
572     HTMLImgElement_put_src,
573     HTMLImgElement_get_src,
574     HTMLImgElement_put_lowsrc,
575     HTMLImgElement_get_lowsrc,
576     HTMLImgElement_put_vrml,
577     HTMLImgElement_get_vrml,
578     HTMLImgElement_put_dynsrc,
579     HTMLImgElement_get_dynsrc,
580     HTMLImgElement_get_readyState,
581     HTMLImgElement_get_complete,
582     HTMLImgElement_put_loop,
583     HTMLImgElement_get_loop,
584     HTMLImgElement_put_align,
585     HTMLImgElement_get_align,
586     HTMLImgElement_put_onload,
587     HTMLImgElement_get_onload,
588     HTMLImgElement_put_onerror,
589     HTMLImgElement_get_onerror,
590     HTMLImgElement_put_onabort,
591     HTMLImgElement_get_onabort,
592     HTMLImgElement_put_name,
593     HTMLImgElement_get_name,
594     HTMLImgElement_put_width,
595     HTMLImgElement_get_width,
596     HTMLImgElement_put_height,
597     HTMLImgElement_get_height,
598     HTMLImgElement_put_start,
599     HTMLImgElement_get_start
600 };
601
602 static inline HTMLImgElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
603 {
604     return CONTAINING_RECORD(iface, HTMLImgElement, element.node);
605 }
606
607 static HRESULT HTMLImgElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
608 {
609     HTMLImgElement *This = impl_from_HTMLDOMNode(iface);
610
611     *ppv = NULL;
612
613     if(IsEqualGUID(&IID_IHTMLImgElement, riid)) {
614         TRACE("(%p)->(IID_IHTMLImgElement %p)\n", This, ppv);
615         *ppv = &This->IHTMLImgElement_iface;
616     }else {
617         return HTMLElement_QI(&This->element.node, riid, ppv);
618     }
619
620     IUnknown_AddRef((IUnknown*)*ppv);
621     return S_OK;
622 }
623
624 static void HTMLImgElement_destructor(HTMLDOMNode *iface)
625 {
626     HTMLImgElement *This = impl_from_HTMLDOMNode(iface);
627
628     if(This->nsimg)
629         nsIDOMHTMLImageElement_Release(This->nsimg);
630
631     HTMLElement_destructor(&This->element.node);
632 }
633
634 static HRESULT HTMLImgElement_get_readystate(HTMLDOMNode *iface, BSTR *p)
635 {
636     HTMLImgElement *This = impl_from_HTMLDOMNode(iface);
637
638     return IHTMLImgElement_get_readyState(&This->IHTMLImgElement_iface, p);
639 }
640
641 static const NodeImplVtbl HTMLImgElementImplVtbl = {
642     HTMLImgElement_QI,
643     HTMLImgElement_destructor,
644     HTMLElement_clone,
645     HTMLElement_get_attr_col,
646     NULL,
647     NULL,
648     NULL,
649     NULL,
650     NULL,
651     NULL,
652     HTMLImgElement_get_readystate
653 };
654
655 static const tid_t HTMLImgElement_iface_tids[] = {
656     HTMLELEMENT_TIDS,
657     IHTMLImgElement_tid,
658     0
659 };
660 static dispex_static_data_t HTMLImgElement_dispex = {
661     NULL,
662     DispHTMLImg_tid,
663     NULL,
664     HTMLImgElement_iface_tids
665 };
666
667 HRESULT HTMLImgElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
668 {
669     HTMLImgElement *ret;
670     nsresult nsres;
671
672     ret = heap_alloc_zero(sizeof(HTMLImgElement));
673     if(!ret)
674         return E_OUTOFMEMORY;
675
676     ret->IHTMLImgElement_iface.lpVtbl = &HTMLImgElementVtbl;
677     ret->element.node.vtbl = &HTMLImgElementImplVtbl;
678
679     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLImageElement, (void**)&ret->nsimg);
680     if(NS_FAILED(nsres)) {
681         ERR("Could not get nsIDOMHTMLImageElement: %08x\n", nsres);
682         heap_free(ret);
683         return E_FAIL;
684     }
685
686     HTMLElement_Init(&ret->element, doc, nselem, &HTMLImgElement_dispex);
687
688     *elem = &ret->element;
689     return S_OK;
690 }
691
692 static inline HTMLImageElementFactory *impl_from_IHTMLImageElementFactory(IHTMLImageElementFactory *iface)
693 {
694     return CONTAINING_RECORD(iface, HTMLImageElementFactory, IHTMLImageElementFactory_iface);
695 }
696
697 static HRESULT WINAPI HTMLImageElementFactory_QueryInterface(IHTMLImageElementFactory *iface,
698         REFIID riid, void **ppv)
699 {
700     HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
701
702     *ppv = NULL;
703
704     if(IsEqualGUID(&IID_IUnknown, riid)) {
705         TRACE("(%p)->(IID_Unknown %p)\n", This, ppv);
706         *ppv = &This->IHTMLImageElementFactory_iface;
707     }else if(IsEqualGUID(&IID_IHTMLImageElementFactory, riid)) {
708         TRACE("(%p)->(IID_IHTMLImageElementFactory %p)\n", This, ppv);
709         *ppv = &This->IHTMLImageElementFactory_iface;
710     }else if(dispex_query_interface(&This->dispex, riid, ppv))
711         return *ppv ? S_OK : E_NOINTERFACE;
712
713     if(*ppv) {
714         IUnknown_AddRef((IUnknown*)*ppv);
715         return S_OK;
716     }
717
718     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
719     return E_NOINTERFACE;
720 }
721
722 static ULONG WINAPI HTMLImageElementFactory_AddRef(IHTMLImageElementFactory *iface)
723 {
724     HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
725     LONG ref = InterlockedIncrement(&This->ref);
726
727     TRACE("(%p) ref=%d\n", This, ref);
728
729     return ref;
730 }
731
732 static ULONG WINAPI HTMLImageElementFactory_Release(IHTMLImageElementFactory *iface)
733 {
734     HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
735     LONG ref = InterlockedDecrement(&This->ref);
736
737     TRACE("(%p) ref=%d\n", This, ref);
738
739     if(!ref)
740         heap_free(This);
741
742     return ref;
743 }
744
745 static HRESULT WINAPI HTMLImageElementFactory_GetTypeInfoCount(IHTMLImageElementFactory *iface,
746         UINT *pctinfo)
747 {
748     HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
749     FIXME("(%p)->(%p)\n", This, pctinfo);
750     return E_NOTIMPL;
751 }
752
753 static HRESULT WINAPI HTMLImageElementFactory_GetTypeInfo(IHTMLImageElementFactory *iface,
754         UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
755 {
756     HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
757     FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
758     return E_NOTIMPL;
759 }
760
761 static HRESULT WINAPI HTMLImageElementFactory_GetIDsOfNames(IHTMLImageElementFactory *iface,
762         REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
763         DISPID *rgDispId)
764 {
765     HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
766     FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames,
767             cNames, lcid, rgDispId);
768     return E_NOTIMPL;
769 }
770
771 static HRESULT WINAPI HTMLImageElementFactory_Invoke(IHTMLImageElementFactory *iface,
772         DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
773         DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
774         UINT *puArgErr)
775 {
776     HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
777     FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
778             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
779     return E_NOTIMPL;
780 }
781
782 static LONG var_to_size(const VARIANT *v)
783 {
784     switch(V_VT(v)) {
785     case VT_EMPTY:
786         return 0;
787     case VT_I4:
788         return V_I4(v);
789     case VT_BSTR: {
790         LONG ret;
791         HRESULT hres;
792
793         hres = VarI4FromStr(V_BSTR(v), 0, 0, &ret);
794         if(FAILED(hres)) {
795             FIXME("VarI4FromStr failed: %08x\n", hres);
796             return 0;
797         }
798         return ret;
799     }
800     default:
801         FIXME("unsupported size %s\n", debugstr_variant(v));
802     }
803     return 0;
804 }
805
806 static HRESULT WINAPI HTMLImageElementFactory_create(IHTMLImageElementFactory *iface,
807         VARIANT width, VARIANT height, IHTMLImgElement **img_elem)
808 {
809     HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface);
810     IHTMLImgElement *img;
811     HTMLElement *elem;
812     nsIDOMHTMLElement *nselem;
813     LONG l;
814     HRESULT hres;
815
816     static const PRUnichar imgW[] = {'I','M','G',0};
817
818     TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&width),
819             debugstr_variant(&height), img_elem);
820
821     if(!This->window || !This->window->doc) {
822         WARN("NULL doc\n");
823         return E_UNEXPECTED;
824     }
825
826     *img_elem = NULL;
827
828     hres = create_nselem(This->window->doc, imgW, &nselem);
829     if(FAILED(hres))
830         return hres;
831
832     hres = HTMLElement_Create(This->window->doc, (nsIDOMNode*)nselem, FALSE, &elem);
833     nsIDOMHTMLElement_Release(nselem);
834     if(FAILED(hres)) {
835         ERR("HTMLElement_Create failed\n");
836         return hres;
837     }
838
839     hres = IHTMLElement_QueryInterface(&elem->IHTMLElement_iface, &IID_IHTMLImgElement,
840             (void**)&img);
841     if(FAILED(hres)) {
842         ERR("IHTMLElement_QueryInterface failed: 0x%08x\n", hres);
843         return hres;
844     }
845
846     l = var_to_size(&width);
847     if(l)
848         IHTMLImgElement_put_width(img, l);
849     l = var_to_size(&height);
850     if(l)
851         IHTMLImgElement_put_height(img, l);
852
853     *img_elem = img;
854     return S_OK;
855 }
856
857 static const IHTMLImageElementFactoryVtbl HTMLImageElementFactoryVtbl = {
858     HTMLImageElementFactory_QueryInterface,
859     HTMLImageElementFactory_AddRef,
860     HTMLImageElementFactory_Release,
861     HTMLImageElementFactory_GetTypeInfoCount,
862     HTMLImageElementFactory_GetTypeInfo,
863     HTMLImageElementFactory_GetIDsOfNames,
864     HTMLImageElementFactory_Invoke,
865     HTMLImageElementFactory_create
866 };
867
868 static inline HTMLImageElementFactory *impl_from_DispatchEx(DispatchEx *iface)
869 {
870     return CONTAINING_RECORD(iface, HTMLImageElementFactory, dispex);
871 }
872
873 static HRESULT HTMLImageElementFactory_value(DispatchEx *dispex, LCID lcid,
874         WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei,
875         IServiceProvider *caller)
876 {
877     HTMLImageElementFactory *This = impl_from_DispatchEx(dispex);
878     IHTMLImgElement *img;
879     VARIANT empty, *width, *height;
880     HRESULT hres;
881     int argc = params->cArgs - params->cNamedArgs;
882
883     V_VT(res) = VT_NULL;
884
885     V_VT(&empty) = VT_EMPTY;
886
887     width = argc >= 1 ? params->rgvarg + (params->cArgs - 1) : &empty;
888     height = argc >= 2 ? params->rgvarg + (params->cArgs - 2) : &empty;
889
890     hres = IHTMLImageElementFactory_create(&This->IHTMLImageElementFactory_iface, *width, *height,
891             &img);
892     if(FAILED(hres))
893         return hres;
894
895     V_VT(res) = VT_DISPATCH;
896     V_DISPATCH(res) = (IDispatch*)img;
897
898     return S_OK;
899 }
900
901 static const tid_t HTMLImageElementFactory_iface_tids[] = {
902     IHTMLImageElementFactory_tid,
903     0
904 };
905
906 static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = {
907     HTMLImageElementFactory_value,
908     NULL,
909     NULL,
910     NULL
911 };
912
913 static dispex_static_data_t HTMLImageElementFactory_dispex = {
914     &HTMLImageElementFactory_dispex_vtbl,
915     IHTMLImageElementFactory_tid,
916     NULL,
917     HTMLImageElementFactory_iface_tids
918 };
919
920 HTMLImageElementFactory *HTMLImageElementFactory_Create(HTMLWindow *window)
921 {
922     HTMLImageElementFactory *ret;
923
924     ret = heap_alloc(sizeof(HTMLImageElementFactory));
925
926     ret->IHTMLImageElementFactory_iface.lpVtbl = &HTMLImageElementFactoryVtbl;
927     ret->ref = 1;
928     ret->window = window;
929
930     init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLImageElementFactory_iface,
931             &HTMLImageElementFactory_dispex);
932
933     return ret;
934 }