Jacek Caban : mshtml: Added IHTMLElement2:: getBoundingClientRect implementation.

Alexandre Julliard julliard at winehq.org
Mon Jul 19 11:05:30 CDT 2010


Module: wine
Branch: master
Commit: 489320b9ab4ba5e183cab0c6b3ea00ccbcaac08a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=489320b9ab4ba5e183cab0c6b3ea00ccbcaac08a

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sat Jul 17 13:29:24 2010 +0200

mshtml: Added IHTMLElement2::getBoundingClientRect implementation.

---

 dlls/mshtml/dispex.c         |    1 +
 dlls/mshtml/htmlelem2.c      |  200 +++++++++++++++++++++++++++++++++++++++++-
 dlls/mshtml/mshtml_private.h |    1 +
 dlls/mshtml/tests/dom.c      |   18 ++++
 4 files changed, 217 insertions(+), 3 deletions(-)

diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
index de0c948..64356f5 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 548bab8..b6030b8 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 4deb4d6..46886d8 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 4f954a8..c877b96 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");




More information about the wine-cvs mailing list