Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
fdb3c9f9
Commit
fdb3c9f9
authored
Mar 09, 2023
by
Connor McAdams
Committed by
Alexandre Julliard
Mar 16, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Implement IUIAutomationElement::FindAll{BuildCache}.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
3b68d75f
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
142 additions
and
50 deletions
+142
-50
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+15
-31
uia_com_client.c
dlls/uiautomationcore/uia_com_client.c
+127
-19
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
fdb3c9f9
...
...
@@ -11361,9 +11361,8 @@ static void test_Element_Find(IUIAutomation *uia_iface)
* root is FALSE.
*/
hr
=
IUIAutomationElement_FindAllBuildCache
(
element
,
TreeScope_SubTree
,
condition
,
cache_req
,
&
element_arr
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
set_elem_desc
(
&
exp_elems
[
0
],
&
Provider
,
NULL
,
GetCurrentProcessId
(),
2
,
2
);
add_provider_desc
(
&
exp_elems
[
0
].
prov_desc
,
L"Main"
,
L"Provider"
,
TRUE
);
set_elem_desc
(
&
exp_elems
[
1
],
&
Provider_child
,
NULL
,
GetCurrentProcessId
(),
2
,
1
);
...
...
@@ -11381,16 +11380,14 @@ static void test_Element_Find(IUIAutomation *uia_iface)
test_uia_element_arr
(
element_arr
,
exp_elems
,
7
);
ok_method_sequence
(
find_seq1
,
"find_seq1"
);
}
/*
* Equivalent to: Maximum find depth of 1, find first is FALSE, exclude root
* is FALSE.
*/
hr
=
IUIAutomationElement_FindAllBuildCache
(
element
,
TreeScope_Element
|
TreeScope_Children
,
condition
,
cache_req
,
&
element_arr
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
set_elem_desc
(
&
exp_elems
[
0
],
&
Provider
,
NULL
,
GetCurrentProcessId
(),
2
,
2
);
add_provider_desc
(
&
exp_elems
[
0
].
prov_desc
,
L"Main"
,
L"Provider"
,
TRUE
);
set_elem_desc
(
&
exp_elems
[
1
],
&
Provider_child
,
NULL
,
GetCurrentProcessId
(),
2
,
1
);
...
...
@@ -11400,16 +11397,14 @@ static void test_Element_Find(IUIAutomation *uia_iface)
test_uia_element_arr
(
element_arr
,
exp_elems
,
3
);
ok_method_sequence
(
find_seq2
,
"find_seq2"
);
}
/*
* Equivalent to: Maximum find depth of 1, find first is FALSE, exclude root
* is TRUE.
*/
hr
=
IUIAutomationElement_FindAllBuildCache
(
element
,
TreeScope_Children
,
condition
,
cache_req
,
&
element_arr
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
set_elem_desc
(
&
exp_elems
[
0
],
&
Provider_child
,
NULL
,
GetCurrentProcessId
(),
2
,
1
);
add_provider_desc
(
&
exp_elems
[
0
].
prov_desc
,
L"Main"
,
L"Provider_child"
,
TRUE
);
set_elem_desc
(
&
exp_elems
[
1
],
&
Provider_child2
,
NULL
,
GetCurrentProcessId
(),
2
,
1
);
...
...
@@ -11417,7 +11412,6 @@ static void test_Element_Find(IUIAutomation *uia_iface)
test_uia_element_arr
(
element_arr
,
exp_elems
,
2
);
ok_method_sequence
(
find_seq3
,
"find_seq3"
);
}
/*
* Equivalent to: Maximum find depth of 1, find first is TRUE, exclude
...
...
@@ -11518,9 +11512,8 @@ static void test_Element_Find(IUIAutomation *uia_iface)
* depth 1.
*/
hr
=
IUIAutomationElement_FindAllBuildCache
(
element
,
TreeScope_Element
|
TreeScope_Children
,
condition2
,
cache_req
,
&
element_arr
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
set_elem_desc
(
&
exp_elems
[
0
],
&
Provider
,
NULL
,
GetCurrentProcessId
(),
2
,
2
);
add_provider_desc
(
&
exp_elems
[
0
].
prov_desc
,
L"Main"
,
L"Provider"
,
TRUE
);
set_elem_desc
(
&
exp_elems
[
1
],
&
Provider_child_child
,
NULL
,
GetCurrentProcessId
(),
2
,
1
);
...
...
@@ -11532,7 +11525,6 @@ static void test_Element_Find(IUIAutomation *uia_iface)
test_uia_element_arr
(
element_arr
,
exp_elems
,
4
);
ok_method_sequence
(
find_seq7
,
"find_seq7"
);
}
initialize_provider_tree
(
FALSE
);
/*
...
...
@@ -11547,9 +11539,8 @@ static void test_Element_Find(IUIAutomation *uia_iface)
set_provider_prop_override
(
&
Provider_child_child2
,
&
prop_override
,
1
);
hr
=
IUIAutomationElement_FindAllBuildCache
(
element
,
TreeScope_Element
|
TreeScope_Children
,
condition2
,
cache_req
,
&
element_arr
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
set_elem_desc
(
&
exp_elems
[
0
],
&
Provider
,
NULL
,
GetCurrentProcessId
(),
2
,
2
);
add_provider_desc
(
&
exp_elems
[
0
].
prov_desc
,
L"Main"
,
L"Provider"
,
TRUE
);
set_elem_desc
(
&
exp_elems
[
1
],
&
Provider_child_child
,
NULL
,
GetCurrentProcessId
(),
2
,
1
);
...
...
@@ -11565,11 +11556,8 @@ static void test_Element_Find(IUIAutomation *uia_iface)
test_uia_element_arr
(
element_arr
,
exp_elems
,
4
);
ok_method_sequence
(
find_seq8
,
"find_seq8"
);
}
initialize_provider_tree
(
FALSE
);
if
(
element2
)
{
variant_init_bool
(
&
v
,
FALSE
);
set_property_override
(
&
prop_override
,
UIA_IsContentElementPropertyId
,
&
v
);
set_provider_prop_override
(
&
Provider_child_child2
,
&
prop_override
,
1
);
...
...
@@ -11594,9 +11582,9 @@ static void test_Element_Find(IUIAutomation *uia_iface)
add_provider_desc
(
&
exp_elems
[
1
].
prov_desc
,
L"Main"
,
L"Provider_child2"
,
TRUE
);
set_elem_desc
(
&
exp_elems
[
2
],
&
Provider_child2_child
,
NULL
,
GetCurrentProcessId
(),
2
,
1
);
add_provider_desc
(
&
exp_elems
[
2
].
prov_desc
,
L"Main"
,
L"Provider_child2_child"
,
TRUE
);
test_uia_element_arr
(
element_arr
,
exp_elems
,
3
);
ok_method_sequence
(
find_seq9
,
"find_seq9"
);
}
initialize_provider_tree
(
FALSE
);
/*
...
...
@@ -11611,15 +11599,13 @@ static void test_Element_Find(IUIAutomation *uia_iface)
set_provider_prop_override
(
&
Provider_child
,
&
prop_override
,
1
);
set_provider_prop_override
(
&
Provider_child2
,
&
prop_override
,
1
);
hr
=
IUIAutomationElement_FindAllBuildCache
(
element
,
TreeScope_Children
,
condition2
,
cache_req
,
&
element_arr
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
set_elem_desc
(
&
exp_elems
[
0
],
&
Provider_child2
,
NULL
,
GetCurrentProcessId
(),
2
,
1
);
add_provider_desc
(
&
exp_elems
[
0
].
prov_desc
,
L"Main"
,
L"Provider_child2"
,
TRUE
);
test_uia_element_arr
(
element_arr
,
exp_elems
,
1
);
ok_method_sequence
(
find_seq10
,
"find_seq10"
);
}
initialize_provider_tree
(
FALSE
);
variant_init_bool
(
&
v
,
FALSE
);
...
...
@@ -11674,9 +11660,8 @@ static void test_Element_Find(IUIAutomation *uia_iface)
ok
(
!!
condition
,
"cond == NULL
\n
"
);
hr
=
IUIAutomationElement_FindAll
(
element
,
TreeScope_Element
|
TreeScope_Children
,
condition
,
&
element_arr
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
set_elem_desc
(
&
exp_elems
[
0
],
&
Provider
,
NULL
,
GetCurrentProcessId
(),
2
,
2
);
add_provider_desc
(
&
exp_elems
[
0
].
prov_desc
,
L"Main"
,
L"Provider"
,
TRUE
);
set_elem_desc
(
&
exp_elems
[
1
],
&
Provider_child_child
,
NULL
,
GetCurrentProcessId
(),
2
,
1
);
...
...
@@ -11688,7 +11673,6 @@ static void test_Element_Find(IUIAutomation *uia_iface)
test_uia_element_arr
(
element_arr
,
exp_elems
,
4
);
ok_method_sequence
(
element_find_seq1
,
"element_find_seq1"
);
}
initialize_provider_tree
(
FALSE
);
/*
...
...
dlls/uiautomationcore/uia_com_client.c
View file @
fdb3c9f9
...
...
@@ -876,14 +876,6 @@ static HRESULT create_uia_cache_request_iface(IUIAutomationCacheRequest **out_ca
uia_cache_request
->
cache_req
.
Scope
=
TreeScope_Element
;
uia_cache_request
->
cache_req
.
automationElementMode
=
AutomationElementMode_Full
;
hr
=
IUIAutomationCacheRequest_AddProperty
(
&
uia_cache_request
->
IUIAutomationCacheRequest_iface
,
UIA_RuntimeIdPropertyId
);
if
(
FAILED
(
hr
))
{
IUIAutomationCacheRequest_Release
(
&
uia_cache_request
->
IUIAutomationCacheRequest_iface
);
return
hr
;
}
*
out_cache_req
=
&
uia_cache_request
->
IUIAutomationCacheRequest_iface
;
return
S_OK
;
}
...
...
@@ -1125,10 +1117,27 @@ static HRESULT WINAPI uia_element_FindFirst(IUIAutomationElement9 *iface, enum T
static
HRESULT
WINAPI
uia_element_FindAll
(
IUIAutomationElement9
*
iface
,
enum
TreeScope
scope
,
IUIAutomationCondition
*
condition
,
IUIAutomationElementArray
**
found
)
{
FIXME
(
"%p: stub
\n
"
,
iface
);
return
E_NOTIMPL
;
IUIAutomationCacheRequest
*
cache_req
;
HRESULT
hr
;
TRACE
(
"%p, %#x, %p, %p
\n
"
,
iface
,
scope
,
condition
,
found
);
if
(
!
found
)
return
E_POINTER
;
*
found
=
NULL
;
hr
=
create_uia_cache_request_iface
(
&
cache_req
);
if
(
FAILED
(
hr
))
return
hr
;
hr
=
IUIAutomationElement9_FindAllBuildCache
(
iface
,
scope
,
condition
,
cache_req
,
found
);
IUIAutomationCacheRequest_Release
(
cache_req
);
return
hr
;
}
static
HRESULT
create_uia_element_from_cache_req
(
IUIAutomationElement
**
iface
,
BOOL
from_cui8
,
struct
UiaCacheRequest
*
cache_req
,
LONG
start_idx
,
SAFEARRAY
*
req_data
,
BSTR
tree_struct
);
static
HRESULT
WINAPI
uia_element_FindFirstBuildCache
(
IUIAutomationElement9
*
iface
,
enum
TreeScope
scope
,
IUIAutomationCondition
*
condition
,
IUIAutomationCacheRequest
*
cache_req
,
IUIAutomationElement
**
found
)
{
...
...
@@ -1139,12 +1148,97 @@ static HRESULT WINAPI uia_element_FindFirstBuildCache(IUIAutomationElement9 *ifa
static
HRESULT
WINAPI
uia_element_FindAllBuildCache
(
IUIAutomationElement9
*
iface
,
enum
TreeScope
scope
,
IUIAutomationCondition
*
condition
,
IUIAutomationCacheRequest
*
cache_req
,
IUIAutomationElementArray
**
found
)
{
FIXME
(
"%p: stub
\n
"
,
iface
);
return
E_NOTIMPL
;
struct
uia_element
*
element
=
impl_from_IUIAutomationElement9
(
iface
);
LONG
lbound_offsets
,
lbound_tree_structs
,
elems_count
;
struct
uia_element_array
*
element_array_data
;
struct
UiaFindParams
find_params
=
{
0
};
struct
UiaCacheRequest
*
cache_req_struct
;
SAFEARRAY
*
sa
,
*
tree_structs
,
*
offsets
;
IUIAutomationElementArray
*
array
;
HRESULT
hr
;
int
i
;
TRACE
(
"%p, %#x, %p, %p, %p
\n
"
,
iface
,
scope
,
condition
,
cache_req
,
found
);
if
(
!
found
)
return
E_POINTER
;
*
found
=
array
=
NULL
;
hr
=
get_uia_cache_request_struct_from_iface
(
cache_req
,
&
cache_req_struct
);
if
(
FAILED
(
hr
))
return
hr
;
hr
=
get_uia_condition_struct_from_iface
(
condition
,
&
find_params
.
pFindCondition
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
!
scope
||
(
scope
&
(
~
TreeScope_SubTree
)))
return
E_INVALIDARG
;
if
(
scope
&
TreeScope_Element
)
find_params
.
ExcludeRoot
=
FALSE
;
else
find_params
.
ExcludeRoot
=
TRUE
;
if
(
scope
&
TreeScope_Descendants
)
find_params
.
MaxDepth
=
-
1
;
else
if
(
scope
&
TreeScope_Children
)
find_params
.
MaxDepth
=
1
;
else
find_params
.
MaxDepth
=
0
;
sa
=
offsets
=
tree_structs
=
NULL
;
hr
=
UiaFind
(
element
->
node
,
&
find_params
,
cache_req_struct
,
&
sa
,
&
offsets
,
&
tree_structs
);
if
(
FAILED
(
hr
)
||
!
sa
)
goto
exit
;
hr
=
get_safearray_bounds
(
tree_structs
,
&
lbound_tree_structs
,
&
elems_count
);
if
(
FAILED
(
hr
))
goto
exit
;
hr
=
get_safearray_bounds
(
offsets
,
&
lbound_offsets
,
&
elems_count
);
if
(
FAILED
(
hr
))
goto
exit
;
hr
=
create_uia_element_array_iface
(
&
array
,
elems_count
);
if
(
FAILED
(
hr
))
goto
exit
;
element_array_data
=
impl_from_IUIAutomationElementArray
(
array
);
for
(
i
=
0
;
i
<
elems_count
;
i
++
)
{
BSTR
tree_struct_str
;
LONG
offset_idx
,
idx
;
idx
=
lbound_offsets
+
i
;
hr
=
SafeArrayGetElement
(
offsets
,
&
idx
,
&
offset_idx
);
if
(
FAILED
(
hr
))
goto
exit
;
idx
=
lbound_tree_structs
+
i
;
hr
=
SafeArrayGetElement
(
tree_structs
,
&
idx
,
&
tree_struct_str
);
if
(
FAILED
(
hr
))
goto
exit
;
hr
=
create_uia_element_from_cache_req
(
&
element_array_data
->
elements
[
i
],
element
->
from_cui8
,
cache_req_struct
,
offset_idx
,
sa
,
tree_struct_str
);
if
(
FAILED
(
hr
))
goto
exit
;
}
*
found
=
array
;
exit:
if
(
FAILED
(
hr
)
&&
array
)
IUIAutomationElementArray_Release
(
array
);
SafeArrayDestroy
(
tree_structs
);
SafeArrayDestroy
(
offsets
);
SafeArrayDestroy
(
sa
);
return
hr
;
}
static
HRESULT
create_uia_element_from_cache_req
(
IUIAutomationElement
**
iface
,
BOOL
from_cui8
,
struct
UiaCacheRequest
*
cache_req
,
SAFEARRAY
*
req_data
,
BSTR
tree_struct
);
static
HRESULT
WINAPI
uia_element_BuildUpdatedCache
(
IUIAutomationElement9
*
iface
,
IUIAutomationCacheRequest
*
cache_req
,
IUIAutomationElement
**
updated_elem
)
{
...
...
@@ -1169,7 +1263,7 @@ static HRESULT WINAPI uia_element_BuildUpdatedCache(IUIAutomationElement9 *iface
if
(
FAILED
(
hr
))
return
hr
;
hr
=
create_uia_element_from_cache_req
(
&
cache_elem
,
element
->
from_cui8
,
cache_req_struct
,
sa
,
tree_struct
);
hr
=
create_uia_element_from_cache_req
(
&
cache_elem
,
element
->
from_cui8
,
cache_req_struct
,
0
,
sa
,
tree_struct
);
if
(
SUCCEEDED
(
hr
))
*
updated_elem
=
cache_elem
;
...
...
@@ -2185,7 +2279,7 @@ static int __cdecl uia_compare_cache_props(const void *a, const void *b)
}
static
HRESULT
create_uia_element_from_cache_req
(
IUIAutomationElement
**
iface
,
BOOL
from_cui8
,
struct
UiaCacheRequest
*
cache_req
,
SAFEARRAY
*
req_data
,
BSTR
tree_struct
)
struct
UiaCacheRequest
*
cache_req
,
LONG
start_idx
,
SAFEARRAY
*
req_data
,
BSTR
tree_struct
)
{
IUIAutomationElement
*
element
=
NULL
;
struct
uia_element
*
elem_data
;
...
...
@@ -2197,7 +2291,8 @@ static HRESULT create_uia_element_from_cache_req(IUIAutomationElement **iface, B
*
iface
=
NULL
;
VariantInit
(
&
v
);
idx
[
0
]
=
idx
[
1
]
=
0
;
idx
[
0
]
=
start_idx
;
idx
[
1
]
=
0
;
hr
=
SafeArrayGetElement
(
req_data
,
idx
,
&
v
);
if
(
FAILED
(
hr
))
goto
exit
;
...
...
@@ -2230,7 +2325,7 @@ static HRESULT create_uia_element_from_cache_req(IUIAutomationElement **iface, B
elem_data
->
cached_props
[
i
].
prop_id
=
prop_info
->
prop_id
;
idx
[
0
]
=
0
;
idx
[
0
]
=
start_idx
;
idx
[
1
]
=
1
+
i
;
hr
=
SafeArrayGetElement
(
req_data
,
idx
,
&
elem_data
->
cached_props
[
i
].
prop_val
);
if
(
FAILED
(
hr
))
...
...
@@ -2445,9 +2540,22 @@ static HRESULT WINAPI uia_iface_get_ContentViewCondition(IUIAutomation6 *iface,
static
HRESULT
WINAPI
uia_iface_CreateCacheRequest
(
IUIAutomation6
*
iface
,
IUIAutomationCacheRequest
**
out_cache_req
)
{
HRESULT
hr
;
TRACE
(
"%p, %p
\n
"
,
iface
,
out_cache_req
);
return
create_uia_cache_request_iface
(
out_cache_req
);
hr
=
create_uia_cache_request_iface
(
out_cache_req
);
if
(
FAILED
(
hr
))
return
hr
;
hr
=
IUIAutomationCacheRequest_AddProperty
(
*
out_cache_req
,
UIA_RuntimeIdPropertyId
);
if
(
FAILED
(
hr
))
{
IUIAutomationCacheRequest_Release
(
*
out_cache_req
);
*
out_cache_req
=
NULL
;
}
return
hr
;
}
static
HRESULT
WINAPI
uia_iface_CreateTrueCondition
(
IUIAutomation6
*
iface
,
IUIAutomationCondition
**
out_condition
)
...
...
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