Como deixar as suas aplicações Delphi mais acessíveis

By: Marco A. A. Sangali

Abstract: Dicas e truques para facilitar o uso de aplicações VCL e WinForms por pessoas cegas

Introdução

Como as tecnologias do BDS se adequam a esse propósito?

Estou em desvantagem se uso C++ em vez de Delphi?

VCL para Win32

Dicas gerais de projeto

A sequência de tabulação

Não deixe TabStop em TRUE para componentes somente visuais

Rotulando corretamente seus controles

Forneça mnemônicos para os seus controles

Nunca deixe o foco do teclado na Terra de Ninguém

Assegure-se que cada opção possa ser alcançada via teclado

Agrupe controles relacionados

Evite mudanças de foco automáticas

Controles específicos

           TMemo

           TStringGrid

ActionBands

TSpinEdit, TSpeedButton, TBitBtn

Desenvolvendo os seus próprios componentes visuais

VCL.NET

Winforms com Delphi ou C#

Situações a serem evitadas a todo custo

Conclusão

Introdução

Há duas grandes categorias de usuários de computadores: Os que preferem usar o mouse e os que preferem o uso do teclado em detrimento do mouse. A maioria provavelmente está entre estes dois extremos. Claro que para digitar texto usa-se o teclado, e para interagir com caixas de diálogos e chamar menus usa-se o mouse. Os atalhos mais usados podem ser memorizados para que as mãos não tenham que trocar constantemente o teclado pelo mouse.

E há aqueles que têm que usar apenas o teclado em vez do mouse, porque o uso desse último é quase impossível para eles. A razão é simples: Eles não podem ver o que estão fazendo. São as pessoas cegas, e para elas o teclado é a única forma confiável de interação com o computador.

Você pode imaginar: Como é que pessoas cegas usam um computador se elas não podem ver o monitor?

A resposta é uma tecnologia chamada leitura de tela ("screen reading"). Um tipo especial de software chamado leitor de tela busca os objetos de tela como documentos, menus, caixas de diálogo, páginas de web, mensagens de correio eletrônico, etc., e converte todos esses dados em voz (através de um sintetizador) e/ou informação em um monitor Braille.

Muitos destes produtos também conseguem simular o movimento do mouse e até mesmo operações de "arrastar-e-soltar", mas essas características avançadas dependem da existência de dados para interagir. Geralmente, trabalhar com eles deste jeito é ineficiente.

Se um software é inacessível, isso é um verdadeiro problema. Exigir o uso extensivo de barras de ferramentas, por exemplo, sem meios alternativos de uso via teclado ou menus, irá diminuir enormemente a eficiência da interface para um usuário cego, mesmo que a os ícones da barra de ferramentas sejam visíveis para o software leitor de tela.

Se um software é acessível, significa que ele exibe seus dados de forma que um leitor de tela possa entender, seus menus e caixas de diálogo podem ser alcançados com o uso do teclado, e os seus controles podem interagir plenamente usando-se apenas o teclado.

Boa parte dos softwares padrão presentes nos computadores rodando o sistema operacional Microsoft Windows, tais como navegadores de web, correio eletrônico ou processadores de texto, são bem acessíveis hoje em dia. A Microsoft, a Corel, a Fundação Mozilla e outras companhias adotaram a noção de que acessibilidade é importante não apenas para quem não enxerga, mas que na verdade beneficia qualquer usuário de computador.

Como as tecnologias do BDS se adequam a esse propósito?

A Borland projetou a VCL (Visual Library Component - Biblioteca de Componentes Visuais) de uma forma que se mostrou bem compatível com os controles MFC (Microsoft Foundation Class - Classes Fundamentais da Microsoft), usadas pelo Windows e pelas aplicações que o acompanham. A maioria dos leitores de tela depende de que os controles da aplicação estejam organizados hierarquicamente. Uma caixa de diálogo, por exemplo, pode ter um ou mais controles filhos como caixas de edição, botões, etc. Os leitores de texto então mandam um conjunto padrão de mensagens para a janela para verificar qual o seu estado e outras propriedades. Por exemplo, uma caixa de edição pode ter mais de uma linha de texto, ou ser apenas de leitura. Uma caixa de seleção (checkbox) pode estar selecionada, desselecionada, ou até mesmo ser uma caixa de seleção de 3 estados.

