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 . |