Module: wine Branch: master Commit: f36e1b9138aa5865ece2988d641767a4742c81a1 URL: https://gitlab.winehq.org/wine/wine/-/commit/f36e1b9138aa5865ece2988d641767a...
Author: Connor McAdams cmcadams@codeweavers.com Date: Wed Oct 12 13:54:28 2022 -0400
uiautomationcore: Add support for getting HWND providers to uia_node_from_lresult().
Signed-off-by: Connor McAdams cmcadams@codeweavers.com
---
dlls/uiautomationcore/tests/uiautomation.c | 10 +++++----- dlls/uiautomationcore/uia_classes.idl | 1 + dlls/uiautomationcore/uia_client.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index d8271ea048c..c9ed575c1ae 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -5061,12 +5061,12 @@ static const struct prov_method_sequence node_from_hwnd7[] = { { &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider_child, PROV_GET_PROVIDER_OPTIONS }, { &Provider_child, PROV_GET_PROVIDER_OPTIONS }, - { &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, + { &Provider, PROV_GET_PROVIDER_OPTIONS }, { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */ - { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_TODO }, + { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ - { &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, - { &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, + { &Provider, PROV_GET_PROVIDER_OPTIONS }, + { &Provider, PROV_GET_PROVIDER_OPTIONS }, { &Provider_child, PROV_GET_PROPERTY_VALUE, METHOD_TODO }, /* UIA_ProviderDescriptionPropertyId */ { 0 } }; @@ -5352,7 +5352,7 @@ static DWORD WINAPI uia_node_from_handle_test_thread(LPVOID param) SET_EXPECT(winproc_GETOBJECT_CLIENT); hr = UiaGetPropertyValue(node, UIA_LabeledByPropertyId, &v); ok(hr == S_OK, "Unexpected hr %#lx\n", hr); - todo_wine CHECK_CALLED(winproc_GETOBJECT_UiaRoot); + CHECK_CALLED(winproc_GETOBJECT_UiaRoot); called_winproc_GETOBJECT_CLIENT = expect_winproc_GETOBJECT_CLIENT = 0; ok(Provider_child.ref == 2, "Unexpected refcnt %ld\n", Provider_child.ref);
diff --git a/dlls/uiautomationcore/uia_classes.idl b/dlls/uiautomationcore/uia_classes.idl index 4540613bba2..a240534222a 100644 --- a/dlls/uiautomationcore/uia_classes.idl +++ b/dlls/uiautomationcore/uia_classes.idl @@ -58,5 +58,6 @@ library UIA_wine_private HRESULT get_provider([in]int idx, [out, retval]IWineUiaProvider **out_prov); HRESULT get_prop_val([in]const GUID *prop_guid, [out, retval]VARIANT *ret_val); HRESULT disconnect(); + HRESULT get_hwnd([out, retval]ULONG *out_hwnd); } } diff --git a/dlls/uiautomationcore/uia_client.c b/dlls/uiautomationcore/uia_client.c index 8f4cb8b69ce..94046066354 100644 --- a/dlls/uiautomationcore/uia_client.c +++ b/dlls/uiautomationcore/uia_client.c @@ -523,6 +523,17 @@ static HRESULT WINAPI uia_node_disconnect(IWineUiaNode *iface) return S_OK; }
+static HRESULT WINAPI uia_node_get_hwnd(IWineUiaNode *iface, ULONG *out_hwnd) +{ + struct uia_node *node = impl_from_IWineUiaNode(iface); + + TRACE("%p, %p\n", node, out_hwnd); + + *out_hwnd = HandleToUlong(node->hwnd); + + return S_OK; +} + static const IWineUiaNodeVtbl uia_node_vtbl = { uia_node_QueryInterface, uia_node_AddRef, @@ -530,6 +541,7 @@ static const IWineUiaNodeVtbl uia_node_vtbl = { uia_node_get_provider, uia_node_get_prop_val, uia_node_disconnect, + uia_node_get_hwnd, };
static struct uia_node *unsafe_impl_from_IWineUiaNode(IWineUiaNode *iface) @@ -1351,6 +1363,15 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU IWineUiaProvider_Release(&prov->IWineUiaProvider_iface); return hr; } + + if (!node->hwnd) + { + ULONG hwnd; + + hr = IWineUiaNode_get_hwnd(nested_node, &hwnd); + if (SUCCEEDED(hr)) + node->hwnd = UlongToHandle(hwnd); + } }
node->prov[prov_type] = provider_iface; @@ -1383,6 +1404,13 @@ static HRESULT uia_node_from_lresult(LRESULT lr, HUIANODE *huianode) return hr; }
+ if (node->hwnd) + { + hr = uia_get_provider_from_hwnd(node); + if (FAILED(hr)) + WARN("uia_get_provider_from_hwnd failed with hr %#lx\n", hr); + } + hr = prepare_uia_node(node); if (FAILED(hr)) {