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
12dfa742
Commit
12dfa742
authored
May 23, 2022
by
Connor McAdams
Committed by
Alexandre Julliard
Jun 10, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Implement get_HostRawElementProvider for MSAA providers.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
de280569
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
188 additions
and
2 deletions
+188
-2
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+0
-0
uia_provider.c
dlls/uiautomationcore/uia_provider.c
+188
-2
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
12dfa742
This diff is collapsed.
Click to expand it.
dlls/uiautomationcore/uia_provider.c
View file @
12dfa742
...
...
@@ -23,9 +23,12 @@
#include "wine/debug.h"
#include "wine/heap.h"
#include "initguid.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
uiautomation
);
DEFINE_GUID
(
SID_AccFromDAWrapper
,
0x33f139ee
,
0xe509
,
0x47f7
,
0xbf
,
0x39
,
0x83
,
0x76
,
0x44
,
0xf7
,
0x45
,
0x76
);
static
void
variant_init_i4
(
VARIANT
*
v
,
int
val
)
{
V_VT
(
v
)
=
VT_I4
;
...
...
@@ -51,6 +54,157 @@ static BOOL msaa_check_acc_state(IAccessible *acc, VARIANT cid, ULONG flag)
return
FALSE
;
}
static
IAccessible
*
msaa_acc_da_unwrap
(
IAccessible
*
acc
)
{
IServiceProvider
*
sp
;
IAccessible
*
acc2
;
HRESULT
hr
;
hr
=
IAccessible_QueryInterface
(
acc
,
&
IID_IServiceProvider
,
(
void
**
)
&
sp
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IServiceProvider_QueryService
(
sp
,
&
SID_AccFromDAWrapper
,
&
IID_IAccessible
,
(
void
**
)
&
acc2
);
IServiceProvider_Release
(
sp
);
}
if
(
SUCCEEDED
(
hr
)
&&
acc2
)
return
acc2
;
IAccessible_AddRef
(
acc
);
return
acc
;
}
/*
* Compare role, state, child count, and location properties of the two
* IAccessibles. If all four are successfully retrieved and are equal, this is
* considered a match.
*/
static
HRESULT
msaa_acc_prop_match
(
IAccessible
*
acc
,
IAccessible
*
acc2
)
{
BOOL
role_match
,
state_match
,
child_count_match
,
location_match
;
LONG
child_count
[
2
],
left
[
2
],
top
[
2
],
width
[
2
],
height
[
2
];
VARIANT
cid
,
v
,
v2
;
HRESULT
hr
,
hr2
;
role_match
=
state_match
=
child_count_match
=
location_match
=
FALSE
;
variant_init_i4
(
&
cid
,
CHILDID_SELF
);
hr
=
IAccessible_get_accRole
(
acc
,
cid
,
&
v
);
if
(
SUCCEEDED
(
hr
)
&&
(
V_VT
(
&
v
)
==
VT_I4
))
{
VariantInit
(
&
v2
);
hr
=
IAccessible_get_accRole
(
acc2
,
cid
,
&
v2
);
if
(
SUCCEEDED
(
hr
)
&&
(
V_VT
(
&
v2
)
==
VT_I4
))
{
if
(
V_I4
(
&
v
)
!=
V_I4
(
&
v2
))
return
E_FAIL
;
role_match
=
TRUE
;
}
}
VariantInit
(
&
v
);
hr
=
IAccessible_get_accState
(
acc
,
cid
,
&
v
);
if
(
SUCCEEDED
(
hr
)
&&
(
V_VT
(
&
v
)
==
VT_I4
))
{
VariantInit
(
&
v2
);
hr
=
IAccessible_get_accState
(
acc2
,
cid
,
&
v2
);
if
(
SUCCEEDED
(
hr
)
&&
(
V_VT
(
&
v2
)
==
VT_I4
))
{
if
(
V_I4
(
&
v
)
!=
V_I4
(
&
v2
))
return
E_FAIL
;
state_match
=
TRUE
;
}
}
hr
=
IAccessible_get_accChildCount
(
acc
,
&
child_count
[
0
]);
hr2
=
IAccessible_get_accChildCount
(
acc2
,
&
child_count
[
1
]);
if
(
SUCCEEDED
(
hr
)
&&
SUCCEEDED
(
hr2
))
{
if
(
child_count
[
0
]
!=
child_count
[
1
])
return
E_FAIL
;
child_count_match
=
TRUE
;
}
hr
=
IAccessible_accLocation
(
acc
,
&
left
[
0
],
&
top
[
0
],
&
width
[
0
],
&
height
[
0
],
cid
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IAccessible_accLocation
(
acc2
,
&
left
[
1
],
&
top
[
1
],
&
width
[
1
],
&
height
[
1
],
cid
);
if
(
SUCCEEDED
(
hr
))
{
if
((
left
[
0
]
!=
left
[
1
])
||
(
top
[
0
]
!=
top
[
1
])
||
(
width
[
0
]
!=
width
[
1
])
||
(
height
[
0
]
!=
height
[
1
]))
return
E_FAIL
;
location_match
=
TRUE
;
}
}
if
(
role_match
&&
state_match
&&
child_count_match
&&
location_match
)
return
S_OK
;
return
S_FALSE
;
}
static
BOOL
msaa_acc_compare
(
IAccessible
*
acc
,
IAccessible
*
acc2
)
{
IUnknown
*
unk
,
*
unk2
;
BOOL
matched
=
FALSE
;
BSTR
name
[
2
];
VARIANT
cid
;
HRESULT
hr
;
acc
=
msaa_acc_da_unwrap
(
acc
);
acc2
=
msaa_acc_da_unwrap
(
acc2
);
IAccessible_QueryInterface
(
acc
,
&
IID_IUnknown
,
(
void
**
)
&
unk
);
IAccessible_QueryInterface
(
acc2
,
&
IID_IUnknown
,
(
void
**
)
&
unk2
);
if
(
unk
==
unk2
)
{
matched
=
TRUE
;
goto
exit
;
}
hr
=
msaa_acc_prop_match
(
acc
,
acc2
);
if
(
FAILED
(
hr
))
goto
exit
;
if
(
hr
==
S_OK
)
matched
=
TRUE
;
variant_init_i4
(
&
cid
,
CHILDID_SELF
);
hr
=
IAccessible_get_accName
(
acc
,
cid
,
&
name
[
0
]);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IAccessible_get_accName
(
acc2
,
cid
,
&
name
[
1
]);
if
(
SUCCEEDED
(
hr
))
{
if
(
!
name
[
0
]
&&
!
name
[
1
])
matched
=
TRUE
;
else
if
(
!
name
[
0
]
||
!
name
[
1
])
matched
=
FALSE
;
else
{
if
(
!
wcscmp
(
name
[
0
],
name
[
1
]))
matched
=
TRUE
;
else
matched
=
FALSE
;
}
SysFreeString
(
name
[
1
]);
}
SysFreeString
(
name
[
0
]);
}
exit:
IUnknown_Release
(
unk
);
IUnknown_Release
(
unk2
);
IAccessible_Release
(
acc
);
IAccessible_Release
(
acc2
);
return
matched
;
}
static
LONG
msaa_role_to_uia_control_type
(
LONG
role
)
{
switch
(
role
)
...
...
@@ -141,8 +295,34 @@ struct msaa_provider {
VARIANT
cid
;
HWND
hwnd
;
LONG
control_type
;
BOOL
root_acc_check_ran
;
BOOL
is_root_acc
;
};
static
BOOL
msaa_check_root_acc
(
struct
msaa_provider
*
msaa_prov
)
{
IAccessible
*
acc
;
HRESULT
hr
;
if
(
msaa_prov
->
root_acc_check_ran
)
return
msaa_prov
->
is_root_acc
;
msaa_prov
->
root_acc_check_ran
=
TRUE
;
if
(
V_I4
(
&
msaa_prov
->
cid
)
!=
CHILDID_SELF
)
return
FALSE
;
hr
=
AccessibleObjectFromWindow
(
msaa_prov
->
hwnd
,
OBJID_CLIENT
,
&
IID_IAccessible
,
(
void
**
)
&
acc
);
if
(
FAILED
(
hr
))
return
FALSE
;
if
(
msaa_acc_compare
(
msaa_prov
->
acc
,
acc
))
msaa_prov
->
is_root_acc
=
TRUE
;
IAccessible_Release
(
acc
);
return
msaa_prov
->
is_root_acc
;
}
static
inline
struct
msaa_provider
*
impl_from_msaa_provider
(
IRawElementProviderSimple
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
msaa_provider
,
IRawElementProviderSimple_iface
);
...
...
@@ -264,9 +444,15 @@ HRESULT WINAPI msaa_provider_GetPropertyValue(IRawElementProviderSimple *iface,
HRESULT
WINAPI
msaa_provider_get_HostRawElementProvider
(
IRawElementProviderSimple
*
iface
,
IRawElementProviderSimple
**
ret_val
)
{
FIXME
(
"%p, %p: stub!
\n
"
,
iface
,
ret_val
);
struct
msaa_provider
*
msaa_prov
=
impl_from_msaa_provider
(
iface
);
TRACE
(
"%p, %p
\n
"
,
iface
,
ret_val
);
*
ret_val
=
NULL
;
return
E_NOTIMPL
;
if
(
msaa_check_root_acc
(
msaa_prov
))
return
UiaHostProviderFromHwnd
(
msaa_prov
->
hwnd
,
ret_val
);
return
S_OK
;
}
static
const
IRawElementProviderSimpleVtbl
msaa_provider_vtbl
=
{
...
...
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