Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
c375765e
Commit
c375765e
authored
Oct 17, 2022
by
Connor McAdams
Committed by
Alexandre Julliard
Nov 01, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Implement ConditionType_True parent navigation for HUIANODEs.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
4bab221b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
153 additions
and
17 deletions
+153
-17
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+12
-15
uia_classes.idl
dlls/uiautomationcore/uia_classes.idl
+1
-0
uia_client.c
dlls/uiautomationcore/uia_client.c
+140
-2
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
c375765e
...
...
@@ -8205,24 +8205,21 @@ static void test_UiaNavigate(void)
tree_struct
=
NULL
;
out_req
=
NULL
;
hr
=
UiaNavigate
(
node
,
NavigateDirection_Parent
,
(
struct
UiaCondition
*
)
&
UiaTrueCondition
,
&
cache_req
,
&
out_req
,
&
tree_struct
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
todo_wine
ok
(
!!
out_req
,
"out_req == NULL
\n
"
);
todo_wine
ok
(
!!
tree_struct
,
"tree_struct == NULL
\n
"
);
todo_wine
ok
(
Provider2
.
ref
==
2
,
"Unexpected refcnt %ld
\n
"
,
Provider2
.
ref
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
ok
(
!!
out_req
,
"out_req == NULL
\n
"
);
ok
(
!!
tree_struct
,
"tree_struct == NULL
\n
"
);
ok
(
Provider2
.
ref
==
2
,
"Unexpected refcnt %ld
\n
"
,
Provider2
.
ref
);
if
(
SUCCEEDED
(
hr
))
{
exp_lbound
[
0
]
=
exp_lbound
[
1
]
=
0
;
exp_elems
[
0
]
=
exp_elems
[
1
]
=
1
;
test_cache_req_sa
(
out_req
,
exp_lbound
,
exp_elems
,
exp_node_desc
);
exp_lbound
[
0
]
=
exp_lbound
[
1
]
=
0
;
exp_elems
[
0
]
=
exp_elems
[
1
]
=
1
;
test_cache_req_sa
(
out_req
,
exp_lbound
,
exp_elems
,
exp_node_desc
);
ok
(
!
wcscmp
(
tree_struct
,
L"P)"
),
"tree structure %s
\n
"
,
debugstr_w
(
tree_struct
));
ok
(
!
wcscmp
(
tree_struct
,
L"P)"
),
"tree structure %s
\n
"
,
debugstr_w
(
tree_struct
));
SafeArrayDestroy
(
out_req
);
SysFreeString
(
tree_struct
);
ok
(
Provider2
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Provider2
.
ref
);
ok_method_sequence
(
nav_seq14
,
"nav_seq14"
);
}
SafeArrayDestroy
(
out_req
);
SysFreeString
(
tree_struct
);
ok
(
Provider2
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Provider2
.
ref
);
ok_method_sequence
(
nav_seq14
,
"nav_seq14"
);
ok
(
UiaNodeRelease
(
node
),
"UiaNodeRelease returned FALSE
\n
"
);
ok
(
Provider
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Provider
.
ref
);
...
...
dlls/uiautomationcore/uia_classes.idl
View file @
c375765e
...
...
@@ -46,6 +46,7 @@ library UIA_wine_private
HRESULT
get_prop_val
(
[
in
]
const
struct
uia_prop_info
*
prop_info
,
[
out
,
retval
]
VARIANT
*
ret_val
)
;
HRESULT
get_prov_opts
(
[
out
,
retval
]
int
*
out_opts
)
;
HRESULT
has_parent
(
[
out
,
retval
]
BOOL
*
out_val
)
;
HRESULT
navigate
(
[
in
]
int
nav_dir
,
[
out
,
retval
]
VARIANT
*
ret_val
)
;
}
[
...
...
dlls/uiautomationcore/uia_client.c
View file @
c375765e
...
...
@@ -371,6 +371,22 @@ static HRESULT get_has_parent_from_node_provider(IWineUiaNode *node, int idx, BO
return
hr
;
}
static
HRESULT
get_navigate_from_node_provider
(
IWineUiaNode
*
node
,
int
idx
,
int
nav_dir
,
VARIANT
*
ret_val
)
{
IWineUiaProvider
*
prov
;
HRESULT
hr
;
VariantInit
(
ret_val
);
hr
=
IWineUiaNode_get_provider
(
node
,
idx
,
&
prov
);
if
(
FAILED
(
hr
))
return
hr
;
hr
=
IWineUiaProvider_navigate
(
prov
,
nav_dir
,
ret_val
);
IWineUiaProvider_Release
(
prov
);
return
hr
;
}
/*
* IWineUiaNode interface.
*/
...
...
@@ -643,6 +659,41 @@ static HRESULT prepare_uia_node(struct uia_node *node)
return
S_OK
;
}
static
HRESULT
navigate_uia_node
(
struct
uia_node
*
node
,
int
nav_dir
,
HUIANODE
*
out_node
)
{
HRESULT
hr
;
VARIANT
v
;
*
out_node
=
NULL
;
VariantInit
(
&
v
);
switch
(
nav_dir
)
{
case
NavigateDirection_FirstChild
:
case
NavigateDirection_LastChild
:
case
NavigateDirection_NextSibling
:
case
NavigateDirection_PreviousSibling
:
FIXME
(
"Unimplemented NavigateDirection %d
\n
"
,
nav_dir
);
return
E_NOTIMPL
;
case
NavigateDirection_Parent
:
hr
=
get_navigate_from_node_provider
(
&
node
->
IWineUiaNode_iface
,
node
->
parent_link_idx
,
nav_dir
,
&
v
);
if
(
FAILED
(
hr
))
WARN
(
"Parent navigation failed with hr %#lx
\n
"
,
hr
);
hr
=
UiaHUiaNodeFromVariant
(
&
v
,
out_node
);
if
(
FAILED
(
hr
))
*
out_node
=
NULL
;
break
;
default:
WARN
(
"Invalid NavigateDirection %d
\n
"
,
nav_dir
);
return
E_INVALIDARG
;
}
return
S_OK
;
}
/*
* IWineUiaProvider interface.
*/
...
...
@@ -977,6 +1028,38 @@ static HRESULT WINAPI uia_provider_has_parent(IWineUiaProvider *iface, BOOL *out
return
S_OK
;
}
static
HRESULT
WINAPI
uia_provider_navigate
(
IWineUiaProvider
*
iface
,
int
nav_dir
,
VARIANT
*
out_val
)
{
struct
uia_provider
*
prov
=
impl_from_IWineUiaProvider
(
iface
);
IRawElementProviderFragment
*
elfrag
,
*
elfrag2
;
HRESULT
hr
;
TRACE
(
"%p, %d, %p
\n
"
,
iface
,
nav_dir
,
out_val
);
VariantInit
(
out_val
);
hr
=
IRawElementProviderSimple_QueryInterface
(
prov
->
elprov
,
&
IID_IRawElementProviderFragment
,
(
void
**
)
&
elfrag
);
if
(
FAILED
(
hr
)
||
!
elfrag
)
return
S_OK
;
hr
=
IRawElementProviderFragment_Navigate
(
elfrag
,
nav_dir
,
&
elfrag2
);
IRawElementProviderFragment_Release
(
elfrag
);
if
(
SUCCEEDED
(
hr
)
&&
elfrag2
)
{
IRawElementProviderSimple
*
elprov
;
hr
=
IRawElementProviderFragment_QueryInterface
(
elfrag2
,
&
IID_IRawElementProviderSimple
,
(
void
**
)
&
elprov
);
IRawElementProviderFragment_Release
(
elfrag2
);
if
(
FAILED
(
hr
)
||
!
elprov
)
return
hr
;
hr
=
get_variant_for_elprov_node
(
elprov
,
prov
->
return_nested_node
,
out_val
);
if
(
FAILED
(
hr
))
return
hr
;
}
return
S_OK
;
}
static
const
IWineUiaProviderVtbl
uia_provider_vtbl
=
{
uia_provider_QueryInterface
,
uia_provider_AddRef
,
...
...
@@ -984,6 +1067,7 @@ static const IWineUiaProviderVtbl uia_provider_vtbl = {
uia_provider_get_prop_val
,
uia_provider_get_prov_opts
,
uia_provider_has_parent
,
uia_provider_navigate
,
};
static
HRESULT
create_wine_uia_provider
(
struct
uia_node
*
node
,
IRawElementProviderSimple
*
elprov
,
...
...
@@ -1358,6 +1442,30 @@ static HRESULT WINAPI uia_nested_node_provider_has_parent(IWineUiaProvider *ifac
return
get_has_parent_from_node_provider
(
prov
->
nested_node
,
0
,
out_val
);
}
static
HRESULT
WINAPI
uia_nested_node_provider_navigate
(
IWineUiaProvider
*
iface
,
int
nav_dir
,
VARIANT
*
out_val
)
{
struct
uia_nested_node_provider
*
prov
=
impl_from_nested_node_IWineUiaProvider
(
iface
);
HUIANODE
node
;
HRESULT
hr
;
VARIANT
v
;
TRACE
(
"%p, %d, %p
\n
"
,
iface
,
nav_dir
,
out_val
);
VariantInit
(
out_val
);
hr
=
get_navigate_from_node_provider
(
prov
->
nested_node
,
0
,
nav_dir
,
&
v
);
if
(
FAILED
(
hr
)
||
V_VT
(
&
v
)
==
VT_EMPTY
)
return
hr
;
hr
=
uia_node_from_lresult
((
LRESULT
)
V_I4
(
&
v
),
&
node
);
if
(
FAILED
(
hr
))
return
hr
;
get_variant_for_node
(
node
,
out_val
);
VariantClear
(
&
v
);
return
S_OK
;
}
static
const
IWineUiaProviderVtbl
uia_nested_node_provider_vtbl
=
{
uia_nested_node_provider_QueryInterface
,
uia_nested_node_provider_AddRef
,
...
...
@@ -1365,6 +1473,7 @@ static const IWineUiaProviderVtbl uia_nested_node_provider_vtbl = {
uia_nested_node_provider_get_prop_val
,
uia_nested_node_provider_get_prov_opts
,
uia_nested_node_provider_has_parent
,
uia_nested_node_provider_navigate
,
};
static
BOOL
is_nested_node_provider
(
IWineUiaProvider
*
iface
)
...
...
@@ -2234,7 +2343,36 @@ HRESULT WINAPI UiaGetUpdatedCache(HUIANODE huianode, struct UiaCacheRequest *cac
HRESULT
WINAPI
UiaNavigate
(
HUIANODE
huianode
,
enum
NavigateDirection
dir
,
struct
UiaCondition
*
nav_condition
,
struct
UiaCacheRequest
*
cache_req
,
SAFEARRAY
**
out_req
,
BSTR
*
tree_struct
)
{
FIXME
(
"(%p, %u, %p, %p, %p, %p): stub
\n
"
,
huianode
,
dir
,
nav_condition
,
cache_req
,
out_req
,
struct
uia_node
*
node
=
unsafe_impl_from_IWineUiaNode
((
IWineUiaNode
*
)
huianode
);
HUIANODE
node2
;
HRESULT
hr
;
TRACE
(
"(%p, %u, %p, %p, %p, %p)
\n
"
,
huianode
,
dir
,
nav_condition
,
cache_req
,
out_req
,
tree_struct
);
return
E_NOTIMPL
;
if
(
!
node
||
!
nav_condition
||
!
cache_req
||
!
out_req
||
!
tree_struct
)
return
E_INVALIDARG
;
*
out_req
=
NULL
;
*
tree_struct
=
NULL
;
if
(
nav_condition
->
ConditionType
!=
ConditionType_True
)
{
FIXME
(
"ConditionType %d based navigation is not implemented.
\n
"
,
nav_condition
->
ConditionType
);
return
E_NOTIMPL
;
}
hr
=
navigate_uia_node
(
node
,
dir
,
&
node2
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
node2
)
{
hr
=
UiaGetUpdatedCache
(
node2
,
cache_req
,
NormalizeState_None
,
NULL
,
out_req
,
tree_struct
);
if
(
FAILED
(
hr
))
WARN
(
"UiaGetUpdatedCache failed with hr %#lx
\n
"
,
hr
);
UiaNodeRelease
(
node2
);
}
return
hr
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment