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