Connor McAdams : uiautomationcore: Implement MSAA accState based property IDs for MSAA providers.
Alexandre Julliard
julliard at winehq.org
Wed Jun 8 15:56:05 CDT 2022
Module: wine
Branch: master
Commit: f256979be1df085ae9ed1f31ada6f98cbe8c5949
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f256979be1df085ae9ed1f31ada6f98cbe8c5949
Author: Connor McAdams <cmcadams at codeweavers.com>
Date: Fri May 20 12:17:50 2022 -0400
uiautomationcore: Implement MSAA accState based property IDs for MSAA providers.
Signed-off-by: Connor McAdams <cmcadams at codeweavers.com>
---
dlls/uiautomationcore/tests/uiautomation.c | 65 ++++++++++++++++++++++++++++--
dlls/uiautomationcore/uia_provider.c | 39 ++++++++++++++++++
2 files changed, 100 insertions(+), 4 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c
index c735e7a0bd5..f3e4b89a120 100644
--- a/dlls/uiautomationcore/tests/uiautomation.c
+++ b/dlls/uiautomationcore/tests/uiautomation.c
@@ -59,6 +59,7 @@ DEFINE_EXPECT(winproc_GETOBJECT_CLIENT);
DEFINE_EXPECT(Accessible_accNavigate);
DEFINE_EXPECT(Accessible_get_accParent);
DEFINE_EXPECT(Accessible_get_accRole);
+DEFINE_EXPECT(Accessible_get_accState);
DEFINE_EXPECT(Accessible_child_accNavigate);
DEFINE_EXPECT(Accessible_child_get_accParent);
@@ -72,6 +73,14 @@ static BOOL check_variant_i4(VARIANT *v, int val)
return FALSE;
}
+static BOOL check_variant_bool(VARIANT *v, BOOL val)
+{
+ if (V_VT(v) == VT_BOOL && V_BOOL(v) == (val ? VARIANT_TRUE : VARIANT_FALSE))
+ return TRUE;
+
+ return FALSE;
+}
+
static struct Accessible
{
IAccessible IAccessible_iface;
@@ -82,6 +91,7 @@ static struct Accessible
HWND acc_hwnd;
HWND ow_hwnd;
INT role;
+ INT state;
} Accessible, Accessible_child;
static inline struct Accessible* impl_from_Accessible(IAccessible *iface)
@@ -217,7 +227,18 @@ static HRESULT WINAPI Accessible_get_accRole(IAccessible *iface, VARIANT child_i
static HRESULT WINAPI Accessible_get_accState(IAccessible *iface, VARIANT child_id,
VARIANT *out_state)
{
- ok(0, "unexpected call\n");
+ struct Accessible *This = impl_from_Accessible(iface);
+
+ ok(This == &Accessible, "unexpected call\n");
+ CHECK_EXPECT(Accessible_get_accState);
+
+ if (This->state)
+ {
+ V_VT(out_state) = VT_I4;
+ V_I4(out_state) = This->state;
+ return S_OK;
+ }
+
return E_NOTIMPL;
}
@@ -409,7 +430,7 @@ static struct Accessible Accessible =
1,
NULL,
0, 0,
- 0,
+ 0, 0,
};
static struct Accessible Accessible_child =
{
@@ -418,7 +439,7 @@ static struct Accessible Accessible_child =
1,
&Accessible.IAccessible_iface,
0, 0,
- 0,
+ 0, 0,
};
static LRESULT WINAPI test_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
@@ -749,12 +770,24 @@ static const struct msaa_role_uia_type msaa_role_uia_types[] = {
{ ROLE_SYSTEM_OUTLINEBUTTON, 0 },
};
+struct msaa_state_uia_prop {
+ INT acc_state;
+ INT prop_id;
+};
+
+static const struct msaa_state_uia_prop msaa_state_uia_props[] = {
+ { STATE_SYSTEM_FOCUSED, UIA_HasKeyboardFocusPropertyId },
+ { STATE_SYSTEM_FOCUSABLE, UIA_IsKeyboardFocusablePropertyId },
+ { ~STATE_SYSTEM_UNAVAILABLE, UIA_IsEnabledPropertyId },
+ { STATE_SYSTEM_PROTECTED, UIA_IsPasswordPropertyId },
+};
+
static void test_uia_prov_from_acc_properties(void)
{
IRawElementProviderSimple *elprov;
HRESULT hr;
VARIANT v;
- int i;
+ int i, x;
/* MSAA role to UIA control type test. */
for (i = 0; i < ARRAY_SIZE(msaa_role_uia_types); i++)
@@ -822,6 +855,30 @@ static void test_uia_prov_from_acc_properties(void)
Accessible.role = 0;
IRawElementProviderSimple_Release(elprov);
ok(Accessible.ref == 1, "Unexpected refcnt %ld\n", Accessible.ref);
+
+ hr = pUiaProviderFromIAccessible(&Accessible.IAccessible_iface, CHILDID_SELF, UIA_PFIA_DEFAULT, &elprov);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref);
+
+ /* UIA PropertyId's that correspond directly to individual MSAA state flags. */
+ for (i = 0; i < ARRAY_SIZE(msaa_state_uia_props); i++)
+ {
+ const struct msaa_state_uia_prop *state = &msaa_state_uia_props[i];
+
+ for (x = 0; x < 2; x++)
+ {
+ Accessible.state = x ? state->acc_state : ~state->acc_state;
+ SET_EXPECT(Accessible_get_accState);
+ hr = IRawElementProviderSimple_GetPropertyValue(elprov, state->prop_id, &v);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(check_variant_bool(&v, x), "V_BOOL(&v) = %#x\n", V_BOOL(&v));
+ CHECK_CALLED(Accessible_get_accState);
+ }
+ }
+ Accessible.state = 0;
+
+ IRawElementProviderSimple_Release(elprov);
+ ok(Accessible.ref == 1, "Unexpected refcnt %ld\n", Accessible.ref);
}
static void test_UiaProviderFromIAccessible(void)
diff --git a/dlls/uiautomationcore/uia_provider.c b/dlls/uiautomationcore/uia_provider.c
index ab2b8305b10..dae0187596d 100644
--- a/dlls/uiautomationcore/uia_provider.c
+++ b/dlls/uiautomationcore/uia_provider.c
@@ -32,6 +32,25 @@ static void variant_init_i4(VARIANT *v, int val)
V_I4(v) = val;
}
+static void variant_init_bool(VARIANT *v, BOOL val)
+{
+ V_VT(v) = VT_BOOL;
+ V_BOOL(v) = val ? VARIANT_TRUE : VARIANT_FALSE;
+}
+
+static BOOL msaa_check_acc_state(IAccessible *acc, VARIANT cid, ULONG flag)
+{
+ HRESULT hr;
+ VARIANT v;
+
+ VariantInit(&v);
+ hr = IAccessible_get_accState(acc, cid, &v);
+ if (SUCCEEDED(hr) && V_VT(&v) == VT_I4 && (V_I4(&v) & flag))
+ return TRUE;
+
+ return FALSE;
+}
+
static LONG msaa_role_to_uia_control_type(LONG role)
{
switch (role)
@@ -214,6 +233,26 @@ HRESULT WINAPI msaa_provider_GetPropertyValue(IRawElementProviderSimple *iface,
break;
+ case UIA_HasKeyboardFocusPropertyId:
+ variant_init_bool(ret_val, msaa_check_acc_state(msaa_prov->acc, msaa_prov->cid,
+ STATE_SYSTEM_FOCUSED));
+ break;
+
+ case UIA_IsKeyboardFocusablePropertyId:
+ variant_init_bool(ret_val, msaa_check_acc_state(msaa_prov->acc, msaa_prov->cid,
+ STATE_SYSTEM_FOCUSABLE));
+ break;
+
+ case UIA_IsEnabledPropertyId:
+ variant_init_bool(ret_val, !msaa_check_acc_state(msaa_prov->acc, msaa_prov->cid,
+ STATE_SYSTEM_UNAVAILABLE));
+ break;
+
+ case UIA_IsPasswordPropertyId:
+ variant_init_bool(ret_val, msaa_check_acc_state(msaa_prov->acc, msaa_prov->cid,
+ STATE_SYSTEM_PROTECTED));
+ break;
+
default:
FIXME("Unimplemented propertyId %d\n", prop_id);
break;
More information about the wine-cvs
mailing list