Connor McAdams : uiautomationcore: Use WindowFromAccessibleObject to get HWND in UiaProviderFromIAccessible.

Alexandre Julliard julliard at winehq.org
Wed Jun 8 15:56:05 CDT 2022


Module: wine
Branch: master
Commit: 06344846d5208e5bf8b1f237ba6d0eb312ad05f9
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=06344846d5208e5bf8b1f237ba6d0eb312ad05f9

Author: Connor McAdams <cmcadams at codeweavers.com>
Date:   Tue May 17 10:37:59 2022 -0400

uiautomationcore: Use WindowFromAccessibleObject to get HWND in UiaProviderFromIAccessible.

Signed-off-by: Connor McAdams <cmcadams at codeweavers.com>

---

 dlls/uiautomationcore/Makefile.in          |  2 +-
 dlls/uiautomationcore/tests/uiautomation.c | 64 +++++++++++++++++++++++++-----
 dlls/uiautomationcore/uia_provider.c       | 28 +++----------
 3 files changed, 61 insertions(+), 33 deletions(-)

diff --git a/dlls/uiautomationcore/Makefile.in b/dlls/uiautomationcore/Makefile.in
index 61a560d6c2e..a1cf5575814 100644
--- a/dlls/uiautomationcore/Makefile.in
+++ b/dlls/uiautomationcore/Makefile.in
@@ -1,6 +1,6 @@
 MODULE = uiautomationcore.dll
 IMPORTLIB = uiautomationcore
-IMPORTS   = uuid ole32 oleaut32 user32
+IMPORTS   = uuid ole32 oleaut32 user32 oleacc
 
 EXTRADLLFLAGS = -Wb,--prefer-native
 
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c
index 704e43180bd..344fd2cdbf0 100644
--- a/dlls/uiautomationcore/tests/uiautomation.c
+++ b/dlls/uiautomationcore/tests/uiautomation.c
@@ -53,11 +53,18 @@ static HRESULT (WINAPI *pUiaProviderFromIAccessible)(IAccessible *, long, DWORD,
         expect_ ## func = called_ ## func = FALSE; \
     }while(0)
 
+#define NAVDIR_INTERNAL_HWND 10
+
 DEFINE_EXPECT(winproc_GETOBJECT_CLIENT);
 DEFINE_EXPECT(Accessible_accNavigate);
+DEFINE_EXPECT(Accessible_get_accParent);
+DEFINE_EXPECT(Accessible_child_accNavigate);
+DEFINE_EXPECT(Accessible_child_get_accParent);
 
 static LONG Accessible_ref = 1;
+static LONG Accessible_child_ref = 1;
 static IAccessible Accessible;
+static IAccessible Accessible_child;
 static IOleWindow OleWindow;
 static HWND Accessible_hwnd = NULL;
 static HWND OleWindow_hwnd = NULL;
@@ -77,7 +84,7 @@ static HRESULT WINAPI Accessible_QueryInterface(IAccessible *iface, REFIID riid,
     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch) ||
             IsEqualIID(riid, &IID_IAccessible))
         *obj = iface;
-    else if (IsEqualIID(riid, &IID_IOleWindow))
+    else if (IsEqualIID(riid, &IID_IOleWindow) && (iface == &Accessible))
         *obj = &OleWindow;
     else
         return E_NOINTERFACE;
