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

uiautomationcore: Implement NavigateDirection_Parent for MSAA Providers.

parent ef27965e
...@@ -1078,38 +1078,35 @@ static void test_uia_prov_from_acc_navigation(void) ...@@ -1078,38 +1078,35 @@ static void test_uia_prov_from_acc_navigation(void)
elfrag2 = (void *)0xdeadbeef; elfrag2 = (void *)0xdeadbeef;
hr = IRawElementProviderFragment_Navigate(elfrag, NavigateDirection_Parent, &elfrag2); hr = IRawElementProviderFragment_Navigate(elfrag, NavigateDirection_Parent, &elfrag2);
ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref); ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(!elfrag2, "elfrag2 != NULL\n"); ok(!elfrag2, "elfrag2 != NULL\n");
todo_wine CHECK_CALLED(winproc_GETOBJECT_CLIENT); CHECK_CALLED(winproc_GETOBJECT_CLIENT);
todo_wine CHECK_CALLED(Accessible_get_accRole); CHECK_CALLED(Accessible_get_accRole);
todo_wine CHECK_CALLED(Accessible_get_accState); CHECK_CALLED(Accessible_get_accState);
todo_wine CHECK_CALLED(Accessible_get_accChildCount); CHECK_CALLED(Accessible_get_accChildCount);
todo_wine CHECK_CALLED(Accessible_accLocation); CHECK_CALLED(Accessible_accLocation);
todo_wine CHECK_CALLED(Accessible_get_accName); CHECK_CALLED(Accessible_get_accName);
todo_wine CHECK_CALLED(Accessible2_get_accRole); CHECK_CALLED(Accessible2_get_accRole);
todo_wine CHECK_CALLED(Accessible2_get_accState); CHECK_CALLED(Accessible2_get_accState);
todo_wine CHECK_CALLED(Accessible2_get_accChildCount); CHECK_CALLED(Accessible2_get_accChildCount);
todo_wine CHECK_CALLED(Accessible2_accLocation); CHECK_CALLED(Accessible2_accLocation);
todo_wine CHECK_CALLED(Accessible2_get_accName); CHECK_CALLED(Accessible2_get_accName);
todo_wine CHECK_CALLED(Accessible2_QI_IAccIdentity); todo_wine CHECK_CALLED(Accessible2_QI_IAccIdentity);
todo_wine CHECK_CALLED(Accessible2_get_accParent); todo_wine CHECK_CALLED(Accessible2_get_accParent);
acc_client = NULL; acc_client = NULL;
if (SUCCEEDED(hr)) /* No check against root IAccessible, since it was done previously. */
{ elprov2 = (void *)0xdeadbeef;
/* No check against root IAccessible, since it was done previously. */ hr = IRawElementProviderSimple_get_HostRawElementProvider(elprov, &elprov2);
elprov2 = (void *)0xdeadbeef; ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IRawElementProviderSimple_get_HostRawElementProvider(elprov, &elprov2); ok(!!elprov2, "elprov == NULL, elprov %p\n", elprov2);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IRawElementProviderSimple_Release(elprov2);
ok(!!elprov2, "elprov == NULL, elprov %p\n", elprov2);
IRawElementProviderSimple_Release(elprov2);
}
/* Do nothing. */ /* Do nothing. */
elfrag2 = (void *)0xdeadbeef; elfrag2 = (void *)0xdeadbeef;
hr = IRawElementProviderFragment_Navigate(elfrag, NavigateDirection_Parent, &elfrag2); hr = IRawElementProviderFragment_Navigate(elfrag, NavigateDirection_Parent, &elfrag2);
ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref); ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(!elfrag2, "elfrag2 != NULL\n"); ok(!elfrag2, "elfrag2 != NULL\n");
elfrag2 = (void *)0xdeadbeef; elfrag2 = (void *)0xdeadbeef;
...@@ -1284,36 +1281,30 @@ static void test_uia_prov_from_acc_navigation(void) ...@@ -1284,36 +1281,30 @@ static void test_uia_prov_from_acc_navigation(void)
SET_EXPECT(Accessible2_QI_IAccIdentity); SET_EXPECT(Accessible2_QI_IAccIdentity);
SET_EXPECT(Accessible2_get_accParent); SET_EXPECT(Accessible2_get_accParent);
hr = IRawElementProviderFragment_Navigate(elfrag, NavigateDirection_Parent, &elfrag2); hr = IRawElementProviderFragment_Navigate(elfrag, NavigateDirection_Parent, &elfrag2);
todo_wine ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref); ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(!!elfrag2, "elfrag2 == NULL\n"); ok(!!elfrag2, "elfrag2 == NULL\n");
todo_wine CHECK_CALLED(Accessible_child_get_accParent); CHECK_CALLED(Accessible_child_get_accParent);
todo_wine CHECK_CALLED(Accessible_child_get_accRole); CHECK_CALLED(Accessible_child_get_accRole);
todo_wine CHECK_CALLED(Accessible2_get_accRole); CHECK_CALLED(Accessible2_get_accRole);
todo_wine CHECK_CALLED(Accessible2_QI_IAccIdentity); todo_wine CHECK_CALLED(Accessible2_QI_IAccIdentity);
todo_wine CHECK_CALLED(Accessible2_get_accParent); todo_wine CHECK_CALLED(Accessible2_get_accParent);
todo_wine CHECK_CALLED(winproc_GETOBJECT_CLIENT); CHECK_CALLED(winproc_GETOBJECT_CLIENT);
if (elfrag2) check_fragment_acc(elfrag2, &Accessible.IAccessible_iface, CHILDID_SELF);
{ IRawElementProviderFragment_Release(elfrag2);
check_fragment_acc(elfrag2, &Accessible.IAccessible_iface, CHILDID_SELF); ok(Accessible.ref == 1, "Unexpected refcnt %ld\n", Accessible.ref);
IRawElementProviderFragment_Release(elfrag2);
ok(Accessible.ref == 1, "Unexpected refcnt %ld\n", Accessible.ref);
}
acc_client = NULL; acc_client = NULL;
/* Second call only does get_accParent, no root check. */ /* Second call only does get_accParent, no root check. */
SET_EXPECT(Accessible_child_get_accParent); SET_EXPECT(Accessible_child_get_accParent);
hr = IRawElementProviderFragment_Navigate(elfrag, NavigateDirection_Parent, &elfrag2); hr = IRawElementProviderFragment_Navigate(elfrag, NavigateDirection_Parent, &elfrag2);
todo_wine ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref); ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(!!elfrag2, "elfrag2 == NULL\n"); ok(!!elfrag2, "elfrag2 == NULL\n");
todo_wine CHECK_CALLED(Accessible_child_get_accParent); CHECK_CALLED(Accessible_child_get_accParent);
if (elfrag2) check_fragment_acc(elfrag2, &Accessible.IAccessible_iface, CHILDID_SELF);
{ IRawElementProviderFragment_Release(elfrag2);
check_fragment_acc(elfrag2, &Accessible.IAccessible_iface, CHILDID_SELF); ok(Accessible.ref == 1, "Unexpected refcnt %ld\n", Accessible.ref);
IRawElementProviderFragment_Release(elfrag2);
ok(Accessible.ref == 1, "Unexpected refcnt %ld\n", Accessible.ref);
}
/* ChildCount of 0, do nothing for First/Last child.*/ /* ChildCount of 0, do nothing for First/Last child.*/
SET_EXPECT(Accessible_child_get_accChildCount); SET_EXPECT(Accessible_child_get_accChildCount);
...@@ -1434,15 +1425,12 @@ static void test_uia_prov_from_acc_navigation(void) ...@@ -1434,15 +1425,12 @@ static void test_uia_prov_from_acc_navigation(void)
* can't be the root IAccessible. * can't be the root IAccessible.
*/ */
hr = IRawElementProviderFragment_Navigate(elfrag, NavigateDirection_Parent, &elfrag2); hr = IRawElementProviderFragment_Navigate(elfrag, NavigateDirection_Parent, &elfrag2);
todo_wine ok(Accessible.ref == 3, "Unexpected refcnt %ld\n", Accessible.ref); ok(Accessible.ref == 3, "Unexpected refcnt %ld\n", Accessible.ref);
todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine ok(!!elfrag2, "elfrag2 == NULL\n"); ok(!!elfrag2, "elfrag2 == NULL\n");
if (elfrag2) check_fragment_acc(elfrag2, &Accessible.IAccessible_iface, CHILDID_SELF);
{ IRawElementProviderFragment_Release(elfrag2);
check_fragment_acc(elfrag2, &Accessible.IAccessible_iface, CHILDID_SELF); ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref);
IRawElementProviderFragment_Release(elfrag2);
ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref);
}
/* /*
* Test NavigateDirection_First/LastChild on simple child element. Does * Test NavigateDirection_First/LastChild on simple child element. Does
......
...@@ -205,6 +205,21 @@ exit: ...@@ -205,6 +205,21 @@ exit:
return matched; return matched;
} }
static HRESULT msaa_acc_get_parent(IAccessible *acc, IAccessible **parent)
{
IDispatch *disp = NULL;
HRESULT hr;
*parent = NULL;
hr = IAccessible_get_accParent(acc, &disp);
if (FAILED(hr) || !disp)
return hr;
hr = IDispatch_QueryInterface(disp, &IID_IAccessible, (void**)parent);
IDispatch_Release(disp);
return hr;
}
static LONG msaa_role_to_uia_control_type(LONG role) static LONG msaa_role_to_uia_control_type(LONG role)
{ {
switch (role) switch (role)
...@@ -515,9 +530,54 @@ static ULONG WINAPI msaa_fragment_Release(IRawElementProviderFragment *iface) ...@@ -515,9 +530,54 @@ static ULONG WINAPI msaa_fragment_Release(IRawElementProviderFragment *iface)
static HRESULT WINAPI msaa_fragment_Navigate(IRawElementProviderFragment *iface, static HRESULT WINAPI msaa_fragment_Navigate(IRawElementProviderFragment *iface,
enum NavigateDirection direction, IRawElementProviderFragment **ret_val) enum NavigateDirection direction, IRawElementProviderFragment **ret_val)
{ {
FIXME("%p, %d, %p: stub!\n", iface, direction, ret_val); struct msaa_provider *msaa_prov = impl_from_msaa_fragment(iface);
IRawElementProviderSimple *elprov;
IAccessible *acc;
HRESULT hr;
TRACE("%p, %d, %p\n", iface, direction, ret_val);
*ret_val = NULL; *ret_val = NULL;
return E_NOTIMPL; switch (direction)
{
case NavigateDirection_Parent:
if (msaa_check_root_acc(msaa_prov))
break;
if (V_I4(&msaa_prov->cid) == CHILDID_SELF)
{
hr = msaa_acc_get_parent(msaa_prov->acc, &acc);
if (FAILED(hr) || !acc)
break;
}
else
acc = msaa_prov->acc;
hr = UiaProviderFromIAccessible(acc, CHILDID_SELF, 0, &elprov);
if (SUCCEEDED(hr))
{
struct msaa_provider *prov = impl_from_msaa_provider(elprov);
*ret_val = &prov->IRawElementProviderFragment_iface;
}
if (acc != msaa_prov->acc)
IAccessible_Release(acc);
break;
case NavigateDirection_FirstChild:
case NavigateDirection_LastChild:
case NavigateDirection_NextSibling:
case NavigateDirection_PreviousSibling:
FIXME("Unimplemented NavigateDirection %d\n", direction);
return E_NOTIMPL;
default:
FIXME("Invalid NavigateDirection %d\n", direction);
return E_INVALIDARG;
}
return S_OK;
} }
static HRESULT WINAPI msaa_fragment_GetRuntimeId(IRawElementProviderFragment *iface, static HRESULT WINAPI msaa_fragment_GetRuntimeId(IRawElementProviderFragment *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