From: Zhenbo Li Subject: mshtml: Added IHTMLTable::width property implementation. Message-Id: <53397B19.5020403@gmail.com> Date: Mon, 31 Mar 2014 22:26:33 +0800 As my test case shows, windows would truncate float numbers. I considered VarInt() in oleaut32.dll, but I think to declare var2str_length() is more clear. --- dlls/mshtml/htmltable.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++--- dlls/mshtml/tests/dom.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 4 deletions(-) diff --git a/dlls/mshtml/htmltable.c b/dlls/mshtml/htmltable.c index e3a1264..a21355a 100644 --- a/dlls/mshtml/htmltable.c +++ b/dlls/mshtml/htmltable.c @@ -57,6 +57,32 @@ static inline HTMLTable *impl_from_IHTMLTable3(IHTMLTable3 *iface) return CONTAINING_RECORD(iface, HTMLTable, IHTMLTable3_iface); } +static HRESULT var2str_length(nsAString *nsstr, const VARIANT *p) +{ + static WCHAR buf[64]; + static const WCHAR formatW[] = {'%','d',0}; + LONG width; + + switch(V_VT(p)) { + case VT_BSTR: + return nsAString_Init(nsstr, V_BSTR(p)); + case VT_R8: + width = (LONG)(V_R8(p)); + break; + case VT_R4: + width = (LONG)(V_R4(p)); + break; + case VT_I4: + width = V_I4(p); + break; + default: + FIXME("unsupported arg %s\n", debugstr_variant(p)); + return E_NOTIMPL; + } + sprintfW(buf, formatW, width); + return nsAString_Init(nsstr, buf); +} + static HRESULT WINAPI HTMLTable_QueryInterface(IHTMLTable *iface, REFIID riid, void **ppv) { @@ -362,15 +388,55 @@ static HRESULT WINAPI HTMLTable_get_rows(IHTMLTable *iface, IHTMLElementCollecti static HRESULT WINAPI HTMLTable_put_width(IHTMLTable *iface, VARIANT v) { HTMLTable *This = impl_from_IHTMLTable(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; + nsAString val; + HRESULT nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + nsres = var2str_length(&val, &v); + + if (NS_FAILED(nsres)){ + ERR("Set Width(%s) failed when initializing a nsAString!\n", + debugstr_variant(&v)); + nsAString_Finish(&val); + return E_FAIL; + } + + nsres = nsIDOMHTMLTableElement_SetWidth(This->nstable, &val); + + if (NS_FAILED(nsres)){ + ERR("Set Width(%s) failed!\n", debugstr_variant(&v)); + nsAString_Finish(&val); + return E_FAIL; + } + + nsAString_Finish(&val); + + return S_OK; } static HRESULT WINAPI HTMLTable_get_width(IHTMLTable *iface, VARIANT *p) { HTMLTable *This = impl_from_IHTMLTable(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString val; + HRESULT nsres; + DOUBLE width; + + TRACE("(%p)->(%p)\n", This, p); + nsAString_Init(&val, NULL); + nsres = nsIDOMHTMLTableElement_GetWidth(This->nstable, &val); + + V_VT(p) = VT_BSTR; + nsres = return_nsstr(nsres, &val, &V_BSTR(p)); + if (nsres != S_OK) + return nsres; + + nsres = VarR8FromStr(V_BSTR(p), 0, 0, &width); + if (nsres == S_OK){ + VariantClear(p); + V_VT(p) = VT_I4; + V_I4(p) = (LONG)width; + } + return S_OK; } static HRESULT WINAPI HTMLTable_put_height(IHTMLTable *iface, VARIANT v) diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 76c283a..ca62735 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -5721,6 +5721,25 @@ static void _test_table_cell_spacing(unsigned line, IHTMLTable *table, const cha VariantClear(&v); } +#define cmp_length(a,b) _cmp_length(__LINE__,a,b) +static void _cmp_length(unsigned line, VARIANT got, const char * exstr) +{ + static char buf[64]; + ok_(__FILE__,line) (V_VT(&got)==VT_BSTR || V_VT(&got)==VT_I4, + "V_VT is %hu, expected VT_BSTR(%hu) or VT_I4(%hu)\n", + V_VT(&got), VT_BSTR, VT_I4); + + if (V_VT(&got) == VT_BSTR){ + ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&got), exstr), + "Expected %s, got %s\n", exstr, wine_dbgstr_w(V_BSTR(&got))); + } + else { + sprintf(buf, "%d", V_I4(&got)); + ok_(__FILE__,line) (!strcmp(buf, exstr), + "Expected %s, got %d\n", exstr, V_I4(&got)); + } +} + static void test_table_elem(IHTMLElement *elem) { IHTMLElementCollection *col; @@ -5794,6 +5813,54 @@ static void test_table_elem(IHTMLElement *elem) ok(!strcmp_wa(bstr, "left"), "get_align returned %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr); + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("11"); + hres = IHTMLTable_put_width(table, v); + ok(hres == S_OK, "put_width = %08x\n", hres); + VariantClear(&v); + IHTMLTable_get_width(table, &v); + ok(hres == S_OK, "get_width = %08x\n", hres); + cmp_length(v, "11"); + VariantClear(&v); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("11.9"); + hres = IHTMLTable_put_width(table, v); + ok(hres == S_OK, "put_width = %08x\n", hres); + VariantClear(&v); + IHTMLTable_get_width(table, &v); + ok(hres == S_OK, "get_width = %08x\n", hres); + cmp_length(v, "11"); + VariantClear(&v); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("40.2%"); + hres = IHTMLTable_put_width(table, v); + ok(hres == S_OK, "put_width = %08x\n", hres); + VariantClear(&v); + IHTMLTable_get_width(table, &v); + ok(hres == S_OK, "get_width = %08x\n", hres); + cmp_length(v, "40.2%"); + VariantClear(&v); + + V_VT(&v) = VT_I4; + V_I4(&v) = 11; + hres = IHTMLTable_put_width(table, v); + ok(hres == S_OK, "put_width = %08x\n", hres); + IHTMLTable_get_width(table, &v); + ok(hres == S_OK, "get_width = %08x\n", hres); + cmp_length(v, "11"); + VariantClear(&v); + + V_VT(&v) = VT_R8; + V_R8(&v) = 11.9; + hres = IHTMLTable_put_width(table, v); + ok(hres == S_OK, "put_width = %08x\n", hres); + IHTMLTable_get_width(table, &v); + ok(hres == S_OK, "get_width = %08x\n", hres); + cmp_length(v, "11"); + VariantClear(&v); + IHTMLTable_Release(table); }