[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