Exposing Data Tables through Microsoft Active Accessibility

Microsoft Corporation

April 2002

Summary: This article explains how to use the Microsoft Active Accessibility IAccessible interface to expose data table information to assistive technologies. This article assumes that you are familiar with the Active Accessibility 2.0 architecture. (19 printed pages)

Introduction

Microsoft Active Accessibility version 2.0 defines a consistent way to expose accessibility information about an application's user interface elements. Assistive technologies collect this information and present it to users as needed.

Because Active Accessibility does not currently support data tables, many assistive technology vendors (ATVs) extract data table information directly from the application's native object model. This technique is time consuming, requires the use of class name-based special casing for each application, and must be updated every time a new application is released.

Currently, Microsoft recommends that application developers use the MSHTML.dll or Microsoft Excel object models to expose data table information in server applications. Both technologies are proven and already supported by many ATVs. However, application developers who cannot support these models need an alternative solution. Microsoft recommends using the Active Accessibility IAccessible interface as an interim solution that will enable assistive technologies to collect data table information, navigate the table, and receive notification when information in the table changes. IAccessible provides the least complicated and most complete way to support data tables, until a permanent solution is developed.

Exposing Data Table Information

Microsoft recommends that you use the existing MSHTML.dll or Excel object model to expose data table information to assistive technologies. However, for application developers who cannot support these models, an alternative solution is to use the IAccessibleinterface implementation described in this article.

The IAccessible interface provides a suitable alternative solution because it uses a well-known set of methods and properties to convey information about user interface elements to assistive technologies. The Active Accessibility ITextStore* interfaces are designed to expose rich text information, such as documents. However, the IAccessible properties and methods are more appropriate for table-based data.

Note

ITextStore* documents containing embedded data tables can support this IAccessible implementation.

The following sections discuss the implementation of Active Accessibility for data tables, describe the IAccessible object roles, present the IAccessible data table hierarchy, and define the IAccessible methods, properties, and events.

IAccessible Object Roles for Data Tables

Use the following IAccessible object role constants to define the data table hierarchy in server applications. Note that each constant is followed by its abbreviated convention, which is used throughout the remainder of the article:

Term Description
ROLE_SYSTEM_TABLE (or Table)
An object that represents a table containing rows and columns of cells, and optionally, row headers and column headers.
ROLE_SYSTEM_ROW (or Row)
An object that represents a row of cells within a table.
ROLE_SYSTEM_COLUMNHEADER (or ColumnHeader)
An object that represents a column header that provides a visual label for a column in a table.
ROLE_SYSTEM_ROWHEADER (or RowHeader)
An object that represents a row header that provides a visual label for a row in a table.
ROLE_SYSTEM_CELL (or Cell)
An object that represents a cell within a table.
ROLE_SYSTEM_COLUMN
An object that represents a column of cells within a table. The ROLE_SYSTEM_COLUMN role is not used because only a row-based table is presented for this solution.

IAccessible Data Table Hierarchy Overview

This article focuses on common row-based tables, and defines the data table structure as a grid of columns, rows, and cells. Cells are restricted to one column of one row. Summary text, if available, is exposed on the overall Table object.

The following tree represents an IAccessible data table hierarchy.

ROLE_SYSTEM_TABLE
  |- ROLE_SYSTEM_ROW
  |  |- ROLE_SYSTEM_ROWHEADER
  |  |- ROLE_SYSTEM_COLUMNHEADER
  |  |- ROLE_SYSTEM_COLUMNHEADER
  |  |- ROLE_SYSTEM_COLUMNHEADER
  |     '- ..
  |- ROLE_SYSTEM_ROW
  |  |- ROLE_SYSTEM_ROWHEADER
  |  |- ROLE_SYSTEM_CELL
  |  |- ROLE_SYSTEM_CELL
  |  |- ROLE_SYSTEM_CELL
  |   '- ..
  |- ROLE_SYSTEM_ROW
  |  |- ROLE_SYSTEM_ROWHEADER
  |  |- ROLE_SYSTEM_CELL
  |  |- ROLE_SYSTEM_CELL
  |  |- ROLE_SYSTEM_CELL
  |   '- ..
   '- ..

As previously defined, a Table object is a collection of one or more Row objects, where each Row object is the parent of one or more children. A Row object can contain one or more Cell objects. However, all Row objects must have the same number of Cell objects. Although not shown in the IAccessible data table hierarchy, a Cell object is also a container that can have an arbitrarily deep hierarchy of IAccessible objects with any valid role. For example, a nested or embedded table is represented by placing a Table object inside a Cell object.

Note

For improved performance, a server application can create an IAccessible object on demand, in response to the WM_GETOBJECT windows message or the IAccessible::get_accChild method. After creating an IAccessible object, it is managed like any other standard COM object.

