From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/uiautomationcore/tests/uiautomation.c | 89 ++++++++++------------ dlls/uiautomationcore/uia_com_client.c | 80 ++++++++++++++++++- 2 files changed, 118 insertions(+), 51 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index 193ea1a89a7..ac9c7f07242 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -10787,12 +10787,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 @@ -10800,47 +10800,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 @@ -10852,26 +10846,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); diff --git a/dlls/uiautomationcore/uia_com_client.c b/dlls/uiautomationcore/uia_com_client.c index 598739746d6..ff9688125be 100644 --- a/dlls/uiautomationcore/uia_com_client.c +++ b/dlls/uiautomationcore/uia_com_client.c @@ -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. */