1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef UI_VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_WIN_H_
6 #define UI_VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_WIN_H_
12 #include <UIAutomationCore.h>
17 #include "third_party/iaccessible2/ia2_api_all.h"
18 #include "ui/accessibility/ax_view_state.h"
19 #include "ui/views/accessibility/native_view_accessibility.h"
20 #include "ui/views/controls/native/native_view_host.h"
21 #include "ui/views/view.h"
24 enum TextBoundaryDirection
;
25 enum TextBoundaryType
;
30 ////////////////////////////////////////////////////////////////////////////////
32 // NativeViewAccessibilityWin
34 // Class implementing the MSAA IAccessible COM interface for a generic View,
35 // providing accessibility to be used by screen readers and other assistive
38 ////////////////////////////////////////////////////////////////////////////////
39 class __declspec(uuid("26f5641a-246d-457b-a96d-07f3fae6acf2"))
40 NativeViewAccessibilityWin
41 : public CComObjectRootEx
<CComMultiThreadModel
>,
42 public IDispatchImpl
<IAccessible2_2
, &IID_IAccessible2_2
,
43 &LIBID_IAccessible2Lib
>,
44 public IAccessibleText
,
45 public IServiceProvider
,
47 public IRawElementProviderSimple
,
48 public NativeViewAccessibility
{
50 BEGIN_COM_MAP(NativeViewAccessibilityWin
)
51 COM_INTERFACE_ENTRY2(IDispatch
, IAccessible2_2
)
52 COM_INTERFACE_ENTRY(IAccessible
)
53 COM_INTERFACE_ENTRY(IAccessible2
)
54 COM_INTERFACE_ENTRY(IAccessible2_2
)
55 COM_INTERFACE_ENTRY(IAccessibleEx
)
56 COM_INTERFACE_ENTRY(IAccessibleText
)
57 COM_INTERFACE_ENTRY(IRawElementProviderSimple
)
58 COM_INTERFACE_ENTRY(IServiceProvider
)
61 virtual ~NativeViewAccessibilityWin();
63 // NativeViewAccessibility.
64 virtual void NotifyAccessibilityEvent(
65 ui::AXEvent event_type
) OVERRIDE
;
66 virtual gfx::NativeViewAccessible
GetNativeObject() OVERRIDE
;
67 virtual void Destroy() OVERRIDE
;
69 // Supported IAccessible methods.
71 // Retrieves the child element or child object at a given point on the screen.
72 virtual STDMETHODIMP
accHitTest(LONG x_left
, LONG y_top
, VARIANT
* child
);
74 // Performs the object's default action.
75 STDMETHODIMP
accDoDefaultAction(VARIANT var_id
);
77 // Retrieves the specified object's current screen location.
78 STDMETHODIMP
accLocation(LONG
* x_left
,
84 // Traverses to another UI element and retrieves the object.
85 STDMETHODIMP
accNavigate(LONG nav_dir
, VARIANT start
, VARIANT
* end
);
87 // Retrieves an IDispatch interface pointer for the specified child.
88 virtual STDMETHODIMP
get_accChild(VARIANT var_child
, IDispatch
** disp_child
);
90 // Retrieves the number of accessible children.
91 virtual STDMETHODIMP
get_accChildCount(LONG
* child_count
);
93 // Retrieves a string that describes the object's default action.
94 STDMETHODIMP
get_accDefaultAction(VARIANT var_id
, BSTR
* default_action
);
96 // Retrieves the tooltip description.
97 STDMETHODIMP
get_accDescription(VARIANT var_id
, BSTR
* desc
);
99 // Retrieves the object that has the keyboard focus.
100 STDMETHODIMP
get_accFocus(VARIANT
* focus_child
);
102 // Retrieves the specified object's shortcut.
103 STDMETHODIMP
get_accKeyboardShortcut(VARIANT var_id
, BSTR
* access_key
);
105 // Retrieves the name of the specified object.
106 STDMETHODIMP
get_accName(VARIANT var_id
, BSTR
* name
);
108 // Retrieves the IDispatch interface of the object's parent.
109 STDMETHODIMP
get_accParent(IDispatch
** disp_parent
);
111 // Retrieves information describing the role of the specified object.
112 STDMETHODIMP
get_accRole(VARIANT var_id
, VARIANT
* role
);
114 // Retrieves the current state of the specified object.
115 STDMETHODIMP
get_accState(VARIANT var_id
, VARIANT
* state
);
117 // Retrieve or set the string value associated with the specified object.
118 // Setting the value is not typically used by screen readers, but it's
119 // used frequently by automation software.
120 STDMETHODIMP
get_accValue(VARIANT var_id
, BSTR
* value
);
121 STDMETHODIMP
put_accValue(VARIANT var_id
, BSTR new_value
);
123 // Selections not applicable to views.
124 STDMETHODIMP
get_accSelection(VARIANT
* selected
);
125 STDMETHODIMP
accSelect(LONG flags_sel
, VARIANT var_id
);
127 // Help functions not supported.
128 STDMETHODIMP
get_accHelp(VARIANT var_id
, BSTR
* help
);
129 STDMETHODIMP
get_accHelpTopic(BSTR
* help_file
,
133 // Deprecated functions, not implemented here.
134 STDMETHODIMP
put_accName(VARIANT var_id
, BSTR put_name
);
140 STDMETHODIMP
role(LONG
* role
);
142 STDMETHODIMP
get_states(AccessibleStates
* states
);
144 STDMETHODIMP
get_uniqueID(LONG
* unique_id
);
146 STDMETHODIMP
get_windowHandle(HWND
* window_handle
);
148 STDMETHODIMP
get_relationTargetsOfType(BSTR type
,
153 STDMETHODIMP
get_attributes(BSTR
* attributes
);
156 // IAccessible2 methods not implemented.
159 STDMETHODIMP
get_attribute(BSTR name
, VARIANT
* attribute
) {
162 STDMETHODIMP
get_indexInParent(LONG
* index_in_parent
) {
165 STDMETHODIMP
get_extendedRole(BSTR
* extended_role
) {
168 STDMETHODIMP
get_nRelations(LONG
* n_relations
) {
171 STDMETHODIMP
get_relation(LONG relation_index
,
172 IAccessibleRelation
** relation
) {
175 STDMETHODIMP
get_relations(LONG max_relations
,
176 IAccessibleRelation
** relations
,
180 STDMETHODIMP
scrollTo(enum IA2ScrollType scroll_type
) {
183 STDMETHODIMP
scrollToPoint(
184 enum IA2CoordinateType coordinate_type
,
189 STDMETHODIMP
get_groupPosition(LONG
* group_level
,
190 LONG
* similar_items_in_group
,
191 LONG
* position_in_group
) {
194 STDMETHODIMP
get_localizedExtendedRole(
195 BSTR
* localized_extended_role
) {
198 STDMETHODIMP
get_nExtendedStates(LONG
* n_extended_states
) {
201 STDMETHODIMP
get_extendedStates(LONG max_extended_states
,
202 BSTR
** extended_states
,
203 LONG
* n_extended_states
) {
206 STDMETHODIMP
get_localizedExtendedStates(
207 LONG max_localized_extended_states
,
208 BSTR
** localized_extended_states
,
209 LONG
* n_localized_extended_states
) {
212 STDMETHODIMP
get_locale(IA2Locale
* locale
) {
215 STDMETHODIMP
get_accessibleWithCaret(IUnknown
** accessible
,
216 long* caret_offset
) {
221 // IAccessibleText methods.
224 STDMETHODIMP
get_nCharacters(LONG
* n_characters
);
226 STDMETHODIMP
get_caretOffset(LONG
* offset
);
228 STDMETHODIMP
get_nSelections(LONG
* n_selections
);
230 STDMETHODIMP
get_selection(LONG selection_index
,
234 STDMETHODIMP
get_text(LONG start_offset
, LONG end_offset
, BSTR
* text
);
236 STDMETHODIMP
get_textAtOffset(LONG offset
,
237 enum IA2TextBoundaryType boundary_type
,
238 LONG
* start_offset
, LONG
* end_offset
,
241 STDMETHODIMP
get_textBeforeOffset(LONG offset
,
242 enum IA2TextBoundaryType boundary_type
,
243 LONG
* start_offset
, LONG
* end_offset
,
246 STDMETHODIMP
get_textAfterOffset(LONG offset
,
247 enum IA2TextBoundaryType boundary_type
,
248 LONG
* start_offset
, LONG
* end_offset
,
251 STDMETHODIMP
get_offsetAtPoint(LONG x
, LONG y
,
252 enum IA2CoordinateType coord_type
,
256 // IAccessibleText methods not implemented.
259 STDMETHODIMP
get_newText(IA2TextSegment
* new_text
) {
262 STDMETHODIMP
get_oldText(IA2TextSegment
* old_text
) {
265 STDMETHODIMP
addSelection(LONG start_offset
, LONG end_offset
) {
268 STDMETHODIMP
get_attributes(LONG offset
,
271 BSTR
* text_attributes
) {
274 STDMETHODIMP
get_characterExtents(LONG offset
,
275 enum IA2CoordinateType coord_type
,
277 LONG
* width
, LONG
* height
) {
280 STDMETHODIMP
removeSelection(LONG selection_index
) {
283 STDMETHODIMP
setCaretOffset(LONG offset
) {
286 STDMETHODIMP
setSelection(LONG selection_index
,
291 STDMETHODIMP
scrollSubstringTo(LONG start_index
,
293 enum IA2ScrollType scroll_type
) {
296 STDMETHODIMP
scrollSubstringToPoint(LONG start_index
,
298 enum IA2CoordinateType coordinate_type
,
304 // IServiceProvider methods.
307 STDMETHODIMP
QueryService(REFGUID guidService
, REFIID riid
, void** object
);
310 // IAccessibleEx methods not implemented.
312 STDMETHODIMP
GetObjectForChild(long child_id
, IAccessibleEx
** ret
) {
316 STDMETHODIMP
GetIAccessiblePair(IAccessible
** acc
, long* child_id
) {
320 STDMETHODIMP
GetRuntimeId(SAFEARRAY
** runtime_id
) {
324 STDMETHODIMP
ConvertReturnedElement(IRawElementProviderSimple
* element
,
325 IAccessibleEx
** acc
) {
330 // IRawElementProviderSimple methods.
332 // The GetPatternProvider/GetPropertyValue methods need to be implemented for
333 // the on-screen keyboard to show up in Windows 8 metro.
334 STDMETHODIMP
GetPatternProvider(PATTERNID id
, IUnknown
** provider
);
335 STDMETHODIMP
GetPropertyValue(PROPERTYID id
, VARIANT
* ret
);
338 // IRawElementProviderSimple methods not implemented.
340 STDMETHODIMP
get_ProviderOptions(enum ProviderOptions
* ret
) {
344 STDMETHODIMP
get_HostRawElementProvider(
345 IRawElementProviderSimple
** provider
) {
351 // Returns a conversion from the event (as defined in ax_enums.idl)
353 static int32
MSAAEvent(ui::AXEvent event
);
355 // Returns a conversion from the Role (as defined in ax_enums.idl)
357 static int32
MSAARole(ui::AXRole role
);
359 // Returns a conversion from the State (as defined in ax_enums.idl)
360 // to MSAA states set.
361 static int32
MSAAState(const ui::AXViewState
& state
);
364 NativeViewAccessibilityWin();
367 // Determines navigation direction for accNavigate, based on left, up and
368 // previous being mapped all to previous and right, down, next being mapped
369 // to next. Returns true if navigation direction is next, false otherwise.
370 bool IsNavDirNext(int nav_dir
) const;
372 // Determines if the navigation target is within the allowed bounds. Returns
373 // true if it is, false otherwise.
374 bool IsValidNav(int nav_dir
,
377 int upper_bound
) const;
379 // Determines if the child id variant is valid.
380 bool IsValidId(const VARIANT
& child
) const;
382 // Helper function which sets applicable states of view.
383 void SetState(VARIANT
* msaa_state
, View
* view
);
385 // Return the text to use for IAccessibleText.
386 base::string16
TextForIAccessibleText();
388 // If offset is a member of IA2TextSpecialOffsets this function updates the
389 // value of offset and returns, otherwise offset remains unchanged.
390 void HandleSpecialTextOffset(const base::string16
& text
, LONG
* offset
);
392 // Convert from a IA2TextBoundaryType to a ui::TextBoundaryType.
393 ui::TextBoundaryType
IA2TextBoundaryToTextBoundary(IA2TextBoundaryType type
);
395 // Search forwards (direction == 1) or backwards (direction == -1)
396 // from the given offset until the given boundary is found, and
397 // return the offset of that boundary.
398 LONG
FindBoundary(const base::string16
& text
,
399 IA2TextBoundaryType ia2_boundary
,
401 ui::TextBoundaryDirection direction
);
403 // Populates the given vector with all widgets that are either a child
404 // or are owned by this view's widget, and who are not contained in a
406 void PopulateChildWidgetVector(std::vector
<Widget
*>* child_widgets
);
408 // Adds this view to alert_target_view_storage_ids_.
409 void AddAlertTarget();
411 // Removes this view from alert_target_view_storage_ids_.
412 void RemoveAlertTarget();
414 // Give CComObject access to the class constructor.
415 template <class Base
> friend class CComObject
;
417 // A unique id for each object, needed for IAccessible2.
420 // Next unique id to assign.
421 static long next_unique_id_
;
423 // Circular queue size.
424 static const int kMaxViewStorageIds
= 20;
426 // Circular queue of view storage ids corresponding to child ids
427 // used to post notifications using NotifyWinEvent.
428 static int view_storage_ids_
[kMaxViewStorageIds
];
430 // Next index into |view_storage_ids_| to use.
431 static int next_view_storage_id_index_
;
433 // A vector of view storage ids of views that have been the target of
434 // an alert event, in order to provide an api to quickly identify all
436 static std::vector
<int> alert_target_view_storage_ids_
;
438 DISALLOW_COPY_AND_ASSIGN(NativeViewAccessibilityWin
);
443 #endif // UI_VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_WIN_H_