IAccessible Methods and Properties for Data Tables

The following tables are organized by object role, and briefly describe the IAccessible methods and properties required to support data tables. In-depth descriptions and implementations are available in the Microsoft Windows Software Development Kit (SDK). .

ROLE_SYSTEM_TABLE

Method Description
[IAccessible::accDoDefaultAction](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accdodefaultaction) Returns DISP_E_MEMBERNOTFOUND; this property is not supported.
[IAccessible::accHitTest](/windows/win32/api/oleacc/nf-oleacc-iaccessible-acchittest) Returns the Table object or one of its children based on the screen coordinates.
[IAccessible::accLocation](/windows/win32/api/oleacc/nf-oleacc-iaccessible-acclocation) Returns the Table object's current screen location.
[IAccessible::accNavigate](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accnavigate) The [IAccessible](/windows/win32/api/oleacc/nn-oleacc-iaccessible) object returned is determined by the navigational constant passed to this method.
Spatial navigation returns a sibling of the Table object.
Logical navigation:
  • NAVDIR_NEXT or NAVDIR_PREV returns a sibling of the Table object.
  • NAVDIR_PARENT returns the Table object's parent.
  • NAVDIR_FIRSTCHILD or NAVDIR_LASTCHILD returns the appropriate Row object.
For more information, see [IAccessible::accNavigate Additional Information](#iaccessibleacc-navigate-additional-information).
[IAccessible::accSelect](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accselect) Adds or removes the selection for the entire Table object.
[IAccessible::get_accChild](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accchild) Returns an [IDispatch](/windows/win32/winauto/idispatch-interface) interface pointer of role type Row for the specified child.
[IAccessible::get_accChildCount](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accchildcount) Returns the total number of rows.
[IAccessible::get_accDefaultAction](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accdefaultaction) Returns DISP_E_MEMBERNOTFOUND; this property is not supported.
[IAccessible::get_accDescription](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accdescription) Returns DISP_E_MEMBERNOTFOUND, a string containing the table's summary text, or a string containing the number of rows and columns.
For example, current status and owners of all active documents. Or 6 Rows, 3 Columns.
For more information, see [IAccessible::get_accDescription Alternatives](#iaccessibleget-accdescription-alternatives).
[IAccessible::get_accFocus](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accfocus) Returns the descendant of the Table object that has the input focus.
[IAccessible::get_accHelp](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acchelp) Returns DISP_E_MEMBERNOTFOUND or a localized string containing the table's Help property string.
[IAccessible::get_accHelpTopic](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acchelptopic) Returns DISP_E_MEMBERNOTFOUND or the full path of the WinHelp file associated with the Table object and the identifier of the appropriate topic within that file.
[IAccessible::get_accKeyboardShortcut](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acckeyboardshortcut) Returns DISP_E_MEMBERNOTFOUND or the Table object's shortcut key or access key.
[IAccessible::get_accName](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accname) Returns a localized string containing the Table object's name or summary text.
[IAccessible::get_accParent](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accparent) Returns the [IDispatch](/windows/win32/winauto/idispatch-interface) interface of the Table object.
[IAccessible::get_accSelection](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accselection) Returns a collection of selected Cell objects.
[IAccessible::get_accState](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accstate) Returns a bitmask representing the current state of the Table object.
[IAccessible::get_accValue](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accvalue) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.

ROLE_SYSTEM_ROW

Method Description
[IAccessible::accDoDefaultAction](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accdodefaultaction) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.
[IAccessible::accHitTest](/windows/win32/api/oleacc/nf-oleacc-iaccessible-acchittest) Returns the Row object or one of its children based on a given point on the screen.
[IAccessible::accLocation](/windows/win32/api/oleacc/nf-oleacc-iaccessible-acclocation) Returns the Row object's current screen location.
[IAccessible::accNavigate](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accnavigate) The [IAccessible](/windows/win32/api/oleacc/nn-oleacc-iaccessible) object returned is determined by the navigational constant passed to this method.
Spatial navigation:
  • NAVDIR_UP or NAVDIR_DOWN returns another Row object or S_FALSE, if navigating from the top or bottom row, respectively.
  • NAVDIR_LEFT and NAVDIR_RIGHT always return S_FALSE.
Logical navigation:
  • NAVDIR_PARENT returns the Table object.
  • NAVDIR_PREV or NAVDIR_NEXT returns another Row object or S_FALSE, if navigating from the first or last Row object, respectively.
  • NAVDIR_FIRSTCHILD or NAVDIR_LASTCHILD returns a Cell, RowHeader, or ColumnHeader object.
For more information, see [IAccessible::accNavigate Additional Information](#iaccessibleacc-navigate-additional-information).
[IAccessible::accSelect](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accselect) Adds or removes a selection on a Row object.
[IAccessible::get_accChild](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accchild) Returns an [IDispatch](/windows/win32/winauto/idispatch-interface) interface pointer for the specified Cell, ColumnHeader, or RowHeader object.
[IAccessible::get_accChildCount](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accchildcount) Returns the number of columns in the table.
[IAccessible::get_accDefaultAction](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accdefaultaction) Returns DISP_E_MEMBERNOTFOUND; this property is not supported.
[IAccessible::get_accDescription](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accdescription) Returns DISP_E_MEMBERNOTFOUND or a localized string containing the summary of a specific Row object's information.
For example, Row3: Sales_Midwest_Q2.doc, Jill, Reviewed.
For more information, see [IAccessible::get_accDescription Alternatives](#iaccessibleget-accdescription-alternatives).
[IAccessible::get_accFocus](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accfocus) Returns the descendant of the Row object that has the input focus.
[IAccessible::get_accHelp](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acchelp) Returns DISP_E_MEMBERNOTFOUND or a localized string containing the Row object's Help property string.
[IAccessible::get_accHelpTopic](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acchelptopic) Returns DISP_E_MEMBERNOTFOUND or the full path of the WinHelp file associated with the Row object and the identifier of the appropriate topic within that file.
[IAccessible::get_accKeyboardShortcut](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acckeyboardshortcut) Returns DISP_E_MEMBERNOTFOUND or the Row object's shortcut key or access key.
[IAccessible::get_accName](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accname) Returns NULL, or a localized descriptive title, such as the "Header Row" or "New Row".
[IAccessible::get_accParent](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accparent) Returns the [IDispatch](/windows/win32/winauto/idispatch-interface) interface of the Table object.
[IAccessible::get_accSelection](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accselection) Returns a collection of Cell object's that are selected within the Row object.
[IAccessible::get_accState](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accstate) Returns a bitmask representing the current state of the Row object.
When exposing a large table with rows that may be scrolled out of view, it is important to mark the appropriate cells and rows as STATE_SYSTEM_INVISIBLE, and send the appropriate state change events.
[IAccessible::get_accValue](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accvalue) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.

ROLE_SYSTEM_COLUMNHEADER and ROLE_SYSTEM_ROWHEADER

Method Description
[IAccessible::accDoDefaultAction](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accdodefaultaction) Returns DISP_E_MEMBERNOTFOUND; this property is not supported.
[IAccessible::accHitTest](/windows/win32/api/oleacc/nf-oleacc-iaccessible-acchittest) Returns the ColumnHeader object, RowHeader object, or one of its children based on a given point on the screen.
[IAccessible::accLocation](/windows/win32/api/oleacc/nf-oleacc-iaccessible-acclocation) Returns the ColumnHeader or RowHeader object's current screen location.
[IAccessible::accNavigate](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accnavigate) The [IAccessible](/windows/win32/api/oleacc/nn-oleacc-iaccessible) object returned is determined by the navigational constant passed to this method.
Spatial navigation returns a Cell, RowHeader, or ColumnHeader object, or S_FALSE, if no other cell exists in the specified direction.
Logical navigation:
  • NAVDIR_PARENT returns the parent Row object.
  • NAVDIR_PREV or NAVDIR_NEXT returns a Cell, RowHeader, or ColumnHeader object, or S_FALSE, if navigating from the first or last cell, respectively, in a row.
  • NAVDIR_FIRSTCHILD or NAVDIR_LASTCHILD returns a valid child of the RowHeader, or ColumnHeader object, or S_FALSE, if it has no children.
For more information, see [IAccessible::accNavigate Additional Information](#iaccessibleacc-navigate-additional-information).
[IAccessible::accSelect](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accselect) Adds or removes the selection, or sets the focus.
[IAccessible::get_accChild](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accchild) Returns an [IDispatch](/windows/win32/winauto/idispatch-interface) interface pointer for the specified child, if one exists. Depending on the table's implementation, children are not limited to simple text.
[IAccessible::get_accChildCount](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accchildcount) Returns the number of children that belong to the ColumnHeader or RowHeader object. The column or row header can have more than one child.
[IAccessible::get_accDefaultAction](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accdefaultaction) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.
[IAccessible::get_accDescription](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accdescription) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.
[IAccessible::get_accFocus](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accfocus) Returns the descendant of the ColumnHeader or RowHeader object that has the input focus.
[IAccessible::get_accHelp](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acchelp) Returns DISP_E_MEMBERNOTFOUND or a localized string containing the ColumnHeader or RowHeader object's HELP property string.
[IAccessible::get_accHelpTopic](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acchelptopic) Returns DISP_E_MEMBERNOTFOUND or the full path of the WinHelp file associated with a ColumnHeader or RowHeader object and the identifier of the appropriate topic within that file.
[IAccessible::get_accKeyboardShortcut](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acckeyboardshortcut) Returns DISP_E_MEMBERNOTFOUND or the ColumnHeader or RowHeader object's shortcut key or access key.
[IAccessible::get_accName](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accname) Returns a localized string that is visually displayed as the ColumnHeader or RowHeader object.
[IAccessible::get_accParent](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accparent) Returns the [IDispatch](/windows/win32/winauto/idispatch-interface) interface of the parent Row object.
[IAccessible::get_accSelection](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accselection) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.
[IAccessible::get_accState](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accstate) Returns a bitmask representing the current state of the ColumnHeader or RowHeader object.
[IAccessible::get_accValue](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accvalue) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.

ROLE_SYSTEM_CELL

Method Description
[IAccessible::accDoDefaultAction](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accdodefaultaction) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.
[IAccessible::accHitTest](/windows/win32/api/oleacc/nf-oleacc-iaccessible-acchittest) Returns the Cell object or one of its children based on a given point on the screen.
[IAccessible::accLocation](/windows/win32/api/oleacc/nf-oleacc-iaccessible-acclocation) Returns the Cell object's current screen location.
[IAccessible::accNavigate](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accnavigate) The [IAccessible](/windows/win32/api/oleacc/nn-oleacc-iaccessible) object returned is determined by the navigational constant passed to this method. Spatial navigation returns a Cell object, RowHeader object, ColumnHeader object or S_FALSE if no other cell exists in the specified direction.
Logical navigation:
  • NAVDIR_PARENT returns the parent Row object.
  • NAVDIR_PREV or NAVDIR_NEXT returns a Cell, or RowHeader object, or S_FALSE if navigating from the first or last cell, respectively, in a row.
  • NAVDIR_FIRSTCHILD or NAVDIR_LASTCHILD returns a valid child of the Cell object, or S_FALSE if it has no children.
For more information, see [IAccessible::accNavigate Additional Information](#iaccessibleacc-navigate-additional-information).
[IAccessible::accSelect](/windows/win32/api/oleacc/nf-oleacc-iaccessible-accselect) Adds or removes selection, or sets focus for a particular Cell object.
[IAccessible::get_accChild](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accchild) Returns an [IDispatch](/windows/win32/winauto/idispatch-interface) interface pointer for the specified child, if one exists. However, children are not limited to simple text.
[IAccessible::get_accChildCount](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accchildcount) Returns the number of children that belong to the Cell object. A Cell object can have more than one child.
[IAccessible::get_accDefaultAction](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accdefaultaction) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.
[IAccessible::get_accDescription](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accdescription) Returns DISP_E_MEMBERNOTFOUND or a localized string containing a summary of specific ColumnHeader and RowHeader object information.
For example: 2, Status.
For more information, see [IAccessible::get_accDescription Alternatives](#iaccessibleget-accdescription-alternatives).
[IAccessible::get_accFocus](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accfocus) Returns the Cell object, or one of its descendants, that has the input focus.
[IAccessible::get_accHelp](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acchelp) Returns DISP_E_MEMBERNOTFOUND or a localized string containing the Cell object's Help property string.
[IAccessible::get_accHelpTopic](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acchelptopic) Returns DISP_E_MEMBERNOTFOUND or the full path of the WinHelp file related to the Cell, and the appropriate topic's identifier located within that file.
[IAccessible::get_accKeyboardShortcut](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_acckeyboardshortcut) Returns DISP_E_MEMBERNOTFOUND or a Cell object's shortcut key or access key.
[IAccessible::get_accName](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accname) Returns a string that represents the Cell object's location within the data table.
[IAccessible::get_accParent](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accparent) Returns the [IDispatch](/windows/win32/winauto/idispatch-interface) interface for the parent Row object.
[IAccessible::get_accSelection](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accselection) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.
[IAccessible::get_accState](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accstate) Returns STATE_SYSTEM_FOCUSED, STATE_SYSTEM_FOCUSABLE, STATE_SYSTEM_INVISIBLE, STATE_SYSTEM_OFFSCREEN, STATE_SYSTEM_SELECTABLE, STATE_SYSTEM_SELECTED, STATE_SYSTEM_MULTISELECTABLE, or according to your implementation, additional states as defined within the [Microsoft Windows Software Development Kit (SDK)](https://go.microsoft.com/fwlink/p/?linkid=208210).
When exposing a large table with rows that may be scrolled out of view, it is important to mark the appropriate cells and rows as STATE_SYSTEM_INVISIBLE, and send the appropriate state change events.
[IAccessible::get_accValue](/windows/win32/api/oleacc/nf-oleacc-iaccessible-get_accvalue) Returns DISP_E_MEMBERNOTFOUND. This property is not supported.

IAccessible::get_accDescription Alternatives

Supporting the IAccessible::get_accDescription method for data table elements is optional. However, when compared to the alternatives listed below, supporting the IAccessible::get_accDescription method involves less development work.

If you choose not to implement the IAccessible::get_accDescription method, then ATVs will have to use the following approaches to obtain the same information:

  • To find the number of rows in the data table, they will call IAccessible::get_accChildCount on the Table object.
  • To find the number of columns in the data table, they will call IAccessible::get_accChildCount on any of the Row objects.
  • To find individual row summary information, they will access each child object of that row.
  • To find row header information for a Cell object, they will locate the sibling RowHeader object and query its children for the desired information. In most cases the RowHeader object will be the first child of the Row object, and can be reached by calling the IAccessible::accNavigate (the Cell object's Parent ID, NAVDIR_FIRSTCHILD) method.
  • To find the column header information for a Cell object, they will locate the appropriate ColumnHeader object and query its children for the desired information. To locate a ColumnHeader object from a Cell object, they call IAccessible::accNavigate (CHILDID_SELF, NAVDIR_UP) repeatedly until a ColumnHeader object is returned.

IAccessible::acc_Navigate Additional Information

Spatial navigation allows a client to traverse an object's IAccessible hierarchy using constants that represent direction: NAVDIR_UP, NAVDIR_DOWN, NAVDIR_LEFT, and NAVDIR_RIGHT. Typically, spatial navigation can be used only to move between siblings in the IAccessible hierarchy. In a dialog box, this means spatial navigation can be used to move from one control to another, but not from a control in the dialog box to another control in an adjacent dialog box. If this rule were applied to Table objects, spatial navigation would be restricted to movement within a single cell or row. The NAVDIR_UP and NAVDIR_DOWN navigation constants would be supported only on Rowobjects. Because spatial navigation between Cell objects is a common scenario, Table objects deviate from this convention and support spatial navigation between containers.

Supporting Events

Active Accessibility relies on Window Events (WinEvents) to notify clients of changes in an application's user interface. The following table provides a brief overview of the WinEvents that are most relevant for data tables. For more information, see WinEvents.

IAccessible Events for Data Tables

Name Description
EVENT_OBJECT_CREATE Event is sent as IAccessibleobjects are created, as a row or column is added to the table. Based on the previous data table definition, a cell will never be created without a Row object.
EVENT_OBJECT_DESTROY Event is sent as IAccessible objects are removed. If the parent Cell or Row object is destroyed, it does not need to be sent for the individual Cell objects or their child objects.
EVENT_OBJECT_REORDER Event is sent for the Table object when its descendants (Row or Cell objects) are reorganized, due to sorting or moving of the table's rows or columns.
EVENT_OBJECT_FOCUS Event is sent, for a Cell object or one of its children, if the user moves the input focus to a new Cell object. Assistive technologies can access information from the children of a Cell object in order to report the contents to the user. If the user moves focus into the contents of the Cell object, then EVENT_OBJECT_FOCUS is sent for the appropriate IAccessible child of that Cell object.
EVENT_OBJECT_SELECTION Event is sent as a user moves from cell to cell. It also occurs if the selection is programmatically changed.
EVENT_OBJECT_SELECTIONADD Event is sent for tables that support multiselection, when the SHIFT + ARROW key combinations are used to increase the selection by Rows or by Cells. It also occurs if the selection is programmatically changed.
EVENT_OBJECT_SELECTIONREMOVE Event is sent for tables that support multiselection, when the SHIFT + ARROW keys are used to decrease the selection by Rows or Cells. It also occurs if the selection is programmatically changed.
EVENT_OBJECT_SELECTIONWITHIN Event is sent on the Table object, if the selected items within the table have significantly changed. It is used instead of sending several EVENT_OBJECT_SELECTIONADD, or EVENT_OBJECT_SELECTIONREMOVE events. It also occurs if the selection is programmatically changed.
Microsoft Active Accessibility 2.0 servers can define a significant change as more than 20 cells.
If a small number of cells are selected as a result of a column or row being selected, an EVENT_OBJECT_SELECTION event occurs on the first cell within that row or column, and the EVENT_OBJECT_SELECTIONADD event occurs on each additional cell. The reverse is true for EVENT_OBJECT_SELECTIONREMOVE events.
EVENT_OBJECT_STATECHANGE Event is sent as the IAccessible::get_accStatemethod is changed.

Note

The hwnd and idObject parameters of the WinEventProc callback function describe the container, while the idChild parameter identifies the event-related object.

Implementing a Data Table

Figure 1 illustrates a data table that tracks business documentation for customers and employees. It is a general solution that does not rely on a specific HWND or native object model support.

In this example, only the input cells have focusable, selectable, and multi-selectable states. The column headers File Name, Owner and Status and the row headers 1, 2, 3, 4 and * are not focusable.

figure 1. data table example

Data Table Example Overview

The following criteria are used to define the hierarchy in Figure 1. First, the role of an IAccessibleobject is defined. Second, the state of an IAccessible object appears in square brackets. Third, the name of an IAccessible object appears in bold italics. Finally, if needed, the value of an IAccessible object appears in double quotes.

The following is the tree view of the data table hierarchy associated with Figure 1.

ROLE_SYSTEM_TABLE <b><i>"Project Status"
</i></b> |- ROLE_SYSTEM_ROW [STATE_SYSTEM_SELECTABLE,
 |  |        STATE_SYSTEM_MULTISELECTABLE] <b><i>"Header Row"
</i></b> |  |- ROLE_SYSTEM_ROWHEADER <b><i>""
</i></b> |  |     '- ROLE_SYSTEM_PUSHBUTTON <b><i>"SelectThe Entire Table"
</i></b> |  |- ROLE_SYSTEM_COLUMNHEADER <b><i>"Column1"
</i></b> |  |     '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_READONLY] <b><i>"File Name"
</i></b> |  |- ROLE_SYSTEM_COLUMNHEADER <b><i>"Column 2"
</i></b> |  |     '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_READONLY] <b><i>"Owner"
</i></b> |     '- ROLE_SYSTEM_COLUMNHEADER <b><i>"Column 3"
</i></b> |          '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_READONLY] <b><i>"Status"
</i></b> |- ROLE_SYSTEM_ROW [STATE_SYSTEM_SELECTABLE,
 |  |        STATE_SYSTEM_MULTISELECTABLE] <b><i>""
</i></b> |  |- ROLE_SYSTEM_ROWHEADER <b><i>"1"
</i></b> |  |    '- ROLE_SYSTEM_PUSHBUTTON <b><i>"Select This Row"
</i></b> |  |- ROLE_SYSTEM_CELL [STATE_SYSTEM_SELECTABLE,
 |  |    |     STATE_SYSTEM_MULTISELECTABLE, STATE_SYSTEM_FOCUSABLE]   <b><i>"Row 1, Column 1"
</i></b> |  |    '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_FOCUSABLE] <b><i>"Midyear review.doc"
</i></b> |  |- ROLE_SYSTEM_CELL [STATE_SYSTEM_SELECTABLE,
 |  |   |      STATE_SYSTEM_MULTISELECTABLE, STATE_SYSTEM_FOCUSABLE] <b><i>"Row 1, Column 2"
</i></b> |  |    '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_FOCUSABLE] <b><i>"Jim"
</i></b> |  '- ROLE_SYSTEM_CELL [STATE_SYSTEM_SELECTABLE,
 |    |   STATE_SYSTEM_MULTISELECTABLE, STATE_SYSTEM_FOCUSABLE] <b><i>"Row 1, Column 3"
</i></b> |         |- ROLE_SYSTEM_STATICTEXT [STATE_SYSTEM_FOCUSABLE]<i> <b>"Completed"
</b></i> |          '- ROLE_SYSTEM_COMBOBOX [STATE_SYSTEM_INVISIBLE,
 |              |         STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"</i></b> "Completed"
 |              |- ROLE_SYSTEM_STATICTEXT [STATE_SYSTEM_INVISIBLE,
 |              |         STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"</i></b> "Completed"
 |              |- ROLE_SYSTEM_PUSHBUTTON [STATE_SYSTEM_INVISIBLE,
 |              |         STATE_SYSTEM_FOCUSABLE]<i> <b>"Open"
</b></i> |               '- ROLE_SYSTEM_LIST [STATE_SYSTEM_INVISIBLE,
 |                   |         STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"
</i></b> |                   |- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_INVISIBLE,
 |                   |         STATE_SYSTEM_FOCUSABLE] <b><i>"Draft"
</i></b> |                   |- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_INVISIBLE,
 |                   |         STATE_SYSTEM_FOCUSABLE] <b><i>"Reviewed"
</i></b> |                    '- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_INVISIBLE,
 |                              STATE_SYSTEM_FOCUSABLE] <b><i>"Completed"
</i></b> |- ROLE_SYSTEM_ROW [STATE_SYSTEM_SELECTABLE,
 |    |        STATE_SYSTEM_MULTISELECTABLE] <b>""
</b> |    |- ROLE_SYSTEM_ROWHEADER <b><i>"2"
</i></b> |    |    |    '- ROLE_SYSTEM_PUSHBUTTON <b><i>"Select This Row"
</i></b> |    |- ROLE_SYSTEM_CELL [STATE_SYSTEM_FOCUSABLE,
 |    |    |        STATE_SYSTEM_SELECTABLE, STATE_SYSTEM_MULTISELECTABLE]
 |    |    |         <b><i>"Row 2, Column 1"
</i></b> |    |     '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_FOCUSABLE] <b><i>"customer visit.doc"
</i></b> |    |- ROLE_SYSTEM_CELL [STATE_SYSTEM_SELECTABLE,
 |    |   |          STATE_SYSTEM_MULTISELECTABLE, STATE_SYSTEM_FOCUSABLE] <b><i>"Row 2, Column 2"
</i></b> |    |    '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_FOCUSABLE] <b><i>"Jim"
          </i></b> |  '- ROLE_SYSTEM_CELL [STATE_SYSTEM_SELECTABLE,
           STATE_SYSTEM_MULTISELECTABLE,       |
           STATE_SYSTEM_FOCUSABLE]     <b><i>"Row 2, Column 3"
</i></b> |         |- ROLE_SYSTEM_STATICTEXT [STATE_SYSTEM_INVISIBLE,
 |         |         STATE_SYSTEM_FOCUSABLE]<i> <b>"Draft"
</b></i> |          '- ROLE_SYSTEM_COMBOBOX [STATE_SYSTEM_FOCUSABLE] <b><i>"Status:" </i></b>"Draft"
 |              |- ROLE_SYSTEM_STATICTEXT [STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"</i></b> "Draft"
 |              |- ROLE_SYSTEM_PUSHBUTTON [STATE_SYSTEM_FOCUSABLE]<i><b>"Open"
</b></i> |               '- ROLE_SYSTEM_LIST [STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"
</i></b> |                   |- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_FOCUSABLE, STATE_SYSTEM_FOCUSED] <b><i>"Draft"
</i></b> |                   |- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_FOCUSABLE] <b><i>"Reviewed"
</i></b> |                    '- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_FOCUSABLE] <b><i>"Completed"
</i></b> |- ROLE_SYSTEM_ROW [STATE_SYSTEM_SELECTABLE, STATE_SYSTEM_MULTISELECTABLE] <b>""
</b> |    |              |   |- ROLE_SYSTEM_ROWHEADER <b><i>"3"
</i></b> |    |    '- ROLE_SYSTEM_PUSHBUTTON <b><i>"Select This Row"
</i></b> |    |- ROLE_SYSTEM_CELL [STATE_SYSTEM_SELECTABLE, STATE_SYSTEM_MULTISELECTABLE,
 |    |    |        STATE_SYSTEM_FOCUSABLE] <b><i>"Row 3, Column 1"
</i></b> |    |     '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_FOCUSABLE] <b><i>"Sales_Midwest_Q2.doc"
</i></b> |    |- ROLE_SYSTEM_CELL [STATE_SYSTEM_SELECTABLE,
 |    |    |        STATE_SYSTEM_MULTISELECTABLE, STATE_SYSTEM_FOCUSABLE] <b><i>"Row 3, Column 2"
</i></b> |    |     '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_FOCUSABLE] <b><i>"Jill"
</i></b> |     '- ROLE_SYSTEM_CELL [STATE_SYSTEM_SELECTABLE,
 |         |         STATE_SYSTEM_MULTISELECTABLE, STATE_SYSTEM_FOCUSABLE]
 |         |         <b><i>"Row 3, Column 3"
</i></b> |         |- ROLE_SYSTEM_STATICTEXT [STATE_SYSTEM_FOCUSABLE]<i><b>"Reviewed"
</b></i> |          '- ROLE_SYSTEM_COMBOBOX [STATE_SYSTEM_INVISIBLE,
 |              |         STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"</i></b> "Reviewed"
 |              |- ROLE_SYSTEM_STATICTEXT [STATE_SYSTEM_INVISIBLE,
 |              |         STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"</i></b> "Reviewed"
 |              |- ROLE_SYSTEM_PUSHBUTTON [STATE_SYSTEM_INVISIBLE,
 |              |         STATE_SYSTEM_FOCUSABLE]<i><b>"Open"
</b></i> |               '- ROLE_SYSTEM_LIST [STATE_SYSTEM_INVISIBLE,
 |                   |         STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"
</i></b> |                   |- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_INVISIBLE,
 |                   |         STATE_SYSTEM_FOCUSABLE] <b><i>"Draft"
</i></b> |                   |- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_INVISIBLE,
 |                   |         STATE_SYSTEM_FOCUSABLE] <b><i>"Reviewed"
</i></b> |                    '- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_INVISIBLE,
 |                             STATE_SYSTEM_FOCUSABLE] <b><i>"Completed"
</i></b>   '- ROLE_SYSTEM_ROW, STATE_SYSTEM_SELECTABLE,
          |         STATE_SYSTEM_MULTISELECTABLE] <b>""
