[PATCH 2/2] oleacc: Add semi-stub and tests for AccessibleObjectFromPoint

Alex Henrie alexhenrie24 at gmail.com
Tue Nov 23 00:02:09 CST 2021


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 at 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);
-- 
2.34.0




More information about the wine-devel mailing list