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
c5b2c036
Commit
c5b2c036
authored
May 23, 2023
by
Connor McAdams
Committed by
Alexandre Julliard
Jun 12, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Implement UiaRaiseAutomationEvent.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
61712ec7
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
211 additions
and
27 deletions
+211
-27
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+38
-13
uia_client.c
dlls/uiautomationcore/uia_client.c
+3
-5
uia_event.c
dlls/uiautomationcore/uia_event.c
+167
-0
uia_main.c
dlls/uiautomationcore/uia_main.c
+0
-9
uia_private.h
dlls/uiautomationcore/uia_private.h
+3
-0
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
c5b2c036
...
...
@@ -13869,6 +13869,32 @@ static void test_UiaRemoveEvent_args(HUIANODE node)
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#lx.
\n
"
,
hr
);
}
static
void
test_UiaRaiseAutomationEvent_args
(
void
)
{
HRESULT
hr
;
hr
=
UiaRaiseAutomationEvent
(
NULL
,
UIA_AutomationFocusChangedEventId
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#lx.
\n
"
,
hr
);
/* Returns failure code from get_ProviderOptions. */
initialize_provider
(
&
Provider2
,
0
,
NULL
,
TRUE
);
hr
=
UiaRaiseAutomationEvent
(
&
Provider2
.
IRawElementProviderSimple_iface
,
UIA_AutomationFocusChangedEventId
);
/* Windows 7 returns S_OK. */
ok
(
hr
==
E_NOTIMPL
||
broken
(
hr
==
S_OK
),
"Unexpected hr %#lx.
\n
"
,
hr
);
/* Invalid event ID - doesn't return failure code. */
initialize_provider
(
&
Provider2
,
ProviderOptions_ServerSideProvider
,
NULL
,
TRUE
);
hr
=
UiaRaiseAutomationEvent
(
&
Provider2
.
IRawElementProviderSimple_iface
,
1
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
/*
* UIA_StructureChangedEventId should use UiaRaiseStructureChangedEvent.
* No failure code is returned, however.
*/
hr
=
UiaRaiseAutomationEvent
(
&
Provider2
.
IRawElementProviderSimple_iface
,
UIA_StructureChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
}
static
void
test_UiaAddEvent
(
void
)
{
IRawElementProviderFragmentRoot
*
embedded_roots
[
2
]
=
{
&
Provider_child
.
IRawElementProviderFragmentRoot_iface
,
...
...
@@ -13908,6 +13934,7 @@ static void test_UiaAddEvent(void)
/* Test valid function input arguments. */
test_UiaAddEvent_args
(
node
);
test_UiaRemoveEvent_args
(
node
);
test_UiaRaiseAutomationEvent_args
();
/*
* Raise event without any registered event handlers.
...
...
@@ -13915,8 +13942,7 @@ static void test_UiaAddEvent(void)
method_sequences_enabled
=
TRUE
;
hr
=
UiaRaiseAutomationEvent
(
&
Provider
.
IRawElementProviderSimple_iface
,
UIA_AutomationFocusChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
)
&&
sequence_cnt
)
ok_method_sequence
(
event_seq1
,
"event_seq1"
);
ok_method_sequence
(
event_seq1
,
"event_seq1"
);
/*
* Register an event on a node without an HWND/RuntimeId. The event will
...
...
@@ -13941,8 +13967,7 @@ static void test_UiaAddEvent(void)
*/
hr
=
UiaRaiseAutomationEvent
(
&
Provider
.
IRawElementProviderSimple_iface
,
UIA_AutomationFocusChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
)
&&
sequence_cnt
)
ok_method_sequence
(
event_seq3
,
"event_seq3"
);
ok_method_sequence
(
event_seq3
,
"event_seq3"
);
hr
=
UiaRemoveEvent
(
event
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
...
...
@@ -13976,7 +14001,7 @@ static void test_UiaAddEvent(void)
SET_EXPECT
(
uia_event_callback
);
hr
=
UiaRaiseAutomationEvent
(
&
Provider
.
IRawElementProviderSimple_iface
,
UIA_AutomationFocusChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
CHECK_CALLED
(
uia_event_callback
);
CHECK_CALLED
(
uia_event_callback
);
/*
* Runtime ID matches so event callback is invoked, but nothing matches
...
...
@@ -13991,7 +14016,7 @@ static void test_UiaAddEvent(void)
SET_EXPECT
(
uia_event_callback
);
hr
=
UiaRaiseAutomationEvent
(
&
Provider
.
IRawElementProviderSimple_iface
,
UIA_AutomationFocusChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
CHECK_CALLED
(
uia_event_callback
);
CHECK_CALLED
(
uia_event_callback
);
set_provider_prop_override
(
&
Provider
,
NULL
,
0
);
method_sequences_enabled
=
TRUE
;
...
...
@@ -14027,7 +14052,7 @@ static void test_UiaAddEvent(void)
SET_EXPECT
(
uia_event_callback
);
hr
=
UiaRaiseAutomationEvent
(
&
Provider_child
.
IRawElementProviderSimple_iface
,
UIA_AutomationFocusChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
CHECK_CALLED
(
uia_event_callback
);
CHECK_CALLED
(
uia_event_callback
);
/* Provider_child doesn't match the view condition, but Provider does. */
variant_init_bool
(
&
v
,
FALSE
);
...
...
@@ -14040,7 +14065,7 @@ static void test_UiaAddEvent(void)
SET_EXPECT
(
uia_event_callback
);
hr
=
UiaRaiseAutomationEvent
(
&
Provider_child
.
IRawElementProviderSimple_iface
,
UIA_AutomationFocusChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
CHECK_CALLED
(
uia_event_callback
);
CHECK_CALLED
(
uia_event_callback
);
set_provider_prop_override
(
&
Provider_child
,
NULL
,
0
);
hr
=
UiaRemoveEvent
(
event
);
...
...
@@ -14061,7 +14086,7 @@ static void test_UiaAddEvent(void)
SET_EXPECT
(
uia_event_callback
);
hr
=
UiaRaiseAutomationEvent
(
&
Provider_child_child
.
IRawElementProviderSimple_iface
,
UIA_AutomationFocusChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
CHECK_CALLED
(
uia_event_callback
);
CHECK_CALLED
(
uia_event_callback
);
hr
=
UiaRemoveEvent
(
event
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
...
...
@@ -14206,11 +14231,11 @@ static void test_UiaAddEvent(void)
Provider_hwnd2
.
prov_opts
=
ProviderOptions_ClientSideProvider
;
hr
=
UiaRaiseAutomationEvent
(
&
Provider_hwnd2
.
IRawElementProviderSimple_iface
,
UIA_AutomationFocusChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
CHECK_CALLED
(
winproc_GETOBJECT_UiaRoot
);
todo_wine
CHECK_CALLED
(
prov_callback_base_hwnd
);
todo_wine
CHECK_CALLED
(
prov_callback_nonclient
);
CHECK_CALLED
(
winproc_GETOBJECT_UiaRoot
);
CHECK_CALLED
(
prov_callback_base_hwnd
);
CHECK_CALLED
(
prov_callback_nonclient
);
todo_wine
CHECK_CALLED_MULTI
(
prov_callback_proxy
,
2
);
todo_wine
CHECK_CALLED
(
uia_event_callback
);
CHECK_CALLED
(
uia_event_callback
);
hr
=
UiaRemoveEvent
(
event
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
...
...
dlls/uiautomationcore/uia_client.c
View file @
c5b2c036
...
...
@@ -747,7 +747,7 @@ static HRESULT get_child_for_node(struct uia_node *node, int start_prov_idx, int
return
S_OK
;
}
static
HRESULT
navigate_uia_node
(
struct
uia_node
*
node
,
int
nav_dir
,
HUIANODE
*
out_node
)
HRESULT
navigate_uia_node
(
struct
uia_node
*
node
,
int
nav_dir
,
HUIANODE
*
out_node
)
{
HRESULT
hr
;
VARIANT
v
;
...
...
@@ -835,8 +835,6 @@ static HRESULT navigate_uia_node(struct uia_node *node, int nav_dir, HUIANODE *o
return
S_OK
;
}
static
HRESULT
uia_condition_check
(
HUIANODE
node
,
struct
UiaCondition
*
condition
);
static
BOOL
uia_condition_matched
(
HRESULT
hr
);
static
HRESULT
conditional_navigate_uia_node
(
struct
uia_node
*
node
,
int
nav_dir
,
struct
UiaCondition
*
cond
,
HUIANODE
*
out_node
)
{
...
...
@@ -3024,7 +3022,7 @@ void WINAPI UiaRegisterProviderCallback(UiaProviderCallback *callback)
uia_provider_callback
=
default_uia_provider_callback
;
}
static
BOOL
uia_condition_matched
(
HRESULT
hr
)
BOOL
uia_condition_matched
(
HRESULT
hr
)
{
if
(
hr
==
S_FALSE
)
return
FALSE
;
...
...
@@ -3085,7 +3083,7 @@ static HRESULT uia_property_condition_check(HUIANODE node, struct UiaPropertyCon
return
hr
;
}
static
HRESULT
uia_condition_check
(
HUIANODE
node
,
struct
UiaCondition
*
condition
)
HRESULT
uia_condition_check
(
HUIANODE
node
,
struct
UiaCondition
*
condition
)
{
HRESULT
hr
;
...
...
dlls/uiautomationcore/uia_event.c
View file @
c5b2c036
...
...
@@ -503,3 +503,170 @@ HRESULT WINAPI UiaRemoveEvent(HUIAEVENT huiaevent)
return
S_OK
;
}
static
HRESULT
uia_event_invoke
(
HUIANODE
node
,
struct
UiaEventArgs
*
args
,
struct
uia_event
*
event
)
{
SAFEARRAY
*
out_req
;
BSTR
tree_struct
;
HRESULT
hr
;
hr
=
UiaGetUpdatedCache
(
node
,
&
event
->
cache_req
,
NormalizeState_View
,
NULL
,
&
out_req
,
&
tree_struct
);
if
(
SUCCEEDED
(
hr
))
{
event
->
cback
(
args
,
out_req
,
tree_struct
);
SafeArrayDestroy
(
out_req
);
SysFreeString
(
tree_struct
);
}
return
hr
;
}
/*
* Check if the provider that raised the event matches this particular event.
*/
static
HRESULT
uia_event_check_match
(
HUIANODE
node
,
SAFEARRAY
*
rt_id
,
struct
UiaEventArgs
*
args
,
struct
uia_event
*
event
)
{
struct
UiaPropertyCondition
prop_cond
=
{
ConditionType_Property
,
UIA_RuntimeIdPropertyId
};
struct
uia_node
*
node_data
=
impl_from_IWineUiaNode
((
IWineUiaNode
*
)
node
);
HRESULT
hr
=
S_OK
;
/* Event is no longer valid. */
if
(
InterlockedCompareExchange
(
&
event
->
event_defunct
,
0
,
0
)
!=
0
)
return
S_OK
;
/* Can't match an event that doesn't have a runtime ID, early out. */
if
(
!
event
->
runtime_id
)
return
S_OK
;
if
(
rt_id
&&
!
uia_compare_safearrays
(
rt_id
,
event
->
runtime_id
,
UIAutomationType_IntArray
))
{
if
(
event
->
scope
&
TreeScope_Element
)
hr
=
uia_event_invoke
(
node
,
args
,
event
);
return
hr
;
}
if
(
!
(
event
->
scope
&
(
TreeScope_Descendants
|
TreeScope_Children
)))
return
S_OK
;
V_VT
(
&
prop_cond
.
Value
)
=
VT_I4
|
VT_ARRAY
;
V_ARRAY
(
&
prop_cond
.
Value
)
=
event
->
runtime_id
;
IWineUiaNode_AddRef
(
&
node_data
->
IWineUiaNode_iface
);
while
(
1
)
{
HUIANODE
node2
=
NULL
;
hr
=
navigate_uia_node
(
node_data
,
NavigateDirection_Parent
,
&
node2
);
IWineUiaNode_Release
(
&
node_data
->
IWineUiaNode_iface
);
if
(
FAILED
(
hr
)
||
!
node2
)
return
hr
;
node_data
=
impl_from_IWineUiaNode
((
IWineUiaNode
*
)
node2
);
hr
=
uia_condition_check
(
node2
,
(
struct
UiaCondition
*
)
&
prop_cond
);
if
(
FAILED
(
hr
))
break
;
if
(
uia_condition_matched
(
hr
))
{
hr
=
uia_event_invoke
(
node
,
args
,
event
);
break
;
}
if
(
!
(
event
->
scope
&
TreeScope_Descendants
))
break
;
}
IWineUiaNode_Release
(
&
node_data
->
IWineUiaNode_iface
);
return
hr
;
}
static
HRESULT
uia_raise_event
(
IRawElementProviderSimple
*
elprov
,
struct
UiaEventArgs
*
args
)
{
struct
uia_event_map_entry
*
event_entry
;
enum
ProviderOptions
prov_opts
=
0
;
struct
list
*
cursor
,
*
cursor2
;
HUIANODE
node
;
SAFEARRAY
*
sa
;
HRESULT
hr
;
hr
=
IRawElementProviderSimple_get_ProviderOptions
(
elprov
,
&
prov_opts
);
if
(
FAILED
(
hr
))
return
hr
;
EnterCriticalSection
(
&
event_map_cs
);
if
((
event_entry
=
uia_get_event_map_entry_for_event
(
args
->
EventId
)))
InterlockedIncrement
(
&
event_entry
->
refs
);
LeaveCriticalSection
(
&
event_map_cs
);
if
(
!
event_entry
)
return
S_OK
;
/*
* For events raised on server-side providers, we don't want to add any
* clientside HWND providers.
*/
if
(
prov_opts
&
ProviderOptions_ServerSideProvider
)
hr
=
create_uia_node_from_elprov
(
elprov
,
&
node
,
FALSE
);
else
hr
=
create_uia_node_from_elprov
(
elprov
,
&
node
,
TRUE
);
if
(
FAILED
(
hr
))
{
uia_event_map_entry_release
(
event_entry
);
return
hr
;
}
hr
=
UiaGetRuntimeId
(
node
,
&
sa
);
if
(
FAILED
(
hr
))
{
uia_event_map_entry_release
(
event_entry
);
UiaNodeRelease
(
node
);
return
hr
;
}
LIST_FOR_EACH_SAFE
(
cursor
,
cursor2
,
&
event_entry
->
events_list
)
{
struct
uia_event
*
event
=
LIST_ENTRY
(
cursor
,
struct
uia_event
,
event_list_entry
);
hr
=
uia_event_check_match
(
node
,
sa
,
args
,
event
);
if
(
FAILED
(
hr
))
break
;
}
uia_event_map_entry_release
(
event_entry
);
SafeArrayDestroy
(
sa
);
UiaNodeRelease
(
node
);
return
hr
;
}
/***********************************************************************
* UiaRaiseAutomationEvent (uiautomationcore.@)
*/
HRESULT
WINAPI
UiaRaiseAutomationEvent
(
IRawElementProviderSimple
*
elprov
,
EVENTID
id
)
{
const
struct
uia_event_info
*
event_info
=
uia_event_info_from_id
(
id
);
struct
UiaEventArgs
args
=
{
EventArgsType_Simple
,
id
};
HRESULT
hr
;
TRACE
(
"(%p, %d)
\n
"
,
elprov
,
id
);
if
(
!
elprov
)
return
E_INVALIDARG
;
if
(
!
event_info
||
event_info
->
event_arg_type
!=
EventArgsType_Simple
)
{
if
(
!
event_info
)
FIXME
(
"No event info structure for event id %d
\n
"
,
id
);
else
WARN
(
"Wrong event raising function for event args type %d
\n
"
,
event_info
->
event_arg_type
);
return
S_OK
;
}
hr
=
uia_raise_event
(
elprov
,
&
args
);
if
(
FAILED
(
hr
))
return
hr
;
return
S_OK
;
}
dlls/uiautomationcore/uia_main.c
View file @
c5b2c036
...
...
@@ -299,15 +299,6 @@ HRESULT WINAPI UiaGetReservedNotSupportedValue(IUnknown **value)
}
/***********************************************************************
* UiaRaiseAutomationEvent (uiautomationcore.@)
*/
HRESULT
WINAPI
UiaRaiseAutomationEvent
(
IRawElementProviderSimple
*
provider
,
EVENTID
id
)
{
FIXME
(
"(%p, %d): stub
\n
"
,
provider
,
id
);
return
S_OK
;
}
/***********************************************************************
* UiaRaiseAutomationPropertyChangedEvent (uiautomationcore.@)
*/
HRESULT
WINAPI
UiaRaiseAutomationPropertyChangedEvent
(
IRawElementProviderSimple
*
provider
,
PROPERTYID
id
,
VARIANT
old
,
VARIANT
new
)
...
...
dlls/uiautomationcore/uia_private.h
View file @
c5b2c036
...
...
@@ -159,8 +159,11 @@ static inline BOOL uia_array_reserve(void **elements, SIZE_T *capacity, SIZE_T c
/* uia_client.c */
int
get_node_provider_type_at_idx
(
struct
uia_node
*
node
,
int
idx
)
DECLSPEC_HIDDEN
;
HRESULT
attach_event_to_uia_node
(
HUIANODE
node
,
struct
uia_event
*
event
)
DECLSPEC_HIDDEN
;
HRESULT
navigate_uia_node
(
struct
uia_node
*
node
,
int
nav_dir
,
HUIANODE
*
out_node
)
DECLSPEC_HIDDEN
;
HRESULT
create_uia_node_from_elprov
(
IRawElementProviderSimple
*
elprov
,
HUIANODE
*
out_node
,
BOOL
get_hwnd_providers
)
DECLSPEC_HIDDEN
;
HRESULT
uia_condition_check
(
HUIANODE
node
,
struct
UiaCondition
*
condition
)
DECLSPEC_HIDDEN
;
BOOL
uia_condition_matched
(
HRESULT
hr
)
DECLSPEC_HIDDEN
;
/* uia_com_client.c */
HRESULT
create_uia_iface
(
IUnknown
**
iface
,
BOOL
is_cui8
)
DECLSPEC_HIDDEN
;
...
...
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