@@ -88,12 +95,18 @@ static HRESULT WINAPI Accessible_QueryInterface(IAccessible *iface, REFIID riid,
 
 static ULONG WINAPI Accessible_AddRef(IAccessible *iface)
 {
-    return InterlockedIncrement(&Accessible_ref);
+    if (iface == &Accessible_child)
+        return InterlockedIncrement(&Accessible_child_ref);
+    else
+        return InterlockedIncrement(&Accessible_ref);
 }
 
 static ULONG WINAPI Accessible_Release(IAccessible *iface)
 {
-    return InterlockedDecrement(&Accessible_ref);
+    if (iface == &Accessible_child)
+        return InterlockedDecrement(&Accessible_child_ref);
+    else
+        return InterlockedDecrement(&Accessible_ref);
 }
 
 static HRESULT WINAPI Accessible_GetTypeInfoCount(IAccessible *iface, UINT *pctinfo)
@@ -126,8 +139,16 @@ static HRESULT WINAPI Accessible_Invoke(IAccessible *iface, DISPID disp_id_membe
 
 static HRESULT WINAPI Accessible_get_accParent(IAccessible *iface, IDispatch **out_parent)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    if (iface == &Accessible_child)
+    {
+        CHECK_EXPECT(Accessible_child_get_accParent);
+        return IAccessible_QueryInterface(&Accessible, &IID_IDispatch, (void **)out_parent);
+    }
+    else
+        CHECK_EXPECT(Accessible_get_accParent);
+
+    *out_parent = NULL;
+    return S_FALSE;
 }
 
 static HRESULT WINAPI Accessible_get_accChildCount(IAccessible *iface, LONG *out_count)
@@ -235,14 +256,18 @@ static HRESULT WINAPI Accessible_accLocation(IAccessible *iface, LONG *out_left,
 static HRESULT WINAPI Accessible_accNavigate(IAccessible *iface, LONG nav_direction,
         VARIANT child_id_start, VARIANT *out_var)
 {
-    CHECK_EXPECT(Accessible_accNavigate);
+    if (iface == &Accessible_child)
+        CHECK_EXPECT(Accessible_child_accNavigate);
+    else
+        CHECK_EXPECT(Accessible_accNavigate);
     VariantInit(out_var);
 
     /*
      * This is an undocumented way for UI Automation to get an HWND for
      * IAccessible's contained in a Direct Annotation wrapper object.
      */
-    if ((nav_direction == 10) && check_variant_i4(&child_id_start, CHILDID_SELF))
+    if ((nav_direction == NAVDIR_INTERNAL_HWND) && check_variant_i4(&child_id_start, CHILDID_SELF) &&
+            Accessible_hwnd)
     {
         V_VT(out_var) = VT_I4;
         V_I4(out_var) = HandleToUlong(Accessible_hwnd);
@@ -326,8 +351,13 @@ static ULONG WINAPI OleWindow_Release(IOleWindow *iface)
 
 static HRESULT WINAPI OleWindow_GetWindow(IOleWindow *iface, HWND *hwnd)
 {
-    *hwnd = OleWindow_hwnd;
-    return S_OK;
+    if (OleWindow_hwnd)
+    {
+        *hwnd = OleWindow_hwnd;
+        return S_OK;
+    }
+
+    return E_FAIL;
 }
 
 static HRESULT WINAPI OleWindow_ContextSensitiveHelp(IOleWindow *iface, BOOL f_enter_mode)
@@ -344,6 +374,7 @@ static const IOleWindowVtbl OleWindowVtbl = {
 };
 
 static IAccessible Accessible = {&AccessibleVtbl};
+static IAccessible Accessible_child = {&AccessibleVtbl};
 static IOleWindow OleWindow   = {&OleWindowVtbl};
 
 static LRESULT WINAPI test_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
@@ -650,11 +681,13 @@ static void test_UiaProviderFromIAccessible(void)
 
     /* Don't return an HWND from accNavigate or OleWindow. */
     SET_EXPECT(Accessible_accNavigate);
+    SET_EXPECT(Accessible_get_accParent);
     Accessible_hwnd = NULL;
     OleWindow_hwnd = NULL;
     hr = pUiaProviderFromIAccessible(&Accessible, CHILDID_SELF, UIA_PFIA_DEFAULT, &elprov);
     ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
     CHECK_CALLED(Accessible_accNavigate);
+    CHECK_CALLED(Accessible_get_accParent);
 
     /* Return an HWND from accNavigate, not OleWindow. */
     SET_EXPECT(Accessible_accNavigate);
@@ -678,6 +711,19 @@ static void test_UiaProviderFromIAccessible(void)
     }
     expect_winproc_GETOBJECT_CLIENT = FALSE;
 
+    /* Return an HWND from parent IAccessible's IOleWindow interface. */
+    SET_EXPECT(Accessible_child_accNavigate);
+    SET_EXPECT(Accessible_child_get_accParent);
+    Accessible_hwnd = NULL;
+    OleWindow_hwnd = hwnd;
+    hr = pUiaProviderFromIAccessible(&Accessible_child, CHILDID_SELF, UIA_PFIA_DEFAULT, &elprov);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+    CHECK_CALLED(Accessible_child_accNavigate);
+    CHECK_CALLED(Accessible_child_get_accParent);
+    ok(Accessible_child_ref == 2, "Unexpected refcnt %ld\n", Accessible_child_ref);
+    IRawElementProviderSimple_Release(elprov);
+    ok(Accessible_child_ref == 1, "Unexpected refcnt %ld\n", Accessible_child_ref);
+
     /* Return an HWND from OleWindow, not accNavigate. */
     Accessible_hwnd = NULL;
     OleWindow_hwnd = hwnd;
diff --git a/dlls/uiautomationcore/uia_provider.c b/dlls/uiautomationcore/uia_provider.c
index 790593dbcab..d2a0da15c3c 100644
--- a/dlls/uiautomationcore/uia_provider.c
+++ b/dlls/uiautomationcore/uia_provider.c
@@ -151,7 +151,6 @@ HRESULT WINAPI UiaProviderFromIAccessible(IAccessible *acc, long child_id, DWORD
     struct msaa_provider *msaa_prov;
     IServiceProvider *serv_prov;
     HWND hwnd = NULL;
-    IOleWindow *win;
     HRESULT hr;
 
     TRACE("(%p, %ld, %#lx, %p)\n", acc, child_id, flags, elprov);
@@ -187,28 +186,11 @@ HRESULT WINAPI UiaProviderFromIAccessible(IAccessible *acc, long child_id, DWORD
         IServiceProvider_Release(serv_prov);
     }
 
-    hr = IAccessible_QueryInterface(acc, &IID_IOleWindow, (void **)&win);
-    if (SUCCEEDED(hr))
-    {
-        hr = IOleWindow_GetWindow(win, &hwnd);
-        if (FAILED(hr))
-            hwnd = NULL;
-        IOleWindow_Release(win);
-    }
-
-    if (!IsWindow(hwnd))
-    {
-        VARIANT v, cid;
-
-        VariantInit(&v);
-        variant_init_i4(&cid, CHILDID_SELF);
-        hr = IAccessible_accNavigate(acc, 10, cid, &v);
-        if (SUCCEEDED(hr) && V_VT(&v) == VT_I4)
-            hwnd = ULongToHandle(V_I4(&v));
-
-        if (!IsWindow(hwnd))
-            return E_FAIL;
-    }
+    hr = WindowFromAccessibleObject(acc, &hwnd);
+    if (FAILED(hr))
+       return hr;
+    if (!hwnd)
+        return E_FAIL;
 
     msaa_prov = heap_alloc(sizeof(*msaa_prov));
     if (!msaa_prov)




More information about the wine-cvs mailing list