From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/uiautomationcore/tests/uiautomation.c | 177 ++++++++++++++++++++- 1 file changed, 176 insertions(+), 1 deletion(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index f34f020b814..f9a6a352970 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -13310,13 +13310,19 @@ static const struct prov_method_sequence get_cached_prop_val_seq3[] = {
static void test_Element_cache_methods(IUIAutomation *uia_iface) { + static const int cache_test_props[] = { UIA_IsKeyboardFocusablePropertyId, UIA_NamePropertyId, UIA_ControlTypePropertyId, + UIA_BoundingRectanglePropertyId, UIA_HasKeyboardFocusPropertyId, }; HWND hwnd = create_test_hwnd("test_Element_cache_methods class"); IUIAutomationElement *element, *element2, *element3; + struct Provider_prop_override prop_override; IUIAutomationCacheRequest *cache_req; IUIAutomationElementArray *elem_arr; - int tmp_rt_id[2], i, len; + int tmp_rt_id[2], i, len, tmp_int; IUnknown *unk_ns; + BSTR tmp_bstr; + BOOL tmp_bool; HRESULT hr; + RECT rect; VARIANT v;
element = create_test_element_from_hwnd(uia_iface, hwnd, TRUE); @@ -13534,6 +13540,175 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface) ok(Provider.ref == 1, "Unexpected refcnt %ld\n", Provider.ref); IUnknown_Release(unk_ns);
+ /* + * Windows 7 will call get_FragmentRoot in an endless loop until the fragment root returns an HWND. + * It's the only version with this behavior. + */ + if (!UiaLookupId(AutomationIdentifierType_Property, &OptimizeForVisualContent_Property_GUID)) + { + win_skip("Skipping cached UIA_BoundingRectanglePropertyId tests for Win7\n"); + goto exit; + } + + /* + * Cached property value helper function tests. + */ + element = create_test_element_from_hwnd(uia_iface, hwnd, TRUE); + method_sequences_enabled = FALSE; + + /* + * element has no cached values, element2 has cached values but they're + * all the equivalent of VT_EMPTY, element3 has valid cached values. + */ + cache_req = NULL; + hr = IUIAutomation_CreateCacheRequest(uia_iface, &cache_req); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!cache_req, "cache_req == NULL\n"); + + for (i = 0; i < ARRAY_SIZE(cache_test_props); i++) + { + hr = IUIAutomationCacheRequest_AddProperty(cache_req, cache_test_props[i]); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } + + /* element2, invalid values for all cached properties. */ + element2 = NULL; + Provider.ret_invalid_prop_type = TRUE; + set_uia_rect(&Provider.bounds_rect, 0, 0, 0, 0); + hr = IUIAutomationElement_BuildUpdatedCache(element, cache_req, &element2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!element2, "element3 == NULL\n"); + Provider.ret_invalid_prop_type = FALSE; + + /* element3, valid values for all cached properties. */ + V_VT(&v) = VT_I4; + V_I4(&v) = UIA_HyperlinkControlTypeId; + set_property_override(&prop_override, UIA_ControlTypePropertyId, &v); + set_provider_prop_override(&Provider, &prop_override, 1); + set_uia_rect(&Provider.bounds_rect, 0, 0, 50, 50); + + element3 = NULL; + hr = IUIAutomationElement_BuildUpdatedCache(element, cache_req, &element3); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!element3, "element3 == NULL\n"); + set_provider_prop_override(&Provider, NULL, 0); + + IUIAutomationCacheRequest_Release(cache_req); + + /* Cached UIA_HasKeyboardFocusPropertyId helper. */ + hr = IUIAutomationElement_get_CachedHasKeyboardFocus(element, NULL); + todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + tmp_bool = 0xdeadbeef; + hr = IUIAutomationElement_get_CachedHasKeyboardFocus(element, &tmp_bool); + todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(tmp_bool == 0xdeadbeef, "Unexpected tmp_bool %d\n", tmp_bool); + + tmp_bool = 0xdeadbeef; + hr = IUIAutomationElement_get_CachedHasKeyboardFocus(element2, &tmp_bool); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine ok(!tmp_bool, "tmp_bool != FALSE\n"); + + tmp_bool = FALSE; + hr = IUIAutomationElement_get_CachedHasKeyboardFocus(element3, &tmp_bool); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine ok(!!tmp_bool, "tmp_bool == FALSE\n"); + + /* Cached UIA_IsKeyboardFocusablePropertyId helper. */ + hr = IUIAutomationElement_get_CachedIsKeyboardFocusable(element, NULL); + todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + tmp_bool = 0xdeadbeef; + hr = IUIAutomationElement_get_CachedIsKeyboardFocusable(element, &tmp_bool); + todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(tmp_bool == 0xdeadbeef, "Unexpected tmp_bool %d\n", tmp_bool); + + tmp_bool = 0xdeadbeef; + hr = IUIAutomationElement_get_CachedIsKeyboardFocusable(element2, &tmp_bool); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine ok(!tmp_bool, "tmp_bool != FALSE\n"); + + tmp_bool = FALSE; + hr = IUIAutomationElement_get_CachedIsKeyboardFocusable(element3, &tmp_bool); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine ok(!!tmp_bool, "tmp_bool == FALSE\n"); + + /* Cached UIA_NamePropertyId helper. */ + hr = IUIAutomationElement_get_CachedName(element, NULL); + todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + tmp_bstr = (void *)0xdeadbeef; + hr = IUIAutomationElement_get_CachedName(element, &tmp_bstr); + todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(tmp_bstr == (void *)0xdeadbeef, "Unexpected BSTR ptr %p\n", tmp_bstr); + + tmp_bstr = NULL; + hr = IUIAutomationElement_get_CachedName(element2, &tmp_bstr); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + ok(!lstrcmpW(tmp_bstr, L""), "Unexpected BSTR %s\n", wine_dbgstr_w(tmp_bstr)); + SysFreeString(tmp_bstr); + + tmp_bstr = NULL; + hr = IUIAutomationElement_get_CachedName(element3, &tmp_bstr); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + ok(!lstrcmpW(tmp_bstr, uia_bstr_prop_str), "Unexpected BSTR %s\n", wine_dbgstr_w(tmp_bstr)); + SysFreeString(tmp_bstr); + + /* Cached UIA_ControlTypePropertyId. */ + hr = IUIAutomationElement_get_CachedControlType(element, NULL); + todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + tmp_int = 0xdeadbeef; + hr = IUIAutomationElement_get_CachedControlType(element, &tmp_int); + todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(tmp_int == 0xdeadbeef, "Unexpected control type %#x\n", tmp_int); + + tmp_int = 0; + hr = IUIAutomationElement_get_CachedControlType(element2, &tmp_int); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine ok(tmp_int == UIA_CustomControlTypeId, "Unexpected control type %#x\n", tmp_int); + + tmp_int = 0; + hr = IUIAutomationElement_get_CachedControlType(element3, &tmp_int); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine ok(tmp_int == UIA_HyperlinkControlTypeId, "Unexpected control type %#x\n", tmp_int); + + /* Cached UIA_BoundingRectanglePropertyId helper. */ + hr = IUIAutomationElement_get_CachedBoundingRectangle(element, NULL); + todo_wine 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(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); + ok(rect.bottom == 1, "Unexpected rect bottom %ld\n", rect.bottom); + + 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); + + 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); + + IUIAutomationElement_Release(element3); + IUIAutomationElement_Release(element2); + IUIAutomationElement_Release(element); + + set_uia_rect(&Provider.bounds_rect, 0, 0, 0, 0); + method_sequences_enabled = TRUE; + +exit: DestroyWindow(hwnd); UnregisterClassA("test_Element_cache_methods class", NULL); }
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/uiautomationcore/tests/uiautomation.c | 12 +++--- dlls/uiautomationcore/uia_com_client.c | 43 ++++++++++++++++------ 2 files changed, 37 insertions(+), 18 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index f9a6a352970..b2ffc62fdfc 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -13658,22 +13658,22 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface)
/* Cached UIA_ControlTypePropertyId. */ hr = IUIAutomationElement_get_CachedControlType(element, NULL); - todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
tmp_int = 0xdeadbeef; hr = IUIAutomationElement_get_CachedControlType(element, &tmp_int); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(tmp_int == 0xdeadbeef, "Unexpected control type %#x\n", tmp_int);
tmp_int = 0; hr = IUIAutomationElement_get_CachedControlType(element2, &tmp_int); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(tmp_int == UIA_CustomControlTypeId, "Unexpected control type %#x\n", tmp_int); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(tmp_int == UIA_CustomControlTypeId, "Unexpected control type %#x\n", tmp_int);
tmp_int = 0; hr = IUIAutomationElement_get_CachedControlType(element3, &tmp_int); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(tmp_int == UIA_HyperlinkControlTypeId, "Unexpected control type %#x\n", tmp_int); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(tmp_int == UIA_HyperlinkControlTypeId, "Unexpected control type %#x\n", tmp_int);
/* Cached UIA_BoundingRectanglePropertyId helper. */ hr = IUIAutomationElement_get_CachedBoundingRectangle(element, NULL); diff --git a/dlls/uiautomationcore/uia_com_client.c b/dlls/uiautomationcore/uia_com_client.c index d138d4ed919..e47c64c479b 100644 --- a/dlls/uiautomationcore/uia_com_client.c +++ b/dlls/uiautomationcore/uia_com_client.c @@ -2143,27 +2143,33 @@ static HRESULT WINAPI uia_element_get_CurrentProcessId(IUIAutomationElement9 *if return E_NOTIMPL; }
+static void uia_elem_get_control_type(VARIANT *v, CONTROLTYPEID *ret_val) +{ + const struct uia_control_type_info *info = NULL; + + *ret_val = UIA_CustomControlTypeId; + if (V_VT(v) != VT_I4) + return; + + if ((info = uia_control_type_info_from_id(V_I4(v)))) + *ret_val = info->control_type_id; + else + WARN("Provider returned invalid control type ID %ld\n", V_I4(v)); +} + static HRESULT WINAPI uia_element_get_CurrentControlType(IUIAutomationElement9 *iface, CONTROLTYPEID *ret_val) { struct uia_element *element = impl_from_IUIAutomationElement9(iface); - const struct uia_control_type_info *control_type_info = NULL; HRESULT hr; VARIANT v;
TRACE("%p, %p\n", iface, ret_val);
VariantInit(&v); - *ret_val = UIA_CustomControlTypeId; hr = UiaGetPropertyValue(element->node, UIA_ControlTypePropertyId, &v); - if (SUCCEEDED(hr) && V_VT(&v) == VT_I4) - { - if ((control_type_info = uia_control_type_info_from_id(V_I4(&v)))) - *ret_val = control_type_info->control_type_id; - else - WARN("Provider returned invalid control type ID %ld\n", V_I4(&v)); - } - + uia_elem_get_control_type(&v, ret_val); VariantClear(&v); + return hr; }
@@ -2393,8 +2399,21 @@ static HRESULT WINAPI uia_element_get_CachedProcessId(IUIAutomationElement9 *ifa
static HRESULT WINAPI uia_element_get_CachedControlType(IUIAutomationElement9 *iface, CONTROLTYPEID *ret_val) { - FIXME("%p: stub\n", iface); - return E_NOTIMPL; + struct uia_element *element = impl_from_IUIAutomationElement9(iface); + const int prop_id = UIA_ControlTypePropertyId; + 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_elem_get_control_type(&cache_prop->prop_val, ret_val); + return S_OK; }
static HRESULT WINAPI uia_element_get_CachedLocalizedControlType(IUIAutomationElement9 *iface, BSTR *ret_val)
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/uiautomationcore/tests/uiautomation.c | 12 ++++++------ dlls/uiautomationcore/uia_com_client.c | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index b2ffc62fdfc..f9a033c7002 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -13597,22 +13597,22 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface)
/* Cached UIA_HasKeyboardFocusPropertyId helper. */ hr = IUIAutomationElement_get_CachedHasKeyboardFocus(element, NULL); - todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
tmp_bool = 0xdeadbeef; hr = IUIAutomationElement_get_CachedHasKeyboardFocus(element, &tmp_bool); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(tmp_bool == 0xdeadbeef, "Unexpected tmp_bool %d\n", tmp_bool);
tmp_bool = 0xdeadbeef; hr = IUIAutomationElement_get_CachedHasKeyboardFocus(element2, &tmp_bool); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!tmp_bool, "tmp_bool != FALSE\n"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!tmp_bool, "tmp_bool != FALSE\n");
tmp_bool = FALSE; hr = IUIAutomationElement_get_CachedHasKeyboardFocus(element3, &tmp_bool); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!!tmp_bool, "tmp_bool == FALSE\n"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!tmp_bool, "tmp_bool == FALSE\n");
/* Cached UIA_IsKeyboardFocusablePropertyId helper. */ hr = IUIAutomationElement_get_CachedIsKeyboardFocusable(element, NULL); diff --git a/dlls/uiautomationcore/uia_com_client.c b/dlls/uiautomationcore/uia_com_client.c index e47c64c479b..d949b3c0a92 100644 --- a/dlls/uiautomationcore/uia_com_client.c +++ b/dlls/uiautomationcore/uia_com_client.c @@ -2442,8 +2442,21 @@ static HRESULT WINAPI uia_element_get_CachedAccessKey(IUIAutomationElement9 *ifa
static HRESULT WINAPI uia_element_get_CachedHasKeyboardFocus(IUIAutomationElement9 *iface, BOOL *ret_val) { - FIXME("%p: stub\n", iface); - return E_NOTIMPL; + struct uia_element *element = impl_from_IUIAutomationElement9(iface); + const int prop_id = UIA_HasKeyboardFocusPropertyId; + 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; + + *ret_val = ((V_VT(&cache_prop->prop_val) == VT_BOOL) && (V_BOOL(&cache_prop->prop_val) == VARIANT_TRUE)); + return S_OK; }
static HRESULT WINAPI uia_element_get_CachedIsKeyboardFocusable(IUIAutomationElement9 *iface, BOOL *ret_val)
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/uiautomationcore/tests/uiautomation.c | 12 ++++++------ dlls/uiautomationcore/uia_com_client.c | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index f9a033c7002..960a2ec24de 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -13616,22 +13616,22 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface)
/* Cached UIA_IsKeyboardFocusablePropertyId helper. */ hr = IUIAutomationElement_get_CachedIsKeyboardFocusable(element, NULL); - todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
tmp_bool = 0xdeadbeef; hr = IUIAutomationElement_get_CachedIsKeyboardFocusable(element, &tmp_bool); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(tmp_bool == 0xdeadbeef, "Unexpected tmp_bool %d\n", tmp_bool);
tmp_bool = 0xdeadbeef; hr = IUIAutomationElement_get_CachedIsKeyboardFocusable(element2, &tmp_bool); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!tmp_bool, "tmp_bool != FALSE\n"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!tmp_bool, "tmp_bool != FALSE\n");
tmp_bool = FALSE; hr = IUIAutomationElement_get_CachedIsKeyboardFocusable(element3, &tmp_bool); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!!tmp_bool, "tmp_bool == FALSE\n"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!tmp_bool, "tmp_bool == FALSE\n");
/* Cached UIA_NamePropertyId helper. */ hr = IUIAutomationElement_get_CachedName(element, NULL); diff --git a/dlls/uiautomationcore/uia_com_client.c b/dlls/uiautomationcore/uia_com_client.c index d949b3c0a92..d517b680bdd 100644 --- a/dlls/uiautomationcore/uia_com_client.c +++ b/dlls/uiautomationcore/uia_com_client.c @@ -2461,8 +2461,21 @@ static HRESULT WINAPI uia_element_get_CachedHasKeyboardFocus(IUIAutomationElemen
static HRESULT WINAPI uia_element_get_CachedIsKeyboardFocusable(IUIAutomationElement9 *iface, BOOL *ret_val) { - FIXME("%p: stub\n", iface); - return E_NOTIMPL; + struct uia_element *element = impl_from_IUIAutomationElement9(iface); + const int prop_id = UIA_IsKeyboardFocusablePropertyId; + 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; + + *ret_val = ((V_VT(&cache_prop->prop_val) == VT_BOOL) && (V_BOOL(&cache_prop->prop_val) == VARIANT_TRUE)); + return S_OK; }
static HRESULT WINAPI uia_element_get_CachedIsEnabled(IUIAutomationElement9 *iface, BOOL *ret_val)
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/uiautomationcore/tests/uiautomation.c | 14 ++++++-------- dlls/uiautomationcore/uia_com_client.c | 21 +++++++++++++++++++-- 2 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index 960a2ec24de..424443ae0fa 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -13635,25 +13635,23 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface)
/* Cached UIA_NamePropertyId helper. */ hr = IUIAutomationElement_get_CachedName(element, NULL); - todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
tmp_bstr = (void *)0xdeadbeef; hr = IUIAutomationElement_get_CachedName(element, &tmp_bstr); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(tmp_bstr == (void *)0xdeadbeef, "Unexpected BSTR ptr %p\n", tmp_bstr);
tmp_bstr = NULL; hr = IUIAutomationElement_get_CachedName(element2, &tmp_bstr); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - ok(!lstrcmpW(tmp_bstr, L""), "Unexpected BSTR %s\n", wine_dbgstr_w(tmp_bstr)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!lstrcmpW(tmp_bstr, L""), "Unexpected BSTR %s\n", wine_dbgstr_w(tmp_bstr)); SysFreeString(tmp_bstr);
tmp_bstr = NULL; hr = IUIAutomationElement_get_CachedName(element3, &tmp_bstr); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - ok(!lstrcmpW(tmp_bstr, uia_bstr_prop_str), "Unexpected BSTR %s\n", wine_dbgstr_w(tmp_bstr)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!lstrcmpW(tmp_bstr, uia_bstr_prop_str), "Unexpected BSTR %s\n", wine_dbgstr_w(tmp_bstr)); SysFreeString(tmp_bstr);
/* Cached UIA_ControlTypePropertyId. */ diff --git a/dlls/uiautomationcore/uia_com_client.c b/dlls/uiautomationcore/uia_com_client.c index d517b680bdd..d383abe0d9b 100644 --- a/dlls/uiautomationcore/uia_com_client.c +++ b/dlls/uiautomationcore/uia_com_client.c @@ -2424,8 +2424,25 @@ static HRESULT WINAPI uia_element_get_CachedLocalizedControlType(IUIAutomationEl
static HRESULT WINAPI uia_element_get_CachedName(IUIAutomationElement9 *iface, BSTR *ret_val) { - FIXME("%p: stub\n", iface); - return E_NOTIMPL; + struct uia_element *element = impl_from_IUIAutomationElement9(iface); + struct uia_cache_property *cache_prop = NULL; + const int prop_id = UIA_NamePropertyId; + + 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; + + if ((V_VT(&cache_prop->prop_val) == VT_BSTR) && V_BSTR(&cache_prop->prop_val)) + *ret_val = SysAllocString(V_BSTR(&cache_prop->prop_val)); + else + *ret_val = SysAllocString(L""); + + return S_OK; }
static HRESULT WINAPI uia_element_get_CachedAcceleratorKey(IUIAutomationElement9 *iface, BSTR *ret_val)
From: Connor McAdams cmcadams@codeweavers.com
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 424443ae0fa..c659d495b49 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)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=138822
Your paranoid android.
=== w10pro64_zh_CN (64 bit report) ===
uiautomationcore: uiautomation.c:14778: Test failed: expected prov_callback_base_hwnd 1 times (got 0) uiautomation.c:14779: Test failed: expected prov_callback_nonclient 1 times (got 0) uiautomation.c:14780: Test failed: expected winproc_GETOBJECT_UiaRoot 1 times (got 0)
Esme Povirk (@madewokherd) commented about dlls/uiautomationcore/tests/uiautomation.c:
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- ok(!!cache_req, "cache_req == NULL\n");
- for (i = 0; i < ARRAY_SIZE(cache_test_props); i++)
- {
hr = IUIAutomationCacheRequest_AddProperty(cache_req, cache_test_props[i]);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- }
- /* element2, invalid values for all cached properties. */
- element2 = NULL;
- Provider.ret_invalid_prop_type = TRUE;
- set_uia_rect(&Provider.bounds_rect, 0, 0, 0, 0);
- hr = IUIAutomationElement_BuildUpdatedCache(element, cache_req, &element2);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- ok(!!element2, "element3 == NULL\n");
Typo in message.