As classes da VCL se comportam da mesma maneira: Elas reagem às mesmas mensagens do mesmo jeito. Assim, um leitor de tela sabe que pode mandar as mesmas mensagens que manda para um componente Edit da MFC para um componente TEDit que o resultado será virtualmente o mesmo. Claro, existem excessões, e elas serão mencionadas abaixo.

Estou em desvantagem se uso C++ em vez de Delphi?

Não. Se você usar o C++Builder, vai ter acesso aos mesmos componentes da VCL e pode usar as mesmas técnicas descritas abaixo para o Delphi.

VCL para Win32

A VCL para Win32 existe há mais tempo, então vamos começar por ela. Ela foi introduzida com o Delphi-1 como VCL para Win16, mas o projeto geral é consistente com o ambiente do BDS2006.

Dicas gerais de projeto

Como dito acima, a maioria dos leitores de tela usa uma hierarquia de janelas dentro de um aplicativo para obter informações sobre o leiaute da aplicação e as relações entre as janelas. Lembre-se: Todo controle é uma janela, mesmo que ele não tenha uma borda ou uma barra de título. Ele tem - e isso é a parte importante - um manipulador de janela que está registrado no sistema operacional Windows, e que é a referência usada pelo leitor de tela para interagir com ele.

Ao desenhar a interface visual do seu aplicativo, assegure-se de seguir as regras simples abaixo:

A sequência de tabulação

Certifique-se de que todos os seus controles estão na seqüência de tabulação. Pode-se testar isso colocando o aplicativo para rodar e pressionando a tecla de tabulaçao seguidamente e acompanhar a movimentação do foco de teclado. Se um controle não estiver na seqüência de tabulação, significa que ele não pode ser facilmente alcançado via teclado.

Não deixe TabStop em TRUE para componentes somente visuais

Sim, apesar de ser importante que todo controle com o qual o usuário possa interagir seja acessível via seqüência de tabulação, é igualmente importante se certificar que o foco não atinja controles com os quais não se possa interagir. Por exemplo, há aplicativos que permitem que o foco de teclado seja posicionado em um TPanel. Esses são controles apenas para desenho e não expõem nenhum nome de janela. O que acontece é que se o foco vai pra um TPanel mas, como não há nome de janela para falar, o usuário cego recebe apenas silêncio como resposta. Além disso, como o controle não é interativo, mesmo para um usuário não deficiente visual não há indicação de onde está o foco do teclado e qual controle responderá à próxima ação. Então, ao testar o seu aplicativo, certifique-se de que ele não vai levar o usuário a esse tipo de situação, seja ele deficiente visual ou não.

Rotulando corretamente seus controles

Inclua componentes TLabel e TStaticText na seqüência de tabulação, imediatamente antes do controle que eles estão rotulando. A maioria dos leitores de tela usa a seqüência de tabulação para associar rótulos (labels) com caixas de texto ou de lista, e isso ajuda enormemente o leitor de tela a associar o rótulo ao controle. A diferença entre o TLabel e o TStaticText é que o último se registra com o seu próprio manipulador de janela, enquanto o TLabel não o faz. Idealmente o TStaticText é a melhor escolha se você realmente quer que o seu rótulo seja encontrado. Testes recentes com o controle TLabeledEdit, entretanto, mostraram resultados muito bons. Isso inclui todos os posicionamentos possíveis do rótulo.

Idealmente, um rótulo para um campo de texto deve ser colocado à esquerda deste último. Isso facilita a sua localização pelos leitores de tela. Além disso, usuários de monitores Braille se beneficiam dessa estratégia porque tanto o rótulo como o texto editado podem ser vistos ao mesmo tempo.

Forneça mnemônicos para os seus controles

