Commit f9fd7b77 authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Implement enumerator for HTMLFormElement.

parent 6c98c657
...@@ -41,6 +41,15 @@ struct HTMLFormElement { ...@@ -41,6 +41,15 @@ struct HTMLFormElement {
nsIDOMHTMLFormElement *nsform; nsIDOMHTMLFormElement *nsform;
}; };
typedef struct {
IEnumVARIANT IEnumVARIANT_iface;
LONG ref;
ULONG iter;
HTMLFormElement *elem;
} HTMLFormElementEnum;
HRESULT return_nsform(nsresult nsres, nsIDOMHTMLFormElement *form, IHTMLFormElement **p) HRESULT return_nsform(nsresult nsres, nsIDOMHTMLFormElement *form, IHTMLFormElement **p)
{ {
nsIDOMNode *form_node; nsIDOMNode *form_node;
...@@ -108,6 +117,135 @@ static HRESULT htmlform_item(HTMLFormElement *This, int i, IDispatch **ret) ...@@ -108,6 +117,135 @@ static HRESULT htmlform_item(HTMLFormElement *This, int i, IDispatch **ret)
return S_OK; return S_OK;
} }
static inline HTMLFormElementEnum *impl_from_IEnumVARIANT(IEnumVARIANT *iface)
{
return CONTAINING_RECORD(iface, HTMLFormElementEnum, IEnumVARIANT_iface);
}
static HRESULT WINAPI HTMLFormElementEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
{
HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface);
TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
if(IsEqualGUID(riid, &IID_IUnknown)) {
*ppv = &This->IEnumVARIANT_iface;
}else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) {
*ppv = &This->IEnumVARIANT_iface;
}else {
FIXME("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI HTMLFormElementEnum_AddRef(IEnumVARIANT *iface)
{
HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%ld\n", This, ref);
return ref;
}
static ULONG WINAPI HTMLFormElementEnum_Release(IEnumVARIANT *iface)
{
HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) {
IHTMLFormElement_Release(&This->elem->IHTMLFormElement_iface);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI HTMLFormElementEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
{
HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface);
nsresult nsres;
HRESULT hres;
ULONG num, i;
LONG len;
TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
nsres = nsIDOMHTMLFormElement_GetLength(This->elem->nsform, &len);
if(NS_FAILED(nsres))
return E_FAIL;
num = min(len - This->iter, celt);
for(i = 0; i < num; i++) {
hres = htmlform_item(This->elem, This->iter + i, &V_DISPATCH(&rgVar[i]));
if(FAILED(hres)) {
while(i--)
VariantClear(&rgVar[i]);
return hres;
}
V_VT(&rgVar[i]) = VT_DISPATCH;
}
This->iter += num;
if(pCeltFetched)
*pCeltFetched = num;
return num == celt ? S_OK : S_FALSE;
}
static HRESULT WINAPI HTMLFormElementEnum_Skip(IEnumVARIANT *iface, ULONG celt)
{
HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface);
nsresult nsres;
LONG len;
TRACE("(%p)->(%lu)\n", This, celt);
nsres = nsIDOMHTMLFormElement_GetLength(This->elem->nsform, &len);
if(NS_FAILED(nsres))
return E_FAIL;
if(This->iter + celt > len) {
This->iter = len;
return S_FALSE;
}
This->iter += celt;
return S_OK;
}
static HRESULT WINAPI HTMLFormElementEnum_Reset(IEnumVARIANT *iface)
{
HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface);
TRACE("(%p)->()\n", This);
This->iter = 0;
return S_OK;
}
static HRESULT WINAPI HTMLFormElementEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
{
HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface);
FIXME("(%p)->(%p)\n", This, ppEnum);
return E_NOTIMPL;
}
static const IEnumVARIANTVtbl HTMLFormElementEnumVtbl = {
HTMLFormElementEnum_QueryInterface,
HTMLFormElementEnum_AddRef,
HTMLFormElementEnum_Release,
HTMLFormElementEnum_Next,
HTMLFormElementEnum_Skip,
HTMLFormElementEnum_Reset,
HTMLFormElementEnum_Clone
};
static inline HTMLFormElement *impl_from_IHTMLFormElement(IHTMLFormElement *iface) static inline HTMLFormElement *impl_from_IHTMLFormElement(IHTMLFormElement *iface)
{ {
return CONTAINING_RECORD(iface, HTMLFormElement, IHTMLFormElement_iface); return CONTAINING_RECORD(iface, HTMLFormElement, IHTMLFormElement_iface);
...@@ -545,8 +683,23 @@ static HRESULT WINAPI HTMLFormElement_get_length(IHTMLFormElement *iface, LONG * ...@@ -545,8 +683,23 @@ static HRESULT WINAPI HTMLFormElement_get_length(IHTMLFormElement *iface, LONG *
static HRESULT WINAPI HTMLFormElement__newEnum(IHTMLFormElement *iface, IUnknown **p) static HRESULT WINAPI HTMLFormElement__newEnum(IHTMLFormElement *iface, IUnknown **p)
{ {
HTMLFormElement *This = impl_from_IHTMLFormElement(iface); HTMLFormElement *This = impl_from_IHTMLFormElement(iface);
FIXME("(%p)->(%p)\n", This, p); HTMLFormElementEnum *ret;
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, p);
ret = heap_alloc(sizeof(*ret));
if(!ret)
return E_OUTOFMEMORY;
ret->IEnumVARIANT_iface.lpVtbl = &HTMLFormElementEnumVtbl;
ret->ref = 1;
ret->iter = 0;
HTMLFormElement_AddRef(&This->IHTMLFormElement_iface);
ret->elem = This;
*p = (IUnknown*)&ret->IEnumVARIANT_iface;
return S_OK;
} }
static HRESULT WINAPI HTMLFormElement_item(IHTMLFormElement *iface, VARIANT name, static HRESULT WINAPI HTMLFormElement_item(IHTMLFormElement *iface, VARIANT name,
......
...@@ -5504,7 +5504,10 @@ static void test_form_item(IHTMLElement *elem) ...@@ -5504,7 +5504,10 @@ static void test_form_item(IHTMLElement *elem)
{ {
IHTMLFormElement *form = get_form_iface((IUnknown*)elem); IHTMLFormElement *form = get_form_iface((IUnknown*)elem);
IDispatch *disp, *disp2; IDispatch *disp, *disp2;
VARIANT name, index; IEnumVARIANT *enum_var;
VARIANT name, index, v;
IUnknown *enum_unk;
ULONG fetched;
HRESULT hres; HRESULT hres;
V_VT(&index) = VT_EMPTY; V_VT(&index) = VT_EMPTY;
...@@ -5543,6 +5546,40 @@ static void test_form_item(IHTMLElement *elem) ...@@ -5543,6 +5546,40 @@ static void test_form_item(IHTMLElement *elem)
ok(iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n"); ok(iface_cmp((IUnknown*)disp, (IUnknown*)disp2), "disp != disp2\n");
IDispatch_Release(disp2); IDispatch_Release(disp2);
IDispatch_Release(disp); IDispatch_Release(disp);
hres = IHTMLFormElement_get__newEnum(form, &enum_unk);
ok(hres == S_OK, "_newEnum failed: %08lx\n", hres);
hres = IUnknown_QueryInterface(enum_unk, &IID_IEnumVARIANT, (void**)&enum_var);
IUnknown_Release(enum_unk);
ok(hres == S_OK, "Could not get IEnumVARIANT iface: %08lx\n", hres);
fetched = 0;
V_VT(&v) = VT_ERROR;
hres = IEnumVARIANT_Next(enum_var, 1, &v, &fetched);
ok(hres == S_OK, "Next failed: %08lx\n", hres);
ok(fetched == 1, "fetched = %lu\n", fetched);
ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
ok(V_DISPATCH(&v) != NULL, "V_DISPATCH(&v) == NULL\n");
test_disp((IUnknown*)V_DISPATCH(&v), &DIID_DispHTMLTextAreaElement, &CLSID_HTMLTextAreaElement, NULL);
VariantClear(&v);
fetched = 0;
V_VT(&v) = VT_ERROR;
hres = IEnumVARIANT_Next(enum_var, 1, &v, &fetched);
ok(hres == S_OK, "Next failed: %08lx\n", hres);
ok(fetched == 1, "fetched = %lu\n", fetched);
ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
ok(V_DISPATCH(&v) != NULL, "V_DISPATCH(&v) == NULL\n");
test_disp((IUnknown*)V_DISPATCH(&v), &DIID_DispHTMLInputElement, &CLSID_HTMLInputElement, NULL);
VariantClear(&v);
fetched = 0;
V_VT(&v) = VT_ERROR;
hres = IEnumVARIANT_Next(enum_var, 1, &v, &fetched);
ok(hres == S_FALSE, "Next failed: %08lx\n", hres);
ok(fetched == 0, "fetched = %lu\n", fetched);
IEnumVARIANT_Release(enum_var);
} }
static void test_create_option_elem(IHTMLDocument2 *doc) static void test_create_option_elem(IHTMLDocument2 *doc)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment