uiautomationcore: Implement IUIAutomationCacheRequest::AddProperty.

Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
Connor McAdams 2023-03-07 13:41:50 -05:00 committed by Alexandre Julliard
parent b9410e8c39
commit 29a4e096d7
6 changed files with 85 additions and 40 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -23,7 +23,6 @@
#include "uia_private.h"
#include "wine/debug.h"
#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);

View file

@ -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;

View file

@ -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"