uiautomationcore: Use EVENT_OBJECT_FOCUS to advise HWND providers of focus change events in the COM API.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
parent
6b972a68b8
commit
a275834bdd
2 changed files with 54 additions and 3 deletions
|
@ -15436,12 +15436,12 @@ static void test_uia_com_event_handler_event_advisement(IUIAutomation *uia_iface
|
|||
set_uia_hwnd_expects(0, 1, 1, 2, 0); /* Only Win11 sends WM_GETOBJECT 2 times. */
|
||||
|
||||
NotifyWinEvent(EVENT_OBJECT_FOCUS, test_child_hwnd, OBJID_CLIENT, CHILDID_SELF);
|
||||
todo_wine ok(msg_wait_for_all_events(method_event, 1, 2000) != WAIT_TIMEOUT, "Wait for method_event(s) timed out.\n");
|
||||
ok(msg_wait_for_all_events(method_event, 1, 2000) != WAIT_TIMEOUT, "Wait for method_event(s) timed out.\n");
|
||||
if (wait_for_clientside_callbacks(2000)) trace("Kept getting callbacks up until timeout\n");
|
||||
|
||||
check_uia_hwnd_expects_at_most(0, 1, 1, 2, 0);
|
||||
CHECK_CALLED_AT_MOST(child_winproc_GETOBJECT_UiaRoot, 3);
|
||||
test_provider_event_advise_added(&Provider2, UIA_AutomationFocusChangedEventId, TRUE);
|
||||
test_provider_event_advise_added(&Provider2, UIA_AutomationFocusChangedEventId, FALSE);
|
||||
test_provider_event_advise_added(&Provider_hwnd3, 0, FALSE);
|
||||
test_provider_event_advise_added(&Provider_nc3, 0, FALSE);
|
||||
|
||||
|
|
|
@ -974,10 +974,43 @@ struct uia_com_event {
|
|||
HUIAEVENT event;
|
||||
BOOL from_cui8;
|
||||
|
||||
struct rb_tree focus_hwnd_map;
|
||||
struct list event_handler_map_list_entry;
|
||||
struct uia_event_handler_map_entry *handler_map;
|
||||
};
|
||||
|
||||
static void uia_com_focus_handler_advise_node(struct uia_com_event *event, HUIANODE node, HWND hwnd)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = uia_event_advise_node((struct uia_event *)event->event, node);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WARN("uia_event_advise_node failed with hr %#lx\n", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = uia_hwnd_map_add_hwnd(&event->focus_hwnd_map, hwnd);
|
||||
if (FAILED(hr))
|
||||
WARN("Failed to add hwnd for focus winevent, hr %#lx\n", hr);
|
||||
}
|
||||
|
||||
static void uia_com_focus_win_event_handler(HUIANODE node, HWND hwnd, struct uia_event_handler_event_id_map_entry *event_id_map)
|
||||
{
|
||||
struct uia_event_handler_map_entry *entry;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(entry, &event_id_map->handlers_list, struct uia_event_handler_map_entry, handler_event_id_map_list_entry)
|
||||
{
|
||||
struct uia_com_event *event;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(event, &entry->handlers_list, struct uia_com_event, event_handler_map_list_entry)
|
||||
{
|
||||
if (!uia_hwnd_map_check_hwnd(&event->focus_hwnd_map, hwnd))
|
||||
uia_com_focus_handler_advise_node(event, node, hwnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG child_id, DWORD thread_id, DWORD event_time)
|
||||
{
|
||||
LONG handler_count;
|
||||
|
@ -1060,11 +1093,13 @@ HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG
|
|||
|
||||
if ((rb_entry = rb_get(&com_event_handlers.handler_event_id_map, &uia_event_id)))
|
||||
{
|
||||
struct uia_event_handler_event_id_map_entry *event_id_map;
|
||||
HUIANODE node = NULL;
|
||||
|
||||
event_id_map = RB_ENTRY_VALUE(rb_entry, struct uia_event_handler_event_id_map_entry, entry);
|
||||
hr = create_uia_node_from_hwnd(hwnd, &node, NODE_FLAG_IGNORE_CLIENTSIDE_HWND_PROVS);
|
||||
if (SUCCEEDED(hr))
|
||||
FIXME("EVENT_OBJECT_FOCUS event advisement currently unimplemented\n");
|
||||
uia_com_focus_win_event_handler(node, hwnd, event_id_map);
|
||||
|
||||
UiaNodeRelease(node);
|
||||
}
|
||||
|
@ -1155,6 +1190,20 @@ static HRESULT uia_event_handlers_add_handler(IUnknown *handler_iface, SAFEARRAY
|
|||
list_add_tail(&event_map->handlers_list, &event->event_handler_map_list_entry);
|
||||
event->handler_map = event_map;
|
||||
com_event_handlers.handler_count++;
|
||||
if (event_id == UIA_AutomationFocusChangedEventId)
|
||||
{
|
||||
GUITHREADINFO info = { sizeof(info) };
|
||||
|
||||
if (GetGUIThreadInfo(0, &info) && info.hwndFocus)
|
||||
{
|
||||
HUIANODE node = NULL;
|
||||
|
||||
hr = create_uia_node_from_hwnd(info.hwndFocus, &node, NODE_FLAG_IGNORE_CLIENTSIDE_HWND_PROVS);
|
||||
if (SUCCEEDED(hr))
|
||||
uia_com_focus_handler_advise_node(event, node, info.hwndFocus);
|
||||
UiaNodeRelease(node);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
LeaveCriticalSection(&com_event_handlers_cs);
|
||||
|
@ -1165,6 +1214,7 @@ exit:
|
|||
static void uia_event_handler_destroy(struct uia_com_event *event)
|
||||
{
|
||||
list_remove(&event->event_handler_map_list_entry);
|
||||
uia_hwnd_map_destroy(&event->focus_hwnd_map);
|
||||
if (event->event)
|
||||
UiaRemoveEvent(event->event);
|
||||
if (event->git_cookie)
|
||||
|
@ -3459,6 +3509,7 @@ static HRESULT uia_add_com_event_handler(IUIAutomation6 *iface, EVENTID event_id
|
|||
|
||||
com_event->from_cui8 = element->from_cui8;
|
||||
list_init(&com_event->event_handler_map_list_entry);
|
||||
uia_hwnd_map_init(&com_event->focus_hwnd_map);
|
||||
|
||||
hr = IUnknown_QueryInterface(handler_unk, handler_riid, (void **)&handler_iface);
|
||||
if (FAILED(hr))
|
||||
|
|
Loading…
Add table
Reference in a new issue