Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- 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..d1d75356063 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); }
+struct hwnd_provider { + IRawElementProviderSimple IRawElementProviderSimple_iface; + LONG ref; + + HWND hwnd; +}; + +static inline struct hwnd_provider *impl_from_hwnd_provider(IRawElementProviderSimple *iface) +{ + return CONTAINING_RECORD(iface, struct hwnd_provider, IRawElementProviderSimple_iface); +} + +HRESULT WINAPI hwnd_provider_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 hwnd_provider_AddRef(IRawElementProviderSimple *iface) +{ + struct hwnd_provider *hwnd_prov = impl_from_hwnd_provider(iface); + return InterlockedIncrement(&hwnd_prov->ref); +} + +ULONG WINAPI hwnd_provider_Release(IRawElementProviderSimple *iface) +{ + struct hwnd_provider *hwnd_prov = impl_from_hwnd_provider(iface); + ULONG ref = InterlockedDecrement(&hwnd_prov->ref); + + if (!ref) + heap_free(hwnd_prov); + + return ref; +} + +HRESULT WINAPI hwnd_provider_get_ProviderOptions(IRawElementProviderSimple *iface, + enum ProviderOptions *ret_val) +{ + *ret_val = ProviderOptions_ServerSideProvider; + return S_OK; +} + +HRESULT WINAPI hwnd_provider_GetPatternProvider(IRawElementProviderSimple *iface, + PATTERNID pattern_id, IUnknown **ret_val) +{ + *ret_val = NULL; + return S_OK; +} + +HRESULT WINAPI hwnd_provider_GetPropertyValue(IRawElementProviderSimple *iface, + PROPERTYID property_id, VARIANT *ret_val) +{ + struct hwnd_provider *hwnd_prov = impl_from_hwnd_provider(iface); + + switch (property_id) + { + case UIA_NativeWindowHandlePropertyId: + V_VT(ret_val) = VT_I4; + V_I4(ret_val) = HandleToUlong(hwnd_prov->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 hwnd_provider_get_HostRawElementProvider(IRawElementProviderSimple *iface, + IRawElementProviderSimple **ret_val) +{ + *ret_val = NULL; + return S_OK; +} + +IRawElementProviderSimpleVtbl hwnd_provider_vtbl = { + hwnd_provider_QueryInterface, + hwnd_provider_AddRef, + hwnd_provider_Release, + hwnd_provider_get_ProviderOptions, + hwnd_provider_GetPatternProvider, + hwnd_provider_GetPropertyValue, + hwnd_provider_get_HostRawElementProvider, +}; + HRESULT WINAPI UiaHostProviderFromHwnd(HWND hwnd, IRawElementProviderSimple **provider) { - FIXME("(%p, %p): stub\n", hwnd, provider); - return E_NOTIMPL; + struct hwnd_provider *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 = &hwnd_provider_vtbl; + hwnd_prov->ref = 1; + hwnd_prov->hwnd = hwnd; + *provider = &hwnd_prov->IRawElementProviderSimple_iface; + + return S_OK; }
HRESULT WINAPI UiaDisconnectProvider(IRawElementProviderSimple *provider)