Normal, Unavailable, Offscreen, and Invisible AA States Explained

I’m often asked about the relationship among Normal (same as Visible), Unavailable, and Offscreen, and Invisible AA States. Here’s my best guess at an explanation.

What the docs say

Starting with the MSAA Docs on Object State Constants, the following terms are defined as follows:

  • STATE_SYSTEM_NORMAL - Indicates that the object does not have another state assigned to it.

  • STATE_SYSTEM_INVISIBLE - The object is programmatically hidden. For example, menu itmes are programmatically hidden until a user activates the menu. Because objects with this state are not available to users, client applications should not communicate information about the object to users. However, if client applications find an object with this state, they should check to see if STATE_SYSTEM_OFFSCREEN is also set. If this second state is defined, then clients can communicate the information about the object to users. For example, a list box can have both STATE_SYSTEM_INVISIBLE and STATE_SYSTEM_OFFSCREEN set. In this case, the client application can communicate all items in the list to users.

  • STATE_SYSTEM_UNAVAILABLE – The object is unavailable.

  • STATE_SYSTEM_OFFSCREEN - The object is clipped, or scrolled out of view, but not programmatically hidden. If the user makes the viewport larger, more of the object will be visible on the computer screen.

Simple explanations for each term

Normal just implies that the control is visible and available. If no state bits are set by the server developer, the out parameter for the IAccessible::get_accState is 0. When the client calls GetStateText for a 0 out parameter, Normal is returned. Obviously, Normal is #defined as 0.

Unavailable means that the control is either unavailable or disabled. For example, the Start -> Run dialog s OK button is unavailable when the combo box is empty. Although I can visually see the button, it is grayed-out and disabled, such that I cannot press the button (or perform the default action).

Offscreen occurs when the object is either normal or unavailable, but it has been scrolled off the screen. Increase the screen resolution or window size would cause the object to come into view.

An Invisible object is programmatically hidden, implying that I cannot see it on the screen.

Although these explanations seem simple enough on their own, combinations of such states are much more interesting…

Possible combinations

Normal cannot be and’ed with any other state by definition.

Offscreen and Unavailable: The control is unavailable, but is scrolled off the screen. In the previous example, suppose the Run dialog were resizeable. If I were to resize the dialog such that the unavailable OK button were offscreen, I would expect this button to have both Offscreen and Unavailable states set.

Invisible and Unavailable: In my opinion, a control would never have these two bits set at the same time. Invisible seems to have a higher precedence than unavailable. If a control were invisible, it isn t on the screen. An unavailable control must be on the screen to be grayed-out.

Having said that, a member of my team today gave me an interesting scenario where this could be true. Suppose a control were unavailable and the user performed some action that caused it to disappear. If the user were to revert this action (suppose unchecking a checkbox), the control would reappear in an unavailable state. He concluded that both bits should be set. I kinda disagree with this, considering a control cannot be invisible and grayed-out at the same time. However, I hope that the client would check for the invisible bit before checking for any unavailable or offscreen bits, which leads me to the last combination…

Invisible and Offscreen: The definitions from the MSAA docs, as referenced above, state that

However, if client applications find an object with this state, they should check to see if STATE_SYSTEM_OFFSCREEN is also set. If this second state is defined, then clients can communicate the information about the object to users. For example, a list box can have both STATE_SYSTEM_INVISIBLE and STATE_SYSTEM_OFFSCREEN set. In this case, the client application can communicate all items in the list to users.

Offscreen means the control is programmatically accessible, but invisible means the control is not programmatically accessible. Seems like there’s a paradox here.

I’ve found an interesting issue in the Windows Explorer -> View -> Folders tree view. The child tree view item of a collapsed parent item (suppose the item has been expanded and collapsed at least once to generate the AA object) has the Invisible and Offscreen bits set. However, so does any tree view item (child or parent) that is offscreen. In my opinion, it seems that clients need to check for the offscreen bit whenever invisible is set to determine if the object is really invisible or just offscreen in cases such as this one.

Hope this helps!

Watch Out for these Unpopular Accessibility Bugs

I attended a few get-togethers with some Assistive Technology vendors a while back when they were on campus for an Accessibility conference. While eating dinner with one particular AT vendor, I had asked him what we, Visual Studio , could do to improve our Assistive Technology compatibility story. Next thing I knew, I was writing frantically on paper usually used for receipts.

  1. Consider allowing Graphics to take focus. If there s a control the mouse user can interact with, the keyboard user will most likely want to interact with that control in a similar fashion. Sure, there are workarounds, like telling the user to go to the menus to find the same functionality. But, depending on what the control does, it could mean a lot of extra steps, especially if the control is frequently used.
  2. All graphics should have an AA object. If it is too costly for the graphic to have an AA object, at least draw it as a bitmap. Never just paint graphics. These are black holes to ATs.
  3. Graphics should have a bitmap associated with it, especially for those that don t have AA objects or are just bitmaps. If the graphic is painted, it is critical that it have a tooltip. This at least gives ATs a chance to identify the graphic.
  4. Correct cursor location is returned. For example, the (x,y) screen coordinates for an italicized cursor is at the baseline.  I was told by the AT vendor that Word does not return Italicized cursor coordinates correctly, but I have not investigated this issue to confirm this at this time.
  5. After selecting text, the cursor must not disappear. The cursor must continue to blink based on OS Settings.  I was told by the AT vendor that Notepad does this correctly; Word does not, but I have not investigated this issue to confirm this at this time.  ATs may have to write special logic to determine cursor location.
  6. Use win32 API DrawFocusRect, even if you’ve drawn your own focus rect. I was told by the AT Vendor that there s a parameter you can pass in to draw the focus rectangle as invisible, but I didn t see it in the docs. It doesn t mean that it isn t possible. The AT s Off Screen Model goes by the focus rectangle drawn by DrawFocusRect, so if the AT can t find focus, although it is visible on the screen, this is the most likely cause.

View original comments