</b>          |- ROWHEADER [ROLE_SYSTEM_ROWHEADER] <b>"*"
</b>          |     '- ROLE_SYSTEM_PUSHBUTTON <b><i>"Select This Row"</i></b>  
          |- ROLE_SYSTEM_CELL [STATE_SYSTEM_SELECTABLE,
          |    |         STATE_SYSTEM_MULTISELECTABLE, STATE_SYSTEM_FOCUSABLE] <b><i>"New Row, Column 1"
</i></b>          |     '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_FOCUSABLE] <b>""
</b>          |- ROLE_SYSTEM_CELL, [STATE_SYSTEM_SELECTABLE,
          |    |         STATE_SYSTEM_MULTISELECTABLE, STATE_SYSTEM_FOCUSABLE] <b><i>"New Row, Column 2"
</i></b>          |     '- ROLE_SYSTEM_TEXT [STATE_SYSTEM_FOCUSABLE] <b>""
</b>           '- ROLE_SYSTEM_CELL [STATE_SYSTEM_SELECTABLE,
               |          STATE_SYSTEM_MULTISELECTABLE, STATE_SYSTEM_FOCUSABLE] <b><i>"New Row, Column 3"
</i></b>               |- ROLE_SYSTEM_STATICTEXT [STATE_SYSTEM_FOCUSABLE]<b><i> ""
</i></b>                '- ROLE_SYSTEM_COMBOBOX [STATE_SYSTEM_INVISIBLE,
                    |         STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"</i></b> ""
                    |- ROLE_SYSTEM_STATICTEXT [STATE_SYSTEM_INVISIBLE,
                    |         STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"</i></b> ""
                    |- ROLE_SYSTEM_PUSHBUTTON [STATE_SYSTEM_INVISIBLE,
                    |         STATE_SYSTEM_FOCUSABLE]<i><b>"Open"
</b></i>                     '- ROLE_SYSTEM_LIST [STATE_SYSTEM_INVISIBLE,
                          |        STATE_SYSTEM_FOCUSABLE] <b><i>"Status:"</i></b>
                          |- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_INVISIBLE,
                          |        STATE_SYSTEM_FOCUSABLE] <b><i>"Draft"
