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
6254f663
Commit
6254f663
authored
Feb 02, 2023
by
Connor McAdams
Committed by
Alexandre Julliard
Feb 20, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Implement IUIAutomationElement::GetCurrentPropertyValueEx.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
2d8bf67b
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
159 additions
and
15 deletions
+159
-15
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+123
-14
uia_com_client.c
dlls/uiautomationcore/uia_com_client.c
+36
-1
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
6254f663
...
...
@@ -4504,7 +4504,7 @@ static const struct prov_method_sequence node_from_prov8[] = {
{
0
}
};
static
void
check_uia_prop_val
(
PROPERTYID
prop_id
,
enum
UIAutomationType
type
,
VARIANT
*
v
);
static
void
check_uia_prop_val
(
PROPERTYID
prop_id
,
enum
UIAutomationType
type
,
VARIANT
*
v
,
BOOL
from_com
);
static
DWORD
WINAPI
uia_node_from_provider_test_com_thread
(
LPVOID
param
)
{
HUIANODE
node
=
param
;
...
...
@@ -4523,7 +4523,7 @@ static DWORD WINAPI uia_node_from_provider_test_com_thread(LPVOID param)
hr
=
UiaGetPropertyValue
(
node
,
UIA_ProcessIdPropertyId
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
check_uia_prop_val
(
UIA_ProcessIdPropertyId
,
UIAutomationType_Int
,
&
v
);
check_uia_prop_val
(
UIA_ProcessIdPropertyId
,
UIAutomationType_Int
,
&
v
,
FALSE
);
/*
* When retrieving a UIAutomationType_Element property, if UseComThreading
...
...
@@ -4537,7 +4537,7 @@ static DWORD WINAPI uia_node_from_provider_test_com_thread(LPVOID param)
Provider_child
.
expected_tid
=
Provider
.
expected_tid
;
hr
=
UiaGetPropertyValue
(
node
,
UIA_LabeledByPropertyId
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
check_uia_prop_val
(
UIA_LabeledByPropertyId
,
UIAutomationType_Element
,
&
v
);
check_uia_prop_val
(
UIA_LabeledByPropertyId
,
UIAutomationType_Element
,
&
v
,
FALSE
);
/* Unset ProviderOptions_UseComThreading. */
Provider_child
.
prov_opts
=
ProviderOptions_ServerSideProvider
;
...
...
@@ -4549,7 +4549,7 @@ static DWORD WINAPI uia_node_from_provider_test_com_thread(LPVOID param)
* called on the current thread.
*/
Provider_child
.
expected_tid
=
GetCurrentThreadId
();
check_uia_prop_val
(
UIA_LabeledByPropertyId
,
UIAutomationType_Element
,
&
v
);
check_uia_prop_val
(
UIA_LabeledByPropertyId
,
UIAutomationType_Element
,
&
v
,
FALSE
);
CoUninitialize
();
...
...
@@ -4982,7 +4982,7 @@ static void check_uia_rect_val_(VARIANT *v, struct UiaRect *rect, const char *fi
ok_
(
file
,
line
)(
tmp
[
3
]
==
rect
->
height
,
"Unexpected height value %f, expected %f
\n
"
,
tmp
[
3
],
rect
->
height
);
}
static
void
check_uia_prop_val
(
PROPERTYID
prop_id
,
enum
UIAutomationType
type
,
VARIANT
*
v
)
static
void
check_uia_prop_val
(
PROPERTYID
prop_id
,
enum
UIAutomationType
type
,
VARIANT
*
v
,
BOOL
from_com
)
{
LONG
idx
;
...
...
@@ -5053,6 +5053,22 @@ static void check_uia_prop_val(PROPERTYID prop_id, enum UIAutomationType type, V
HRESULT
hr
;
VARIANT
v1
;
if
(
from_com
)
{
IUIAutomationElement
*
elem
;
ok
(
V_VT
(
v
)
==
VT_UNKNOWN
,
"Unexpected VT %d
\n
"
,
V_VT
(
v
));
hr
=
IUnknown_QueryInterface
(
V_UNKNOWN
(
v
),
&
IID_IUIAutomationElement
,
(
void
**
)
&
elem
);
VariantClear
(
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
ok
(
Provider_child
.
ref
==
2
,
"Unexpected refcnt %ld
\n
"
,
Provider_child
.
ref
);
hr
=
IUIAutomationElement_GetCurrentPropertyValueEx
(
elem
,
UIA_ControlTypePropertyId
,
TRUE
,
&
v1
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
IUIAutomationElement_Release
(
elem
);
}
else
{
#ifdef _WIN64
ok
(
V_VT
(
v
)
==
VT_I8
,
"Unexpected VT %d
\n
"
,
V_VT
(
v
));
tmp_node
=
(
HUIANODE
)
V_I8
(
v
);
...
...
@@ -5064,11 +5080,13 @@ static void check_uia_prop_val(PROPERTYID prop_id, enum UIAutomationType type, V
hr
=
UiaGetPropertyValue
(
tmp_node
,
UIA_ControlTypePropertyId
,
&
v1
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
ok
(
UiaNodeRelease
(
tmp_node
),
"Failed to release node
\n
"
);
}
ok
(
V_VT
(
&
v1
)
==
VT_I4
,
"Unexpected VT %d
\n
"
,
V_VT
(
&
v1
));
ok
(
V_I4
(
&
v1
)
==
uia_i4_prop_val
,
"Unexpected I4 %#lx
\n
"
,
V_I4
(
&
v1
));
ok
(
UiaNodeRelease
(
tmp_node
),
"Failed to release node
\n
"
);
ok
(
Provider_child
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Provider_child
.
ref
);
ok_method_sequence
(
get_elem_prop_seq
,
NULL
);
break
;
}
...
...
@@ -5214,7 +5232,7 @@ static void test_UiaGetPropertyValue(void)
winetest_push_context
(
"prop_id %d"
,
prop_id
);
hr
=
UiaGetPropertyValue
(
node
,
prop_id
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
check_uia_prop_val
(
prop_id
,
elem_prop
->
type
,
&
v
);
check_uia_prop_val
(
prop_id
,
elem_prop
->
type
,
&
v
,
FALSE
);
/*
* Some properties have special behavior if an invalid value is
...
...
@@ -5973,7 +5991,7 @@ static DWORD WINAPI uia_node_from_handle_test_thread(LPVOID param)
hr
=
UiaGetPropertyValue
(
node
,
UIA_ControlTypePropertyId
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
check_uia_prop_val
(
UIA_ControlTypePropertyId
,
UIAutomationType_Int
,
&
v
);
check_uia_prop_val
(
UIA_ControlTypePropertyId
,
UIAutomationType_Int
,
&
v
,
FALSE
);
/*
* On Windows, nested providers are always called on a separate thread if
...
...
@@ -6132,7 +6150,7 @@ static DWORD WINAPI uia_node_from_handle_test_thread(LPVOID param)
hr
=
UiaGetPropertyValue
(
node
,
UIA_ControlTypePropertyId
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
check_uia_prop_val
(
UIA_ControlTypePropertyId
,
UIAutomationType_Int
,
&
v
);
check_uia_prop_val
(
UIA_ControlTypePropertyId
,
UIAutomationType_Int
,
&
v
,
FALSE
);
/* Nodes returned from a nested node will be tracked and disconnectable. */
Provider_child
.
prov_opts
=
ProviderOptions_ServerSideProvider
;
...
...
@@ -6225,7 +6243,7 @@ static DWORD WINAPI uia_node_from_handle_test_thread(LPVOID param)
hr
=
UiaGetPropertyValue
(
node
,
UIA_ControlTypePropertyId
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
check_uia_prop_val
(
UIA_ControlTypePropertyId
,
UIAutomationType_Int
,
&
v
);
check_uia_prop_val
(
UIA_ControlTypePropertyId
,
UIAutomationType_Int
,
&
v
,
FALSE
);
/* Finally, disconnect node. */
Provider
.
hwnd
=
hwnd
;
...
...
@@ -6447,7 +6465,7 @@ static void test_UiaNodeFromHandle(const char *name)
Provider
.
expected_tid
=
GetCurrentThreadId
();
hr
=
UiaGetPropertyValue
(
node
,
UIA_ControlTypePropertyId
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
check_uia_prop_val
(
UIA_ControlTypePropertyId
,
UIAutomationType_Int
,
&
v
);
check_uia_prop_val
(
UIA_ControlTypePropertyId
,
UIAutomationType_Int
,
&
v
,
FALSE
);
/* UIAutomationType_Element properties will return a normal node. */
Provider_child
.
prov_opts
=
ProviderOptions_ServerSideProvider
;
...
...
@@ -9642,12 +9660,22 @@ static HWND create_test_hwnd(const char *class_name)
0
,
0
,
100
,
100
,
NULL
,
NULL
,
NULL
,
NULL
);
}
static
IUIAutomationElement
*
create_test_element_from_hwnd
(
IUIAutomation
*
uia_iface
,
HWND
hwnd
)
static
IUIAutomationElement
*
create_test_element_from_hwnd
(
IUIAutomation
*
uia_iface
,
HWND
hwnd
,
BOOL
block_hwnd_provs
)
{
IUIAutomationElement
*
element
;
HRESULT
hr
;
VARIANT
v
;
if
(
block_hwnd_provs
)
{
SET_EXPECT
(
prov_callback_base_hwnd
);
SET_EXPECT
(
prov_callback_nonclient
);
base_hwnd_prov
=
proxy_prov
=
parent_proxy_prov
=
nc_prov
=
NULL
;
UiaRegisterProviderCallback
(
test_uia_provider_callback
);
}
else
UiaRegisterProviderCallback
(
NULL
);
initialize_provider
(
&
Provider
,
ProviderOptions_ServerSideProvider
,
hwnd
,
TRUE
);
prov_root
=
&
Provider
.
IRawElementProviderSimple_iface
;
SET_EXPECT
(
winproc_GETOBJECT_UiaRoot
);
...
...
@@ -9659,19 +9687,31 @@ static IUIAutomationElement *create_test_element_from_hwnd(IUIAutomation *uia_if
ok
(
Provider
.
ref
==
2
,
"Unexpected refcnt %ld
\n
"
,
Provider
.
ref
);
CHECK_CALLED
(
winproc_GETOBJECT_UiaRoot
);
called_winproc_GETOBJECT_CLIENT
=
expect_winproc_GETOBJECT_CLIENT
=
0
;
if
(
block_hwnd_provs
)
{
CHECK_CALLED
(
prov_callback_base_hwnd
);
CHECK_CALLED
(
prov_callback_nonclient
);
}
hr
=
IUIAutomationElement_GetCurrentPropertyValueEx
(
element
,
UIA_ProviderDescriptionPropertyId
,
TRUE
,
&
v
);
todo_wine
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
check_node_provider_desc_prefix
(
V_BSTR
(
&
v
),
GetCurrentProcessId
(),
hwnd
);
if
(
!
block_hwnd_provs
)
{
check_node_provider_desc
(
V_BSTR
(
&
v
),
L"Main"
,
L"Provider"
,
FALSE
);
check_node_provider_desc
(
V_BSTR
(
&
v
),
L"Nonclient"
,
NULL
,
FALSE
);
check_node_provider_desc
(
V_BSTR
(
&
v
),
L"Hwnd"
,
NULL
,
TRUE
);
}
else
check_node_provider_desc
(
V_BSTR
(
&
v
),
L"Main"
,
L"Provider"
,
TRUE
);
VariantClear
(
&
v
);
}
ok_method_sequence
(
node_from_hwnd2
,
"create_test_element"
);
UiaRegisterProviderCallback
(
NULL
);
return
element
;
}
...
...
@@ -9683,7 +9723,7 @@ static void test_ElementFromHandle(IUIAutomation *uia_iface, BOOL is_cui8)
IUIAutomationElement
*
element
;
HRESULT
hr
;
element
=
create_test_element_from_hwnd
(
uia_iface
,
hwnd
);
element
=
create_test_element_from_hwnd
(
uia_iface
,
hwnd
,
FALSE
);
hr
=
IUIAutomationElement_QueryInterface
(
element
,
&
IID_IUIAutomationElement2
,
(
void
**
)
&
element_2
);
if
(
is_cui8
)
{
...
...
@@ -9702,6 +9742,74 @@ static void test_ElementFromHandle(IUIAutomation *uia_iface, BOOL is_cui8)
prov_root
=
NULL
;
}
static
void
test_Element_GetPropertyValue
(
IUIAutomation
*
uia_iface
)
{
HWND
hwnd
=
create_test_hwnd
(
"test_Element_GetPropertyValue class"
);
const
struct
uia_element_property
*
elem_prop
;
IUIAutomationElement
*
element
;
IUnknown
*
unk_ns
;
int
i
,
prop_id
;
HRESULT
hr
;
VARIANT
v
;
element
=
create_test_element_from_hwnd
(
uia_iface
,
hwnd
,
TRUE
);
Provider
.
frag_root
=
&
Provider
.
IRawElementProviderFragmentRoot_iface
;
initialize_provider
(
&
Provider_child
,
ProviderOptions_ServerSideProvider
,
NULL
,
TRUE
);
provider_add_child
(
&
Provider
,
&
Provider_child
);
hr
=
UiaGetReservedNotSupportedValue
(
&
unk_ns
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
VariantInit
(
&
v
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
element_properties
);
i
++
)
{
elem_prop
=
&
element_properties
[
i
];
/* Skip ElementArray properties for now. */
if
(
elem_prop
->
type
==
UIAutomationType_ElementArray
)
continue
;
Provider
.
ret_invalid_prop_type
=
FALSE
;
VariantClear
(
&
v
);
if
(
!
(
prop_id
=
UiaLookupId
(
AutomationIdentifierType_Property
,
elem_prop
->
prop_guid
)))
{
win_skip
(
"No propertyId for GUID %s, skipping further tests.
\n
"
,
debugstr_guid
(
elem_prop
->
prop_guid
));
break
;
}
winetest_push_context
(
"Element prop_id %d"
,
prop_id
);
hr
=
IUIAutomationElement_GetCurrentPropertyValueEx
(
element
,
prop_id
,
TRUE
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
check_uia_prop_val
(
prop_id
,
elem_prop
->
type
,
&
v
,
TRUE
);
/*
* Some properties have special behavior if an invalid value is
* returned, skip them here.
*/
if
(
!
elem_prop
->
skip_invalid
)
{
Provider
.
ret_invalid_prop_type
=
TRUE
;
hr
=
IUIAutomationElement_GetCurrentPropertyValueEx
(
element
,
prop_id
,
TRUE
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
ok_method_sequence
(
get_prop_invalid_type_seq
,
NULL
);
ok
(
V_VT
(
&
v
)
==
VT_UNKNOWN
,
"Unexpected vt %d
\n
"
,
V_VT
(
&
v
));
ok
(
V_UNKNOWN
(
&
v
)
==
unk_ns
,
"unexpected IUnknown %p
\n
"
,
V_UNKNOWN
(
&
v
));
VariantClear
(
&
v
);
}
}
winetest_pop_context
();
}
IUIAutomationElement_Release
(
element
);
ok
(
Provider
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Provider
.
ref
);
DestroyWindow
(
hwnd
);
UnregisterClassA
(
"test_Element_GetPropertyValue class"
,
NULL
);
}
struct
uia_com_classes
{
const
GUID
*
clsid
;
const
GUID
*
iid
;
...
...
@@ -9766,6 +9874,7 @@ static void test_CUIAutomation(void)
ok
(
!!
uia_iface
,
"uia_iface == NULL
\n
"
);
test_ElementFromHandle
(
uia_iface
,
has_cui8
);
test_Element_GetPropertyValue
(
uia_iface
);
IUIAutomation_Release
(
uia_iface
);
CoUninitialize
();
...
...
dlls/uiautomationcore/uia_com_client.c
View file @
6254f663
...
...
@@ -134,11 +134,46 @@ static HRESULT WINAPI uia_element_GetCurrentPropertyValue(IUIAutomationElement9
return
E_NOTIMPL
;
}
static
HRESULT
create_uia_element
(
IUIAutomationElement
**
iface
,
BOOL
from_cui8
,
HUIANODE
node
);
static
HRESULT
WINAPI
uia_element_GetCurrentPropertyValueEx
(
IUIAutomationElement9
*
iface
,
PROPERTYID
prop_id
,
BOOL
ignore_default
,
VARIANT
*
ret_val
)
{
FIXME
(
"%p: stub
\n
"
,
iface
);
const
struct
uia_prop_info
*
prop_info
=
uia_prop_info_from_id
(
prop_id
);
struct
uia_element
*
element
=
impl_from_IUIAutomationElement9
(
iface
);
HRESULT
hr
;
TRACE
(
"%p, %d, %d, %p
\n
"
,
iface
,
prop_id
,
ignore_default
,
ret_val
);
if
(
!
ignore_default
)
FIXME
(
"Default values currently unimplemented
\n
"
);
VariantInit
(
ret_val
);
if
(
prop_info
->
type
==
UIAutomationType_ElementArray
)
{
FIXME
(
"ElementArray property types currently unsupported for IUIAutomationElement
\n
"
);
return
E_NOTIMPL
;
}
hr
=
UiaGetPropertyValue
(
element
->
node
,
prop_id
,
ret_val
);
if
((
prop_info
->
type
==
UIAutomationType_Element
)
&&
(
V_VT
(
ret_val
)
!=
VT_UNKNOWN
))
{
IUIAutomationElement
*
out_elem
;
HUIANODE
node
;
hr
=
UiaHUiaNodeFromVariant
(
ret_val
,
&
node
);
VariantClear
(
ret_val
);
if
(
FAILED
(
hr
))
return
hr
;
hr
=
create_uia_element
(
&
out_elem
,
element
->
from_cui8
,
node
);
if
(
SUCCEEDED
(
hr
))
{
V_VT
(
ret_val
)
=
VT_UNKNOWN
;
V_UNKNOWN
(
ret_val
)
=
(
IUnknown
*
)
out_elem
;
}
}
return
hr
;
}
static
HRESULT
WINAPI
uia_element_GetCachedPropertyValue
(
IUIAutomationElement9
*
iface
,
PROPERTYID
prop_id
,
...
...
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