[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-devel
Subject: [PATCH 1/2] uiautomationcore: Implement UiaProviderFromIAccessible.
From: Connor McAdams <cmcadams () codeweavers ! com>
Date: 2022-04-29 13:46:55
Message-ID: 20220429134656.980054-1-cmcadams () codeweavers ! com
[Download RAW message or body]
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/uiautomationcore/Makefile.in | 3 +-
dlls/uiautomationcore/uia_main.c | 1 +
dlls/uiautomationcore/uia_provider.c | 226 ++++++++++++++++++++
dlls/uiautomationcore/uiautomationcore.spec | 2 +-
include/uiautomationcoreapi.h | 4 +
5 files changed, 234 insertions(+), 2 deletions(-)
create mode 100644 dlls/uiautomationcore/uia_provider.c
diff --git a/dlls/uiautomationcore/Makefile.in b/dlls/uiautomationcore/Makefile.in
index f0973fdec4c..bda3614f051 100644
--- a/dlls/uiautomationcore/Makefile.in
+++ b/dlls/uiautomationcore/Makefile.in
@@ -5,4 +5,5 @@ IMPORTS = uuid ole32 oleaut32 user32
EXTRADLLFLAGS = -Wb,--prefer-native
C_SRCS = \
- uia_main.c
+ uia_main.c \
+ uia_provider.c
diff --git a/dlls/uiautomationcore/uia_main.c b/dlls/uiautomationcore/uia_main.c
index a303e71cf76..9f257684333 100644
--- a/dlls/uiautomationcore/uia_main.c
+++ b/dlls/uiautomationcore/uia_main.c
@@ -20,6 +20,7 @@
#include "initguid.h"
#include "uiautomation.h"
+#include "ocidl.h"
#include "wine/debug.h"
#include "wine/heap.h"
diff --git a/dlls/uiautomationcore/uia_provider.c \
b/dlls/uiautomationcore/uia_provider.c new file mode 100644
index 00000000000..790593dbcab
--- /dev/null
+++ b/dlls/uiautomationcore/uia_provider.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2022 Connor McAdams for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+
+#include "uiautomation.h"
+#include "ocidl.h"
+
+#include "wine/debug.h"
+#include "wine/heap.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
+
+static void variant_init_i4(VARIANT *v, int val)
+{
+ V_VT(v) = VT_I4;
+ V_I4(v) = val;
+}
+
+/*
+ * UiaProviderFromIAccessible IRawElementProviderSimple interface.
+ */
+struct msaa_provider {
+ IRawElementProviderSimple IRawElementProviderSimple_iface;
+ LONG refcount;
+
+ IAccessible *acc;
+ VARIANT cid;
+ HWND hwnd;
+};
+
+static inline struct msaa_provider \
*impl_from_msaa_provider(IRawElementProviderSimple *iface) +{
+ return CONTAINING_RECORD(iface, struct msaa_provider, \
IRawElementProviderSimple_iface); +}
+
+HRESULT WINAPI msaa_provider_QueryInterface(IRawElementProviderSimple *iface, REFIID \
riid, void **ppv) +{
+ *ppv = NULL;
+ if (IsEqualIID(riid, &IID_IRawElementProviderSimple) || IsEqualIID(riid, \
&IID_IUnknown)) + *ppv = iface;
+ else
+ return E_NOINTERFACE;
+
+ IRawElementProviderSimple_AddRef(iface);
+ return S_OK;
+}
+
+ULONG WINAPI msaa_provider_AddRef(IRawElementProviderSimple *iface)
+{
+ struct msaa_provider *msaa_prov = impl_from_msaa_provider(iface);
+ ULONG refcount = InterlockedIncrement(&msaa_prov->refcount);
+
+ TRACE("%p, refcount %ld\n", iface, refcount);
+
+ return refcount;
+}
+
+ULONG WINAPI msaa_provider_Release(IRawElementProviderSimple *iface)
+{
+ struct msaa_provider *msaa_prov = impl_from_msaa_provider(iface);
+ ULONG refcount = InterlockedDecrement(&msaa_prov->refcount);
+
+ TRACE("%p, refcount %ld\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IAccessible_Release(msaa_prov->acc);
+ heap_free(msaa_prov);
+ }
+
+ return refcount;
+}
+
+HRESULT WINAPI msaa_provider_get_ProviderOptions(IRawElementProviderSimple *iface,
+ enum ProviderOptions *ret_val)
+{
+ TRACE("%p, %p\n", iface, ret_val);
+ *ret_val = ProviderOptions_ServerSideProvider | ProviderOptions_UseComThreading;
+ return S_OK;
+}
+
+HRESULT WINAPI msaa_provider_GetPatternProvider(IRawElementProviderSimple *iface,
+ PATTERNID pattern_id, IUnknown **ret_val)
+{
+ FIXME("%p, %d, %p: stub!\n", iface, pattern_id, ret_val);
+ *ret_val = NULL;
+ return E_NOTIMPL;
+}
+
+HRESULT WINAPI msaa_provider_GetPropertyValue(IRawElementProviderSimple *iface,
+ PROPERTYID prop_id, VARIANT *ret_val)
+{
+ TRACE("%p, %d, %p\n", iface, prop_id, ret_val);
+
+ VariantInit(ret_val);
+ switch (prop_id)
+ {
+ case UIA_ProviderDescriptionPropertyId:
+ V_VT(ret_val) = VT_BSTR;
+ V_BSTR(ret_val) = SysAllocString(L"Wine: MSAA Proxy");
+ break;
+
+ default:
+ FIXME("Unimplemented propertyId %d\n", prop_id);
+ break;
+ }
+
+ return S_OK;
+}
+
+HRESULT WINAPI msaa_provider_get_HostRawElementProvider(IRawElementProviderSimple \
*iface, + IRawElementProviderSimple **ret_val)
+{
+ FIXME("%p, %p: stub!\n", iface, ret_val);
+ *ret_val = NULL;
+ return E_NOTIMPL;
+}
+
+static const IRawElementProviderSimpleVtbl msaa_provider_vtbl = {
+ msaa_provider_QueryInterface,
+ msaa_provider_AddRef,
+ msaa_provider_Release,
+ msaa_provider_get_ProviderOptions,
+ msaa_provider_GetPatternProvider,
+ msaa_provider_GetPropertyValue,
+ msaa_provider_get_HostRawElementProvider,
+};
+
+/***********************************************************************
+ * UiaProviderFromIAccessible (uiautomationcore.@)
+ */
+HRESULT WINAPI UiaProviderFromIAccessible(IAccessible *acc, long child_id, DWORD \
flags, + IRawElementProviderSimple **elprov)
+{
+ struct msaa_provider *msaa_prov;
+ IServiceProvider *serv_prov;
+ HWND hwnd = NULL;
+ IOleWindow *win;
+ HRESULT hr;
+
+ TRACE("(%p, %ld, %#lx, %p)\n", acc, child_id, flags, elprov);
+
+ if (elprov)
+ *elprov = NULL;
+
+ if (!elprov)
+ return E_POINTER;
+ if (!acc)
+ return E_INVALIDARG;
+
+ if (flags != UIA_PFIA_DEFAULT)
+ {
+ FIXME("unsupported flags %#lx\n", flags);
+ return E_NOTIMPL;
+ }
+
+ hr = IAccessible_QueryInterface(acc, &IID_IServiceProvider, (void \
**)&serv_prov); + if (SUCCEEDED(hr))
+ {
+ IUnknown *unk;
+
+ hr = IServiceProvider_QueryService(serv_prov, &IIS_IsOleaccProxy, \
&IID_IUnknown, (void **)&unk); + if (SUCCEEDED(hr))
+ {
+ WARN("Cannot wrap an oleacc proxy IAccessible!\n");
+ IUnknown_Release(unk);
+ IServiceProvider_Release(serv_prov);
+ return E_INVALIDARG;
+ }
+
+ IServiceProvider_Release(serv_prov);
+ }
+
+ hr = IAccessible_QueryInterface(acc, &IID_IOleWindow, (void **)&win);
+ if (SUCCEEDED(hr))
+ {
+ hr = IOleWindow_GetWindow(win, &hwnd);
+ if (FAILED(hr))
+ hwnd = NULL;
+ IOleWindow_Release(win);
+ }
+
+ if (!IsWindow(hwnd))
+ {
+ VARIANT v, cid;
+
+ VariantInit(&v);
+ variant_init_i4(&cid, CHILDID_SELF);
+ hr = IAccessible_accNavigate(acc, 10, cid, &v);
+ if (SUCCEEDED(hr) && V_VT(&v) == VT_I4)
+ hwnd = ULongToHandle(V_I4(&v));
+
+ if (!IsWindow(hwnd))
+ return E_FAIL;
+ }
+
+ msaa_prov = heap_alloc(sizeof(*msaa_prov));
+ if (!msaa_prov)
+ return E_OUTOFMEMORY;
+
+ msaa_prov->IRawElementProviderSimple_iface.lpVtbl = &msaa_provider_vtbl;
+ msaa_prov->refcount = 1;
+ msaa_prov->hwnd = hwnd;
+ variant_init_i4(&msaa_prov->cid, child_id);
+ msaa_prov->acc = acc;
+ IAccessible_AddRef(acc);
+ *elprov = &msaa_prov->IRawElementProviderSimple_iface;
+
+ return S_OK;
+}
diff --git a/dlls/uiautomationcore/uiautomationcore.spec \
b/dlls/uiautomationcore/uiautomationcore.spec index 82071bd2317..70d78d52085 100644
--- a/dlls/uiautomationcore/uiautomationcore.spec
+++ b/dlls/uiautomationcore/uiautomationcore.spec
@@ -83,7 +83,7 @@
@ stub UiaNodeRelease
@ stub UiaPatternRelease
#@ stub UiaProviderForNonClient
-#@ stub UiaProviderFromIAccessible
+@ stdcall UiaProviderFromIAccessible(ptr long long ptr)
@ stub UiaRaiseAsyncContentLoadedEvent
@ stdcall UiaRaiseAutomationEvent(ptr long)
@ stdcall UiaRaiseAutomationPropertyChangedEvent(ptr long int128 int128)
diff --git a/include/uiautomationcoreapi.h b/include/uiautomationcoreapi.h
index 563d5c602bd..22b3888dc6e 100644
--- a/include/uiautomationcoreapi.h
+++ b/include/uiautomationcoreapi.h
@@ -34,6 +34,9 @@ extern "C" {
#define UiaAppendRuntimeId 3
#define UiaRootObjectId -25
+#define UIA_PFIA_DEFAULT 0x00
+#define UIA_PFIA_UNWRAP_BRIDGE 0x01
+
DECLARE_HANDLE(HUIANODE);
DECLARE_HANDLE(HUIAPATTERNOBJECT);
DECLARE_HANDLE(HUIATEXTRANGE);
@@ -71,6 +74,7 @@ void WINAPI UiaRegisterProviderCallback(UiaProviderCallback \
*pCallback); LRESULT WINAPI UiaReturnRawElementProvider(HWND hwnd, WPARAM wParam, \
LPARAM lParam, IRawElementProviderSimple *elprov); BOOL WINAPI \
UiaTextRangeRelease(HUIATEXTRANGE hobj); HRESULT WINAPI UiaHostProviderFromHwnd(HWND \
hwnd, IRawElementProviderSimple **elprov); +HRESULT WINAPI \
UiaProviderFromIAccessible(IAccessible *acc, long child_id, DWORD flags, \
IRawElementProviderSimple **elprov);
#ifdef __cplusplus
}
--
2.25.1
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic