[PATCH 3/3] uiautomationcore: Add ILegacyIAccessibleProvider implementation for MSAA providers.
Connor McAdams
wine at gitlab.winehq.org
Thu Jun 9 08:20:50 CDT 2022
From: Connor McAdams <cmcadams at codeweavers.com>
Signed-off-by: Connor McAdams <cmcadams at codeweavers.com>
---
dlls/uiautomationcore/tests/uiautomation.c | 57 +++++++
dlls/uiautomationcore/uia_provider.c | 167 ++++++++++++++++++++-
2 files changed, 222 insertions(+), 2 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c
index 6ed3c907a40..6a7e9afbdc0 100644
--- a/dlls/uiautomationcore/tests/uiautomation.c
+++ b/dlls/uiautomationcore/tests/uiautomation.c
@@ -89,6 +89,20 @@ static BOOL check_variant_bool(VARIANT *v, BOOL val)
return FALSE;
}
+static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
+{
+ IUnknown *unk1, *unk2;
+
+ if(iface1 == iface2)
+ return TRUE;
+
+ IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
+ IUnknown_Release(unk1);
+ IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2);
+ IUnknown_Release(unk2);
+ return unk1 == unk2;
+}
+
static struct Accessible
{
IAccessible IAccessible_iface;
@@ -977,13 +991,16 @@ static void test_uia_prov_from_acc_properties(void)
static void test_UiaProviderFromIAccessible(void)
{
+ ILegacyIAccessibleProvider *accprov;
IRawElementProviderSimple *elprov, *elprov2;
enum ProviderOptions prov_opt;
IAccessible *acc;
+ IUnknown *unk;
WNDCLASSA cls;
HRESULT hr;
HWND hwnd;
VARIANT v;
+ INT cid;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
cls.style = 0;
@@ -1084,6 +1101,26 @@ static void test_UiaProviderFromIAccessible(void)
ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
VariantClear(&v);
+ hr = IRawElementProviderSimple_GetPatternProvider(elprov, UIA_LegacyIAccessiblePatternId, &unk);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(!!unk, "unk == NULL\n");
+ ok(iface_cmp((IUnknown *)elprov, unk), "unk != elprov\n");
+
+ hr = IUnknown_QueryInterface(unk, &IID_ILegacyIAccessibleProvider, (void **)&accprov);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(!!accprov, "accprov == NULL\n");
+
+ hr = ILegacyIAccessibleProvider_get_ChildId(accprov, &cid);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(cid == CHILDID_SELF, "cid != CHILDID_SELF\n");
+
+ hr = ILegacyIAccessibleProvider_GetIAccessible(accprov, &acc);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(acc == &Accessible.IAccessible_iface, "acc != &Accessible.IAccessible_iface\n");
+ IAccessible_Release(acc);
+ IUnknown_Release(unk);
+ ILegacyIAccessibleProvider_Release(accprov);
+
IRawElementProviderSimple_Release(elprov);
ok(Accessible.ref == 1, "Unexpected refcnt %ld\n", Accessible.ref);
@@ -1101,6 +1138,26 @@ static void test_UiaProviderFromIAccessible(void)
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(!elprov2, "elprov != NULL\n");
+ hr = IRawElementProviderSimple_GetPatternProvider(elprov, UIA_LegacyIAccessiblePatternId, &unk);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(!!unk, "unk == NULL\n");
+ ok(iface_cmp((IUnknown *)elprov, unk), "unk != elprov\n");
+
+ hr = IUnknown_QueryInterface(unk, &IID_ILegacyIAccessibleProvider, (void **)&accprov);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(!!accprov, "accprov == NULL\n");
+
+ hr = ILegacyIAccessibleProvider_get_ChildId(accprov, &cid);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(cid == 1, "cid != CHILDID_SELF\n");
+
+ hr = ILegacyIAccessibleProvider_GetIAccessible(accprov, &acc);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(acc == &Accessible.IAccessible_iface, "acc != &Accessible.IAccessible_iface\n");
+ IAccessible_Release(acc);
+ IUnknown_Release(unk);
+ ILegacyIAccessibleProvider_Release(accprov);
+
IRawElementProviderSimple_Release(elprov);
ok(Accessible.ref == 1, "Unexpected refcnt %ld\n", Accessible.ref);
diff --git a/dlls/uiautomationcore/uia_provider.c b/dlls/uiautomationcore/uia_provider.c
index 700eaae4a2c..f6a1a7d7bf3 100644
--- a/dlls/uiautomationcore/uia_provider.c
+++ b/dlls/uiautomationcore/uia_provider.c
@@ -272,6 +272,7 @@ static LONG msaa_role_to_uia_control_type(LONG role)
*/
struct msaa_provider {
IRawElementProviderSimple IRawElementProviderSimple_iface;
+ ILegacyIAccessibleProvider ILegacyIAccessibleProvider_iface;
LONG refcount;
IAccessible *acc;
@@ -313,9 +314,13 @@ static inline struct msaa_provider *impl_from_msaa_provider(IRawElementProviderS
HRESULT WINAPI msaa_provider_QueryInterface(IRawElementProviderSimple *iface, REFIID riid, void **ppv)
{
+ struct msaa_provider *msaa_prov = impl_from_msaa_provider(iface);
+
*ppv = NULL;
if (IsEqualIID(riid, &IID_IRawElementProviderSimple) || IsEqualIID(riid, &IID_IUnknown))
*ppv = iface;
+ else if (IsEqualIID(riid, &IID_ILegacyIAccessibleProvider))
+ *ppv = &msaa_prov->ILegacyIAccessibleProvider_iface;
else
return E_NOINTERFACE;
@@ -360,9 +365,20 @@ HRESULT WINAPI msaa_provider_get_ProviderOptions(IRawElementProviderSimple *ifac
HRESULT WINAPI msaa_provider_GetPatternProvider(IRawElementProviderSimple *iface,
PATTERNID pattern_id, IUnknown **ret_val)
{
- FIXME("%p, %d, %p: stub!\n", iface, pattern_id, ret_val);
+ TRACE("%p, %d, %p\n", iface, pattern_id, ret_val);
+
*ret_val = NULL;
- return E_NOTIMPL;
+ switch (pattern_id)
+ {
+ case UIA_LegacyIAccessiblePatternId:
+ return IRawElementProviderSimple_QueryInterface(iface, &IID_IUnknown, (void **)ret_val);
+
+ default:
+ FIXME("Unimplemented patternId %d\n", pattern_id);
+ break;
+ }
+
+ return S_OK;
}
HRESULT WINAPI msaa_provider_GetPropertyValue(IRawElementProviderSimple *iface,
@@ -448,6 +464,152 @@ static const IRawElementProviderSimpleVtbl msaa_provider_vtbl = {
msaa_provider_get_HostRawElementProvider,
};
+/*
+ * ILegacyIAccessibleProvider interface for UiaProviderFromIAccessible
+ * providers.
+ */
+static inline struct msaa_provider *impl_from_msaa_acc_provider(ILegacyIAccessibleProvider *iface)
+{
+ return CONTAINING_RECORD(iface, struct msaa_provider, ILegacyIAccessibleProvider_iface);
+}
+
+static HRESULT WINAPI msaa_acc_provider_QueryInterface(ILegacyIAccessibleProvider *iface, REFIID riid, void **ppv)
+{
+ struct msaa_provider *msaa_prov = impl_from_msaa_acc_provider(iface);
+ return IRawElementProviderSimple_QueryInterface(&msaa_prov->IRawElementProviderSimple_iface, riid, ppv);
+}
+
+static ULONG WINAPI msaa_acc_provider_AddRef(ILegacyIAccessibleProvider *iface)
+{
+ struct msaa_provider *msaa_prov = impl_from_msaa_acc_provider(iface);
+ return IRawElementProviderSimple_AddRef(&msaa_prov->IRawElementProviderSimple_iface);
+}
+
+static ULONG WINAPI msaa_acc_provider_Release(ILegacyIAccessibleProvider *iface)
+{
+ struct msaa_provider *msaa_prov = impl_from_msaa_acc_provider(iface);
+ return IRawElementProviderSimple_Release(&msaa_prov->IRawElementProviderSimple_iface);
+}
+
+static HRESULT WINAPI msaa_acc_provider_Select(ILegacyIAccessibleProvider *iface, LONG select_flags)
+{
+ FIXME("%p, %#lx: stub!\n", iface, select_flags);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_DoDefaultAction(ILegacyIAccessibleProvider *iface)
+{
+ FIXME("%p: stub!\n", iface);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_SetValue(ILegacyIAccessibleProvider *iface, LPCWSTR val)
+{
+ FIXME("%p, %p<%s>: stub!\n", iface, val, debugstr_w(val));
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_GetIAccessible(ILegacyIAccessibleProvider *iface,
+ IAccessible **out_acc)
+{
+ struct msaa_provider *msaa_prov = impl_from_msaa_acc_provider(iface);
+
+ TRACE("%p, %p\n", iface, out_acc);
+
+ IAccessible_AddRef(msaa_prov->acc);
+ *out_acc = msaa_prov->acc;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI msaa_acc_provider_get_ChildId(ILegacyIAccessibleProvider *iface, int *out_cid)
+{
+ struct msaa_provider *msaa_prov = impl_from_msaa_acc_provider(iface);
+
+ TRACE("%p, %p\n", iface, out_cid);
+ *out_cid = V_I4(&msaa_prov->cid);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI msaa_acc_provider_get_Name(ILegacyIAccessibleProvider *iface, BSTR *out_name)
+{
+ FIXME("%p, %p: stub!\n", iface, out_name);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_get_Value(ILegacyIAccessibleProvider *iface, BSTR *out_value)
+{
+ FIXME("%p, %p: stub!\n", iface, out_value);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_get_Description(ILegacyIAccessibleProvider *iface,
+ BSTR *out_description)
+{
+ FIXME("%p, %p: stub!\n", iface, out_description);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_get_Role(ILegacyIAccessibleProvider *iface, DWORD *out_role)
+{
+ FIXME("%p, %p: stub!\n", iface, out_role);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_get_State(ILegacyIAccessibleProvider *iface, DWORD *out_state)
+{
+ FIXME("%p, %p: stub!\n", iface, out_state);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_get_Help(ILegacyIAccessibleProvider *iface, BSTR *out_help)
+{
+ FIXME("%p, %p: stub!\n", iface, out_help);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_get_KeyboardShortcut(ILegacyIAccessibleProvider *iface,
+ BSTR *out_kbd_shortcut)
+{
+ FIXME("%p, %p: stub!\n", iface, out_kbd_shortcut);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_GetSelection(ILegacyIAccessibleProvider *iface,
+ SAFEARRAY **out_selected)
+{
+ FIXME("%p, %p: stub!\n", iface, out_selected);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI msaa_acc_provider_get_DefaultAction(ILegacyIAccessibleProvider *iface,
+ BSTR *out_default_action)
+{
+ FIXME("%p, %p: stub!\n", iface, out_default_action);
+ return E_NOTIMPL;
+}
+
+static const ILegacyIAccessibleProviderVtbl msaa_acc_provider_vtbl = {
+ msaa_acc_provider_QueryInterface,
+ msaa_acc_provider_AddRef,
+ msaa_acc_provider_Release,
+ msaa_acc_provider_Select,
+ msaa_acc_provider_DoDefaultAction,
+ msaa_acc_provider_SetValue,
+ msaa_acc_provider_GetIAccessible,
+ msaa_acc_provider_get_ChildId,
+ msaa_acc_provider_get_Name,
+ msaa_acc_provider_get_Value,
+ msaa_acc_provider_get_Description,
+ msaa_acc_provider_get_Role,
+ msaa_acc_provider_get_State,
+ msaa_acc_provider_get_Help,
+ msaa_acc_provider_get_KeyboardShortcut,
+ msaa_acc_provider_GetSelection,
+ msaa_acc_provider_get_DefaultAction,
+};
+
/***********************************************************************
* UiaProviderFromIAccessible (uiautomationcore.@)
*/
@@ -503,6 +665,7 @@ HRESULT WINAPI UiaProviderFromIAccessible(IAccessible *acc, long child_id, DWORD
return E_OUTOFMEMORY;
msaa_prov->IRawElementProviderSimple_iface.lpVtbl = &msaa_provider_vtbl;
+ msaa_prov->ILegacyIAccessibleProvider_iface.lpVtbl = &msaa_acc_provider_vtbl;
msaa_prov->refcount = 1;
msaa_prov->hwnd = hwnd;
variant_init_i4(&msaa_prov->cid, child_id);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/216
More information about the wine-devel
mailing list