mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-07 05:24:06 +00:00
uiautomationcore: Use WindowFromAccessibleObject to get HWND in UiaProviderFromIAccessible.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
parent
97357ea622
commit
06344846d5
|
@ -1,6 +1,6 @@
|
|||
MODULE = uiautomationcore.dll
|
||||
IMPORTLIB = uiautomationcore
|
||||
IMPORTS = uuid ole32 oleaut32 user32
|
||||
IMPORTS = uuid ole32 oleaut32 user32 oleacc
|
||||
|
||||
EXTRADLLFLAGS = -Wb,--prefer-native
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue