演练:创建可访问的基于 Windows 的应用程序

更新:2007 年 11 月

创建具有辅助功能的应用程序有重要的商业意义。许多政府都有针对软件购买的辅助功能法规。Windows 徽标认证包括辅助功能要求。据估计仅美国就有三千万居民(其中许多是潜在的客户)受到软件辅助功能的影响。

此项演练将针对 Certified for Windows 徽标的五项辅助功能要求。根据这些要求,具有辅助功能的应用程序将:

  • 支持控制面板大小、颜色、字体和输入设置。菜单栏、标题栏、边框和状态栏会在用户更改控制面板设置时调整它们自身的大小。本应用程序中不需要对控件或代码进行其他更改。

  • 支持高对比度模式。

  • 可以通过键盘访问所有功能,并提供键盘使用的详细说明。

  • 以可视和编程的方式公开键盘焦点的位置。

  • 避免仅靠声音传递重要信息。

有关更多信息,请参见用于设计辅助应用程序的资源、“MSDN Online Certified for Windows Program”(Windows 程序的 MSDN 在线认证)网页 (https://www.microsoft.com/china/windowsserver2003/partners/isvs/default.mspx) 和“Designed for Windows XP Application Specification”(Windows XP 应用程序专用规范)网页 (https://go.microsoft.com/fwlink/?linkid=9775)。

有关支持不同键盘布局的信息,请参见开发全球通用应用程序的最佳做法

创建项目

此演练为一个接受比萨饼订单的应用程序创建用户界面。它包括以下内容:一个用于输入客户名称的 TextBox,一个用于选择比萨饼大小的 RadioButton 组,一个用于选择浇汁的 CheckedListBox,两个分别标记为“Order”(定购)和“Cancel”(取消)的按钮控件以及一个带“Exit”(退出)命令的菜单。

用户输入客户的名称、比萨饼的大小和想要的浇汁。当用户单击“Order”(定购)按钮时,将在消息框中显示订单的一览表及其价格,然后将控件清除以便为下一个订单做好准备。当用户单击“Cancel”(取消)按钮时,将控件清除并为下一个订单做好准备。当用户单击“Exit”(退出)菜单项时,程序关闭。

本演练的重点不是零售订单系统的代码,而是用户界面的辅助功能。本演练说明若干个常用控件(包括按钮、单选按钮、文本框和标签)的辅助功能特性。

开始生成应用程序

  • 在 Visual Basic、Visual C# 或 Visual J# 中创建一个新的 Windows 应用程序。将项目命名为 PizzaOrder。(有关详细信息,请参见创建新解决方案和项目。)

将控件添加到窗体中

将控件添加到窗体时,请牢记下列生成具有辅助功能的应用程序的准则:

  • 设置 AccessibleDescriptionAccessibleName 属性。本示例中,AccessibleRole 的默认设置足够满足要求。有关辅助功能属性的更多信息,请参见为 Windows 窗体上的控件提供辅助功能信息

  • 将字体大小设置为 10 磅或更大。

    说明:

    如果开始时将窗体的字体大小设置为 10,则随后添加到该窗体的所有控件的字体大小均将为 10。

  • 确保任何描述文本框控件的标签控件的 Tab 键顺序紧排在相应文本框控件之前。

  • 使用“&”字符将访问键添加到用户要定位的任何控件的 Text 属性。

  • 使用“&”字符将访问键添加到用户要定位的标签的 Text 属性。将标签的 UseMnemonic 属性设置为 true,以便用户按下访问键时将焦点设置到 Tab 键顺序的下一个控件上。

  • 向所有的菜单项添加访问键。

使 Windows 应用程序具有辅助功能

  • 将控件添加到窗体中,并按下文描述设置属性。有关如何在窗体上排列控件的样式,请参见表结尾处的图片。

    对象

    属性

    Form1

    AccessibleDescription

    “定购”窗体

     

    AccessibleName

    “定购”窗体

     

    Font Size

    10

     

    Text

    “定购”比萨饼窗体

    PictureBox

    Name

    logo

     

    AccessibleDescription

    一块比萨饼

     

    AccessibleName

    公司徽标

     

    Image

    任何图标或位图

    Label

    Name

    companyLabel

     

    Text

    Good Pizza

     

    TabIndex

    1

     

    AccessibleDescription

    公司名称

     

    AccessibleName

    公司名称

     

    Backcolor

    蓝色

     

    Forecolor

    黄色

     

    Font size

    18

    Label

    Name

    customerLabel

     

    Text

    &Name

     

    TabIndex

    2

     

    AccessibleDescription

    客户名称标签

     

    AccessibleName

    客户名称标签

     

    UseMnemonic

    True

    TextBox

    Name

    customerName

     

    Text

    (无)

     

    TabIndex

    3

     

    AccessibleDescription

    客户名称

     

    AccessibleName

    客户名称

    GroupBox

    Name

    sizeOptions

     

    AccessibleDescription

    比萨饼大小选项

     

    AccessibleName

    比萨饼大小选项

     

    Text

    比萨饼大小

     

    TabIndex

    4

    RadioButton

    Name

    smallPizza

     

    Text

    &Small $6.00

     

    选中

    True

     

    TabIndex

    0

     

    AccessibleDescription

    小比萨饼

     

    AccessibleName

    小比萨饼

    RadioButton

    Name

    largePizza

     

    Text

    &Large $10.00

     

    TabIndex

    1

     

    AccessibleDescription

    大比萨饼

     

    AccessibleName

    大比萨饼

    Label

    Name

    toppingsLabel

     

    Text

    &Toppings(每个 $0.75)

     

    TabIndex

    5

     

    AccessibleDescription

    浇汁标签

     

    AccessibleName

    浇汁标签

     

    UseMnemonic

    True

    CheckedListBox

    Name

    toppings

     

    TabIndex

    6

     

    AccessibleDescription

    可选的浇汁

     

    AccessibleName

    可选的浇汁

     

    Items

    Pepperoni, Sausage, Mushrooms

    Button

    Name

    order

     

    Text

    &Order

     

    TabIndex

    7

     

    AccessibleDescription

    合计订单

     

    AccessibleName

    订单合计

    Button

    Name

    取消

     

    Text

    &Cancel

     

    TabIndex

    8

     

    AccessibleDescription

    取消订单

     

    AccessibleName

    取消订单

    MainMenu

    Name

    theMainMenu

    MenuItem

    Name

    fileCommands

     

    Text

    文件(&F)

    MenuItem

    Name

    exitApp

     

    Text

    E&xit

    窗体的外观应类似于:

    比萨饼订购窗体

支持高对比度模式

高对比度模式是一种 Windows 系统设置,它通过使用有益于视力受损用户的对比鲜明的色彩和字体大小提高可读性。提供 SystemInformation.HighContrast 属性以确定是否设置了高对比度模式。

如果 SystemInformation.HighContrast 为 true,则应用程序应当:

  • 使用系统配色方案显示所有用户界面元素。

  • 用可视提示或声音传递任何通过颜色传递的信息。例如,如果特定列表项用红色字体突出显示,则可以将字体改为粗体,这样用户就得到一种有关突出显示项目的非颜色提示。

  • 忽略文本后面的任何图像或图案。

应用程序在启动时应检查 HighContrast 的设置,并响应系统事件 UserPreferenceChanged。只要 HighContrast 的值发生改变,就会引发 UserPreferenceChanged 事件。

此应用程序中,不使用系统颜色设置的唯一元素是 lblCompanyName。SystemColors 类用来将标签的颜色设置更改为用户选定的系统颜色。

有效地启用高对比度模式

  1. 创建一个方法以将标签的颜色设置为系统颜色。

    ' Visual Basic
    Private Sub SetColorScheme()
       If SystemInformation.HighContrast Then
          companyLabel.BackColor = SystemColors.Window
          companyLabel.ForeColor = SystemColors.WindowText
       Else
          companyLabel.BackColor = Color.Blue
          companyLabel.ForeColor = Color.Yellow
       End If
    End Sub
    
    // C#
    private void SetColorScheme()
    {
       if (SystemInformation.HighContrast)
       {
          companyLabel.BackColor = SystemColors.Window;
          companyLabel.ForeColor = SystemColors.WindowText;
       }
       else
       {
          companyLabel.BackColor = Color.Blue;
          companyLabel.ForeColor = Color.Yellow;
       }
    }
    
    // Visual J#
    private void SetColorScheme()
    {
       if (SystemInformation.get_HighContrast())
       {
          companyLabel.set_BackColor(SystemColors.get_Window());
          companyLabel.set_ForeColor(SystemColors.get_WindowText());
       }
       else
       {
          companyLabel.set_BackColor(Color.get_Blue());
          companyLabel.set_ForeColor(Color.get_Yellow());
       }
    }
    
  2. 在窗体构造函数(Visual Basic 中为 Public Sub New() ,Visual C# 中为 public class Form1 ,Visual J# 中为 Public Form1)中调用 SetColorScheme 过程。若要在 Visual Basic 中访问构造函数,则需要展开标记为“Windows 窗体设计器生成的代码”的区域。

    ' Visual Basic 
    Public Sub New()
       MyBase.New()
       InitializeComponent()
       SetColorScheme()
    End Sub
    
    // C#
    public Form1()
    {
       InitializeComponent();
       SetColorScheme();
    }
    
    // Visual J#
    public Form1()
    {
       InitializeComponent();
       SetColorScheme();
    }
    
  3. 使用适当的签名创建一个事件过程,以响应 UserPreferenceChanged 事件。

    ' Visual Basic
    Protected Sub UserPreferenceChanged(ByVal sender As Object, _
    ByVal e As Microsoft.Win32.UserPreferenceChangedEventArgs)
       SetColorScheme()
    End Sub
    
    // C#
    public void UserPreferenceChanged(object sender, 
    Microsoft.Win32.UserPreferenceChangedEventArgs e)
    {
       SetColorScheme();
    }
    // Visual J#
    public void UserPreferenceChanged(Object sender, Microsoft.Win32.UserPreferenceChangedEventArgs e)
    {
       SetColorScheme();
    }
    
  4. 在窗体构造函数中对 InitializeComponents 的调用后面添加代码,以便将事件过程挂钩到系统事件上。此方法调用 SetColorScheme 过程。

    ' Visual Basic
    Public Sub New()
       MyBase.New()
       InitializeComponent()
       SetColorScheme()
       AddHandler Microsoft.Win32.SystemEvents.UserPreferenceChanged, _
          AddressOf Me.UserPreferenceChanged
    End Sub
    
    // C#
    public Form1()
    {
       InitializeComponent();
       SetColorScheme();
       Microsoft.Win32.SystemEvents.UserPreferenceChanged 
          += new Microsoft.Win32.UserPreferenceChangedEventHandler(
          this.UserPreferenceChanged);
    }
    
    // Visual J#
    public Form1()
    {
       //
       // Required for Windows Form Designer support
       //
       InitializeComponent();
       SetColorScheme();
       Microsoft.Win32.SystemEvents.add_UserPreferenceChanged(
           new Microsoft.Win32.UserPreferenceChangedEventHandler(this.UserPreferenceChanged));
       //
       // Add any constructor code after InitializeComponent call
       //
    }
    
  5. 在调用基类的 Dispose 方法之前,向窗体的 Dispose 方法添加代码,以在关闭应用程序时释放事件。若要在 Visual Basic 中访问 Dispose 方法,则需要展开标记为“Windows 窗体设计器生成的代码”的区域。

    说明:

    系统事件代码运行一个独立于主应用程序的线程。如果不释放事件,则即使程序关闭后挂接到该事件上的代码也将运行。

    ' Visual Basic
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
       If disposing Then
          If Not (components Is Nothing) Then
             components.Dispose()
          End If
       End If
       RemoveHandler Microsoft.Win32.SystemEvents.UserPreferenceChanged, _
          AddressOf Me.UserPreferenceChanged
       MyBase.Dispose(disposing)
    End Sub
    
    
    // C#
    protected override void Dispose( bool disposing )
    {
       if( disposing )
       {
          if (components != null) 
          {
             components.Dispose();
          }
       }
       Microsoft.Win32.SystemEvents.UserPreferenceChanged 
          -= new Microsoft.Win32.UserPreferenceChangedEventHandler(
          this.UserPreferenceChanged);
       base.Dispose( disposing );
    }
    
    // Visual J#
    protected void Dispose(boolean disposing)
    {
       if (disposing)
       {
          if (components != null)
             {
                components.Dispose();
             }
          }
          Microsoft.Win32.SystemEvents.remove_UserPreferenceChanged(
             new Microsoft.Win32.UserPreferenceChangedEventHandler( this.UserPreferenceChanged));
          super.Dispose(disposing);
       }
    
  6. 按 F5 运行应用程序。

用非声音方法传达重要信息

在本应用程序中,没有一种信息是只用声音传达的。如果在应用程序中使用声音,则还应使用其他一些方法提供信息。

若要用声音以外的其他方法提供信息

  1. 使用 Windows API 函数 FlashWindow 令标题栏闪烁。有关如何调用 Windows API 函数的示例,请参见演练:调用 Windows API

    说明:

    用户可能已经启用了 Windows SoundSentry 服务,这也会在使用计算机内置扬声器播放系统声音时引起窗口闪烁。

  2. 在非模式窗口中显示重要信息以使用户可以响应它。有关详细信息,请参见显示有模式和无模式 Windows 窗体

  3. 显示一个获取键盘焦点的消息框。在用户可能正在键入的时候避免使用此方法。

  4. 在任务栏的状态通知区域显示一个状态指示器。有关详细信息,请参见使用 Windows 窗体 NotifyIcon 组件向任务栏添加应用程序图标

测试应用程序

在部署本应用程序之前,应当测试已经实现的辅助功能特性。

测试辅助功能特性

  1. 若要测试键盘访问,请拔掉鼠标,只使用键盘在用户界面中导航以检查每个特性。确保只使用键盘就可以执行所有任务。

  2. 若要测试是否支持高对比度,请选择“控制面板”中的“辅助功能选项”图标。单击“显示”选项卡,再选择“使用高对比度”复选框。定位到所有用户界面元素以确保反映了颜色和字体的更改。同时,确保忽略所有在文本后面绘制的图像或图案。

    说明:

    Windows NT 4 的“控制面板”中没有“辅助功能选项”图标。因此,更改 SystemInformation.HighContrast 设置的这个过程在 Windows NT 4 中是无效的。

  3. 还有其他工具可用以测试应用程序的辅助功能。

  4. 若要测试公开键盘焦点,请运行放大镜。(若要打开它,请单击“开始”菜单,指向“程序”,指向“附件”,指向“辅助功能选项”,再单击“放大镜”。) 使用键盘 Tab 键和鼠标导航用户界面。确保在“放大镜”中准确跟踪了所有的导航。

  5. 若要测试公开的屏幕元素,运行 Inspect,并使用鼠标和 Tab 键选中每个元素。确保在 Inspect 窗口的“Name”、“State”、“Role”、“Location”和“Value”字段中展示的信息对于 UI 中的每个对象的用户都是有意义的。Inspect 可作为 Microsoft® Active Accessibility® SDK 的一部分进行安装,该 SDK 可在网址 https://msdn.microsoft.com/library/default.asp?url=/downloads/list/accessibility.asp 上找到。