atl80: Added AtlComModuleRegisterServer implementation (based on AtlModuleRegisterSer...
[wine] / dlls / mshtml / htmliframe.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 "mshtml_private.h"
29
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
33
34 typedef struct {
35     HTMLFrameBase framebase;
36     IHTMLIFrameElement IHTMLIFrameElement_iface;
37     IHTMLIFrameElement2 IHTMLIFrameElement2_iface;
38     IHTMLIFrameElement3 IHTMLIFrameElement3_iface;
39 } HTMLIFrame;
40
41 static inline HTMLIFrame *impl_from_IHTMLIFrameElement(IHTMLIFrameElement *iface)
42 {
43     return CONTAINING_RECORD(iface, HTMLIFrame, IHTMLIFrameElement_iface);
44 }
45
46 static HRESULT WINAPI HTMLIFrameElement_QueryInterface(IHTMLIFrameElement *iface,
47         REFIID riid, void **ppv)
48 {
49     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
50
51     return IHTMLDOMNode_QueryInterface(&This->framebase.element.node.IHTMLDOMNode_iface, riid, ppv);
52 }
53
54 static ULONG WINAPI HTMLIFrameElement_AddRef(IHTMLIFrameElement *iface)
55 {
56     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
57
58     return IHTMLDOMNode_AddRef(&This->framebase.element.node.IHTMLDOMNode_iface);
59 }
60
61 static ULONG WINAPI HTMLIFrameElement_Release(IHTMLIFrameElement *iface)
62 {
63     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
64
65     return IHTMLDOMNode_Release(&This->framebase.element.node.IHTMLDOMNode_iface);
66 }
67
68 static HRESULT WINAPI HTMLIFrameElement_GetTypeInfoCount(IHTMLIFrameElement *iface, UINT *pctinfo)
69 {
70     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
71     return IDispatchEx_GetTypeInfoCount(&This->framebase.element.node.dispex.IDispatchEx_iface,
72             pctinfo);
73 }
74
75 static HRESULT WINAPI HTMLIFrameElement_GetTypeInfo(IHTMLIFrameElement *iface, UINT iTInfo,
76         LCID lcid, ITypeInfo **ppTInfo)
77 {
78     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
79     return IDispatchEx_GetTypeInfo(&This->framebase.element.node.dispex.IDispatchEx_iface, iTInfo,
80             lcid, ppTInfo);
81 }
82
83 static HRESULT WINAPI HTMLIFrameElement_GetIDsOfNames(IHTMLIFrameElement *iface, REFIID riid,
84         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
85 {
86     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
87     return IDispatchEx_GetIDsOfNames(&This->framebase.element.node.dispex.IDispatchEx_iface, riid,
88             rgszNames, cNames, lcid, rgDispId);
89 }
90
91 static HRESULT WINAPI HTMLIFrameElement_Invoke(IHTMLIFrameElement *iface, DISPID dispIdMember,
92         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
93         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
94 {
95     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
96     return IDispatchEx_Invoke(&This->framebase.element.node.dispex.IDispatchEx_iface, dispIdMember,
97             riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
98 }
99
100 static HRESULT WINAPI HTMLIFrameElement_put_vspace(IHTMLIFrameElement *iface, LONG v)
101 {
102     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
103     FIXME("(%p)->(%d)\n", This, v);
104     return E_NOTIMPL;
105 }
106
107 static HRESULT WINAPI HTMLIFrameElement_get_vspace(IHTMLIFrameElement *iface, LONG *p)
108 {
109     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
110     FIXME("(%p)->(%p)\n", This, p);
111     return E_NOTIMPL;
112 }
113
114 static HRESULT WINAPI HTMLIFrameElement_put_hspace(IHTMLIFrameElement *iface, LONG v)
115 {
116     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
117     FIXME("(%p)->(%d)\n", This, v);
118     return E_NOTIMPL;
119 }
120
121 static HRESULT WINAPI HTMLIFrameElement_get_hspace(IHTMLIFrameElement *iface, LONG *p)
122 {
123     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
124     FIXME("(%p)->(%p)\n", This, p);
125     return E_NOTIMPL;
126 }
127
128 static HRESULT WINAPI HTMLIFrameElement_put_align(IHTMLIFrameElement *iface, BSTR v)
129 {
130     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
131     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
132     return E_NOTIMPL;
133 }
134
135 static HRESULT WINAPI HTMLIFrameElement_get_align(IHTMLIFrameElement *iface, BSTR *p)
136 {
137     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
138     FIXME("(%p)->(%p)\n", This, p);
139     return E_NOTIMPL;
140 }
141
142 static const IHTMLIFrameElementVtbl HTMLIFrameElementVtbl = {
143     HTMLIFrameElement_QueryInterface,
144     HTMLIFrameElement_AddRef,
145     HTMLIFrameElement_Release,
146     HTMLIFrameElement_GetTypeInfoCount,
147     HTMLIFrameElement_GetTypeInfo,
148     HTMLIFrameElement_GetIDsOfNames,
149     HTMLIFrameElement_Invoke,
150     HTMLIFrameElement_put_vspace,
151     HTMLIFrameElement_get_vspace,
152     HTMLIFrameElement_put_hspace,
153     HTMLIFrameElement_get_hspace,
154     HTMLIFrameElement_put_align,
155     HTMLIFrameElement_get_align
156 };
157
158 static inline HTMLIFrame *impl_from_IHTMLIFrameElement2(IHTMLIFrameElement2 *iface)
159 {
160     return CONTAINING_RECORD(iface, HTMLIFrame, IHTMLIFrameElement2_iface);
161 }
162
163 static HRESULT WINAPI HTMLIFrameElement2_QueryInterface(IHTMLIFrameElement2 *iface,
164         REFIID riid, void **ppv)
165 {
166     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
167
168     return IHTMLDOMNode_QueryInterface(&This->framebase.element.node.IHTMLDOMNode_iface, riid, ppv);
169 }
170
171 static ULONG WINAPI HTMLIFrameElement2_AddRef(IHTMLIFrameElement2 *iface)
172 {
173     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
174
175     return IHTMLDOMNode_AddRef(&This->framebase.element.node.IHTMLDOMNode_iface);
176 }
177
178 static ULONG WINAPI HTMLIFrameElement2_Release(IHTMLIFrameElement2 *iface)
179 {
180     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
181
182     return IHTMLDOMNode_Release(&This->framebase.element.node.IHTMLDOMNode_iface);
183 }
184
185 static HRESULT WINAPI HTMLIFrameElement2_GetTypeInfoCount(IHTMLIFrameElement2 *iface, UINT *pctinfo)
186 {
187     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
188     return IDispatchEx_GetTypeInfoCount(&This->framebase.element.node.dispex.IDispatchEx_iface,
189             pctinfo);
190 }
191
192 static HRESULT WINAPI HTMLIFrameElement2_GetTypeInfo(IHTMLIFrameElement2 *iface, UINT iTInfo,
193         LCID lcid, ITypeInfo **ppTInfo)
194 {
195     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
196     return IDispatchEx_GetTypeInfo(&This->framebase.element.node.dispex.IDispatchEx_iface, iTInfo,
197             lcid, ppTInfo);
198 }
199
200 static HRESULT WINAPI HTMLIFrameElement2_GetIDsOfNames(IHTMLIFrameElement2 *iface, REFIID riid,
201         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
202 {
203     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
204     return IDispatchEx_GetIDsOfNames(&This->framebase.element.node.dispex.IDispatchEx_iface, riid,
205             rgszNames, cNames, lcid, rgDispId);
206 }
207
208 static HRESULT WINAPI HTMLIFrameElement2_Invoke(IHTMLIFrameElement2 *iface, DISPID dispIdMember,
209         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
210         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
211 {
212     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
213     return IDispatchEx_Invoke(&This->framebase.element.node.dispex.IDispatchEx_iface, dispIdMember,
214             riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
215 }
216
217 static HRESULT WINAPI HTMLIFrameElement2_put_height(IHTMLIFrameElement2 *iface, VARIANT v)
218 {
219     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
220     nsAString nsstr;
221     nsresult nsres;
222
223     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
224
225     if(V_VT(&v) != VT_BSTR) {
226         FIXME("Unsupported %s\n", debugstr_variant(&v));
227         return E_NOTIMPL;
228     }
229
230     nsAString_InitDepend(&nsstr, V_BSTR(&v));
231     nsres = nsIDOMHTMLIFrameElement_SetHeight(This->framebase.nsiframe, &nsstr);
232     nsAString_Finish(&nsstr);
233     if(NS_FAILED(nsres)) {
234         ERR("SetHeight failed: %08x\n", nsres);
235         return E_FAIL;
236     }
237
238     return S_OK;
239 }
240
241 static HRESULT WINAPI HTMLIFrameElement2_get_height(IHTMLIFrameElement2 *iface, VARIANT *p)
242 {
243     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
244     nsAString nsstr;
245     nsresult nsres;
246
247     TRACE("(%p)->(%p)\n", This, p);
248
249     nsAString_Init(&nsstr, NULL);
250     nsres = nsIDOMHTMLIFrameElement_GetHeight(This->framebase.nsiframe, &nsstr);
251
252     V_VT(p) = VT_BSTR;
253     return return_nsstr(nsres, &nsstr, &V_BSTR(p));
254 }
255
256 static HRESULT WINAPI HTMLIFrameElement2_put_width(IHTMLIFrameElement2 *iface, VARIANT v)
257 {
258     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
259     nsAString nsstr;
260     nsresult nsres;
261
262     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
263
264     if(V_VT(&v) != VT_BSTR) {
265         FIXME("Unsupported %s\n", debugstr_variant(&v));
266         return E_NOTIMPL;
267     }
268
269     nsAString_InitDepend(&nsstr, V_BSTR(&v));
270     nsres = nsIDOMHTMLIFrameElement_SetWidth(This->framebase.nsiframe, &nsstr);
271     nsAString_Finish(&nsstr);
272     if(NS_FAILED(nsres)) {
273         ERR("SetWidth failed: %08x\n", nsres);
274         return E_FAIL;
275     }
276
277     return S_OK;
278 }
279
280 static HRESULT WINAPI HTMLIFrameElement2_get_width(IHTMLIFrameElement2 *iface, VARIANT *p)
281 {
282     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
283     nsAString nsstr;
284     nsresult nsres;
285
286     TRACE("(%p)->(%p)\n", This, p);
287
288     nsAString_Init(&nsstr, NULL);
289     nsres = nsIDOMHTMLIFrameElement_GetWidth(This->framebase.nsiframe, &nsstr);
290
291     V_VT(p) = VT_BSTR;
292     return return_nsstr(nsres, &nsstr, &V_BSTR(p));
293 }
294
295 static const IHTMLIFrameElement2Vtbl HTMLIFrameElement2Vtbl = {
296     HTMLIFrameElement2_QueryInterface,
297     HTMLIFrameElement2_AddRef,
298     HTMLIFrameElement2_Release,
299     HTMLIFrameElement2_GetTypeInfoCount,
300     HTMLIFrameElement2_GetTypeInfo,
301     HTMLIFrameElement2_GetIDsOfNames,
302     HTMLIFrameElement2_Invoke,
303     HTMLIFrameElement2_put_height,
304     HTMLIFrameElement2_get_height,
305     HTMLIFrameElement2_put_width,
306     HTMLIFrameElement2_get_width
307 };
308
309 static inline HTMLIFrame *impl_from_IHTMLIFrameElement3(IHTMLIFrameElement3 *iface)
310 {
311     return CONTAINING_RECORD(iface, HTMLIFrame, IHTMLIFrameElement3_iface);
312 }
313
314 static HRESULT WINAPI HTMLIFrameElement3_QueryInterface(IHTMLIFrameElement3 *iface,
315         REFIID riid, void **ppv)
316 {
317     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
318
319     return IHTMLDOMNode_QueryInterface(&This->framebase.element.node.IHTMLDOMNode_iface, riid, ppv);
320 }
321
322 static ULONG WINAPI HTMLIFrameElement3_AddRef(IHTMLIFrameElement3 *iface)
323 {
324     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
325
326     return IHTMLDOMNode_AddRef(&This->framebase.element.node.IHTMLDOMNode_iface);
327 }
328
329 static ULONG WINAPI HTMLIFrameElement3_Release(IHTMLIFrameElement3 *iface)
330 {
331     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
332
333     return IHTMLDOMNode_Release(&This->framebase.element.node.IHTMLDOMNode_iface);
334 }
335
336 static HRESULT WINAPI HTMLIFrameElement3_GetTypeInfoCount(IHTMLIFrameElement3 *iface, UINT *pctinfo)
337 {
338     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
339     return IDispatchEx_GetTypeInfoCount(&This->framebase.element.node.dispex.IDispatchEx_iface,
340             pctinfo);
341 }
342
343 static HRESULT WINAPI HTMLIFrameElement3_GetTypeInfo(IHTMLIFrameElement3 *iface, UINT iTInfo,
344         LCID lcid, ITypeInfo **ppTInfo)
345 {
346     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
347     return IDispatchEx_GetTypeInfo(&This->framebase.element.node.dispex.IDispatchEx_iface, iTInfo,
348             lcid, ppTInfo);
349 }
350
351 static HRESULT WINAPI HTMLIFrameElement3_GetIDsOfNames(IHTMLIFrameElement3 *iface, REFIID riid,
352         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
353 {
354     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
355     return IDispatchEx_GetIDsOfNames(&This->framebase.element.node.dispex.IDispatchEx_iface, riid,
356             rgszNames, cNames, lcid, rgDispId);
357 }
358
359 static HRESULT WINAPI HTMLIFrameElement3_Invoke(IHTMLIFrameElement3 *iface, DISPID dispIdMember,
360         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
361         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
362 {
363     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
364     return IDispatchEx_Invoke(&This->framebase.element.node.dispex.IDispatchEx_iface, dispIdMember,
365             riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
366 }
367
368 static HRESULT WINAPI HTMLIFrameElement3_get_contentDocument(IHTMLIFrameElement3 *iface, IDispatch **p)
369 {
370     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
371     IHTMLDocument2 *doc;
372     HRESULT hres;
373
374     TRACE("(%p)->(%p)\n", This, p);
375
376     if(!This->framebase.content_window) {
377         *p = NULL;
378         return S_OK;
379     }
380
381     hres = IHTMLWindow2_get_document(&This->framebase.content_window->base.IHTMLWindow2_iface, &doc);
382     *p = (IDispatch*)doc;
383     return hres;
384 }
385
386 static HRESULT WINAPI HTMLIFrameElement3_put_src(IHTMLIFrameElement3 *iface, BSTR v)
387 {
388     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
389     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
390     return E_NOTIMPL;
391 }
392
393 static HRESULT WINAPI HTMLIFrameElement3_get_src(IHTMLIFrameElement3 *iface, BSTR *p)
394 {
395     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
396     FIXME("(%p)->(%p)\n", This, p);
397     return E_NOTIMPL;
398 }
399
400 static HRESULT WINAPI HTMLIFrameElement3_put_longDesc(IHTMLIFrameElement3 *iface, BSTR v)
401 {
402     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
403     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
404     return E_NOTIMPL;
405 }
406
407 static HRESULT WINAPI HTMLIFrameElement3_get_longDesc(IHTMLIFrameElement3 *iface, BSTR *p)
408 {
409     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
410     FIXME("(%p)->(%p)\n", This, p);
411     return E_NOTIMPL;
412 }
413
414 static HRESULT WINAPI HTMLIFrameElement3_put_frameBorder(IHTMLIFrameElement3 *iface, BSTR v)
415 {
416     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
417     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
418     return E_NOTIMPL;
419 }
420
421 static HRESULT WINAPI HTMLIFrameElement3_get_frameBorder(IHTMLIFrameElement3 *iface, BSTR *p)
422 {
423     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
424     FIXME("(%p)->(%p)\n", This, p);
425     return E_NOTIMPL;
426 }
427
428 static const IHTMLIFrameElement3Vtbl HTMLIFrameElement3Vtbl = {
429     HTMLIFrameElement3_QueryInterface,
430     HTMLIFrameElement3_AddRef,
431     HTMLIFrameElement3_Release,
432     HTMLIFrameElement3_GetTypeInfoCount,
433     HTMLIFrameElement3_GetTypeInfo,
434     HTMLIFrameElement3_GetIDsOfNames,
435     HTMLIFrameElement3_Invoke,
436     HTMLIFrameElement3_get_contentDocument,
437     HTMLIFrameElement3_put_src,
438     HTMLIFrameElement3_get_src,
439     HTMLIFrameElement3_put_longDesc,
440     HTMLIFrameElement3_get_longDesc,
441     HTMLIFrameElement3_put_frameBorder,
442     HTMLIFrameElement3_get_frameBorder
443 };
444
445 static inline HTMLIFrame *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
446 {
447     return CONTAINING_RECORD(iface, HTMLIFrame, framebase.element.node);
448 }
449
450 static HRESULT HTMLIFrame_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
451 {
452     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
453
454     if(IsEqualGUID(&IID_IHTMLIFrameElement, riid)) {
455         TRACE("(%p)->(IID_IHTMLIFrameElement %p)\n", This, ppv);
456         *ppv = &This->IHTMLIFrameElement_iface;
457     }else if(IsEqualGUID(&IID_IHTMLIFrameElement2, riid)) {
458         TRACE("(%p)->(IID_IHTMLIFrameElement2 %p)\n", This, ppv);
459         *ppv = &This->IHTMLIFrameElement2_iface;
460     }else if(IsEqualGUID(&IID_IHTMLIFrameElement3, riid)) {
461         TRACE("(%p)->(IID_IHTMLIFrameElement3 %p)\n", This, ppv);
462         *ppv = &This->IHTMLIFrameElement3_iface;
463     }else {
464         return HTMLFrameBase_QI(&This->framebase, riid, ppv);
465     }
466
467     IUnknown_AddRef((IUnknown*)*ppv);
468     return S_OK;
469 }
470
471 static void HTMLIFrame_destructor(HTMLDOMNode *iface)
472 {
473     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
474
475     HTMLFrameBase_destructor(&This->framebase);
476 }
477
478 static HRESULT HTMLIFrame_get_document(HTMLDOMNode *iface, IDispatch **p)
479 {
480     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
481
482     if(!This->framebase.content_window || !This->framebase.content_window->base.inner_window->doc) {
483         *p = NULL;
484         return S_OK;
485     }
486
487     *p = (IDispatch*)&This->framebase.content_window->base.inner_window->doc->basedoc.IHTMLDocument2_iface;
488     IDispatch_AddRef(*p);
489     return S_OK;
490 }
491
492 static HRESULT HTMLIFrame_get_dispid(HTMLDOMNode *iface, BSTR name,
493         DWORD grfdex, DISPID *pid)
494 {
495     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
496
497     if(!This->framebase.content_window)
498         return DISP_E_UNKNOWNNAME;
499
500     return search_window_props(This->framebase.content_window->base.inner_window, name, grfdex, pid);
501 }
502
503 static HRESULT HTMLIFrame_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid,
504         WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
505 {
506     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
507
508     if(!This->framebase.content_window) {
509         ERR("no content window to invoke on\n");
510         return E_FAIL;
511     }
512
513     return IDispatchEx_InvokeEx(&This->framebase.content_window->base.IDispatchEx_iface, id, lcid,
514             flags, params, res, ei, caller);
515 }
516
517 static HRESULT HTMLIFrame_get_readystate(HTMLDOMNode *iface, BSTR *p)
518 {
519     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
520
521     return IHTMLFrameBase2_get_readyState(&This->framebase.IHTMLFrameBase2_iface, p);
522 }
523
524 static HRESULT HTMLIFrame_bind_to_tree(HTMLDOMNode *iface)
525 {
526     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
527     nsIDOMDocument *nsdoc;
528     nsresult nsres;
529     HRESULT hres;
530
531     nsres = nsIDOMHTMLIFrameElement_GetContentDocument(This->framebase.nsiframe, &nsdoc);
532     if(NS_FAILED(nsres) || !nsdoc) {
533         ERR("GetContentDocument failed: %08x\n", nsres);
534         return E_FAIL;
535     }
536
537     hres = set_frame_doc(&This->framebase, nsdoc);
538     nsIDOMDocument_Release(nsdoc);
539     return hres;
540 }
541
542 static const NodeImplVtbl HTMLIFrameImplVtbl = {
543     HTMLIFrame_QI,
544     HTMLIFrame_destructor,
545     HTMLElement_clone,
546     HTMLElement_handle_event,
547     HTMLElement_get_attr_col,
548     NULL,
549     NULL,
550     NULL,
551     NULL,
552     HTMLIFrame_get_document,
553     HTMLIFrame_get_readystate,
554     HTMLIFrame_get_dispid,
555     HTMLIFrame_invoke,
556     HTMLIFrame_bind_to_tree
557 };
558
559 static const tid_t HTMLIFrame_iface_tids[] = {
560     HTMLELEMENT_TIDS,
561     IHTMLFrameBase_tid,
562     IHTMLFrameBase2_tid,
563     IHTMLIFrameElement_tid,
564     IHTMLIFrameElement2_tid,
565     IHTMLIFrameElement3_tid,
566     0
567 };
568
569 static dispex_static_data_t HTMLIFrame_dispex = {
570     NULL,
571     DispHTMLIFrame_tid,
572     NULL,
573     HTMLIFrame_iface_tids
574 };
575
576 HRESULT HTMLIFrame_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
577 {
578     HTMLIFrame *ret;
579
580     ret = heap_alloc_zero(sizeof(HTMLIFrame));
581     if(!ret)
582         return E_OUTOFMEMORY;
583
584     ret->IHTMLIFrameElement_iface.lpVtbl = &HTMLIFrameElementVtbl;
585     ret->IHTMLIFrameElement2_iface.lpVtbl = &HTMLIFrameElement2Vtbl;
586     ret->IHTMLIFrameElement3_iface.lpVtbl = &HTMLIFrameElement3Vtbl;
587     ret->framebase.element.node.vtbl = &HTMLIFrameImplVtbl;
588
589     HTMLFrameBase_Init(&ret->framebase, doc, nselem, &HTMLIFrame_dispex);
590
591     *elem = &ret->framebase.element;
592     return S_OK;
593 }