From time to time, I get questions of “Which properties do I need to support for my control?” or “What values do I specify for these properties.” I wrote the MsaaVerify Testing Tool to do this level of testing for you, but from a dev’s perspective, they need to know this information at design time, not at testing time. Consider this post to be a specification on how to implement (and test!) Windows controls for accessiblity.

Frequently Ask Questions regarding MSAA Properties

Which Properties Must Every Control Support?

There are 4 properties every control must support:

  • Name – absolutely all controls must have an MSAA name. Imagine a button not having a caption, or a checkbox without any text describing what you’re checking.
  • Role – describes what sort of control you’re interacting with. Imagine if a dev where to owner-draw all buttons to look like edit boxes. It would be very disconcerting to use such UI.
  • State- describes whether a checkbox is checked or not, whether the control is available, and so forth.
  • Parent – the object’s relationship to all other objects.

Can I Use E_NOTIMPL instead of DISP_E_MEMBERNOTFOUND?

No. Because of the time when MSAA was written, DISP_E_MEMBERNOTFOUND was used instead of E_NOTIMPL. Always return DISP_E_MEMBERNOTFOUND if a method or property is not supported.

What if another HRESULT is returned for a Property?

Then it is a bug. Only DISP_E_MEMBERNOTFOUND or S_OK are supported. For example, no properties that I am aware of should ever return S_FALSE.

Are Help and Help Topic really required?

No. Help and HelpTopic are not required. I have rarely seen them used by an Assistive Technology. HelpTopic is a URL that provides help for the given control and Help is just more info on how to use the control. To the best of my knowledge, HelpTopic is the same thing as if the user were to press F1 for a dialog in Visual Studio. The result is that a help topic link is opened for the user. Technically, you need to return DISP_E_MEMBERNOTFOUND for both of these; however, it isn’t necessarily a bug if the dev returns S_OK with a null string.

What Is a Normal State? Why isn’t there an Uncheck State?

MSAA States are represented as bits. If no bits are set, the control is said to be in a “normal” state. Actually ::get_accState will return 0. If a checkbox is checked, the “checked” state is set. If the checkbox isn’t checked, the “checked” state isn’t checked, hence the normal state.

What about Tables?

Check out this whitepaper about tables: http://msdn.microsoft.com/library/en-us/dnacc/html/ATG_MSAASupportforTables.asp

What if I have a control that merges a list view or tree view with check boxes?

Check out this whitepaper about list views / tree views with check boxes: http://msdn.microsoft.com/library/en-us/dnacc/html/ATG_UpdatedListViewWithCheckboxes.asp

What if I have a custom control (something I implemented myself) that doesn’t look anything like any standard Windows Controls?

What you’ll want to do is to look at all of the MSAA properties for all of the standard Windows controls your custom control kinda looks like or kinda behaves like. Then you’ll need to merge these properties together.

Or say you’re designing something that doesn’t even look like a Windows control. You’ll want to match your control’s behavior as closely as possible to a Windows control. For example, say you implemented some color picker that contains a bunch of “boxes” that represent colors. The UI looks something like a color palette that you can navigate and select different colors, but what should the MSAA properties look like? One idea, and this is just an idea or suggestion (use at own risk), is to represent each of the boxes of the color palettes as a radio button in MSAA, because only one color can ever have selection. If the designer were to replace the color palette with a standard Windows control, he/she could use a radio button group. A color palette is just a better visual representation of the UI than the radio button group, but for MSAA, using a radio button group should work.

How To Implement MSAA for A Given Control

Button

Reference: http://msdn.microsoft.com/library/en-us/msaa/msaapndx_6ypa.asp

ChildCount – Return 0.  A button doesn’t have any children.

DefaultAction* – Required. Return “Press”.  Just use oleaccrc.dll to get the correct localization.

Description – 99% of the time, just return DISP_E_MEMBERNOTFOUND.  According to docs, this is used to describe an image on a button, but I’ve seen this used to describe what the button does (although help topic would be a better choice).

KeyboardShortcut – Required. Returns the mnemonic.  All buttons must have a mnemonic.

Name -  Required. Returns the caption.  If you have a button that has a graphic, you must use either Dynamic Annotation to set the AA name directly or use a win32 call to set an invisible caption on the button.

Parent – Required. Returns the invisible window container wrapper that has the same name of the control.  This window’s parent is the dialog itself.

