Active Accessibility and Common Controls

From time to time, I get questions of “Which properties do I need to support for my control?” or “What values do I put 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 the MsaaVerify Specification or a MSAA Properties test specification.

 

Frequently Ask Questions regarding MSAA Properties

Which Properties Must Every Control Support?

 

Name – absolutely all controls must have an AA 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 objects 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?

 

It is a bug. Only DISP_E_MEMBERNOTFOUND or S_OK are supported. 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: https://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: https://msdn.microsoft.com/library/en-us/dnacc/html/ATG_UpdatedListViewWithCheckboxes.asp

 

What if I’ve created my own custom control that isn’t necessarily a <insert control here> or a <insert control here>, but behaves like <insert control here>? Or I have a control 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:

 

Required fields are indicated in red and with an asterisk (*).

 

 

Button

 

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

 

Property

How To Implement

ChildCount

Return 0. A button doesn’t have any children

DefaultAction*

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*

Returns the mnemonic. All buttons must have a mnemonic. 

Name*

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*

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

Role*

ROLE_SYSTEM_PUSHBUTTON (defined in oleacc.h)

State*

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: https://msdn.microsoft.com/library/en-us/msaa/msaapndx_4erc.asp

Property

How To Implement

ChildCount

Return 0. A checkbox doesn’t have any children

DefaultAction*

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*

Returns the mnemonic. All checkboxes must have a mnemonic. 

Name*

Returns the caption. 

Parent*

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

Role*

ROLE_SYSTEM_CHECKBUTTON (defined in oleacc.h)

State*

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

 

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

 

Property

How To Implement

ChildCount

Return 0. A button doesn’t have any children

DefaultAction*

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

Description

Return DISP_E_MEMBERNOTFOUND. 

KeyboardShortcut*

Returns the mnemonic. All radiobuttons must have a mnemonic. 

Name*

Returns the caption. 

Parent*

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

Role*

ROLE_SYSTEM_RADIOBUTTON (defined in oleacc.h)

State*

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: https://msdn.microsoft.com/library/en-us/msaa/msaapndx_53nc.asp.

 

For the Combo Box window:

Property

How To Implement

ChildCount*

Return 3. (the push button, the edit box, and the drop-down list)

DefaultAction*

Return DISP_E_MEMBERNOTFOUND

Description

Return DISP_E_MEMBERNOTFOUND 

KeyboardShortcut*

Returns the mnemonic from its label.

Name*

Returns its label. The label must precede (come before) the combo box in tab order

Parent*

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

Role*

ROLE_SYSTEM_COMBOBOX (defined in oleacc.h)

State*

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*

The text within the edit box / combo box itself

 

For the Button:

 

Property

How To Implement

ChildCount

Return 0

DefaultAction*

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

Description

Return DISP_E_MEMBERNOTFOUND 

KeyboardShortcut*

“Alt+Down Arrow”

Name*

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

Parent*

Returns the combo box

Role*

ROLE_SYSTEM_PUSHBUTTON (defined in oleacc.h)

State*

STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)

STATE_SYSTEM_PRESSED – if depressed with list showing

Value

Return DISP_E_MEMBERNOTFOUND

 

For the Edit Box:

 

Property

How To Implement

ChildCount

Return 0

DefaultAction*

Return DISP_E_MEMBERNOTFOUND

Description

Return DISP_E_MEMBERNOTFOUND 

KeyboardShortcut*

Return DISP_E_MEMBERNOTFOUND 

Name*

Same as the combo box’s name

Parent*

Returns the combo box

Role*

ROLE_SYSTEM_TEXT (defined in oleacc.h)

State*

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*

The text within the edit box / combo box itself

For the List:

Property

How To Implement

ChildCount*

Return the number of items in the list

DefaultAction

Return DISP_E_MEMBERNOTFOUND

Description

Return DISP_E_MEMBERNOTFOUND 

KeyboardShortcut

Return DISP_E_MEMBERNOTFOUND 

Name*

Same as the combo box’s name

Parent*

Returns the combo box

Role*

ROLE_SYSTEM_LIST (defined in oleacc.h)

State*

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 ListItem:

 

Property

How To Implement

ChildCount

Return 0

DefaultAction*

Return “Double Click” Use oleaccrc for the correct localization

Description

Return DISP_E_MEMBERNOTFOUND 

KeyboardShortcut

Return DISP_E_MEMBERNOTFOUND 

Name*

The list item text

Parent*

Returns the list

Role*

ROLE_SYSTEM_LISTITEM (defined in oleacc.h)

State*

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: https://msdn.microsoft.com/library/en-us/msaa/msaapndx_7bu4.asp

 

Property

How To Implement

ChildCount

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

DefaultAction

Return DISP_E_MEMBERNOTFOUND

Description

Return DISP_E_MEMBERNOTFOUND. 

KeyboardShortcut*

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

Name*

Returns the caption. The label must precede (come before) the combo box in tab order

Parent*

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

Role*

ROLE_SYSTEM_TEXT (defined in oleacc.h)

State*

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*

The text within the edit box itself

 

 

List View

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

Property

How To Implement

ChildCount

Return the number of items in the list

DefaultAction

Return DISP_E_MEMBERNOTFOUND

Description

Return DISP_E_MEMBERNOTFOUND 

KeyboardShortcut*

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*

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*

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

Role*

ROLE_SYSTEM_LIST (defined in oleacc.h)

State*

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

Property

How To Implement

ChildCount

Return DISP_E_MEMBERNOTFOUND

DefaultAction*

Return “Double Click” use oleaccrc for correct localization

Description*

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*

The same as the text of the list view item

Parent*

Return the list view

Role*

ROLE_SYSTEM_LISTITEM (defined in oleacc.h)

State*

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: https://msdn.microsoft.com/library/en-us/msaa/msaapndx_1jy0.asp

 

Property

How To Implement

ChildCount

Return the number of items in the list

DefaultAction

Return DISP_E_MEMBERNOTFOUND

Description

Return DISP_E_MEMBERNOTFOUND 

KeyboardShortcut*

The label must precede the list view in tab order. And, it must have a mnemonic.

Name*

The label must precede the list view in tab order.

Parent*

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

Role*

ROLE_SYSTEM_LIST (defined in oleacc.h)

State*

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 

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

Progress Bar

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

 

Property

How To Implement

ChildCount

Return 0

DefaultAction

Return DISP_E_MEMBERNOTFOUND

Description

Return DISP_E_MEMBERNOTFOUND 

KeyboardShortcut

Return DISP_E_MEMBERNOTFOUND 

Name*

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*

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

Role*

ROLE_SYSTEM_PROGRESSBAR (defined in oleacc.h)

State*

STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)

STATE_SYSTEM_UNAVAILABLE – if disabled

Value*

Return a string from "0%" to "100%" that describes the progress.

 

Static Text

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

 

Property

How To Implement

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*

The caption or the actual text of the static text. Pretty simple.

Parent*

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

Role*

ROLE_SYSTEM_STATICTEXT (defined in oleacc.h)

State*

STATE_SYSTEM_INVISIBLE – if invisible (not shown yet)

STATE_SYSTEM_UNAVAILABLE – if disabled

STATE_SYSTEM_READONLY – if disabled

Value

Return DISP_E_MEMBERNOTFOUND .