mshtml: Use ifaces instead of vtbl pointers in HTMLFrameBase.
[wine] / dlls / mshtml / htmlframe.c
1 /*
2  * Copyright 2010 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     IHTMLFrameElement3 IHTMLFrameElement3_iface;
37 } HTMLFrameElement;
38
39 static inline HTMLFrameElement *impl_from_IHTMLFrameElement3(IHTMLFrameElement3 *iface)
40 {
41     return CONTAINING_RECORD(iface, HTMLFrameElement, IHTMLFrameElement3_iface);
42 }
43
44 static HRESULT WINAPI HTMLFrameElement3_QueryInterface(IHTMLFrameElement3 *iface,
45         REFIID riid, void **ppv)
46 {
47     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
48
49     return IHTMLDOMNode_QueryInterface(&This->framebase.element.node.IHTMLDOMNode_iface, riid, ppv);
50 }
51
52 static ULONG WINAPI HTMLFrameElement3_AddRef(IHTMLFrameElement3 *iface)
53 {
54     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
55
56     return IHTMLDOMNode_AddRef(&This->framebase.element.node.IHTMLDOMNode_iface);
57 }
58
59 static ULONG WINAPI HTMLFrameElement3_Release(IHTMLFrameElement3 *iface)
60 {
61     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
62
63     return IHTMLDOMNode_Release(&This->framebase.element.node.IHTMLDOMNode_iface);
64 }
65
66 static HRESULT WINAPI HTMLFrameElement3_GetTypeInfoCount(IHTMLFrameElement3 *iface, UINT *pctinfo)
67 {
68     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
69     return IDispatchEx_GetTypeInfoCount(&This->framebase.element.node.dispex.IDispatchEx_iface,
70             pctinfo);
71 }
72
73 static HRESULT WINAPI HTMLFrameElement3_GetTypeInfo(IHTMLFrameElement3 *iface, UINT iTInfo,
74         LCID lcid, ITypeInfo **ppTInfo)
75 {
76     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
77     return IDispatchEx_GetTypeInfo(&This->framebase.element.node.dispex.IDispatchEx_iface, iTInfo,
78             lcid, ppTInfo);
79 }
80
81 static HRESULT WINAPI HTMLFrameElement3_GetIDsOfNames(IHTMLFrameElement3 *iface, REFIID riid,
82         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
83 {
84     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
85     return IDispatchEx_GetIDsOfNames(&This->framebase.element.node.dispex.IDispatchEx_iface, riid,
86             rgszNames, cNames, lcid, rgDispId);
87 }
88
89 static HRESULT WINAPI HTMLFrameElement3_Invoke(IHTMLFrameElement3 *iface, DISPID dispIdMember,
90         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
91         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
92 {
93     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(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 HTMLFrameElement3_get_contentDocument(IHTMLFrameElement3 *iface, IDispatch **p)
99 {
100     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
101     IHTMLDocument2 *doc;
102     HRESULT hres;
103
104     TRACE("(%p)->(%p)\n", This, p);
105
106     if(!This->framebase.content_window) {
107         FIXME("NULL window\n");
108         return E_FAIL;
109     }
110
111     hres = IHTMLWindow2_get_document(&This->framebase.content_window->IHTMLWindow2_iface, &doc);
112     if(FAILED(hres))
113         return hres;
114
115     *p = doc ? (IDispatch*)doc : NULL;
116     return S_OK;
117 }
118
119 static HRESULT WINAPI HTMLFrameElement3_put_src(IHTMLFrameElement3 *iface, BSTR v)
120 {
121     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
122     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
123     return E_NOTIMPL;
124 }
125
126 static HRESULT WINAPI HTMLFrameElement3_get_src(IHTMLFrameElement3 *iface, BSTR *p)
127 {
128     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
129     FIXME("(%p)->(%p)\n", This, p);
130     return E_NOTIMPL;
131 }
132
133 static HRESULT WINAPI HTMLFrameElement3_put_longDesc(IHTMLFrameElement3 *iface, BSTR v)
134 {
135     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
136     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
137     return E_NOTIMPL;
138 }
139
140 static HRESULT WINAPI HTMLFrameElement3_get_longDesc(IHTMLFrameElement3 *iface, BSTR *p)
141 {
142     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
143     FIXME("(%p)->(%p)\n", This, p);
144     return E_NOTIMPL;
145 }
146
147 static HRESULT WINAPI HTMLFrameElement3_put_frameBorder(IHTMLFrameElement3 *iface, BSTR v)
148 {
149     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
150     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
151     return E_NOTIMPL;
152 }
153
154 static HRESULT WINAPI HTMLFrameElement3_get_frameBorder(IHTMLFrameElement3 *iface, BSTR *p)
155 {
156     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
157     FIXME("(%p)->(%p)\n", This, p);
158     return E_NOTIMPL;
159 }
160
161 static const IHTMLFrameElement3Vtbl HTMLFrameElement3Vtbl = {
162     HTMLFrameElement3_QueryInterface,
163     HTMLFrameElement3_AddRef,
164     HTMLFrameElement3_Release,
165     HTMLFrameElement3_GetTypeInfoCount,
166     HTMLFrameElement3_GetTypeInfo,
167     HTMLFrameElement3_GetIDsOfNames,
168     HTMLFrameElement3_Invoke,
169     HTMLFrameElement3_get_contentDocument,
170     HTMLFrameElement3_put_src,
171     HTMLFrameElement3_get_src,
172     HTMLFrameElement3_put_longDesc,
173     HTMLFrameElement3_get_longDesc,
174     HTMLFrameElement3_put_frameBorder,
175     HTMLFrameElement3_get_frameBorder
176 };
177
178 static inline HTMLFrameElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
179 {
180     return CONTAINING_RECORD(iface, HTMLFrameElement, framebase.element.node);
181 }
182
183 static HRESULT HTMLFrameElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
184 {
185     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
186
187     if(IsEqualGUID(&IID_IHTMLFrameElement3, riid)) {
188         TRACE("(%p)->(IID_IHTMLFrameElement3 %p)\n", This, ppv);
189         *ppv = &This->IHTMLFrameElement3_iface;
190     }else {
191         return HTMLFrameBase_QI(&This->framebase, riid, ppv);
192     }
193
194     IUnknown_AddRef((IUnknown*)*ppv);
195     return S_OK;
196 }
197
198 static void HTMLFrameElement_destructor(HTMLDOMNode *iface)
199 {
200     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
201
202     HTMLFrameBase_destructor(&This->framebase);
203 }
204
205 static HRESULT HTMLFrameElement_get_document(HTMLDOMNode *iface, IDispatch **p)
206 {
207     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
208
209     if(!This->framebase.content_window || !This->framebase.content_window->doc) {
210         *p = NULL;
211         return S_OK;
212     }
213
214     *p = (IDispatch*)&This->framebase.content_window->doc->basedoc.IHTMLDocument2_iface;
215     IDispatch_AddRef(*p);
216     return S_OK;
217 }
218
219 static HRESULT HTMLFrameElement_get_readystate(HTMLDOMNode *iface, BSTR *p)
220 {
221     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
222
223     return IHTMLFrameBase2_get_readyState(&This->framebase.IHTMLFrameBase2_iface, p);
224 }
225
226 static HRESULT HTMLFrameElement_get_dispid(HTMLDOMNode *iface, BSTR name,
227         DWORD grfdex, DISPID *pid)
228 {
229     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
230
231     if(!This->framebase.content_window)
232         return DISP_E_UNKNOWNNAME;
233
234     return search_window_props(This->framebase.content_window, name, grfdex, pid);
235 }
236
237 static HRESULT HTMLFrameElement_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid,
238         WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
239 {
240     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
241
242     if(!This->framebase.content_window) {
243         ERR("no content window to invoke on\n");
244         return E_FAIL;
245     }
246
247     return IDispatchEx_InvokeEx(&This->framebase.content_window->IDispatchEx_iface, id, lcid,
248             flags, params, res, ei, caller);
249 }
250
251 static HRESULT HTMLFrameElement_bind_to_tree(HTMLDOMNode *iface)
252 {
253     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
254     nsIDOMDocument *nsdoc;
255     nsresult nsres;
256     HRESULT hres;
257
258     nsres = nsIDOMHTMLFrameElement_GetContentDocument(This->framebase.nsframe, &nsdoc);
259     if(NS_FAILED(nsres) || !nsdoc) {
260         ERR("GetContentDocument failed: %08x\n", nsres);
261         return E_FAIL;
262     }
263
264     hres = set_frame_doc(&This->framebase, nsdoc);
265     nsIDOMDocument_Release(nsdoc);
266     return hres;
267 }
268
269 static const NodeImplVtbl HTMLFrameElementImplVtbl = {
270     HTMLFrameElement_QI,
271     HTMLFrameElement_destructor,
272     HTMLElement_clone,
273     NULL,
274     NULL,
275     NULL,
276     NULL,
277     HTMLFrameElement_get_document,
278     HTMLFrameElement_get_readystate,
279     HTMLFrameElement_get_dispid,
280     HTMLFrameElement_invoke,
281     HTMLFrameElement_bind_to_tree
282 };
283
284 static const tid_t HTMLFrameElement_iface_tids[] = {
285     HTMLELEMENT_TIDS,
286     IHTMLFrameBase_tid,
287     IHTMLFrameBase2_tid,
288     IHTMLFrameElement3_tid,
289     0
290 };
291
292 static dispex_static_data_t HTMLFrameElement_dispex = {
293     NULL,
294     DispHTMLFrameElement_tid,
295     NULL,
296     HTMLFrameElement_iface_tids
297 };
298
299 HRESULT HTMLFrameElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
300 {
301     HTMLFrameElement *ret;
302
303     ret = heap_alloc_zero(sizeof(HTMLFrameElement));
304     if(!ret)
305         return E_OUTOFMEMORY;
306
307     ret->framebase.element.node.vtbl = &HTMLFrameElementImplVtbl;
308     ret->IHTMLFrameElement3_iface.lpVtbl = &HTMLFrameElement3Vtbl;
309
310     HTMLFrameBase_Init(&ret->framebase, doc, nselem, &HTMLFrameElement_dispex);
311
312     *elem = &ret->framebase.element;
313     return S_OK;
314 }