Role – Required. ROLE_SYSTEM_PUSHBUTTON (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it
  • STATE_SYSTEM_PRESSED – if depressed
  • STATE_SYSTEM_DEFAULT – is default button on dialog

Value – Return DISP_E_MEMBERNOTFOUND

CheckBox

Reference: http://msdn.microsoft.com/library/en-us/msaa/msaapndx_4erc.asp

ChildCount – Return 0.  A checkbox doesn’t have any children.

DefaultAction -  Required. Depends on the current state of the checkbox.  If currently checked, return “Uncheck”.  If currently unchecked, return “Check”.  If currently a three-state checkbox, return “Toggle.”  Use oleaccrc.dll to get the correct localization.

Description – Return DISP_E_MEMBERNOTFOUND.

KeyboardShortcut – Required. Returns the mnemonic.  All checkboxes must have a mnemonic.

Name – Required. Returns the caption.

Parent – Required. Returns the invisible window container wrapper that has the same name of the control.  This window’s parent is the dialog itself.

Role – Required. ROLE_SYSTEM_CHECKBUTTON (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it
  • STATE_SYSTEM_MIXED – indeterminate state
  • STATE_SYSTEM_CHECKED – checked

Value – Return DISP_E_MEMBERNOTFOUND

RadioButton

Reference: http://msdn.microsoft.com/library/en-us/msaa/msaapndx_7ulq.asp

ChildCount – Return 0.  A button doesn’t have any children.

DefaultAction – Required. Return “Check”  Use oleaccrc.dll to get the correct localization.

Description – Return DISP_E_MEMBERNOTFOUND.

KeyboardShortcut – Required. Returns the mnemonic.  All radiobuttons must have a mnemonic.

Name – Required. Returns the caption.

Parent – Required. Returns the invisible window container wrapper that has the same name of the control.  This window’s parent is the dialog itself.

Role – Required. ROLE_SYSTEM_RADIOBUTTON (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it
  • STATE_SYSTEM_CHECKED – checked

Value – Return DISP_E_MEMBERNOTFOUND

ComboBox

Reference: http://msdn.microsoft.com/library/en-us/msaa/msaapndx_53nc.asp.

For the Combo Box window:

ChildCount – Required. – Return ’3′.  (the push button, the edit box, and the drop-down list)

DefaultAction - Return DISP_E_MEMBERNOTFOUND

Description – Return DISP_E_MEMBERNOTFOUND

KeyboardShortcut – Required. Returns the mnemonic from its label.

Name – Required. Returns its label.  Note: The label must precede (come before) the combo box in tab order.

Parent – Required. Returns the invisible window container wrapper that has the same name of the control.  This window’s parent is the dialog itself.

Role – Required. ROLE_SYSTEM_COMBOBOX (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it

Value – Required. Return the text within the edit box / combo box itself.

For the Combo Box button:

ChildCount – Return 0.

DefaultAction – Required. If the list isn’t opened, return “Open”; otherwise, “Close”.  Use oleaccrc.dll to get the correct localization.

Description – Return DISP_E_MEMBERNOTFOUND

KeyboardShortcut – Required. Correct keyboard shortcut is “Alt+Down Arrow”.

Name – Required. If the list isn’t opened, return “Open”; otherwise, “Close”.  Use oleaccrc.dll to get the correct localization.

Parent – Required. Returns the combo box.

Role – Required. ROLE_SYSTEM_PUSHBUTTON (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_PRESSED – if depressed with list showing

Value – Return DISP_E_MEMBERNOTFOUND

For the Combo Box Edit Box:

ChildCount – Return 0

DefaultAction – Return DISP_E_MEMBERNOTFOUND

Description – Return DISP_E_MEMBERNOTFOUND

KeyboardShortcut – Required. Return DISP_E_MEMBERNOTFOUND

Name – Required. Same as the combo box’s name

Parent – Required. Returns the combo box

Role – Required.  ROLE_SYSTEM_TEXT  (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it

Value – Required. The text within the edit box / combo box itself

For the Combo Box List:

ChildCount – Required. Return the number of items in the list

DefaultAction – Return DISP_E_MEMBERNOTFOUND

Description – Return DISP_E_MEMBERNOTFOUND

KeyboardShortcut – Return DISP_E_MEMBERNOTFOUND

Name – Required. Same as the combo box’s name

Parent – Required. Returns the combo box

Role – Required. ROLE_SYSTEM_LIST  (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it
  • STATE_SYSTEM_FLOATING – if it is opened

Value – Return DISP_E_MEMBERNOTFOUND

For the Combo Box ListItem:

ChildCount – Return 0

DefaultAction – Required. Return “Double Click” Use oleaccrc for the correct localization

Description – Return DISP_E_MEMBERNOTFOUND

KeyboardShortcut – Return DISP_E_MEMBERNOTFOUND

Name – Required. The list item text

Parent – Required. Returns the list

Role – Required. ROLE_SYSTEM_LISTITEM  (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it
  • STATE_SYSTEM_SELECTABLE – if the user can select it
  • STATE_SYSTEM_SELECTED – if selected

Value – Return DISP_E_MEMBERNOTFOUND

Edit Box

Reference: http://msdn.microsoft.com/library/en-us/msaa/msaapndx_7bu4.asp

ChildCount – Return 0.  An edit box doesn’t have any children

DefaultAction – Return DISP_E_MEMBERNOTFOUND

Description – Return DISP_E_MEMBERNOTFOUND.

KeyboardShortcut – Required. Returns the mnemonic from the label.  All edit boxes must have a mnemonic.

Name – Required. Returns the caption. Note: The label must precede (come before) the combo box in tab order.

Parent – Required. Returns the invisible window container wrapper that has the same name of the control.  This window’s parent is the dialog itself.

Role – Required. ROLE_SYSTEM_TEXT (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it
  • STATE_SYSTEM_READONLY – Read-only edit box
  • STATE_SYSTEM_PROTECTED – password protected

Value – Required. The text within the edit box itself

List View

Reference: http://msdn.microsoft.com/library/en-us/msaa/msaapndx_3y5o.asp

ChildCount – Return the number of items in the list

DefaultAction – Return DISP_E_MEMBERNOTFOUND

Description – Return DISP_E_MEMBERNOTFOUND

KeyboardShortcut – Required. About 90% of the time, there’s a label for the list view.  If there is a label, it must precede the list view in tab order.  And, it must have a mnemonic.

Name – Required. About 90% of the time, there’s a label for the list view.  If there is a label, it must precede the list view in tab order.

Parent – Required. Returns the invisible window container wrapper that has the same name of the control.  This window’s parent is the dialog itself.

Role – Required. ROLE_SYSTEM_LIST  (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it
  • STATE_SYSTEM_OFFSCREEN – the control is there, but just scrolled off the screen

Value – Return DISP_E_MEMBERNOTFOUND

For the List View item

ChildCount – Return DISP_E_MEMBERNOTFOUND

DefaultAction – Required. Return “Double Click” use oleaccrc for correct localization.

Description – Required. If the list view contains columns, then each list view item is the text contained in the item’s second and subsequent columns. A comma is inserted between the text for each column.

KeyboardShortcut – Return DISP_E_MEMBERNOTFOUND

Name – Required. The same as the text of the list view item.

Parent – Required. Return the list view.

Role – Required. ROLE_SYSTEM_LISTITEM  (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it
  • STATE_SYSTEM_OFFSCREEN – the control is there, but just scrolled off the screen
  • STATE_SYSTEM_SELECTABLE – if the user can select it
  • STATE_SYSTEM_SELECTED – if selected
  • STATE_SYSTEM_MULTISELECTABLE – if multi-selected
  • STATE_SYSTEM_CHECKED – if it has checkboxes

Value – Return DISP_E_MEMBERNOTFOUND

List Box

Reference: http://msdn.microsoft.com/library/en-us/msaa/msaapndx_1jy0.asp

ChildCount – Return the number of items in the list

DefaultAction – Return DISP_E_MEMBERNOTFOUND

Description – Return DISP_E_MEMBERNOTFOUND

KeyboardShortcut – Required. Note: The label must precede the list view in tab order.  And, it must have a mnemonic.

Name – Required.  Note: The label must precede the list view in tab order.

Parent – Required: Returns the invisible window container wrapper that has the same name of the control.  This window’s parent is the dialog itself.

Role – Required. ROLE_SYSTEM_LIST  (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_FOCUSED – has focus
  • STATE_SYSTEM_FOCUSABLE – the user can tab to it
  • STATE_SYSTEM_OFFSCREEN – the control is there, but just scrolled off the screen
  • STATE_SYSTEM_UNAVAILABLE – if disabled

Value – Return DISP_E_MEMBERNOTFOUND

List Box Item

For the list box item, see the “List View Item” above.

Progress Bar

Reference: http://msdn.microsoft.com/library/en-us/msaa/msaapndx_5u7g.asp

ChildCount – Return 0

DefaultAction – Return DISP_E_MEMBERNOTFOUND

Description – Return DISP_E_MEMBERNOTFOUND

KeyboardShortcut – Return DISP_E_MEMBERNOTFOUND

Name – Required. Note: If there is a label, it must precede the progress bar in tab order.  If it isn’t clear what this progress bar does, place an invisible label that precedes the progress bar in tab order, so that it will have an AA Name.

Parent – Required. Returns the invisible window container wrapper that has the same name of the control.  This window’s parent is the dialog itself.

Role – Required. Return ROLE_SYSTEM_PROGRESSBAR  (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled

Value – Required. Return a string from “0%” to “100%” that describes the progress.

Static Text

Reference: http://msdn.microsoft.com/library/en-us/msaa/msaapndx_4ws4.asp

ChildCount – Return 0

DefaultAction – Return DISP_E_MEMBERNOTFOUND

Description – Return DISP_E_MEMBERNOTFOUND

KeyboardShortcut – Return DISP_E_MEMBERNOTFOUND (unless it is acting like a label)

Name – Required. The caption or the actual text of the static text.  Pretty simple.

Parent – Required. Returns the invisible window container wrapper that has the same name of the control.  This window’s parent is the dialog itself.

Role – Required. ROLE_SYSTEM_STATICTEXT  (defined in oleacc.h)

State – Required:

  • STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)
  • STATE_SYSTEM_UNAVAILABLE – if disabled
  • STATE_SYSTEM_READONLY – if disabled

Value – Return DISP_E_MEMBERNOTFOUND