Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/oleacc/tests/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/oleacc/tests/main.c b/dlls/oleacc/tests/main.c index 62346ffed01..8c234aee8aa 100644 --- a/dlls/oleacc/tests/main.c +++ b/dlls/oleacc/tests/main.c @@ -720,7 +720,7 @@ static void test_AccessibleObjectFromEvent(void) ok(hr == S_OK, "got %#x\n", hr); todo_wine ok(!iface_cmp((IUnknown*)acc, (IUnknown*)&Accessible), "acc == &Accessible\n"); ok(V_VT(&cid) == VT_I4, "got %#x, expected %#x\n", V_VT(&cid), VT_I4); - ok(V_I4(&cid) == 1, "got %#x, expected %#x\n", V_I4(&cid), CHILDID_SELF); + ok(V_I4(&cid) == 1, "got %#x, expected 1\n", V_I4(&cid)); SET_EXPECT(Accessible_get_accParent); SET_EXPECT(Accessible_get_accName); V_I4(&cid) = 0; @@ -736,7 +736,7 @@ static void test_AccessibleObjectFromEvent(void) ok(hr == S_OK, "got %#x\n", hr); todo_wine ok(!iface_cmp((IUnknown*)acc, (IUnknown*)&Accessible), "acc == &Accessible\n"); ok(V_VT(&cid) == VT_I4, "got %#x, expected %#x\n", V_VT(&cid), VT_I4); - ok(V_I4(&cid) == 2, "got %#x, expected %#x\n", V_I4(&cid), CHILDID_SELF); + ok(V_I4(&cid) == 2, "got %#x, expected 2\n", V_I4(&cid)); SET_EXPECT(Accessible_get_accParent); SET_EXPECT(Accessible_get_accName); V_I4(&cid) = 0; @@ -752,7 +752,7 @@ static void test_AccessibleObjectFromEvent(void) ok(hr == S_OK, "got %#x\n", hr); todo_wine ok(!iface_cmp((IUnknown*)acc, (IUnknown*)&Accessible_child), "acc == &Accessible_child\n"); ok(V_VT(&cid) == VT_I4, "got %#x, expected %#x\n", V_VT(&cid), VT_I4); - ok(V_I4(&cid) == 0, "got %#x, expected %#x\n", V_I4(&cid), CHILDID_SELF); + ok(V_I4(&cid) == CHILDID_SELF, "got %#x, expected %#x\n", V_I4(&cid), CHILDID_SELF); SET_EXPECT(Accessible_child_get_accParent); SET_EXPECT(Accessible_child_get_accName); hr = IAccessible_get_accName(acc, cid, NULL); @@ -767,7 +767,7 @@ static void test_AccessibleObjectFromEvent(void) ok(hr == S_OK, "got %#x\n", hr); ok(acc == &Accessible_child, "acc != &Accessible_child\n"); ok(V_VT(&cid) == VT_I4, "got %#x, expected %#x\n", V_VT(&cid), VT_I4); - ok(V_I4(&cid) == 0, "got %#x, expected %#x\n", V_I4(&cid), CHILDID_SELF); + ok(V_I4(&cid) == CHILDID_SELF, "got %#x, expected %#x\n", V_I4(&cid), CHILDID_SELF); SET_EXPECT(Accessible_child_get_accName); hr = IAccessible_get_accName(acc, cid, NULL); ok(hr == E_INVALIDARG, "get_accName returned %x\n", hr);
This is not a complete implementation, but it makes the NVDA screen reader much more usable.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48950 Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/oleacc/main.c | 23 +++++++++++----- dlls/oleacc/tests/main.c | 57 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 6 deletions(-)
diff --git a/dlls/oleacc/main.c b/dlls/oleacc/main.c index 3ce616ae0c1..eb0429d7afe 100644 --- a/dlls/oleacc/main.c +++ b/dlls/oleacc/main.c @@ -263,18 +263,29 @@ LRESULT WINAPI LresultFromObject( REFIID riid, WPARAM wParam, LPUNKNOWN pAcc ) return atom; }
-HRESULT WINAPI AccessibleObjectFromPoint( POINT ptScreen, IAccessible** ppacc, VARIANT* pvarChild ) -{ - FIXME("{%d,%d} %p %p: stub\n", ptScreen.x, ptScreen.y, ppacc, pvarChild ); - return E_NOTIMPL; -} - static void variant_init_i4( VARIANT *v, int val ) { V_VT(v) = VT_I4; V_I4(v) = val; }
+HRESULT WINAPI AccessibleObjectFromPoint( POINT point, IAccessible** acc, VARIANT* child_id ) +{ + HRESULT hr; + + FIXME("{%d,%d} %p %p: semi-stub\n", point.x, point.y, acc, child_id); + + if (!acc || !child_id) + return E_INVALIDARG; + + hr = AccessibleObjectFromWindow(WindowFromPoint(point), OBJID_CLIENT, &IID_IAccessible, (void **)acc); + + if (SUCCEEDED(hr)) + variant_init_i4(child_id, CHILDID_SELF); + + return hr; +} + HRESULT WINAPI AccessibleObjectFromEvent( HWND hwnd, DWORD object_id, DWORD child_id, IAccessible **acc_out, VARIANT *child_id_out ) { diff --git a/dlls/oleacc/tests/main.c b/dlls/oleacc/tests/main.c index 8c234aee8aa..a7101e9af6f 100644 --- a/dlls/oleacc/tests/main.c +++ b/dlls/oleacc/tests/main.c @@ -681,6 +681,62 @@ static void test_AccessibleObjectFromWindow(void) DestroyWindow(hwnd); }
+static void test_AccessibleObjectFromPoint(void) +{ + IAccessible *acc; + VARIANT cid; + HRESULT hr; + HWND hwnd; + RECT rect; + POINT point = {0, 0}; + + VariantInit(&cid); + + hr = AccessibleObjectFromPoint(point, NULL, NULL); + ok(hr == E_INVALIDARG, "got %x\n", hr); + + hr = AccessibleObjectFromPoint(point, &acc, NULL); + ok(hr == E_INVALIDARG, "got %x\n", hr); + + hr = AccessibleObjectFromPoint(point, NULL, &cid); + ok(hr == E_INVALIDARG, "got %x\n", hr); + ok(V_VT(&cid) == VT_EMPTY, "got %#x, expected %#x\n", V_VT(&cid), VT_EMPTY); + + hwnd = CreateWindowA("oleacc_test", "test", WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "CreateWindow failed\n"); + + hr = GetWindowRect(hwnd, &rect); + ok(hr, "GetWindowRect failed\n"); + + point.x = rect.left; + point.y = rect.top; + hr = AccessibleObjectFromPoint(point, &acc, &cid); + ok(hr == S_OK, "got %x\n", hr); + ok(V_VT(&cid) == VT_I4, "got %#x, expected %#x\n", V_VT(&cid), VT_I4); + ok(V_I4(&cid) == CHILDID_SELF || broken(V_I4(&cid) == 1) /* <= vista */, + "got %#x, expected %#x\n", V_I4(&cid), CHILDID_SELF); + IAccessible_Release(acc); + + point.x = rect.right; + point.y = rect.bottom; + hr = AccessibleObjectFromPoint(point, &acc, &cid); + ok(hr == S_OK, "got %x\n", hr); + ok(V_VT(&cid) == VT_I4, "got %#x, expected %#x\n", V_VT(&cid), VT_I4); + ok(V_I4(&cid) == CHILDID_SELF, "got %#x, expected %#x\n", V_I4(&cid), CHILDID_SELF); + IAccessible_Release(acc); + + point.x = (rect.left + rect.right) / 2; + point.y = (rect.top + rect.bottom) / 2; + hr = AccessibleObjectFromPoint(point, &acc, &cid); + ok(hr == S_OK, "got %x\n", hr); + ok(V_VT(&cid) == VT_I4, "got %#x, expected %#x\n", V_VT(&cid), VT_I4); + todo_wine ok(V_I4(&cid) != CHILDID_SELF || broken(V_I4(&cid) == CHILDID_SELF) /* arabic and hebrew */, + "expected child other than %#x\n", CHILDID_SELF); + IAccessible_Release(acc); + + DestroyWindow(hwnd); +} + static void test_AccessibleObjectFromEvent(void) { IAccessible *acc; @@ -1745,6 +1801,7 @@ START_TEST(main) test_GetStateText(); test_LresultFromObject(argv[0]); test_AccessibleObjectFromWindow(); + test_AccessibleObjectFromPoint(); test_GetProcessHandleFromHwnd(); test_default_client_accessible_object(); test_AccessibleChildren(&Accessible);
Hi Alex,
On 11/23/21 07:02, Alex Henrie wrote:
- hwnd = CreateWindowA("oleacc_test", "test", WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
- ok(hwnd != NULL, "CreateWindow failed\n");
Invisible windows are ignored by AccessibleObjectFromPoint.
- hr = GetWindowRect(hwnd, &rect);
- ok(hr, "GetWindowRect failed\n");
- point.x = rect.left;
- point.y = rect.top;
- hr = AccessibleObjectFromPoint(point, &acc, &cid);
- ok(hr == S_OK, "got %x\n", hr);
- ok(V_VT(&cid) == VT_I4, "got %#x, expected %#x\n", V_VT(&cid), VT_I4);
- ok(V_I4(&cid) == CHILDID_SELF || broken(V_I4(&cid) == 1) /* <= vista */,
"got %#x, expected %#x\n", V_I4(&cid), CHILDID_SELF);
Please test hwnd associated with accessibility object (check_acc_hwnd macro).
- IAccessible_Release(acc);
Thanks, Piotr