Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
c250b5c7
Commit
c250b5c7
authored
May 17, 2022
by
Connor McAdams
Committed by
Alexandre Julliard
Jun 08, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Implement UIA_ControlTypePropertyId for MSAA providers.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
e3349cef
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
266 additions
and
4 deletions
+266
-4
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+167
-3
uia_provider.c
dlls/uiautomationcore/uia_provider.c
+99
-1
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
c250b5c7
...
...
@@ -58,6 +58,7 @@ static HRESULT (WINAPI *pUiaProviderFromIAccessible)(IAccessible *, long, DWORD,
DEFINE_EXPECT
(
winproc_GETOBJECT_CLIENT
);
DEFINE_EXPECT
(
Accessible_accNavigate
);
DEFINE_EXPECT
(
Accessible_get_accParent
);
DEFINE_EXPECT
(
Accessible_get_accRole
);
DEFINE_EXPECT
(
Accessible_child_accNavigate
);
DEFINE_EXPECT
(
Accessible_child_get_accParent
);
...
...
@@ -80,6 +81,7 @@ static struct Accessible
IAccessible
*
parent
;
HWND
acc_hwnd
;
HWND
ow_hwnd
;
INT
role
;
}
Accessible
,
Accessible_child
;
static
inline
struct
Accessible
*
impl_from_Accessible
(
IAccessible
*
iface
)
...
...
@@ -197,7 +199,18 @@ static HRESULT WINAPI Accessible_get_accDescription(IAccessible *iface, VARIANT
static
HRESULT
WINAPI
Accessible_get_accRole
(
IAccessible
*
iface
,
VARIANT
child_id
,
VARIANT
*
out_role
)
{
ok
(
0
,
"unexpected call
\n
"
);
struct
Accessible
*
This
=
impl_from_Accessible
(
iface
);
ok
(
This
==
&
Accessible
,
"unexpected call
\n
"
);
CHECK_EXPECT
(
Accessible_get_accRole
);
if
(
This
->
role
)
{
V_VT
(
out_role
)
=
VT_I4
;
V_I4
(
out_role
)
=
This
->
role
;
return
S_OK
;
}
return
E_NOTIMPL
;
}
...
...
@@ -395,7 +408,8 @@ static struct Accessible Accessible =
{
&
OleWindowVtbl
},
1
,
NULL
,
0
,
0
0
,
0
,
0
,
};
static
struct
Accessible
Accessible_child
=
{
...
...
@@ -403,7 +417,8 @@ static struct Accessible Accessible_child =
{
&
OleWindowVtbl
},
1
,
&
Accessible
.
IAccessible_iface
,
0
,
0
0
,
0
,
0
,
};
static
LRESULT
WINAPI
test_wnd_proc
(
HWND
hwnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
...
...
@@ -662,6 +677,153 @@ static void test_uia_reserved_value_ifaces(void)
CoUninitialize
();
}
struct
msaa_role_uia_type
{
INT
acc_role
;
INT
uia_control_type
;
};
static
const
struct
msaa_role_uia_type
msaa_role_uia_types
[]
=
{
{
ROLE_SYSTEM_TITLEBAR
,
UIA_TitleBarControlTypeId
},
{
ROLE_SYSTEM_MENUBAR
,
UIA_MenuBarControlTypeId
},
{
ROLE_SYSTEM_SCROLLBAR
,
UIA_ScrollBarControlTypeId
},
{
ROLE_SYSTEM_GRIP
,
UIA_ThumbControlTypeId
},
{
ROLE_SYSTEM_WINDOW
,
UIA_WindowControlTypeId
},
{
ROLE_SYSTEM_MENUPOPUP
,
UIA_MenuControlTypeId
},
{
ROLE_SYSTEM_MENUITEM
,
UIA_MenuItemControlTypeId
},
{
ROLE_SYSTEM_TOOLTIP
,
UIA_ToolTipControlTypeId
},
{
ROLE_SYSTEM_APPLICATION
,
UIA_WindowControlTypeId
},
{
ROLE_SYSTEM_DOCUMENT
,
UIA_DocumentControlTypeId
},
{
ROLE_SYSTEM_PANE
,
UIA_PaneControlTypeId
},
{
ROLE_SYSTEM_GROUPING
,
UIA_GroupControlTypeId
},
{
ROLE_SYSTEM_SEPARATOR
,
UIA_SeparatorControlTypeId
},
{
ROLE_SYSTEM_TOOLBAR
,
UIA_ToolBarControlTypeId
},
{
ROLE_SYSTEM_STATUSBAR
,
UIA_StatusBarControlTypeId
},
{
ROLE_SYSTEM_TABLE
,
UIA_TableControlTypeId
},
{
ROLE_SYSTEM_COLUMNHEADER
,
UIA_HeaderControlTypeId
},
{
ROLE_SYSTEM_ROWHEADER
,
UIA_HeaderControlTypeId
},
{
ROLE_SYSTEM_CELL
,
UIA_DataItemControlTypeId
},
{
ROLE_SYSTEM_LINK
,
UIA_HyperlinkControlTypeId
},
{
ROLE_SYSTEM_LIST
,
UIA_ListControlTypeId
},
{
ROLE_SYSTEM_LISTITEM
,
UIA_ListItemControlTypeId
},
{
ROLE_SYSTEM_OUTLINE
,
UIA_TreeControlTypeId
},
{
ROLE_SYSTEM_OUTLINEITEM
,
UIA_TreeItemControlTypeId
},
{
ROLE_SYSTEM_PAGETAB
,
UIA_TabItemControlTypeId
},
{
ROLE_SYSTEM_INDICATOR
,
UIA_ThumbControlTypeId
},
{
ROLE_SYSTEM_GRAPHIC
,
UIA_ImageControlTypeId
},
{
ROLE_SYSTEM_STATICTEXT
,
UIA_TextControlTypeId
},
{
ROLE_SYSTEM_TEXT
,
UIA_EditControlTypeId
},
{
ROLE_SYSTEM_PUSHBUTTON
,
UIA_ButtonControlTypeId
},
{
ROLE_SYSTEM_CHECKBUTTON
,
UIA_CheckBoxControlTypeId
},
{
ROLE_SYSTEM_RADIOBUTTON
,
UIA_RadioButtonControlTypeId
},
{
ROLE_SYSTEM_COMBOBOX
,
UIA_ComboBoxControlTypeId
},
{
ROLE_SYSTEM_PROGRESSBAR
,
UIA_ProgressBarControlTypeId
},
{
ROLE_SYSTEM_SLIDER
,
UIA_SliderControlTypeId
},
{
ROLE_SYSTEM_SPINBUTTON
,
UIA_SpinnerControlTypeId
},
{
ROLE_SYSTEM_BUTTONDROPDOWN
,
UIA_SplitButtonControlTypeId
},
{
ROLE_SYSTEM_BUTTONMENU
,
UIA_MenuItemControlTypeId
},
{
ROLE_SYSTEM_BUTTONDROPDOWNGRID
,
UIA_ButtonControlTypeId
},
{
ROLE_SYSTEM_PAGETABLIST
,
UIA_TabControlTypeId
},
{
ROLE_SYSTEM_SPLITBUTTON
,
UIA_SplitButtonControlTypeId
},
/* These accessible roles have no equivalent in UI Automation. */
{
ROLE_SYSTEM_SOUND
,
0
},
{
ROLE_SYSTEM_CURSOR
,
0
},
{
ROLE_SYSTEM_CARET
,
0
},
{
ROLE_SYSTEM_ALERT
,
0
},
{
ROLE_SYSTEM_CLIENT
,
0
},
{
ROLE_SYSTEM_CHART
,
0
},
{
ROLE_SYSTEM_DIALOG
,
0
},
{
ROLE_SYSTEM_BORDER
,
0
},
{
ROLE_SYSTEM_COLUMN
,
0
},
{
ROLE_SYSTEM_ROW
,
0
},
{
ROLE_SYSTEM_HELPBALLOON
,
0
},
{
ROLE_SYSTEM_CHARACTER
,
0
},
{
ROLE_SYSTEM_PROPERTYPAGE
,
0
},
{
ROLE_SYSTEM_DROPLIST
,
0
},
{
ROLE_SYSTEM_DIAL
,
0
},
{
ROLE_SYSTEM_HOTKEYFIELD
,
0
},
{
ROLE_SYSTEM_DIAGRAM
,
0
},
{
ROLE_SYSTEM_ANIMATION
,
0
},
{
ROLE_SYSTEM_EQUATION
,
0
},
{
ROLE_SYSTEM_WHITESPACE
,
0
},
{
ROLE_SYSTEM_IPADDRESS
,
0
},
{
ROLE_SYSTEM_OUTLINEBUTTON
,
0
},
};
static
void
test_uia_prov_from_acc_properties
(
void
)
{
IRawElementProviderSimple
*
elprov
;
HRESULT
hr
;
VARIANT
v
;
int
i
;
/* MSAA role to UIA control type test. */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
msaa_role_uia_types
);
i
++
)
{
const
struct
msaa_role_uia_type
*
role
=
&
msaa_role_uia_types
[
i
];
/*
* Roles get cached once a valid one is mapped, so create a new
* element for each role.
*/
hr
=
pUiaProviderFromIAccessible
(
&
Accessible
.
IAccessible_iface
,
CHILDID_SELF
,
UIA_PFIA_DEFAULT
,
&
elprov
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
Accessible
.
ref
==
2
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
Accessible
.
role
=
role
->
acc_role
;
SET_EXPECT
(
Accessible_get_accRole
);
VariantClear
(
&
v
);
hr
=
IRawElementProviderSimple_GetPropertyValue
(
elprov
,
UIA_ControlTypePropertyId
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
role
->
uia_control_type
)
ok
(
check_variant_i4
(
&
v
,
role
->
uia_control_type
),
"MSAA role %d: V_I4(&v) = %ld
\n
"
,
role
->
acc_role
,
V_I4
(
&
v
));
else
ok
(
V_VT
(
&
v
)
==
VT_EMPTY
,
"MSAA role %d: V_VT(&v) = %d
\n
"
,
role
->
acc_role
,
V_VT
(
&
v
));
CHECK_CALLED
(
Accessible_get_accRole
);
if
(
!
role
->
uia_control_type
)
SET_EXPECT
(
Accessible_get_accRole
);
VariantClear
(
&
v
);
hr
=
IRawElementProviderSimple_GetPropertyValue
(
elprov
,
UIA_ControlTypePropertyId
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
if
(
role
->
uia_control_type
)
ok
(
check_variant_i4
(
&
v
,
role
->
uia_control_type
),
"MSAA role %d: V_I4(&v) = %ld
\n
"
,
role
->
acc_role
,
V_I4
(
&
v
));
else
ok
(
V_VT
(
&
v
)
==
VT_EMPTY
,
"MSAA role %d: V_VT(&v) = %d
\n
"
,
role
->
acc_role
,
V_VT
(
&
v
));
if
(
!
role
->
uia_control_type
)
CHECK_CALLED
(
Accessible_get_accRole
);
IRawElementProviderSimple_Release
(
elprov
);
ok
(
Accessible
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
}
/* ROLE_SYSTEM_CLOCK has no mapping in Windows < 10 1809. */
hr
=
pUiaProviderFromIAccessible
(
&
Accessible
.
IAccessible_iface
,
CHILDID_SELF
,
UIA_PFIA_DEFAULT
,
&
elprov
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
Accessible
.
ref
==
2
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
Accessible
.
role
=
ROLE_SYSTEM_CLOCK
;
SET_EXPECT
(
Accessible_get_accRole
);
VariantClear
(
&
v
);
hr
=
IRawElementProviderSimple_GetPropertyValue
(
elprov
,
UIA_ControlTypePropertyId
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
check_variant_i4
(
&
v
,
UIA_ButtonControlTypeId
)
||
broken
(
V_VT
(
&
v
)
==
VT_EMPTY
),
/* Windows < 10 1809 */
"MSAA role %d: V_I4(&v) = %ld
\n
"
,
Accessible
.
role
,
V_I4
(
&
v
));
CHECK_CALLED
(
Accessible_get_accRole
);
if
(
V_VT
(
&
v
)
==
VT_EMPTY
)
SET_EXPECT
(
Accessible_get_accRole
);
VariantClear
(
&
v
);
hr
=
IRawElementProviderSimple_GetPropertyValue
(
elprov
,
UIA_ControlTypePropertyId
,
&
v
);
ok
(
check_variant_i4
(
&
v
,
UIA_ButtonControlTypeId
)
||
broken
(
V_VT
(
&
v
)
==
VT_EMPTY
),
/* Windows < 10 1809 */
"MSAA role %d: V_I4(&v) = %ld
\n
"
,
Accessible
.
role
,
V_I4
(
&
v
));
if
(
V_VT
(
&
v
)
==
VT_EMPTY
)
CHECK_CALLED
(
Accessible_get_accRole
);
Accessible
.
role
=
0
;
IRawElementProviderSimple_Release
(
elprov
);
ok
(
Accessible
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
}
static
void
test_UiaProviderFromIAccessible
(
void
)
{
IRawElementProviderSimple
*
elprov
;
...
...
@@ -781,6 +943,8 @@ static void test_UiaProviderFromIAccessible(void)
IRawElementProviderSimple_Release
(
elprov
);
ok
(
Accessible
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Accessible
.
ref
);
test_uia_prov_from_acc_properties
();
DestroyWindow
(
hwnd
);
UnregisterClassA
(
"pUiaProviderFromIAccessible class"
,
NULL
);
Accessible
.
acc_hwnd
=
NULL
;
...
...
dlls/uiautomationcore/uia_provider.c
View file @
c250b5c7
...
...
@@ -32,6 +32,85 @@ static void variant_init_i4(VARIANT *v, int val)
V_I4
(
v
)
=
val
;
}
static
LONG
msaa_role_to_uia_control_type
(
LONG
role
)
{
switch
(
role
)
{
case
ROLE_SYSTEM_TITLEBAR
:
return
UIA_TitleBarControlTypeId
;
case
ROLE_SYSTEM_MENUBAR
:
return
UIA_MenuBarControlTypeId
;
case
ROLE_SYSTEM_SCROLLBAR
:
return
UIA_ScrollBarControlTypeId
;
case
ROLE_SYSTEM_INDICATOR
:
case
ROLE_SYSTEM_GRIP
:
return
UIA_ThumbControlTypeId
;
case
ROLE_SYSTEM_APPLICATION
:
case
ROLE_SYSTEM_WINDOW
:
return
UIA_WindowControlTypeId
;
case
ROLE_SYSTEM_MENUPOPUP
:
return
UIA_MenuControlTypeId
;
case
ROLE_SYSTEM_TOOLTIP
:
return
UIA_ToolTipControlTypeId
;
case
ROLE_SYSTEM_DOCUMENT
:
return
UIA_DocumentControlTypeId
;
case
ROLE_SYSTEM_PANE
:
return
UIA_PaneControlTypeId
;
case
ROLE_SYSTEM_GROUPING
:
return
UIA_GroupControlTypeId
;
case
ROLE_SYSTEM_SEPARATOR
:
return
UIA_SeparatorControlTypeId
;
case
ROLE_SYSTEM_TOOLBAR
:
return
UIA_ToolBarControlTypeId
;
case
ROLE_SYSTEM_STATUSBAR
:
return
UIA_StatusBarControlTypeId
;
case
ROLE_SYSTEM_TABLE
:
return
UIA_TableControlTypeId
;
case
ROLE_SYSTEM_COLUMNHEADER
:
case
ROLE_SYSTEM_ROWHEADER
:
return
UIA_HeaderControlTypeId
;
case
ROLE_SYSTEM_CELL
:
return
UIA_DataItemControlTypeId
;
case
ROLE_SYSTEM_LINK
:
return
UIA_HyperlinkControlTypeId
;
case
ROLE_SYSTEM_LIST
:
return
UIA_ListControlTypeId
;
case
ROLE_SYSTEM_LISTITEM
:
return
UIA_ListItemControlTypeId
;
case
ROLE_SYSTEM_OUTLINE
:
return
UIA_TreeControlTypeId
;
case
ROLE_SYSTEM_OUTLINEITEM
:
return
UIA_TreeItemControlTypeId
;
case
ROLE_SYSTEM_PAGETAB
:
return
UIA_TabItemControlTypeId
;
case
ROLE_SYSTEM_GRAPHIC
:
return
UIA_ImageControlTypeId
;
case
ROLE_SYSTEM_STATICTEXT
:
return
UIA_TextControlTypeId
;
case
ROLE_SYSTEM_TEXT
:
return
UIA_EditControlTypeId
;
case
ROLE_SYSTEM_CLOCK
:
case
ROLE_SYSTEM_BUTTONDROPDOWNGRID
:
case
ROLE_SYSTEM_PUSHBUTTON
:
return
UIA_ButtonControlTypeId
;
case
ROLE_SYSTEM_CHECKBUTTON
:
return
UIA_CheckBoxControlTypeId
;
case
ROLE_SYSTEM_RADIOBUTTON
:
return
UIA_RadioButtonControlTypeId
;
case
ROLE_SYSTEM_COMBOBOX
:
return
UIA_ComboBoxControlTypeId
;
case
ROLE_SYSTEM_PROGRESSBAR
:
return
UIA_ProgressBarControlTypeId
;
case
ROLE_SYSTEM_SLIDER
:
return
UIA_SliderControlTypeId
;
case
ROLE_SYSTEM_SPINBUTTON
:
return
UIA_SpinnerControlTypeId
;
case
ROLE_SYSTEM_BUTTONMENU
:
case
ROLE_SYSTEM_MENUITEM
:
return
UIA_MenuItemControlTypeId
;
case
ROLE_SYSTEM_PAGETABLIST
:
return
UIA_TabControlTypeId
;
case
ROLE_SYSTEM_BUTTONDROPDOWN
:
case
ROLE_SYSTEM_SPLITBUTTON
:
return
UIA_SplitButtonControlTypeId
;
case
ROLE_SYSTEM_SOUND
:
case
ROLE_SYSTEM_CURSOR
:
case
ROLE_SYSTEM_CARET
:
case
ROLE_SYSTEM_ALERT
:
case
ROLE_SYSTEM_CLIENT
:
case
ROLE_SYSTEM_CHART
:
case
ROLE_SYSTEM_DIALOG
:
case
ROLE_SYSTEM_BORDER
:
case
ROLE_SYSTEM_COLUMN
:
case
ROLE_SYSTEM_ROW
:
case
ROLE_SYSTEM_HELPBALLOON
:
case
ROLE_SYSTEM_CHARACTER
:
case
ROLE_SYSTEM_PROPERTYPAGE
:
case
ROLE_SYSTEM_DROPLIST
:
case
ROLE_SYSTEM_DIAL
:
case
ROLE_SYSTEM_HOTKEYFIELD
:
case
ROLE_SYSTEM_DIAGRAM
:
case
ROLE_SYSTEM_ANIMATION
:
case
ROLE_SYSTEM_EQUATION
:
case
ROLE_SYSTEM_WHITESPACE
:
case
ROLE_SYSTEM_IPADDRESS
:
case
ROLE_SYSTEM_OUTLINEBUTTON
:
WARN
(
"No UIA control type mapping for MSAA role %ld
\n
"
,
role
);
break
;
default:
FIXME
(
"UIA control type mapping unimplemented for MSAA role %ld
\n
"
,
role
);
break
;
}
return
0
;
}
/*
* UiaProviderFromIAccessible IRawElementProviderSimple interface.
*/
...
...
@@ -42,6 +121,7 @@ struct msaa_provider {
IAccessible
*
acc
;
VARIANT
cid
;
HWND
hwnd
;
LONG
control_type
;
};
static
inline
struct
msaa_provider
*
impl_from_msaa_provider
(
IRawElementProviderSimple
*
iface
)
...
...
@@ -106,9 +186,14 @@ HRESULT WINAPI msaa_provider_GetPatternProvider(IRawElementProviderSimple *iface
HRESULT
WINAPI
msaa_provider_GetPropertyValue
(
IRawElementProviderSimple
*
iface
,
PROPERTYID
prop_id
,
VARIANT
*
ret_val
)
{
struct
msaa_provider
*
msaa_prov
=
impl_from_msaa_provider
(
iface
);
HRESULT
hr
;
VARIANT
v
;
TRACE
(
"%p, %d, %p
\n
"
,
iface
,
prop_id
,
ret_val
);
VariantInit
(
ret_val
);
VariantInit
(
&
v
);
switch
(
prop_id
)
{
case
UIA_ProviderDescriptionPropertyId
:
...
...
@@ -116,6 +201,19 @@ HRESULT WINAPI msaa_provider_GetPropertyValue(IRawElementProviderSimple *iface,
V_BSTR
(
ret_val
)
=
SysAllocString
(
L"Wine: MSAA Proxy"
);
break
;
case
UIA_ControlTypePropertyId
:
if
(
!
msaa_prov
->
control_type
)
{
hr
=
IAccessible_get_accRole
(
msaa_prov
->
acc
,
msaa_prov
->
cid
,
&
v
);
if
(
SUCCEEDED
(
hr
)
&&
(
V_VT
(
&
v
)
==
VT_I4
))
msaa_prov
->
control_type
=
msaa_role_to_uia_control_type
(
V_I4
(
&
v
));
}
if
(
msaa_prov
->
control_type
)
variant_init_i4
(
ret_val
,
msaa_prov
->
control_type
);
break
;
default:
FIXME
(
"Unimplemented propertyId %d
\n
"
,
prop_id
);
break
;
...
...
@@ -192,7 +290,7 @@ HRESULT WINAPI UiaProviderFromIAccessible(IAccessible *acc, long child_id, DWORD
if
(
!
hwnd
)
return
E_FAIL
;
msaa_prov
=
heap_alloc
(
sizeof
(
*
msaa_prov
));
msaa_prov
=
heap_alloc
_zero
(
sizeof
(
*
msaa_prov
));
if
(
!
msaa_prov
)
return
E_OUTOFMEMORY
;
...
...
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