Connor McAdams : uiautomationcore: Implement UiaHostProviderFromHwnd.
Alexandre Julliard
julliard at winehq.org
Fri Nov 19 15:45:32 CST 2021
Module: wine
Branch: master
Commit: b5f4511b8eb92e357a4688d886f9228230405d11
URL: https://source.winehq.org/git/wine.git/?a=commit;h=b5f4511b8eb92e357a4688d886f9228230405d11
Author: Connor McAdams <cmcadams at codeweavers.com>
Date: Tue Nov 16 14:32:31 2021 -0500
uiautomationcore: Implement UiaHostProviderFromHwnd.
Signed-off-by: Connor McAdams <cmcadams at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/uiautomationcore/Makefile.in | 2 +-
dlls/uiautomationcore/tests/uiautomation.c | 7 +-
dlls/uiautomationcore/uia_main.c | 134 ++++++++++++++++++++++++++++-
3 files changed, 134 insertions(+), 9 deletions(-)
diff --git a/dlls/uiautomationcore/Makefile.in b/dlls/uiautomationcore/Makefile.in
index 5a72ea144c4..f0973fdec4c 100644
--- a/dlls/uiautomationcore/Makefile.in
+++ b/dlls/uiautomationcore/Makefile.in
@@ -1,6 +1,6 @@
MODULE = uiautomationcore.dll
IMPORTLIB = uiautomationcore
-IMPORTS = uuid ole32
+IMPORTS = uuid ole32 oleaut32 user32
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c
index 52a6648dad2..76d2e06e07e 100644
--- a/dlls/uiautomationcore/tests/uiautomation.c
+++ b/dlls/uiautomationcore/tests/uiautomation.c
@@ -58,17 +58,13 @@ static void test_UiaHostProviderFromHwnd(void)
p = (void *)0xdeadbeef;
hr = UiaHostProviderFromHwnd(NULL, &p);
-todo_wine {
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
ok(p == NULL, "Unexpected instance.\n");
-}
+
p = NULL;
hr = UiaHostProviderFromHwnd(hwnd, &p);
-todo_wine
ok(hr == S_OK, "Failed to get host provider, hr %#x.\n", hr);
-if (hr == S_OK)
-{
p2 = NULL;
hr = UiaHostProviderFromHwnd(hwnd, &p2);
ok(hr == S_OK, "Failed to get host provider, hr %#x.\n", hr);
@@ -80,7 +76,6 @@ if (hr == S_OK)
ok(p2 == NULL, "Unexpected instance.\n");
IRawElementProviderSimple_Release(p);
-}
DestroyWindow(hwnd);
UnregisterClassA("HostProviderFromHwnd class", NULL);
diff --git a/dlls/uiautomationcore/uia_main.c b/dlls/uiautomationcore/uia_main.c
index 174e4756920..44fd42742d9 100644
--- a/dlls/uiautomationcore/uia_main.c
+++ b/dlls/uiautomationcore/uia_main.c
@@ -18,6 +18,7 @@
#define COBJMACROS
+#include "initguid.h"
#include "uiautomation.h"
#include "wine/debug.h"
@@ -145,6 +146,117 @@ static const IUnknownVtbl uia_reserved_obj_vtbl = {
static IUnknown uia_reserved_ns_iface = {&uia_reserved_obj_vtbl};
static IUnknown uia_reserved_ma_iface = {&uia_reserved_obj_vtbl};
+/*
+ * UiaHostProviderFromHwnd IRawElementProviderSimple interface.
+ */
+struct hwnd_host_provider {
+ IRawElementProviderSimple IRawElementProviderSimple_iface;
+ LONG refcount;
+
+ HWND hwnd;
+};
+
+static inline struct hwnd_host_provider *impl_from_hwnd_host_provider(IRawElementProviderSimple *iface)
+{
+ return CONTAINING_RECORD(iface, struct hwnd_host_provider, IRawElementProviderSimple_iface);
+}
+
+HRESULT WINAPI hwnd_host_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 hwnd_host_provider_AddRef(IRawElementProviderSimple *iface)
+{
+ struct hwnd_host_provider *host_prov = impl_from_hwnd_host_provider(iface);
+ ULONG refcount = InterlockedIncrement(&host_prov->refcount);
+
+ TRACE("%p, refcount %d\n", iface, refcount);
+
+ return refcount;
+}
+
+ULONG WINAPI hwnd_host_provider_Release(IRawElementProviderSimple *iface)
+{
+ struct hwnd_host_provider *host_prov = impl_from_hwnd_host_provider(iface);
+ ULONG refcount = InterlockedDecrement(&host_prov->refcount);
+
+ TRACE("%p, refcount %d\n", iface, refcount);
+
+ if (!refcount)
+ heap_free(host_prov);
+
+ return refcount;
+}
+
+HRESULT WINAPI hwnd_host_provider_get_ProviderOptions(IRawElementProviderSimple *iface,
+ enum ProviderOptions *ret_val)
+{
+ TRACE("%p, %p\n", iface, ret_val);
+ *ret_val = ProviderOptions_ServerSideProvider;
+ return S_OK;
+}
+
+HRESULT WINAPI hwnd_host_provider_GetPatternProvider(IRawElementProviderSimple *iface,
+ PATTERNID pattern_id, IUnknown **ret_val)
+{
+ TRACE("%p, %d, %p\n", iface, pattern_id, ret_val);
+ *ret_val = NULL;
+ return S_OK;
+}
+
+HRESULT WINAPI hwnd_host_provider_GetPropertyValue(IRawElementProviderSimple *iface,
+ PROPERTYID prop_id, VARIANT *ret_val)
+{
+ struct hwnd_host_provider *host_prov = impl_from_hwnd_host_provider(iface);
+
+ TRACE("%p, %d, %p\n", iface, prop_id, ret_val);
+
+ VariantInit(ret_val);
+ switch (prop_id)
+ {
+ case UIA_NativeWindowHandlePropertyId:
+ V_VT(ret_val) = VT_I4;
+ V_I4(ret_val) = HandleToUlong(host_prov->hwnd);
+ break;
+
+ case UIA_ProviderDescriptionPropertyId:
+ V_VT(ret_val) = VT_BSTR;
+ V_BSTR(ret_val) = SysAllocString(L"Wine: HWND Provider Proxy");
+ break;
+
+ default:
+ break;
+ }
+
+ return S_OK;
+}
+
+HRESULT WINAPI hwnd_host_provider_get_HostRawElementProvider(IRawElementProviderSimple *iface,
+ IRawElementProviderSimple **ret_val)
+{
+ TRACE("%p, %p\n", iface, ret_val);
+ *ret_val = NULL;
+ return S_OK;
+}
+
+IRawElementProviderSimpleVtbl hwnd_host_provider_vtbl = {
+ hwnd_host_provider_QueryInterface,
+ hwnd_host_provider_AddRef,
+ hwnd_host_provider_Release,
+ hwnd_host_provider_get_ProviderOptions,
+ hwnd_host_provider_GetPatternProvider,
+ hwnd_host_provider_GetPropertyValue,
+ hwnd_host_provider_get_HostRawElementProvider,
+};
+
/***********************************************************************
* UiaClientsAreListening (uiautomationcore.@)
*/
@@ -219,8 +331,26 @@ void WINAPI UiaRegisterProviderCallback(UiaProviderCallback *callback)
HRESULT WINAPI UiaHostProviderFromHwnd(HWND hwnd, IRawElementProviderSimple **provider)
{
- FIXME("(%p, %p): stub\n", hwnd, provider);
- return E_NOTIMPL;
+ struct hwnd_host_provider *host_prov;
+
+ TRACE("(%p, %p)\n", hwnd, provider);
+
+ if (provider)
+ *provider = NULL;
+
+ if (!IsWindow(hwnd) || !provider)
+ return E_INVALIDARG;
+
+ host_prov = heap_alloc(sizeof(*host_prov));
+ if (!host_prov)
+ return E_OUTOFMEMORY;
+
+ host_prov->IRawElementProviderSimple_iface.lpVtbl = &hwnd_host_provider_vtbl;
+ host_prov->refcount = 1;
+ host_prov->hwnd = hwnd;
+ *provider = &host_prov->IRawElementProviderSimple_iface;
+
+ return S_OK;
}
HRESULT WINAPI UiaDisconnectProvider(IRawElementProviderSimple *provider)
More information about the wine-cvs
mailing list