Module: wine Branch: master Commit: 29a4e096d76a2e26ff377766c049ddb352751b40 URL: https://gitlab.winehq.org/wine/wine/-/commit/29a4e096d76a2e26ff377766c049ddb...
Author: Connor McAdams cmcadams@codeweavers.com Date: Tue Mar 7 13:41:50 2023 -0500
uiautomationcore: Implement IUIAutomationCacheRequest::AddProperty.
Signed-off-by: Connor McAdams cmcadams@codeweavers.com
---
dlls/uiautomationcore/tests/uiautomation.c | 18 ++++++++++--- dlls/uiautomationcore/uia_client.c | 31 --------------------- dlls/uiautomationcore/uia_com_client.c | 43 +++++++++++++++++++++++++++--- dlls/uiautomationcore/uia_main.c | 1 - dlls/uiautomationcore/uia_private.h | 31 +++++++++++++++++++++ dlls/uiautomationcore/uia_provider.c | 1 - 6 files changed, 85 insertions(+), 40 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index 715629cd8df..41bd168e3c6 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -10839,6 +10839,16 @@ static void test_CUIAutomation_cache_request_iface(IUIAutomation *uia_iface) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); todo_wine ok(elem_mode == AutomationElementMode_None, "Unexpected element mode %#x\n", elem_mode);
+ /* + * AddProperty tests. + */ + hr = IUIAutomationCacheRequest_AddProperty(cache_req, UIA_IsContentElementPropertyId); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* Invalid property ID. */ + hr = IUIAutomationCacheRequest_AddProperty(cache_req, 1); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + IUIAutomationCacheRequest_Release(cache_req); }
@@ -10849,13 +10859,13 @@ static const struct prov_method_sequence get_elem_cache_seq[] = { };
static const struct prov_method_sequence get_cached_prop_val_seq[] = { - { &Provider_child, FRAG_GET_RUNTIME_ID, METHOD_TODO }, + { &Provider_child, FRAG_GET_RUNTIME_ID }, { 0 }, };
static const struct prov_method_sequence get_cached_prop_val_seq2[] = { - { &Provider_child, FRAG_GET_RUNTIME_ID, METHOD_TODO }, - { &Provider_child, PROV_GET_PROPERTY_VALUE, METHOD_TODO }, /* UIA_IsControlElementPropertyId */ + { &Provider_child, FRAG_GET_RUNTIME_ID }, + { &Provider_child, PROV_GET_PROPERTY_VALUE }, /* UIA_IsControlElementPropertyId */ { 0 }, };
@@ -10963,7 +10973,7 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface) * values. */ hr = IUIAutomationCacheRequest_AddProperty(cache_req, UIA_IsControlElementPropertyId); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
Provider_child.runtime_id[0] = Provider_child.runtime_id[1] = 0xdeadb33f; element2 = NULL; diff --git a/dlls/uiautomationcore/uia_client.c b/dlls/uiautomationcore/uia_client.c index 4de9dc1919e..195974c25f6 100644 --- a/dlls/uiautomationcore/uia_client.c +++ b/dlls/uiautomationcore/uia_client.c @@ -19,42 +19,11 @@ #include "uia_private.h"
#include "wine/debug.h" -#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
static const struct UiaCondition UiaFalseCondition = { ConditionType_False };
-static BOOL uia_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) -{ - SIZE_T max_capacity, new_capacity; - void *new_elements; - - if (count <= *capacity) - return TRUE; - - max_capacity = ~(SIZE_T)0 / size; - if (count > max_capacity) - return FALSE; - - new_capacity = max(1, *capacity); - while (new_capacity < count && new_capacity <= max_capacity / 2) - new_capacity *= 2; - if (new_capacity < count) - new_capacity = count; - - if (!*elements) - new_elements = heap_alloc_zero(new_capacity * size); - else - new_elements = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *elements, new_capacity * size); - if (!new_elements) - return FALSE; - - *elements = new_elements; - *capacity = new_capacity; - return TRUE; -} - struct uia_node_array { HUIANODE *nodes; int node_count; diff --git a/dlls/uiautomationcore/uia_com_client.c b/dlls/uiautomationcore/uia_com_client.c index 44d715684c1..2b499fa8bc5 100644 --- a/dlls/uiautomationcore/uia_com_client.c +++ b/dlls/uiautomationcore/uia_com_client.c @@ -19,7 +19,6 @@ #include "uia_private.h"
#include "wine/debug.h" -#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
@@ -632,6 +631,10 @@ struct uia_cache_request {
IUIAutomationCondition *view_condition; struct UiaCacheRequest cache_req; + + int *prop_ids; + int prop_ids_count; + SIZE_T prop_ids_arr_size; };
static inline struct uia_cache_request *impl_from_IUIAutomationCacheRequest(IUIAutomationCacheRequest *iface) @@ -670,6 +673,7 @@ static ULONG WINAPI uia_cache_request_Release(IUIAutomationCacheRequest *iface) if (!ref) { IUIAutomationCondition_Release(uia_cache_request->view_condition); + heap_free(uia_cache_request->prop_ids); heap_free(uia_cache_request); }
@@ -678,8 +682,33 @@ static ULONG WINAPI uia_cache_request_Release(IUIAutomationCacheRequest *iface)
static HRESULT WINAPI uia_cache_request_AddProperty(IUIAutomationCacheRequest *iface, PROPERTYID prop_id) { - FIXME("%p, %d: stub\n", iface, prop_id); - return E_NOTIMPL; + struct uia_cache_request *uia_cache_request = impl_from_IUIAutomationCacheRequest(iface); + const struct uia_prop_info *prop_info = uia_prop_info_from_id(prop_id); + int i; + + TRACE("%p, %d\n", iface, prop_id); + + if (!prop_info) + return E_INVALIDARG; + + /* Don't add a duplicate property to the cache request. */ + for (i = 0; i < uia_cache_request->prop_ids_count; i++) + { + if (uia_cache_request->prop_ids[i] == prop_id) + return S_OK; + } + + if (!uia_array_reserve((void **)&uia_cache_request->prop_ids, &uia_cache_request->prop_ids_arr_size, + uia_cache_request->prop_ids_count + 1, sizeof(*uia_cache_request->prop_ids))) + return E_OUTOFMEMORY; + + uia_cache_request->prop_ids[uia_cache_request->prop_ids_count] = prop_id; + uia_cache_request->prop_ids_count++; + + uia_cache_request->cache_req.pProperties = uia_cache_request->prop_ids; + uia_cache_request->cache_req.cProperties = uia_cache_request->prop_ids_count; + + return S_OK; }
static HRESULT WINAPI uia_cache_request_AddPattern(IUIAutomationCacheRequest *iface, PATTERNID pattern_id) @@ -847,6 +876,14 @@ static HRESULT create_uia_cache_request_iface(IUIAutomationCacheRequest **out_ca uia_cache_request->cache_req.Scope = TreeScope_Element; uia_cache_request->cache_req.automationElementMode = AutomationElementMode_Full;
+ hr = IUIAutomationCacheRequest_AddProperty(&uia_cache_request->IUIAutomationCacheRequest_iface, + UIA_RuntimeIdPropertyId); + if (FAILED(hr)) + { + IUIAutomationCacheRequest_Release(&uia_cache_request->IUIAutomationCacheRequest_iface); + return hr; + } + *out_cache_req = &uia_cache_request->IUIAutomationCacheRequest_iface; return S_OK; } diff --git a/dlls/uiautomationcore/uia_main.c b/dlls/uiautomationcore/uia_main.c index aa297983867..d0ab909f102 100644 --- a/dlls/uiautomationcore/uia_main.c +++ b/dlls/uiautomationcore/uia_main.c @@ -23,7 +23,6 @@ #include "uia_private.h"
#include "wine/debug.h" -#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
diff --git a/dlls/uiautomationcore/uia_private.h b/dlls/uiautomationcore/uia_private.h index 2c6e41eac6d..f7e991ee4fd 100644 --- a/dlls/uiautomationcore/uia_private.h +++ b/dlls/uiautomationcore/uia_private.h @@ -21,6 +21,7 @@ #include "uiautomation.h" #include "uia_classes.h" #include "wine/list.h" +#include "wine/heap.h"
extern HMODULE huia_module DECLSPEC_HIDDEN;
@@ -98,6 +99,36 @@ static inline void variant_init_bool(VARIANT *v, BOOL val) V_BOOL(v) = val ? VARIANT_TRUE : VARIANT_FALSE; }
+static inline BOOL uia_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) +{ + SIZE_T max_capacity, new_capacity; + void *new_elements; + + if (count <= *capacity) + return TRUE; + + max_capacity = ~(SIZE_T)0 / size; + if (count > max_capacity) + return FALSE; + + new_capacity = max(1, *capacity); + while (new_capacity < count && new_capacity <= max_capacity / 2) + new_capacity *= 2; + if (new_capacity < count) + new_capacity = count; + + if (!*elements) + new_elements = heap_alloc_zero(new_capacity * size); + else + new_elements = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *elements, new_capacity * size); + if (!new_elements) + return FALSE; + + *elements = new_elements; + *capacity = new_capacity; + return TRUE; +} + /* uia_client.c */ HRESULT get_safearray_bounds(SAFEARRAY *sa, LONG *lbound, LONG *elems) DECLSPEC_HIDDEN; int uia_compare_safearrays(SAFEARRAY *sa1, SAFEARRAY *sa2, int prop_type) DECLSPEC_HIDDEN; diff --git a/dlls/uiautomationcore/uia_provider.c b/dlls/uiautomationcore/uia_provider.c index 58d1db9bae8..a7d41248abc 100644 --- a/dlls/uiautomationcore/uia_provider.c +++ b/dlls/uiautomationcore/uia_provider.c @@ -20,7 +20,6 @@ #include "ocidl.h"
#include "wine/debug.h" -#include "wine/heap.h" #include "wine/rbtree.h" #include "initguid.h" #include "wine/iaccessible2.h"