Mnemônicos são os caracteres sublinhados que vemos em muitas caixas de diálogo do Windows. Apertar Alt mais a letra sublinhada imediatamente posiciona o foco naquele controle. O menmônico é declarado na propriedade caption do componente. A letra usada pelo mnemônico é precedida pelo E comercial "&". Se você quer fornecer um mnemônico para um controle que não tem caption, como, por exemplo, um TEdit, coloque o mnemônico no rótulo associado a ele, e, para completar, ajuste a propriedade FocusControl para o controle para o qual o foco deve ir. Isso se aplica tanto ao TLabel como ao TStaticText.

Cerifique-se também que dentro do mesmo formulário, os mnemônicos não se repitam. Se dois controles em dois formulários distintos têm os mesmos mnemônicos, isso não é problema. Além disso, mnemônicos em ítens de menus podem ser os mesmos em dois submenus ou pop-up menus distintos. Só é problemático quando o mesmo mnemônico for especificado para duas opções dentro do mesmo nível de menu.

Nunca deixe o foco do teclado na Terra de Ninguém

Por exemplo, se você disponibiliza um botão "Aplicar" que se torna ativo assim que uma opção de uma caixa de diálogo é alterada, mas se torna inativo assim que é pressionado, certifique-se que a última ação de seu evento OnClick devolve o foco para um controle que esteja ativo. De preferência, para o primeiro controle a receber o foco quando o usuário abriu a caixa de diálogo. Se o foco não for posicionado em um controle ativo, isso irá exigir que o usuário dê um alt-tab para sair da sua aplicação, e então voltar para ela, e torcer para que o formulário automaticamente devolva o foco para o primeiro controle que aceite. Ou, ainda pior, o usuário terá que recorrer à emulação do mouse para clicar num controle ativo para recuperar o controle do foco.

Assegure-se que cada opção possa ser alcançada via teclado

Ao projetar o seu aplicativo assegure-se que toda opção possa ser alcançada via teclado ou ítem de menu. Tudo bem disponibilizar uma barra de ferramentas para o seu usuário, desde que você também dê a ele formas de usar o teclado para a mesma opção. Por exemplo, o Microsoft Word dá ao usuário a escolha de clicar no botão "Novo" na barra de ferramentas padrão, mas também permite o atalho comum Ctrl-N para obter o mesmo resultado. Sempre se pergunte se a opção que você acabou de implementar pode ser alcançada via teclado. Se você não tem certeza, rode o seu aplicativo, deixe as mãos longe do mouse, e tente usar a sua aplicação apenas com o teclado.

Agrupe controles relacionados

Agrupe botões de rádio que pertençam à mesma opção dentro de um grupo de botões de rádio, mas se possível não misture os botões de rádio. Assegure-se de que a caixa de agrupamento é realmente o controle-pai dos botões de rádio que agrupa. Os componentes TGroupBox e TRadioGroup são boas escolhas para isso.

Evite mudanças de foco automáticas

É comum posicionar o foco em uma caixa de edição assim que a opção em um botão de rádio é feita. Por exemplo, numa caixa de diálogo de impressão, clicar no botão de rádio "Imprimir as páginas selecionadas" leva automaticamente o foco para a caixa de edição que define a página inicial. O mesmo acontece freqüentemente quando se navega com o teclado: O Tab chega a um grupo de botões de rádio, com um deles normalmente selecionado. A forma que o Windows disponibiliza para selecionar outro botão de rádio é através das teclas de setas para cima ou para baixo. Se uma mudança de foco é ligada ao evento OnClick, ao se pressionar a seta para baixo teremos duas mudanças de foco praticamente instantâneas: O OnClick do botão de rádio que acabou de receber o foco, seguido imediatamente pela mudança de foco no campo de edição. Leitores de tela normalmente não têm chance de dizer ao usuário em qual botão de rádio eles acabaram de chegar. A segunda mudança de foco simplesmente é feita rápido demais para que o leitor de tela tenha uma oportunidade de registrar a primeira em tempo hábil. Em vez de disponibilizar uma mudança automática de foco, certifique-se de que o seu botão de rádio recebeu o foco, e que pressionar TAB, dependendo do botão de rádio selecionado, vai levar usuário para o controle desejado. No nosso exemplo, a caixa de edição para a página inicial se a opção "Imprimir as páginas selecionadas" estiver selecionada, ou então a caixa de edição para o número de cópias se a opção selecionada for "Imprimir tudo".

