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