From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/uiautomationcore/tests/uiautomation.c | 189 +++++++++++++++++++++ dlls/uiautomationcore/uia_client.c | 10 ++ dlls/uiautomationcore/uia_ids.c | 4 +- dlls/uiautomationcore/uia_private.h | 6 + dlls/uiautomationcore/uia_provider.c | 6 - 5 files changed, 208 insertions(+), 7 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index 2971f356688..8f28271b25b 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -1115,6 +1115,12 @@ struct Provider_value_pattern_data BOOL is_read_only; };
+struct Provider_legacy_accessible_pattern_data +{ + BOOL is_supported; + int child_id; +}; + static struct Provider { IRawElementProviderSimple IRawElementProviderSimple_iface; @@ -1122,6 +1128,7 @@ static struct Provider IRawElementProviderFragmentRoot IRawElementProviderFragmentRoot_iface; IRawElementProviderHwndOverride IRawElementProviderHwndOverride_iface; IValueProvider IValueProvider_iface; + ILegacyIAccessibleProvider ILegacyIAccessibleProvider_iface; LONG ref;
const char *prov_name; @@ -1143,6 +1150,7 @@ static struct Provider int prop_override_count; struct UiaRect bounds_rect; struct Provider_value_pattern_data value_pattern_data; + struct Provider_legacy_accessible_pattern_data legacy_acc_pattern_data; } Provider, Provider2, Provider_child, Provider_child2; static struct Provider Provider_hwnd, Provider_nc, Provider_proxy, Provider_proxy2, Provider_override; static void initialize_provider(struct Provider *prov, int prov_opts, HWND hwnd, BOOL initialize_nav_links); @@ -1571,6 +1579,8 @@ HRESULT WINAPI ProviderSimple_QueryInterface(IRawElementProviderSimple *iface, R *ppv = &This->IRawElementProviderHwndOverride_iface; else if (IsEqualIID(riid, &IID_IValueProvider)) *ppv = &This->IValueProvider_iface; + else if (IsEqualIID(riid, &IID_ILegacyIAccessibleProvider)) + *ppv = &This->ILegacyIAccessibleProvider_iface; else return E_NOINTERFACE;
@@ -1628,6 +1638,11 @@ HRESULT WINAPI ProviderSimple_GetPatternProvider(IRawElementProviderSimple *ifac *ret_val = (IUnknown *)iface; break;
+ case UIA_LegacyIAccessiblePatternId: + if (This->legacy_acc_pattern_data.is_supported) + *ret_val = (IUnknown *)iface; + break; + default: break; } @@ -2176,6 +2191,141 @@ static const IValueProviderVtbl ProviderValuePatternVtbl = { ProviderValuePattern_get_IsReadOnly, };
+static inline struct Provider *impl_from_ProviderLegacyIAccessiblePattern(ILegacyIAccessibleProvider *iface) +{ + return CONTAINING_RECORD(iface, struct Provider, ILegacyIAccessibleProvider_iface); +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_QueryInterface(ILegacyIAccessibleProvider *iface, REFIID riid, + void **ppv) +{ + struct Provider *Provider = impl_from_ProviderLegacyIAccessiblePattern(iface); + return IRawElementProviderSimple_QueryInterface(&Provider->IRawElementProviderSimple_iface, riid, ppv); +} + +static ULONG WINAPI ProviderLegacyIAccessiblePattern_AddRef(ILegacyIAccessibleProvider *iface) +{ + struct Provider *Provider = impl_from_ProviderLegacyIAccessiblePattern(iface); + return IRawElementProviderSimple_AddRef(&Provider->IRawElementProviderSimple_iface); +} + +static ULONG WINAPI ProviderLegacyIAccessiblePattern_Release(ILegacyIAccessibleProvider *iface) +{ + struct Provider *Provider = impl_from_ProviderLegacyIAccessiblePattern(iface); + return IRawElementProviderSimple_Release(&Provider->IRawElementProviderSimple_iface); +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_Select(ILegacyIAccessibleProvider *iface, LONG select_flags) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_DoDefaultAction(ILegacyIAccessibleProvider *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_SetValue(ILegacyIAccessibleProvider *iface, LPCWSTR val) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_GetIAccessible(ILegacyIAccessibleProvider *iface, + IAccessible **out_acc) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_get_ChildId(ILegacyIAccessibleProvider *iface, int *out_cid) +{ + struct Provider *Provider = impl_from_ProviderLegacyIAccessiblePattern(iface); + + *out_cid = Provider->legacy_acc_pattern_data.child_id; + return S_OK; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_get_Name(ILegacyIAccessibleProvider *iface, BSTR *out_name) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_get_Value(ILegacyIAccessibleProvider *iface, BSTR *out_value) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_get_Description(ILegacyIAccessibleProvider *iface, + BSTR *out_description) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_get_Role(ILegacyIAccessibleProvider *iface, DWORD *out_role) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_get_State(ILegacyIAccessibleProvider *iface, DWORD *out_state) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_get_Help(ILegacyIAccessibleProvider *iface, BSTR *out_help) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_get_KeyboardShortcut(ILegacyIAccessibleProvider *iface, + BSTR *out_kbd_shortcut) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_GetSelection(ILegacyIAccessibleProvider *iface, + SAFEARRAY **out_selected) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProviderLegacyIAccessiblePattern_get_DefaultAction(ILegacyIAccessibleProvider *iface, + BSTR *out_default_action) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const ILegacyIAccessibleProviderVtbl ProviderLegacyIAccessiblePatternVtbl = { + ProviderLegacyIAccessiblePattern_QueryInterface, + ProviderLegacyIAccessiblePattern_AddRef, + ProviderLegacyIAccessiblePattern_Release, + ProviderLegacyIAccessiblePattern_Select, + ProviderLegacyIAccessiblePattern_DoDefaultAction, + ProviderLegacyIAccessiblePattern_SetValue, + ProviderLegacyIAccessiblePattern_GetIAccessible, + ProviderLegacyIAccessiblePattern_get_ChildId, + ProviderLegacyIAccessiblePattern_get_Name, + ProviderLegacyIAccessiblePattern_get_Value, + ProviderLegacyIAccessiblePattern_get_Description, + ProviderLegacyIAccessiblePattern_get_Role, + ProviderLegacyIAccessiblePattern_get_State, + ProviderLegacyIAccessiblePattern_get_Help, + ProviderLegacyIAccessiblePattern_get_KeyboardShortcut, + ProviderLegacyIAccessiblePattern_GetSelection, + ProviderLegacyIAccessiblePattern_get_DefaultAction, +}; + static struct Provider Provider = { { &ProviderSimpleVtbl }, @@ -2183,6 +2333,7 @@ static struct Provider Provider = { &ProviderFragmentRootVtbl }, { &ProviderHwndOverrideVtbl }, { &ProviderValuePatternVtbl }, + { &ProviderLegacyIAccessiblePatternVtbl }, 1, "Provider", NULL, NULL, @@ -2198,6 +2349,7 @@ static struct Provider Provider2 = { &ProviderFragmentRootVtbl }, { &ProviderHwndOverrideVtbl }, { &ProviderValuePatternVtbl }, + { &ProviderLegacyIAccessiblePatternVtbl }, 1, "Provider2", NULL, NULL, @@ -2213,6 +2365,7 @@ static struct Provider Provider_child = { &ProviderFragmentRootVtbl }, { &ProviderHwndOverrideVtbl }, { &ProviderValuePatternVtbl }, + { &ProviderLegacyIAccessiblePatternVtbl }, 1, "Provider_child", &Provider.IRawElementProviderFragment_iface, &Provider.IRawElementProviderFragmentRoot_iface, @@ -2228,6 +2381,7 @@ static struct Provider Provider_child2 = { &ProviderFragmentRootVtbl }, { &ProviderHwndOverrideVtbl }, { &ProviderValuePatternVtbl }, + { &ProviderLegacyIAccessiblePatternVtbl }, 1, "Provider_child2", &Provider.IRawElementProviderFragment_iface, &Provider.IRawElementProviderFragmentRoot_iface, @@ -2243,6 +2397,7 @@ static struct Provider Provider_hwnd = { &ProviderFragmentRootVtbl }, { &ProviderHwndOverrideVtbl }, { &ProviderValuePatternVtbl }, + { &ProviderLegacyIAccessiblePatternVtbl }, 1, "Provider_hwnd", NULL, NULL, @@ -2258,6 +2413,7 @@ static struct Provider Provider_nc = { &ProviderFragmentRootVtbl }, { &ProviderHwndOverrideVtbl }, { &ProviderValuePatternVtbl }, + { &ProviderLegacyIAccessiblePatternVtbl }, 1, "Provider_nc", NULL, NULL, @@ -2274,6 +2430,7 @@ static struct Provider Provider_proxy = { &ProviderFragmentRootVtbl }, { &ProviderHwndOverrideVtbl }, { &ProviderValuePatternVtbl }, + { &ProviderLegacyIAccessiblePatternVtbl }, 1, "Provider_proxy", NULL, NULL, @@ -2290,6 +2447,7 @@ static struct Provider Provider_proxy2 = { &ProviderFragmentRootVtbl }, { &ProviderHwndOverrideVtbl }, { &ProviderValuePatternVtbl }, + { &ProviderLegacyIAccessiblePatternVtbl }, 1, "Provider_proxy2", NULL, NULL, @@ -2306,6 +2464,7 @@ static struct Provider Provider_override = { &ProviderFragmentRootVtbl }, { &ProviderHwndOverrideVtbl }, { &ProviderValuePatternVtbl }, + { &ProviderLegacyIAccessiblePatternVtbl }, 1, "Provider_override", NULL, NULL, @@ -2323,6 +2482,7 @@ static struct Provider Provider_override = { &ProviderFragmentRootVtbl }, \ { &ProviderHwndOverrideVtbl }, \ { &ProviderValuePatternVtbl }, \ + { &ProviderLegacyIAccessiblePatternVtbl }, \ 1, \ "Provider_" # name "", \ NULL, NULL, \ @@ -5065,6 +5225,12 @@ static const struct prov_method_sequence get_pattern_prop_seq[] = { { 0 } };
+static const struct prov_method_sequence get_pattern_prop_seq2[] = { + { &Provider, PROV_GET_PATTERN_PROV }, + { &Provider, FRAG_GET_FRAGMENT_ROOT, METHOD_TODO }, + { 0 } +}; + static const struct prov_method_sequence get_bounding_rect_seq[] = { NODE_CREATE_SEQ(&Provider_child), { &Provider_child, FRAG_GET_BOUNDING_RECT }, @@ -5520,6 +5686,28 @@ static void test_UiaGetPropertyValue(void) VariantClear(&v); }
+ /* ILegacyIAccessibleProvider pattern property IDs. */ + Provider.legacy_acc_pattern_data.is_supported = FALSE; + hr = UiaGetPropertyValue(node, UIA_LegacyIAccessibleChildIdPropertyId, &v); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(V_VT(&v) == VT_UNKNOWN, "Unexpected vt %d\n", V_VT(&v)); + ok(V_UNKNOWN(&v) == unk_ns, "unexpected IUnknown %p\n", V_UNKNOWN(&v)); + ok_method_sequence(get_pattern_prop_seq2, NULL); + VariantClear(&v); + + Provider.legacy_acc_pattern_data.is_supported = TRUE; + for (i = 0; i < 2; i++) + { + Provider.legacy_acc_pattern_data.child_id = i; + + hr = UiaGetPropertyValue(node, UIA_LegacyIAccessibleChildIdPropertyId, &v); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(V_VT(&v) == VT_I4, "Unexpected VT %d\n", V_VT(&v)); + ok(V_I4(&v) == i, "Unexpected I4 %#lx\n", V_I4(&v)); + ok_method_sequence(get_pattern_prop_seq, NULL); + VariantClear(&v); + } + ok(UiaNodeRelease(node), "UiaNodeRelease returned FALSE\n"); ok(Provider.ref == 1, "Unexpected refcnt %ld\n", Provider.ref); initialize_provider(&Provider, ProviderOptions_ServerSideProvider, NULL, FALSE); @@ -9013,6 +9201,7 @@ static void initialize_provider(struct Provider *prov, int prov_opts, HWND hwnd, prov->prop_override_count = 0; memset(&prov->bounds_rect, 0, sizeof(prov->bounds_rect)); memset(&prov->value_pattern_data, 0, sizeof(prov->value_pattern_data)); + memset(&prov->legacy_acc_pattern_data, 0, sizeof(prov->legacy_acc_pattern_data)); if (initialize_nav_links) { prov->frag_root = NULL; diff --git a/dlls/uiautomationcore/uia_client.c b/dlls/uiautomationcore/uia_client.c index dae78ea8ff4..95287179f92 100644 --- a/dlls/uiautomationcore/uia_client.c +++ b/dlls/uiautomationcore/uia_client.c @@ -1571,6 +1571,16 @@ static HRESULT uia_provider_get_pattern_prop_val(struct uia_provider *prov, break; }
+ case UIA_LegacyIAccessibleChildIdPropertyId: + { + int val; + + hr = ILegacyIAccessibleProvider_get_ChildId((ILegacyIAccessibleProvider *)pattern_prov, &val); + if (SUCCEEDED(hr)) + variant_init_i4(ret_val, val); + break; + } + default: break; } diff --git a/dlls/uiautomationcore/uia_ids.c b/dlls/uiautomationcore/uia_ids.c index d518b2dd44f..62f26de0982 100644 --- a/dlls/uiautomationcore/uia_ids.c +++ b/dlls/uiautomationcore/uia_ids.c @@ -152,7 +152,9 @@ static const struct uia_prop_info default_uia_properties[] = { { &RangeValue_SmallChange_Property_GUID, UIA_RangeValueSmallChangePropertyId, }, { &IsTextEditPatternAvailable_Property_GUID, UIA_IsTextEditPatternAvailablePropertyId, }, { &GridItem_Column_Property_GUID, UIA_GridItemColumnPropertyId, }, - { &LegacyIAccessible_ChildId_Property_GUID, UIA_LegacyIAccessibleChildIdPropertyId, }, + { &LegacyIAccessible_ChildId_Property_GUID, UIA_LegacyIAccessibleChildIdPropertyId, + PROP_TYPE_PATTERN_PROP, UIAutomationType_Int, + UIA_LegacyIAccessiblePatternId, }, { &Annotation_DateTime_Property_GUID, UIA_AnnotationDateTimePropertyId, }, { &IsTablePatternAvailable_Property_GUID, UIA_IsTablePatternAvailablePropertyId, }, { &SelectionItem_IsSelected_Property_GUID, UIA_SelectionItemIsSelectedPropertyId, }, diff --git a/dlls/uiautomationcore/uia_private.h b/dlls/uiautomationcore/uia_private.h index f7e991ee4fd..63c6f7dde22 100644 --- a/dlls/uiautomationcore/uia_private.h +++ b/dlls/uiautomationcore/uia_private.h @@ -99,6 +99,12 @@ static inline void variant_init_bool(VARIANT *v, BOOL val) V_BOOL(v) = val ? VARIANT_TRUE : VARIANT_FALSE; }
+static inline void variant_init_i4(VARIANT *v, int val) +{ + V_VT(v) = VT_I4; + V_I4(v) = val; +} + static inline BOOL uia_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) { SIZE_T max_capacity, new_capacity; diff --git a/dlls/uiautomationcore/uia_provider.c b/dlls/uiautomationcore/uia_provider.c index 119a7e69abc..a950df599d8 100644 --- a/dlls/uiautomationcore/uia_provider.c +++ b/dlls/uiautomationcore/uia_provider.c @@ -28,12 +28,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
DEFINE_GUID(SID_AccFromDAWrapper, 0x33f139ee, 0xe509, 0x47f7, 0xbf,0x39, 0x83,0x76,0x44,0xf7,0x45,0x76);
-static void variant_init_i4(VARIANT *v, int val) -{ - V_VT(v) = VT_I4; - V_I4(v) = val; -} - static BOOL msaa_check_acc_state(IAccessible *acc, VARIANT cid, ULONG flag) { HRESULT hr;