Controles específicos

Há controles que não tem correspondentes nas classes da Microsoft, como por exemplo, o TStringGrid ou os componentes ActionBand. Alguns deles serão tratados aqui.

           TMemo

O TMemo é uma caixa de edição de várias linhas que pode exibir textos extensos. Foi feito de modo a se comportar como uma caixa de edição padrão. Leitores de tela não têm problemas para interagir com ele normalmente.

           TStringGrid

O TStringGrid é um controle bem difícil. A parte mais complicada é que sua estrutura em forma de tabela não pode ser facilmente traduzida para leitores de tela. Não há modo fácil de associar programaticamente o conteúdo de uma célula com o título da coluna em que ela está, por exemplo. O melhor é se certificar que as teclas de setas podem ir para todas as células, e que o texto dentro da célula está sempre destacado para que os leitores de tela possam pelo menos obter o conteúdo de cada célula.

ActionBands

A resposta depende de qual versão do Delphi, C++Builder ou BDS você usa. Se você usa o BDS2006, fique tranqüilo. O componente ActionBand que vem com o BDS2006 inclui uma tecnologia chamada MSAA (Microsoft Active Acessibility - Acessibilidade Ativa Microsoft). A MSAA permite que programadores passem informações para os leitores de tela através de formas não visuais. Isso pode ser tão simples como obter um rótulo para uma caixa de edição, o menu atualmente selecionado, ou o ícone da barra de ferramentas em que o foco está. Um controle que implemente MSAA usualmente tem propriedades como Name (Nome), Value (Valor), State (Estado), Description(Descrição) e HotKey(Tecla de atalho) que um leitor de tela pode acessar para obter informações, independentemente das características visuais do controle. As ActionBands foram introduzidas no Delphi 5 e foram desenvolvidas ao longo dos anos, mas eram completamente inacessíveis aos usuários de leitores de telas até o lançamento do BDS2006.

Se você ainda usa uma versão antiga do Delphi, e requer tanto ActionBands e acessibilidade, é hora de conversar com seu chefe sobre uma atualização de versão para o BDS2006.

TSpinEdit, TSpeedButton, TBitBtn

Se adequam perfeitamente aos leitores de tela, mesmo não tendo correspondentes do lado da MFC (exceto pelo TSpinEdit).

Desenvolvendo os seus próprios componentes visuais

Desenvolver os seus próprios componentes visuais não quer dizer que automaticamente sua aplicação será inacessível. Pelo contrário: Se o seu componente descende de um componente da VCL, normalmente todas as características de acessibiliade também ficam disponíveis. Apenas se você explicitamente excluir características herdadas você terá problemas de inacessibilidade.

Por outro lado, existem componentes de terceiros que parecem, e na maior parte, se comportam como controles padrão, mas que não incorporam todas as mensagens e eventos padrões que um componente Windows com a mesma aparência e comportamento oferece. Um exemplo é o TVirtualStringTree, um componente avançado para visualização hierárquica com muitas características interessantes. Mas tem alguns problemas também. Por exemplo, quando se abre ou fecha um nó, ele não gera os mesmos eventos que um controle SysTreeView32. Além disso, ele não informa o seu estado de aberto ou fechado para o leitor de tela, quando solicitado. Ele também permite selcionar e desselecionar os ítens hierárquicos, mas com o mesmo problema: Quando essa informação é solicitada pelo leitor de tela, ele não a retorna.

Se você desenvolve componentes, considere implementar a MSAA, especialmente quando se você quiser informar um usuário através de ícones ou cores que não são facilmente exibidas através de outros meios visuais. Comunicação não-visual com uma tecnologia de acessibilidade pode ser mesmo a melhor soluição. Ainda mais se o seu cliente precisa de acessibilidade no seu produto.

VCL.NET

As regras que se aplicam para a VCL para Win32 geralmente também se aplicam para a VCL.NET. Note que, porque a VCL.NET não é tão antiga quanto a VCL para Win32, as companhias que desenvolvem leitores de tela talvez ainda não tenham se ajustado para todos os componentes VCL.NET. Se você está desenvolvendo uma aplicação VCL.NET, ou baixe uma verssão de avaliação de um leitor de tela e teste você mesmo, ou ofereça ao seu cliente uma versão beta do seu aplicativo para que ele a avalie e lhe dê um retorno. Você pode até mesmo criar uma configuração que contenha as alterações de classes e anexá-la à sua aplicação para que o leitor de tela obtenha acesso imediato à ela já na instalação.

Winforms com Delphi ou C#

Se você cria uma aplicação WinForms tanto com Delphi como com C#, você possivelmente já se deparou com propriedades como AccName, AccValue, AccRole, e AccDescription no Inspetor de Objetos. A Microsoft desenvolveu o conjunto de controles do WinForms, e, como a MSAA também é uma tecnologia desenvolvida por ela, ela decidiu colocá-la direto nos seus controles e assim permitir que desenvolvedores manipulem o que é comunicado aos leitores de tela. A Borland, quando implementou o suporte a WinForms, também passou a oferecer essas propriedades, logo aplicações desenvolvidas em Delphi ou C# oferecem as mesmas características de acessibilidade que as desenvolvidas no Visual Studio usando-se C# ou VB.NET.

Basicamente as mesmas regras se mantêm, entretanto com a capacidade de se dar a uma caixa de edição um nome de acessibilidade (AccName), a necessidade de o rótulo receber foco deixa de existir. Leitores de tela normalmente usam informações da MSAA sempre que disponível, e apenas quando ela não existe é que buscam por informações na tela que identifiquem um rótulo para uma caixa de edição ou de lista.

Normalmente a propriedade AccessibleRole não deve ser alterada. Use-a quando desenvolver os seus próprios componentes WinForms, para dizer ao leitor de tela que tipo de controle ele é.

O AccDescription pode ser usado para dar mais informações. A Microsoft o usa no (ainda não lançado) Office 2007 para fornecer uma descrição para cada um dos controles de "Faixa de Opções" (Ribbon). Leitores de tela podem normalmente usar esses controles, ou padronizar para ler a descrição junto com o nome e valor se existir.

Situações a serem evitadas a todo custo

A única coisa realmente inacessível que você pode fazer com certas versões do Delphi e do C++Builder é criar aplicações CLX (aquelas que você também compila no Kylix). Componentes CLX, para serem independentes de plataforma, tem que evitar usar características específicas do Windows como se registrarem e terem seus próprios manipuladores de janelas. Aplicações CLX têm uma janela que é visível para o Windows, e tudo mais ocorre dentro dessa única janela, sem que o Windows seja notificado de nada. Mudanças de foco, menus abrindo e fechando, etc., tudo ocorre sem que o Windows, e, portanto, também o leitor de tela possa saber.

Conclusão

Do que foi exposto, se você desenvolve aplicações usando a VCL para Win32, VCL.NET ou WinForms, as suas aplicações são, na maior parte, acessíveis desde o começo. Há algumas regras que você deve seguir para fazê-las mais acessíveis. A questão mais importante que você deve se perguntar: Eu consigo fazer isso sem usar o mouse?

Todas essas técnicas podem ser aplicadas tanto no projeto de novas aplicações como quando você quer alterar alguma aplicação existente para torná-la mais acessível. Muito é automático, mas algumas questões dependem de decisões ponderadas de sua parte.

Eu espero que este arquivo o ajude a tomar algumas dessas decisões em favor de clientes que precisem de leitores de telas para acessar o conteúdo das telas. Feliz programação acessível!




Server Response from: ETNASC03