</i></b>                          |- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_INVISIBLE,
                          |        STATE_SYSTEM_FOCUSABLE] <b><i>"Reviewed"
</i></b>                           '- ROLE_SYSTEM_LISTITEM [STATE_SYSTEM_INVISIBLE,
                                    STATE_SYSTEM_FOCUSABLE] <b><i>"Completed"</i></b>

Example of Event Support

The following scenario relates to the data table example in Figure 1 and describes the events that occur within it.

  1. The input focus and selection is on the first child (Draft) of a drop-down list box located in the Status column of the second row.
  2. The user navigates in the drop-down list box by using the UP ARROW and DOWN ARROW keys, which changes the input focus and selection.
  3. The EVENT_OBJECT_FOCUS and the EVENT_OBJECT_SELECTION events are sent, as if the drop-down list box is contained within a traditional dialog box. After the user chooses a selection from the drop-down list box by pressing ENTER, the input focus and selection move back to the parent cell.
  4. As the user navigates in the data table with the LEFT ARROW, RIGHT ARROW, UP ARROW, and DOWN ARROW keys, the EVENT_OBJECT_FOCUS and EVENT_OBJECT_SELECTION events are sent for each Cell object. Assistive technologies rely on these events to track the input focus and determine which cell's information should be reported to the user.
  5. The user continues to navigate in the data table using the SHIFT+ARROW key combinations to increase or decrease the selection by a single cell or by a small group of cells. The EVENT_OBJECT_SELECTIONADD and EVENT_OBJECT_SELECTIONREMOVE events are sent along with the EVENT_OBJECT_FOCUS event, as the user continues to hold the SHIFT key down and change the input focus.
  6. If the user presses the CTRL+ARROW key combinations in the data table, then the input focus changes. However, the selection remains the same, so only the EVENT_OBJECT_FOCUS event is sent for the Cell object that takes focus.
  7. While the input focus is on an individual cell, the user can press a shortcut key to enter the cell and edit its contents. If this happens, the EVENT_OBJECT_FOCUS event is sent again for the correct IAccessible child of that cell.
  8. When the user creates a new row, by navigating to the (*) Row or 'New Row', then the EVENT_OBJECT_CREATE event is sent for the new Row object.
  9. If the data table supports sorting, EVENT_OBJECT_REORDER is sent on the Table object when a sort order change has occurred.

Additional References

See the following references for more information about specific topics discussed in this article: