Sviluppare con Delphi applicazioni più accessibili
Nel mondo dei computer esistono due grandi categorie di utenti: c'è chi preferisce usare il mouse e
chi la tastiera. Molti utilizzeranno un mix delle due cose: la tastiera per scrivere, il mouse per
interagire con l'interfaccia grafica. Col tempo si ricordano anche le combinazioni di tasti più
utilizzate (
shortcut), evitando così di spostare le mani costantemente fra la
tastiera ed il mouse.
Alcune persone sono impossibilitate ad usare il mouse e devono affidarsi completamente alla tastiera.
La ragione è che non possono vedere quello che stanno facendo: la tastiera è l'unico dispositivo
affidabile per interagire col computer. Ci si può chiedere: come può un ipovedente utilizzare un
elaboratore se non è in grado di vedere lo schermo? La risposta è in una tecnologia detta
screen reading.
Un software specializzato individua il contenuto dello schermo (documenti, menù, dialog, pagine web,
e-mail…) e lo converte in una voce sintetizzata o in Braille. Molti di questi software offrono
anche la possibilità di simulare i movimenti del mouse, ma si basano sulla disponibilità di particolari
informazioni e, in genere, l'uso di questa funzionalità è inefficiente. Pacchetti software non
accessibili costituiscono un problema insormontabile per qualsiasi
screen reader.
Per esempio, l'uso di
toolbar senza un metodo alternativo per ottenere lo stesso
risultato tramite la tastiera o una voce del menù, diminuirà drasticamente la fruibilità del software
per un utente ipovedente (sempre ammesso che lo
screen reader sia in grado di
identificare il contenuto della
toolbar).
Col termine programma accessibile intendiamo un software che presenta dati ed interfaccia in un modo
comprensibile allo
screen reader e permetta di sfruttare tutte le sue funzionalità
interamente tramite tastiera. Oggigiorno una gran parte dei programmi funzionanti sotto Windows risulta
abbastanza accessibile. Microsoft, Corel, Mozilla Foundation ed altre aziende sostengono che
l'accessibilità non è importante solo per le persone ipovedenti, ma presenta ricadute benefiche per
qualsiasi utente.
In che modo integrare BDS ed accessibilità?
Borland ha progettato le librerie
VCL in modo che
risultino completamente compatibili con le Microsoft Foundation Class. Quasi tutti gli
screen reader richiedono, per il loro funzionamento, un'organizzazione gerarchica
degli elementi dell'interfaccia.
Un dialog, per esempio, può avere uno o più elementi figli: bottoni, check box, edit… Gli
screen reader inviano un insieme di messaggi, standardizzato, ad una finestra per
richiederne le proprietà e verificarne lo stato. Per esempio un Edit control potrebbe essere multi linea
o in uno stato di sola lettura; una Checkbox selezionata, non selezionata od in un terzo stato. La classi
della libreria VCL si comportano in maniera analoga alle
MFC: rispondono agli stessi messaggi nello stesso
modo. Così è sufficiente che uno
screen reader sappia di poter mandare lo stesso
messaggio ad una MFC Edit e ad una TEdit perché la risposta sia virtualmente identica (ci sono alcune
eccezioni che menzioneremo in seguito).
Ci sono degli svantaggi se utilizzo il C++ al posto di Delphi?
No. Utilizzando il C++Builder, si utilizzano gli stessi elementi delle librerie VCL e si possono adottare
le stesse tecniche descritte per Delphi.
VCL per Win32
Dato che risultano disponibili da tempo, cominceremo con l'analisi delle librerie VCL per Win32 (sono state
introdotte con Delphi 1, ma la struttura generale è rimasta invariata con il Borland Developer Studio 2006).
Consigli generali
Come già accennato, molti
screen reader sfruttano l'organizzazione gerarchica delle
finestre per ottenere informazioni sia sul layout che sulle reciproche relazioni. Bisogna ricordare che ogni
elemento visibile è una finestra, anche se non ha un frame o una barra del titolo. Infatti ha, ed è l'aspetto
fondamentale, un window handle registrato dal sistema operativo ed utilizzato come riferimento dallo
screen reader per interagire con l'elemento.
Nel disegnare l'interfaccia utente, bisogna assicurarsi di rispettare le seguenti regole generali.
Il "tab order"
Verificare che tutti gli elementi siano nell'ordine giusto: selezionare la form da controllare e, premendo
ripetutamente il tasto TAB, osservare come si sposta il focus (tab order). Gli elementi che non sono nel tab order
previsto non sono facilmente accessibili mediante la sola tastiera.
Non impostare TabStop a TRUE per tutti gli elementi visibili
È importante che l'utente possa raggiungere tutti gli elementi tramite il tasto TAB, purché si tratti di
elementi dell'interfaccia con cui sia possibile interagire. Alcune applicazioni, per esempio, permettono di
selezionare gli elementi TPanel tramite la tastiera. I TPanel servono per organizzare graficamente l'interfaccia, ma
non sono identificabili tramite un proprio nome. Così quando vengono selezionati non c'è un modo univoco per avvertire
l'utente ipovedente (lo
screen reader rimarrà nel più completo silenzio). Inoltre, visto che non
c'è possibilità di interazione col TPanel, tutti gli utenti non avranno un'indicazione visiva del punto di inserimento
attivo (focus).
Durante la verifica di un'applicazione ci si dovrebbe assicurare che non si verifichino situazioni di questo genere,
noiose per tutti.
Etichettare opportunamente gli elementi
Gli oggetti TLabel e TStaticText devono precedere immediatamente, nel tab order, gli elementi a cui fanno riferimento.
Questo accorgimento è importante perché molti
screen reader utilizzano il tab order per associare
le etichette agli elementi TLabel e alle list box. La differenza fra un TLabel ed un TStaticText sta nel fatto che
quest'ultimo si registra con un proprio
window handle. Teoricamente un oggetto TStaticText è la
miglior scelta se si vuol esser sicuri che l'etichetta venga individuata. In realtà test recenti effettuati con TLabeledEdit
hanno evidenziato risultati soddisfacenti indipendentemente dalla disposizione delle etichette. L'etichetta descrittiva
dovrebbe esser posta alla sinistra del campo inserimento dati cui fa riferimento. Questo accorgimento facilita il compito
degli
screen reader, così come degli utenti che fanno uso di display Braille (etichetta e testo inserito
possono venir consultati contemporaneamente).
Predisporre codici mnemonici
In questo contesto, con la dizione codici mnemonici, si intendono i caratteri sottolineati che compaiono in molte finestre
di dialogo. Premendo il tasto Alt e la lettera sottolineata, viene immediatamente selezionato un elemento dell'interfaccia
grafica. Il codice mnemonico viene definito nella proprietà Caption di un oggetto. La lettera da utilizzare deve esser preceduta
dal carattere "&". Per definire un codice mnemonico destinato ad un oggetto che non abbia una propria Caption, per
esempio un oggetto TEdit, bisogna assegnare all'etichetta del TEdit il codice desiderato e specificare nella proprietà
FocusControl dell'etichetta l'oggetto che si desidera selezionare. Questa procedura può esser utilizzata per TLabel e
TStaticText. Bisogna assicurarsi che all'interno della stessa form non vengano utilizzati più volte gli stessi codici mnemonici.
Invece non ci sono problemi se due oggetti, in form differenti, hanno lo stesso codice mnemonico. La stessa accortezza va
utilizzata per voci all'interno dello stesso menù (non per quelle di due differenti sottomenù o di differenti finestre di drop
down).
Mai lasciare il focus nella "terra di nessuno"
Per esempio, se si predispone un bottone "Apply" che diviene attivo appena si modifica un'opzione e ritorna inattivo
dopo essere stato premuto, bisogna assicurarsi che l'ultima azione del metodo OnClick sia di spostare il focus ad un elemento
attivo dell'interfaccia. L'ideale è scegliere il primo elemento nel tab order. Se non si ripristina il focus, l'utente sarà
costretto a premere più volte Alt+TAB per spostarsi fra le applicazioni attive sperando di tornare in una situazione valida.
Oppure, anche peggio, dovrà ricorrere all'emulazione del mouse per selezionare un elemento attivo e ripristinare i focus.
Assicurarsi che ogni azione sia effettuabile con la tastiera
Progettando la vostra applicazione, assicuratevi che ogni opzione sia selezionabile tramite una combinazione di tasti o una
voce di menù. Offrire una
toolbar all'utente va bene, purché si preveda un meccanismo che permetta di
raggiungere lo stesso scopo con la sola tastiera. Microsoft Word, per esempio, offre all'utente la possibilità di premere
il tasto "New" della
toolbar o ricorrere alla combinazione CTRL+N per ottenere lo stesso
risultato. Bisogna sempre chiedersi se l'opzione appena introdotta possa esser sfruttata con la sola tastiera. Nel dubbio
eseguite la vostra applicazione e tentate di utilizzarla tenendo le mani ben lontane dal mouse.
Raggruppare elementi correlati
Riunire all'interno di un apposito raggruppamento i TRadioButton che riguardano la stessa opzione, senza mischiare i
raggruppamenti. Si possono utilizzare sia i TGroupBox sia i TRadioGroup, assicurandosi che risultino i
"parent control" dei TRadioButton che contengono.
Evitare cambi di focus automatici
Quando si seleziona un TRadioButton, è pratica comune spostare automaticamente il focus su un particolare elemento
dell'interfaccia. Per esempio, in un Print dialog, cliccando su "Print selected pages", il punto di inserimento
potrebbe esser automaticamente spostato su un TEdit destinato a specificare la pagina iniziale. Questo comportamento si
verifica anche quando si utilizza la sola tastiera: con il Tab ci si sposta su un gruppo di TRadioButton, che ha già una voce
selezionata. In Windows, utilizzando i tasti cursore UP o DOWN, si verificheranno due cambi di focus. Il primo selezionando
il TRadioButton, il secondo, automatico e quasi istantaneo, dovuto all'evento OnClick del TRadioButton (che provvederà a
spostare il focus sul TEdit). Gli
screen reader non hanno l'opportunità di segnalare all'utente il
TRadioButton scelto perché il cambio di focus è troppo rapido. Per questa ragione, al posto di predisporre un cambiamento
automatico di focus, si può fare in modo che il focus si sposti all'elemento appropriato dell'interfaccia solo dopo aver
premuto TAB (in base al TRadioButton selezionato). Nel nostro esempio sul TEdit "Pagina iniziale"; invece, nel caso
fosse stata selezionata la voce "Print All", sul TEdit utilizzato per specificare il numero di copie.
Oggetti Non-Standard
Vari oggetti della VCL non hanno una controparte prevista da Microsoft (per esempio TStringGrid o ActionBand). Di seguito ne
analizzeremo alcuni.
TMemo
Il TMemo serve per mostrare grandi blocchi di testo su più linee. È stato pensato per "comportarsi" come un comune TEdit.
Gli
screen reader, solitamente, non hanno problemi ad interagire con questo componente.
TStringGrid
L'oggetto TStringGrid è piuttosto problematico. In particolare la sua struttura tabellare impedisce una semplicemente descrizione da
parte di uno
screen reader. Per esempio non esiste una maniera semplice di associare il contenuto di una cella
con l'intestazione delle colonne. Il meglio che si può fare è assicurarsi di poter raggiungere ogni cella con i tasti cursore e che
la cella venga evidenziata in modo che lo
screen reader possa almeno leggerne il contenuto.
ActionBand
Le considerazioni variano in base alla versione di Delphi, C++Builder o Borland Developer Studio in uso. Col BDS 2006 siamo fortunati:
il componente ActionBand sfrutta una tecnologia detta Microsoft Active Accessibility (MSAA). MSAA permette ai programmatori il
trasferimento di informazioni allo
screen reader tramite canali non visuali. L'interazione è semplice come per
l'etichetta di un TLabel o l'icona di una barra degli strumenti. Un oggetto che supporta MSAA ha proprietà come Name, Value, State,
Description e Hotkey e lo
screen reader può utilizzarle per acquisire utili informazioni, indipendentemente dal
layout grafico dell'oggetto. Le TActionBand sono state introdotte in Delphi 5 e successivamente sviluppate negli anni; purtroppo prima
del rilascio del BDS 2006 risultavano un componente completamente non accessibile.
Nel caso stiate ancora lavorando con una vecchia versione di Delphi e necessitiate di ActionBand accessibili, allora è giunto il momento
di spingere il vostro "boss" ad aggiornare il sistema di sviluppo al BDS 2006.
TSpinEdit, TSpeedButton, TBitBtn
Tutti questi componenti, sebbene privi di una controparte nelle librerie MFC, interagiscono bene con gli
screen reader.
Sviluppare i propri componenti visuali
Sviluppare propri componenti visuali non significa perdere automaticamente in accessibilità. Al contrario, derivazioni da componenti VCL
permettono, solitamente, di ereditarne l'accessibilità. Solo allontanandosi sostanzialmente dall'oggetto base si possono avere problemi.
Ci sono componenti di terze parti che appaiono e si comportano, per lo più, come oggetti standard, ma non gestiscono tutti i messaggi e gli
eventi standard di Windows. Un esempio è TVirtualStringTree, un componente avanzato per la visualizzazione di grafici ad albero, ricco di
numerose utili caratteristiche, che presenta però alcuni problemi. Fra gli altri, quando si apre o chiude un nodo dell'albero, non viene
lanciato l'evento che un componente SysTreeView32 lancerebbe nella stessa situazione. Ancor peggio non viene comunicato allo
screen reader lo stato del nodo (aperto/non aperto) quando richiesto. Anche il supporto per voci selezionabili
dell'albero soffre dello stesso problema: non c'è scambio di informazioni con lo
screen reader.
Nel caso sviluppiate vostri componenti, dovreste considerare l'adozione della tecnologia MSAA, specie quando è evidente la necessità di
comunicare con l'utente tramite colori o icone: quando il cliente richiede l'accessibilità il ricorso a MSAA è la scelta migliore.
VCL per .NET
Le regole che si applicano alle librerie VCL per Win32 si traspongono, generalmente, alla controparte VCL per .NET. Considerate però che
le librerie VCL per .NET sono disponibili da poco tempo rispetto a quelle per Win32 e gli
screen reader potrebbero
interfacciarsi solo in parte. Sviluppando applicazioni VCL .NET, bisogna sperimentare in prima persona od offrire una versione dimostrativa
al cliente così da permettere una valutazione preliminare del prodotto. Si possono anche considerare configurazioni ad hoc con finestre
riprogettate per interfacciarsi correttamente con gli
screen reader.
Se sviluppate applicazioni WinForms in Delphi o C#, potreste già esservi imbattuti nelle proprietà AccName, AccValue, AccRole e
AccDescription. Dato che Microsoft ha sviluppato sia le WinForms che le MSAA, ha deciso di fornire agli sviluppatori un mezzo per
specificare cosa comunicare agli
screen reader. Anche la Borland, introducendo il supporto per le WinForms, ha dato
accesso a queste proprietà, così le applicazioni scritte in Delphi o C# godono delle stesse caratteristiche di accessibilità del Visual C#
e del Visual Basic .NET.
In sostanza valgono le solite regole, con la differenza che potendo specificare, per un TEdit, un "nome accessibile" non c'è più
la necessità di individuare l'etichetta associata. Gli
screen reader di solito utilizzano la tecnologia MSAA ogni volta
che possono e adottano altri sistemi di raccolta informazioni solo in via secondaria.
La proprietà "AccessibleRole" non dovrebbe esser modificata, tranne nel caso in cui si stia sviluppando un proprio componente
WinForm e si desideri comunicare allo
screen reader il tipo di componente.
La proprietà "AccDescription" può esser utilizzata per fornire informazioni supplementari (come fa Microsoft con Office 2007). Gli
screen reader possono trarre vantaggio da questa proprietà e leggerne la descrizione insieme al nome del componente.
Scelte da evitare a tutti i costi
L'unica scelta che porta a creare applicazioni completamente non accessibili è decidere di ricorrere alle librerie CLX (disponibili in alcune
versioni del C++Builder, Delphi e Kylix). I componenti CLX, per non essere legati ad una particolare piattaforma di elaborazione, evitano di
registrarsi con un proprio handle (comportamento tipico in ambiente Windows). Per Windows un'applicazione CLX presenta una sola finestra
visibile; qualsiasi cosa accada all'interno di quella finestra non è visibile dal sistema operativo. I cambi di focus, l'apertura e la
chiusura di menù, la selezione di elementi… sono tutte azioni non monitorabili da Windows e, di conseguenza, dallo
screen reader.
Conclusioni
Abbiamo visto che applicazioni sviluppate basandosi sulle librerie VCL per Win32, VCL per .NET o WinForms, soddisfano immediatamente ed in
gran parte i principali requisiti di accessibilità. Rimangono da seguire alcune linee guida per assicurarsi un ulteriore livello di
accessibilità. La domanda più importante da porsi è: "Posso farlo senza il mouse?".
Le tecniche descritte si possono applicare a design time, ma anche in un secondo momento, allorché sia necessario rendere più accessibile
il software. Nonostante tutto alcuni aspetti richiederanno sempre scelte consce da parte del progettista. Spero che questo articolo porti a
decisioni tali da favorire gli utenti che hanno bisogno di uno
screen reader per utilizzare le vostre applicazioni.
Happy accessible programming!