mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
uiautomationcore: Implement UiaHasServerSideProvider.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
parent
815e3889c6
commit
f0525a5ff6
3 changed files with 105 additions and 16 deletions
|
@ -15302,6 +15302,64 @@ static void test_UiaAddEvent(const char *name)
|
|||
UnregisterClassA("UiaAddEvent test class", NULL);
|
||||
}
|
||||
|
||||
static const struct prov_method_sequence serverside_prov_seq[] = {
|
||||
NODE_CREATE_SEQ2(&Provider),
|
||||
/* Windows 10+ calls this. */
|
||||
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_OPTIONAL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void test_UiaHasServerSideProvider(void)
|
||||
{
|
||||
BOOL ret_val;
|
||||
HWND hwnd;
|
||||
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
hwnd = create_test_hwnd("UiaHasServerSideProvider test class");
|
||||
|
||||
/* NULL hwnd. */
|
||||
ret_val = UiaHasServerSideProvider(NULL);
|
||||
ok(!ret_val, "UiaHasServerSideProvider returned TRUE\n");
|
||||
|
||||
/* Desktop window has no serverside providers. */
|
||||
UiaRegisterProviderCallback(test_uia_provider_callback);
|
||||
ret_val = UiaHasServerSideProvider(GetDesktopWindow());
|
||||
ok(!ret_val, "UiaHasServerSideProvider returned TRUE\n");
|
||||
|
||||
/* No provider to pass to UiaReturnRawElementProvider, returns FALSE. */
|
||||
prov_root = NULL;
|
||||
SET_EXPECT(winproc_GETOBJECT_UiaRoot);
|
||||
ret_val = UiaHasServerSideProvider(hwnd);
|
||||
ok(!ret_val, "UiaHasServerSideProvider returned TRUE\n");
|
||||
CHECK_CALLED(winproc_GETOBJECT_UiaRoot);
|
||||
|
||||
/*
|
||||
* Provider passed to UiaReturnRawElementProvider returns a failure from
|
||||
* get_ProviderOptions. Returns FALSE.
|
||||
*/
|
||||
initialize_provider(&Provider, 0, hwnd, TRUE);
|
||||
prov_root = &Provider.IRawElementProviderSimple_iface;
|
||||
SET_EXPECT(winproc_GETOBJECT_UiaRoot);
|
||||
ret_val = UiaHasServerSideProvider(hwnd);
|
||||
ok(!ret_val, "UiaHasServerSideProvider returned TRUE\n");
|
||||
ok_method_sequence(node_from_hwnd1, NULL);
|
||||
CHECK_CALLED(winproc_GETOBJECT_UiaRoot);
|
||||
|
||||
/* Successfully return a provider from UiaReturnRawElementProvider. */
|
||||
initialize_provider(&Provider, ProviderOptions_ServerSideProvider, hwnd, TRUE);
|
||||
SET_EXPECT(winproc_GETOBJECT_UiaRoot);
|
||||
ret_val = UiaHasServerSideProvider(hwnd);
|
||||
ok(ret_val, "UiaHasServerSideProvider returned FALSE\n");
|
||||
ok_method_sequence(serverside_prov_seq, "serverside_prov_seq");
|
||||
CHECK_CALLED(winproc_GETOBJECT_UiaRoot);
|
||||
|
||||
UiaRegisterProviderCallback(NULL);
|
||||
prov_root = NULL;
|
||||
CoUninitialize();
|
||||
DestroyWindow(hwnd);
|
||||
UnregisterClassA("UiaHasServerSideProvider test class", NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Once a process returns a UI Automation provider with
|
||||
* UiaReturnRawElementProvider it ends up in an implicit MTA until exit. This
|
||||
|
@ -15375,6 +15433,7 @@ START_TEST(uiautomation)
|
|||
test_UiaGetRootNode();
|
||||
test_UiaNodeFromFocus();
|
||||
test_UiaAddEvent(argv[0]);
|
||||
test_UiaHasServerSideProvider();
|
||||
if (uia_dll)
|
||||
{
|
||||
pUiaProviderFromIAccessible = (void *)GetProcAddress(uia_dll, "UiaProviderFromIAccessible");
|
||||
|
|
|
@ -597,7 +597,7 @@ static struct uia_node *unsafe_impl_from_IWineUiaNode(IWineUiaNode *iface)
|
|||
return CONTAINING_RECORD(iface, struct uia_node, IWineUiaNode_iface);
|
||||
}
|
||||
|
||||
static HRESULT create_uia_node(struct uia_node **out_node)
|
||||
static HRESULT create_uia_node(struct uia_node **out_node, int node_flags)
|
||||
{
|
||||
struct uia_node *node;
|
||||
|
||||
|
@ -609,6 +609,10 @@ static HRESULT create_uia_node(struct uia_node **out_node)
|
|||
list_init(&node->prov_thread_list_entry);
|
||||
list_init(&node->node_map_list_entry);
|
||||
node->ref = 1;
|
||||
if (node_flags & NODE_FLAG_IGNORE_CLIENTSIDE_HWND_PROVS)
|
||||
node->ignore_clientside_hwnd_provs = TRUE;
|
||||
if (node_flags & NODE_FLAG_NO_PREPARE)
|
||||
node->no_prepare = TRUE;
|
||||
|
||||
*out_node = node;
|
||||
return S_OK;
|
||||
|
@ -620,6 +624,9 @@ static HRESULT prepare_uia_node(struct uia_node *node)
|
|||
int i, prov_idx;
|
||||
HRESULT hr;
|
||||
|
||||
if (node->no_prepare)
|
||||
return S_OK;
|
||||
|
||||
/* Get the provider index for the provider that created the node. */
|
||||
for (i = prov_idx = 0; i < PROV_TYPE_COUNT; i++)
|
||||
{
|
||||
|
@ -714,7 +721,7 @@ HRESULT clone_uia_node(HUIANODE in_node, HUIANODE *out_node)
|
|||
}
|
||||
}
|
||||
|
||||
hr = create_uia_node(&node);
|
||||
hr = create_uia_node(&node, 0);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
|
@ -1980,7 +1987,7 @@ HRESULT create_uia_node_from_elprov(IRawElementProviderSimple *elprov, HUIANODE
|
|||
else
|
||||
prov_type = PROV_TYPE_MAIN;
|
||||
|
||||
hr = create_uia_node(&node);
|
||||
hr = create_uia_node(&node, 0);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
|
@ -2503,7 +2510,7 @@ HRESULT uia_node_from_lresult(LRESULT lr, HUIANODE *huianode)
|
|||
|
||||
*huianode = NULL;
|
||||
|
||||
hr = create_uia_node(&node);
|
||||
hr = create_uia_node(&node, 0);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
|
@ -2564,25 +2571,20 @@ static HRESULT uia_get_provider_from_hwnd(struct uia_node *node)
|
|||
return SendMessageW(client_thread.hwnd, WM_UIA_CLIENT_GET_NODE_PROV, (WPARAM)&args, (LPARAM)node);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* UiaNodeFromHandle (uiautomationcore.@)
|
||||
*/
|
||||
HRESULT WINAPI UiaNodeFromHandle(HWND hwnd, HUIANODE *huianode)
|
||||
static HRESULT create_uia_node_from_hwnd(HWND hwnd, HUIANODE *out_node, int node_flags)
|
||||
{
|
||||
struct uia_node *node;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p, %p)\n", hwnd, huianode);
|
||||
|
||||
if (!huianode)
|
||||
if (!out_node)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*huianode = NULL;
|
||||
*out_node = NULL;
|
||||
|
||||
if (!IsWindow(hwnd))
|
||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||
|
||||
hr = create_uia_node(&node);
|
||||
hr = create_uia_node(&node, node_flags);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
|
@ -2601,11 +2603,21 @@ HRESULT WINAPI UiaNodeFromHandle(HWND hwnd, HUIANODE *huianode)
|
|||
return hr;
|
||||
}
|
||||
|
||||
*huianode = (void *)&node->IWineUiaNode_iface;
|
||||
*out_node = (void *)&node->IWineUiaNode_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* UiaNodeFromHandle (uiautomationcore.@)
|
||||
*/
|
||||
HRESULT WINAPI UiaNodeFromHandle(HWND hwnd, HUIANODE *huianode)
|
||||
{
|
||||
TRACE("(%p, %p)\n", hwnd, huianode);
|
||||
|
||||
return create_uia_node_from_hwnd(hwnd, huianode, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* UiaGetRootNode (uiautomationcore.@)
|
||||
*/
|
||||
|
@ -2621,8 +2633,15 @@ HRESULT WINAPI UiaGetRootNode(HUIANODE *huianode)
|
|||
*/
|
||||
BOOL WINAPI UiaHasServerSideProvider(HWND hwnd)
|
||||
{
|
||||
FIXME("(%p): stub\n", hwnd);
|
||||
return FALSE;
|
||||
HUIANODE node = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)\n", hwnd);
|
||||
|
||||
hr = create_uia_node_from_hwnd(hwnd, &node, NODE_FLAG_NO_PREPARE | NODE_FLAG_IGNORE_CLIENTSIDE_HWND_PROVS);
|
||||
UiaNodeRelease(node);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
static HRESULT get_focused_uia_node(HUIANODE in_node, HUIANODE *out_node)
|
||||
|
@ -3026,6 +3045,9 @@ static HRESULT uia_get_clientside_provider(struct uia_node *node, int prov_type,
|
|||
VARTYPE vt;
|
||||
HRESULT hr;
|
||||
|
||||
if (node->ignore_clientside_hwnd_provs)
|
||||
return S_OK;
|
||||
|
||||
if (!(sa = uia_provider_callback(node->hwnd, prov_type)))
|
||||
return S_OK;
|
||||
|
||||
|
|
|
@ -54,6 +54,11 @@ enum uia_node_prov_type {
|
|||
PROV_TYPE_COUNT,
|
||||
};
|
||||
|
||||
enum uia_node_flags {
|
||||
NODE_FLAG_IGNORE_CLIENTSIDE_HWND_PROVS = 0x01,
|
||||
NODE_FLAG_NO_PREPARE = 0x02,
|
||||
};
|
||||
|
||||
struct uia_node {
|
||||
IWineUiaNode IWineUiaNode_iface;
|
||||
LONG ref;
|
||||
|
@ -65,9 +70,12 @@ struct uia_node {
|
|||
int creator_prov_idx;
|
||||
|
||||
HWND hwnd;
|
||||
BOOL no_prepare;
|
||||
BOOL nested_node;
|
||||
BOOL disconnected;
|
||||
int creator_prov_type;
|
||||
BOOL ignore_clientside_hwnd_provs;
|
||||
|
||||
struct list prov_thread_list_entry;
|
||||
struct list node_map_list_entry;
|
||||
struct uia_provider_thread_map_entry *map;
|
||||
|
|
Loading…
Reference in a new issue