Commit a8697c43 authored by Connor McAdams's avatar Connor McAdams Committed by Alexandre Julliard

uiautomationcore: Implement IUIAutomation::{Add/Remove}FocusChangedEventHandler.

parent 63330c61
...@@ -13392,8 +13392,8 @@ static void test_IUIAutomationFocusChangedEventHandler(IUIAutomation *uia_iface) ...@@ -13392,8 +13392,8 @@ static void test_IUIAutomationFocusChangedEventHandler(IUIAutomation *uia_iface)
set_uia_hwnd_expects(6, 6, 6, 3, 0); set_uia_hwnd_expects(6, 6, 6, 3, 0);
hr = IUIAutomation_AddFocusChangedEventHandler(uia_iface, NULL, hr = IUIAutomation_AddFocusChangedEventHandler(uia_iface, NULL,
&FocusChangedHandler.IUIAutomationFocusChangedEventHandler_iface); &FocusChangedHandler.IUIAutomationFocusChangedEventHandler_iface);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(FocusChangedHandler.ref > 1, "Unexpected refcnt %ld\n", FocusChangedHandler.ref); ok(FocusChangedHandler.ref > 1, "Unexpected refcnt %ld\n", FocusChangedHandler.ref);
check_uia_hwnd_expects_at_most(6, 6, 6, 3, 0); check_uia_hwnd_expects_at_most(6, 6, 6, 3, 0);
FocusChangedHandler.event_handler_added = TRUE; FocusChangedHandler.event_handler_added = TRUE;
...@@ -13407,7 +13407,7 @@ static void test_IUIAutomationFocusChangedEventHandler(IUIAutomation *uia_iface) ...@@ -13407,7 +13407,7 @@ static void test_IUIAutomationFocusChangedEventHandler(IUIAutomation *uia_iface)
set_com_event_data(&exp_node_desc); set_com_event_data(&exp_node_desc);
hr = UiaRaiseAutomationEvent(&Provider2.IRawElementProviderSimple_iface, UIA_AutomationFocusChangedEventId); hr = UiaRaiseAutomationEvent(&Provider2.IRawElementProviderSimple_iface, UIA_AutomationFocusChangedEventId);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine CHECK_CALLED(uia_com_event_callback); CHECK_CALLED(uia_com_event_callback);
/* /*
* Removing the focus changed event handler creates a desktop node - * Removing the focus changed event handler creates a desktop node -
...@@ -13416,10 +13416,10 @@ static void test_IUIAutomationFocusChangedEventHandler(IUIAutomation *uia_iface) ...@@ -13416,10 +13416,10 @@ static void test_IUIAutomationFocusChangedEventHandler(IUIAutomation *uia_iface)
set_uia_hwnd_expects(1, 1, 1, 0, 0); set_uia_hwnd_expects(1, 1, 1, 0, 0);
hr = IUIAutomation_RemoveFocusChangedEventHandler(uia_iface, hr = IUIAutomation_RemoveFocusChangedEventHandler(uia_iface,
&FocusChangedHandler.IUIAutomationFocusChangedEventHandler_iface); &FocusChangedHandler.IUIAutomationFocusChangedEventHandler_iface);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(FocusChangedHandler.ref == 1, "Unexpected refcnt %ld\n", FocusChangedHandler.ref); ok(FocusChangedHandler.ref == 1, "Unexpected refcnt %ld\n", FocusChangedHandler.ref);
FocusChangedHandler.event_handler_added = FALSE; FocusChangedHandler.event_handler_added = FALSE;
check_uia_hwnd_expects(1, TRUE, 1, TRUE, 1, TRUE, 0, FALSE, 0, FALSE); check_uia_hwnd_expects(1, FALSE, 1, FALSE, 1, FALSE, 0, FALSE, 0, FALSE);
/* /*
* The focus changed event handler can also be removed by called * The focus changed event handler can also be removed by called
...@@ -13428,8 +13428,8 @@ static void test_IUIAutomationFocusChangedEventHandler(IUIAutomation *uia_iface) ...@@ -13428,8 +13428,8 @@ static void test_IUIAutomationFocusChangedEventHandler(IUIAutomation *uia_iface)
set_uia_hwnd_expects(6, 6, 6, 3, 0); set_uia_hwnd_expects(6, 6, 6, 3, 0);
hr = IUIAutomation_AddFocusChangedEventHandler(uia_iface, NULL, hr = IUIAutomation_AddFocusChangedEventHandler(uia_iface, NULL,
&FocusChangedHandler.IUIAutomationFocusChangedEventHandler_iface); &FocusChangedHandler.IUIAutomationFocusChangedEventHandler_iface);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(FocusChangedHandler.ref > 1, "Unexpected refcnt %ld\n", FocusChangedHandler.ref); ok(FocusChangedHandler.ref > 1, "Unexpected refcnt %ld\n", FocusChangedHandler.ref);
check_uia_hwnd_expects_at_most(6, 6, 6, 3, 0); check_uia_hwnd_expects_at_most(6, 6, 6, 3, 0);
FocusChangedHandler.event_handler_added = TRUE; FocusChangedHandler.event_handler_added = TRUE;
......
...@@ -1051,7 +1051,6 @@ static HRESULT uia_com_event_callback(struct uia_event *event, struct uia_event_ ...@@ -1051,7 +1051,6 @@ static HRESULT uia_com_event_callback(struct uia_event *event, struct uia_event_
SAFEARRAY *cache_req, BSTR tree_struct) SAFEARRAY *cache_req, BSTR tree_struct)
{ {
struct uia_com_event *com_event = (struct uia_com_event *)event->u.clientside.callback_data; struct uia_com_event *com_event = (struct uia_com_event *)event->u.clientside.callback_data;
IUIAutomationEventHandler *handler;
IUIAutomationElement *elem; IUIAutomationElement *elem;
BSTR tree_struct2; BSTR tree_struct2;
HRESULT hr; HRESULT hr;
...@@ -1067,11 +1066,33 @@ static HRESULT uia_com_event_callback(struct uia_event *event, struct uia_event_ ...@@ -1067,11 +1066,33 @@ static HRESULT uia_com_event_callback(struct uia_event *event, struct uia_event_
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = get_interface_in_git(&IID_IUIAutomationEventHandler, com_event->git_cookie, (IUnknown **)&handler); switch (event->event_id)
if (SUCCEEDED(hr)) {
case UIA_AutomationFocusChangedEventId:
{
IUIAutomationFocusChangedEventHandler *handler;
hr = get_interface_in_git(&IID_IUIAutomationFocusChangedEventHandler, com_event->git_cookie, (IUnknown **)&handler);
if (SUCCEEDED(hr))
{
hr = IUIAutomationFocusChangedEventHandler_HandleFocusChangedEvent(handler, elem);
IUIAutomationFocusChangedEventHandler_Release(handler);
}
break;
}
default:
{ {
hr = IUIAutomationEventHandler_HandleAutomationEvent(handler, elem, event->event_id); IUIAutomationEventHandler *handler;
IUIAutomationEventHandler_Release(handler);
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);
}
break;
}
} }
IUIAutomationElement_Release(elem); IUIAutomationElement_Release(elem);
...@@ -3239,9 +3260,8 @@ static HRESULT WINAPI uia_iface_CreateNotCondition(IUIAutomation6 *iface, IUIAut ...@@ -3239,9 +3260,8 @@ static HRESULT WINAPI uia_iface_CreateNotCondition(IUIAutomation6 *iface, IUIAut
return create_uia_not_condition_iface(out_condition, cond); return create_uia_not_condition_iface(out_condition, cond);
} }
static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface, EVENTID event_id, static HRESULT uia_add_com_event_handler(IUIAutomation6 *iface, EVENTID event_id, IUIAutomationElement *elem,
IUIAutomationElement *elem, enum TreeScope scope, IUIAutomationCacheRequest *cache_req, enum TreeScope scope, IUIAutomationCacheRequest *cache_req, REFIID handler_riid, IUnknown *handler_unk)
IUIAutomationEventHandler *handler)
{ {
struct UiaCacheRequest *cache_req_struct; struct UiaCacheRequest *cache_req_struct;
struct uia_com_event *com_event = NULL; struct uia_com_event *com_event = NULL;
...@@ -3250,25 +3270,10 @@ static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface, ...@@ -3250,25 +3270,10 @@ static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface,
IUnknown *handler_iface; IUnknown *handler_iface;
HRESULT hr; HRESULT hr;
TRACE("%p, %d, %p, %#x, %p, %p\n", iface, event_id, elem, scope, cache_req, handler);
if (!elem || !handler)
return E_POINTER;
if (event_id == UIA_AutomationFocusChangedEventId)
return E_INVALIDARG;
hr = IUIAutomationEventHandler_QueryInterface(handler, &IID_IUnknown, (void **)&handler_iface);
if (FAILED(hr))
return hr;
element = impl_from_IUIAutomationElement9((IUIAutomationElement9 *)elem); element = impl_from_IUIAutomationElement9((IUIAutomationElement9 *)elem);
hr = UiaGetRuntimeId(element->node, &runtime_id); hr = UiaGetRuntimeId(element->node, &runtime_id);
if (FAILED(hr)) if (FAILED(hr))
{
IUnknown_Release(handler_iface);
return hr; return hr;
}
if (!cache_req) if (!cache_req)
{ {
...@@ -3291,7 +3296,13 @@ static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface, ...@@ -3291,7 +3296,13 @@ static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface,
com_event->from_cui8 = element->from_cui8; com_event->from_cui8 = element->from_cui8;
list_init(&com_event->event_handler_map_list_entry); list_init(&com_event->event_handler_map_list_entry);
hr = register_interface_in_git((IUnknown *)handler, &IID_IUIAutomationEventHandler, &com_event->git_cookie);
hr = IUnknown_QueryInterface(handler_unk, handler_riid, (void **)&handler_iface);
if (FAILED(hr))
goto exit;
hr = register_interface_in_git(handler_iface, handler_riid, &com_event->git_cookie);
IUnknown_Release(handler_iface);
if (FAILED(hr)) if (FAILED(hr))
goto exit; goto exit;
...@@ -3300,49 +3311,79 @@ static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface, ...@@ -3300,49 +3311,79 @@ static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface,
if (FAILED(hr)) if (FAILED(hr))
goto exit; goto exit;
hr = uia_event_handlers_add_handler(handler_iface, runtime_id, event_id, com_event); hr = uia_event_handlers_add_handler(handler_unk, runtime_id, event_id, com_event);
exit: exit:
if (FAILED(hr) && com_event) if (FAILED(hr) && com_event)
uia_event_handler_destroy(com_event); uia_event_handler_destroy(com_event);
if (cache_req) if (cache_req)
IUIAutomationCacheRequest_Release(cache_req); IUIAutomationCacheRequest_Release(cache_req);
IUnknown_Release(handler_iface);
SafeArrayDestroy(runtime_id); SafeArrayDestroy(runtime_id);
return hr; return hr;
} }
static HRESULT WINAPI uia_iface_RemoveAutomationEventHandler(IUIAutomation6 *iface, EVENTID event_id, static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface, EVENTID event_id,
IUIAutomationElement *elem, IUIAutomationEventHandler *handler) IUIAutomationElement *elem, enum TreeScope scope, IUIAutomationCacheRequest *cache_req,
IUIAutomationEventHandler *handler)
{ {
struct uia_element *element; IUnknown *handler_unk;
IUnknown *handler_iface;
SAFEARRAY *runtime_id;
HRESULT hr; HRESULT hr;
TRACE("%p, %d, %p, %p\n", iface, event_id, elem, handler); TRACE("%p, %d, %p, %#x, %p, %p\n", iface, event_id, elem, scope, cache_req, handler);
if (!elem || !handler) if (!elem || !handler)
return S_OK; return E_POINTER;
if (event_id == UIA_AutomationFocusChangedEventId)
return E_INVALIDARG;
hr = IUIAutomationEventHandler_QueryInterface(handler, &IID_IUnknown, (void **)&handler_unk);
if (FAILED(hr))
return hr;
hr = uia_add_com_event_handler(iface, event_id, elem, scope, cache_req, &IID_IUIAutomationEventHandler, handler_unk);
IUnknown_Release(handler_unk);
return hr;
}
static HRESULT uia_remove_com_event_handler(EVENTID event_id, IUIAutomationElement *elem, IUnknown *handler_unk)
{
struct uia_element *element;
SAFEARRAY *runtime_id;
HRESULT hr;
element = impl_from_IUIAutomationElement9((IUIAutomationElement9 *)elem); element = impl_from_IUIAutomationElement9((IUIAutomationElement9 *)elem);
hr = UiaGetRuntimeId(element->node, &runtime_id); hr = UiaGetRuntimeId(element->node, &runtime_id);
if (FAILED(hr) || !runtime_id) if (FAILED(hr) || !runtime_id)
return hr; return hr;
hr = IUIAutomationEventHandler_QueryInterface(handler, &IID_IUnknown, (void **)&handler_iface); uia_event_handlers_remove_handlers(handler_unk, runtime_id, event_id);
SafeArrayDestroy(runtime_id);
return S_OK;
}
static HRESULT WINAPI uia_iface_RemoveAutomationEventHandler(IUIAutomation6 *iface, EVENTID event_id,
IUIAutomationElement *elem, IUIAutomationEventHandler *handler)
{
IUnknown *handler_unk;
HRESULT hr;
TRACE("%p, %d, %p, %p\n", iface, event_id, elem, handler);
if (!elem || !handler)
return S_OK;
hr = IUIAutomationEventHandler_QueryInterface(handler, &IID_IUnknown, (void **)&handler_unk);
if (FAILED(hr)) if (FAILED(hr))
{
SafeArrayDestroy(runtime_id);
return hr; return hr;
}
uia_event_handlers_remove_handlers(handler_iface, runtime_id, event_id); hr = uia_remove_com_event_handler(event_id, elem, handler_unk);
IUnknown_Release(handler_iface); IUnknown_Release(handler_unk);
SafeArrayDestroy(runtime_id);
return S_OK; return hr;
} }
static HRESULT WINAPI uia_iface_AddPropertyChangedEventHandlerNativeArray(IUIAutomation6 *iface, static HRESULT WINAPI uia_iface_AddPropertyChangedEventHandlerNativeArray(IUIAutomation6 *iface,
...@@ -3386,15 +3427,59 @@ static HRESULT WINAPI uia_iface_RemoveStructureChangedEventHandler(IUIAutomation ...@@ -3386,15 +3427,59 @@ static HRESULT WINAPI uia_iface_RemoveStructureChangedEventHandler(IUIAutomation
static HRESULT WINAPI uia_iface_AddFocusChangedEventHandler(IUIAutomation6 *iface, static HRESULT WINAPI uia_iface_AddFocusChangedEventHandler(IUIAutomation6 *iface,
IUIAutomationCacheRequest *cache_req, IUIAutomationFocusChangedEventHandler *handler) IUIAutomationCacheRequest *cache_req, IUIAutomationFocusChangedEventHandler *handler)
{ {
FIXME("%p, %p, %p: stub\n", iface, cache_req, handler); IUIAutomationElement *elem;
return E_NOTIMPL; IUnknown *handler_unk;
HRESULT hr;
TRACE("%p, %p, %p\n", iface, cache_req, handler);
if (!handler)
return E_POINTER;
hr = IUIAutomationFocusChangedEventHandler_QueryInterface(handler, &IID_IUnknown, (void **)&handler_unk);
if (FAILED(hr))
return hr;
hr = IUIAutomation6_GetRootElement(iface, &elem);
if (FAILED(hr))
{
IUnknown_Release(handler_unk);
return hr;
}
hr = uia_add_com_event_handler(iface, UIA_AutomationFocusChangedEventId, elem, TreeScope_SubTree, cache_req,
&IID_IUIAutomationFocusChangedEventHandler, handler_unk);
IUIAutomationElement_Release(elem);
IUnknown_Release(handler_unk);
return hr;
} }
static HRESULT WINAPI uia_iface_RemoveFocusChangedEventHandler(IUIAutomation6 *iface, static HRESULT WINAPI uia_iface_RemoveFocusChangedEventHandler(IUIAutomation6 *iface,
IUIAutomationFocusChangedEventHandler *handler) IUIAutomationFocusChangedEventHandler *handler)
{ {
FIXME("%p, %p: stub\n", iface, handler); IUIAutomationElement *elem;
return E_NOTIMPL; IUnknown *handler_unk;
HRESULT hr;
TRACE("%p, %p\n", iface, handler);
hr = IUIAutomationFocusChangedEventHandler_QueryInterface(handler, &IID_IUnknown, (void **)&handler_unk);
if (FAILED(hr))
return hr;
hr = IUIAutomation6_GetRootElement(iface, &elem);
if (FAILED(hr))
{
IUnknown_Release(handler_unk);
return hr;
}
hr = uia_remove_com_event_handler(UIA_AutomationFocusChangedEventId, elem, handler_unk);
IUIAutomationElement_Release(elem);
IUnknown_Release(handler_unk);
return hr;
} }
static HRESULT WINAPI uia_iface_RemoveAllEventHandlers(IUIAutomation6 *iface) static HRESULT WINAPI uia_iface_RemoveAllEventHandlers(IUIAutomation6 *iface)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment