uiautomationcore: Query EVENT_OBJECT_FOCUS HWND for a serverside provider if there is a registered focus change event handler.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
parent
7886e4d08b
commit
6b972a68b8
3 changed files with 89 additions and 1 deletions
|
@ -2631,7 +2631,7 @@ static HRESULT uia_get_provider_from_hwnd(struct uia_node *node)
|
|||
return SendMessageW(client_thread.hwnd, WM_UIA_CLIENT_GET_NODE_PROV, (WPARAM)&args, (LPARAM)node);
|
||||
}
|
||||
|
||||
static HRESULT create_uia_node_from_hwnd(HWND hwnd, HUIANODE *out_node, int node_flags)
|
||||
HRESULT create_uia_node_from_hwnd(HWND hwnd, HUIANODE *out_node, int node_flags)
|
||||
{
|
||||
struct uia_node *node;
|
||||
HRESULT hr;
|
||||
|
|
|
@ -903,6 +903,7 @@ static HRESULT get_uia_cache_request_struct_from_iface(IUIAutomationCacheRequest
|
|||
*/
|
||||
static struct uia_com_event_handlers
|
||||
{
|
||||
struct rb_tree handler_event_id_map;
|
||||
struct rb_tree handler_map;
|
||||
|
||||
LONG handler_count;
|
||||
|
@ -917,6 +918,22 @@ static CRITICAL_SECTION_DEBUG com_event_handlers_cs_debug =
|
|||
};
|
||||
static CRITICAL_SECTION com_event_handlers_cs = { &com_event_handlers_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
struct uia_event_handler_event_id_map_entry
|
||||
{
|
||||
struct rb_entry entry;
|
||||
int event_id;
|
||||
|
||||
struct list handlers_list;
|
||||
};
|
||||
|
||||
static int uia_com_event_handler_event_id_compare(const void *key, const struct rb_entry *entry)
|
||||
{
|
||||
struct uia_event_handler_event_id_map_entry *event_entry = RB_ENTRY_VALUE(entry, struct uia_event_handler_event_id_map_entry, entry);
|
||||
int event_id = *((int *)key);
|
||||
|
||||
return (event_entry->event_id > event_id) - (event_entry->event_id < event_id);
|
||||
}
|
||||
|
||||
struct uia_event_handler_identifier {
|
||||
IUnknown *handler_iface;
|
||||
SAFEARRAY *runtime_id;
|
||||
|
@ -932,6 +949,9 @@ struct uia_event_handler_map_entry
|
|||
int event_id;
|
||||
|
||||
struct list handlers_list;
|
||||
|
||||
struct uia_event_handler_event_id_map_entry *handler_event_id_map;
|
||||
struct list handler_event_id_map_list_entry;
|
||||
};
|
||||
|
||||
static int uia_com_event_handler_id_compare(const void *key, const struct rb_entry *entry)
|
||||
|
@ -1027,6 +1047,32 @@ HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG
|
|||
break;
|
||||
}
|
||||
|
||||
case EVENT_OBJECT_FOCUS:
|
||||
{
|
||||
static const int uia_event_id = UIA_AutomationFocusChangedEventId;
|
||||
struct rb_entry *rb_entry;
|
||||
HRESULT hr;
|
||||
|
||||
if (obj_id != OBJID_CLIENT)
|
||||
break;
|
||||
|
||||
EnterCriticalSection(&com_event_handlers_cs);
|
||||
|
||||
if ((rb_entry = rb_get(&com_event_handlers.handler_event_id_map, &uia_event_id)))
|
||||
{
|
||||
HUIANODE node = NULL;
|
||||
|
||||
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");
|
||||
|
||||
UiaNodeRelease(node);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&com_event_handlers_cs);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1034,6 +1080,29 @@ HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT uia_event_handlers_add_handler_to_event_id_map(struct uia_event_handler_map_entry *event_map)
|
||||
{
|
||||
struct uia_event_handler_event_id_map_entry *event_id_map;
|
||||
struct rb_entry *rb_entry;
|
||||
|
||||
if ((rb_entry = rb_get(&com_event_handlers.handler_event_id_map, &event_map->event_id)))
|
||||
event_id_map = RB_ENTRY_VALUE(rb_entry, struct uia_event_handler_event_id_map_entry, entry);
|
||||
else
|
||||
{
|
||||
if (!(event_id_map = calloc(1, sizeof(*event_id_map))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
event_id_map->event_id = event_map->event_id;
|
||||
list_init(&event_id_map->handlers_list);
|
||||
rb_put(&com_event_handlers.handler_event_id_map, &event_map->event_id, &event_id_map->entry);
|
||||
}
|
||||
|
||||
list_add_tail(&event_id_map->handlers_list, &event_map->handler_event_id_map_list_entry);
|
||||
event_map->handler_event_id_map = event_id_map;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT uia_event_handlers_add_handler(IUnknown *handler_iface, SAFEARRAY *runtime_id, int event_id,
|
||||
struct uia_com_event *event)
|
||||
{
|
||||
|
@ -1045,7 +1114,10 @@ static HRESULT uia_event_handlers_add_handler(IUnknown *handler_iface, SAFEARRAY
|
|||
EnterCriticalSection(&com_event_handlers_cs);
|
||||
|
||||
if (!com_event_handlers.handler_count)
|
||||
{
|
||||
rb_init(&com_event_handlers.handler_map, uia_com_event_handler_id_compare);
|
||||
rb_init(&com_event_handlers.handler_event_id_map, uia_com_event_handler_event_id_compare);
|
||||
}
|
||||
|
||||
if ((rb_entry = rb_get(&com_event_handlers.handler_map, &event_ident)))
|
||||
event_map = RB_ENTRY_VALUE(rb_entry, struct uia_event_handler_map_entry, entry);
|
||||
|
@ -1065,6 +1137,14 @@ static HRESULT uia_event_handlers_add_handler(IUnknown *handler_iface, SAFEARRAY
|
|||
}
|
||||
|
||||
event_map->event_id = event_id;
|
||||
hr = uia_event_handlers_add_handler_to_event_id_map(event_map);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
SafeArrayDestroy(event_map->runtime_id);
|
||||
free(event_map);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
event_map->handler_iface = handler_iface;
|
||||
IUnknown_AddRef(event_map->handler_iface);
|
||||
|
||||
|
@ -1102,6 +1182,13 @@ static void uia_event_handler_map_entry_destroy(struct uia_event_handler_map_ent
|
|||
com_event_handlers.handler_count--;
|
||||
}
|
||||
|
||||
list_remove(&entry->handler_event_id_map_list_entry);
|
||||
if (list_empty(&entry->handler_event_id_map->handlers_list))
|
||||
{
|
||||
rb_remove(&com_event_handlers.handler_event_id_map, &entry->handler_event_id_map->entry);
|
||||
free(entry->handler_event_id_map);
|
||||
}
|
||||
|
||||
rb_remove(&com_event_handlers.handler_map, &entry->entry);
|
||||
IUnknown_Release(entry->handler_iface);
|
||||
SafeArrayDestroy(entry->runtime_id);
|
||||
|
|
|
@ -219,6 +219,7 @@ HRESULT navigate_uia_node(struct uia_node *node, int nav_dir, HUIANODE *out_node
|
|||
HRESULT create_uia_node_from_elprov(IRawElementProviderSimple *elprov, HUIANODE *out_node,
|
||||
BOOL get_hwnd_providers, int node_flags) DECLSPEC_HIDDEN;
|
||||
HRESULT uia_node_from_lresult(LRESULT lr, HUIANODE *huianode) DECLSPEC_HIDDEN;
|
||||
HRESULT create_uia_node_from_hwnd(HWND hwnd, HUIANODE *out_node, int node_flags) DECLSPEC_HIDDEN;
|
||||
HRESULT uia_condition_check(HUIANODE node, struct UiaCondition *condition) DECLSPEC_HIDDEN;
|
||||
BOOL uia_condition_matched(HRESULT hr) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue