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