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
62d76348
Commit
62d76348
authored
Jun 13, 2022
by
Connor McAdams
Committed by
Alexandre Julliard
Jun 15, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Add basic IAccessible2 support.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
7d5708a1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
656 additions
and
0 deletions
+656
-0
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+603
-0
uia_provider.c
dlls/uiautomationcore/uia_provider.c
+53
-0
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
62d76348
...
...
@@ -24,6 +24,7 @@
#include "initguid.h"
#include "uiautomation.h"
#include "ocidl.h"
#include "wine/iaccessible2.h"
#include "wine/test.h"
...
...
@@ -73,6 +74,7 @@ DEFINE_EXPECT(Accessible_get_accRole);
DEFINE_EXPECT
(
Accessible_get_accState
);
DEFINE_EXPECT
(
Accessible_accLocation
);
DEFINE_EXPECT
(
Accessible_get_accChild
);
DEFINE_EXPECT
(
Accessible_get_uniqueID
);
DEFINE_EXPECT
(
Accessible2_get_accParent
);
DEFINE_EXPECT
(
Accessible2_get_accChildCount
);
DEFINE_EXPECT
(
Accessible2_get_accName
);
...
...
@@ -80,6 +82,7 @@ DEFINE_EXPECT(Accessible2_get_accRole);
DEFINE_EXPECT
(
Accessible2_get_accState
);
DEFINE_EXPECT
(
Accessible2_accLocation
);
DEFINE_EXPECT
(
Accessible2_QI_IAccIdentity
);
DEFINE_EXPECT
(
Accessible2_get_uniqueID
);
DEFINE_EXPECT
(
Accessible_child_accNavigate
);
DEFINE_EXPECT
(
Accessible_child_get_accParent
);
DEFINE_EXPECT
(
Accessible_child_get_accChildCount
);
...
...
@@ -128,7 +131,9 @@ static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
static
struct
Accessible
{
IAccessible
IAccessible_iface
;
IAccessible2
IAccessible2_iface
;
IOleWindow
IOleWindow_iface
;
IServiceProvider
IServiceProvider_iface
;
LONG
ref
;
IAccessible
*
parent
;
...
...
@@ -139,6 +144,8 @@ static struct Accessible
LONG
child_count
;
LPCWSTR
name
;
LONG
left
,
top
,
width
,
height
;
BOOL
enable_ia2
;
LONG
unique_id
;
}
Accessible
,
Accessible2
,
Accessible_child
,
Accessible_child2
;
static
inline
struct
Accessible
*
impl_from_Accessible
(
IAccessible
*
iface
)
...
...
@@ -164,6 +171,10 @@ static HRESULT WINAPI Accessible_QueryInterface(IAccessible *iface, REFIID riid,
*
obj
=
iface
;
else
if
(
IsEqualIID
(
riid
,
&
IID_IOleWindow
))
*
obj
=
&
This
->
IOleWindow_iface
;
else
if
(
IsEqualIID
(
riid
,
&
IID_IServiceProvider
))
*
obj
=
&
This
->
IServiceProvider_iface
;
else
if
(
IsEqualIID
(
riid
,
&
IID_IAccessible2
)
&&
This
->
enable_ia2
)
*
obj
=
&
This
->
IAccessible2_iface
;
else
return
E_NOINTERFACE
;
...
...
@@ -559,6 +570,383 @@ static IAccessibleVtbl AccessibleVtbl = {
Accessible_put_accValue
};
static
inline
struct
Accessible
*
impl_from_Accessible2
(
IAccessible2
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
Accessible
,
IAccessible2_iface
);
}
static
HRESULT
WINAPI
Accessible2_QueryInterface
(
IAccessible2
*
iface
,
REFIID
riid
,
void
**
obj
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_QueryInterface
(
&
This
->
IAccessible_iface
,
riid
,
obj
);
}
static
ULONG
WINAPI
Accessible2_AddRef
(
IAccessible2
*
iface
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_AddRef
(
&
This
->
IAccessible_iface
);
}
static
ULONG
WINAPI
Accessible2_Release
(
IAccessible2
*
iface
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_Release
(
&
This
->
IAccessible_iface
);
}
static
HRESULT
WINAPI
Accessible2_GetTypeInfoCount
(
IAccessible2
*
iface
,
UINT
*
pctinfo
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_GetTypeInfoCount
(
&
This
->
IAccessible_iface
,
pctinfo
);
}
static
HRESULT
WINAPI
Accessible2_GetTypeInfo
(
IAccessible2
*
iface
,
UINT
iTInfo
,
LCID
lcid
,
ITypeInfo
**
out_tinfo
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_GetTypeInfo
(
&
This
->
IAccessible_iface
,
iTInfo
,
lcid
,
out_tinfo
);
}
static
HRESULT
WINAPI
Accessible2_GetIDsOfNames
(
IAccessible2
*
iface
,
REFIID
riid
,
LPOLESTR
*
rg_names
,
UINT
name_count
,
LCID
lcid
,
DISPID
*
rg_disp_id
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_GetIDsOfNames
(
&
This
->
IAccessible_iface
,
riid
,
rg_names
,
name_count
,
lcid
,
rg_disp_id
);
}
static
HRESULT
WINAPI
Accessible2_Invoke
(
IAccessible2
*
iface
,
DISPID
disp_id_member
,
REFIID
riid
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
disp_params
,
VARIANT
*
var_result
,
EXCEPINFO
*
excep_info
,
UINT
*
arg_err
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_Invoke
(
&
This
->
IAccessible_iface
,
disp_id_member
,
riid
,
lcid
,
flags
,
disp_params
,
var_result
,
excep_info
,
arg_err
);
}
static
HRESULT
WINAPI
Accessible2_get_accParent
(
IAccessible2
*
iface
,
IDispatch
**
out_parent
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accParent
(
&
This
->
IAccessible_iface
,
out_parent
);
}
static
HRESULT
WINAPI
Accessible2_get_accChildCount
(
IAccessible2
*
iface
,
LONG
*
out_count
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accChildCount
(
&
This
->
IAccessible_iface
,
out_count
);
}
static
HRESULT
WINAPI
Accessible2_get_accChild
(
IAccessible2
*
iface
,
VARIANT
child_id
,
IDispatch
**
out_child
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accChild
(
&
This
->
IAccessible_iface
,
child_id
,
out_child
);
}
static
HRESULT
WINAPI
Accessible2_get_accName
(
IAccessible2
*
iface
,
VARIANT
child_id
,
BSTR
*
out_name
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accName
(
&
This
->
IAccessible_iface
,
child_id
,
out_name
);
}
static
HRESULT
WINAPI
Accessible2_get_accValue
(
IAccessible2
*
iface
,
VARIANT
child_id
,
BSTR
*
out_value
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accValue
(
&
This
->
IAccessible_iface
,
child_id
,
out_value
);
}
static
HRESULT
WINAPI
Accessible2_get_accDescription
(
IAccessible2
*
iface
,
VARIANT
child_id
,
BSTR
*
out_description
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accDescription
(
&
This
->
IAccessible_iface
,
child_id
,
out_description
);
}
static
HRESULT
WINAPI
Accessible2_get_accRole
(
IAccessible2
*
iface
,
VARIANT
child_id
,
VARIANT
*
out_role
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accRole
(
&
This
->
IAccessible_iface
,
child_id
,
out_role
);
}
static
HRESULT
WINAPI
Accessible2_get_accState
(
IAccessible2
*
iface
,
VARIANT
child_id
,
VARIANT
*
out_state
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accState
(
&
This
->
IAccessible_iface
,
child_id
,
out_state
);
}
static
HRESULT
WINAPI
Accessible2_get_accHelp
(
IAccessible2
*
iface
,
VARIANT
child_id
,
BSTR
*
out_help
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accHelp
(
&
This
->
IAccessible_iface
,
child_id
,
out_help
);
}
static
HRESULT
WINAPI
Accessible2_get_accHelpTopic
(
IAccessible2
*
iface
,
BSTR
*
out_help_file
,
VARIANT
child_id
,
LONG
*
out_topic_id
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accHelpTopic
(
&
This
->
IAccessible_iface
,
out_help_file
,
child_id
,
out_topic_id
);
}
static
HRESULT
WINAPI
Accessible2_get_accKeyboardShortcut
(
IAccessible2
*
iface
,
VARIANT
child_id
,
BSTR
*
out_kbd_shortcut
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accKeyboardShortcut
(
&
This
->
IAccessible_iface
,
child_id
,
out_kbd_shortcut
);
}
static
HRESULT
WINAPI
Accessible2_get_accFocus
(
IAccessible2
*
iface
,
VARIANT
*
pchild_id
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accFocus
(
&
This
->
IAccessible_iface
,
pchild_id
);
}
static
HRESULT
WINAPI
Accessible2_get_accSelection
(
IAccessible2
*
iface
,
VARIANT
*
out_selection
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accSelection
(
&
This
->
IAccessible_iface
,
out_selection
);
}
static
HRESULT
WINAPI
Accessible2_get_accDefaultAction
(
IAccessible2
*
iface
,
VARIANT
child_id
,
BSTR
*
out_default_action
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_get_accDefaultAction
(
&
This
->
IAccessible_iface
,
child_id
,
out_default_action
);
}
static
HRESULT
WINAPI
Accessible2_accSelect
(
IAccessible2
*
iface
,
LONG
select_flags
,
VARIANT
child_id
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_accSelect
(
&
This
->
IAccessible_iface
,
select_flags
,
child_id
);
}
static
HRESULT
WINAPI
Accessible2_accLocation
(
IAccessible2
*
iface
,
LONG
*
out_left
,
LONG
*
out_top
,
LONG
*
out_width
,
LONG
*
out_height
,
VARIANT
child_id
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_accLocation
(
&
This
->
IAccessible_iface
,
out_left
,
out_top
,
out_width
,
out_height
,
child_id
);
}
static
HRESULT
WINAPI
Accessible2_accNavigate
(
IAccessible2
*
iface
,
LONG
nav_direction
,
VARIANT
child_id_start
,
VARIANT
*
out_var
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_accNavigate
(
&
This
->
IAccessible_iface
,
nav_direction
,
child_id_start
,
out_var
);
}
static
HRESULT
WINAPI
Accessible2_accHitTest
(
IAccessible2
*
iface
,
LONG
left
,
LONG
top
,
VARIANT
*
out_child_id
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_accHitTest
(
&
This
->
IAccessible_iface
,
left
,
top
,
out_child_id
);
}
static
HRESULT
WINAPI
Accessible2_accDoDefaultAction
(
IAccessible2
*
iface
,
VARIANT
child_id
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_accDoDefaultAction
(
&
This
->
IAccessible_iface
,
child_id
);
}
static
HRESULT
WINAPI
Accessible2_put_accName
(
IAccessible2
*
iface
,
VARIANT
child_id
,
BSTR
name
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_put_accName
(
&
This
->
IAccessible_iface
,
child_id
,
name
);
}
static
HRESULT
WINAPI
Accessible2_put_accValue
(
IAccessible2
*
iface
,
VARIANT
child_id
,
BSTR
value
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
return
IAccessible_put_accValue
(
&
This
->
IAccessible_iface
,
child_id
,
value
);
}
static
HRESULT
WINAPI
Accessible2_get_nRelations
(
IAccessible2
*
iface
,
LONG
*
out_nRelations
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_relation
(
IAccessible2
*
iface
,
LONG
relation_idx
,
IAccessibleRelation
**
out_relation
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_relations
(
IAccessible2
*
iface
,
LONG
count
,
IAccessibleRelation
**
out_relations
,
LONG
*
out_relation_count
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_role
(
IAccessible2
*
iface
,
LONG
*
out_role
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_scrollTo
(
IAccessible2
*
iface
,
enum
IA2ScrollType
scroll_type
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_scrollToPoint
(
IAccessible2
*
iface
,
enum
IA2CoordinateType
coordinate_type
,
LONG
x
,
LONG
y
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_groupPosition
(
IAccessible2
*
iface
,
LONG
*
out_group_level
,
LONG
*
out_similar_items_in_group
,
LONG
*
out_position_in_group
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_states
(
IAccessible2
*
iface
,
AccessibleStates
*
out_states
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_extendedRole
(
IAccessible2
*
iface
,
BSTR
*
out_extended_role
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_localizedExtendedRole
(
IAccessible2
*
iface
,
BSTR
*
out_localized_extended_role
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_nExtendedStates
(
IAccessible2
*
iface
,
LONG
*
out_nExtendedStates
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_extendedStates
(
IAccessible2
*
iface
,
LONG
count
,
BSTR
**
out_extended_states
,
LONG
*
out_extended_states_count
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_localizedExtendedStates
(
IAccessible2
*
iface
,
LONG
count
,
BSTR
**
out_localized_extended_states
,
LONG
*
out_localized_extended_states_count
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_uniqueID
(
IAccessible2
*
iface
,
LONG
*
out_unique_id
)
{
struct
Accessible
*
This
=
impl_from_Accessible2
(
iface
);
if
(
This
==
&
Accessible2
)
CHECK_EXPECT
(
Accessible2_get_uniqueID
);
else
CHECK_EXPECT
(
Accessible_get_uniqueID
);
*
out_unique_id
=
0
;
if
(
This
->
unique_id
)
{
*
out_unique_id
=
This
->
unique_id
;
return
S_OK
;
}
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_windowHandle
(
IAccessible2
*
iface
,
HWND
*
out_hwnd
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_indexInParent
(
IAccessible2
*
iface
,
LONG
*
out_idx_in_parent
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_locale
(
IAccessible2
*
iface
,
IA2Locale
*
out_locale
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
Accessible2_get_attributes
(
IAccessible2
*
iface
,
BSTR
*
out_attributes
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
const
IAccessible2Vtbl
Accessible2Vtbl
=
{
Accessible2_QueryInterface
,
Accessible2_AddRef
,
Accessible2_Release
,
Accessible2_GetTypeInfoCount
,
Accessible2_GetTypeInfo
,
Accessible2_GetIDsOfNames
,
Accessible2_Invoke
,
Accessible2_get_accParent
,
Accessible2_get_accChildCount
,
Accessible2_get_accChild
,
Accessible2_get_accName
,
Accessible2_get_accValue
,
Accessible2_get_accDescription
,
Accessible2_get_accRole
,
Accessible2_get_accState
,
Accessible2_get_accHelp
,
Accessible2_get_accHelpTopic
,
Accessible2_get_accKeyboardShortcut
,
Accessible2_get_accFocus
,
Accessible2_get_accSelection
,
Accessible2_get_accDefaultAction
,
Accessible2_accSelect
,
Accessible2_accLocation
,
Accessible2_accNavigate
,
Accessible2_accHitTest
,
Accessible2_accDoDefaultAction
,
Accessible2_put_accName
,
Accessible2_put_accValue
,
Accessible2_get_nRelations
,
Accessible2_get_relation
,
Accessible2_get_relations
,
Accessible2_role
,
Accessible2_scrollTo
,
Accessible2_scrollToPoint
,
Accessible2_get_groupPosition
,
Accessible2_get_states
,
Accessible2_get_extendedRole
,
Accessible2_get_localizedExtendedRole
,
Accessible2_get_nExtendedStates
,
Accessible2_get_extendedStates
,
Accessible2_get_localizedExtendedStates
,
Accessible2_get_uniqueID
,
Accessible2_get_windowHandle
,
Accessible2_get_indexInParent
,
Accessible2_get_locale
,
Accessible2_get_attributes
,
};
static
inline
struct
Accessible
*
impl_from_OleWindow
(
IOleWindow
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
Accessible
,
IOleWindow_iface
);
...
...
@@ -603,48 +991,102 @@ static const IOleWindowVtbl OleWindowVtbl = {
OleWindow_ContextSensitiveHelp
};
static
inline
struct
Accessible
*
impl_from_ServiceProvider
(
IServiceProvider
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
Accessible
,
IServiceProvider_iface
);
}
static
HRESULT
WINAPI
ServiceProvider_QueryInterface
(
IServiceProvider
*
iface
,
REFIID
riid
,
void
**
obj
)
{
struct
Accessible
*
This
=
impl_from_ServiceProvider
(
iface
);
return
IAccessible_QueryInterface
(
&
This
->
IAccessible_iface
,
riid
,
obj
);
}
static
ULONG
WINAPI
ServiceProvider_AddRef
(
IServiceProvider
*
iface
)
{
struct
Accessible
*
This
=
impl_from_ServiceProvider
(
iface
);
return
IAccessible_AddRef
(
&
This
->
IAccessible_iface
);
}
static
ULONG
WINAPI
ServiceProvider_Release
(
IServiceProvider
*
iface
)
{
struct
Accessible
*
This
=
impl_from_ServiceProvider
(
iface
);
return
IAccessible_Release
(
&
This
->
IAccessible_iface
);
}
static
HRESULT
WINAPI
ServiceProvider_QueryService
(
IServiceProvider
*
iface
,
REFGUID
service_guid
,
REFIID
riid
,
void
**
obj
)
{
struct
Accessible
*
This
=
impl_from_ServiceProvider
(
iface
);
if
(
IsEqualIID
(
riid
,
&
IID_IAccessible2
)
&&
IsEqualIID
(
service_guid
,
&
IID_IAccessible2
)
&&
This
->
enable_ia2
)
return
IAccessible_QueryInterface
(
&
This
->
IAccessible_iface
,
riid
,
obj
);
return
E_NOTIMPL
;
}
static
const
IServiceProviderVtbl
ServiceProviderVtbl
=
{
ServiceProvider_QueryInterface
,
ServiceProvider_AddRef
,
ServiceProvider_Release
,
ServiceProvider_QueryService
,
};
static
struct
Accessible
Accessible
=
{
{
&
AccessibleVtbl
},
{
&
Accessible2Vtbl
},
{
&
OleWindowVtbl
},
{
&
ServiceProviderVtbl
},
1
,
NULL
,
0
,
0
,
0
,
0
,
0
,
NULL
,
0
,
0
,
0
,
0
,
FALSE
,
0
,
};
static
struct
Accessible
Accessible2
=
{
{
&
AccessibleVtbl
},
{
&
Accessible2Vtbl
},
{
&
OleWindowVtbl
},
{
&
ServiceProviderVtbl
},
1
,
NULL
,
0
,
0
,
0
,
0
,
0
,
NULL
,
0
,
0
,
0
,
0
,
FALSE
,
0
,
};
static
struct
Accessible
Accessible_child
=
{
{
&
AccessibleVtbl
},
{
&
Accessible2Vtbl
},
{
&
OleWindowVtbl
},
{
&
ServiceProviderVtbl
},
1
,
&
Accessible
.
IAccessible_iface
,
0
,
0
,
0
,
0
,
0
,
NULL
,
0
,
0
,
0
,
0
,
FALSE
,
0
,
};
static
struct
Accessible
Accessible_child2
=
{
{
&
AccessibleVtbl
},
{
&
Accessible2Vtbl
},
{
&
OleWindowVtbl
},
{
&
ServiceProviderVtbl
},
1
,
&
Accessible
.
IAccessible_iface
,
0
,
0
,
0
,
0
,
0
,
NULL
,
0
,
0
,
0
,
0
,
FALSE
,
0
,
};
static
IAccessible
*
acc_client
;
...
...
@@ -1002,6 +1444,166 @@ static void set_accessible_props(struct Accessible *acc, INT role, INT state,
acc
->
height
=
height
;
}
static
void
set_accessible_ia2_props
(
struct
Accessible
*
acc
,
BOOL
enable_ia2
,
LONG
unique_id
)
{
acc
->
enable_ia2
=
enable_ia2
;
acc
->
unique_id
=
unique_id
;
}
static
void
test_uia_prov_from_acc_ia2
(
void
)
{
IRawElementProviderSimple
*
elprov
,
*
elprov2
;
HRESULT
hr
;
/* Only one exposes an IA2 interface, no match. */
set_accessible_props
(
&
Accessible
,
0
,
0
,
0
,
L"acc_name"
,
0
,
0
,
0
,
0
);
set_accessible_ia2_props
(
&
Accessible
,
TRUE
,
0
);
set_accessible_props
(
&
Accessible2
,
0
,
0
,
0
,
L"acc_name"
,
0
,
0
,
0
,
0
);
set_accessible_ia2_props
(
&
Accessible2
,
FALSE
,
0
);
hr
=
pUiaProviderFromIAccessible
(
&
Accessible
.
IAccessible_iface
,
CHILDID_SELF
,
UIA_PFIA_DEFAULT
,
&
elprov
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
Accessible
.
ref
!=
3
)
{
IRawElementProviderSimple_Release
(
elprov
);
win_skip
(
"UiaProviderFromIAccessible has no IAccessible2 support, skipping tests.
\n
"
);
return
;
}
acc_client
=
&
Accessible2
.
IAccessible_iface
;
SET_EXPECT
(
winproc_GETOBJECT_CLIENT
);
elprov2
=
(
void
*
)
0xdeadbeef
;
hr
=
IRawElementProviderSimple_get_HostRawElementProvider
(
elprov
,
&
elprov2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
!
elprov2
,
"elprov != NULL, elprov %p
\n
"
,
elprov2
);
ok
(
Accessible2
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible2
.
ref
);
CHECK_CALLED
(
winproc_GETOBJECT_CLIENT
);
elprov2
=
(
void
*
)
0xdeadbeef
;
acc_client
=
NULL
;
hr
=
IRawElementProviderSimple_get_HostRawElementProvider
(
elprov
,
&
elprov2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
!
elprov2
,
"elprov != NULL, elprov %p
\n
"
,
elprov2
);
IRawElementProviderSimple_Release
(
elprov
);
ok
(
Accessible
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
/*
* If &Accessible returns a failure code on get_uniqueID, &Accessible2's
* uniqueID is not checked.
*/
set_accessible_ia2_props
(
&
Accessible
,
TRUE
,
0
);
set_accessible_ia2_props
(
&
Accessible2
,
TRUE
,
0
);
hr
=
pUiaProviderFromIAccessible
(
&
Accessible
.
IAccessible_iface
,
CHILDID_SELF
,
UIA_PFIA_DEFAULT
,
&
elprov
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
Accessible
.
ref
==
3
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
acc_client
=
&
Accessible2
.
IAccessible_iface
;
SET_EXPECT
(
winproc_GETOBJECT_CLIENT
);
SET_EXPECT
(
Accessible_get_accRole
);
SET_EXPECT
(
Accessible_get_accState
);
SET_EXPECT
(
Accessible_get_accChildCount
);
SET_EXPECT
(
Accessible_accLocation
);
SET_EXPECT
(
Accessible_get_accName
);
SET_EXPECT
(
Accessible_get_uniqueID
);
SET_EXPECT
(
Accessible2_get_accChildCount
);
SET_EXPECT
(
Accessible2_get_accName
);
SET_EXPECT
(
Accessible2_QI_IAccIdentity
);
SET_EXPECT
(
Accessible2_get_accParent
);
elprov2
=
(
void
*
)
0xdeadbeef
;
hr
=
IRawElementProviderSimple_get_HostRawElementProvider
(
elprov
,
&
elprov2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
!!
elprov2
,
"elprov == NULL, elprov %p
\n
"
,
elprov2
);
ok
(
Accessible2
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible2
.
ref
);
CHECK_CALLED
(
winproc_GETOBJECT_CLIENT
);
CHECK_CALLED
(
Accessible_get_accRole
);
CHECK_CALLED
(
Accessible_get_accState
);
CHECK_CALLED
(
Accessible_get_accChildCount
);
CHECK_CALLED
(
Accessible_accLocation
);
CHECK_CALLED
(
Accessible_get_accName
);
CHECK_CALLED
(
Accessible_get_uniqueID
);
CHECK_CALLED
(
Accessible2_get_accChildCount
);
CHECK_CALLED
(
Accessible2_get_accName
);
todo_wine
CHECK_CALLED
(
Accessible2_QI_IAccIdentity
);
todo_wine
CHECK_CALLED
(
Accessible2_get_accParent
);
IRawElementProviderSimple_Release
(
elprov2
);
elprov2
=
(
void
*
)
0xdeadbeef
;
acc_client
=
NULL
;
hr
=
IRawElementProviderSimple_get_HostRawElementProvider
(
elprov
,
&
elprov2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
!!
elprov2
,
"elprov == NULL, elprov %p
\n
"
,
elprov2
);
IRawElementProviderSimple_Release
(
elprov2
);
IRawElementProviderSimple_Release
(
elprov
);
ok
(
Accessible
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
/* Unique ID matches. */
set_accessible_ia2_props
(
&
Accessible
,
TRUE
,
1
);
set_accessible_ia2_props
(
&
Accessible2
,
TRUE
,
1
);
hr
=
pUiaProviderFromIAccessible
(
&
Accessible
.
IAccessible_iface
,
CHILDID_SELF
,
UIA_PFIA_DEFAULT
,
&
elprov
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
Accessible
.
ref
==
3
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
acc_client
=
&
Accessible2
.
IAccessible_iface
;
SET_EXPECT
(
winproc_GETOBJECT_CLIENT
);
SET_EXPECT
(
Accessible_get_uniqueID
);
SET_EXPECT
(
Accessible2_get_uniqueID
);
elprov2
=
(
void
*
)
0xdeadbeef
;
hr
=
IRawElementProviderSimple_get_HostRawElementProvider
(
elprov
,
&
elprov2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
!!
elprov2
,
"elprov == NULL, elprov %p
\n
"
,
elprov2
);
ok
(
Accessible2
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible2
.
ref
);
CHECK_CALLED
(
winproc_GETOBJECT_CLIENT
);
CHECK_CALLED
(
Accessible_get_uniqueID
);
CHECK_CALLED
(
Accessible2_get_uniqueID
);
IRawElementProviderSimple_Release
(
elprov2
);
elprov2
=
(
void
*
)
0xdeadbeef
;
acc_client
=
NULL
;
hr
=
IRawElementProviderSimple_get_HostRawElementProvider
(
elprov
,
&
elprov2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
!!
elprov2
,
"elprov == NULL, elprov %p
\n
"
,
elprov2
);
IRawElementProviderSimple_Release
(
elprov2
);
IRawElementProviderSimple_Release
(
elprov
);
ok
(
Accessible
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
/* Unique ID mismatch. */
set_accessible_ia2_props
(
&
Accessible
,
TRUE
,
1
);
set_accessible_ia2_props
(
&
Accessible2
,
TRUE
,
2
);
hr
=
pUiaProviderFromIAccessible
(
&
Accessible
.
IAccessible_iface
,
CHILDID_SELF
,
UIA_PFIA_DEFAULT
,
&
elprov
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
Accessible
.
ref
==
3
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
acc_client
=
&
Accessible2
.
IAccessible_iface
;
SET_EXPECT
(
winproc_GETOBJECT_CLIENT
);
SET_EXPECT
(
Accessible_get_uniqueID
);
SET_EXPECT
(
Accessible2_get_uniqueID
);
elprov2
=
(
void
*
)
0xdeadbeef
;
hr
=
IRawElementProviderSimple_get_HostRawElementProvider
(
elprov
,
&
elprov2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
!
elprov2
,
"elprov != NULL, elprov %p
\n
"
,
elprov2
);
ok
(
Accessible2
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible2
.
ref
);
CHECK_CALLED
(
winproc_GETOBJECT_CLIENT
);
CHECK_CALLED
(
Accessible_get_uniqueID
);
CHECK_CALLED
(
Accessible2_get_uniqueID
);
elprov2
=
(
void
*
)
0xdeadbeef
;
acc_client
=
NULL
;
hr
=
IRawElementProviderSimple_get_HostRawElementProvider
(
elprov
,
&
elprov2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
!
elprov2
,
"elprov != NULL, elprov %p
\n
"
,
elprov2
);
IRawElementProviderSimple_Release
(
elprov
);
ok
(
Accessible
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
set_accessible_props
(
&
Accessible
,
0
,
0
,
0
,
NULL
,
0
,
0
,
0
,
0
);
set_accessible_ia2_props
(
&
Accessible
,
FALSE
,
0
);
set_accessible_props
(
&
Accessible2
,
0
,
0
,
0
,
NULL
,
0
,
0
,
0
,
0
);
set_accessible_ia2_props
(
&
Accessible2
,
FALSE
,
0
);
}
#define check_fragment_acc( fragment, acc, cid) \
check_fragment_acc_( (fragment), (acc), (cid), __LINE__)
static
void
check_fragment_acc_
(
IRawElementProviderFragment
*
elfrag
,
IAccessible
*
acc
,
...
...
@@ -2091,6 +2693,7 @@ static void test_UiaProviderFromIAccessible(void)
test_uia_prov_from_acc_properties
();
test_uia_prov_from_acc_navigation
();
test_uia_prov_from_acc_ia2
();
CoUninitialize
();
DestroyWindow
(
hwnd
);
...
...
dlls/uiautomationcore/uia_provider.c
View file @
62d76348
...
...
@@ -24,6 +24,7 @@
#include "wine/debug.h"
#include "wine/heap.h"
#include "initguid.h"
#include "wine/iaccessible2.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
uiautomation
);
...
...
@@ -54,6 +55,28 @@ static BOOL msaa_check_acc_state(IAccessible *acc, VARIANT cid, ULONG flag)
return
FALSE
;
}
static
IAccessible2
*
msaa_acc_get_ia2
(
IAccessible
*
acc
)
{
IServiceProvider
*
serv_prov
;
IAccessible2
*
ia2
=
NULL
;
HRESULT
hr
;
hr
=
IAccessible_QueryInterface
(
acc
,
&
IID_IServiceProvider
,
(
void
**
)
&
serv_prov
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IServiceProvider_QueryService
(
serv_prov
,
&
IID_IAccessible2
,
&
IID_IAccessible2
,
(
void
**
)
&
ia2
);
IServiceProvider_Release
(
serv_prov
);
if
(
SUCCEEDED
(
hr
)
&&
ia2
)
return
ia2
;
}
hr
=
IAccessible_QueryInterface
(
acc
,
&
IID_IAccessible2
,
(
void
**
)
&
ia2
);
if
(
SUCCEEDED
(
hr
)
&&
ia2
)
return
ia2
;
return
NULL
;
}
static
IAccessible
*
msaa_acc_da_unwrap
(
IAccessible
*
acc
)
{
IServiceProvider
*
sp
;
...
...
@@ -149,8 +172,10 @@ static HRESULT msaa_acc_prop_match(IAccessible *acc, IAccessible *acc2)
static
BOOL
msaa_acc_compare
(
IAccessible
*
acc
,
IAccessible
*
acc2
)
{
IAccessible2
*
ia2
[
2
]
=
{
NULL
,
NULL
};
IUnknown
*
unk
,
*
unk2
;
BOOL
matched
=
FALSE
;
LONG
unique_id
[
2
];
BSTR
name
[
2
];
VARIANT
cid
;
HRESULT
hr
;
...
...
@@ -165,6 +190,26 @@ static BOOL msaa_acc_compare(IAccessible *acc, IAccessible *acc2)
goto
exit
;
}
ia2
[
0
]
=
msaa_acc_get_ia2
(
acc
);
ia2
[
1
]
=
msaa_acc_get_ia2
(
acc2
);
if
(
!
ia2
[
0
]
!=
!
ia2
[
1
])
goto
exit
;
if
(
ia2
[
0
])
{
hr
=
IAccessible2_get_uniqueID
(
ia2
[
0
],
&
unique_id
[
0
]);
if
(
SUCCEEDED
(
hr
))
{
hr
=
IAccessible2_get_uniqueID
(
ia2
[
1
],
&
unique_id
[
1
]);
if
(
SUCCEEDED
(
hr
))
{
if
(
unique_id
[
0
]
==
unique_id
[
1
])
matched
=
TRUE
;
goto
exit
;
}
}
}
hr
=
msaa_acc_prop_match
(
acc
,
acc2
);
if
(
FAILED
(
hr
))
goto
exit
;
...
...
@@ -201,6 +246,10 @@ exit:
IUnknown_Release
(
unk2
);
IAccessible_Release
(
acc
);
IAccessible_Release
(
acc2
);
if
(
ia2
[
0
])
IAccessible2_Release
(
ia2
[
0
]);
if
(
ia2
[
1
])
IAccessible2_Release
(
ia2
[
1
]);
return
matched
;
}
...
...
@@ -456,6 +505,7 @@ struct msaa_provider {
LONG
refcount
;
IAccessible
*
acc
;
IAccessible2
*
ia2
;
VARIANT
cid
;
HWND
hwnd
;
LONG
control_type
;
...
...
@@ -535,6 +585,8 @@ ULONG WINAPI msaa_provider_Release(IRawElementProviderSimple *iface)
IAccessible_Release
(
msaa_prov
->
acc
);
if
(
msaa_prov
->
parent
)
IAccessible_Release
(
msaa_prov
->
parent
);
if
(
msaa_prov
->
ia2
)
IAccessible2_Release
(
msaa_prov
->
ia2
);
heap_free
(
msaa_prov
);
}
...
...
@@ -1069,6 +1121,7 @@ HRESULT WINAPI UiaProviderFromIAccessible(IAccessible *acc, long child_id, DWORD
variant_init_i4
(
&
msaa_prov
->
cid
,
child_id
);
msaa_prov
->
acc
=
acc
;
IAccessible_AddRef
(
acc
);
msaa_prov
->
ia2
=
msaa_acc_get_ia2
(
acc
);
*
elprov
=
&
msaa_prov
->
IRawElementProviderSimple_iface
;
return
S_OK
;
...
...
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