Content by Category
.NET 1.x
.NET 2.0
.NET 3.0
.NET 3.5
.NET 4.0
.NET 4.5
.NET Assemblies
.NET Framework
.NET Getting Started
Accessibility
ADO.NET
Advertorials
Agile Development
AJAX
Amazon Web Services
Analysis Services
Android
Architecture
Arduino
ASP .NET Web API
ASP.NET
ASP.NET MVC
ASP.NET WebForms
Azure
B2B (Business Integration)
BDD
Big Data
Bing
BizTalk
Book Excerpts
Build and Deploy
Business Intelligence
C#
C++
ClickOnce
Cloud Computing
Code Contracts
CODE Framework Info - non Technical
CODE on the Road!
COM+
Community
Conferences
Continuous Integration
Crystal Reports
CSLA.NET
CSS
Data
Debugger
Design Patterns
Development Process
Display Technologies
Distributed Computing
Document Database
DotNetNuke
DSL
Dynamic Languages
Dynamic Programming
Editorials
Enterprise Services ("COM+")
Entity Framework
Events
Expression Blend
F#
Fox to Fox
Frameworks
Functional Programming
Git
Graphics
HTML 5
Internet Explorer 8.0
Interviews
IOS
iPhone
Iron Ruby
Java
Java Script
JavaScript
jQuery
JSON
Lightswitch
LINQ
Linux
LUA
Mac OS X
MDX
Messaging
Metro
Microsoft Application Blocks
Microsoft Business Rules Framework
Microsoft Dynamics
Microsoft Expression
Microsoft Office
Mobile Development
Mobile PC
Mono
MsBuild
MVVM
MySQL
Network
NHibernate
node.js
NOSQL
Nuget
Object Oriented Development
Objective C
Odata
OLAP
Open Source
Opinion
Opinions
Oracle
ORM
Other Languages
Parallel Programming
Patterns
PHP
Podcasts
Post Mortem
PowerPoint
Print/Output
Prism
Product News
Product Reviews
Project Management
Prolog
Python
Q&A
Rails
Rake
Razor
Reporting Services
REST
RIA Services
Ruby
Ruby on Rails
Scheme
Search
Security
Services
SharePoint
SignalR
Silverlight
SOA
Social Networks
Software & Law
Software Business
Source Control
Speech-Enabled Applications
SQL Server
SQL Server 2000
SQL Server 2005
SQL Server 2008
SQL Server 2012
SQL Server CE/AnyWhere/Mobile/Compact
SSIS
Subversion
Sync Framework
Tablet PC
TDD
Team System
Techniques
Testing and Quality Control
TFS
Tips
TypeScript
UI Design
UML
User Groups
VB Script
VB.NET
Version Control
VFP and .NET
VFP and SQL Server
Virtual Earth
Vista
Visual Basic
Visual Basic 6 (and older)
Visual FoxPro
Visual Studio .NET
Visual Studio 11
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio 2011
Visual Studio 2012
Visual Studio Tools for Office
VSX
WCF
Web Development (general)
Web Services
WebMatrix
WF
Whitepapers
Windows 7
Windows 8
Windows Azure
Windows Live
Windows Phone 7
Windows Phone SDK
Windows Server
Windows Vista
WinForms
WinRT
Workflow
WPF
XAML
Xiine Documentation
XML
XNA
XSLT



SSWUG


XAMALOT
 


CODE Training

Reader rating:
Article source: CoDe (2008 - Vol. 5 - Issue 4 - Windows Accessibility Focus)


Article Pages:  1  2 3 - Next >


Making Custom Controls Accessible

While custom controls are introduced every day, not all of them are easily accessible. This article provides a quick summary of Microsoft® technologies that help make Win32-based custom controls programmatically accessible. Techniques range from implementing UI Automation, to creating or overriding properties with Dynamic Annotation, to using the new IAccessibleEx interface to close the gap between UI Automation and Microsoft Active Accessibility®.

The Windows® operating system offers several technologies to help make controls accessible: Microsoft Active Accessibility, UI frameworks, and UI Automation. As Table 1 shows, the most effective technology depends on how developers introduce their new controls.

"
Before investing time designing a new control or customizing a standard control, you should ask yourself: “Do I really need that control?”
"

For controls and frameworks written from scratch, UI Automation is recommended today. While Microsoft Active Accessibility is handy for relatively simple controls, the technology doesn’t support the complexity of modern user interfaces (UI).

For controls based on common controls (such as COMCTL32.DLL or USER32.DLL), Dynamic Annotation enables modest customization. However, it may not be sufficient for significant customization or for sub-classed controls. For controls based on solid Microsoft Active Accessibility implementations, developers can use the IAccessibleEx Interface specification to enhance accessibility with new UI Automation interfaces.

This article introduces the basics of using UI Automation, Dynamic Annotation, and the IAccessibleEx interface for developing controls.

Quick Tips: “Do I Really Need that Control?”

Before investing time in designing a new control or customizing a standard control, you should ask yourself: “Do I really need that control?”

If you’re lucky, you may find a standard control that does the job. Many modern UI libraries support accessibility and customization.

If you customize a standard control, try not to overload it with features. Unnecessary complexity can result in expensive accessibility support cost, not to mention reduced usability. Never underestimate the implication of a small modification. If you have to introduce major customizations, consider creating a control from scratch

If you have to introduce a new control, try to follow standard practices to support UI accessibility. For example, never assume that all users have access to pointing devices, and try to use system or desktop theme colors to avoid accessibility problems with custom colors. While the focus of this article is on programmatic access to the user interface, these fundamental accessibility criteria are very important.

Many accessibility practices are available in the form of industry standards (such as Section 508 of the Federal Rehabilitation Act). Some useful resources are introduced at the Microsoft Accessibility Developer Center (http://msdn.microsoft.com/en-us/accessibility/default.aspx).

Part I: Implementing UI Automation

This article talks about implementing UI Automation for new controls in a few simplified steps. Designing a UI Automation object model for a new user interface is straightforward if you follow a few basic principles:

  1. Define user scenarios clearly. Actual user scenarios are helpful. During the design process, you shouldn’t rely on a single operation device such as mice, custom color, or screen size.
  2. Define the UI functionality as simply as possible. Is it clickable (such as a button or hyperlink)? Does it allow for selection (such as a list box)?
  3. Isolate fundamental UI elements by function or feature. Structure a complex UI in a way consistent with user scenarios. A keyboard navigation model is a useful guide.
  4. Match a UI feature from the previous step with existing controls. The UI Automation Control Type specification is a useful guideline. If you have trouble finding the correct control type, see the Control Pattern specifications and locate a control type that has the control patterns you want.

Step 1: The Foundation

Note: This sample project is available for download at MSDN Online (http://msdn.microsoft.com/en-us/library/ms771315(VS.85).aspx). The Windows SDK also features two additional UI Automation provider samples.

The foundation of UI Automation provider objects is the IRawElementProviderSimple interface implemented by the applications or by the UI Framework that supports UI Automation. Objects that contain a more complex tree structure should also implement IRawElementProviderFragment, and the root for this structure implements IRawElementProviderFragmentRoot. Objects whose performance is very important can use IRawElementProviderAdviseEvents to know which events they should raise. Finally, you should use the IRawElementProviderHwndOverride interface when the provider needs to reorder the automation tree. Most providers do not implement this interface.

In this project, you implement only IRawElementProviderSimple, which contains the following methods:

// IRawElementProviderSimple
STDMETHODIMP GetPatternProvider(
  PATTERNID patternId, IUnknown** pRetVal);

STDMETHODIMP GetPropertyValue(
  PROPERTYID propertyId, VARIANT* pRetVal);

STDMETHODIMP get_HostRawElementProvider(
  IRawElementProviderSimple** pRetVal);

STDMETHODIMP get_ProviderOptions(
  ProviderOptions* pRetVal);

For the UI Automation Framework to recognize your UI Automation provider implementation, you must respond to the WM_GETOBJECT message. The UiaReturnRawElementProvider function helps produce the key to establish a connection to the UI Automation Core:

case WM_GETOBJECT:
  {
    if (_pProxy == NULL)
      {
        // Create an automation element object
        _pProxy =
          CCheckbox3UIAProxy::Create(this);
      }
    return UiaReturnRawElementProvider(
      _hwnd, wParam, lParam, _pProxy);
  }
  break;

Now you are ready to implement the support for UI Automation properties and pattern interfaces.

Step 2: Implementing the Properties and Control Patterns

UI Automation providers add support for properties with the GetPropertyValue method. For control patterns, providers support the corresponding patternId for the GetPatternProvider method.

"
Many accessibility practices are available in the form of industry standards (such as Section 508 of the Federal Rehabilitation Act).
"

You can register the properties and control patterns with GUIDs (such as the Toggle_Pattern_GUID) that you map to the corresponding IDs with the UiaLookupId function. For existing control patterns and properties, you can find corresponding IDs in UIAutomationClient.h (such as UIA_TogglePatternId).

In this example, you get the property value of a check box:

HRESULT CCheckbox3UIAProxy::GetPropertyValue(
    PROPERTYID propertyId,
    IUnknown **pRetVal)
{
  // Clear out param
  pRetVal->vt = VT_EMPTY;
 
  // Specify ControlType.CheckBox for the
  // ControlType property
  if (propertyId == UIA_ControlTypePropertyId)
  {
     pRetVal->vt = VT_I4;
     pRetVal->lVal = UIA_CheckBoxControlTypeId;
  }
  return S_OK;
}

To support controls with a binary status such as the check box (checked or cleared), the Toggle Pattern is best, and the implementation is straightforward as shown in Listing 1.

Here, you get the pattern provider for the toggle pattern:

HRESULT CCheckbox3UIAProxy::GetPatternProvider(
  PATTERNID patternId,
  IUnknown **pRetVal)
{
  // Clear out param
  *pRetVal = NULL; 

  if (patternId == UIA_TogglePatternId)
  {
    *pRetVal = 
    static_cast<IRawElementProviderSimple*>(this);
    AddRef();
  }
  return hr;
}
&

By: LeAnne Fossmeyer

LeAnne is a Content Publishing Lead in the Windows Experience organization at Microsoft.

leannef@microsoft.com

Fast Facts

To meet the accessibility requirements, a small change in standard controls can cause more code changes than the change itself. Never underestimate the implication of a small modification.


Meet Microsoft’s Accessibility Team



Type of Custom ControlType of CustomizationSuggested Approach
New controlWrite new UI code from scratchImplement UI Automation or Microsoft Active Accessibility for relatively simple controls such as a button.
COMCTRL/USER controls with minor modificationMake small changes that have no functional impact (background color)Use Dynamic Annotation to modify (or add) Microsoft Active Accessibility/UI Automation properties.
Microsoft Active Accessibility-based controlsAdd new functionality not compatible with Microsoft Active Accessibility designImplement the IAccessibleEx interface and address only the gap from Microsoft Active Accessibility to UI Automation.


Listing 1: The Toggle Pattern supports the binary status of a check box control.
// IToggleProvider to support the Toggle control pattern.
HRESULT CCheckbox3UIAProxy::Toggle()
{
  HRESULT hr = CheckAlive();
  if (SUCCEEDED(hr))
  {
    _pControl->MoveToNextState();
  }
  return hr;
}

HRESULT CCheckbox3UIAProxy::get_ToggleState(ToggleState* pRetVal)
{
  HRESULT hr = CheckAlive();
  if (SUCCEEDED(hr))
  {
    switch(_pControl->CheckboxCheckedState())
    {
    case CHECKED:
      {
        *pRetVal = ToggleState_On;
      }
      break;

    case MIXED:
      {
        *pRetVal = ToggleState_Indeterminate;
      }
      break;

    case UNCHEcKED:
      {
        *pRetVal = ToggleState_Off;
      }
      break;
    }
  }
  return hr;
}


Article Pages:  1  2 3 - Next Page: 'Part II: Using Dynamic Annotation' >>

Page 1: Making Custom Controls Accessible
Page 2: Part II: Using Dynamic Annotation
Page 3: Part III: Implementing IAccessibleEx

How would you rate the quality of this article?
1 2 3 4 5
Poor      Outstanding

Tell us why you rated the content this way. (optional)

Average rating:
3 out of 5

6 people have rated this article.

Instantly Search Terabytes Of Text
“Lightning Fast”
– Redmond Mag
“Covers all data
sources” – eWeek
25+ fielded & full-text search options
dtSearch’s own document filters highlight hits in popular file types
Web Spider supports static & dynamic data
APIs for .NET, Java, C++, SQL, etc.
Win / Linux (64-bit & 32-bit)
www.dtSearch.com
 

      LearnNow

 

CODE Training