Commit 98027dd6 authored by Connor McAdams's avatar Connor McAdams Committed by Alexandre Julliard

uiautomationcore: Implement IUIAutomationElement::BuildUpdatedCache.

parent 062584af
......@@ -10792,12 +10792,12 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface)
}
hr = IUIAutomationElement_BuildUpdatedCache(element, cache_req, NULL);
todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
element2 = (void *)0xdeadbeef;
hr = IUIAutomationElement_BuildUpdatedCache(element, NULL, &element2);
todo_wine ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
todo_wine ok(!element2, "element2 != NULL\n");
ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
ok(!element2, "element2 != NULL\n");
/*
* Test cached property values. The default IUIAutomationCacheRequest
......@@ -10805,47 +10805,41 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface)
*/
element2 = NULL;
hr = IUIAutomationElement_BuildUpdatedCache(element, cache_req, &element2);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(!!element2, "element2 == NULL\n");
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(!!element2, "element2 == NULL\n");
ok_method_sequence(get_cached_prop_val_seq, "get_cached_prop_val_seq");
if (element2)
{
/* RuntimeId is currently unset, so we'll get the NotSupported value. */
hr = IUIAutomationElement_GetCachedPropertyValueEx(element2, UIA_RuntimeIdPropertyId, TRUE, &v);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(V_VT(&v) == VT_UNKNOWN, "Unexpected vt %d\n", V_VT(&v));
if (SUCCEEDED(hr))
ok(V_UNKNOWN(&v) == unk_ns, "unexpected IUnknown %p\n", V_UNKNOWN(&v));
VariantClear(&v);
/* RuntimeId is currently unset, so we'll get the NotSupported value. */
hr = IUIAutomationElement_GetCachedPropertyValueEx(element2, UIA_RuntimeIdPropertyId, TRUE, &v);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(V_VT(&v) == VT_UNKNOWN, "Unexpected vt %d\n", V_VT(&v));
if (SUCCEEDED(hr))
ok(V_UNKNOWN(&v) == unk_ns, "unexpected IUnknown %p\n", V_UNKNOWN(&v));
VariantClear(&v);
/* Attempting to get a cached value for a non-cached property. */
hr = IUIAutomationElement_GetCachedPropertyValueEx(element2, UIA_IsControlElementPropertyId, TRUE, &v);
todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
ok(V_VT(&v) == VT_EMPTY, "Unexpected vt %d\n", V_VT(&v));
VariantClear(&v);
/* Attempting to get a cached value for a non-cached property. */
hr = IUIAutomationElement_GetCachedPropertyValueEx(element2, UIA_IsControlElementPropertyId, TRUE, &v);
todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
ok(V_VT(&v) == VT_EMPTY, "Unexpected vt %d\n", V_VT(&v));
VariantClear(&v);
IUIAutomationElement_Release(element2);
}
IUIAutomationElement_Release(element2);
/* RuntimeId is now set. */
Provider_child.runtime_id[0] = Provider_child.runtime_id[1] = 0xdeadbeef;
element2 = NULL;
hr = IUIAutomationElement_BuildUpdatedCache(element, cache_req, &element2);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(!!element2, "element2 == NULL\n");
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(!!element2, "element2 == NULL\n");
ok_method_sequence(get_cached_prop_val_seq, "get_cached_prop_val_seq");
if (element2)
{
hr = IUIAutomationElement_GetCachedPropertyValueEx(element2, UIA_RuntimeIdPropertyId, TRUE, &v);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(V_VT(&v) == (VT_I4 | VT_ARRAY), "Unexpected vt %d\n", V_VT(&v));
if (SUCCEEDED(hr))
check_runtime_id(Provider_child.runtime_id, ARRAY_SIZE(Provider_child.runtime_id), V_ARRAY(&v));
VariantClear(&v);
IUIAutomationElement_Release(element2);
}
hr = IUIAutomationElement_GetCachedPropertyValueEx(element2, UIA_RuntimeIdPropertyId, TRUE, &v);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(V_VT(&v) == (VT_I4 | VT_ARRAY), "Unexpected vt %d\n", V_VT(&v));
if (SUCCEEDED(hr))
check_runtime_id(Provider_child.runtime_id, ARRAY_SIZE(Provider_child.runtime_id), V_ARRAY(&v));
VariantClear(&v);
IUIAutomationElement_Release(element2);
/*
* Add UIA_IsControlElementPropertyId to the list of cached property
......@@ -10857,26 +10851,23 @@ static void test_Element_cache_methods(IUIAutomation *uia_iface)
Provider_child.runtime_id[0] = Provider_child.runtime_id[1] = 0xdeadb33f;
element2 = NULL;
hr = IUIAutomationElement_BuildUpdatedCache(element, cache_req, &element2);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(!!element2, "element2 == NULL\n");
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(!!element2, "element2 == NULL\n");
ok_method_sequence(get_cached_prop_val_seq2, "get_cached_prop_val_seq2");
if (element2)
{
hr = IUIAutomationElement_GetCachedPropertyValueEx(element2, UIA_RuntimeIdPropertyId, TRUE, &v);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(V_VT(&v) == (VT_I4 | VT_ARRAY), "Unexpected vt %d\n", V_VT(&v));
if (SUCCEEDED(hr))
check_runtime_id(Provider_child.runtime_id, ARRAY_SIZE(Provider_child.runtime_id), V_ARRAY(&v));
VariantClear(&v);
hr = IUIAutomationElement_GetCachedPropertyValueEx(element2, UIA_RuntimeIdPropertyId, TRUE, &v);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(V_VT(&v) == (VT_I4 | VT_ARRAY), "Unexpected vt %d\n", V_VT(&v));
if (SUCCEEDED(hr))
check_runtime_id(Provider_child.runtime_id, ARRAY_SIZE(Provider_child.runtime_id), V_ARRAY(&v));
VariantClear(&v);
hr = IUIAutomationElement_GetCachedPropertyValueEx(element2, UIA_IsControlElementPropertyId, TRUE, &v);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(check_variant_bool(&v, TRUE), "V_BOOL(&v) = %#x\n", V_BOOL(&v));
VariantClear(&v);
hr = IUIAutomationElement_GetCachedPropertyValueEx(element2, UIA_IsControlElementPropertyId, TRUE, &v);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(check_variant_bool(&v, TRUE), "V_BOOL(&v) = %#x\n", V_BOOL(&v));
VariantClear(&v);
IUIAutomationElement_Release(element2);
}
IUIAutomationElement_Release(element2);
IUIAutomationElement_Release(element);
ok(Provider_child.ref == 1, "Unexpected refcnt %ld\n", Provider_child.ref);
......
......@@ -851,6 +851,24 @@ static HRESULT create_uia_cache_request_iface(IUIAutomationCacheRequest **out_ca
return S_OK;
}
static HRESULT get_uia_cache_request_struct_from_iface(IUIAutomationCacheRequest *cache_request,
struct UiaCacheRequest **cache_req_struct)
{
struct uia_cache_request *cache_req_data;
*cache_req_struct = NULL;
if (!cache_request)
return E_POINTER;
if (cache_request->lpVtbl != &uia_cache_request_vtbl)
return E_FAIL;
cache_req_data = impl_from_IUIAutomationCacheRequest(cache_request);
*cache_req_struct = &cache_req_data->cache_req;
return S_OK;
}
/*
* IUIAutomationElementArray interface.
*/
......@@ -1071,11 +1089,38 @@ static HRESULT WINAPI uia_element_FindAllBuildCache(IUIAutomationElement9 *iface
return E_NOTIMPL;
}
static HRESULT create_uia_element_from_cache_req(IUIAutomationElement **iface, BOOL from_cui8, SAFEARRAY *req_data,
BSTR tree_struct);
static HRESULT WINAPI uia_element_BuildUpdatedCache(IUIAutomationElement9 *iface, IUIAutomationCacheRequest *cache_req,
IUIAutomationElement **updated_elem)
{
FIXME("%p: stub\n", iface);
return E_NOTIMPL;
struct uia_element *element = impl_from_IUIAutomationElement9(iface);
struct UiaCacheRequest *cache_req_struct;
IUIAutomationElement *cache_elem;
BSTR tree_struct;
SAFEARRAY *sa;
HRESULT hr;
TRACE("%p, %p, %p\n", iface, cache_req, updated_elem);
if (!updated_elem)
return E_POINTER;
*updated_elem = NULL;
hr = get_uia_cache_request_struct_from_iface(cache_req, &cache_req_struct);
if (FAILED(hr))
return hr;
hr = UiaGetUpdatedCache(element->node, cache_req_struct, NormalizeState_None, NULL, &sa, &tree_struct);
if (FAILED(hr))
return hr;
hr = create_uia_element_from_cache_req(&cache_elem, element->from_cui8, sa, tree_struct);
if (SUCCEEDED(hr))
*updated_elem = cache_elem;
SafeArrayDestroy(sa);
return S_OK;
}
static HRESULT WINAPI uia_element_GetCurrentPropertyValue(IUIAutomationElement9 *iface, PROPERTYID prop_id,
......@@ -2062,6 +2107,37 @@ static HRESULT create_uia_element(IUIAutomationElement **iface, BOOL from_cui8,
return S_OK;
}
static HRESULT create_uia_element_from_cache_req(IUIAutomationElement **iface, BOOL from_cui8, SAFEARRAY *req_data,
BSTR tree_struct)
{
HUIANODE node;
LONG idx[2];
HRESULT hr;
VARIANT v;
*iface = NULL;
VariantInit(&v);
idx[0] = idx[1] = 0;
hr = SafeArrayGetElement(req_data, idx, &v);
if (FAILED(hr))
goto exit;
hr = UiaHUiaNodeFromVariant(&v, &node);
if (FAILED(hr))
goto exit;
VariantClear(&v);
hr = create_uia_element(iface, from_cui8, node);
exit:
if (FAILED(hr))
WARN("Failed to create element from cache request, hr %#lx\n", hr);
SysFreeString(tree_struct);
return hr;
}
/*
* IUIAutomation interface.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment