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
53376c55
Commit
53376c55
authored
Jul 20, 2023
by
Connor McAdams
Committed by
Alexandre Julliard
Jul 24, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Add support for calling COM event handlers.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
9ab915a7
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
99 additions
and
27 deletions
+99
-27
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+4
-4
uia_com_client.c
dlls/uiautomationcore/uia_com_client.c
+91
-22
uia_event.c
dlls/uiautomationcore/uia_event.c
+1
-1
uia_private.h
dlls/uiautomationcore/uia_private.h
+3
-0
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
53376c55
...
...
@@ -13132,8 +13132,8 @@ static DWORD WINAPI uia_com_event_handler_test_thread(LPVOID param)
set_com_event_data
(
&
exp_node_desc
);
hr
=
UiaRaiseAutomationEvent
(
&
Provider2
.
IRawElementProviderSimple_iface
,
UIA_LiveRegionChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
CHECK_CALLED
(
uia_com_event_callback
);
todo_wine
ok
(
ComEventData
.
last_call_tid
==
GetCurrentThreadId
(),
"Event handler called on unexpected thread %ld
\n
"
,
CHECK_CALLED
(
uia_com_event_callback
);
ok
(
ComEventData
.
last_call_tid
==
GetCurrentThreadId
(),
"Event handler called on unexpected thread %ld
\n
"
,
ComEventData
.
last_call_tid
);
CoUninitialize
();
...
...
@@ -13146,7 +13146,7 @@ static DWORD WINAPI uia_com_event_handler_test_thread(LPVOID param)
set_com_event_data
(
&
exp_node_desc
);
hr
=
UiaRaiseAutomationEvent
(
&
Provider2
.
IRawElementProviderSimple_iface
,
UIA_LiveRegionChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
CHECK_CALLED
(
uia_com_event_callback
);
CHECK_CALLED
(
uia_com_event_callback
);
ok
(
ComEventData
.
last_call_tid
!=
GetCurrentThreadId
(),
"Event handler called on unexpected thread %ld
\n
"
,
ComEventData
.
last_call_tid
);
CoUninitialize
();
...
...
@@ -13233,7 +13233,7 @@ static void test_IUIAutomationEventHandler(IUIAutomation *uia_iface, IUIAutomati
set_com_event_data
(
&
exp_node_desc
);
hr
=
UiaRaiseAutomationEvent
(
&
Provider2
.
IRawElementProviderSimple_iface
,
UIA_LiveRegionChangedEventId
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
CHECK_CALLED
(
uia_com_event_callback
);
CHECK_CALLED
(
uia_com_event_callback
);
/*
* If no cache request is provided by the user in
...
...
dlls/uiautomationcore/uia_com_client.c
View file @
53376c55
...
...
@@ -950,26 +950,22 @@ static int uia_com_event_handler_id_compare(const void *key, const struct rb_ent
}
struct
uia_com_event
{
IUnknown
*
handler_iface
;
DWORD
git_cookie
;
HUIAEVENT
event
;
BOOL
from_cui8
;
struct
list
event_handler_map_list_entry
;
struct
uia_event_handler_map_entry
*
handler_map
;
};
static
HRESULT
uia_event_handlers_add_handler
(
IUnknown
*
handler_iface
,
SAFEARRAY
*
runtime_id
,
int
event_id
)
static
HRESULT
uia_event_handlers_add_handler
(
IUnknown
*
handler_iface
,
SAFEARRAY
*
runtime_id
,
int
event_id
,
struct
uia_com_event
*
event
)
{
struct
uia_event_handler_identifier
event_ident
=
{
handler_iface
,
runtime_id
,
event_id
};
struct
uia_event_handler_map_entry
*
event_map
;
struct
uia_com_event
*
event
;
struct
rb_entry
*
rb_entry
;
HRESULT
hr
=
S_OK
;
if
(
!
(
event
=
heap_alloc_zero
(
sizeof
(
*
event
))))
return
E_OUTOFMEMORY
;
event
->
handler_iface
=
handler_iface
;
IUnknown_AddRef
(
handler_iface
);
EnterCriticalSection
(
&
com_event_handlers_cs
);
if
(
!
com_event_handlers
.
handler_count
)
...
...
@@ -993,7 +989,7 @@ static HRESULT uia_event_handlers_add_handler(IUnknown *handler_iface, SAFEARRAY
}
event_map
->
event_id
=
event_id
;
event_map
->
handler_iface
=
event
->
handler_iface
;
event_map
->
handler_iface
=
handler_iface
;
IUnknown_AddRef
(
event_map
->
handler_iface
);
list_init
(
&
event_map
->
handlers_list
);
...
...
@@ -1006,25 +1002,28 @@ static HRESULT uia_event_handlers_add_handler(IUnknown *handler_iface, SAFEARRAY
exit:
LeaveCriticalSection
(
&
com_event_handlers_cs
);
if
(
FAILED
(
hr
))
{
IUnknown_Release
(
event
->
handler_iface
);
heap_free
(
event
);
}
return
hr
;
}
static
void
uia_event_handler_destroy
(
struct
uia_com_event
*
event
)
{
list_remove
(
&
event
->
event_handler_map_list_entry
);
if
(
event
->
event
)
UiaRemoveEvent
(
event
->
event
);
if
(
event
->
git_cookie
)
unregister_interface_in_git
(
event
->
git_cookie
);
heap_free
(
event
);
}
static
void
uia_event_handler_map_entry_destroy
(
struct
uia_event_handler_map_entry
*
entry
)
{
struct
uia_com_event
*
event
,
*
event2
;
LIST_FOR_EACH_ENTRY_SAFE
(
event
,
event2
,
&
entry
->
handlers_list
,
struct
uia_com_event
,
event_handler_map_list_entry
)
{
list_remove
(
&
event
->
event_handler_map_list_entry
);
IUnknown_Release
(
event
->
handler_iface
);
uia_event_handler_destroy
(
event
);
com_event_handlers
.
handler_count
--
;
heap_free
(
event
);
}
rb_remove
(
&
com_event_handlers
.
handler_map
,
&
entry
->
entry
);
...
...
@@ -1046,6 +1045,39 @@ static void uia_event_handlers_remove_handlers(IUnknown *handler_iface, SAFEARRA
LeaveCriticalSection
(
&
com_event_handlers_cs
);
}
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
uia_com_event_callback
(
struct
uia_event
*
event
,
struct
uia_event_args
*
args
,
SAFEARRAY
*
cache_req
,
BSTR
tree_struct
)
{
struct
uia_com_event
*
com_event
=
(
struct
uia_com_event
*
)
event
->
u
.
clientside
.
callback_data
;
IUIAutomationEventHandler
*
handler
;
IUIAutomationElement
*
elem
;
BSTR
tree_struct2
;
HRESULT
hr
;
/* Nothing matches the cache request view condition, do nothing. */
if
(
!
cache_req
)
return
S_OK
;
/* create_uia_element_from_cache_req frees the passed in BSTR. */
tree_struct2
=
SysAllocString
(
tree_struct
);
hr
=
create_uia_element_from_cache_req
(
&
elem
,
com_event
->
from_cui8
,
&
event
->
u
.
clientside
.
cache_req
,
0
,
cache_req
,
tree_struct2
);
if
(
FAILED
(
hr
))
return
hr
;
hr
=
get_interface_in_git
(
&
IID_IUIAutomationEventHandler
,
com_event
->
git_cookie
,
(
IUnknown
**
)
&
handler
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IUIAutomationEventHandler_HandleAutomationEvent
(
handler
,
elem
,
event
->
event_id
);
IUIAutomationEventHandler_Release
(
handler
);
}
IUIAutomationElement_Release
(
elem
);
return
hr
;
}
/*
* IUIAutomationElementArray interface.
*/
...
...
@@ -1332,8 +1364,6 @@ static HRESULT set_find_params_struct(struct UiaFindParams *params, IUIAutomatio
return
S_OK
;
}
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
)
{
...
...
@@ -3213,9 +3243,11 @@ static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface,
IUIAutomationElement
*
elem
,
enum
TreeScope
scope
,
IUIAutomationCacheRequest
*
cache_req
,
IUIAutomationEventHandler
*
handler
)
{
struct
UiaCacheRequest
*
cache_req_struct
;
struct
uia_com_event
*
com_event
=
NULL
;
SAFEARRAY
*
runtime_id
=
NULL
;
struct
uia_element
*
element
;
IUnknown
*
handler_iface
;
SAFEARRAY
*
runtime_id
;
HRESULT
hr
;
TRACE
(
"%p, %d, %p, %#x, %p, %p
\n
"
,
iface
,
event_id
,
elem
,
scope
,
cache_req
,
handler
);
...
...
@@ -3233,11 +3265,48 @@ static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface,
element
=
impl_from_IUIAutomationElement9
((
IUIAutomationElement9
*
)
elem
);
hr
=
UiaGetRuntimeId
(
element
->
node
,
&
runtime_id
);
if
(
FAILED
(
hr
))
{
IUnknown_Release
(
handler_iface
);
return
hr
;
}
if
(
!
cache_req
)
{
hr
=
create_uia_cache_request_iface
(
&
cache_req
);
if
(
FAILED
(
hr
))
goto
exit
;
}
else
IUIAutomationCacheRequest_AddRef
(
cache_req
);
hr
=
get_uia_cache_request_struct_from_iface
(
cache_req
,
&
cache_req_struct
);
if
(
FAILED
(
hr
))
goto
exit
;
if
(
!
(
com_event
=
heap_alloc_zero
(
sizeof
(
*
com_event
))))
{
hr
=
E_OUTOFMEMORY
;
goto
exit
;
}
com_event
->
from_cui8
=
element
->
from_cui8
;
list_init
(
&
com_event
->
event_handler_map_list_entry
);
hr
=
register_interface_in_git
((
IUnknown
*
)
handler
,
&
IID_IUIAutomationEventHandler
,
&
com_event
->
git_cookie
);
if
(
FAILED
(
hr
))
goto
exit
;
hr
=
uia_event_handlers_add_handler
(
handler_iface
,
runtime_id
,
event_id
);
hr
=
uia_add_clientside_event
(
element
->
node
,
event_id
,
scope
,
NULL
,
0
,
cache_req_struct
,
runtime_id
,
uia_com_event_callback
,
(
void
*
)
com_event
,
&
com_event
->
event
);
if
(
FAILED
(
hr
))
goto
exit
;
hr
=
uia_event_handlers_add_handler
(
handler_iface
,
runtime_id
,
event_id
,
com_event
);
exit:
if
(
FAILED
(
hr
)
&&
com_event
)
uia_event_handler_destroy
(
com_event
);
if
(
cache_req
)
IUIAutomationCacheRequest_Release
(
cache_req
);
IUnknown_Release
(
handler_iface
);
SafeArrayDestroy
(
runtime_id
);
...
...
dlls/uiautomationcore/uia_event.c
View file @
53376c55
...
...
@@ -1140,7 +1140,7 @@ static HRESULT uia_clientside_event_callback(struct uia_event *event, struct uia
return
S_OK
;
}
static
HRESULT
uia_add_clientside_event
(
HUIANODE
huianode
,
EVENTID
event_id
,
enum
TreeScope
scope
,
PROPERTYID
*
prop_ids
,
HRESULT
uia_add_clientside_event
(
HUIANODE
huianode
,
EVENTID
event_id
,
enum
TreeScope
scope
,
PROPERTYID
*
prop_ids
,
int
prop_ids_count
,
struct
UiaCacheRequest
*
cache_req
,
SAFEARRAY
*
rt_id
,
UiaWineEventCallback
*
cback
,
void
*
cback_data
,
HUIAEVENT
*
huiaevent
)
{
...
...
dlls/uiautomationcore/uia_private.h
View file @
53376c55
...
...
@@ -218,6 +218,9 @@ HRESULT create_serverside_uia_event(struct uia_event **out_event, LONG process_i
HRESULT
uia_event_add_provider_event_adviser
(
IRawElementProviderAdviseEvents
*
advise_events
,
struct
uia_event
*
event
)
DECLSPEC_HIDDEN
;
HRESULT
uia_event_add_serverside_event_adviser
(
IWineUiaEvent
*
serverside_event
,
struct
uia_event
*
event
)
DECLSPEC_HIDDEN
;
HRESULT
uia_add_clientside_event
(
HUIANODE
huianode
,
EVENTID
event_id
,
enum
TreeScope
scope
,
PROPERTYID
*
prop_ids
,
int
prop_ids_count
,
struct
UiaCacheRequest
*
cache_req
,
SAFEARRAY
*
rt_id
,
UiaWineEventCallback
*
cback
,
void
*
cback_data
,
HUIAEVENT
*
huiaevent
)
DECLSPEC_HIDDEN
;
/* uia_ids.c */
const
struct
uia_prop_info
*
uia_prop_info_from_id
(
PROPERTYID
prop_id
)
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