Module: wine Branch: master Commit: 27aed609c6ea0c2c06e5e66d957695bd5480641d URL: https://gitlab.winehq.org/wine/wine/-/commit/27aed609c6ea0c2c06e5e66d957695b...
Author: Connor McAdams cmcadams@codeweavers.com Date: Thu Sep 21 11:31:49 2023 -0400
uiautomationcore: Implement IUIAutomationElement::get_CachedBoundingRectangle.
Signed-off-by: Connor McAdams cmcadams@codeweavers.com
---
dlls/uiautomationcore/tests/uiautomation.c | 19 +++++----- dlls/uiautomationcore/uia_com_client.c | 58 +++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 26 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index 2f2a5e1329c..b527e5bf98d 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -13675,11 +13675,11 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface)
/* Cached UIA_BoundingRectanglePropertyId helper. */ hr = IUIAutomationElement_get_CachedBoundingRectangle(element, NULL); - todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
rect.left = rect.top = rect.bottom = rect.right = 1; hr = IUIAutomationElement_get_CachedBoundingRectangle(element, &rect); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(rect.left == 1, "Unexpected rect left %ld\n", rect.left); ok(rect.top == 1, "Unexpected rect top %ld\n", rect.top); ok(rect.right == 1, "Unexpected rect right %ld\n", rect.right); @@ -13687,17 +13687,16 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface)
rect.left = rect.top = rect.bottom = rect.right = 1; hr = IUIAutomationElement_get_CachedBoundingRectangle(element2, &rect); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!rect.left, "Unexpected rect left %ld\n", rect.left); - todo_wine ok(!rect.top, "Unexpected rect top %ld\n", rect.top); - todo_wine ok(!rect.right, "Unexpected rect right %ld\n", rect.right); - todo_wine ok(!rect.bottom, "Unexpected rect bottom %ld\n", rect.bottom); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!rect.left, "Unexpected rect left %ld\n", rect.left); + ok(!rect.top, "Unexpected rect top %ld\n", rect.top); + ok(!rect.right, "Unexpected rect right %ld\n", rect.right); + ok(!rect.bottom, "Unexpected rect bottom %ld\n", rect.bottom);
memset(&rect, 0, sizeof(rect)); hr = IUIAutomationElement_get_CachedBoundingRectangle(element3, &rect); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - check_uia_rect_rect_val(&rect, &Provider.bounds_rect); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_uia_rect_rect_val(&rect, &Provider.bounds_rect);
IUIAutomationElement_Release(element3); IUIAutomationElement_Release(element2); diff --git a/dlls/uiautomationcore/uia_com_client.c b/dlls/uiautomationcore/uia_com_client.c index d383abe0d9b..5c0d0cd0b9e 100644 --- a/dlls/uiautomationcore/uia_com_client.c +++ b/dlls/uiautomationcore/uia_com_client.c @@ -2312,6 +2312,32 @@ static HRESULT WINAPI uia_element_get_CurrentItemStatus(IUIAutomationElement9 *i return E_NOTIMPL; }
+static void uia_variant_rect_to_rect(VARIANT *v, RECT *ret_val) +{ + double *vals; + HRESULT hr; + + memset(ret_val, 0, sizeof(*ret_val)); + if (V_VT(v) != (VT_R8 | VT_ARRAY)) + return; + + hr = SafeArrayAccessData(V_ARRAY(v), (void **)&vals); + if (FAILED(hr)) + { + WARN("SafeArrayAccessData failed with hr %#lx\n", hr); + return; + } + + ret_val->left = vals[0]; + ret_val->top = vals[1]; + ret_val->right = ret_val->left + vals[2]; + ret_val->bottom = ret_val->top + vals[3]; + + hr = SafeArrayUnaccessData(V_ARRAY(v)); + if (FAILED(hr)) + WARN("SafeArrayUnaccessData failed with hr %#lx\n", hr); +} + static HRESULT WINAPI uia_element_get_CurrentBoundingRectangle(IUIAutomationElement9 *iface, RECT *ret_val) { struct uia_element *element = impl_from_IUIAutomationElement9(iface); @@ -2320,22 +2346,9 @@ static HRESULT WINAPI uia_element_get_CurrentBoundingRectangle(IUIAutomationElem
TRACE("%p, %p\n", element, ret_val);
- memset(ret_val, 0, sizeof(*ret_val)); VariantInit(&v); hr = UiaGetPropertyValue(element->node, UIA_BoundingRectanglePropertyId, &v); - if (SUCCEEDED(hr) && V_VT(&v) == (VT_R8 | VT_ARRAY)) - { - double vals[4]; - LONG idx; - - for (idx = 0; idx < ARRAY_SIZE(vals); idx++) - SafeArrayGetElement(V_ARRAY(&v), &idx, &vals[idx]); - - ret_val->left = vals[0]; - ret_val->top = vals[1]; - ret_val->right = ret_val->left + vals[2]; - ret_val->bottom = ret_val->top + vals[3]; - } + uia_variant_rect_to_rect(&v, ret_val);
VariantClear(&v); return hr; @@ -2588,8 +2601,21 @@ static HRESULT WINAPI uia_element_get_CachedItemStatus(IUIAutomationElement9 *if
static HRESULT WINAPI uia_element_get_CachedBoundingRectangle(IUIAutomationElement9 *iface, RECT *ret_val) { - FIXME("%p: stub\n", iface); - return E_NOTIMPL; + struct uia_element *element = impl_from_IUIAutomationElement9(iface); + const int prop_id = UIA_BoundingRectanglePropertyId; + struct uia_cache_property *cache_prop = NULL; + + TRACE("%p, %p\n", iface, ret_val); + + if (!ret_val) + return E_POINTER; + + if (!(cache_prop = bsearch(&prop_id, element->cached_props, element->cached_props_count, sizeof(*cache_prop), + uia_cached_property_id_compare))) + return E_INVALIDARG; + + uia_variant_rect_to_rect(&cache_prop->prop_val, ret_val); + return S_OK; }
static HRESULT WINAPI uia_element_get_CachedLabeledBy(IUIAutomationElement9 *iface, IUIAutomationElement **ret_val)