Module: wine Branch: master Commit: 32814b87857b995d824b8a4832e1b114889bbb28 URL: https://gitlab.winehq.org/wine/wine/-/commit/32814b87857b995d824b8a4832e1b11...
Author: Connor McAdams cmcadams@codeweavers.com Date: Tue Aug 29 09:42:55 2023 -0400
uiautomationcore: Add stub IRawElementProviderFragmentRoot implementation for MSAA providers.
Signed-off-by: Connor McAdams cmcadams@codeweavers.com
---
dlls/uiautomationcore/tests/uiautomation.c | 25 +++++++++++++ dlls/uiautomationcore/uia_provider.c | 56 ++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index 9a13a5bb7a8..408e90c2046 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -431,6 +431,20 @@ static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2) return cmp; }
+#define test_implements_interface( unk, iid, exp_implemented ) \ + test_implements_interface_( ((IUnknown *)(unk)), (iid), (exp_implemented), __FILE__, __LINE__) +static void test_implements_interface_(IUnknown *unk, const GUID *iid, BOOL exp_implemented, const char *file, int line) +{ + IUnknown *unk2 = NULL; + HRESULT hr; + + hr = IUnknown_QueryInterface(unk, iid, (void **)&unk2); + ok_(file, line)(hr == (exp_implemented ? S_OK : E_NOINTERFACE), "Unexpected hr %#lx\n", hr); + ok_(file, line)(!!unk2 == exp_implemented, "Unexpected iface %p\n", unk2); + if (unk2) + IUnknown_Release(unk2); +} + #define DEFINE_ACC_METHOD_EXPECT(method) \ int expect_ ## method , called_ ## method
@@ -4435,6 +4449,8 @@ static void test_UiaProviderFromIAccessible(void) broken(prov_opt == ProviderOptions_ClientSideProvider), /* Windows < 10 1507 */ "Unexpected provider options %#x\n", prov_opt);
+ test_implements_interface(elprov, &IID_IRawElementProviderFragmentRoot, TRUE); + hr = IRawElementProviderSimple_GetPropertyValue(elprov, UIA_ProviderDescriptionPropertyId, &v); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v)); @@ -4468,6 +4484,9 @@ static void test_UiaProviderFromIAccessible(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(Accessible.ref == 2, "Unexpected refcnt %ld\n", Accessible.ref);
+ /* Even simple children implement IRawElementProviderFragmentRoot. */ + test_implements_interface(elprov, &IID_IRawElementProviderFragmentRoot, TRUE); + /* * Simple child element (IAccessible without CHILDID_SELF) cannot be root * IAccessible. No checks against the root HWND IAccessible will be done. @@ -4527,6 +4546,12 @@ static void test_UiaProviderFromIAccessible(void) CHECK_ACC_METHOD_CALLED(&Accessible, accLocation); CHECK_ACC_METHOD_CALLED(&Accessible, get_accName);
+ /* + * Interface that isn't the HWND root, still implements + * IRawElementProviderFragmentRoot. + */ + test_implements_interface(elprov, &IID_IRawElementProviderFragmentRoot, TRUE); + /* Second call won't send WM_GETOBJECT. */ elprov2 = (void *)0xdeadbeef; hr = IRawElementProviderSimple_get_HostRawElementProvider(elprov, &elprov2); diff --git a/dlls/uiautomationcore/uia_provider.c b/dlls/uiautomationcore/uia_provider.c index b16077b607c..abf97a60f08 100644 --- a/dlls/uiautomationcore/uia_provider.c +++ b/dlls/uiautomationcore/uia_provider.c @@ -486,6 +486,7 @@ static LONG msaa_role_to_uia_control_type(LONG role) struct msaa_provider { IRawElementProviderSimple IRawElementProviderSimple_iface; IRawElementProviderFragment IRawElementProviderFragment_iface; + IRawElementProviderFragmentRoot IRawElementProviderFragmentRoot_iface; ILegacyIAccessibleProvider ILegacyIAccessibleProvider_iface; LONG refcount;
@@ -539,6 +540,8 @@ HRESULT WINAPI msaa_provider_QueryInterface(IRawElementProviderSimple *iface, RE *ppv = iface; else if (IsEqualIID(riid, &IID_IRawElementProviderFragment)) *ppv = &msaa_prov->IRawElementProviderFragment_iface; + else if (IsEqualIID(riid, &IID_IRawElementProviderFragmentRoot)) + *ppv = &msaa_prov->IRawElementProviderFragmentRoot_iface; else if (IsEqualIID(riid, &IID_ILegacyIAccessibleProvider)) *ppv = &msaa_prov->ILegacyIAccessibleProvider_iface; else @@ -976,6 +979,58 @@ static const IRawElementProviderFragmentVtbl msaa_fragment_vtbl = { msaa_fragment_get_FragmentRoot, };
+/* + * IRawElementProviderFragmentRoot interface for UiaProviderFromIAccessible + * providers. + */ +static inline struct msaa_provider *impl_from_msaa_fragment_root(IRawElementProviderFragmentRoot *iface) +{ + return CONTAINING_RECORD(iface, struct msaa_provider, IRawElementProviderFragmentRoot_iface); +} + +static HRESULT WINAPI msaa_fragment_root_QueryInterface(IRawElementProviderFragmentRoot *iface, REFIID riid, + void **ppv) +{ + struct msaa_provider *msaa_prov = impl_from_msaa_fragment_root(iface); + return IRawElementProviderSimple_QueryInterface(&msaa_prov->IRawElementProviderSimple_iface, riid, ppv); +} + +static ULONG WINAPI msaa_fragment_root_AddRef(IRawElementProviderFragmentRoot *iface) +{ + struct msaa_provider *msaa_prov = impl_from_msaa_fragment_root(iface); + return IRawElementProviderSimple_AddRef(&msaa_prov->IRawElementProviderSimple_iface); +} + +static ULONG WINAPI msaa_fragment_root_Release(IRawElementProviderFragmentRoot *iface) +{ + struct msaa_provider *msaa_prov = impl_from_msaa_fragment_root(iface); + return IRawElementProviderSimple_Release(&msaa_prov->IRawElementProviderSimple_iface); +} + +static HRESULT WINAPI msaa_fragment_root_ElementProviderFromPoint(IRawElementProviderFragmentRoot *iface, + double x, double y, IRawElementProviderFragment **ret_val) +{ + FIXME("%p, %f, %f, %p: stub!\n", iface, x, y, ret_val); + *ret_val = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI msaa_fragment_root_GetFocus(IRawElementProviderFragmentRoot *iface, + IRawElementProviderFragment **ret_val) +{ + FIXME("%p, %p: stub!\n", iface, ret_val); + *ret_val = NULL; + return E_NOTIMPL; +} + +static const IRawElementProviderFragmentRootVtbl msaa_fragment_root_vtbl = { + msaa_fragment_root_QueryInterface, + msaa_fragment_root_AddRef, + msaa_fragment_root_Release, + msaa_fragment_root_ElementProviderFromPoint, + msaa_fragment_root_GetFocus, +}; + /* * ILegacyIAccessibleProvider interface for UiaProviderFromIAccessible * providers. @@ -1143,6 +1198,7 @@ HRESULT create_msaa_provider(IAccessible *acc, LONG child_id, HWND hwnd, BOOL kn
msaa_prov->IRawElementProviderSimple_iface.lpVtbl = &msaa_provider_vtbl; msaa_prov->IRawElementProviderFragment_iface.lpVtbl = &msaa_fragment_vtbl; + msaa_prov->IRawElementProviderFragmentRoot_iface.lpVtbl = &msaa_fragment_root_vtbl; msaa_prov->ILegacyIAccessibleProvider_iface.lpVtbl = &msaa_acc_provider_vtbl; msaa_prov->refcount = 1; variant_init_i4(&msaa_prov->cid, child_id);