Commit ef7e88ea authored by Connor McAdams's avatar Connor McAdams Committed by Alexandre Julliard

uiautomationcore: Partially implement ConditionType_True sibling navigation for HUIANODEs.

Add support for navigating between siblings of an individual IWineUiaProvider for an HUIANODE. Signed-off-by: 's avatarConnor McAdams <cmcadams@codeweavers.com>
parent c375765e
...@@ -596,6 +596,18 @@ static HRESULT prepare_uia_node(struct uia_node *node) ...@@ -596,6 +596,18 @@ static HRESULT prepare_uia_node(struct uia_node *node)
int i, prov_idx; int i, prov_idx;
HRESULT hr; HRESULT hr;
/* Get the provider index for the provider that created the node. */
for (i = prov_idx = 0; i < PROV_TYPE_COUNT; i++)
{
if (i == node->creator_prov_type)
{
node->creator_prov_idx = prov_idx;
break;
}
else if (node->prov[i])
prov_idx++;
}
/* /*
* HUIANODEs can only have one 'parent link' provider, which handles * HUIANODEs can only have one 'parent link' provider, which handles
* parent and sibling navigation for the entire HUIANODE. Each provider is * parent and sibling navigation for the entire HUIANODE. Each provider is
...@@ -659,6 +671,62 @@ static HRESULT prepare_uia_node(struct uia_node *node) ...@@ -659,6 +671,62 @@ static HRESULT prepare_uia_node(struct uia_node *node)
return S_OK; return S_OK;
} }
static BOOL node_creator_is_parent_link(struct uia_node *node)
{
if (node->creator_prov_idx == node->parent_link_idx)
return TRUE;
else
return FALSE;
}
static HRESULT get_sibling_from_node_provider(struct uia_node *node, int prov_idx, int nav_dir,
VARIANT *out_node)
{
HUIANODE tmp_node;
HRESULT hr;
VARIANT v;
hr = get_navigate_from_node_provider(&node->IWineUiaNode_iface, prov_idx, nav_dir, &v);
if (FAILED(hr))
return hr;
hr = UiaHUiaNodeFromVariant(&v, &tmp_node);
if (FAILED(hr))
goto exit;
while (1)
{
struct uia_node *node_data = impl_from_IWineUiaNode((IWineUiaNode *)tmp_node);
/*
* If our sibling provider is the parent link of it's HUIANODE, then
* it is a valid sibling of this node.
*/
if (node_creator_is_parent_link(node_data))
break;
/*
* If our sibling provider is not the parent link of it's HUIANODE, we
* need to try the next sibling.
*/
hr = get_navigate_from_node_provider((IWineUiaNode *)tmp_node, node_data->creator_prov_idx, nav_dir, &v);
UiaNodeRelease(tmp_node);
if (FAILED(hr))
return hr;
tmp_node = NULL;
hr = UiaHUiaNodeFromVariant(&v, &tmp_node);
if (FAILED(hr))
break;
}
exit:
if (tmp_node)
*out_node = v;
return S_OK;
}
static HRESULT navigate_uia_node(struct uia_node *node, int nav_dir, HUIANODE *out_node) static HRESULT navigate_uia_node(struct uia_node *node, int nav_dir, HUIANODE *out_node)
{ {
HRESULT hr; HRESULT hr;
...@@ -671,19 +739,20 @@ static HRESULT navigate_uia_node(struct uia_node *node, int nav_dir, HUIANODE *o ...@@ -671,19 +739,20 @@ static HRESULT navigate_uia_node(struct uia_node *node, int nav_dir, HUIANODE *o
{ {
case NavigateDirection_FirstChild: case NavigateDirection_FirstChild:
case NavigateDirection_LastChild: case NavigateDirection_LastChild:
case NavigateDirection_NextSibling:
case NavigateDirection_PreviousSibling:
FIXME("Unimplemented NavigateDirection %d\n", nav_dir); FIXME("Unimplemented NavigateDirection %d\n", nav_dir);
return E_NOTIMPL; return E_NOTIMPL;
case NavigateDirection_NextSibling:
case NavigateDirection_PreviousSibling:
hr = get_sibling_from_node_provider(node, node->parent_link_idx, nav_dir, &v);
if (FAILED(hr))
WARN("Sibling navigation failed with hr %#lx\n", hr);
break;
case NavigateDirection_Parent: case NavigateDirection_Parent:
hr = get_navigate_from_node_provider(&node->IWineUiaNode_iface, node->parent_link_idx, nav_dir, &v); hr = get_navigate_from_node_provider(&node->IWineUiaNode_iface, node->parent_link_idx, nav_dir, &v);
if (FAILED(hr)) if (FAILED(hr))
WARN("Parent navigation failed with hr %#lx\n", hr); WARN("Parent navigation failed with hr %#lx\n", hr);
hr = UiaHUiaNodeFromVariant(&v, out_node);
if (FAILED(hr))
*out_node = NULL;
break; break;
default: default:
...@@ -691,6 +760,13 @@ static HRESULT navigate_uia_node(struct uia_node *node, int nav_dir, HUIANODE *o ...@@ -691,6 +760,13 @@ static HRESULT navigate_uia_node(struct uia_node *node, int nav_dir, HUIANODE *o
return E_INVALIDARG; return E_INVALIDARG;
} }
if (V_VT(&v) != VT_EMPTY)
{
hr = UiaHUiaNodeFromVariant(&v, (HUIANODE *)out_node);
if (FAILED(hr))
WARN("UiaHUiaNodeFromVariant failed with hr %#lx\n", hr);
}
return S_OK; return S_OK;
} }
...@@ -1082,6 +1158,8 @@ static HRESULT create_wine_uia_provider(struct uia_node *node, IRawElementProvid ...@@ -1082,6 +1158,8 @@ static HRESULT create_wine_uia_provider(struct uia_node *node, IRawElementProvid
prov->elprov = elprov; prov->elprov = elprov;
prov->ref = 1; prov->ref = 1;
node->prov[prov_type] = &prov->IWineUiaProvider_iface; node->prov[prov_type] = &prov->IWineUiaProvider_iface;
if (!node->prov_count)
node->creator_prov_type = prov_type;
node->prov_count++; node->prov_count++;
IRawElementProviderSimple_AddRef(elprov); IRawElementProviderSimple_AddRef(elprov);
...@@ -1595,6 +1673,8 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU ...@@ -1595,6 +1673,8 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU
node->prov[prov_type] = provider_iface; node->prov[prov_type] = provider_iface;
node->git_cookie[prov_type] = git_cookie; node->git_cookie[prov_type] = git_cookie;
if (!node->prov_count)
node->creator_prov_type = prov_type;
node->prov_count++; node->prov_count++;
return S_OK; return S_OK;
......
...@@ -60,10 +60,12 @@ struct uia_node { ...@@ -60,10 +60,12 @@ struct uia_node {
DWORD git_cookie[PROV_TYPE_COUNT]; DWORD git_cookie[PROV_TYPE_COUNT];
int prov_count; int prov_count;
int parent_link_idx; int parent_link_idx;
int creator_prov_idx;
HWND hwnd; HWND hwnd;
BOOL nested_node; BOOL nested_node;
BOOL disconnected; BOOL disconnected;
int creator_prov_type;
struct list prov_thread_list_entry; struct list prov_thread_list_entry;
struct list node_map_list_entry; struct list node_map_list_entry;
struct uia_provider_thread_map_entry *map; struct uia_provider_thread_map_entry *map;
......
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