uiautomationcore: Add support for getting HWND providers to UiaNodeFromProvider().

Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
Connor McAdams 2022-10-12 13:44:41 -04:00 committed by Alexandre Julliard
parent 59a629810a
commit 750d11a49a
4 changed files with 51 additions and 31 deletions

View file

@ -3843,10 +3843,10 @@ static const struct prov_method_sequence node_from_prov5[] = {
/* Win10v1507 and below call this. */
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS },
/* Win10v1507 and below call this. */
{ &Provider2, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider2, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_TODO },
{ &Provider2, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider2, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
/* These three are only done on Win10v1507 and below. */
{ &Provider2, PROV_GET_PROVIDER_OPTIONS, METHOD_OPTIONAL },
@ -3868,13 +3868,13 @@ static const struct prov_method_sequence node_from_prov6[] = {
/* Win10v1507 and below call this. */
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS },
/* Win10v1507 and below call this. */
{ &Provider2, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider2, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_TODO },
{ &Provider2, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider2, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider2, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS },
/* Only called on Windows versions past Win10v1507. */
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_OPTIONAL },
{ &Provider2, FRAG_NAVIGATE, METHOD_OPTIONAL }, /* NavigateDirection_Parent */
@ -3893,13 +3893,13 @@ static const struct prov_method_sequence node_from_prov7[] = {
/* Win10v1507 and below call this. */
{ &Provider_child, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS },
/* Win10v1507 and below call this. */
{ &Provider2, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider2, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_TODO },
{ &Provider2, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider2, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider2, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS },
{ &Provider2, PROV_GET_PROVIDER_OPTIONS },
/* Only called on Windows versions past Win10v1507. */
{ &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_OPTIONAL },
{ &Provider2, FRAG_NAVIGATE, METHOD_OPTIONAL }, /* NavigateDirection_Parent */
@ -4136,7 +4136,7 @@ static void test_UiaNodeFromProvider(void)
hr = UiaNodeFromProvider(&Provider.IRawElementProviderSimple_iface, &node);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(Provider.ref == 2, "Unexpected refcnt %ld\n", Provider.ref);
todo_wine CHECK_CALLED(winproc_GETOBJECT_UiaRoot);
CHECK_CALLED(winproc_GETOBJECT_UiaRoot);
called_winproc_GETOBJECT_CLIENT = expect_winproc_GETOBJECT_CLIENT = 0;
hr = UiaGetPropertyValue(node, UIA_ProviderDescriptionPropertyId, &v);
@ -4178,7 +4178,7 @@ static void test_UiaNodeFromProvider(void)
SET_EXPECT(winproc_GETOBJECT_CLIENT);
hr = UiaNodeFromProvider(&Provider.IRawElementProviderSimple_iface, &node);
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;
/* Win10v1507 and below hold a reference to the root provider for the HWND */
@ -4227,7 +4227,7 @@ static void test_UiaNodeFromProvider(void)
SET_EXPECT(winproc_GETOBJECT_CLIENT);
hr = UiaNodeFromProvider(&Provider.IRawElementProviderSimple_iface, &node);
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;
hr = UiaGetPropertyValue(node, UIA_ProviderDescriptionPropertyId, &v);
@ -4242,7 +4242,7 @@ static void test_UiaNodeFromProvider(void)
}
ok_method_sequence(node_from_prov6, "node_from_prov6");
todo_wine ok(Provider2.ref == 2, "Unexpected refcnt %ld\n", Provider2.ref);
ok(Provider2.ref == 2, "Unexpected refcnt %ld\n", Provider2.ref);
ok(Provider.ref == 2, "Unexpected refcnt %ld\n", Provider.ref);
ok(!!node, "node == NULL\n");
@ -4261,7 +4261,7 @@ static void test_UiaNodeFromProvider(void)
SET_EXPECT(winproc_GETOBJECT_CLIENT);
hr = UiaNodeFromProvider(&Provider_child.IRawElementProviderSimple_iface, &node);
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;
hr = UiaGetPropertyValue(node, UIA_ProviderDescriptionPropertyId, &v);
@ -4276,7 +4276,7 @@ static void test_UiaNodeFromProvider(void)
}
ok_method_sequence(node_from_prov7, "node_from_prov7");
todo_wine ok(Provider2.ref == 2, "Unexpected refcnt %ld\n", Provider2.ref);
ok(Provider2.ref == 2, "Unexpected refcnt %ld\n", Provider2.ref);
ok(Provider_child.ref == 2, "Unexpected refcnt %ld\n", Provider.ref);
ok(!!node, "node == NULL\n");
@ -4839,7 +4839,7 @@ static void test_UiaGetRuntimeId(void)
SET_EXPECT(winproc_GETOBJECT_CLIENT);
hr = UiaNodeFromProvider(&Provider.IRawElementProviderSimple_iface, &node);
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;
VariantInit(&v);

View file

@ -718,7 +718,7 @@ static HRESULT uia_provider_get_elem_prop_val(struct uia_provider *prov,
if (FAILED(hr))
goto exit;
hr = UiaNodeFromProvider(elprov, &node);
hr = create_uia_node_from_elprov(elprov, &node, !prov->return_nested_node);
IRawElementProviderSimple_Release(elprov);
if (SUCCEEDED(hr))
{
@ -897,10 +897,9 @@ static HRESULT create_wine_uia_provider(struct uia_node *node, IRawElementProvid
return S_OK;
}
/***********************************************************************
* UiaNodeFromProvider (uiautomationcore.@)
*/
HRESULT WINAPI UiaNodeFromProvider(IRawElementProviderSimple *elprov, HUIANODE *huianode)
static HRESULT uia_get_provider_from_hwnd(struct uia_node *node);
HRESULT create_uia_node_from_elprov(IRawElementProviderSimple *elprov, HUIANODE *out_node,
BOOL get_hwnd_providers)
{
static const int unsupported_prov_opts = ProviderOptions_ProviderOwnsSetFocus | ProviderOptions_HasNativeIAccessible |
ProviderOptions_UseClientCoordinates;
@ -909,12 +908,7 @@ HRESULT WINAPI UiaNodeFromProvider(IRawElementProviderSimple *elprov, HUIANODE *
int prov_type;
HRESULT hr;
TRACE("(%p, %p)\n", elprov, huianode);
if (!elprov || !huianode)
return E_INVALIDARG;
*huianode = NULL;
*out_node = NULL;
hr = IRawElementProviderSimple_get_ProviderOptions(elprov, &prov_opts);
if (FAILED(hr))
@ -951,6 +945,9 @@ HRESULT WINAPI UiaNodeFromProvider(IRawElementProviderSimple *elprov, HUIANODE *
return hr;
}
if (node->hwnd && get_hwnd_providers)
uia_get_provider_from_hwnd(node);
hr = prepare_uia_node(node);
if (FAILED(hr))
{
@ -958,11 +955,24 @@ HRESULT WINAPI UiaNodeFromProvider(IRawElementProviderSimple *elprov, HUIANODE *
return hr;
}
*huianode = (void *)&node->IWineUiaNode_iface;
*out_node = (void *)&node->IWineUiaNode_iface;
return S_OK;
}
/***********************************************************************
* UiaNodeFromProvider (uiautomationcore.@)
*/
HRESULT WINAPI UiaNodeFromProvider(IRawElementProviderSimple *elprov, HUIANODE *huianode)
{
TRACE("(%p, %p)\n", elprov, huianode);
if (!elprov || !huianode)
return E_INVALIDARG;
return create_uia_node_from_elprov(elprov, huianode, TRUE);
}
/*
* UI Automation client thread functions.
*/
@ -1277,6 +1287,14 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU
else
prov_type = PROV_TYPE_MAIN;
if (node->prov[prov_type])
{
TRACE("Already have a provider of type %d for this node.\n", prov_type);
IWineUiaNode_Release(nested_node);
uia_stop_client_thread();
return S_OK;
}
/*
* If we're retrieving a node from an HWND that belongs to the same thread
* as the client making the request, return a normal provider instead of a

View file

@ -89,6 +89,8 @@ static inline struct uia_provider *impl_from_IWineUiaProvider(IWineUiaProvider *
/* uia_client.c */
int uia_compare_runtime_ids(SAFEARRAY *sa1, SAFEARRAY *sa2) DECLSPEC_HIDDEN;
int get_node_provider_type_at_idx(struct uia_node *node, int idx) DECLSPEC_HIDDEN;
HRESULT create_uia_node_from_elprov(IRawElementProviderSimple *elprov, HUIANODE *out_node,
BOOL get_hwnd_providers) DECLSPEC_HIDDEN;
/* uia_ids.c */
const struct uia_prop_info *uia_prop_info_from_id(PROPERTYID prop_id) DECLSPEC_HIDDEN;

View file

@ -1464,7 +1464,7 @@ LRESULT WINAPI UiaReturnRawElementProvider(HWND hwnd, WPARAM wparam,
return 0;
}
hr = UiaNodeFromProvider(elprov, &node);
hr = create_uia_node_from_elprov(elprov, &node, FALSE);
if (FAILED(hr))
{
WARN("Failed to create HUIANODE with hr %#lx\n", hr);
@ -1485,7 +1485,7 @@ HRESULT WINAPI UiaDisconnectProvider(IRawElementProviderSimple *elprov)
TRACE("(%p)\n", elprov);
hr = UiaNodeFromProvider(elprov, &node);
hr = create_uia_node_from_elprov(elprov, &node, FALSE);
if (FAILED(hr))
return hr;