mshtml: Implement enumerator for HTMLRectCollection.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7c311fbcc1
commit
6c98c65707
|
@ -781,6 +781,139 @@ typedef struct {
|
|||
nsIDOMClientRectList *rect_list;
|
||||
} HTMLRectCollection;
|
||||
|
||||
typedef struct {
|
||||
IEnumVARIANT IEnumVARIANT_iface;
|
||||
|
||||
LONG ref;
|
||||
|
||||
ULONG iter;
|
||||
HTMLRectCollection *col;
|
||||
} HTMLRectCollectionEnum;
|
||||
|
||||
static inline HTMLRectCollectionEnum *HTMLRectCollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, HTMLRectCollectionEnum, IEnumVARIANT_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLRectCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_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 HTMLRectCollectionEnum_AddRef(IEnumVARIANT *iface)
|
||||
{
|
||||
HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI HTMLRectCollectionEnum_Release(IEnumVARIANT *iface)
|
||||
{
|
||||
HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%ld\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
IHTMLRectCollection_Release(&This->col->IHTMLRectCollection_iface);
|
||||
heap_free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLRectCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
|
||||
{
|
||||
HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface);
|
||||
VARIANT index;
|
||||
HRESULT hres;
|
||||
ULONG num, i;
|
||||
UINT32 len;
|
||||
|
||||
TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
|
||||
|
||||
nsIDOMClientRectList_GetLength(This->col->rect_list, &len);
|
||||
num = min(len - This->iter, celt);
|
||||
V_VT(&index) = VT_I4;
|
||||
|
||||
for(i = 0; i < num; i++) {
|
||||
V_I4(&index) = This->iter + i;
|
||||
hres = IHTMLRectCollection_item(&This->col->IHTMLRectCollection_iface, &index, &rgVar[i]);
|
||||
if(FAILED(hres)) {
|
||||
while(i--)
|
||||
VariantClear(&rgVar[i]);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
This->iter += num;
|
||||
if(pCeltFetched)
|
||||
*pCeltFetched = num;
|
||||
return num == celt ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLRectCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt)
|
||||
{
|
||||
HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface);
|
||||
UINT32 len;
|
||||
|
||||
TRACE("(%p)->(%lu)\n", This, celt);
|
||||
|
||||
nsIDOMClientRectList_GetLength(This->col->rect_list, &len);
|
||||
if(This->iter + celt > len) {
|
||||
This->iter = len;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
This->iter += celt;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLRectCollectionEnum_Reset(IEnumVARIANT *iface)
|
||||
{
|
||||
HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface);
|
||||
|
||||
TRACE("(%p)->()\n", This);
|
||||
|
||||
This->iter = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLRectCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
|
||||
{
|
||||
HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface);
|
||||
FIXME("(%p)->(%p)\n", This, ppEnum);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IEnumVARIANTVtbl HTMLRectCollectionEnumVtbl = {
|
||||
HTMLRectCollectionEnum_QueryInterface,
|
||||
HTMLRectCollectionEnum_AddRef,
|
||||
HTMLRectCollectionEnum_Release,
|
||||
HTMLRectCollectionEnum_Next,
|
||||
HTMLRectCollectionEnum_Skip,
|
||||
HTMLRectCollectionEnum_Reset,
|
||||
HTMLRectCollectionEnum_Clone
|
||||
};
|
||||
|
||||
static inline HTMLRectCollection *impl_from_IHTMLRectCollection(IHTMLRectCollection *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, HTMLRectCollection, IHTMLRectCollection_iface);
|
||||
|
@ -883,8 +1016,23 @@ static HRESULT WINAPI HTMLRectCollection_get_length(IHTMLRectCollection *iface,
|
|||
static HRESULT WINAPI HTMLRectCollection_get__newEnum(IHTMLRectCollection *iface, IUnknown **p)
|
||||
{
|
||||
HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
|
||||
FIXME("(%p)->(%p)\n", This, p);
|
||||
return E_NOTIMPL;
|
||||
HTMLRectCollectionEnum *ret;
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, p);
|
||||
|
||||
ret = heap_alloc(sizeof(*ret));
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ret->IEnumVARIANT_iface.lpVtbl = &HTMLRectCollectionEnumVtbl;
|
||||
ret->ref = 1;
|
||||
ret->iter = 0;
|
||||
|
||||
HTMLRectCollection_AddRef(&This->IHTMLRectCollection_iface);
|
||||
ret->col = This;
|
||||
|
||||
*p = (IUnknown*)&ret->IEnumVARIANT_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLRectCollection_item(IHTMLRectCollection *iface, VARIANT *index, VARIANT *result)
|
||||
|
|
|
@ -5229,8 +5229,11 @@ static void test_elem_bounding_client_rect(IUnknown *unk)
|
|||
{
|
||||
IHTMLRectCollection *rects;
|
||||
IHTMLRect *rect, *rect2;
|
||||
IEnumVARIANT *enum_var;
|
||||
IHTMLElement2 *elem2;
|
||||
IUnknown *enum_unk;
|
||||
VARIANT v, index;
|
||||
ULONG fetched;
|
||||
LONG l;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -5285,6 +5288,30 @@ static void test_elem_bounding_client_rect(IUnknown *unk)
|
|||
test_disp((IUnknown*)V_DISPATCH(&v), &IID_IHTMLRect, NULL, L"[object]");
|
||||
VariantClear(&v);
|
||||
|
||||
hres = IHTMLRectCollection_get__newEnum(rects, &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), &IID_IHTMLRect, NULL, L"[object]");
|
||||
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);
|
||||
|
||||
IHTMLRectCollection_Release(rects);
|
||||
IHTMLElement2_Release(elem2);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue