diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index de0c94871f6..64356f5fde0 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -146,6 +146,7 @@ static REFIID tid_ids[] = { &IID_IHTMLInputElement, &IID_IHTMLLocation, &IID_IHTMLOptionElement, + &IID_IHTMLRect, &IID_IHTMLScreen, &IID_IHTMLScriptElement, &IID_IHTMLSelectElement, diff --git a/dlls/mshtml/htmlelem2.c b/dlls/mshtml/htmlelem2.c index 548bab8b2f5..b6030b8b54a 100644 --- a/dlls/mshtml/htmlelem2.c +++ b/dlls/mshtml/htmlelem2.c @@ -1,5 +1,5 @@ /* - * Copyright 2006 Jacek Caban for CodeWeavers + * Copyright 2006-2010 Jacek Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,6 +33,198 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +typedef struct { + DispatchEx dispex; + const IHTMLRectVtbl *lpIHTMLRectVtbl; + LONG ref; +} HTMLRect; + +#define HTMLRECT(x) ((IHTMLRect*) &(x)->lpIHTMLRectVtbl) + +#define HTMLRECT_THIS(iface) DEFINE_THIS(HTMLRect, IHTMLRect, iface) + +static HRESULT WINAPI HTMLRect_QueryInterface(IHTMLRect *iface, REFIID riid, void **ppv) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = HTMLRECT(This); + }else if(IsEqualGUID(&IID_IHTMLRect, riid)) { + TRACE("(%p)->(IID_IHTMLRect %p)\n", This, ppv); + *ppv = HTMLRECT(This); + }else if(dispex_query_interface(&This->dispex, riid, ppv)) { + return *ppv ? S_OK : E_NOINTERFACE; + }else { + FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI HTMLRect_AddRef(IHTMLRect *iface) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI HTMLRect_Release(IHTMLRect *iface) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) + heap_free(This); + + return ref; +} + +static HRESULT WINAPI HTMLRect_GetTypeInfoCount(IHTMLRect *iface, UINT *pctinfo) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLRect_GetTypeInfo(IHTMLRect *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLRect_GetIDsOfNames(IHTMLRect *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); +} + +static HRESULT WINAPI HTMLRect_Invoke(IHTMLRect *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + + return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLRect_put_left(IHTMLRect *iface, LONG v) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + FIXME("(%p)->(%d)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLRect_get_left(IHTMLRect *iface, LONG *p) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLRect_put_top(IHTMLRect *iface, LONG v) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + FIXME("(%p)->(%d)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLRect_get_top(IHTMLRect *iface, LONG *p) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLRect_put_right(IHTMLRect *iface, LONG v) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + FIXME("(%p)->(%d)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLRect_get_right(IHTMLRect *iface, LONG *p) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLRect_put_bottom(IHTMLRect *iface, LONG v) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + FIXME("(%p)->(%d)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLRect_get_bottom(IHTMLRect *iface, LONG *p) +{ + HTMLRect *This = HTMLRECT_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +#undef HTMLRECT_THIS + +static const IHTMLRectVtbl HTMLRectVtbl = { + HTMLRect_QueryInterface, + HTMLRect_AddRef, + HTMLRect_Release, + HTMLRect_GetTypeInfoCount, + HTMLRect_GetTypeInfo, + HTMLRect_GetIDsOfNames, + HTMLRect_Invoke, + HTMLRect_put_left, + HTMLRect_get_left, + HTMLRect_put_top, + HTMLRect_get_top, + HTMLRect_put_right, + HTMLRect_get_right, + HTMLRect_put_bottom, + HTMLRect_get_bottom +}; + +static const tid_t HTMLRect_iface_tids[] = { + IHTMLRect_tid, + 0 +}; +static dispex_static_data_t HTMLRect_dispex = { + NULL, + IHTMLRect_tid, + NULL, + HTMLRect_iface_tids +}; + +static HRESULT create_html_rect(IHTMLRect **ret) +{ + HTMLRect *rect; + + rect = heap_alloc_zero(sizeof(HTMLRect)); + if(!rect) + return E_OUTOFMEMORY; + + rect->lpIHTMLRectVtbl = &HTMLRectVtbl; + rect->ref = 1; + + init_dispex(&rect->dispex, (IUnknown*)HTMLRECT(rect), &HTMLRect_dispex); + + *ret = HTMLRECT(rect); + return S_OK; +} + #define HTMLELEM2_THIS(iface) DEFINE_THIS(HTMLElement, HTMLElement2, iface) static HRESULT WINAPI HTMLElement2_QueryInterface(IHTMLElement2 *iface, @@ -364,8 +556,10 @@ static HRESULT WINAPI HTMLElement2_getClientRects(IHTMLElement2 *iface, IHTMLRec static HRESULT WINAPI HTMLElement2_getBoundingClientRect(IHTMLElement2 *iface, IHTMLRect **pRect) { HTMLElement *This = HTMLELEM2_THIS(iface); - FIXME("(%p)->(%p)\n", This, pRect); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, pRect); + + return create_html_rect(pRect); } static HRESULT WINAPI HTMLElement2_setExpression(IHTMLElement2 *iface, BSTR propname, diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 4deb4d6357d..46886d8b3b1 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -120,6 +120,7 @@ typedef enum { IHTMLInputElement_tid, IHTMLLocation_tid, IHTMLOptionElement_tid, + IHTMLRect_tid, IHTMLScreen_tid, IHTMLScriptElement_tid, IHTMLSelectElement_tid, diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 4f954a8ba30..c877b96e3b7 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -2852,6 +2852,23 @@ static void _test_style_set_csstext(unsigned line, IHTMLStyle *style, const char SysFreeString(tmp); } +static void test_elem_bounding_client_rect(IUnknown *unk) +{ + IHTMLElement2 *elem2; + IHTMLRect *rect; + HRESULT hres; + + elem2 = get_elem2_iface(unk); + hres = IHTMLElement2_getBoundingClientRect(elem2, &rect); + IHTMLElement2_Release(elem2); + ok(hres == S_OK, "getBoundingClientRect failed: %08x\n", hres); + ok(rect != NULL, "rect == NULL\n"); + + test_disp((IUnknown*)rect, &IID_IHTMLRect, "[object]"); + + IHTMLRect_Release(rect); +} + static void test_elem_col_item(IHTMLElementCollection *col, const char *n, const elem_type_t *elem_types, LONG len) { @@ -5862,6 +5879,7 @@ static void test_elems(IHTMLDocument2 *doc) test_elem_set_title((IUnknown*)select, "Title"); test_elem_title((IUnknown*)select, "Title"); test_elem_offset((IUnknown*)select); + test_elem_bounding_client_rect((IUnknown*)select); node = get_first_child((IUnknown*)select); ok(node != NULL, "node == NULL\n");