Merge mozilla-central and tracemonkey. (a=blockers)
[mozilla-central.git] / accessible / accessible-docs.html
blob91c78b0603c1006cd2d21be1a48b5fe662d34c6f
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html>
3 <head>
4 <title>Implementing an MSAA Server - How Mozilla Does It, and
5 Practical Tips for Developers</title>
6 </head>
7 <body>
8 <h1>Implementing an MSAA Server</h1>
9 <h2>Practical Tips for Developers, and How Mozilla Does It<br>
10 </h2>
11 <h2>Contents</h2>
12 <div style="margin-left: 40px;">
13 <p>This document is for people working to support MSAA in an
14 application in order to make it accessible with 3rd party assistive
15 technologies, as well as for hackers wishing to be involved in Mozilla's
16 MSAA support specifically.<br>
17 You may also wish to read <a
18 href="http://www.mozilla.org/projects/ui/accessibility/vendors-win.html">Gecko
19 Info for Windows Accessibility Vendors</a>, a primer for vendors of 3rd
20 party accessibility software, on how MSAA clients can utilize Gecko's
21 MSAA support.</p>
22 <a href="#intro">1. Intro: What is MSAA</a><br>
23 <br>
24 </div>
25 <div style="margin-left: 40px;"><a href="#cheatsheets">2. Deciding
26 Which MSAA Features to Support</a><br>
27 <div style="margin-left: 40px;"><big></big><a href="#methods">Methods</a><br>
28 <a href="#events">Events</a><br>
29 <a href="#states">States</a><br>
30 <a href="#roles">Roles</a><br>
31 <a href="#objid">Object Identifiers</a><br>
32 <br>
33 </div>
34 <a href="#quirks">3. </a><a href="#quirks">MSAA's Quirks and
35 Workarounds</a><br>
36 <div style="margin-left: 40px;"><a href="#Crash_prone">MSAA can be
37 crash prone</a><br>
38 <a href="#Hacky_caret_tracking_not_working">Hacky caret tracking not
39 working</a><br>
40 <a href="#Event_window_confusion">Event window confusion</a><br>
41 <a href="#Confusion_with_system-generated_events">Confusion with
42 system-generated events</a><br>
43 <a href="#Hacky_caret_tracking_not_working">No unique child ID for
44 object in window</a><br>
45 <a href="#Not_all_MSAA_features_utilized_by_3rd">Not all MSAA features
46 utilized by 3rd party vendors</a><br>
47 <a href="#Missing_functionality_in_MSAA">Missing functionality in MSAA</a><br>
48 <a href="#Dueling_text_equivalents">Dueling text equivalents</a><br>
49 <a href="#Issues_with_Links">Issues with Links</a><br>
50 <a href="#MSAA_Implementation_is_Not_Performant">Performance Problems</a><br>
51 <a href="#Differing_client_implementations">Differing client
52 implementations</a><br>
53 <a href="#Undocumented_Window_Class_Usage">Undocumented Window Class
54 Usage</a><br>
55 <a href="#Vendor_quirks">Vendor quirks</a><br>
56 <br>
57 </div>
58 <a href="#geckoimpl">4.
59 Example: How Gecko and Mozilla Implement MSAA</a><br>
60 <div style="margin-left: 40px;"><a
61 href="#Creation_of_IAccessible_Objects">Creation
62 of IAccessible Objects</a><br>
64 href="#The_Accessible_Tree_vs._the_DOM_Tree">The
65 Accessible Tree vs. the DOM Tree</a><br>
67 href="#The_Implementations_Behind_IAccessible">The
68 Various Implementations of IAccessible</a><br>
70 href="#Generating_MSAA_Events">Generating
71 MSAA Events</a><br>
72 <br>
73 </div>
74 <a href="#feedback">5. Feedback</a><br>
75 </div>
76 <h2><a name="intro"></a>1. Intro: What is MSAA?</h2>
77 <ul>
78 <p>MSAA is the <a
79 href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msaa/msaastart_9w2t.asp?frame=true">Microsoft
80 Active Accessibility (MSAA) API</a> , used on Windows operating systems.
81 to support assistive technologies for users with disabilities. <br>
82 </p>
83 <p>Third party assistive technology, such as screen readers, screen
84 magnifiers and voice input software, want to track what's happening
85 inside Mozilla. They needs to know about focus changes and other events,
86 and it needs to know what objects are contained in the current document
87 or dialog box. Using this information, a screen reader will speak out
88 loud important changes to the document or UI, and allow the user to
89 track where they navigate. The screen reader user can navigate the web
90 page using screen reader commands or browser commands, and the two
91 pieces of software must remain in sync. Some screen readers can even
92 show information on a <a href="http://www.deafblind.com/display.html">refreshable
93 braille display</a>. Screen magnifiers will zoom to the focus, keeping
94 it on the screen at all times, or even allow the user to enter a special
95 low vision document reading mode, with a variety of features such as
96 ticker mode where text is streamed on a single line.&nbsp; Finally,
97 voice dictation software needs to know what's in the current document or
98 UI in order to implement "say what you see" kinds of features.<br>
99 <br>
100 On Microsoft Windows, these kinds of assistive technology acquire this
101 necessary information via a combination of&nbsp; hacks, MSAA and
102 proprietary DOMs. MSAA is supposed to be the "right way" for
103 accessibility aids to get information, but sometimes the hacks are more
104 effective. For example, screen readers look for screen draws of a
105 vertical blinking line, to determine the location of the caret. Without
106 doing this, screen readers would not be able to let the user know where
107 there caret has moved to in most programs, because so many applications
108 do not use the system caret (Gecko does not). This is so commonly done,
109 that no one even bothers to support the MSAA caret, after all the hack
110 is general solution works with pretty much all applications.</p>
111 <p>MSAA provides information in several different ways: </p>
112 <ol>
113 <li>A COM interface (IAccessible) that allows applications to
114 expose the tree of data nodes that make up each window in the user
115 interface currently being interacted with and</li>
116 <li>Custom interface extensions via interfaces via QueryInterface
117 and QueryService. This can provide assistive technology with contextual
118 information specific to your object model. For example, Gecko support
119 ISimpleDOMNode to provide information about the DOM node for an
120 accessible object.<br>
121 </li>
122 <li>A set of system messages that confer accessibility-related
123 events such as focus changes, changes to document content and state
124 changes in UI objects like checkboxes.<br>
125 </li>
126 </ol>
127 <p></p>
128 <p> To really learn about MSAA, you need to download the entire <a
129 href="http://msdn.microsoft.com/library/default.asp?URL=/downloads/list/accessibility.asp">MSAA
130 SDK</a>. Without downloading the SDK, you won't get the extremely
131 useful tools, which help a great deal in the learning process. The
132 Accessible Event Watcher shows what accessible events are being
133 generated by a given piece of software. The Accessible Explorer and
134 Inspect Object tools show the tree of data nodes the Accessible object
135 is exposing through COM, and what the screen boundaries of each object
136 are. In addition, MSDN has improved their <a
137 href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msaa/msaastart_9w2t.asp">MSAA
138 documentation</a>.<br>
139 </p>
140 </ul>
141 <h2><a name="cheatsheets"></a>2. Deciding Which MSAA Features to Support<br>
142 </h2>
143 <h2 style="margin-left: 40px;"><a name="methods"></a>MSAA Methods -
144 Cheat Sheet for Developers</h2>
145 <div style="margin-left: 40px;"> </div>
146 <ul style="margin-left: 40px;">
147 <p> The IAccessible interface is used in a tree of IAccessible's, each
148 one representing a data node, similar to a DOM. </p>
149 <p> Here are the methods supported in IAccessible - a minimal
150 implementation would contain those marked "<span
151 style="font-weight: bold;">[important]</span>" :<br>
152 </p>
153 <ul>
154 <li>get_accParent: Get the parent of an IAccessible. <span
155 style="font-weight: bold;">[important]</span><br>
156 </li>
157 <li>get_accChildCount: Get the number of children of an
158 IAccessible. <span style="font-weight: bold;">[important]</span></li>
159 <li>get_accChild: Get the child of an IAccessible. <span
160 style="font-weight: bold;">[important]</span></li>
161 <li>get_accName: Get the "name" of the IAccessible, for example the
162 name of a button, checkbox or menu item. <span
163 style="font-weight: bold;">[important]</span></li>
164 <li>get_accValue: Get the "value" of the IAccessible, for example a
165 number in a slider, a URL for a link, the text a user entered in a
166 field. <span style="font-weight: bold;">[important]</span></li>
167 <li>get_accDescription: Get a long description of the current
168 IAccessible. This is not really too useful.</li>
169 <li>get_accRole: Get an enumerated value representing what this
170 IAccessible is used for, for example. <br>
171 </li>
172 is it a link, static text, editable text, a checkbox, or a table
173 cell, etc. <span style="font-weight: bold;">[important]</span><span
174 style="font-weight: bold;"></span><li>get_accState: a 32 bit field
175 representing possible on/off states, such as focused, focusable,
176 selected, selectable, visible, protected (for passwords), checked, etc. <span
177 style="font-weight: bold;">[important]</span> </li>
178 <li>get_accHelp: Get context sensitive help for the IAccessible.</li>
179 <li>get_accHelpTopic: We don't use this, it's only if the Windows
180 help system is used.</li>
181 <li>get_accKeyboardShortcut: What is the keyboard shortcut for this
182 IAccessible (underlined alt+combo mnemonic)<br>
183 </li>
184 <li>get_accFocus: Which child is focused? <span
185 style="font-weight: bold;">[important]</span></li>
186 <li>get_accSelection: Which children of this item are selected?</li>
187 <li>get_accDefaultAction: Get a description or name of the default
188 action for this component, such as "jump" for links.</li>
189 <li>accSelect: Select the item associated with this IAccessible. <span
190 style="font-weight: bold;">[important]</span></li>
191 <li>accLocation: Get the x,y coordinates, and the height and width
192 of this IAccessible node. <span style="font-weight: bold;">[important]<br>
193 </span></li>
194 <li>accNavigate: Navigate to the first/last child, previous/next
195 sibling, up, down, left or right from this IAccessible. <span
196 style="font-weight: bold;">[important, </span><span
197 style="font-weight: bold;">but no need to implement up/down/left/right</span><span
198 style="font-weight: bold;">]</span></li>
199 <li>accHitTest: Find out what IAccessible exists and a specific
200 coordinate.</li>
201 <li>accDoDefaultAction: Perform the action described by
202 get_accDefaultAction.</li>
203 <li>put_accName: Change the name.</li>
204 <li>put_accValue: Change the value.</li>
205 </ul>
206 </ul>
207 <div style="margin-left: 40px;"> </div>
208 <h2 style="margin-left: 40px;"><a name="events"></a>MSAA Events Cheat
209 Sheet<br>
210 </h2>
211 <div style="margin-left: 40px;"> </div>
212 <ul style="margin-left: 40px;">
213 <p>For information on what each event does, see the <a
214 href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msaa/msaaccrf_7jlf.asp">MSDN
215 Event Constants page</a>.</p>
216 <p>Check with your assistive technology partners to find out what
217 events you need to support. There's a very good chance they won't ask
218 for more than the events marked <span style="font-weight: bold;">[important]</span>:<br>
219 </p>
220 </ul>
221 <div style="margin-left: 40px;"> </div>
222 <table
223 style="text-align: left; width: 75%; margin-right: auto; margin-left: auto;"
224 border="0" cellspacing="2" cellpadding="2">
225 <tbody>
226 <tr>
227 <td style="vertical-align: top;">EVENT_SYSTEM_SOUND<br>
228 EVENT_SYSTEM_ALERT<br>
229 EVENT_SYSTEM_FOREGROUND<br>
230 EVENT_SYSTEM_MENUSTART<br>
231 EVENT_SYSTEM_MENUEND<br>
232 EVENT_SYSTEM_MENUPOPUPSTART <span style="font-weight: bold;">[important]</span><br>
233 EVENT_SYSTEM_MENUPOPUPEND <span style="font-weight: bold;">[important]</span><br>
234 EVENT_SYSTEM_CAPTURESTART<br>
235 EVENT_SYSTEM_CAPTUREEND<br>
236 EVENT_SYSTEM_MOVESIZESTART<br>
237 EVENT_SYSTEM_MOVESIZEEND<br>
238 EVENT_SYSTEM_CONTEXTHELPSTART<br>
239 EVENT_SYSTEM_CONTEXTHELPEND<br>
240 EVENT_SYSTEM_DRAGDROPSTART<br>
241 EVENT_SYSTEM_DRAGDROPEND<br>
242 EVENT_SYSTEM_DIALOGSTART<br>
243 EVENT_SYSTEM_DIALOGEND<br>
244 EVENT_SYSTEM_SCROLLINGSTART<br>
245 EVENT_SYSTEM_SCROLLINGEND <span style="font-weight: bold;">[possibly
246 important, talk to AT vendor]</span><br>
247 EVENT_SYSTEM_SWITCHSTART<br>
248 EVENT_SYSTEM_SWITCHEND<br>
249 EVENT_SYSTEM_MINIMIZESTART<br>
250 EVENT_SYSTEM_MINIMIZEEND<br>
251 </td>
252 <td style="vertical-align: top;">EVENT_OBJECT_CREATE <span
253 style="font-weight: bold;">[don't implement, watching system generated
254 versions of this event causes </span><span style="font-weight: bold;">assistive
255 technology </span><span style="font-weight: bold;">crashes]</span><br>
256 EVENT_OBJECT_DESTROY <span style="font-weight: bold;">[don't
257 implement, watching system generated versions of this event causes
258 assistive technology crashes]</span><br>
259 EVENT_OBJECT_SHOW<br>
260 EVENT_OBJECT_HIDE<br>
261 EVENT_OBJECT_REORDER <span style="font-weight: bold;">[important for
262 mutating docs in future, but not yet]</span><br>
263 EVENT_OBJECT_FOCUS <span style="font-weight: bold;">[important]</span><br>
264 EVENT_OBJECT_SELECTION<br>
265 EVENT_OBJECT_SELECTIONADD<br>
266 EVENT_OBJECT_SELECTIONREMOVE<br>
267 EVENT_OBJECT_SELECTIONWITHIN<br>
268 EVENT_OBJECT_STATECHANGE <span style="font-weight: bold;">[important
269 for checkboxes and radio buttons]</span><br>
270 EVENT_OBJECT_LOCATIONCHANGE<br>
271 EVENT_OBJECT_NAMECHANGE<br>
272 EVENT_OBJECT_DESCRIPTIONCHANGE<br>
273 EVENT_OBJECT_VALUECHANGE<br>
274 EVENT_OBJECT_PARENTCHANGE<br>
275 EVENT_OBJECT_HELPCHANGE<br>
276 EVENT_OBJECT_DEFACTIONCHANGE<br>
277 EVENT_OBJECT_ACCELERATORCHANGE<br>
278 </td>
279 </tr>
280 </tbody>
281 </table>
282 <div style="margin-left: 40px;"> </div>
283 <h2 style="margin-left: 40px;"><a name="states"></a>MSAA States Cheat
284 Sheet<br>
285 </h2>
286 <div style="margin-left: 40px;"> </div>
287 <ul style="margin-left: 40px;">
288 <p>For information on what each state does, see the <a
289 href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msaa/msaaccrf_7jlf.asp">MSDN
290 State Constants page</a>.</p>
291 <p>Check with your assistive technology partners to find out what
292 states you need to support. There's a very good chance they won't ask
293 for more than the states marked <span style="font-weight: bold;">[important]</span>:</p>
294 </ul>
295 <div style="margin-left: 40px;"></div>
296 <table
297 style="text-align: left; width: 75%; margin-right: auto; margin-left: auto;"
298 border="0" cellspacing="2" cellpadding="2">
299 <tbody>
300 <tr>
301 <td style="vertical-align: top;">STATE_UNAVAILABLE <span
302 style="font-weight: bold;">[important]</span><br>
303 STATE_SELECTED <span style="font-weight: bold;">[important]</span><br>
304 STATE_FOCUSED <span style="font-weight: bold;">[important]</span><br>
305 STATE_PRESSED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
306 STATE_CHECKED <span style="font-weight: bold;">[important]</span><br>
307 STATE_MIXED<br>
308 STATE_READONLY <span style="font-weight: bold;">[important]</span><br>
309 STATE_HOTTRACKED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
310 STATE_DEFAULT <span style="font-weight: bold;">[important]</span><br>
311 STATE_EXPANDED <span style="font-weight: bold;">[important]</span><br>
312 STATE_COLLAPSED <span style="font-weight: bold;">[important]</span><br>
313 STATE_BUSY <span style="font-weight: bold;">[important]</span><br>
314 STATE_FLOATING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
315 STATE_MARQUEED&nbsp; <br>
316 STATE_ANIMATED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
317 STATE_INVISIBLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
318 <br>
319 </td>
320 <td style="vertical-align: top;">STATE_OFFSCREEN <span
321 style="font-weight: bold;">[important]</span><br>
322 STATE_SIZEABLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
323 STATE_MOVEABLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
324 STATE_SELFVOICING&nbsp;&nbsp; &nbsp;<br>
325 STATE_FOCUSABLE <span style="font-weight: bold;">[important]</span><br>
326 STATE_SELECTABLE <span style="font-weight: bold;">[important]</span><br>
327 STATE_LINKED <span style="font-weight: bold;">[important]</span><br>
328 STATE_TRAVERSED <span style="font-weight: bold;">[important]</span><br>
329 STATE_MULTISELECTABLE <span style="font-weight: bold;">[important]</span><br>
330 STATE_EXTSELECTABLE &nbsp;<br>
331 STATE_ALERT_LOW&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
332 STATE_ALERT_MEDIUM&nbsp; &nbsp;<br>
333 STATE_ALERT_HIGH&nbsp;&nbsp;&nbsp; &nbsp;<br>
334 STATE_PROTECTED <span style="font-weight: bold;">[important]</span><br>
335 STATE_HASPOPUP <br>
336 </td>
337 </tr>
338 </tbody>
339 </table>
340 <h2 style="margin-left: 40px;"><a name="roles"></a>MSAA Roles Cheat
341 Sheet<br>
342 </h2>
343 <div style="margin-left: 40px;"> </div>
344 <ul style="margin-left: 40px;">
345 <p>For information on what each role does, see the <a
346 href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msaa/msaaccrf_7jlf.asp">MSDN
347 Role Constants page</a>.</p>
348 <p>Check with your assistive technology partners to find out what
349 roles you need to support. There's a very good chance they won't ask for
350 more than the roles marked <span style="font-weight: bold;">[important]</span>:<br>
351 There is no need to support the objects marked <span
352 style="font-weight: bold;">[inserted by system]. </span>Windows will
353 add those objects to your hierarchy for you.<br>
354 </p>
355 </ul>
356 <div style="margin-left: 40px;"> </div>
357 <table
358 style="text-align: left; width: 75%; margin-right: auto; margin-left: auto;"
359 border="0" cellspacing="2" cellpadding="2">
360 <tbody>
361 <tr>
362 <td style="vertical-align: top;">ROLE_TITLEBAR <span
363 style="font-weight: bold;">[inserted by system]</span><br>
364 ROLE_MENUBAR <span style="font-weight: bold;">[important if you don't
365 use native menus]</span><br>
366 ROLE_SCROLLBAR<br>
367 ROLE_GRIP<br>
368 ROLE_SOUND<br>
369 ROLE_CURSOR<br>
370 ROLE_CARET<br>
371 ROLE_ALERT<br>
372 ROLE_WINDOW <span style="font-weight: bold;">[inserted by system]</span><br>
373 ROLE_CLIENT <span style="font-weight: bold;">[important]</span><br>
374 ROLE_MENUPOPUP <span style="font-weight: bold;">[important]</span><br>
375 ROLE_MENUITEM <span style="font-weight: bold;">[important]</span><br>
376 ROLE_TOOLTIP<br>
377 ROLE_APPLICATION<br>
378 ROLE_DOCUMENT<br>
379 ROLE_PANE <span style="font-weight: bold;">[important]</span><br>
380 ROLE_CHART<br>
381 ROLE_DIALOG<br>
382 ROLE_BORDER<br>
383 ROLE_GROUPING<br>
384 ROLE_SEPARATOR <span style="font-weight: bold;">[important]</span><br>
385 ROLE_TOOLBAR<br>
386 ROLE_STATUSBAR <span style="font-weight: bold;">[important]</span><br>
387 ROLE_TABLE <span style="font-weight: bold;">[important]</span><br>
388 ROLE_COLUMNHEADER<br>
389 ROLE_ROWHEADER<br>
390 ROLE_COLUMN<br>
391 ROLE_ROW<br>
392 ROLE_CELL <span style="font-weight: bold;">[important]</span><br>
393 ROLE_LINK <span style="font-weight: bold;">[important]</span><br>
394 ROLE_HELPBALLOON<br>
395 ROLE_CHARACTER<br>
396 </td>
397 <td style="vertical-align: top;">ROLE_LIST <span
398 style="font-weight: bold;">[important]</span><br>
399 ROLE_LISTITEM <span style="font-weight: bold;">[important]</span><br>
400 ROLE_OUTLINE <span style="font-weight: bold;">[important]</span><br>
401 ROLE_OUTLINEITEM <span style="font-weight: bold;">[important]</span><br>
402 ROLE_PAGETAB <span style="font-weight: bold;">[important]</span><br>
403 ROLE_PROPERTYPAGE <span style="font-weight: bold;">[important]</span><br>
404 ROLE_INDICATOR<br>
405 ROLE_GRAPHIC <span style="font-weight: bold;">[important]</span><br>
406 ROLE_STATICTEXT <span style="font-weight: bold;">[important]</span><br>
407 ROLE_TEXT <span style="font-weight: bold;">[important]</span><br>
408 ROLE_PUSHBUTTON <span style="font-weight: bold;">[important]</span><br>
409 ROLE_CHECKBUTTON <span style="font-weight: bold;">[important]</span><br>
410 ROLE_RADIOBUTTON <span style="font-weight: bold;">[important]</span><br>
411 ROLE_COMBOBOX <span style="font-weight: bold;">[important]</span><br>
412 ROLE_DROPLIST <span style="font-weight: bold;">[important]</span><br>
413 ROLE_PROGRESSBAR <span style="font-weight: bold;">[important]</span><br>
414 ROLE_DIAL<br>
415 ROLE_HOTKEYFIELD<br>
416 ROLE_SLIDER<br>
417 ROLE_SPINBUTTON<br>
418 ROLE_DIAGRAM<br>
419 ROLE_ANIMATION<br>
420 ROLE_EQUATION<br>
421 ROLE_BUTTONDROPDOWN<br>
422 ROLE_BUTTONMENU<br>
423 ROLE_BUTTONDROPDOWNGRID<br>
424 ROLE_WHITESPACE<br>
425 ROLE_PAGETABLIST <span style="font-weight: bold;">[important]</span><br>
426 ROLE_CLOCK<br>
427 ROLE_SPLITBUTTON<br>
428 ROLE_IPADDRESS<br>
429 ROLE_NOTHING<br>
430 <br>
431 </td>
432 </tr>
433 </tbody>
434 </table>
435 <div style="margin-left: 40px;"></div>
436 <h2 style="margin-left: 40px;"><a name="objid"></a>MSAA Object
437 Identifiers Cheat Sheet<br>
438 </h2>
439 <div style="margin-left: 40px;"> </div>
440 <p style="margin-left: 80px;">For information on what each object
441 identifier does, see the <a
442 href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msaa/msaaccrf_7jlf.asp">MSDN
443 Object Identifiers Constants page</a>.</p>
444 <div style="margin-left: 80px;">Check with <big><big></big></big>our
445 assistive technology partners to find out what object identifiers you
446 need to support. There's a very good chance they won't ask for more than
447 the object itentifiers marked <span style="font-weight: bold;">[important]</span>:<br>
448 </div>
449 <dl style="margin-left: 120px;">
450 <dt>OBJID_ALERT<br>
451 OBJID_CARET<br>
452 OBJID_CLIENT <span style="font-weight: bold;">[important]</span><br>
453 OBJID_CURSOR<br>
454 OBJID_HSCROLL<br>
455 OBJID_NATIVEOM <span style="font-weight: bold;">[important? might be
456 useful for supporting custom interfaces, need to research]</span><br>
457 OBJID_MENU<br>
458 OBJID_QUERYCLASSNAMEIDX<br>
459 OBJID_SIZEGRIP<br>
460 OBJID_SOUND<br>
461 OBJID_SYSMENU<br>
462 OBJID_TITLEBAR<br>
463 OBJID_VSCROLL<br>
464 OBJID_WINDOW<br>
465 </dt>
466 </dl>
467 <h2><a name="quirks"></a>3. Dealing with the Quirks of MSAA</h2>
468 <div style="margin-left: 40px;"> </div>
469 <p style="margin-left: 40px;">MSAA has a well deseved reputation for
470 quirkiness. It is not "plug and play", and will take a lot of
471 testing/refinement before your solution works with any product. Here are
472 some of its quirks and some solutions/workarounds:<br>
473 </p>
474 <div style="margin-left: 40px;"><big><a name="Crash_prone"></a>MSAA can
475 be crash prone</big><br>
476 </div>
477 <div style="margin-left: 80px;"><br>
478 <span style="text-decoration: underline;">Problem</span>: Many of
479 MSAA's crash occur because more than one process is refcounting the same
480 objects, and because pointers are being shared between processes. When
481 your application closes, different signals are typically broadcast. For
482 example, the application window closes and the window is blurred. It is
483 impossible to know if and when the 3rd party assistive technology will
484 use one of these signals to release the objects of yours that is is
485 refcounting. This can lead to crashes where it releases something and
486 the wrong time, when some of your dll's are unloaded but not others,
487 and a destructor is called in an unloaded DLL.<br>
488 <br>
489 <span style="text-decoration: underline;">Solution</span>: Create a
490 "shutdown" method for each internal accessible object, to remove any
491 references to other internal objects before any of your dll's are
492 unloaded. In order to do this effectively, you will have to keep track
493 of every accessible object that you create. The shutdown method for an
494 accessibility object should be called whenever the document or UI object
495 it refers to goes away. The easiest way to do that is to keep a pointer
496 to an accessible in each internal UI object. If that pointer is
497 non-null, then there is an accessible object for it. Whenever the UI
498 object is destroyed, shutdown its accessible object as well. In
499 Gecko/Mozilla we are not allowed to keep this extra pointer for each
500 accessible object, so when accessibility is turned on we use a hash
501 table to cache these objects. Such a cache must be kept in perfect sync
502 with the tree of UI and document objects, which is difficult. Therefore,
503 unless 4 bytes extra on each object is criticial in your application,
504 just keep the extra pointer around instead of using a hash table.<br>
505 <br>
506 Also, don't implement EVENT_OBJECT_CREATE or EVENT_OBJECT_DESTROY.
507 Vendors have found that watching these events causes crashes.<br>
508 <br>
509 </div>
510 <div style="margin-left: 40px;"><big><a
511 name="Hacky_caret_tracking_not_working"></a>Hacky caret tracking
512 causes problems<br>
513 </big></div>
514 <div style="margin-left: 80px;"><br>
515 <span style="text-decoration: underline;">Problem</span>: Assistive
516 technologies do not use the MSAA caret. They follow screen draws,
517 looking for a vertical blinking line. Unfortunately, some products can
518 get confused by the vertical lines on other objects, such as list boxes,
519 even though those lines are not blinking. The assistive technology may
520 not see your caret at all.<br>
521 <br>
522 <span style="text-decoration: underline;">Solution</span>: Make sure
523 there is a configuration file for each assistive technology specific to
524 your application. Read the manual or help, and find the keystroke or
525 commands for training the caret, and save this information in the
526 configuration file. Don't support the MSAA caret, none of the vendors
527 use it.<br>
528 <br>
529 </div>
530 <div style="margin-left: 40px;"> <big><a name="Event_window_confusion"></a>Event
531 window handle is incorrect</big><br>
532 <br>
533 <div style="margin-left: 40px;"><span
534 style="text-decoration: underline;">Problem</span>: The screen reader
535 or other assistive technology does not track the focus or other events
536 correctly.<br>
537 <br>
538 <span style="text-decoration: underline;">Solution</span>: This may be
539 because you are reporting that the events in a different window from the
540 current system focused. The assistive technology may be asking
541 GetGUIThreadInfo for its hwndFocus, and throwing away MSAA events that
542 are not in the currently focused window. Even if you are visibly showing
543 window focus on the correct window, you must also tell the operating
544 system to focus this window before any other accessibility events get
545 fired in it. </div>
546 <br>
547 <big><a name="Confusion_with_system-generated_events"></a>Confusion
548 with system-generated events</big><br>
549 <br>
550 <div style="margin-left: 40px;"> <span
551 style="text-decoration: underline;">Problem</span>: When you test with
552 Accessible Event Watcher in the MSAA SDK, you will see many events that
553 your application did not generate. Microsoft Windows generates some
554 events for you. This is extremely annoying. The assistive technology has
555 no way to tell whether the event came from your application or from
556 Windows. For example, when you set window focus, Windows will generate
557 an EVENT_OBJECT_FOCUS event an a ROLE_WINDOW object it also generated
558 for you. If you happen to set window focus after you fired your own
559 EVENT_OBJECT_FOCUS event on an object in the widnow, your event will be
560 ignored, because assistive technology software tends to pay attention
561 only to the last focus event.<br>
562 <br>
563 <span style="text-decoration: underline;">Solution</span>: When an
564 object is about to get focused in a different window, make sure you
565 focus a window before you fire your own focus events for objects inside
566 it. Test using Accessible Event Watcher in the MSAA SDK, and use the
567 settings panel to watch subsets of accessibility events. Count on the
568 assistive technology to make sense out the jumble of extra
569 system-generated events, it's not your problem.<br>
570 </div>
571 <br>
572 <big><a name="No_unique_child_ID_for_object_in_window"></a>No unique
573 child ID for event target in window</big><br>
574 <br>
575 <div style="margin-left: 40px;"> <span
576 style="text-decoration: underline;">Problem</span>: MSAA expects
577 events to be reported using NotifyWinEvent(eventNum, hWnd, worldID,
578 childID), and there may not be an obvious way to get a window handle and
579 a 32 bit childID for an object. You may be using windowless controls, or
580 have an entire document with lots of objects in a given window. The
581 child ID must be unique, because this is what the assistive technology
582 will use to retrieve the accessible via AccessibleObjectFromEvent()
583 which ends up using get_accChild on the accessible for the given window.<br>
584 <br>
585 <span style="text-decoration: underline;">Solution</span>: In
586 Gecko/Mozilla, we did not want to store an extra 32 bit unique ID value
587 on every object. Instead, we hand back a 32 bit value derived from the
588 UI object's pointer, which is unique. We ensure that the value we hand
589 back is always negative. When the get_accChild call comes back, we check
590 our hash table cache for that window to see if there's an accessible
591 object still associated with that unique value. This means the client
592 must use AccessibleObjectFromEvent immediately, because there is a
593 danger that the object will go away, and another different object will
594 be created with the same pointer value.That case seems extremely remote,
595 because information from events is generally retrieved right after the
596 event.<br>
597 <br>
598 If you're not using a hash table to keep track of unique ID's, store
599 the child ID's and objects for the last 50 or so events in a circular
600 array. In practice, this is enough to keep AccessibleObjectFromEvent()
601 happy.<br>
602 </div>
603 <br>
604 <big><a name="Not_all_MSAA_features_utilized_by_3rd"></a>Not all MSAA
605 features utilized by 3rd party vendors</big><br>
606 <br>
607 <div style="margin-left: 40px;"> <span
608 style="text-decoration: underline;">Problem</span>: The assistive
609 technology does not use 50% of what's available in MSAA, e.g. MSAA
610 caret, a lot of events, roles, states and methods. It's difficult to
611 know which things to support.<br>
612 <br>
613 <span style="text-decoration: underline;">Solution</span>: Use this
614 document to see what is generally considered important by assistive
615 technology manufacturers. Contact the the top vendors early and often as
616 you plan and implement your architecture, to see what's important to
617 them. Implement only what's needed -- supporting everything would take
618 too long for zero results.<br>
619 </div>
620 <br>
621 <big><a name="Missing_functionality_in_MSAA"></a>Missing functionality
622 in MSAA</big><br>
623 <br>
624 <div style="margin-left: 40px;"><span
625 style="text-decoration: underline;">Problem and solutions:</span>
626 Assistive technology vendors need some things which MSAA does not
627 provide, such as:<br>
628 </div>
629 </div>
630 <ul style="margin-left: 40px;">
631 <ul>
632 <li>No way of signifying that a document has finished
633 loading.&nbsp; Fire EVENT_OBJECT_STATECHANGE for a window/client/pane
634 object when it starts to load a new document. Use STATE_BUSY to indicate
635 that a new document is being loaded. When the loading has finished, fire
636 another EVENT_OBJECT_STATECHANGE event and clear the STATE_BUSY
637 flag.&nbsp; </li>
638 <li>No method to get clipped/unclipped bounds of a piece of text
639 within a text object. This is needed by screen magnifiers. No scrollTo
640 method, also needed by screen magnifiers. Implement a custom interface
641 for text objects, and support it through QueryInterface or QueryService
642 if it's being implemented on a different object than IAccessible is.
643 Support a scrollTo method which takes a text index, and a
644 getClippedBounds and getUnclippedBounds method which takes a start and
645 end index. Publish your custom interface.</li>
646 <li>No way for assistive technology to know when scrolling has
647 stopped. Fire the EVENT_SYSTEM_SCROLLINGEND event to indicate when
648 scrolling has ended (try not to fire too many of these, wait until
649 scrolling has truly stopped). There is no need to support
650 EVENT_SYSTEM_SCROLLINGSTART, it is not used by assistive technology.<br>
651 </li>
652 </ul>
653 <ul>
654 <li>No support for document formatting or "DOM" as requested by
655 some vendors: support a custom interface that gives them the formatting
656 information they are requesting.<br>
657 </li>
658 </ul>
659 </ul>
660 <div style="margin-left: 40px;"><big><a name="Dueling_text_equivalents"></a>Dueling
661 text equivalents</big><br>
662 <br>
663 <div style="margin-left: 40px;"><span
664 style="text-decoration: underline;"> Problem</span>: There are three
665 kinds of text equivalents, and it is difficult to know when to use each.
666 Different applications behave differently in this regard. For example,
667 Acrobat uses accessible value for text labels where as most programs use
668 accessible name. There are different roles for text objects,
669 ROLE_STATICTEXT and ROLE_TEXT (editable text), which seems to be used
670 for non-editable text in many places.<br>
671 <br>
672 <span style="text-decoration: underline;">Solution</span>: Be as
673 consistent with Internet Explorer as possible. Use accessible name for
674 most text equivalents, and accessible value for URL's. Don't use
675 accessible description unless you really do have a long description for
676 the object you need to expose -- most assistive technology makes little
677 use of it. Use ROLE_STATICTEXT for labels specific to dialog and UI
678 controls, and always use ROLE_TEXT for document text even if the text is
679 not editable (in that case use ROLE_TEXT with STATE_READONLY).<br>
680 </div>
681 <br>
682 <big><a name="Issues_with_Links"></a>Issues with Links</big><br>
683 <br>
684 <div style="margin-left: 40px;"> <span
685 style="text-decoration: underline;">Problem</span>: The assistive
686 technology has inflexible heuristics when it comes to reading links.
687 First, it won't read the object unless the states are correctly set.
688 Second, it can mishandle the object if it cannot parse the whitespace
689 according to its own rules.<br>
690 <br>
691 <span style="text-decoration: underline;">Solution</span>: Make sure
692 the ROLE_LINK object and its child ROLE_TEXT objects all have
693 STATE_LINKED set. For multi-line links with a line break in the middle,
694 make sure there is no whitespace at the beginning or end of any of the
695 accessible names, and make sure there is a \r\n where the line breaks
696 occur in the accessible name for the ROLE_LINK. For an example of how to
697 do this properly, see Internet Explorer or Gecko. Again, if it's not
698 done exactly this way, some links will not be read.<br>
699 </div>
700 <br>
701 <big><a name="MSAA_Implementation_is_Not_Performant"></a>MSAA
702 Implementation is Not Performant</big><br>
703 <br>
704 <div style="margin-left: 40px;"><span
705 style="text-decoration: underline;"> Problem</span>: The assistive
706 technology may interact slowly with your application.<br>
707 <br>
708 <span style="text-decoration: underline;">Solution</span>: Try not to
709 calculate the same things more than once or create the same objects more
710 than once. For example, create and cache an object's children when you
711 look for them in get_accChildCount(), so that you can just hand them
712 back when asked for using get_accChild() or accNavigate(). Support
713 IEnumVARIANT so that the MSAA client can ask for a number of children in
714 one call. In custom interfaces, create methods that hand back a lot of
715 data in one call, rather than requiring a large number of calls. Fewer
716 calls are much better better because COM Marshaling is slow.<br>
717 </div>
718 <br>
719 <big><a name="Differing_client_implementations"></a>Differing client
720 implementations</big><br>
721 <br>
722 <div style="margin-left: 40px;"> <span
723 style="text-decoration: underline;">Problem</span>: Every assistive
724 technology uses MSAA differently.<br>
725 <br>
726 <span style="text-decoration: underline;">Solution</span>: We don't
727 know of any outright conflicts in the differing uses of MSAA (yet).
728 However, be on guard. If a vendors asks you to do something different
729 from the spec, it's better to check with the other vendors before moving
730 forward. Check to see what applications from Microsoft do in a similar
731 situation.<br>
732 </div>
733 <br>
734 <big><a name="Undocumented_Window_Class_Usage"></a>Undocumented Window
735 Class Usage</big><br>
736 <br>
737 <div style="margin-left: 40px;"> <span
738 style="text-decoration: underline;">Problem</span>: most assistive
739 technologies won't use your MSAA implementation out of the box. They
740 must list your window classes somewhere in their implementation, and
741 then turn on MSAA support when a window of that class receives focus.
742 The window class is also used to determine a host of hard-coded
743 behaviors, such as whether or not a screen reader will load the entire
744 MSAA tree into a special buffer for the user to navigate with screen
745 reader commands. This is only supposed to occur for document navigation,
746 not for UI/dialogs. where your application's keyboard commands will be
747 solely used to navigate.<br>
748 <br>
749 <span style="text-decoration: underline;">Solution</span>: Contact each
750 vendor and let them know what window classes you will be using MSAA for.
751 If possible, use a different window class name for documents/content
752 than you use for UI/dialogs. Or, do what Mozilla does&nbsp; - expose a
753 control ID (GWL_ID) of 1 for content, and 0 for UI. Consistent window
754 class names are important for the assistive technology vendors, so that
755 they can determine what code to run for a given window. Don't change
756 window class names after you have shipped a version.<br>
757 </div>
758 <br>
759 <big><a name="Vendor_quirks"></a>Vendor quirks</big><br>
760 <br>
761 <div style="margin-left: 40px;"> <span
762 style="text-decoration: underline;">Problem</span>: Because assistive
763 technology tends to utilize MSAA as an additional solution resting on
764 top of old hacks, rather than a completely clean and separate way to
765 deal with an application, and because of the quirky nature of MSAA and
766 of the inflexible heuristics that screen readers use, we do not have a
767 "plug and play solution". In addition, assistive technology vendors are
768 tiny companies, often scrambling to keep up with changes in the
769 applications they already support, or new products other than yours
770 which they need to support. It's very difficult to get vendors to spend
771 time testing an MSAA implementation, send feedback or help find out why
772 things aren't working. Time and version commitments often fall through.
773 There is always a belated new version due around corner, after which you
774 will be promised to be the next priority.<br>
775 <br>
776 <span style="text-decoration: underline;">Solution</span>: Try to reach
777 out in a friendly manner to the assistive technology company. Be as easy
778 to work with as you possibly can -- this includes being extremely
779 responsive to their bug reports with new test builds, as well as being
780 very communicative about what you have changed and when. Do as much work
781 as you possibly can without their help. See if your organization can
782 offer something they can't get for themselves. Be patient, and set your
783 expectations to a reasonable level. Realize that it's about both pride
784 and revenue for these companies, and that they need to sell a lot of
785 copies of their software to make up the work they put in to support
786 your app. Remember that no matter how small they are, you need them more
787 than they need you, unless your application's accessibility is being
788 demanded by end-users.</div>
789 </div>
790 <h2><a name="geckoimpl"></a>4. Example: How Gecko and Mozilla Implement
791 MSAA<br>
792 </h2>
793 <p style="margin-left: 40px;">The <a
794 href="http://lxr.mozilla.org/seamonkey/source/accessible/">Accessible
795 module</a> is where the Mozilla MSAA implementation lives. Feel free to <a
796 href="http://lxr.mozilla.org/seamonkey/source/accessible/">peruse the
797 source code in the accessible module</a> whenever you want to see how
798 something can be implemented.<br>
799 </p>
800 <p style="margin-left: 40px;">The accessible module is also where
801 support for Sun's <a
802 href="http://wwws.sun.com/software/star/gnome/accessibility/architecture.html">ATK</a>
803 accessibility API for Linux and UNIX is implemented. For documentation
804 specific to the Mozilla ATK effort, supported by Sun Microsystems, see
805 the <a
806 href="http://www.mozilla.org/projects/ui/accessibility/unix/index.html">Mozilla
807 accessibility on Unix</a> page.</p>
808 <h3 style="margin-left: 40px;"><a name="Creation_of_IAccessible_Objects"></a>Creation
809 of IAccessible Objects<br>
810 </h3>
811 <ul style="margin-left: 40px;">
812 <p> The first thing that happens when an assistive technology wants to
813 watch our application is that calls the Windows API function
814 AccessibleObjectFromWindow(). This usually happens right after a window
815 gets focused.<br>
816 </p>
817 <p>When the WIN32 API function AccessibleObjectFromWindow() is
818 called, Windows sends the window in question a <a
819 href="http://lxr.mozilla.org/seamonkey/search?string=WM_GETOBJECT">WM_GETOBJECT</a>
820 message requesting an IAccessible for your root object in the window. In
821 our case, this event is received in <a
822 href="http://lxr.mozilla.org/seamonkey/source/widget/src/windows/nsWindow.cpp#4370">mozilla/widget/src/windows/nsWindow.cpp</a>.
823 We send back an IAccessible pointer which can be used by the client to
824 get information about this root object. The assistive technology will
825 use that root IAccessible to traverse the rest of the object tree, by
826 navigating to children and then siblings, etc. Every navigation function
827 such as accNavigate(), get_accChild() and get_accParent() returns an
828 IAccessible pointer. <br>
829 </p>
830 <p>To create the root IAccessible for a window the first time it gets
831 the <a
832 href="http://lxr.mozilla.org/seamonkey/search?string=WM_GETOBJECT">WM_GETOBJECT</a>
833 message in, nsWindow.cpp first generates an internal event called <a
834 href="http://lxr.mozilla.org/seamonkey/search?string=NS_GETACCESSIBLE">NS_GETACCESSIBLE</a>,
835 which is handled in <a
836 href="http://lxr.mozilla.org/seamonkey/source/layout/html/base/src/nsPresShell.cpp#6345">PresShell::HandleEventInternal()</a>
837 via the creation of an <a
838 href="http://lxr.mozilla.org/seamonkey/find?string=msaa/nsDocAccessibleWrap">nsDocAccessibleWrap</a>
839 for an inner window or <a
840 href="http://lxr.mozilla.org/seamonkey/find?string=msaa/nsRootAccessibleWrap">nsRootAccessibleWrap</a>
841 for a top level window. These classes implement both nsIAccessible, our
842 cross platform API, as well as IAccessible, which is specific to
843 Windows/MSAA/COM. The cross-platform nsDocAccessible and
844 nsRootAccessible classes they inherit from are then told to start
845 listening for DOM, page load and scroll events.&nbsp; These events cause
846 MSAA-specific events, such as EVENT_OBJECT_FOCUS or
847 EVENT_OBJECT_STATECHANGE, to fire on UI and document objects within the
848 applicable window. We'll explain more about events later in this section.<br>
849 </p>
850 <p>Until the WM_GETOBJECT message is processed, the Gecko
851 accessibility service is not used, and thus the accessibility.dll is not
852 loaded, so there is almost zero overhead for accessibility API support
853 in Mozilla or Gecko, in the general case. Once the accessibility
854 service is created, however, Gecko loads code to create an object on
855 demand for every UI or document object that should support IAccessible.
856 The created objects are cached in a hash table, and shutdown when
857 they're no longer needed. They may still exist in memory in a
858 nonfunctional state until the assistive technology completely releases
859 them. See the section on accessible roles to see what kinds of objects
860 Gecko support IAccessible for.<br>
861 </p>
862 </ul>
863 <div style="margin-left: 40px;"> </div>
864 <h3 style="margin-left: 40px;"><a
865 name="The_Accessible_Tree_vs._the_DOM_Tree"></a>The Accessible Tree
866 vs. the DOM Tree<br>
867 </h3>
868 <div style="margin-left: 40px;"> </div>
869 <ul style="margin-left: 40px;">
870 <p>After the root or doc accessible for a window has been created and
871 handed back to the MSAA client, it is used to traverse the rest of the
872 IAccessible tree using accNavigation, get_accChild and get_accParent.
873 Any IAccessible will support those methods. We also support
874 IEnumVARIANT::Next() which allows for fast marshaling of all of an
875 objects children to a client via COM. In other words, the assistive
876 technology can say "give me all 20 children of this object into this
877 array". That's much faster than 20 separate calls, one for each child.<br>
878 </p>
879 <p>In Mozilla, the client has another choice for tree navigation --
880 it can utilize data stored in the DOM via Mozilla's custom <a
881 href="http://lxr.mozilla.org/seamonkey/source/accessible/public/msaa/ISimpleDOMNode.idl">ISimpleDOMNode</a>
882 COM interface. Any IAccessible can be used to QueryInterface to an
883 ISimpleDOMNode, and vice versa for a round trip. However, one might QI
884 ISimpleDOMNode to IAccessible only to find it is null, which means that
885 particular node in question is not exposed in the IAccessible tree. See
886 the following diagram for examples of nodes that do no support
887 IAccessible.<br>
888 </p>
889 </ul>
890 <div style="margin-left: 40px;"> </div>
891 <h3 style="margin-left: 40px;">MSAA tree vs. DOM tree - what's the
892 relationship?</h3>
893 <div style="margin-left: 40px;"> </div>
894 <ul style="margin-left: 40px;">
895 <p> <img
896 src="http://www.mozilla.org/projects/ui/accessibility/images/tree-relativity.gif"
897 alt="Diagram showing MSAA tree is a subset of the DOM tree"
898 title="Diagram showing MSAA tree is a subset of the DOM tree"> </p>
899 The MSAA tree and the DOM tree are parallel structures, although the
900 MSAA tree is a subset of the DOM tree. <code>QueryInterface()</code> can
901 be used to switch between the interfaces used in the two trees
902 (IAccessible and ISimpleDOMNode). If there is no MSAA node for a DOM
903 node,&nbsp; pAccessible-&gt;<code>QueryInterface(IID_IAccessible)</code>
904 will return null.
905 </ul>
906 <h3 style="margin-left: 40px;"><a
907 name="The_Implementations_Behind_IAccessible"></a>A Variety of
908 Implementations for IAccessible</h3>
909 <div style="margin-left: 40px;">
910 <div style="margin-left: 40px;">
911 <p>There are two main kinds of classes in Mozilla's accessibility class
912 hierarchy, platform-specifc and cross-platform. All of the
913 platform-specific classes have the word "Wrap" appended to them. The
914 Wrap classes contain implementations and interfaces specific to MSAA or
915 ATK. These platform-specific classes inherit from cross-platform
916 classes, where the most of the implementation is done. For example,
917 nsAccessibleWrap inherits from nsAccessible. Every accessible object in
918 the MSAA tree has an implementation dertived from nsAccessible, which
919 exposes accessibility information through nsIAccessible, in a generic
920 cross-platform manner. <br>
921 </p>
922 <p>This default implementation for nsIAccessible knows how to use
923 nsAccessibleTreeWalker to walk Mozilla's content DOM and frame tree,
924 exposing only the objects that are needed for accessibility. The
925 nsAccessibleTreeWalker class knows what it needs to expose by asking
926 each DOM node's primary frame (a Gecko formatting object) for an
927 nsIAccessible, using the nsIFrame::GetAccessible() method. If
928 nsAccessibleTreeWalker gets an nsIAccessible back, then the DOM node
929 considered to be an accessible object. The nsIAccessible that is
930 returned is either a new one, or reused from the accessibility cache,
931 and the correct type of accessibility object to correctly expose that
932 DOM node through the cross-platform nsIAccessible and MSAA-specific
933 IAccessible interfaces.<br>
934 </p>
935 <p>Every accessibility object created must be cached, and must inherit
936 from nsAccessibleWrap so that it supports a base implementation of
937 nsIAccessible and IAccessible. Apart from that, it is free to override
938 IAccessible or nsIAccessible methods. In this way each class is tailored
939 to the specific abilities and properties of the HTML or XUL/UI objects
940 it applies to, and can support both MSAA, ATK and hopefully any future
941 accessibility API's we need to support. For example
942 nsHTMLButtonAccessible overrides nsIAccessible::GetAccRole to expose
943 ROLE_BUTTON for IAccessible::get_accRole which uses that. <br>
944 </p>
945 </div>
946 </div>
947 <ul style="margin-left: 40px;">
948 <p>A more complicated set of nsIAccessible methods which can be
949 overridden are GetAccFirstChild/GetAccLastChild/GetAccChildCount, which
950 allows for objects to define their own decendant subtrees. The default
951 behavior for nsIAccessible::getAccFirstChild is to instantiate a
952 nsDOMTreeWalker, and ask it for the first child. However,
953 nsImageAccessible overrides getAccFirstChild, returning the first area
954 of an image map if there is one, otherwise nsnull. This is necessary
955 because the image map areas can be in a completely different area of the
956 DOM from the image they apply to.<br>
957 </p>
958 </ul>
959 <div style="margin-left: 40px;"> </div>
960 <h3 style="margin-left: 40px;"><a name="Generating_MSAA_Events"></a>Generating
961 MSAA Events</h3>
962 <div style="margin-left: 40px;"> </div>
963 <ul style="margin-left: 40px;">
964 <p>First, keep in mind that most MSAA events aren't utilized by
965 accessibility aids. Therefore we implement only the handful that matter.
966 See the <a
967 href="file:///c%7C/moz/mozdocs/mozilla-org/html/projects/ui/accessibility/accessible-architecture.html#events">Events</a>
968 cheat sheet above for the list of events we implement. By far the most
969 important one is EVENT_OBJECT_FOCUS.<br>
970 </p>
971 <p>When a potential accessibility-related event occurs within
972 Mozilla, it is typically listened for by nsDocAccessible or
973 nsRootAccessible. The event listeners on these classes call
974 FireToolkitEvent(), which is implemented for every accessible.
975 Eventually, the event ends up at nsDocAccessibleWrap::FireToolkitEvent()
976 which calls NotifyWinEvent from the Win32 API. NotifyWinEvent is passed
977 arguments for the window the event occurred in, and the ID of the child
978 within that window. Accessibility aids use the Win32 call
979 SetWinEventHook() to register as a listener for these events. Creating
980 a unique child ID for every object within a window can be difficult,
981 see the problem and solution for <a
982 href="file:///c%7C/moz/mozdocs/mozilla-org/html/projects/ui/accessibility/accessible-architecture.html#Hacky_caret_tracking_not_working">no
983 unique child ID for object in window</a>.<br>
984 </p>
985 <p>The assistive technology chooses which events it is interested in
986 learning more about by calling the Win32 method
987 AccessibleObjectFromEvent, which returns the IAccessible to the node
988 corresponding to the child number that had been indicated from
989 NotifyWinEvent(). This ends up asking
990 nsDocAccessibleWrap::get_accChild() for a child IAccessible which
991 matches the child ID we indicated through NotifyWinEvent(). </p>
992 <p>In Mozilla, we use the DOM node pointer in the accessible object
993 as a basis for its child ID, which is also used as a hash key into our
994 cache. We also negate the 32 bit value so that it is always &lt;0,
995 telling us that they're really looking for the IAccessible for an event,
996 not child number x. During the callback, we look up the original
997 accessible node in the nsDocAccessible's cache and return it. <br>
998 </p>
999 </ul>
1000 <div style="margin-left: 40px;"> </div>
1001 <div style="margin-left: 40px;"> </div>
1002 <h2><a name="feedback"></a>5. Feedback</h2>
1003 <div style="margin-left: 40px;">How can this document be improved? Was
1004 it useful? Questions? Contact <a href="mailto:aaronl@netscape.com">aaronl@netscape.com</a><br>
1005 </div>
1006 </body>
1007 </html>