Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
f0525a5f
Commit
f0525a5f
authored
Aug 21, 2023
by
Connor McAdams
Committed by
Alexandre Julliard
Sep 18, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Implement UiaHasServerSideProvider.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
815e3889
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
105 additions
and
16 deletions
+105
-16
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+59
-0
uia_client.c
dlls/uiautomationcore/uia_client.c
+38
-16
uia_private.h
dlls/uiautomationcore/uia_private.h
+8
-0
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
f0525a5f
...
...
@@ -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"
);
...
...
dlls/uiautomationcore/uia_client.c
View file @
f0525a5f
...
...
@@ -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
;
*
huia
node
=
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,12 +2603,22 @@ HRESULT WINAPI UiaNodeFromHandle(HWND hwnd, HUIANODE *huianode)
return
hr
;
}
*
huia
node
=
(
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.@)
*/
HRESULT
WINAPI
UiaGetRootNode
(
HUIANODE
*
huianode
)
...
...
@@ -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
;
...
...
dlls/uiautomationcore/uia_private.h
View file @
f0525a5f
...
...
@@ -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
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment