<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0"><channel><title>Microsoft Windows UI Automation Blog</title><link>http://blogs.msdn.com/b/winuiautomation/</link><description>The Microsoft Windows UI Automation blog covers topics related to the the Windows Automation API</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/WinUIAutomation" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="winuiautomation" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Customizing the accessibility of my XAML and WinJS Windows 8 apps – Part 4: Postscript</title><link>http://blogs.msdn.com/b/winuiautomation/archive/2013/04/12/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-4-postscript.aspx</link><pubDate>Fri, 12 Apr 2013 03:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10410494</guid><dc:creator>Guy Barker MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/winuiautomation/rsscomments.aspx?WeblogPostID=10410494</wfw:commentRss><comments>http://blogs.msdn.com/b/winuiautomation/archive/2013/04/12/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-4-postscript.aspx#comments</comments><description>&lt;h1&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 4: Postscript&lt;br /&gt;Guy Barker&lt;/h1&gt;
&lt;p&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;amp;ndash; Part 1: Introduction" href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/02/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-1-introduction.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 1: Introduction&lt;/a&gt;&lt;br /&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;amp;ndash; Part 3: The WinJS app" href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/02/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-2-the-xaml-app.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 2: The XAML app&lt;br /&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 3: The WinJS app&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I recently had some fun exploring how I can customize the accessibility of a very simple Windows 8 app. I first built this app with XAML and then with WinJS, and it does the bare minimum required for me to demonstrate how to do the following four specific things.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Assign localized accessible names to elements.&lt;/li&gt;
&lt;li&gt;Associate localized strings with values along a slider.&lt;/li&gt;
&lt;li&gt;Make a screen reader aware that some text has just appeared and should to be spoken.&lt;/li&gt;
&lt;li&gt;Present images appropriate to the customer&amp;rsquo;s current high contrast theme.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Having done that, I thought it might be interesting to upload the apps to the Windows Store. By doing that, people can download them to their Windows 8 device and get a feel for the user experience provided as a result of the actions taken in parts 2 and 3 of this blog. And importantly, I could get feedback from people to let me know where I&amp;rsquo;ve missed something with the accessibility of the app&amp;rsquo;s current UI, or where the app&amp;rsquo;s UI could be expanded to demonstrate some other topic which can be problematic with shipping apps.&lt;/p&gt;
&lt;p&gt;So off I went, submitting the apps to the Store, checking the Accessibility box along the way...&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&lt;input id="AccessibleOptions" type="checkbox" name="AccessibleOptions" value="true" checked="checked" /&gt;&lt;input type="hidden" name="AccessibleOptions" value="false" /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;This app has been tested to meet accessibility guidelines, and should be shown to people who are specifically looking for apps that meet those guidelines. &lt;a class="FWLink" href="http://go.microsoft.com/fwlink/p/?linkid=221112&amp;amp;clcid=0x0409" target="_blank"&gt;Learn more&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Not long after that, I got told that one of the apps had failed the content compliance, and so I canceled the submission of the other app and looked into the problem.&lt;/p&gt;
&lt;p&gt;The first issue was that I&amp;rsquo;d broken the rule around not enhancing screenshots unless I&amp;rsquo;ve made it really obvious that I&amp;rsquo;ve done that. As the rule says, &amp;ldquo;Graphically enhanced screenshots are not allowed, unless they are clearly marked as having been enhanced.&amp;rdquo; I thought it&amp;rsquo;d be fun to stick a big screen reader speech bubble over the screenshot to show what the screen reader&amp;rsquo;s saying. Turns out that&amp;rsquo;s not such a good idea, but it&amp;rsquo;s something that&amp;rsquo;d be easy for me to fix.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/2185.AskHerbi_5F00_Part4.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/2185.AskHerbi_5F00_Part4.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The second issue was the more interesting one, and related to the requirement &amp;ldquo;Your app must offer customers unique, creative value or utility&amp;rdquo;.&amp;nbsp; In my case, the apps are only a resource relating to a developer blog, and not useful at all as end-user apps. So it&amp;rsquo;s fair enough that I got told that the value of the apps wasn&amp;rsquo;t clear.&lt;/p&gt;
&lt;p&gt;But it was fun submitting them anyway, and if I do get end up expanding them based on feedback &amp;ndash; who knows, one day perhaps they will be useful as apps in their own right.&lt;/p&gt;
&lt;p&gt;Given that apps aren&amp;rsquo;t available at the Store, I thought I&amp;rsquo;d make a short video of some of the accessibility-related functionality that the apps support. And as I did this, I also mentioned a few other aspects of the apps&amp;rsquo; accessibility which I&amp;rsquo;d not mentioned in the other parts of this blog.&lt;/p&gt;
&lt;p&gt;So here&amp;rsquo;s the video. Please excuse the poor quality of the filming and the dialogue. But really, when I do this sort of thing at the crack of dawn, I&amp;rsquo;m less concerned about the quality of the video, and more concerned about whether the kettle&amp;rsquo;s boiled.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.youtube.com/watch?v=xzJf3_Kx-JY&amp;amp;feature=share&amp;amp;list=UUy69QyrZ8wApDLD8l5Zp_IQ"&gt;http://www.youtube.com/watch?v=xzJf3_Kx-JY&amp;amp;feature=share&amp;amp;list=UUy69QyrZ8wApDLD8l5Zp_IQ&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10410494" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/XAML/">XAML</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/WinJS/">WinJS</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Accessibility/">Accessibility</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Windows+8/">Windows 8</category></item><item><title>Customizing the accessibility of my XAML and WinJS Windows 8 apps – Part 3: The WinJS app</title><link>http://blogs.msdn.com/b/winuiautomation/archive/2013/04/03/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-3-the-winjs-app.aspx</link><pubDate>Tue, 02 Apr 2013 23:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10407100</guid><dc:creator>Guy Barker MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/winuiautomation/rsscomments.aspx?WeblogPostID=10407100</wfw:commentRss><comments>http://blogs.msdn.com/b/winuiautomation/archive/2013/04/03/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-3-the-winjs-app.aspx#comments</comments><description>&lt;h1&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 3: The WinJS app&lt;br /&gt;Guy Barker&lt;/h1&gt;
&lt;p&gt;Say I&amp;rsquo;m fairly familiar with HTML, css and javascript, so it&amp;rsquo;s quick for me to build my new app in WinJS. I&amp;rsquo;ve found that I can use the app fine when only using the keyboard, and by pointing the Inspect SDK tool at the UI I can see all sorts of accessibility-related properties exposed by the app. I&amp;rsquo;ve also found that there are four places in my app&amp;rsquo;s accessibility story where there are gaps which I need to fill in. The blog describes what I need to do in order to deliver an app that&amp;rsquo;s fully accessible to all the customers I want to reach.&lt;/p&gt;
&lt;h2&gt;Accessible names&lt;/h2&gt;
&lt;p&gt;As I point the Inspect SDK tool to my UI, I can see an accessible name for the button and for the various text elements, but not for the slider or the image. This means as a customer uses the Narrator screen reader to examine the slider, they won&amp;rsquo;t hear a useful name describing what the slider relates to. (This will be case regardless of whether they&amp;rsquo;re using the physical keyboard or touch to interact with my app.) If the meaning of my slider is not made clear, then this significantly impacts the usefulness of my app.&lt;/p&gt;
&lt;p&gt;The image below shows no accessible name being exposed by the slider UI.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6114.Part3_5F00_Inspect1_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6114.Part3_5F00_Inspect1_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So I need at add a helpful accessible name to the slider. I could do this by simply adding an &amp;ldquo;aria-label&amp;rdquo; property to the slider tag that defines my slider. An aria-label is a way to specify an accessible name for some element, and is one of a set of properties you can add to UI, as listed at &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh767301.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/hh767301.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, I must assign a &lt;em&gt;localizable&lt;/em&gt; aria-label to the UI in order for the slider to have a useful name in all the geographical regions in which the app ships. So given that I&amp;rsquo;d not yet taken the steps to add localizable strings to my app, I&amp;rsquo;ll do that now.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a new &amp;ldquo;Resources File (.resjson)&amp;rdquo; item to my project.&lt;/li&gt;
&lt;li&gt;Create a &amp;ldquo;strings\en-us&amp;rdquo; folder in my project and move the new resjson file into there.&lt;/li&gt;
&lt;li&gt;Add an WinJS.Application.onloaded() function in default.js which gets called when the page is loaded.&lt;/li&gt;
&lt;li&gt;Near the top of the onloaded() function, add a call to WinJS.Resources.ProcessAll().&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that localizable strings are available in my app, I&amp;rsquo;ll insert the following in my slider&amp;rsquo;s markup.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; data-win-res="{attributes: {'aria-label' : 'appSliderName'}}"&lt;/p&gt;
&lt;p&gt;And I&amp;rsquo;ll then add the localizable string to my new string resource file.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "appSliderName" : "Risk level"&lt;/p&gt;
&lt;p&gt;So having done that, when I run the app and point the Inspect tool at the UI, I can now see the localizable friendly name.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/4718.Part3_5F00_Inspect2_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/4718.Part3_5F00_Inspect2_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This means that when a customer uses a screen reader to access the slider, they&amp;rsquo;ll hear &amp;ldquo;Risk level&amp;rdquo; and immediately know what the slider relates to.&lt;/p&gt;
&lt;p&gt;Now, a customer using a screen reader can examine UI regardless of whether the UI can get keyboard focus. For example, they may use touch to learn what UI is beneath their finger. So it&amp;rsquo;s important that all UI that&amp;rsquo;s not purely decorative has an accessible name. As such, I want the image that fills up most of the UI to have a useful, localized name.&lt;/p&gt;
&lt;p&gt;This is where things get interesting. When I originally&amp;nbsp;added the image to the app, I decided to make the image a background-image property on a div. When I did this this, I was interested in some of the css styling that&amp;rsquo;s possible with background images. Having built the app, I expect I didn&amp;rsquo;t need to have used a background image and I could have used a regular Img tag. But I&amp;rsquo;m going to stick with a background image here anyway, as it introduces a few interesting topics on accessibility.&lt;/p&gt;
&lt;p&gt;By the way, when building your UI in HTML, don&amp;rsquo;t forget to add explicit closing tags to elements where you can, rather than doing &amp;ldquo;/&amp;gt;&amp;rdquo; to close it. Without the explicit closing tag on some elements, your layout won&amp;rsquo;t following the grid rules you try to set up in css. I forgot this when building the app, and so got some unexpected layout for a while.&lt;/p&gt;
&lt;p&gt;So anyway, I added the image resource to my app, added the div in HTML and the related styling in css.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;div id="appImage"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #appImage {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-image:url(/images/Herbi.png);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-size: contain;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-position: center;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-repeat: no-repeat;&lt;br /&gt;&amp;hellip;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And sure enough, when I ran the app, the image appeared. However, when I point the Inspect tool at the image, it couldn&amp;rsquo;t see the image at all. The image was nowhere to be found in the UIA tree of elements. This means a screen reader won&amp;rsquo;t be able to find it either. The image below shows the slider, the button and the text controls in the UIA element hierarchy, but not the image.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/5241.Part3_5F00_Inspect3_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/5241.Part3_5F00_Inspect3_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So this is a critical problem from an accessibility perspective, and I need to take action to get the image added to the UIA tree. The problem is triggered by the fact that I used a div to create the UI. By default a div is not an accessible element, and isn&amp;rsquo;t exposed to a screen reader user. Other elements, such as a Button or Input are added to the UIA tree. A description of how HTML maps by default to UIA can be found at &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh452708.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/hh452708.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I can make a div element appear in the UIA tree by giving it some accessible role. It&amp;rsquo;s most appropriate in this case to give it a role of &amp;ldquo;img&amp;rdquo;, because it&amp;rsquo;s displaying an image. Once I&amp;rsquo;ve done that, I can point Inspect to the image, and I now see the element appear the UIA tree.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6646.Part3_5F00_Inspect4_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6646.Part3_5F00_Inspect4_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;However, I can now see that the element has no accessible name, so I need to fix that next. This is easy to do in the same way I added an accessible name to the slider earlier. I&amp;rsquo;ll add a localizable string to my string resources, and update my HTML to have the elements aria-label property set to that accessible name.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; data-win-res="{attributes: {'aria-label' : 'appImageName'}}"&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "appImageName" : "Herbi",&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6607.Part3_5F00_Inspect5_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6607.Part3_5F00_Inspect5_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Note that I don&amp;rsquo;t make the name something like &amp;ldquo;Picture of Herbi&amp;rdquo;, because including &amp;ldquo;picture&amp;rdquo; or &amp;ldquo;image&amp;rdquo; is redundant. When I gave the element a role of &amp;ldquo;img&amp;rdquo;, its control type was exposed as an Image control type, so screen readers can already inform my customers that the element is an image. The Name property&amp;nbsp;should be&amp;nbsp;constrained to making it clear exactly what it&amp;rsquo;s an image of.&lt;/p&gt;
&lt;p&gt;One additional note on the onLoaded() function that I added earlier; this is a good moment to stop and think about any other action that might be useful when the app starts. For example, where&amp;rsquo;s the most useful place for keyboard focus to be? For my customers who only use the keyboard, if it&amp;rsquo;s likely that the button is going to be the element that they&amp;rsquo;ll want to interact with first, then I&amp;rsquo;ll set focus to the button in the following way.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; appAskButton.focus();&lt;/p&gt;
&lt;h2&gt;Descriptive Slider values&lt;/h2&gt;
&lt;p&gt;By default, my slider supports the UIA RangeValue pattern. This makes sense, as is it has a minimum, a maximum and a current value, and all this is reported by the Inspect SDK tool.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6746.Part3_5F00_Inspect6_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6746.Part3_5F00_Inspect6_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When the Narrator screen reader examines slider UI that supports the RangeValue pattern, but which doesn&amp;rsquo;t support the Selection pattern or Value pattern, it reports the current value as a percentage of the full range. For my app, I really need friendly text to be associated with each value, to describe what each value means along this &amp;ldquo;Risk level&amp;rdquo; slider. I first wondered whether I could achieve this by adding support for the Selection pattern to the slider, by giving it some specific role, but my attempts there didn&amp;rsquo;t work given that I could find a way to create the element that was the associated selected item. But it turns out that in WinJS, there&amp;rsquo;s a far simpler way of achieving what I need.&lt;/p&gt;
&lt;p&gt;The first thing I should do is add a changeValue event handler for my slider. I&amp;rsquo;ll add this in the onLoaded() function that I added earlier.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById("appSlider").addEventListener('change', changeValue, false);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Then in this event handler I can set the aria-valuetext property of the slider based on its current value.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var risklevelIds = new Array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelLowId",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelMediumId",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelHighId",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelTopId"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Set the localized slider value text based on the supplied value of the slider.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function changeSliderValue() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var riskLevel = appSlider.value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var riskLevelText = WinJS.Resources.getString(risklevelIds[riskLevel]).value;&lt;br /&gt;&lt;span style="background-color: #ffff00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; appSlider.setAttribute("aria-valuetext", riskLevelText);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The aria-valuetext is described up at &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/Hh968009.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/Hh968009.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, doing that alone did not get the value text spoken by Narrator as I&amp;rsquo;d hoped. I then noticed that the description of the related aria-valuenow at &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465728.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/hh465728.aspx&lt;/a&gt;, says that that property &amp;ldquo;applies to elements with an ARIA role of progressbar, slider, or spinbutton.&amp;rdquo; So I added the following to my slider HTML.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; role="slider"&lt;/p&gt;
&lt;p&gt;When I then pointed the Inspect SDK tool at the UI, I could see that UIA Value pattern support had been added to the slider, and the Value property was set to my friendly text. And sure enough when I use my app with Narrator, as I changed the slider value, Narrator would speak the helpful text associated with each slider value.&lt;/p&gt;
&lt;p&gt;By the way, I also explicitly forced the aria-valuetext setting action on startup to, (before the slider value had been changed by my customer), I order to make sure the first time Narrator saw the slider, it had its friendly text set.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/1856.Part3_5F00_Inspect7_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/1856.Part3_5F00_Inspect7_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Announcing visual updates&lt;/h2&gt;
&lt;p&gt;And next we move to the part of the&amp;nbsp;UI which is its raison d'&amp;ecirc;tre &amp;ndash; the advice. When my customer invokes the app button, I present the result on the screen. I have an &amp;ldquo;h2&amp;rdquo; tag for the element which presents the text, and I set the innerText property on that when I want to show the text. If I point the Inspect SDK tool to the text after I&amp;rsquo;ve done that, I can see the result exposed in the UIA tree, and so it&amp;rsquo;s accessible to a screen reader.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/5074.Part3_5F00_Inspect8_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/5074.Part3_5F00_Inspect8_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The problem is that when I presented the text visually, nothing happened to let a screen reader know that the text was appearing. If I don&amp;rsquo;t give a screen reader a heads-up that text has appeared, it can&amp;rsquo;t know to speak the text, and so my customer misses out on the most important information that the app presents. So I must make sure that a screen reader is notified of the text appearing. I can do this my marking the element that shows the text as being a &amp;ldquo;Live Region&amp;rdquo;, as described at &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465711.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/hh465711.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By making the element a Live Region, I can have text-related changes lead to a UIA LiveRegionChanged event being raised. In response to that event, a screen reader can go back to the source element and speak whatever details about the element that it wants to. So I&amp;rsquo;ll add the following attribute to the &amp;ldquo;h2&amp;rdquo; tag.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aria-live="assertive"&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And by declaring it as being assertive, I&amp;rsquo;m telling screen readers that I want changes spoken as soon as the change in text happens, even if that means the screen reader interrupting itself if it was already in the middle of speaking. If I&amp;rsquo;d prefer a screen reader to finish what it was currently speaking before announcing the change in my text, I would make the Live Region &amp;ldquo;polite&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;By the way, some roles for elements automatically lead to the element being declared to be a Live Region. As described at &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh452704.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/hh452704.aspx&lt;/a&gt;, if you give an element the role of &amp;ldquo;log&amp;rdquo;, &amp;ldquo;alert&amp;rdquo; or &amp;ldquo;status&amp;rdquo;, it will become a Live Region. One of these three roles leads to the element being an &amp;ldquo;assertive&amp;rdquo; Live Region and the other two are &amp;ldquo;polite&amp;rdquo;. Which would you guess is the assertive one?&lt;/p&gt;
&lt;p&gt;So I could have given the element one of the roles, but instead I left it as an &amp;ldquo;h2&amp;rdquo; with &amp;ldquo;aria-live&amp;rdquo; explicitly applied. This results in Inspect showing a Text control which is an assertive live region, and whose accessible Name property is the text shown visually for the element. (Interestingly, I also see that the Text control contains another Text control which has the same accessible Name property. I don't know why this hierarchy exists, but having two elements here does not affect what I&amp;rsquo;ll do when it comes to building my app, so I'll not worry about it.)&lt;/p&gt;
&lt;p&gt;Having made my Text control a Live Region, I thought I'd run the AccEvent SDK tool to verify that the LiveRegionChanged events are getting raised as expected. I then noticed something really interesting, in that I'm getting two events raised with each click.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/7563.Part3_5F00_AccEvent_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/7563.Part3_5F00_AccEvent_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;That seemed strange, given that I thought I only set the text once. But then I noticed that before I set the text, I explicitly set the Text control's text to be "", (an empty string,) before I set the actual results. I did this to force the text to change. If the text I display happened to be the same text that I previously displayed, then the displayed text wouldn't change, and I don't think I'd get the LiveRegionChanged event raised. So I set the text on the element twice in rapid succession. I'll bet what's happening is that when AccEvent sees the first event, it goes back to&amp;nbsp;my app to get the new text&amp;nbsp;shown in the UI. But rather than finding the empty string, it find the results text&amp;nbsp;which was set on the UI since the first event was raised. Shortly after that AccEvent will react to the second event and&amp;nbsp;get the same text, (which explains the results shown in AccEvent above). None of this will affect my customer's experience, as the effects of the second event will immediately stomp on the effects of the first, because the element is an &lt;em&gt;assertive&lt;/em&gt; Live Region. So I'll leave all this as it is.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As I poke around my app with Inspect, I do notice one other thing that I&amp;rsquo;d like to tidy up. Before I invoke the button, the advice text element appears in the tree, but with no accessible Name property. This isn&amp;rsquo;t too surprising really, as I&amp;rsquo;ve yet to set any text on the element. So perhaps I should keep the element out of the tree whenever there&amp;rsquo;s no text set on it. I can do that through the use of the aria-hidden property, (&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465705.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/hh465705.aspx&lt;/a&gt;). I&amp;rsquo;ll add the following to my HTML.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aria-hidden="true"&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Then when I set the text on the element later, I&amp;rsquo;ll change the state of the aria-hidden property.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; appResult.setAttribute("aria-hidden", "false");&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now when I point Inspect to my app, the element doesn&amp;rsquo;t appear in the UIA tree until it&amp;rsquo;s presenting some text.&lt;/p&gt;
&lt;h2&gt;Presenting appropriate high contrast images&lt;/h2&gt;
&lt;p&gt;When my customers have specifically chosen a high contrast color theme to be used when my app presents its visuals, I want all visuals to be appropriately displayed. WinJS will do a great job at automatically changing the visuals for the text, button and slider in my app, but if I present a whacking great image in colours that contradict my customers&amp;rsquo; wishes, then that&amp;rsquo;s hardly a good user experience. As it happens, WinJS makes it a piece of cake for me to have appropriate images shown.&lt;/p&gt;
&lt;p&gt;My first step is to generate versions of my image which are black-on-white and white-on-black. The black-on-white version is to be shown when the &amp;ldquo;High Contrast White&amp;rdquo; theme is active, and the white-on-black image is to be shown when one of the light-on-black themes are active, (these being &amp;ldquo;High Contrast Black&amp;rdquo;, &amp;ldquo;High Contrast #1&amp;rdquo; or &amp;ldquo;High Contrast #2&amp;rdquo;). Having made my images, (doing my best with the Paint program), I add my images as assets in my app.&lt;/p&gt;
&lt;p&gt;But here&amp;rsquo;s the key thing; I name the assets such that WinJS will know they&amp;rsquo;re appropriate for use when specific high contrast themes are active. Given that my original image was called Herbi.png, I give my high contrast image assets the following names.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Herbi.contrast-black.png&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Herbi.contrast-white.png&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;My css for the original image-related element the following:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-image:url(/images/Herbi.png);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;WinJS will automatically show the appropriate one of Herbi.png, Herbi.contrast-black.png or Herbi.contrast-white.png depending on whether a high contrast theme is active. Pretty handy!&lt;/p&gt;
&lt;p&gt;There is one very important step I do need to take. When I was building the app, I&amp;rsquo;d deliberately decided to present the image as a background image, given that at the time I thought I might be leveraging some of the scaling and cropping functionality that&amp;rsquo;s possible through css for background images. But WinJS considers background images to be potentially problematic for people who use high contrast themes. If an image is in &amp;ldquo;the background&amp;rdquo;, that suggests that there may well be something in &amp;ldquo;the foreground&amp;rdquo;. The point of high contrast themes is to show a high contrast between the foreground and the background. If text lies on top of some image, then this could really interfere with the goals of using a high contrast theme. So WinJS reasonably decides that by default, background images should not be shown when a high contrast theme is active.&lt;/p&gt;
&lt;p&gt;In my cases however, I&amp;rsquo;ve chosen to present an image as a background image when it&amp;rsquo;s not really a background image at all. And I would like some image to be shown regardless of whether a high contrast theme is active. So I can override the default WinJS action of hiding background images, by setting the following css.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @media screen and (-ms-high-contrast)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #appImage&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -ms-high-contrast-adjust: none;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This means that an image will be shown, and WinJS will select the appropriate one based on which high contrast theme is active.&lt;/p&gt;
&lt;p&gt;I should point out that the appropriate image will be selected based on which high contrast theme, (if any,) was active when my app starts. This will normally be sufficient for my customers. But if my app showed some small UI where I felt that a customer might need to switch to use a high contrast theme while performing a particular task, and switch out of high contrast once that task is complete, then I might choose to have my images react to changes in the state of high contrast while the app is running. I can achieve this will the css below.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @media screen and (-ms-high-contrast)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #appImage&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -ms-high-contrast-adjust: none;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-color: #ffff00;"&gt;background: url(/images/herbi.contrast-black.png);&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-size: contain;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-position: center;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-repeat: no-repeat;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @media screen and (-ms-high-contrast:black-on-white)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #appImage {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-color: #ffff00;"&gt;background: url(/images/herbi.contrast-white.png);&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-size: contain;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-position: center;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; background-repeat: no-repeat;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;In fact, having written that css here, I might as well stick it in my app, and support changing the image as the state of high contrast changes while my app&amp;rsquo;s running, as shown below.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/2084.Part3_5F00_HCB_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/2084.Part3_5F00_HCB_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6266.Part3_5F00_HCW_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6266.Part3_5F00_HCW_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;So by default, my app was fully keyboard accessible. This means that a customer who has mobility impairments, (including those with severe impairments and who use a foot switch or head switch), would be able to use an on-screen keyboard to leverage the features in my app. Also by default, my app exposed a lot of accessibility-related information and visual behaviors which could be leveraged by my customers who have visual impairments. By taking the additional steps described above, I&amp;rsquo;ve completed the accessibility story for those customers, such that whether they interact with my app using a high contrast theme or through touch with a screen reader, all of my customers can access the full functionality of my app.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 1: Introduction" href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/02/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-1-introduction.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 1: Introduction&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 2: The XAML app " href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/02/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-2-the-xaml-app.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 2: The XAML app&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;amp;ndash; Part 4: Postscript" href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/12/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-4-postscript.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 4: Postscript&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10407100" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/WinJS/">WinJS</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Accessibility/">Accessibility</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Windows+8/">Windows 8</category></item><item><title>Customizing the accessibility of my XAML and WinJS Windows 8 apps – Part 2: The XAML app</title><link>http://blogs.msdn.com/b/winuiautomation/archive/2013/04/02/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-2-the-xaml-app.aspx</link><pubDate>Tue, 02 Apr 2013 22:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10407081</guid><dc:creator>Guy Barker MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/winuiautomation/rsscomments.aspx?WeblogPostID=10407081</wfw:commentRss><comments>http://blogs.msdn.com/b/winuiautomation/archive/2013/04/02/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-2-the-xaml-app.aspx#comments</comments><description>&lt;h1&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 2: The XAML app&lt;br /&gt;Guy Barker&lt;/h1&gt;
&lt;p&gt;So I&amp;rsquo;ve built my cool new Windows 8 in XAML. I&amp;rsquo;ve checked out its accessibility, and found there&amp;rsquo;s a lot I&amp;rsquo;ve got by default. I&amp;rsquo;ve also decided there are four specific things I need to do in order to deliver the fully accessible app my customers expect. This blog describes the steps I took around enhancing my XAML app&amp;rsquo;s accessibility.&lt;/p&gt;
&lt;h2&gt;Accessible names&lt;/h2&gt;
&lt;p&gt;If I point the Inspect SDK tool to my slider, it tells me that the slider has no accessible Name property, (as shown in the image below). That&amp;rsquo;s because there's no label for the control that XAML can use to set the accessible Name from. So I need to give the slider an accessible Name, such that when a screen reader user tabs to the control, they&amp;rsquo;re told what the meaning of the slider is.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/8863.Part2_5F00_InspectSlider_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/8863.Part2_5F00_InspectSlider_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I could set the Name in the slider&amp;rsquo;s XAML, by setting the AutomationProperties.Name property. This is really easy to do, and would seem to fix the issue. However, I mustn&amp;rsquo;t hard code English strings in the XAML, as what good is English to a screen reader user who doesn&amp;rsquo;t speak English? I want this app to be fully accessible in every market I ship.&lt;/p&gt;
&lt;p&gt;So instead, I&amp;rsquo;m going to give the slider a localizable accessible Name property. First I have to add the resource file for localizable strings. (I&amp;rsquo;d have to do this anyway, to localize the strings shown visually in the app.) There are lots of details up at MSDN around localizable resources, and it&amp;rsquo;s pretty much a case of doing the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Right click on your project, do Add-&amp;gt;New Item, Resources file (.resw)&lt;/li&gt;
&lt;li&gt;Move the file into a Strings\en-us folder, (for US English strings).&lt;/li&gt;
&lt;li&gt;Add strings to the file, matching ids of elements to the strings associated with them.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So in my case, I&amp;rsquo;m going to give the slider an id, like this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x:Uid="sliderRiskLevelId"&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m then going to update the resources file to match the AutomationProperties.Name for that element with a localizable string:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sliderRiskLevelId.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name &lt;strong&gt;Risk level&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When I next point Inspect to the slider, I see the required Name property.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6064.Part2_5F00_InspectSlider2_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6064.Part2_5F00_InspectSlider2_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I can then take the same steps for the image element in the app, so that when a screen reader examines the image, a relevant localized name can be presented to my customers.&lt;/p&gt;
&lt;p&gt;Note, as someone once said, &amp;ldquo;What&amp;rsquo;s in a name?&amp;rdquo; It can be tempting to think that if your XAML element has an &amp;ldquo;x:Name&amp;rdquo; set, then that will become the accessible Name property, as exposed through UIA. But that&amp;rsquo;s not the case. The &amp;ldquo;x:Name&amp;rdquo; property is exposed as the AutomationId property. The AutomationId is intended to be a unique identifier for that element relative to whatever else is shown in your app. The AutomationId is not localized, so a screen reader or your automation tests can use it to access the element regardless of the language of the app.&lt;/p&gt;
&lt;p&gt;Also, it's worth a comment here on how useful Inspect is when it comes to helping you become aware of things in your UI element hierarchy which could be a problem for your customers. When I ran Inspect, I noticed that the UIA tree of elements for my app included a text-related element with no name. This element was associated with the TextBlock which presents the advice that gets shown after the Ask button is invoked, but initially no text is shown in the TextBlock. As such, it's pretty confusing for it to be exposed in the UIA tree. To fix this, I initialized the TextBlock to not be shown, with the following XAML:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Visibility="Collapsed"&amp;nbsp;&lt;/p&gt;
&lt;p&gt;That removes the element from the UIA tree. When I later set the text on the TextBlock, I made it visible and so it then appeared in the UIA tree.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; adviceTextBlock.Visibility = Windows.UI.Xaml.Visibility.Visible;&lt;/p&gt;
&lt;h2&gt;Descriptive Slider values&lt;/h2&gt;
&lt;p&gt;While the AutomationProperties class can make it really easy to easily control some aspects of the app&amp;rsquo;s accessibility, sometimes you need the deeper customization available through a custom AutomationPeer. AutomationPeers are what make XAML elements accessible, and by introducing your own custom AutomationPeer, you might do a little work to customize a single accessible property, or take more involved steps to add specific behavioral support to a control. This MSDN article on custom automation peers, &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj219211.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj219211.aspx&lt;/a&gt; gives loads of useful details on what they can be used for. (Some of what follows here will only make sense if you&amp;rsquo;ve read that article.)&lt;/p&gt;
&lt;p&gt;After I first built my XAML app containing the slider, I ran Narrator and used the keyboard to change the slider position. Narrator notified me of new the slider values, but that took the form of speaking the percentage values &amp;ldquo;0&amp;rdquo;, &amp;ldquo;33&amp;rdquo;, &amp;ldquo;67&amp;rdquo; and &amp;ldquo;100&amp;rdquo;. The purpose of my slider is to set a risk level, and numeric values don&amp;rsquo;t express much meaning, other than perhaps assuming that a higher number is riskier than a lower number. What&amp;rsquo;s more, why don&amp;rsquo;t I hear the absolute values &amp;ldquo;0&amp;rdquo;, &amp;ldquo;1&amp;rdquo;, &amp;ldquo;2&amp;rdquo; and &amp;ldquo;3&amp;rdquo;? To answer this, we should point the Inspect tool at the slider again, and look closely at what UIA patterns are supported by the slider. (UIA patterns relate to the behaviors of elements.) Of interest to me here is that Inspect tells me that the RangeValue pattern is supported, but the Value pattern and Selection pattern are not, (as shown in the image below).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/3362.Part2_5F00_InspectPattern_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/3362.Part2_5F00_InspectPattern_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When Narrator examines an element, it might look for specific pattern support based on the element&amp;rsquo;s UIA control type. (Inspect shows me that the slider has a control type id of UIA_SliderControlTypeId.) In the case of a slider, Narrator will first check for support of the Selection pattern, then the Value pattern and finally the RangeValue pattern. If only the RangeValue pattern is supported, it will access the current value and speak this as a percentage of the full slider range. This is the behavior I get by default in my app. If I wanted to override this to have absolute values spoken by Narrator, I would need to add Value pattern support to the slider. And if I want to have Narrator speak some descriptive text associated with each slider value, I need to add Selection pattern support. So I&amp;rsquo;ll add Selection pattern support next. (I would add Value pattern support in a similar way, if I&amp;rsquo;d needed that.)&lt;/p&gt;
&lt;p&gt;So here I go, adding Selection pattern support to my slider.&lt;/p&gt;
&lt;p&gt;The first thing I&amp;rsquo;ll do is create my own class, through which my custom AutomationPeer can be accessed.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class CustomSlider : Slider&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override AutomationPeer OnCreateAutomationPeer()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new CustomSliderAutomationPeer(this);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll then reference my custom class in the XAML, by replacing the use of the &amp;ldquo;Slider&amp;rdquo; element with &amp;ldquo;local:CustomSlider&amp;rdquo;. This means that when Narrator asks for accessible data associated with the element, that data will be provided by a CustomSliderAutomationPeer class that I now need to create.&lt;/p&gt;
&lt;p&gt;Given that most of the accessible data that I want exposed by the element will be the same as that exposed by a regular slider, I want my custom AutomationPeer to be derived from the AutomationPeer class that provides the accessible data for a regular slider.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class CustomSliderAutomationPeer : SliderAutomationPeer&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public CustomSliderAutomationPeer(CustomSlider owner)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : base(owner)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Next I&amp;rsquo;ll override the GetPatternCore() method, to say that the element supports the Selection pattern in addition to the RangeValue pattern that it supports by default.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override object GetPatternCore(PatternInterface patternInterface)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (patternInterface == PatternInterface.RangeValue)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;span style="background-color: #ffff00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (patternInterface == PatternInterface.Selection)&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #ffff00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #ffff00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: #ffff00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now, having declared that my custom AutomationPeer class supports the Selection pattern, I&amp;rsquo;d better add that support. To add support, I&amp;rsquo;ll need to implement all the members of the ISelectionProvider interface, (as described at &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.automation.provider.iselectionprovider.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.automation.provider.iselectionprovider.aspx)&lt;/a&gt;. The IsSelectionRequired and CanSelectMultiple properties are easy, but the GetSelection() method&amp;rsquo;s going to take a bit more thought.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class CustomSliderAutomationPeer : SliderAutomationPeer, ISelectionProvider&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool IsSelectionRequired&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool CanSelectMultiple&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IRawElementProviderSimple[] GetSelection()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;hellip;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The GetSelection() method returns an array of IRawElementProviderSimple objects, but in my case there&amp;rsquo;s only going to be one element in the array. This element represents the selection, and will only be used to provide an accessible name to be spoken by Narrator. The object must implement the ISelectionItemProvider interface if it&amp;rsquo;s to be the item returned by the slider as the element that is the current selection, so I first wondered if I needed to define some new class for the selection item. But then I took a look through &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/dd319586(v=vs.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/dd319586(v=vs.85).aspx&lt;/a&gt; to see what standard XAML controls support the SelectionItem pattern. The ListBoxItem seemed pretty tempting, so I decided to leverage that class as my selection item.&lt;/p&gt;
&lt;p&gt;I created an instance of a ListBoxItem when my AutomationPeer is created, and cached the ListBoxItem for later use. I also cached my single-element array which I&amp;rsquo;d return from the calls to GetSelection(). In fact I now have all the objects I need to return a selection.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private ListBoxItem m_item;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private IRawElementProviderSimple[] m_collection;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public CustomSliderAutomationPeer(CustomSlider owner)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : base(owner)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_item = new ListBoxItem();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AutomationPeer itemPeer = FromElement(m_item);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_collection = new IRawElementProviderSimple[1];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_collection[0] = ProviderFromPeer(itemPeer);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Finally, I fill in the blanks in the GetSelection() method, by setting an appropriate AutomationProperties.Name property on the ListBoxItem I created, and returning that in the array representing the selection.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IRawElementProviderSimple[] GetSelection()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] sliderItemTextIds = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelLowId",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelMediumId",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelHighId",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelTopId"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int idxSlider = (int)base.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var loader = new Windows.ApplicationModel.Resources.ResourceLoader();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string sliderText = loader.GetString(sliderItemTextIds[idxSlider]);&lt;/p&gt;
&lt;p&gt;&lt;span style="background-color: #ffff00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_item.SetValue(Windows.UI.Xaml.Automation.AutomationProperties.NameProperty, sliderText);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="background-color: #ffff00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return m_collection;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The bulk of that function simply gets the localized text that I want to be spoken for the slider value.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;By making the changes above, I&amp;rsquo;ve added Selection pattern support to my slider. When Narrator examines the slider and finds the Selection pattern supported, it retrieves an IRawElementProviderSimple associated with the selection. In my case that&amp;rsquo;s provided by the ListBoxItem whose accessible Name property I&amp;rsquo;ve set to be a string associated with the current slider value. Narrator speaks that Name as I change the slider value.&lt;/p&gt;
&lt;p&gt;So this all works great for me. In theory another screen reader might examine other properties of the object that I return as the selection, and those properties might be rather unexpected from the user&amp;rsquo;s perspective. For example, why would a slider&amp;rsquo;s selection have a control type of ListBoxItem? If that ever turned out to be an issue, I&amp;rsquo;d need to look into changing that.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;By the way, for completeness I thought it might be worth setting a ThumbToolTipValueConverter on my slider too. This would allow me to have the tooltips shown which&amp;nbsp;match the text spoken by Narrator. So I created the necessary class, and referenced an instance of it on my slider.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sliderRiskLevel.ThumbToolTipValueConverter = new TooltipStringGenerator();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class TooltipStringGenerator : IValueConverter&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public TooltipStringGenerator() {}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public object Convert(object value, Type type, object parameter, string language)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] sliderItemTextIds = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelLowId",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelMediumId",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelHighId",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "riskLevelTopId"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double dv = (double)value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int idxSlider = (int)dv;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var loader = new Windows.ApplicationModel.Resources.ResourceLoader();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return loader.GetString(sliderItemTextIds[idxSlider]);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public object ConvertBack(object value, Type type, object parameter, string language)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new NotSupportedException();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s worth pointing out here that setting the tooltip strings alone isn&amp;rsquo;t sufficient to meet the meets of the screen reader experience. When the tooltip pops up with the friendly text, Narrator might speak that text, depending on what else is going on at the time. But as the slider value changes, Narrator won&amp;rsquo;t speak the updated tooltip. So the custom AutomationPeer is necessary to provide the experience I want my customers to have.&lt;/p&gt;
&lt;p&gt;The image below shows the Narrator cursor on the slider, and the visual tooltip showing the same text as Narrator is speaking for the slider value.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/0317.Part2_5F00_Tooltips_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/0317.Part2_5F00_Tooltips_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Announcing visual updates&lt;/h2&gt;
&lt;p&gt;When I invoke the app button, the answer I&amp;rsquo;m looking for appears visually in the UI. But if Narrator doesn&amp;rsquo;t announce that text when it appears, then the app&amp;rsquo;s as good as useless. I need a way to tell a screen reader to pay attention to the text that appeared, even though it&amp;rsquo;s appearing at some point distant from where keyboard focus is. (In general, screen readers need to be careful not to announce all visual changes on the screen, because many of those changes would only be a distraction to the user.)&lt;/p&gt;
&lt;p&gt;So I&amp;rsquo;ll explicitly declare the TextBlock that shows the answer to be what&amp;rsquo;s known as a &amp;ldquo;live region&amp;rdquo;, with a handy one-line change.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AutomationProperties.LiveSetting="Assertive"&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(Here we see the same useful AutomationProperties class that we saw earlier when setting the accessible Name.)&lt;/p&gt;
&lt;p&gt;There are two aspects of having some UI be a live region. The first is that when the contents of the element change, an event should be raised so that UIA clients such as screen readers are aware that&amp;rsquo;s something&amp;rsquo;s changed. This is done by raising a UIA LiveRegionChanged event. If I&amp;rsquo;d built some custom control I&amp;rsquo;d need to raise the event itself. But conveniently, if I've declared the TextBlock to be a live region, then XAML raises the event for me whenever the text in the element changes.&lt;/p&gt;
&lt;p&gt;The second part of using live regions is declaring what type of live region the element is. When Narrator receives the event, it will examine the AutomationProperties.LiveSetting property of the element that raised the event. If the LiveSetting is assertive, Narrator will let the user know about the current state of the element immediately, (including the new text set on it). So this announcement will interrupt Narrator if it happened to be saying something else at the time of the event. If I&amp;rsquo;d given the element a LiveSetting of &amp;ldquo;polite&amp;rdquo;, then Narrator would finish what it was in the process of saying when the event was raised, before announcing the new state of the element to my customer.&lt;/p&gt;
&lt;p&gt;To get confirmation that all was as I expected when the contents of the TextBlock in my app changed, I pointed the AccEvent SDK tool to the TextBlock. As the image shows below, I could see the event getting raised, and that the LiveSetting property on the element that raised the event was &amp;ldquo;Assertive&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/5428.Part2_5F00_AccEvent_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/5428.Part2_5F00_AccEvent_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I can&amp;rsquo;t stress the importance of the AutomationProperties.LiveSetting enough. If your customers interact with some controls in your app, and some critical information is displayed elsewhere in the app as a result of the interaction, a screen reader will very likely need to announce that critical information at that time. Often the simple step of declaring a TextBlock to have an assertive LiveSetting is all you need to do.&lt;/p&gt;
&lt;h2&gt;Presenting appropriate high contrast images&lt;/h2&gt;
&lt;p&gt;When I first built my app, I created an Image element and slapped in an existing image that I had lying around. That was easy. But then I turned on one of the high contrast themes and ran my app, and realized I&amp;rsquo;m not quite done yet. I don&amp;rsquo;t want to display large chunks of a white background when my customer wants light text shown on a black blackground. In many cases, presenting colours that are inappropriate to the current theme will make things difficult or impossible to make out, and in some cases it can be physically painful.&lt;/p&gt;
&lt;p&gt;I could choose to show no images at all when a high contrast theme is active. But in the case of my images I think it would generally be preferable to present high contrast versions of them rather than not showing any image at all. So I set to work in Paint, creating black-on-white and white-on-black versions. The results aren&amp;rsquo;t too inspiring, but they illustrate the point I&amp;rsquo;m making here.&lt;/p&gt;
&lt;p&gt;There were three steps to leveraging my new high contrast masterpieces.&lt;/p&gt;
&lt;p&gt;1. Add the new png files as asserts to my app project.&lt;/p&gt;
&lt;p&gt;2. Change the source property in my Image element&amp;rsquo;s declaration to use an image loaded as a resource.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Source="{StaticResource imageHerbi}"&lt;/p&gt;
&lt;p&gt;3. Update the existing ResourceDictionary in the project&amp;rsquo;s StandardStyles.xaml, such that an image appropriate to the active high contrast theme will get loaded.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResourceDictionary.ThemeDictionaries&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResourceDictionary x:Key="Default"&amp;gt;&lt;br /&gt;&amp;hellip;&lt;br /&gt;&lt;span style="background-color: #ffff00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;x:String x:Key="imageHerbi"&amp;gt;Assets/Herbi.png&amp;lt;/x:String&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ResourceDictionary&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResourceDictionary &lt;span style="background-color: #ffff00;"&gt;x:Key="HighContrast"&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;hellip;&lt;br /&gt;&lt;span style="background-color: #ffff00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;x:String x:Key="imageHerbi"&amp;gt;Assets/Herbi.contrast-black.png&amp;lt;/x:String&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ResourceDictionary&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ResourceDictionary &lt;span style="background-color: #ffff00;"&gt;x:Key="HighContrastWhite&lt;/span&gt;"&amp;gt;&lt;br /&gt;&lt;span style="background-color: #ffff00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;x:String x:Key="imageHerbi"&amp;gt;Assets/Herbi.contrast-white.png&amp;lt;/x:String&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ResourceDictionary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ResourceDictionary.ThemeDictionaries&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To test my high contrast change, I need to set&amp;nbsp;the high contrast theme before running my app. I tend to pick a high contrast theme by right-clicking on the desktop, choosing Personalize, and then selecting the theme I&amp;rsquo;m interested in. I could instead just turn on high contrast from&amp;nbsp;the Ease of Access&amp;nbsp;settings, but that will only use the most recent high contrast theme used, (or the default). I&amp;nbsp;always check my UI in High Contrast White and at least one of the light-on-dark themes.&lt;/p&gt;
&lt;p&gt;By the way, in Visual Studio the XAML Design view reported the following exception&amp;nbsp;when I added the resource string:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exception: An object of the type "System.String" cannot be applied to a property that expects the type "Windows.UI.Xaml.Media.ImageSource".&lt;/p&gt;
&lt;p&gt;I ignored that exception given that everything seemed to work fine when I ran the app.&lt;/p&gt;
&lt;p&gt;The images below show the app running in two high contrast themes.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/0218.Part2_5F00_HCB_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/0218.Part2_5F00_HCB_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/5238.Part2_5F00_HCW_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/5238.Part2_5F00_HCW_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Ok, so having done the above, my app now exposes localized friendly names for my slider and image, and also provides meaningful strings for the slider values. It announces the results as they appear in the UI, and also presents colours which are appropriate for high contrast themes. It&amp;rsquo;s now good to be declared &amp;ldquo;Accessible&amp;rdquo; when I upload it to the Windows Store!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 1: Introduction" href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/02/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-1-introduction.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 1: Introduction&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 3: The WinJS app" href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/03/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-3-the-winjs-app.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 3: The WinJS app&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;amp;ndash; Part 4: Postscript" href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/12/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-4-postscript.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 4: Postscript&amp;nbsp;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10407081" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/XAML/">XAML</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Accessibility/">Accessibility</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Windows+8/">Windows 8</category></item><item><title>Customizing the accessibility of my XAML and WinJS Windows 8 apps – Part 1: Introduction</title><link>http://blogs.msdn.com/b/winuiautomation/archive/2013/04/02/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-1-introduction.aspx</link><pubDate>Tue, 02 Apr 2013 21:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10407071</guid><dc:creator>Guy Barker MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/winuiautomation/rsscomments.aspx?WeblogPostID=10407071</wfw:commentRss><comments>http://blogs.msdn.com/b/winuiautomation/archive/2013/04/02/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-1-introduction.aspx#comments</comments><description>&lt;h1&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 1: Introduction&lt;br /&gt;Guy Barker&lt;/h1&gt;
&lt;p&gt;Windows 8 apps built using XAML or WinJS, automatically support a certain level of accessibility by default. These two UI frameworks provide controls which are programmatically accessible, can be controlled through the keyboard and can present visuals appropriate for the current high contrast theme. In some cases however, the nature of the app&amp;rsquo;s UI means that the UI frameworks alone can&amp;rsquo;t automatically provide the fully accessible experience that your customers need. As such, there are steps that you as the app developer can take to elevate the default accessibility to the level required.&lt;/p&gt;
&lt;p&gt;This blog explores some of the more common actions you might do to build that fully accessible experience. To illustrate the points, I&amp;rsquo;ve built a new app called &amp;ldquo;Ask Herbi&amp;rdquo;. (The app helps me with decision-making when I&amp;rsquo;m not in a decision-making mood.) I use a slider to set the level of risk that I find acceptable, and then invoke a button to have a response generated to help me with my course of action. I built two pretty much identical versions of the app using XAML and WinJS, both of which were based on the &amp;ldquo;blank&amp;rdquo; app templates available in VS Express 2012 for Windows 8.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/4604.Part1_5F00_App_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/4604.Part1_5F00_App_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The apps fully support keyboard accessibility by default. I can tab to, and control, the slider and button, and that&amp;rsquo;s really important from an accessibility perspective. If I point the Inspect SDK tool to the controls, I can see all sorts of accessibility-related properties being exposed by the apps through the UI Automation (UIA) API. And if I run the apps while a high contrast theme is active, the controls show colours appropriate to the high contrast theme. So the apps are well on the way to being accessible.&lt;/p&gt;
&lt;p&gt;In the case of my particular apps, there are some gaps in their accessibility which I now need to address. These gaps are listed below.&lt;/p&gt;
&lt;h2&gt;Accessible names&lt;/h2&gt;
&lt;p&gt;The slider has no accessible name, and so a screen reader user doesn&amp;rsquo;t know what the slider refers to. For some controls, (such as a button), the UI frameworks can consider the text displayed with the control to be the control&amp;rsquo;s accessible name. But if the control has no associated text, (such as a slider or list), then the app developer needs to explicitly give the control an accessible name. I also need to do a similar thing with the image displayed by the app. Even though keyboard focus doesn&amp;rsquo;t move to the image, a screen reader user can explore the full UI in the app, and examine all the accessible properties of the image.&lt;/p&gt;
&lt;h2&gt;Descriptive Slider values&lt;/h2&gt;
&lt;p&gt;As I change the value of the slider, its value exposed through the UIA API is based on the numeric range. (In my case, that&amp;rsquo;s 0 to 3.) When the Narrator screen reader speaks the current value, it speaks the value as a percentage of the slider&amp;rsquo;s full range. For my customer&amp;rsquo;s I don&amp;rsquo;t want a numeric value spoken at all. Rather I&amp;rsquo;d like a helpful text string spoken as the value changes, explaining the meaning of the slider at its new value.&lt;/p&gt;
&lt;h2&gt;Announcing visual updates&lt;/h2&gt;
&lt;p&gt;When I tab to the button, Narrator will tell me what has focus, and so I know I&amp;rsquo;m ready to ask the app to generate the answer I&amp;rsquo;m after. So I invoke the button and the result appears visually on the screen. However, Narrator says nothing when the result appears. Knowing this result is the whole point of using the app, so if it&amp;rsquo;s not accessible, my app&amp;rsquo;s serving no purpose. Technically, I could use the screen reader to navigate through the UI that&amp;rsquo;s not keyboard focusable, but there&amp;rsquo;s no way I want to do that for such a critical piece of data. Instead, I simply want to invoke the button, and then hear the result spoken.&lt;/p&gt;
&lt;h2&gt;Presenting appropriate high contrast images&lt;/h2&gt;
&lt;p&gt;When a high contrast theme is active, I want to present an image that&amp;rsquo;s appropriate to the theme. Due to the way I present the image in my WinJS app, no image appears at all when a high contrast theme is active. In my XAML app, I see my regular image, which is really not helpful to my customers, as shown below. &lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6355.Part1_5F00_HC_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6355.Part1_5F00_HC_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Instead, I want an image presented that's appropriate to the active high contrast theme, such as that shown below.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/3264.Part1_5F00_HC_5F00_Image_5F00_scaled.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/3264.Part1_5F00_HC_5F00_Image_5F00_scaled.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So while the UI frameworks have given me a ton of accessibility-related functionality by default, I&amp;rsquo;ll now take the steps necessary to address the issues just listed. And as it happens, the UI frameworks make most of this pretty easy for me to do.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;The following two parts of this blog detail the changes I made to my XAML app and WinJS app in order to make them fully accessible. For your app, there might be some different steps around accessibility that you&amp;rsquo;ll be interested in, but the steps discussed in this blog are some of the more common ones.&lt;/p&gt;
&lt;p&gt;Having built these exploratory apps, I&amp;rsquo;ll probably upload them to the Windows Store next. I&amp;rsquo;ll check the box declaring them as accessible during the upload process. If I&amp;rsquo;ve missed something around accessibility while building the apps, hopefully I&amp;rsquo;ll get feedback from customers describing the issue, and I can update the apps accordingly. And if you&amp;rsquo;d like to have this blog updated to demonstrate something about accessibility that it&amp;rsquo;s not describing today, let me know. It&amp;rsquo;d be interesting for me to explore other aspects of accessibility with Windows 8 apps.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 2: The XAML app" href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/02/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-2-the-xaml-app.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 2: The XAML app&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 3: The WinJS app" href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/03/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-3-the-winjs-app.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 3: The WinJS app &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a title="Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;amp;ndash; Part 4: Postscript" href="http://blogs.msdn.com/b/winuiautomation/archive/2013/04/12/customizing-the-accessibility-of-my-xaml-and-winjs-windows-8-apps-part-4-postscript.aspx"&gt;Customizing the accessibility of my XAML and WinJS Windows 8 apps &amp;ndash; Part 4: Postscript&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10407071" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/XAML/">XAML</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/WinJS/">WinJS</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Accessibility/">Accessibility</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Windows+8/">Windows 8</category></item><item><title>What can I do to make my Windows 8 WinJS.UI.ListView app as accessible as possible?</title><link>http://blogs.msdn.com/b/winuiautomation/archive/2013/02/20/what-can-i-do-to-make-my-windows-8-winjs-ui-listview-app-as-accessible-as-possible.aspx</link><pubDate>Wed, 20 Feb 2013 15:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10395585</guid><dc:creator>Guy Barker MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/winuiautomation/rsscomments.aspx?WeblogPostID=10395585</wfw:commentRss><comments>http://blogs.msdn.com/b/winuiautomation/archive/2013/02/20/what-can-i-do-to-make-my-windows-8-winjs-ui-listview-app-as-accessible-as-possible.aspx#comments</comments><description>&lt;p&gt;I recently spent five years working in the Windows Accessibility team, working on most of the accessibility-related features in Windows. This included the UI Automation API, Narrator, Magnifier and the On-Screen Keyboard. A few months ago I started working in a Windows Apps team, and so was very interested in studying accessibility from the App developer&amp;rsquo;s perspective. In order to learn more about this, I examined a new app that I created from the HTML/Javascript Grid App Template. My goal was to understand exactly how WinJS.UI.ListView UI is accessible by default, and what additional steps a developer can do to make the UI even more accessible. At the end of this blog, I&amp;rsquo;ve listed a summary of my findings.&lt;/p&gt;
&lt;h1&gt;Programmatic Access&lt;/h1&gt;
&lt;p&gt;Many assistive technology products will want to access and interact with your UI. For example, a screen &lt;br /&gt;reader will speak the details of your UI to users who have visual impairments, and magnifiers will follow keyboard focus around the screen. Your UI is made accessible through the UI Automation (UIA) API available in Windows. The WinJS framework builds up a hierarchical tree of elements representing the UI on the screen, and that tree is accessed by UIA client apps.&lt;/p&gt;
&lt;p&gt;So having created my new app from the HTML Grid App template, I pointed the Inspect SDK tool to it, and examined the results reported by Inspect. These results are shown in Figure 1.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/8765.Inspect_5F00_1.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/8765.Inspect_5F00_1.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Figure 1: Inspect reporting the UIA tree for an app based on the Grid App template.&lt;/p&gt;
&lt;p&gt;A number of things caught my attention when I did this, and I could see that there was already a lot of support for accessibility built into the WinJS.UI.ListView control. Great! But I was particularly interested in whether there was additional action I could take myself to further enhance the accessibility of the UI in some way.&lt;/p&gt;
&lt;p&gt;The follow topics were some of the things I considered.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Should I try to name the unnamed &amp;ldquo;pane&amp;rdquo; element high up in the tree?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In general, the user really doesn&amp;rsquo;t want to encounter elements that don&amp;rsquo;t have accessible names. For example, a button without a name means that the user won&amp;rsquo;t know what&amp;rsquo;s going to happen if they click it. Similarly an app with multiple lists which don&amp;rsquo;t have names can make the experience very challenging for a screen reader user. (Sometimes container elements that are only used for layout purposes appear in the tree, and while it&amp;rsquo;s preferable for them to have names, it&amp;rsquo;s not such a problem when they don&amp;rsquo;t given that the user will usually not interact with them.)&lt;/p&gt;
&lt;p&gt;It turns out that that the unnamed pane shown by Inspect is not a part of the UI defined in the HTML that describes the UI in the pages that got generated when I created my app. So this is not something I can easily control myself. As such I&amp;rsquo;ll leave the unnamed pane as it is, and when the user encounters it, they&amp;rsquo;ll ignore it and move on to the more interesting elements.&lt;/p&gt;
&lt;p&gt;By the way, there are a bunch of other pane elements shown high up in the UIA tree, with names of &amp;ldquo;WinJS_NewAppFromGridAppTemplate_1&amp;rdquo;. These names all came from the name I supplied for the new app when I created it form the template. So your pane elements there will have whatever name you gave.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Should I set the accessible names of other elements that are defined in my HTML files?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="background-color: #ffff00;"&gt;The answer here is a resounding &lt;strong&gt;Yes!&lt;/strong&gt;&lt;/span&gt; This is one of the most important things you should do as part of delivering the most accessible app possible. The template used to create the app has already populated many elements with names, such as &amp;ldquo;List of groups&amp;rdquo; for the list shown on the first page when I run the app. But you&amp;rsquo;ll want to change this to best describe your list. So for example, say I was presenting a list of houses for sale. The accessible name on the list is set through the use of the aria-label attribute in the groupedItems.html file, and so by replacing the default text of &amp;ldquo;List of groups&amp;rdquo; with &amp;ldquo;Houses for sale&amp;rdquo;, my customers who user screen readers can know what the list refers to.&lt;/p&gt;
&lt;p&gt;&lt;span style="background-color: #ffff00;"&gt;&lt;em&gt;However&lt;/em&gt;,&lt;/span&gt; to do that would only be useful to my customers who speak English. Given that I want a worldwide customer base, I want to present a localized accessible name for the list. I wouldn&amp;rsquo;t present English text visually to my Spanish speaking customers, so why would I present English text audibly? So, when setting the aria-label attribute here, I want to use a localized string. I can do this by replacing the default aria-label attribute with the following in the HTML, (where &amp;ldquo;stringGreeting&amp;rdquo; is the id of some localized string).&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;data-win-res="{attributes: {'aria-label' : 'stringGreeting'}}"&lt;/p&gt;
&lt;p&gt;Of course, this means you need to update your app to include the localized string. I just did this with my new app with the steps below. (You&amp;rsquo;ll want to do this regardless of accessibility, to make it easy to localize you app for worldwide distribution.)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a new &amp;ldquo;Resources File (.resjson)&amp;rdquo; item to my project.&lt;/li&gt;
&lt;li&gt;Create a &amp;ldquo;strings\en-us&amp;rdquo; folder in my project and move the new resjson file into there.&lt;/li&gt;
&lt;li&gt;Near the top of the &amp;ldquo;ready&amp;rdquo; function in my page&amp;rsquo;s js file, add a call to WinJS.Resources.ProcessAll().&lt;/li&gt;
&lt;li&gt;Edit the new file to contain the localized string I want to show. For example:&lt;br /&gt;"stringGreeting" : "Welcome to Houses For Sale!"&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Similarly I&amp;rsquo;ll want to replace all the other fixed strings that are set through aria-label in the VS solution, with localized strings. I can then point the Inspect SDK tool at my UI and verify that no elements defined on my pages have missing accessible names.&lt;/p&gt;
&lt;p&gt;So with the above few steps, I have an app which is ready for worldwide distribution regardless of whether my customers will consume the text visually or through a screen reader.&lt;/p&gt;
&lt;p&gt;But hold on &amp;ndash; what&amp;rsquo;s that unnamed group element shown in the Inspect results? The results show an unnamed group element as the first and last child elements of another group with the name &amp;ldquo;Scrolling Container&amp;rdquo;. It turns out that all these group elements are created by WinJS when I use the ListView and their names are not under my control. As such, they&amp;rsquo;re not something I should spend time on changing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. The order of the list items and group headers in the UIA tree does not match their order shown on the screen.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Figure 2 shows the UIA tree for the last set of descendant elements beneath the list. It shows a number of list items, followed by elements representing the group headers shown in the list. So this raises the question, does this mean that when a user moves through the list via a screen reader which relies on the UIA tree, the user will be taken to all the items, and then to all the group headers? This seems less helpful than moving to a group header, then to all the items in the group (in order), then onto the next group header.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6811.Inspect_5F00_2.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6811.Inspect_5F00_2.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Figure 2: Descendants of the list element in the UIA tree.&lt;/p&gt;
&lt;p&gt;This more preferable navigation order is supported, thanks to the WinJS.UI.ListView&amp;rsquo;s use of the UIA FlowsTo and FlowsFrom properties. These properties allow an element to specify which element logically precedes it and which follows it in the UI, when those elements aren&amp;rsquo;t adjacent in the UIA tree. So there&amp;rsquo;s nothing I need to do here to enable a useful navigation path through my items and group headers.&lt;/p&gt;
&lt;p&gt;By the way, you may wonder why the Inspect SDK tool reports an ARIA role of &amp;ldquo;option&amp;rdquo; for the list items. (The ARIA specification includes a role of &amp;ldquo;listitem&amp;rdquo; after all.) This is because the ARIA &amp;ldquo;listitem&amp;rdquo; role doesn&amp;rsquo;t support a selected state, whereas the WinJS.UI.ListView makes it very easy to enable single- or multi-selection of items. The ARIA &amp;ldquo;option&amp;rdquo; role does support selection, so that&amp;rsquo;s the role the list gives to its items. The end result is that when UIA exposes data on this element, the element has an ARIA role and localized control type sting of &amp;ldquo;option&amp;rdquo;, and a UIA Control Type of UIA_ListItemControlType.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Do the elements in my UI have unique identifiers?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Sometimes assistive technology apps such as screen readers want a unique identifier to search for a particular element in your UI. Automated test frameworks certainly want to do this. So how do you give your element such an identifier? In many cases, if you set an id on your div, that id will be exposed through UIA as the UIA AutomationId property for the element. For example,&amp;nbsp;if I add some id to the list in my new app, say id=&amp;rdquo;listHouses&amp;rdquo;, then I can see the AutomationId set by using the Inspect tool, as shown in Figure3.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6837.Inspect_5F00_3.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/6837.Inspect_5F00_3.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Figure 3: Inspect reporting the AutomationId for the list in my new app.&lt;/p&gt;
&lt;p&gt;Note that setting the id of divs contained within WinJS.UI.ListView items does not result in the UIA AutomationId being set. So if you want to set some id on the divs contained within the list items for automation test purposes, you&amp;rsquo;d want to set some custom attribute on the div, and have your automated test framework examine the DOM.&lt;/p&gt;
&lt;p&gt;So that wraps up what struck me as I looked at the UIA tree associated with my new WinJS.UI.ListView app. A great UIA element hierarchy, (along with very helpful properties being set on those elements), is critical to allowing a screen reader to provide a fully functional and efficient experience to your customers. While there are a number of screen readers available for Windows, I then wanted to explore the experience provided by one in particular; the in-box screen reader &amp;ndash; Narrator!&lt;/p&gt;
&lt;h1&gt;Narrator&lt;/h1&gt;
&lt;p&gt;As I&amp;rsquo;ve just said, having your app present a great representation of its UI through UIA is essential if a screen reader is to describe the UI to your customers. The Narrator screen reader only uses UIA to access your app&amp;rsquo;s UI, and so if some data&amp;rsquo;s not exposed through UIA, Narrator can&amp;rsquo;t present it. But verifying a great UIA representation alone doesn&amp;rsquo;t necessarily mean your customers are going to get the best screen reader experience they can. So in addition to verifying the UIA representation, it&amp;rsquo;s really helpful to your customers to consider the resulting screen reader experience.&lt;/p&gt;
&lt;p&gt;For example, say your customer wants to navigate through the items in your list to find a particular item. As they move between items, they&amp;rsquo;ll not want to find that they have to listen to a lot of text that&amp;rsquo;s the same for a bunch of nearby items, before they hear the text that differentiates the new item from the previous. That&amp;rsquo;ll be a really slow and frustrating experience. Instead, they want to hear something immediately that lets them know whether they&amp;rsquo;ve found an item of interest. By default WinJS will build up an accessible name for a list item based on the text elements contained within the item. So take a look at that accessible name&amp;nbsp;with the Inspect tool and consider whether the user&amp;rsquo;s going to hear the most valuable text almost immediately or not. And to really get an appreciation for the user experience, turn on Narrator, turn off your monitor, and arrow around your list. Remember that this is not only about building an app that&amp;rsquo;s technically accessible, but providing a fully functional &lt;em&gt;and efficient&lt;/em&gt; experience.&lt;/p&gt;
&lt;p&gt;Another important consideration is around images shown in the list items. In my new app, the list items include an &amp;ldquo;img&amp;rdquo; tag, and also set the alternate text for the images to some bound strings. So it&amp;rsquo;s great that the template reminds app devs to consider alternate text here. (As with the aria-label mentioned earlier, the alternate text that finally gets supplied to the user needs to be localized.) But say for some reason, you wanted to set the background-image attribute of some div to present an image, rather than using the img tag. (Sometimes it can be more straightforward to get a particular cropping and scaling that you want for an image though the styling of the background-image.) So you add your div, and set its background-image attribute accordingly through its css.&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;background-image: url(house.jpg);&lt;/p&gt;
&lt;p&gt;If you then point the Inspect SDK tool to your new div, no element shows up in the UIA tree for the new div. As such Narrator is unaware of the image, and cannot make your customer aware of it. While it&amp;rsquo;s important not to distract the screen reader user with information which is not generally useful to them, I prefer to make the presence of the useful image discoverable to the user if they choose to explore the UI in detail. As such I want to make sure some UIA element associated with the image-related div exists in the UIA tree. This is straightforward by adding the following to the javascript associated with the UI:&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;myBackgroundImageDiv.setAttribute("role", "img");&lt;br /&gt;myBackgroundImageDiv.setAttribute("aria-label", WinJS.Resources.getString("stringImageDescription").value);&lt;/p&gt;
&lt;p&gt;Once I&amp;rsquo;ve added a localized image description, Inspect will then show that a UIA element exists for the image-related div, and it has the useful alternate text.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Controlling the list item&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Programmatic accessibility isn&amp;rsquo;t only about exposing details of what you&amp;rsquo;re showing on the screen. It&amp;rsquo;s also essential that your customers can use a screen reader to control that UI too. For example, your customer needs to be able to invoke or select an item. This is enabled by default, thanks to the WinJS.UI.ListView supporting specific UIA patterns. (A UIA pattern is used to describe the behavior of UI.) Because the list item supports the Invoke pattern, the Narrator user can invoke it. And because the list item supports the SelectionItem pattern the Narrator user can select and deselect it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Navigation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The Narrator user can use touch gestures or keyboard shortcuts to move to the next or previous UI element, so thanks to WinJS.UI.ListView&amp;rsquo;s use of UIA&amp;rsquo;s FlowsTo and FlowsFrom properties, the Narrator user can navigate between list items.&amp;nbsp; By default the navigation will not include the individual elements within a list item, but the user can navigate through these contained elements if they choose to. They would do this with a keyboard by using the CapsLock+RightArrow shortcut. (Note that if the item contains an image div, then this could be included in the navigation by changing Narrator&amp;rsquo;s cursor movement mode setting to &amp;ldquo;Advanced&amp;rdquo; first.)&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s some interesting background on Narrator&amp;rsquo;s touch gestures at &lt;a title="Using your feedback to make Narrator work better with touch" href="http://blogs.msdn.com/b/b8/archive/2012/07/18/using-your-feedback-to-make-narrator-work-better-with-touch.aspx"&gt;Using your feedback to make Narrator work better with touch&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Using your app with the keyboard&lt;/h1&gt;
&lt;p&gt;Many of your customers will want to access the full functionality of your app through use of the keyboard alone. There are a whole host of reasons for wanting to do that, ranging from some users simply finding it most efficient to only use the keyboard, to users who have severe mobility impairments and interact with their device through a head switch or foot switch. (Your customers who use a switch device will interact with your app with an on-screen keyboard rather than a physical keyboard.)&lt;/p&gt;
&lt;p&gt;The great point here is that the list items in the WinJS.UI.ListView supports keyboard access by default. Your customers can use the tab key to move focus into the list, and then use the arrow keys to move between items once the list has focus. Use of the Page Up/Down and Home/End keys allow for faster navigation through the list. If you want an item in the list to have focus when the app starts, be sure to set focus to the list when you create it. When a list item first gets added to the list, focus will move to that list item.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve modified the list from the HTML Grid App template such that it supports selection, a press of the Spacebar will select or deselect the focused list item. A new app created from the template also contains an invoke event handler which gets called when a list item has focus and you press the Enter key.&lt;/p&gt;
&lt;p&gt;All of the above keyboard action can be taken either at a physical keyboard or an on-screen keyboard.&amp;nbsp; Figure 4 shows the Windows OSK docked beneath my new app. The OSK is scanning the keys to allow the user to navigate through the list of items by only using a switch device.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/7607.OSK_5F00_4.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/7607.OSK_5F00_4.png" alt="" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Figure 4: Interacting with the app by using the OSK in scan mode.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Group headers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;An important point that I discovered while working with my new app with the keyboard is that WinJS.UI.ListView doesn&amp;rsquo;t have built-in support for interacting with group headers via the keyboard. As I tabbed around in my app I found that keyboard focus didn&amp;rsquo;t go to the group headers, even though I could invoke the header with a mouse click. The reason why focus didn&amp;rsquo;t go to the headers is because the template used for the list has a &amp;ldquo;tab-index&amp;rdquo; property of -1. (This meant the group headers should not be included in the tab order.) So as a test I removed that, and sure enough keyboard focus navigation included the group headers. But having done that, if I moved focus to a group header and pressed the Enter key, the UI reacted as though focus was really on the most recently focused list item. So to avoid confusion, I added the &amp;ldquo;tab-index&amp;rdquo; of -1 back in.&lt;/p&gt;
&lt;p&gt;But it&amp;rsquo;s essential that your customers who only use a keyboard can access all the functionality in your app. If a group header can be invoked with the mouse, you must allow it to be invoked through the keyboard. This requires the page&amp;rsquo;s javascript to take action to enable this, and it turns out my newly created app already has an example of just how this can be done. If I set focus to a particular list item, and then press Ctrl+Alt+g, this invokes the group header associated with the selected list item. I can see how this is done by looking at the keydown event handler that automatically got created in my app&amp;rsquo;s groupedItems.js file.&lt;/p&gt;
&lt;p&gt;So the end result is that while the WinJS.UI.ListView doesn&amp;rsquo;t have built-in support for invoking the group headers with the keyboard, with the additional javascript that automatically gets created in your app, your customers can invoke the headers just fine. And that&amp;rsquo;s good news &amp;ndash; because it&amp;rsquo;s critical that all your functionality can be leveraged using only the keyboard.&lt;/p&gt;
&lt;h1&gt;High Contrast&lt;/h1&gt;
&lt;p&gt;Your sighted customers need to be able to read all the text that you show, and that means there needs to be a useful contrast between the text and its background. (My keyboard at home shows the Function Key text in dark blue on a black background, and it&amp;rsquo;s really irritating spending time scrutinizing which key&amp;rsquo;s which.) So make sure that when using the default Windows theme, your text stands out clearly against the background.&lt;/p&gt;
&lt;p&gt;Now some of you customers will have selected a high contrast theme to make it practical for them to read text on the screen, and so your text needs to respect those high contrast colours in order to be useable. So I selected a high contrast colour theme, and took a look at the results&amp;nbsp; in my new app. (In order to experiment with different themes, I select these by right clicking on the classic desktop, selecting Personalize, and then picking one of the High Contrast themes. I always at least try out High Contrast Black and High Contrast White.) You don&amp;rsquo;t have to restart a WinJS app after changing the theme, as the app automatically gets updated to reflect the new system colours. Having changed the theme, I found that the items in my list got updated just fine. The background of the list items was the newly active window background colour and the text was the newly activate window text colour.&lt;/p&gt;
&lt;p&gt;Given that everything worked just great, it&amp;rsquo;s tempting to leave high contrast now, and move onto the next topic. But this is where you can stop to consider if there's anything you can do beyond checking that the minimum expectations around high contrast have been met, and elevate the experience to something more useful in practice. For example, when I run my new app with the High Contrast Black theme active I find that the items have no borders showing, which means if my items only contained text, it would be a challenge for some of my customers with low vision to quickly determine where one item ends and the next begins. So once the default text shown in Figure 5 has been replaced with all your actual text, it might be less efficient to use your app than your customers would like.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/4571.HC_5F00_5.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/4571.HC_5F00_5.png" alt="" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Figure 5: High contrast list items with no clear delineator between items.&lt;/p&gt;
&lt;p&gt;So you might consider changing the styling of the items when a high contrast theme is active, to make each item stand out more. For example, all it takes is to add the following styling to the new app&amp;rsquo;s css for the .item-overlay, in order to get the borders shown in Figure 6. And another great thing here is that the colour of the border will automatically be set to the colour appropriate for the currently active high contrast theme.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; border-style: solid;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; border-width: 4px;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/1856.HC_5F00_6.png"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/1856.HC_5F00_6.png" alt="" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Figure 6: High contrast list items with a clear border around each item.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Images&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While the following isn&amp;rsquo;t specific to images presented in lists, given that many lists do show images, I thought it was worth mentioning it here.&lt;/p&gt;
&lt;p&gt;Another important question you&amp;rsquo;ll want to ask yourself relates to background images. As you turn your app from the one created fresh from a template into the one that exactly meets the need of your business, you may have chosen to present some images through styling as background images, rather than with &amp;ldquo;img&amp;rdquo; tags. By default WinJS will hide background images set through styles when a high contrast theme is active. This default WinJS action is helpful, because if background images continued to appear behind text, that would interfere with the goal of making text clearer by maximizing the contrast between text and its background.&lt;/p&gt;
&lt;p&gt;But there may be times when you feel that your image might be of use to some of your customers when a high contrast theme is active, and you still want it to appear. All you need to do then is to set the following css to override the default behavior, and to have the background image appear.&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;-ms-high-contrast-adjust: none;&lt;/p&gt;
&lt;p&gt;If having done that, the image appears behind text when a high contrasts theme is active, you&amp;rsquo;ll want to move or size it as necessary to make sure it can&amp;rsquo;t appear behind text.&lt;/p&gt;
&lt;p&gt;Also, your app may ship with some fixed images which aren&amp;rsquo;t easy for some of your customers who use high contrast themes to make out. So for any fixed image you ship, you&amp;rsquo;ll want to ship a white-on-black version and black-on-white version which can be presented when a particular high contrast theme is active. The following css shows how you can do this.&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;@media screen and (-ms-high-contrast)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; .mypage #houseImage {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -ms-high-contrast-adjust: none;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; background: url(/images/houseimage.contrast-black.png);&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;@media screen and (-ms-high-contrast:black-on-white)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; .mypage #houseImage {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; background: url(/images/houseimage. contrast-white.png);&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;In fact, given that above I&amp;rsquo;ve used the WinJS image file naming convention for high contrast, I don&amp;rsquo;t even need to specify the files in the css there. Rather I can leave it to WinJS to select the appropriate file based on the active high contrast theme, and I only retain the css to say that I don&amp;rsquo;t want background images to be hidden by default.&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;@media screen and (-ms-high-contrast)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; .mypage #houseImage {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -ms-high-contrast-adjust: none;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;Having said that, when I tried this, I found that the image displayed was appropriate only for the theme that was active when I started up my app. So if I changed the active theme I had to restart my app. If the file name was specifically included in the css, (as shown earlier), then the image presented would change in my running app as the active theme changed.&lt;/p&gt;
&lt;h1&gt;Conveying information through colour alone&lt;/h1&gt;
&lt;p&gt;Many of your customers will be colour blind, and so it&amp;rsquo;s really important that information isn&amp;rsquo;t conveyed only through use of colour. The classic example of this is a shape which indicates that all is well by being green, and all is not well by being exactly the same shape, but red. That&amp;rsquo;s not going to help your customers who find it a challenge to differentiate red and green.&lt;/p&gt;
&lt;p&gt;So I took a look at my new app, and found that no information was conveyed through use of colour alone. As such, I didn&amp;rsquo;t need to add additional text, (either in the form of text that appears next to images or shapes, or as tooltips.)&lt;/p&gt;
&lt;h1&gt;Conveying information through audio alone&lt;/h1&gt;
&lt;p&gt;If your app presents some information through audio and no matching visuals change, then your deaf customers may miss out on something very important, such as an alarm. (Depending on how you output the audio, the system may help to get visuals shown.)&amp;nbsp; My new app outputs no audio at all, so this isn&amp;rsquo;t a concern for me here.&lt;/p&gt;
&lt;h1&gt;Make everything bigger&lt;/h1&gt;
&lt;p&gt;Now this Windows Ease of Access setting is another great feature for many customers. On devices with a resolution that supports the setting, everything in your app can be made bigger on the screen. While this helps a lot of people with low vision, (and many people who don&amp;rsquo;t consider themselves to have a disability &amp;ndash; but just find it more efficient to work with things that are bigger,) you don&amp;rsquo;t need to do anything specific to an accessibility setting for your app to support this. Rather, you just need to support all the resolutions that Windows Store apps should support. When your customers turn on the &amp;ldquo;Make everything on the screen bigger&amp;rdquo; setting, your app will just be presented at a particular resolution.&lt;/p&gt;
&lt;p&gt;Given that new apps created from the HTML Grid Template support the required resolutions, I didn&amp;rsquo;t need to change anything in my app related to this setting.&lt;/p&gt;
&lt;p&gt;Note that an HTML app does need to be restarted after the user has changed the state of the &amp;ldquo;Make everything on the screen bigger&amp;rdquo; setting. (If the app is not restarted, then the UI will not be sized correctly after the setting has been changed.)&lt;/p&gt;
&lt;h1&gt;Respecting system settings&lt;/h1&gt;
&lt;p&gt;There are a few additional system settings which you can leverage, and doing so can help you to provide a great user experience to some customers, where otherwise the app might be unusable. For example, respecting the duration for which notifications are to appear on the screen. Some of your customers need a certain amount of time in order to digest the contents of notifications that appear, and so if the notifications only appear for a few seconds, they might as well have not appeared at all.&lt;/p&gt;
&lt;p&gt;My new app presents no notifications, and so I won&amp;rsquo;t check this system setting. In fact I won&amp;rsquo;t be changing the app to leverage any other systems settings either.&lt;/p&gt;
&lt;h1&gt;Summary&lt;/h1&gt;
&lt;p&gt;So having considered all the above, what did I actually change in my new app to make the list as accessible as possible? There were only a few things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set a useful localized accessible name on the list. I did this by using the &amp;ldquo;aria-label&amp;rdquo; attribute. The Inspect SDK tool is invaluable for checking the UIA properties in your UI, and you can use it to make sure all of the UI that you add to your app exposes a localized accessible name.&lt;/li&gt;
&lt;li&gt;I gave some divs unique ids in order to expose useful UIA AutomationId properties which can be accessed by automated tests.&lt;/li&gt;
&lt;li&gt;Show a border around my list items when a high contrast theme is active, to make sure the items really stand out.&lt;/li&gt;
&lt;li&gt;Include high contrast versions of my shipping images, such that when the High Contrast Black and High Contrast White themes are active, the images are as clear as possible to all my customers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other things I considered while doing carrying out these investigations included:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can the Narrator user quickly determine whether a list item&amp;rsquo;s of interest when they navigate to it?&lt;/li&gt;
&lt;li&gt;Should a list item get focus when the app starts?&lt;/li&gt;
&lt;li&gt;If I use the background-image style on a div, what&amp;rsquo;s the best experience for the user when they&amp;rsquo;re using a high contrast theme? (Certainly I don&amp;rsquo;t want an image to appear behind text when a high contrast theme is active.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are lots of interesting topics when considering how you can make your app as accessible as possible, and so reach the most customers. The above investigation relates to a list shown in a new app based on the HTML Grid App template, but many of the things mentioned relate to UI in general.&lt;/p&gt;
&lt;p&gt;So try out your cool new Windows 8 apps using only the keyboard, in high contrast and with Narrator. It&amp;rsquo;s fascinating to consider how you can enhance your app to make it really efficient for all your customers to leverage its full functionality, regardless of how they interact with it!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10395585" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/_2600_quot_3B00_Windows+8_2600_quot_3B00_+WinJS+ListView+_2600_quot_3B00_UI+Automation_2600_quot_3B00_+UIA/">&amp;quot;Windows 8&amp;quot; WinJS ListView &amp;quot;UI Automation&amp;quot; UIA</category></item><item><title>One story of building a useful Assistive Technology tool from a UI Automation sample</title><link>http://blogs.msdn.com/b/winuiautomation/archive/2012/09/08/one-story-of-building-a-useful-assistive-technology-tool-from-a-ui-automation-sample.aspx</link><pubDate>Sat, 08 Sep 2012 17:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10347545</guid><dc:creator>Guy Barker MSFT</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/winuiautomation/rsscomments.aspx?WeblogPostID=10347545</wfw:commentRss><comments>http://blogs.msdn.com/b/winuiautomation/archive/2012/09/08/one-story-of-building-a-useful-assistive-technology-tool-from-a-ui-automation-sample.aspx#comments</comments><description>&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;Background&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;At the 2011 Annual International Technology and Persons with Disabilities Conference (aka &amp;ldquo;the CSUN conference&amp;rdquo;), I gave a presentation on the Windows UI Automation (UIA) API. This API allows apps to find out what things are shown visually on the screen and to programmatically interact with those things. As such, it can be very helpful to Assistive Technology (AT) tools such as screen readers.&lt;/p&gt;
&lt;p&gt;I was new to UIA at the time, and so needed to learn some things on how it&amp;rsquo;s used. The most effective way for me to learn about an API is to build an app which uses it, and to step through the code in a debugger watching what happens. I felt people at the conference would be more interested in the client-side aspects of the API rather than the provider-side. (The &amp;ldquo;client&amp;rdquo; is the app gathering up the data about what&amp;rsquo;s shown in other apps, and the &amp;ldquo;provider&amp;rdquo; is the app that contains the UI of interest.) So I built a &lt;a title="UIA Sample app" href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-9131f729"&gt;sample app&lt;/a&gt; which gathers details on all links shown in a browser and which can programmatically invoke those links. A twist to this sample which is unconnected to UIA is that I also added use of the Window Magnification API, and I&amp;rsquo;d not built an app which used both these API&amp;rsquo;s before. The UIA API and Magnification API are not related, and it was interesting for the sample to clearly separate the data gathering steps from the mechanism by which the results are presented to the user. Other apps might choose different ways to present the results depending on the needs of their users. For example, using speech, (as a screen reader does), or presenting the results using large text elsewhere on the screen, (if it helps with the user&amp;rsquo;s comprehension of what&amp;rsquo;s on the screen.)&lt;/p&gt;
&lt;p&gt;The picture below shows the sample app listing all the links shown in the browser, and highlighting one of the links.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/8741.OriginalSampleSmall.png"&gt;&lt;img border="0" alt="" src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/8741.OriginalSampleSmall.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;After presenting this sample app, (which I&amp;rsquo;d built in C++), I was asked if I had a C# version. So I set to work on an equivalent &lt;a title="UIA Sample C# app " href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-0625f55e"&gt;C# version of the sample&lt;/a&gt;. It&amp;rsquo;s worth noting that all my samples use the native-code version of the UIA API that&amp;rsquo;s included in Windows, not the managed version that&amp;rsquo;s included in the .NET Framework. Since then I&amp;rsquo;ve completed a set of sample apps which use the client-side UIA API, and together the samples demonstrate all the commonly used parts of the API. My goal has always been to build samples which might be the starting point for real-world AT tools. Interacting with hyperlinks in a browser is an extremely common action. &lt;a title="UIA Focus tracker sample app" href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-6390614a"&gt;Another sample&lt;/a&gt; uses UIA to track keyboard focus and magnifies the UI with focus. And a &lt;a title="UIA Text Pattern sample app" href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-9ce18fd5"&gt;third sample&lt;/a&gt; uses UIA&amp;rsquo;s &amp;ldquo;Text Pattern&amp;rdquo; to programmatically interact with e-mails. While none of the samples are feature-complete as AT apps, I had hoped that they would be a good base for people who want to build AT apps.&lt;/p&gt;
&lt;p&gt;Actually, one of the samples is pretty much complete &amp;ndash; &lt;a title="UIA Sample app Key Speaker" href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-433a961f"&gt;the Key Speaker&lt;/a&gt;. This uses UIA to find the text shown on the Prediction Keys in the On-Screen Keyboard. This satisfied a specific need that someone described to me and it was an important reminder that sometimes an AT tool doesn&amp;rsquo;t have to do much to be useful; it just has to do what&amp;rsquo;s needed. I&amp;rsquo;ve had a few thousand downloads of my samples, and so I&amp;rsquo;m pleased that they are proving to be a useful reference.&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;Deciding to build an AT app&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I was recently in contact with an AT consultant who has a client with no gross motor skills, but does have some fine motor skills. This got me thinking about users who can&amp;rsquo;t use a mouse but can move their fingers to press keys on the number pad on a keyboard. How might the user easily browse the web? (I&amp;rsquo;m thinking about browsing again, give that it&amp;rsquo;s such a common thing that people do.) So I then broke the potential actions down into three stages.&lt;/p&gt;
&lt;p&gt;1. Pressing a key to &amp;ldquo;highlight&amp;rdquo; things that can be clicked in the browser.&lt;/p&gt;
&lt;p&gt;2. Pressing keys to specify which thing is to be clicked.&lt;/p&gt;
&lt;p&gt;3. Pressing a key to do the click.&lt;/p&gt;
&lt;p&gt;So I thought I&amp;rsquo;d build an AT tool which does this. Given that my original sample already had classes for calling UIA and then highlighting results, it was natural that I&amp;rsquo;d use this sample as starting point for my new AT app. (In Windows 7, the UIA API has certain threading requirements which means that depending on what client apps do, they sometimes need to do a certain amount of thread-related work. That&amp;rsquo;s all standard thread stuff, but I don&amp;rsquo;t want to write that code from scratch again if I again avoid it.)&lt;/p&gt;
&lt;p&gt;I then grabbed my sample and got to work. I decided that I&amp;rsquo;d build an app which I knew would be useful but which would have some constraints. I&amp;rsquo;d look into addressing those constraints based on future user feedback. One constraint that would not change would be that the browser would have to be accessible through the UIA API. (Pointing the Inspect SDK tool to UI is a great way to get a feel for how accessible an app is.)&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;Getting things which can be clicked&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I concentrated on the UIA aspects of the app next, as that&amp;rsquo;s core to what I&amp;rsquo;m trying to achieve. The original sample has a file called LinkProcessor.cpp, and that&amp;rsquo;s that where all the UIA calls in the sample are made. So this is where all the UIA calls would be made in my new AT app. In the sample, all the calls are made on a background thread, and we can see a call to CoInitializeEx() being made with COINIT_MULTITHREADED. This is necessary if the app might interact with its own UI through UIA. In the case of my new app, this isn&amp;rsquo;t actually necessary, but there was no reason for me to change the threading code. Having the calls done on the background thread would work perfectly fine for my app, and if in the future I change the app such that it does interact with its own UI, it&amp;rsquo;ll continue to work fine.&lt;/p&gt;
&lt;p&gt;So I left all the threading-related code in, (including the mechanism for communication between threads), and then pulled out lots of action taken by the sample which I&amp;rsquo;m not interested in. This left me with one function of real interest; the one that gets me a list of elements on the screen. The sample built up a list of hyperlinks, and I now want a list of things that can be clicked. I decided to use UIA caching in my app in order to get the highest performance possible. (The original sample demonstrated both using caching and not using caching.) So this had now all boiled down to a single call to FindAllBuildCache().&lt;/p&gt;
&lt;p&gt;FindAllBuildCache() takes a condition which describes what elements are to be retrieved. I needed to figure out a condition which would get me all the elements that I&amp;rsquo;m interested in, and only them. By using the Inspect SDK tool I could examine the properties of hyperlinks shown in the browser, and I decided on the following conditions for the element I would retrieve:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1. They would appear in UIA&amp;rsquo;s Control view of the element tree. (This is a subset of the Raw view, and the Raw view contains lots of the elements that the user usually doesn&amp;rsquo;t care about.)&lt;/p&gt;
&lt;p&gt;2. The IsOffscreen property is false. If the IsOffscreen property if true, then the link isn&amp;rsquo;t visible on the screen.&lt;/p&gt;
&lt;p&gt;3. The IsEnabled property is true. If the IsEnabled property is false, the link can&amp;rsquo;t be clicked.&lt;/p&gt;
&lt;p&gt;4. The IsInvokePatternAvailable property is true.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This last condition is the most interesting one. In thinking about the condition, I decided that I&amp;rsquo;m not just interested in links. Rather, I want anything that can be clicked. This means my new AT app can be used to click buttons like the Back button.&lt;/p&gt;
&lt;p&gt;I then combined the conditions with a number of calls to CreateAndCondition() and passed that into the call to FindAllBuildCache(). I also passed in a cache request for the bounding rectangle and InvokePattern. This meant that by calling FindAllBuildCache(), a single cross-process call would be made to gather the bounding rectangles of potentially hundreds of elements which can be clicked. (Cross-process calls are slow and so I want to make as few of them as possible.)&lt;/p&gt;
&lt;p&gt;Having made this call, I did indeed get many elements returned, including links and buttons which could be clicked. However, I didn&amp;rsquo;t quite get all the things I expected. I found that the tabs shown in the browser weren&amp;rsquo;t included. So again I used Inspect and pointed it to the tabs. By doing this I could see that that tabs do not support the InvokePattern, and this explained why they were missing from the results returned from FindAllBuildCache(). Given that the tabs are so important to my app, I decided to change the condition I&amp;rsquo;d built to make sure the tabs were included in the result. Inspect showed me that the tabs support the LegacyIAccessible pattern. (IAccessible is related to the legacy MSAA API. That API has been replaced by the more powerful and performant UIA API.) Since the tabs do support that pattern and not the Invoke pattern, I decided to include that pattern in my condition. An element that supports the Invoke pattern will later be clicked by calling the Invoke() method on that interface, but if that pattern is not supported and LegacyIAccessible() is supported, then LegacyIAccessible&amp;rsquo;s DoDefaultAction() method would be used.&lt;/p&gt;
&lt;p&gt;The final code looked something like this:&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;hr = _pUIAutomation-&amp;gt;CreateCacheRequest(&amp;amp;pCacheRequest);&lt;br /&gt;if (SUCCEEDED(hr))&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = pCacheRequest-&amp;gt;AddProperty(UIA_BoundingRectanglePropertyId);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = pCacheRequest-&amp;gt;AddPattern(UIA_InvokePatternId);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = pCacheRequest-&amp;gt;AddPattern(UIA_LegacyIAccessiblePatternId);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;if (SUCCEEDED(hr))&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _pUIAutomation-&amp;gt;get_ControlViewCondition(&amp;amp;pConditionControlView);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VARIANT varPropOffScreen;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropOffScreen.vt = VT_BOOL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropOffScreen.boolVal = VARIANT_FALSE;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _pUIAutomation-&amp;gt;CreatePropertyCondition(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UIA_IsOffscreenPropertyId,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropOffScreen,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pConditionOffscreen);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VARIANT varPropIsEnabled;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropIsEnabled.vt = VT_BOOL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropIsEnabled.boolVal = VARIANT_TRUE;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _pUIAutomation-&amp;gt;CreatePropertyCondition(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UIA_IsEnabledPropertyId,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropIsEnabled,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pConditionIsEnabled);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VARIANT varPropHasInvokePattern;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropHasInvokePattern.vt = VT_BOOL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropHasInvokePattern.boolVal = VARIANT_TRUE;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _pUIAutomation-&amp;gt;CreatePropertyCondition(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UIA_IsInvokePatternAvailablePropertyId,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropHasInvokePattern, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pConditionHasInvokePattern);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VARIANT varPropHasLegacyIAccessiblePattern;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropHasLegacyIAccessiblePattern.vt = VT_BOOL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropHasLegacyIAccessiblePattern.boolVal = VARIANT_TRUE;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _pUIAutomation-&amp;gt;CreatePropertyCondition(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UIA_IsLegacyIAccessiblePatternAvailablePropertyId,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropHasLegacyIAccessiblePattern,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pConditionHasLegacyIAccessiblePattern);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _pUIAutomation-&amp;gt;CreateOrCondition(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pConditionHasInvokePattern,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pConditionHasLegacyIAccessiblePattern, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pConditionPatterns);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _pUIAutomation-&amp;gt;CreateAndCondition(pConditionControlView,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pConditionOffscreen, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pConditionCombined1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _pUIAutomation-&amp;gt;CreateAndCondition(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pConditionCombined1, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pConditionIsEnabled, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pConditionCombined2);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _pUIAutomation-&amp;gt;CreateAndCondition(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pConditionCombined2, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pConditionPatterns, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pCondition);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;if (SUCCEEDED(hr))&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = pElementWindow-&amp;gt;FindAllBuildCache(TreeScope_Descendants, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pCondition, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pCacheRequest,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pElementArray);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;The above code snippet doesn&amp;rsquo;t include the calls to release all the objects once they&amp;rsquo;re no longer needed.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;Hold on - where am I getting the clickable things from?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The above call to FindAllBuildCache() is being made from an IUIAutomationElement called pElementWindow, but what is that? My goal here is to get clickable things in a browser, but I thought it would also be interesting to get the clickable things in whatever the foreground window is. So the code for getting pElementWindow is:&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;HWND hWndForeground = GetForegroundWindow();&lt;br /&gt;if (hWndForeground != NULL)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationElement *pElementWindow = NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HRESULT hr = _pUIAutomation-&amp;gt;ElementFromHandle((UIA_HWND)hWndForeground,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pElementWindow);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr) &amp;amp;&amp;amp; (pElementWindow!= NULL))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Now get the clickable elements&amp;hellip;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In practice my AT app wasn&amp;rsquo;t able to click things in a number of apps, and I&amp;rsquo;ll look into fixing that at some point. Given that my main goal related to browser usage, and that worked fairly well, the above approach met my needs.&lt;/p&gt;
&lt;p&gt;One approach that I&amp;rsquo;d certainly not want to take would be to get the root element of the UIA tree and then call one of the Find* methods from that with TreeScope_Descendants in the hope of getting every clickable things on the screen. MSDN points out that calling Find* must not be done from the root element with TreeScope_Descendants.&lt;/p&gt;
&lt;p&gt;Another approach I&amp;rsquo;d not want to take is to call ElementFromPoint() to hit-test for every clickable thing on the screen. To feel confident that I&amp;rsquo;d not missed small elements, I&amp;rsquo;d need to make many thousands of calls to ElementFromPoint(). Given that each call would be cross-process, the performance would be grim.&lt;/p&gt;
&lt;p&gt;But I did think that if at some point my AT app would be useful for working in some apps outside of the browser, then in addition to helping the user work in the foreground app, it should also help in starting apps and switching between apps. In that case, the app would need to interact with the Taskbar. So in addition to working with the foreground window, the app also finds the Taskbar with the code below and then finds the clickable things that are shown on it.&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;IUIAutomationElement *pElementRoot = NULL;&lt;br /&gt;HRESULT hr = _pUIAutomation-&amp;gt;GetRootElement(&amp;amp;pElementRoot);&lt;br /&gt;if (SUCCEEDED(hr))&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; VARIANT varPropClassName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropClassName.vt = VT_BSTR;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropClassName.bstrVal = SysAllocString(L"Shell_TrayWnd");&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationCondition *pConditionClassName = NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _pUIAutomation-&amp;gt;CreatePropertyCondition(UIA_ClassNamePropertyId,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varPropClassName, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pConditionClassName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationElement *pElementTaskBar;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = pElementRoot-&amp;gt;FindFirst(TreeScope_Children, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pConditionClassName, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;pElementTaskBar);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr) &amp;amp;&amp;amp; (pElementTaskBar != NULL))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Now get the clickable elements&amp;hellip;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The above code finds the element with the accessible Name property of &amp;ldquo;Shell_TrayWnd&amp;rdquo; which is a direct child of the root element. It&amp;rsquo;s ok to call one of the Find* functions from the root element when TreeScope_Children is used. I used the Inspect SDK tool to look at the properties of the Taskbar in order to figure out a way to programmatically access it.&lt;/p&gt;
&lt;p&gt;It turned out that in practice the gathering the Taskbar buttons was only partially useful in my app as it stands today. The user can start apps by clicking a Taskbar button with my app and sometimes switch between apps, but there were situations where it didn&amp;rsquo;t work. I&amp;rsquo;ll look into this further if I get related feedback about it.&lt;/p&gt;
&lt;p&gt;So with the above code, my app had gathered a long list of elements which can be programmatically clicked in the browser. It keeps this list around, as the app will need to retrieve an element from the list later when the user wants to click it. The next step was to show these elements to the user.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;Highlighting the results&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The original UIA sample has a file called Highlight.cpp which is responsible for all the work to present results to the user. The sample did this by magnifying the element, but for my app I want to present something at the location of every clickable element. This will allow the user to specify that they want to click a particular element.&lt;/p&gt;
&lt;p&gt;So I decided to create a fullscreen window that would be completely transparent except for identifiers that would lie over the clickable elements. I pulled out all the magnification related code from the sample, and modified the existing code which creates a window such that it created the big window I needed.&lt;/p&gt;
&lt;p&gt;In the call to CreateWindowEx(), I passed the flags:&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE | WS_EX_TOPMOST&lt;/p&gt;
&lt;p&gt;I then called SetLayeredWindowAttributes() with LWA_COLORKEY and a colour that I thought would never be used as a system colour in practice. (I used system colours for the display of the element identifiers.)&lt;/p&gt;
&lt;p&gt;By doing the above, I had a fullscreen window that was transparent, and which would not react at all to mouse clicks in it. (When I say &amp;ldquo;fullscreen&amp;rdquo; here, a constraint I have in the app at the moment is that I&amp;rsquo;m not supporting multi-monitor. I&amp;rsquo;ll fix that if I get feedback about it.)&lt;/p&gt;
&lt;p&gt;Having created the window which will present the results to the user, I added a public method to the existing CHighlight object from the sample. This method allowed the object that gathered all the bounding rectangles of the things that can be clicked, to inform the CHighlight object where each identifier is to be displayed on the screen.&amp;nbsp; So CHighlight ends up with an array of points, and that&amp;rsquo;s all it needs. (CHighlight also now calls GetTextExtentPoint32() to take into account the size of the identifier to be displayed, and as such, center the identifier over the element.)&lt;/p&gt;
&lt;p&gt;Finally, whenever the window processes WM_PAINT, it draws the identifiers on the screen. It simply iterates through the array, building up strings as the identifiers based on the index in the point array. So the identifier for the first element in the array is &amp;ldquo; 1 &amp;rdquo;, the next is &amp;ldquo; 2 &amp;rdquo;, and so on.&lt;/p&gt;
&lt;p&gt;The picture below shows clickable elements in the browser.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/1157.App.png"&gt;&lt;img border="0" alt="" src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/1157.App.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For many people the highlighting shown will be usable, but I&amp;rsquo;m conscious of the fact that the person with the mobility impairments which prompted me to build this app, also has visual impairments. So another aspect of the app which I may be enhancing is to try to make the identifiers easier to see. I specifically used theme-based colours for the text colour and background colour, (through calls to GetSysColor() with COLOR_WINDOWTEXT and COLOR_WINDOW), but the identifiers are still very small and often overlap.&lt;/p&gt;
&lt;p&gt;The picture below shows the identifiers when the High Contrast #1 theme has been selected in the Personalization Control Panel.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/1638.AppHighContrast.png"&gt;&lt;img border="0" alt="" src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/1638.AppHighContrast.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;Clicking something&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The last step in all this is providing some way for the user to click the thing that&amp;rsquo;s highlighted. Different users might prefer different ways of doing this, (for example, typing a number and then automatically having the element clicked after say a couple of seconds). But I went with the following approach:&lt;/p&gt;
&lt;p&gt;1. Press the ` key near the top left of the English keyboard to turn the identifier display on or off.&lt;/p&gt;
&lt;p&gt;2. Type the identifying number of the thing you want to click.&lt;/p&gt;
&lt;p&gt;3. Press the Escape key to click it.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;An important question here is, why choose the ` and Escape keys? I did this deliberately to make it as fast as possible for someone using the Windows 7 On-Screen Keyboard (OSK) in its Scan mode. The OSK&amp;rsquo;s Scan mode allows someone to control the keyboard with a hardware switch. So if someone has severe mobility impairments and uses either a foot switch or head switch to interact with the computer, my new app is optimized to make it quick for those users to type the keys they need to. The picture below shows the OSK in Scan mode:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/7080.OSK.png"&gt;&lt;img border="0" alt="" src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/7080.OSK.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I realize the keys I&amp;rsquo;ve chosen will be far from ideal for some people. For example, a user might prefer to be able to use the number pad on a physical keyboard, such that with only small movements of their fingers, they can click things in the browser. If I get feedback asking for the app to be enhanced to allow the user to configure which keys are used, I&amp;rsquo;ll do that.&lt;/p&gt;
&lt;p&gt;The original sample had no code for detecting key presses in the way my app needed to, so I added a low-level keyboard hook through a call to SetWindowsHookEx(). The hook detects VK_OEM_3 to turn the identifier display on and off in response to a press of the ` key. (I&amp;rsquo;ve only used my app with an English keyboard, and so might have to update the hook for non-English keyboards.) In response to key presses of &amp;lsquo;0&amp;rsquo;-&amp;lsquo;9&amp;rsquo; while the identifiers are on, the app builds up a string to cache the full number typed. Then in response to a press of the VK_ESCAPE key while identifiers are on, the app performs the clicking of the element. Whenever it does take action in response to the key press, the app blocks the system from also processing the key press. If it did not do this, then the number that the user&amp;rsquo;s typing to specify an identifier would also appear in whatever control currently has keyboard focus. (And I realize that doing the above, I&amp;rsquo;m assuming that the user never wants to type a ` character into any app.)&lt;/p&gt;
&lt;p&gt;When a click is made, the app uses the number typed to figure out which element is of interest. It still has the long list of elements that it originally gathered through UIA, and so it can retrieve the element of interest. That is, if the user typed &amp;ldquo;1&amp;rdquo;, then the app will use the first element found earlier.&lt;/p&gt;
&lt;p&gt;The code below performs what the user considers to be the click on the element.&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;IUIAutomationInvokePattern *pPattern = NULL;&lt;br /&gt;IUIAutomationLegacyIAccessiblePattern *pPatternLegacyIAccessible = NULL;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;hr = pElement-&amp;gt;GetCachedPatternAs(UIA_InvokePatternId, IID_PPV_ARGS(&amp;amp;pPattern));&lt;br /&gt;if (SUCCEEDED(hr))&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pPattern != NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = pPattern-&amp;gt;Invoke();&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pPattern-&amp;gt;Release();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pPattern = NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = pElement-&amp;gt;GetCachedPatternAs(UIA_LegacyIAccessiblePatternId,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IID_PPV_ARGS(&amp;amp;pPatternLegacyIAccessible));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr) &amp;amp;&amp;amp; (pPatternLegacyIAccessible != NULL))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = pPatternLegacyIAccessible-&amp;gt;DoDefaultAction();&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pPatternLegacyIAccessible-&amp;gt;Release();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pPatternLegacyIAccessible = NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;The calls to GetCachedPatternAs() above do not result in cross-process calls, because I explicitly asked for information about these patterns to be cached in the call to FindAllBuildCache(). The calls to Invoke() or&amp;nbsp; DoDefaultAction() will result in cross-process calls, as this is where the app tells the browser to have the element perform some action. If the original element no longer exists by the time these calls are made, then the calls will return UIA_E_ELEMENTNOTAVAILABLE.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;And that&amp;rsquo;s it&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Having built the working app, I did pull out some more parts of the sample which I didn&amp;rsquo;t need. This included all the code related to UIA event handling. Looking at the final code, the amount of code which I&amp;rsquo;d had to add myself in order to build my app was fairly small, so I was pleased about that. The componentization of the original sample into parts for (i) the main app UI, (ii) the code which calls UIA, and (iii) the code which highlights the results worked well for me.&lt;/p&gt;
&lt;p&gt;So in a few hours over a weekend, I&amp;rsquo;d built a functioning app which can help someone with very limited mobility to browse the web. I&amp;rsquo;ve made the app freely available at my own AT site, and documented the current constraints of the app there. I&amp;rsquo;ll enhance it as I get feedback from people who want to use it.&lt;/p&gt;
&lt;p&gt;If you know of someone who could benefit from an app which helps them interact with things that are shown on the screen, perhaps one of my UI Automation samples could help you build it for them.&lt;/p&gt;
&lt;p&gt;Guy&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10347545" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Microsoft+Windows+Automation+API/">Microsoft Windows Automation API</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Screen+Readers/">Screen Readers</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Samples/">Samples</category></item><item><title>Using Dynamic Annotation with Child IDs</title><link>http://blogs.msdn.com/b/winuiautomation/archive/2012/04/25/using-dynamic-annotation-with-child-ids.aspx</link><pubDate>Wed, 25 Apr 2012 04:50:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10297449</guid><dc:creator>Michael Bernstein</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/winuiautomation/rsscomments.aspx?WeblogPostID=10297449</wfw:commentRss><comments>http://blogs.msdn.com/b/winuiautomation/archive/2012/04/25/using-dynamic-annotation-with-child-ids.aspx#comments</comments><description>&lt;p&gt;The Dynamic Annotation API in the Windows Automation API is a convenient way to make simple accessibility changes to the accessible properties of Win32 Common Controls without writing a lot of code. There is good &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd318060(v=vs.85).aspx"&gt;reference documentation available on MSDN&lt;/a&gt;, and &lt;a href="http://msdn.microsoft.com/en-us/windows/cc307286"&gt;some samples, too&lt;/a&gt;. That said, I’ve received some questions about it and wanted to talk specifically about how it works with Child IDs.&lt;/p&gt;  &lt;h3&gt;A quick refresher&lt;/h3&gt;  &lt;p&gt;The basic usage model for Dynamic Annotation is simple. Suppose I have a static control in my application with an image on it instead of a text label, and I need to set the accessible name to be “Picture of a thermometer” in order to allow a screen reader to read the control correctly. No problem: my app uses CoCreateInstance() to create an AccPropServices object, and calls IAccPropServices::SetHwndPropStr() to annotate the name property (PROPID_ACC_NAME):&lt;/p&gt;&amp;#160;&amp;#160; &lt;div&gt;   &lt;blockquote&gt;     &lt;div style="color: black; background-color: white;"&gt;       &lt;pre&gt;HWND hwndIcon = GetDlgItem(hwnd, IDC_ICON1); &lt;br /&gt;CHECKHR(pAccPropSvc-&amp;gt;SetHwndPropStr(hwndIcon, &lt;span style="color: blue;"&gt;static_cast&lt;/span&gt;&amp;lt;DWORD&amp;gt;(OBJID_CLIENT), CHILDID_SELF, &lt;br /&gt;    PROPID_ACC_NAME, L&lt;span style="color: rgb(163, 21, 21);"&gt;&amp;quot;Picture of a thermometer&amp;quot;&lt;/span&gt;)); 
      &lt;/pre&gt;
    &lt;/div&gt;
  &lt;/blockquote&gt;
In this code snippet, CHECKHR is just a macro that I’m using to log any errors that occur.&amp;#160; A real application would use an error handling strategy consistent with what it was using for the rest of the codebase.&lt;/div&gt;

&lt;p&gt;I make sure to call IAccPropServices::ClearHwndProps() afterwards to clear off the property:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;div style="color: black; background-color: white;"&gt;
    &lt;pre&gt;HWND hwndIcon = GetDlgItem(hwnd, IDC_ICON1); 
MSAAPROPID propids[1] = { PROPID_ACC_NAME }; 
CHECKHR(hr = pAccPropSvc-&amp;gt;ClearHwndProps(hwndIcon, &lt;span style="color: blue;"&gt;static_cast&lt;/span&gt;&amp;lt;DWORD&amp;gt;(OBJID_CLIENT), CHILDID_SELF, &lt;br /&gt;    propids, 1));
    &lt;/pre&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;The samples I mentioned above cover this well.&lt;/p&gt;

&lt;p&gt;One new extension, added in Windows 7, is that I can now annotate with UIA properties. The property IDs for UIA properties are all in UIAutomationCoreApi.h (in the Platform SDK). So, if I want to set new UIA properties like AutomationId or ItemStatus, I’ve got a good way to do that:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;div style="color: black; background-color: white;"&gt;
    &lt;pre&gt;CHECKHR(pAccPropSvc-&amp;gt;SetHwndPropStr(hwndIcon, &lt;span style="color: blue;"&gt;static_cast&lt;/span&gt;&amp;lt;DWORD&amp;gt;(OBJID_CLIENT), CHILDID_SELF, &lt;br /&gt;    &lt;font style="background-color: rgb(255, 255, 0);"&gt;AutomationId_Property_GUID&lt;/font&gt;, L&lt;span style="color: rgb(163, 21, 21);"&gt;&amp;quot;ThermometerAutomationId&amp;quot;&lt;/span&gt;));
 

    &lt;/pre&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;How do I see if this is working?&amp;#160; I can use the Inspect tool, available in the Windows SDK, to inspect the properties on my annotated object and verify that the new properties are showing up.&lt;/p&gt;&amp;#160;&amp;#160;&amp;#160; &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09-metablogapi/8625.image_5F00_7967AFBA.png"&gt;&lt;img title="image" style="margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09-metablogapi/2018.image_5F00_thumb_5F00_5155009B.png" width="382" height="365" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Annotating child items&lt;/h3&gt;

&lt;p&gt;Suppose my application uses a standard menu (CreateMenu()) and I want to add some special accessibility properties to menu items. This is a little different than our button example: we don’t want to annotate the whole menu, but rather one of its children. Well, I can do that, too – I just use IAccPropServices::SetHmenuPropStr() and IAccPropServices::ClearHmenuProps(). They both take a child ID argument, which specifics &lt;i&gt;which &lt;/i&gt;menu item to annotate. The Inspect tool can show you the child ID of the menu item. If you are just annotating one or two menu items, this is a good approach. This technique works on toolbars as well.&amp;#160; In this code snippet, the child ID is 1.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;div style="color: black; background-color: white;"&gt;
    &lt;pre&gt;&lt;span style="color: green;"&gt;// Annotate the menu item with a string... &lt;/span&gt;
CHECKHR(pAccPropSvc-&amp;gt;SetHmenuPropStr(g_hMenuBar, 1, PROPID_ACC_NAME, L&lt;span style="color: rgb(163, 21, 21);"&gt;&amp;quot;NewText&amp;quot;&lt;/span&gt;));
    &lt;/pre&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, It often happens that you want to annotate the properties of &lt;em&gt;all &lt;/em&gt;of the children of a container in a certain way.&amp;#160; For example, suppose I have an owner-drawn menu and I want to set the accessible names for all of the items in the menu, even though the menu items don’t officially have any textual content.&amp;#160; Calling SetHmenuPropStr() for every child ID would be tedious and inflexible – if the menu structure changes, I have to remove all the annotations and reset them.&amp;#160; A better solution would be to use a callback function that can be called with a child ID to request the accessible name (or another property) for that child ID.&amp;#160; &lt;a href="http://msdn.microsoft.com/en-us/windows/cc307286"&gt;The MSDN sample for Dynamic Annotation&lt;/a&gt; demonstrates this in a formal way; the core idea is to create an object that implements IAccPropServer and use dynamic annotation to mark the HWND or HMENU with the &lt;em&gt;IAccPropServer, &lt;/em&gt;rather than with a string.&lt;/p&gt;

&lt;p&gt;The annotation looks very much as it did before:&lt;/p&gt;

&lt;div style="color: black; background-color: white;"&gt;
  &lt;pre&gt;    AutoRelease&amp;lt;MenuAccServer *&amp;gt; pMenuAccSrv = &lt;span style="color: blue;"&gt;new&lt;/span&gt; MenuAccServer(pAccPropSvc);
    MSAAPROPID propid = PROPID_ACC_NAME;
    CHECKHR(pAccPropSvc-&amp;gt;SetHmenuPropServer(g_hPopup, CHILDID_SELF, &amp;amp;propid, 1, pMenuAccSrv, ANNO_CONTAINER));

  &lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The essential function in MenuAccServer looks like this:&lt;/p&gt;

&lt;div style="color: black; background-color: white;"&gt;
  &lt;pre&gt;    BOOL GetPropValue(
        &lt;span style="color: blue;"&gt;const&lt;/span&gt; BYTE *    pIDString,
        DWORD           dwIDStringLen,
        MSAAPROPID      idProp,
        VARIANT *       pvarValue)
    {
        HMENU hmenu = NULL;;
        DWORD idChild = 0;
        BOOL fSuccess = TRUE;

        &lt;span style="color: green;"&gt;// Break down the identity string into components and check the idChild&lt;/span&gt;
        &lt;span style="color: blue;"&gt;if&lt;/span&gt;(S_OK != _pAccPropSvc-&amp;gt;DecomposeHmenuIdentityString(pIDString, dwIDStringLen,
                    &amp;amp;hmenu, &amp;amp;idChild) ||
            idChild == CHILDID_SELF)
        {
            fSuccess = FALSE;
        }

        &lt;span style="color: green;"&gt;// Respond to requests for PROPID_ACC_NAME with the override&lt;/span&gt;
        &lt;span style="color: green;"&gt;// accessible name&lt;/span&gt;
        &lt;span style="color: blue;"&gt;if&lt;/span&gt; (fSuccess)
        {
            &lt;span style="color: blue;"&gt;if&lt;/span&gt; (idProp == PROPID_ACC_NAME)
            {
                &lt;span style="color: blue;"&gt;if&lt;/span&gt; ((idChild - 1) &amp;lt; ARRAYSIZE(g_ColorInfo))
                {
                    pvarValue-&amp;gt;vt = VT_BSTR;
                    pvarValue-&amp;gt;bstrVal = SysAllocString(g_ColorInfo[ idChild - 1 ]._pName);
                }
                &lt;span style="color: blue;"&gt;else&lt;/span&gt;
                {
                    fSuccess = FALSE;
                }
            }
            &lt;span style="color: blue;"&gt;else&lt;/span&gt;
            {
                fSuccess = FALSE;
            }
        }

        &lt;span style="color: blue;"&gt;return&lt;/span&gt; fSuccess;
    }
  &lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And with that, I can mark up all of the children of the HMENU &lt;em&gt;differently &lt;/em&gt;depending on their child IDs.&amp;#160; Very convenient.&lt;/p&gt;

&lt;p&gt;Don’t forget to clear the annotation when the HWND or HMENU is destroyed – leaving stale annotations around is a good way to cause memory leaks or crashes during shutdown.&lt;/p&gt;

&lt;div style="color: black; background-color: white;"&gt;
  &lt;pre&gt;       propid = PROPID_ACC_NAME;
       CHECKHR(pAccPropSvc-&amp;gt;ClearHmenuProps(g_hPopup, CHILDID_SELF, &amp;amp;propid, 1));
  &lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So, if you have an accessibility problem with a common control with children, now you know a useful technique to add or override accessibility properties on the control.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10297449" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Microsoft+Windows+Automation+API/">Microsoft Windows Automation API</category><category domain="http://blogs.msdn.com/b/winuiautomation/archive/tags/Dynamic+Annotation/">Dynamic Annotation</category></item><item><title>Windows 7 UI Automation Client API C# sample (e-mail reader) Version 1.1</title><link>http://blogs.msdn.com/b/winuiautomation/archive/2012/03/18/windows-7-ui-automation-client-api-c-sample-e-mail-reader-version-1-1.aspx</link><pubDate>Sun, 18 Mar 2012 00:09:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10284670</guid><dc:creator>Guy Barker MSFT</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/winuiautomation/rsscomments.aspx?WeblogPostID=10284670</wfw:commentRss><comments>http://blogs.msdn.com/b/winuiautomation/archive/2012/03/18/windows-7-ui-automation-client-api-c-sample-e-mail-reader-version-1-1.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/8206.UIA_5F00_Mail_5F00_Reader1.png"&gt;&lt;img border="0" alt="" src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/8206.UIA_5F00_Mail_5F00_Reader1.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I recently built a very simple C# app which uses the Windows 7 native-code UI Automation (UIA) API to gather text from a Windows Live Mail window, as part of having that text spoken. Sometimes having the text spoken can make text in a mail being read easier to understand, or to detect issues with mail being composed. The app used the UIA TextPattern to gather the text, but did so with a single call to collect all the text in the mail. The app might be useful as it is in some situations, but I've just updated it to leverage some more of the TextPattern and TextRange features.&lt;/p&gt;
&lt;p&gt;As it happens, with UIA's TextPattern and TextRange, you can still do a lot more to manipulate and traverse text that my updated app does, but the updated sample introduces the use of methods such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GetBoundingRectangles() - Get all the bounding rectangles for the text in a range.&lt;/li&gt;
&lt;li&gt;GetSelection() - Get only the text that's selected in the mail.&lt;/li&gt;
&lt;li&gt;Move() - Move an entire range forward or background by some unit, (for example, one paragraph).&lt;/li&gt;
&lt;li&gt;MoveEndpointByRange() - Move one end of a range to be equal to the start or end of another range (or even the same range.)&lt;/li&gt;
&lt;li&gt;MoveEndpointByUnit() - Move one end of a range by some amount, (for example, by one paragraph).&lt;/li&gt;
&lt;li&gt;ScrollIntoView() - Tell the provider app to scroll its view, such that text is actually visible on the screen.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The full set of functionality for TextPattern and TextRange is available at &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ee696214(v=vs.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/desktop/ee696214(v=vs.85).aspx&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ee696221(v=vs.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/desktop/ee696221(v=vs.85).aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The comments in the sample app show why and how the above calls are made. I should say that I've not done a great deal of testing with this app, but I'm sure the UIA related code is working great, which is what the sample's really all about. It's worth pointing out that when working with TextPattern and TextRange, your client app can only use what the provider app supports. If the provider has chosen to only partially implement TextPattern, then there's nothing you or UIA can do to add the missing functionality. Rather, you make the best of what the provider does support.&lt;/p&gt;
&lt;p&gt;This is what you can do with the app once you&amp;rsquo;ve opened a Windows Live Mail window to read or compose a mail&amp;hellip;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To read the whole mail, just hit the Play button.&lt;/li&gt;
&lt;li&gt;Whenever text is being spoken, pressing the Stop button will restore the app to its initial state.&lt;/li&gt;
&lt;li&gt;Whenever text is being spoken, pressing the Play button again will stop the speech in such a way that pressing Play again will start speaking the same text again.&lt;/li&gt;
&lt;li&gt;To start reading from the current selection, (or where the caret is), check the "Start reading the mail from the selection" radio button, and press the Play button.&lt;/li&gt;
&lt;li&gt;To have some visual highlight of the paragraph being read, check the "Highlight the text being read paragraph by paragraph" checkbox. For this sample app, I reused a magnification class I created for another sample, but you could choose to highlight the text in some other way. (The sample app assumes the Windows Live Mail window is not obscured by anything, and the magnified text fits on the screen. I've not looked into a black flash that can sometimes appear in the magnification lens when the magnification is refreshed.)&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;ve checked the "Highlight the text being read paragraph by paragraph" checkbox, then when the text is being read, you can jump to the next or previous paragraph by clicking the Next and Previous button respectively.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/8524.UIA_5F00_Mail_5F00_Reader2.png"&gt;&lt;img border="0" alt="" src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/8524.UIA_5F00_Mail_5F00_Reader2.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So while I've only leveraged a subset of what the TextPattern and TextRange can do, the updated app still can do some very useful things.&lt;/p&gt;
&lt;p&gt;The updated sample's out at &lt;a href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-9ce18fd5"&gt;http://code.msdn.microsoft.com/Windows-7-UI-Automation-9ce18fd5&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally - if you happen to know of someone who might find the sample app a useful tool in practice for working with e-mail, but it needs a few tweaks before it'll really work well for them, let me know. I'd be happy to try to help you use UIA to extend the functionality further in order to turn the app into a working tool for someone.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Guy&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10284670" width="1" height="1"&gt;</description></item><item><title>Windows 7 UI Automation Client API C# sample (e-mail reader) Version 1.0</title><link>http://blogs.msdn.com/b/winuiautomation/archive/2012/03/06/windows-7-ui-automation-client-api-c-sample-e-mail-reader-version-1-0.aspx</link><pubDate>Tue, 06 Mar 2012 02:36:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10278143</guid><dc:creator>Guy Barker MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/winuiautomation/rsscomments.aspx?WeblogPostID=10278143</wfw:commentRss><comments>http://blogs.msdn.com/b/winuiautomation/archive/2012/03/06/windows-7-ui-automation-client-api-c-sample-e-mail-reader-version-1-0.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/5342.MailReader.jpg"&gt;&lt;img border="0" alt="" src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-24-09/5342.MailReader.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In preparation for a demo of the native-code Windows UI Automation (UIA) API last year, I built a sample app which introduces most of the commonly used features of UIA. This included the following topics; properties, events, patterns, cache requests and conditions. The original C++ sample is up at &lt;a href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-9131f729"&gt;http://code.msdn.microsoft.com/Windows-7-UI-Automation-9131f729&lt;/a&gt;, and a version I ported to C# is at &lt;a href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-0625f55e"&gt;http://code.msdn.microsoft.com/Windows-7-UI-Automation-0625f55e&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Probably the most interesting functionality that&amp;rsquo;s not mentioned in that sample relates to the Text Pattern. If a UIA provider supports the Text Pattern, then a client can perform a number of operations to move through the text shown in the provider and to access that text. For example, the client can move through the text, examining the text character-by-character, word-by-word, line-by-line or paragraph-by-paragraph. Details of the Text Pattern are up at &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ee815688(v=vs.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/desktop/ee815688(v=vs.85).aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So I thought it would be interesting to build a new sample that uses the Text Pattern. As I considered this, I wondered whether I could build a very simple app which hardly does anything, but could still be a useful assistive technology (AT) tool in practice. While UIA is great for enabling UI automated tests, the API is also designed to support people building AT, and so I&amp;rsquo;m always very excited to build tools which relate to a real-world AT scenarios. (For example, building the tool to speak the text shown on the OSK prediction keys, &lt;a href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-433a961f"&gt;http://code.msdn.microsoft.com/Windows-7-UI-Automation-433a961f&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;With this in mind, I decided that a future sample would demo some of the more powerful aspects of the Text Pattern, but my next sample would do the absolute minimum required to have the Text Pattern support a useful tool. What I settled on was an app to read e-mail text. Some people find it easier to comprehend an e-mail message if the text is spoken to them as they read it. And sometimes when important e-mail is being composed, if it&amp;rsquo;s spoken prior to being sent, that can help to detect issues with the text which aren&amp;rsquo;t caught by running a spell checker alone. So the new sample app should read both received e-mail and e-mail being composed.&lt;/p&gt;
&lt;p&gt;I decided to build the app in C# and my first step was to copy one of my existing C# samples, &lt;a href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-6390614a"&gt;http://code.msdn.microsoft.com/Windows-7-UI-Automation-6390614a&lt;/a&gt;. I then removed a few existing things which weren&amp;rsquo;t relevant to the new app, (for example the UIA event handler, and use of the Magnification API.) One handy aspect about my new app was that I didn&amp;rsquo;t have to account for the UIA threading rules. That is, if an app uses UIA to access its own UI, or it has UIA event handlers, then certain things must be done on background threads, (as described in my other samples). But since the new app doesn&amp;rsquo;t do any of that, it keeps things really simple.&lt;/p&gt;
&lt;p&gt;I then updated the .cs file for the main app WinForm UI. There&amp;rsquo;s little work done here other than to use a SpeechSynthesizer to speak the text using the current default voice on the computer, and also to change the visuals for a button to start or stop the speaking of the text.&lt;/p&gt;
&lt;p&gt;The more interesting .cs file is the one that actually uses UIA. It initializes and uninitializes an IUIAutomation object, (as any UIA client app does), and then has a single function to access the e-mail text. That function looks like this:&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;// Try to find a Windows Live Mail window for composing and reading e-mails.&lt;br /&gt;// Using the Spy tool, the class of the main window can be found. This test&lt;br /&gt;// app assumes there's only one Windows Live Mail window of interest.&lt;br /&gt;IntPtr hwnd = Win32.FindWindow("ATH_Note", null);&lt;br /&gt;if (hwnd != IntPtr.Zero)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // We found a window, so get the UIA element associated with the window.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationElement elementMailAppWindow = _automation.ElementFromHandle(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hwnd);&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Find an element somewhere beneath the main window element in the UIA &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // tree which represents the main area where the e-mail content is shown. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Using the Inspect SDK tool, we can see that the main e-mail content &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // is contained within an element whose accessible name is "NoteWindow". &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // So create a condition such that the FindFirst() call below will only &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // return an element if its name is "NoteWindow".&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationCondition conditionNote = _automation.CreatePropertyCondition(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _propertyIdName, "NoteWindow");&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationElement elementNoteWindow = elementMailAppWindow.FindFirst(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TreeScope.TreeScope_Descendants, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; conditionNote);&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // As it happens, the actual element that supports the Text Pattern is &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // somewhere beneath the "NoteWindow" element in the UIA tree. Using &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Inspect we can see that there is an element that supports the &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Text Pattern. Once we have that element, we can avoid a cross-process &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // call to access the Text Pattern object by using cache request.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationCacheRequest cacheRequest = _automation.CreateCacheRequest();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cacheRequest.AddPattern(_patternIdTextPattern);&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Now find the element that supports the Text Pattern. This test app assumes&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // there&amp;rsquo;s only one element that can be returned which supports the Text Pattern.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool fTextPatternSupported = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationCondition conditionTextPattern = _automation.CreatePropertyCondition(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _propertyIdIsTextPatternAvailable, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fTextPatternSupported);&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationElement elementMailContent = elementMailAppWindow.FindFirstBuildCache(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TreeScope.TreeScope_Descendants, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; conditionTextPattern, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cacheRequest);&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Because the Text Pattern object is cached, we don't have to make a cross-process &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // call here to get object. Later calls which actually use methods and properties &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // on the Text Pattern object will incur cross-proc calls.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationTextPattern textPattern = (IUIAutomationTextPattern)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; elementMailContent.GetCachedPattern(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _patternIdTextPattern);&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // This test app is only interested in getting all the e-mail text, so we get that through &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // the DocumentRange property. A more fully featured app might be interested in getting a&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // a collection of Text Ranges from the e-mail. Each range might relate to an individual&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // word or paragraph. Given that a provider which supports the Text Pattern allows a &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // client to find the bounding rectangles of these ranges, the client could choose to use &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // its own method of highlighting the text as the text is being spoken.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IUIAutomationTextRange rangeDocument = textPattern.DocumentRange;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Pass -1 here because we're not interested in limiting the amount of text here.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strMailContent = rangeDocument.GetText(-1); &lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This app specifically only works with Windows Live Mail, but with a small adjustment the code above could target other window-based e-mail apps.&lt;/p&gt;
&lt;p&gt;As Text Pattern samples go, this isn&amp;rsquo;t very interesting as all it does is access the text for the entire document as a single string, (through the DocumentRange property.) But I did find this an exciting experiment. In around an hour and a half I built a UIA app which contains very little code, but which could still be a useful AT tool for some people. My next step is to figure out which other parts of the Text Pattern and Text Range interfaces would help most in practice for an e-mail related AT like this, and to update the sample accordingly. For example, the AT tool might get call IUIAutomationTextRange::Move() to access each line in turn, and call GetBoundingRectangles() and render its own highlighting for the line being spoken. The app could also call IUIAutomationTextPattern::GetVisibleRanges() to make sure it only gathers text that&amp;rsquo;s shown on the screen when working with e-mail clients that handle hidden text.&lt;/p&gt;
&lt;p&gt;The e-mail reading sample app is out at &lt;a href="http://code.msdn.microsoft.com/Windows-7-UI-Automation-28b2b537"&gt;http://code.msdn.microsoft.com/Windows-7-UI-Automation-28b2b537&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10278143" width="1" height="1"&gt;</description></item><item><title>UI Automation Featured on Win8 Blog</title><link>http://blogs.msdn.com/b/winuiautomation/archive/2012/02/16/ui-automation-featured-on-win8-blog.aspx</link><pubDate>Thu, 16 Feb 2012 16:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10268657</guid><dc:creator>Michael Bernstein</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/winuiautomation/rsscomments.aspx?WeblogPostID=10268657</wfw:commentRss><comments>http://blogs.msdn.com/b/winuiautomation/archive/2012/02/16/ui-automation-featured-on-win8-blog.aspx#comments</comments><description>&lt;p&gt;You may have wondered why this blog has gone quiet.&amp;nbsp; The UIA team has been very busy with Windows 8.&amp;nbsp; We're excited to link to a new blog post on the &lt;a title="Building Windows 8 blog" href="http://blogs.msdn.com/b/b8/"&gt;Building Windows 8 blog&lt;/a&gt;&amp;nbsp;that goes into depth on&amp;nbsp;Windows 8 Accessibility as&amp;nbsp;a whole:&lt;/p&gt;
&lt;p&gt;&lt;a title="Enabling Accessibility" href="http://blogs.msdn.com/b/b8/archive/2012/02/14/enabling-accessibility.aspx"&gt;Enabling Accessibility&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That post can give you a sense of what we've been up to.&amp;nbsp; While you're at it, you may also want to check out this fine talk by blog contributor Guy Barker from the //BUILD/ conference, about how to build accessible Metro style applications for Windows 8:&lt;/p&gt;
&lt;p&gt;&lt;a title="Reaching more customers with accessible Metro style apps in HTML5" href="http://channel9.msdn.com/Events/BUILD/BUILD2011/APP-843T"&gt;Reaching more customers with accessible Metro style apps in HTML5&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the meantime, if you have pressing questions, be sure to visit &lt;a title="our MSDN forum for Accessibility" href="http://social.msdn.microsoft.com/forums/en-US/windowsaccessibilityandautomation/threads"&gt;our MSDN forum for Accessibility&lt;/a&gt; and ask us there.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- Michael&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10268657" width="1" height="1"&gt;</description></item></channel></rss>
