mstask: Actually run a test and fix the expected behaviour.
[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 } HTMLIFrame;
38
39 static inline HTMLIFrame *impl_from_IHTMLIFrameElement(IHTMLIFrameElement *iface)
40 {
41     return CONTAINING_RECORD(iface, HTMLIFrame, IHTMLIFrameElement_iface);
42 }
43
44 static HRESULT WINAPI HTMLIFrameElement_QueryInterface(IHTMLIFrameElement *iface,
45         REFIID riid, void **ppv)
46 {
47     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
48
49     return IHTMLDOMNode_QueryInterface(&This->framebase.element.node.IHTMLDOMNode_iface, riid, ppv);
50 }
51
52 static ULONG WINAPI HTMLIFrameElement_AddRef(IHTMLIFrameElement *iface)
53 {
54     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
55
56     return IHTMLDOMNode_AddRef(&This->framebase.element.node.IHTMLDOMNode_iface);
57 }
58
59 static ULONG WINAPI HTMLIFrameElement_Release(IHTMLIFrameElement *iface)
60 {
61     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
62
63     return IHTMLDOMNode_Release(&This->framebase.element.node.IHTMLDOMNode_iface);
64 }
65
66 static HRESULT WINAPI HTMLIFrameElement_GetTypeInfoCount(IHTMLIFrameElement *iface, UINT *pctinfo)
67 {
68     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
69     return IDispatchEx_GetTypeInfoCount(&This->framebase.element.node.dispex.IDispatchEx_iface,
70             pctinfo);
71 }
72
73 static HRESULT WINAPI HTMLIFrameElement_GetTypeInfo(IHTMLIFrameElement *iface, UINT iTInfo,
74         LCID lcid, ITypeInfo **ppTInfo)
75 {
76     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
77     return IDispatchEx_GetTypeInfo(&This->framebase.element.node.dispex.IDispatchEx_iface, iTInfo,
78             lcid, ppTInfo);
79 }
80
81 static HRESULT WINAPI HTMLIFrameElement_GetIDsOfNames(IHTMLIFrameElement *iface, REFIID riid,
82         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
83 {
84     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
85     return IDispatchEx_GetIDsOfNames(&This->framebase.element.node.dispex.IDispatchEx_iface, riid,
86             rgszNames, cNames, lcid, rgDispId);
87 }
88
89 static HRESULT WINAPI HTMLIFrameElement_Invoke(IHTMLIFrameElement *iface, DISPID dispIdMember,
90         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
91         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
92 {
93     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
94     return IDispatchEx_Invoke(&This->framebase.element.node.dispex.IDispatchEx_iface, dispIdMember,
95             riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
96 }
97
98 static HRESULT WINAPI HTMLIFrameElement_put_vspace(IHTMLIFrameElement *iface, LONG v)
99 {
100     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
101     FIXME("(%p)->(%d)\n", This, v);
102     return E_NOTIMPL;
103 }
104
105 static HRESULT WINAPI HTMLIFrameElement_get_vspace(IHTMLIFrameElement *iface, LONG *p)
106 {
107     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
108     FIXME("(%p)->(%p)\n", This, p);
109     return E_NOTIMPL;
110 }
111
112 static HRESULT WINAPI HTMLIFrameElement_put_hspace(IHTMLIFrameElement *iface, LONG v)
113 {
114     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
115     FIXME("(%p)->(%d)\n", This, v);
116     return E_NOTIMPL;
117 }
118
119 static HRESULT WINAPI HTMLIFrameElement_get_hspace(IHTMLIFrameElement *iface, LONG *p)
120 {
121     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
122     FIXME("(%p)->(%p)\n", This, p);
123     return E_NOTIMPL;
124 }
125
126 static HRESULT WINAPI HTMLIFrameElement_put_align(IHTMLIFrameElement *iface, BSTR v)
127 {
128     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
129     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
130     return E_NOTIMPL;
131 }
132
133 static HRESULT WINAPI HTMLIFrameElement_get_align(IHTMLIFrameElement *iface, BSTR *p)
134 {
135     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
136     FIXME("(%p)->(%p)\n", This, p);
137     return E_NOTIMPL;
138 }
139
140 static const IHTMLIFrameElementVtbl HTMLIFrameElementVtbl = {
141     HTMLIFrameElement_QueryInterface,
142     HTMLIFrameElement_AddRef,
143     HTMLIFrameElement_Release,
144     HTMLIFrameElement_GetTypeInfoCount,
145     HTMLIFrameElement_GetTypeInfo,
146     HTMLIFrameElement_GetIDsOfNames,
147     HTMLIFrameElement_Invoke,
148     HTMLIFrameElement_put_vspace,
149     HTMLIFrameElement_get_vspace,
150     HTMLIFrameElement_put_hspace,
151     HTMLIFrameElement_get_hspace,
152     HTMLIFrameElement_put_align,
153     HTMLIFrameElement_get_align
154 };
155
156 static inline HTMLIFrame *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
157 {
158     return CONTAINING_RECORD(iface, HTMLIFrame, framebase.element.node);
159 }
160
161 static HRESULT HTMLIFrame_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
162 {
163     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
164
165     if(IsEqualGUID(&IID_IHTMLIFrameElement, riid)) {
166         TRACE("(%p)->(IID_IHTMLIFrameElement %p)\n", This, ppv);
167         *ppv = &This->IHTMLIFrameElement_iface;
168     }else {
169         return HTMLFrameBase_QI(&This->framebase, riid, ppv);
170     }
171
172     IUnknown_AddRef((IUnknown*)*ppv);
173     return S_OK;
174 }
175
176 static void HTMLIFrame_destructor(HTMLDOMNode *iface)
177 {
178     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
179
180     HTMLFrameBase_destructor(&This->framebase);
181 }
182
183 static HRESULT HTMLIFrame_get_document(HTMLDOMNode *iface, IDispatch **p)
184 {
185     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
186
187     if(!This->framebase.content_window || !This->framebase.content_window->doc) {
188         *p = NULL;
189         return S_OK;
190     }
191
192     *p = (IDispatch*)&This->framebase.content_window->doc->basedoc.IHTMLDocument2_iface;
193     IDispatch_AddRef(*p);
194     return S_OK;
195 }
196
197 static HRESULT HTMLIFrame_get_dispid(HTMLDOMNode *iface, BSTR name,
198         DWORD grfdex, DISPID *pid)
199 {
200     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
201
202     if(!This->framebase.content_window)
203         return DISP_E_UNKNOWNNAME;
204
205     return search_window_props(This->framebase.content_window, name, grfdex, pid);
206 }
207
208 static HRESULT HTMLIFrame_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid,
209         WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
210 {
211     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
212
213     if(!This->framebase.content_window) {
214         ERR("no content window to invoke on\n");
215         return E_FAIL;
216     }
217
218     return IDispatchEx_InvokeEx(&This->framebase.content_window->IDispatchEx_iface, id, lcid,
219             flags, params, res, ei, caller);
220 }
221
222 static HRESULT HTMLIFrame_get_readystate(HTMLDOMNode *iface, BSTR *p)
223 {
224     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
225
226     return IHTMLFrameBase2_get_readyState(&This->framebase.IHTMLFrameBase2_iface, p);
227 }
228
229 static HRESULT HTMLIFrame_bind_to_tree(HTMLDOMNode *iface)
230 {
231     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
232     nsIDOMDocument *nsdoc;
233     nsresult nsres;
234     HRESULT hres;
235
236     nsres = nsIDOMHTMLIFrameElement_GetContentDocument(This->framebase.nsiframe, &nsdoc);
237     if(NS_FAILED(nsres) || !nsdoc) {
238         ERR("GetContentDocument failed: %08x\n", nsres);
239         return E_FAIL;
240     }
241
242     hres = set_frame_doc(&This->framebase, nsdoc);
243     nsIDOMDocument_Release(nsdoc);
244     return hres;
245 }
246
247 static const NodeImplVtbl HTMLIFrameImplVtbl = {
248     HTMLIFrame_QI,
249     HTMLIFrame_destructor,
250     HTMLElement_clone,
251     HTMLElement_get_attr_col,
252     NULL,
253     NULL,
254     NULL,
255     NULL,
256     NULL,
257     HTMLIFrame_get_document,
258     HTMLIFrame_get_readystate,
259     HTMLIFrame_get_dispid,
260     HTMLIFrame_invoke,
261     HTMLIFrame_bind_to_tree
262 };
263
264 static const tid_t HTMLIFrame_iface_tids[] = {
265     HTMLELEMENT_TIDS,
266     IHTMLFrameBase_tid,
267     IHTMLFrameBase2_tid,
268     IHTMLIFrameElement_tid,
269     0
270 };
271
272 static dispex_static_data_t HTMLIFrame_dispex = {
273     NULL,
274     DispHTMLIFrame_tid,
275     NULL,
276     HTMLIFrame_iface_tids
277 };
278
279 HRESULT HTMLIFrame_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
280 {
281     HTMLIFrame *ret;
282
283     ret = heap_alloc_zero(sizeof(HTMLIFrame));
284     if(!ret)
285         return E_OUTOFMEMORY;
286
287     ret->IHTMLIFrameElement_iface.lpVtbl = &HTMLIFrameElementVtbl;
288     ret->framebase.element.node.vtbl = &HTMLIFrameImplVtbl;
289
290     HTMLFrameBase_Init(&ret->framebase, doc, nselem, &HTMLIFrame_dispex);
291
292     *elem = &ret->framebase.element;
293     return S_OK;
294 }