[PATCH v3 1/2] uiautomationcore: Implement UiaHostProviderFromHwnd.

Connor McAdams cmcadams at codeweavers.com
Mon Sep 20 22:53:01 CDT 2021


Signed-off-by: Connor McAdams <cmcadams at codeweavers.com>
---
-v3: Match recent Windows behavior, fix tests for earlier Windows
behavior.

 dlls/uiautomationcore/Makefile.in |   1 +
 dlls/uiautomationcore/uia_main.c  | 125 +++++++++++++++++++++++++++++-
 2 files changed, 124 insertions(+), 2 deletions(-)

diff --git a/dlls/uiautomationcore/Makefile.in b/dlls/uiautomationcore/Makefile.in
index 71ea7b99c94..1f6ad85c24f 100644
--- a/dlls/uiautomationcore/Makefile.in
+++ b/dlls/uiautomationcore/Makefile.in
@@ -1,5 +1,6 @@
 MODULE = uiautomationcore.dll
 IMPORTLIB = uiautomationcore
+IMPORTS   = oleaut32 user32
 
 EXTRADLLFLAGS = -Wb,--prefer-native
 
diff --git a/dlls/uiautomationcore/uia_main.c b/dlls/uiautomationcore/uia_main.c
index 2dada95af80..8d4f91947aa 100644
--- a/dlls/uiautomationcore/uia_main.c
+++ b/dlls/uiautomationcore/uia_main.c
@@ -16,9 +16,14 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define COBJMACROS
+
+#include "windows.h"
+#include "initguid.h"
 #include "uiautomation.h"
 
 #include "wine/debug.h"
+#include "wine/heap.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
 
@@ -84,10 +89,126 @@ void WINAPI UiaRegisterProviderCallback(UiaProviderCallback *callback)
     FIXME("(%p): stub\n", callback);
 }
 
+typedef struct {
+    IRawElementProviderSimple IRawElementProviderSimple_iface;
+    LONG ref;
+
+    HWND hwnd;
+} HwndProvider;
+
+static inline HwndProvider *impl_from_HwndProvider(IRawElementProviderSimple *iface)
+{
+    return CONTAINING_RECORD(iface, HwndProvider, IRawElementProviderSimple_iface);
+}
+
+HRESULT WINAPI HwndProvider_QueryInterface(IRawElementProviderSimple *iface, REFIID riid, void **ppv)
+{
+    if (IsEqualIID(riid, &IID_IRawElementProviderSimple) ||
+            IsEqualIID(riid, &IID_IUnknown))
+        *ppv = iface;
+    else
+    {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IRawElementProviderSimple_AddRef(iface);
+    return S_OK;
+}
+
+ULONG WINAPI HwndProvider_AddRef(IRawElementProviderSimple *iface)
+{
+    HwndProvider *This = impl_from_HwndProvider(iface);
+    return InterlockedIncrement(&This->ref);
+}
+
+ULONG WINAPI HwndProvider_Release(IRawElementProviderSimple *iface)
+{
+    HwndProvider *This = impl_from_HwndProvider(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    if (!ref)
+        heap_free(This);
+
+    return ref;
+}
+
+HRESULT WINAPI HwndProvider_get_ProviderOptions(IRawElementProviderSimple *iface,
+        enum ProviderOptions *ret_val)
+{
+    *ret_val = ProviderOptions_ServerSideProvider;
+    return S_OK;
+}
+
+HRESULT WINAPI HwndProvider_GetPatternProvider(IRawElementProviderSimple *iface,
+        PATTERNID pattern_id, IUnknown **ret_val)
+{
+    *ret_val = NULL;
+    return S_OK;
+}
+
+HRESULT WINAPI HwndProvider_GetPropertyValue(IRawElementProviderSimple *iface,
+        PROPERTYID property_id, VARIANT *ret_val)
+{
+    HwndProvider *This = impl_from_HwndProvider(iface);
+
+    switch (property_id)
+    {
+    case UIA_NativeWindowHandlePropertyId:
+        V_VT(ret_val) = VT_I4;
+        V_I4(ret_val) = ((long)This->hwnd);
+        break;
+
+    case UIA_ProviderDescriptionPropertyId:
+        V_VT(ret_val) = VT_BSTR;
+        V_BSTR(ret_val) = SysAllocString(L"Wine: HWND Provider Proxy");
+        break;
+
+    default:
+        V_VT(ret_val) = VT_EMPTY;
+        break;
+    }
+
+    return S_OK;
+}
+
+HRESULT WINAPI HwndProvider_get_HostRawElementProvider(IRawElementProviderSimple *iface,
+        IRawElementProviderSimple **ret_val)
+{
+    *ret_val = NULL;
+    return S_OK;
+}
+
+IRawElementProviderSimpleVtbl HwndProviderVtbl = {
+    HwndProvider_QueryInterface,
+    HwndProvider_AddRef,
+    HwndProvider_Release,
+    HwndProvider_get_ProviderOptions,
+    HwndProvider_GetPatternProvider,
+    HwndProvider_GetPropertyValue,
+    HwndProvider_get_HostRawElementProvider,
+};
+
 HRESULT WINAPI UiaHostProviderFromHwnd(HWND hwnd, IRawElementProviderSimple **provider)
 {
-    FIXME("(%p, %p): stub\n", hwnd, provider);
-    return E_NOTIMPL;
+    HwndProvider *hwnd_prov;
+
+    TRACE("(%p, %p)\n", hwnd, provider);
+
+    *provider = NULL;
+    if (!IsWindow(hwnd))
+        return E_INVALIDARG;
+
+    hwnd_prov = heap_alloc_zero(sizeof(*hwnd_prov));
+    if (!hwnd_prov)
+        return E_OUTOFMEMORY;
+
+    hwnd_prov->IRawElementProviderSimple_iface.lpVtbl = &HwndProviderVtbl;
+    hwnd_prov->ref = 1;
+    hwnd_prov->hwnd = hwnd;
+    *provider = &hwnd_prov->IRawElementProviderSimple_iface;
+
+    return S_OK;
 }
 
 HRESULT WINAPI UiaDisconnectProvider(IRawElementProviderSimple *provider)
-- 
2.25.1




More information about the wine-devel mailing list