1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

uiautomationcore: Implement IUIAutomation::RemoveAutomationEventHandler.

Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
Connor McAdams 2023-07-17 08:54:47 -04:00 committed by Alexandre Julliard
parent 15d352c587
commit fd6b0422cc
2 changed files with 66 additions and 23 deletions

View file

@ -13105,11 +13105,11 @@ static void test_IUIAutomationEventHandler(IUIAutomation *uia_iface, IUIAutomati
}
hr = IUIAutomation_RemoveAutomationEventHandler(uia_iface, 1, elem, NULL);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IUIAutomation_RemoveAutomationEventHandler(uia_iface, UIA_AutomationFocusChangedEventId, elem,
&AutomationEventHandler.IUIAutomationEventHandler_iface);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
/*
* UIA_AutomationFocusChangedEventId can only be listened for with
@ -13131,8 +13131,8 @@ static void test_IUIAutomationEventHandler(IUIAutomation *uia_iface, IUIAutomati
hr = IUIAutomation_RemoveAutomationEventHandler(uia_iface, 1, elem,
&AutomationEventHandler.IUIAutomationEventHandler_iface);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(AutomationEventHandler.ref == 1, "Unexpected refcnt %ld\n", AutomationEventHandler.ref);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(AutomationEventHandler.ref == 1, "Unexpected refcnt %ld\n", AutomationEventHandler.ref);
/*
* Test event raising behavior.
@ -13183,8 +13183,8 @@ static void test_IUIAutomationEventHandler(IUIAutomation *uia_iface, IUIAutomati
hr = IUIAutomation_RemoveAutomationEventHandler(uia_iface, UIA_LiveRegionChangedEventId, elem,
&AutomationEventHandler.IUIAutomationEventHandler_iface);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(AutomationEventHandler.ref == 1, "Unexpected refcnt %ld\n", AutomationEventHandler.ref);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(AutomationEventHandler.ref == 1, "Unexpected refcnt %ld\n", AutomationEventHandler.ref);
VariantInit(&v);
initialize_provider(&Provider_child, ProviderOptions_ServerSideProvider, NULL, TRUE);
@ -13213,7 +13213,7 @@ static void test_IUIAutomationEventHandler(IUIAutomation *uia_iface, IUIAutomati
/* No removal will occur due to a lack of a runtime ID to match. */
hr = IUIAutomation_RemoveAutomationEventHandler(uia_iface, UIA_LiveRegionChangedEventId, elem2,
&AutomationEventHandler.IUIAutomationEventHandler_iface);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(AutomationEventHandler.ref > 1, "Unexpected refcnt %ld\n", AutomationEventHandler.ref);
hr = IUIAutomation_RemoveAllEventHandlers(uia_iface);

View file

@ -1015,6 +1015,37 @@ exit:
return hr;
}
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);
com_event_handlers.handler_count--;
heap_free(event);
}
rb_remove(&com_event_handlers.handler_map, &entry->entry);
IUnknown_Release(entry->handler_iface);
SafeArrayDestroy(entry->runtime_id);
heap_free(entry);
}
static void uia_event_handlers_remove_handlers(IUnknown *handler_iface, SAFEARRAY *runtime_id, int event_id)
{
struct uia_event_handler_identifier event_ident = { handler_iface, runtime_id, event_id };
struct rb_entry *rb_entry;
EnterCriticalSection(&com_event_handlers_cs);
if (com_event_handlers.handler_count && (rb_entry = rb_get(&com_event_handlers.handler_map, &event_ident)))
uia_event_handler_map_entry_destroy(RB_ENTRY_VALUE(rb_entry, struct uia_event_handler_map_entry, entry));
LeaveCriticalSection(&com_event_handlers_cs);
}
/*
* IUIAutomationElementArray interface.
*/
@ -3203,8 +3234,33 @@ exit:
static HRESULT WINAPI uia_iface_RemoveAutomationEventHandler(IUIAutomation6 *iface, EVENTID event_id,
IUIAutomationElement *elem, IUIAutomationEventHandler *handler)
{
FIXME("%p, %d, %p, %p: stub\n", iface, event_id, elem, handler);
return E_NOTIMPL;
struct uia_element *element;
IUnknown *handler_iface;
SAFEARRAY *runtime_id;
HRESULT hr;
TRACE("%p, %d, %p, %p\n", iface, event_id, elem, handler);
if (!elem || !handler)
return S_OK;
element = impl_from_IUIAutomationElement9((IUIAutomationElement9 *)elem);
hr = UiaGetRuntimeId(element->node, &runtime_id);
if (FAILED(hr) || !runtime_id)
return hr;
hr = IUIAutomationEventHandler_QueryInterface(handler, &IID_IUnknown, (void **)&handler_iface);
if (FAILED(hr))
{
SafeArrayDestroy(runtime_id);
return hr;
}
uia_event_handlers_remove_handlers(handler_iface, runtime_id, event_id);
IUnknown_Release(handler_iface);
SafeArrayDestroy(runtime_id);
return S_OK;
}
static HRESULT WINAPI uia_iface_AddPropertyChangedEventHandlerNativeArray(IUIAutomation6 *iface,
@ -3271,20 +3327,7 @@ static HRESULT WINAPI uia_iface_RemoveAllEventHandlers(IUIAutomation6 *iface)
RB_FOR_EACH_ENTRY_DESTRUCTOR(entry, cursor, &com_event_handlers.handler_map, 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);
com_event_handlers.handler_count--;
heap_free(event);
}
rb_remove(&com_event_handlers.handler_map, &entry->entry);
IUnknown_Release(entry->handler_iface);
SafeArrayDestroy(entry->runtime_id);
heap_free(entry);
uia_event_handler_map_entry_destroy(entry);
}
exit: