A political history of Windows accessibility standards

I see around the Internet articles about accessibility APIs and standards like MSAA and IAccessible2, and I don’t think they reflect the history of the technology as much as the politics of the technology. This is a quick note of my memory and take on it from my experience working in screenreaders and AT.

Microsoft comes up with the first accessibility API in the late 90s, MSAA. It’s fine for buttons and textboxes and checkboxes, but richer user interfaces are too much for it – the document area in Word, or web pages.

So Microsoft comes up with UI Automation (UIA), which is a richer accessibility API that addresses the shortcomings of MSAA. This was in 2005.

But no-one picks it up properly: within Microsoft, Office doesn’t, I assume because of the usual Office versus Windows internal politics. Internet Explorer doesn’t, because Microsoft has stopped developing Internet Explorer. And outside Microsoft, all the screenreader guys have already written their code to “slurp” the contents of Internet Explorer and Office, so they don’t care that UIA doesn’t become the new standard. (And if UIA fails, so much more value for their products, which cost lots of money and so can support developers to write custom code for each and every program that fails to support accessibility standards…)

Outside Microsoft UIA adoption is even worse: Sun and IBM actually go to the trouble of creating a competing accessibility API, IAccessible2, and foist that on Java and OpenOffice to aid their competition with Microsoft and prevent Microsoft owning the accessibility API on Windows like Microsoft owns the document format standard (Word) and the web page standard (IE). (Disabled users have a history of being used to further other agendas, whether they know it or not…) Of course, nerds rally round and also foist it on Firefox, then the only Internet Explorer alternative, because hey everyone hates Micro$oft, right?

But, it’s important to understand, at this point in history – mid 00s – things are kind of OK. JAWS and NVDA and other screenreaders write special code (accessing some kind of application-specific API like the Word DOM) to talk to really really important applications, like Internet Explorer and Office, and use the MSAA accessibility API to talk to everything else. We all argue about the price of screenreaders and whether videos should autoplay but everything is stable. If you want to use more applications with your screenreader you pay more for a screenreader with more special code – JAWS is the standard, of course.

Then it all changes. The web and mobile explodes, by which we mean HTML5 and Chrome and iOS breaking the Internet Explorer/Windows dominance, and websites becoming applications in their own right like Google Docs or Facebook. Internet Explorer is dead, the mainstream declares, which means the sophisticated support screenreaders have developed to talk to its application-specific APIs is all useless: at the same time the websites are getting more and more complex. MSAA isn’t going to cut it, and there is no application-specific API for Chrome, the new dominant browser (there is a chrome.automation in development – how nice!) And here we are in 2018, and it’s much harder to use a web app than a desktop application. (Of course, you’ve probably jumped ship to iOS and an iPad with VoiceOver, or you are using a restricted set of desktop applications…)

Hey, maybe UI Automation’s time has come! Everyone knows VoiceOver is super-accessible and great and built into macOS, and so Microsoft needs a better AT story round Office and Windows, so the newly-invigorated Microsoft builds UIA into Office and Edge and here we go! At least until Edge is killed off too…

(The usual caveats and apologies about focusing mainly on blind people apply: showing my history in that area.)

MSAA, UIA and WinForms in .Net

Another item for programmers, more on UIA and MSAA and developing accessible user interfaces, following on from using WPF/XAML with MSAA and UIA.

This is a super-quick guide to using WinForms to make UIs that work well with screenreaders like NVDA or Thunder or JAWS.

  • You don’t need to do anything to Button, CheckBox, MenuItem or MenuStrip controls – other than put some text on them! Image-only controls are no good. It’s fine if only the image is shown to the end user and the text is hidden.
  • You can correctly label content controls that don’t have a Text property, like TextBox, ListBox, ListView, ComboBox, ProgressBar and the like, in one of two ways:
    • Put a Label just before the control you want to label in the tab index order. The Text on the Label labels the control. Use the TabIndex property to make sure the order is correct.
    • Set the AccessibleName property on the content control itself. This labels the control for the screenreader.
  • Groupbox controls don’t label their contents, use one of the other techniques here.
  • You almost certainly want to avoid labelling Panel controls, since they are generally for layout, which is communicated to the screenreader user in other ways than labeling.
  • For WebBrowser controls you need to think about the content in terms of web accessibility – use label elements, ARIA, and other HTML accessibility techniques. You might also need to label the actual WebBrowser control on your form with a Label or AccessibleName, just like any other content control.

Unsurprisingly, these techniques are basically the same as writing forms using the Windows C++ API, since WinForms is a wrapper round that.


A technical note today for programmers.

Screenreaders (blind users) interact with Windows programs through accessibility APIs. The most modern is UI Automation. But the first, and possibly most important still, is MSAA, Microsoft Active Accessibility. Windows will supply information from one interface to the other system if required, so most of the time you shouldn’t have to worry too much.

I’ve been doing some .Net programs using WPF or XAML (that is, not WinForms) and here’s a quick guide to what I’ve found:

  • Buttons and CheckBoxes work fine just as they are. In fact, don’t set any Automation properties or you’ll get odd-looking controls in MSAA.
  • ListBox, ComboBox, TextBox, ProgressBar work fine for their contents just as they are. But:
  • Labels don’t label Listbox/ComboBox/TextBox/ProgressBar unless you use LabeledBy.

In C++ applications you associate labels (e.g. “Enter username:”) with the control they are labelling (e.g. a textbox for the username) by using tab order. The label with tab index N labels the control with tab index N+1. So label with tab index 0 provides the name to the combobox with tab index 1.

In WPF you have to set this explicitly using AutomationProperties.LabeledBy, like this:

<Label Content="A ListBox Control:" x:Name="lblList"></Label>
<ListBox AutomationProperties.LabeledBy="{Binding ElementName=lblList}">

Note the funky “Binding” code – you can’t just use the x:Name of the label. Notice also that your Label must have an x:Name! You can also use a TextBlock instead of a label. Generally the pattern is:

<TextThing Content=”The label for the other control” x:Name=”textThingLabel” />
<OtherControl AutomationProperties.LabeledBy=”{Binding ElementName=textThingLabel}” />

Anyway, that suffices for the basics of MSAA/UIA support for WPF if you’re writing .Net Windows applications.