Partager via


S’assurer que les éléments d’interface utilisateur sont correctement nommés

Cette rubrique décrit la manière correcte de spécifier les noms des éléments d’interface utilisateur dans vos applications Microsoft Win32 afin que Microsoft Active Accessibility puisse exposer avec précision les noms aux applications clientes via la propriété IAccessible Name.

Les informations de cette section s’appliquent uniquement à Microsoft Active Accessibility. Elle ne vise pas les applications qui utilisent Microsoft UI Automation ou celles basées sur des langages de balisage tels que HTML, Dynamic HTML (DHTML) ou XML.

Vue d’ensemble

Dans Microsoft Active Accessibility, chaque élément d’interface utilisateur d’une application est représenté par un objet qui expose l’interface IAccessible. Les applications clientes utilisent les propriétés et méthodes de l’interface IAccessible pour interagir avec l’élément d’interface utilisateur et récupérer des informations à son sujet. L’une des propriétés les plus importantes exposées par l’interface IAccessible est la propriété Nom. Les applications clientes s’appuient sur la propriété Nom pour rechercher, identifier ou annoncer un élément d’interface utilisateur à l’utilisateur. Si Microsoft Active Accessibility ne peut pas exposer correctement la propriété Nom d’un élément d’interface utilisateur donné, les applications clientes ne pourront pas présenter cet élément à l’utilisateur et l’élément sera inaccessible aux utilisateurs en situation de handicap.

Comment un nommage incorrect provoque des problèmes

Pour illustrer les problèmes causés par un nommage incorrect des éléments d’interface utilisateur, considérez le formulaire d’entrée de nom indiqué dans l’illustration suivante.

illustration d’un simple formulaire pour saisir le prénom et le nom de famille

Bien que les éléments de l’interface utilisateur du formulaire semblent corrects, l’implémentation programmatique est inadéquate. Pour un client Microsoft Active Accessibility tel qu’un lecteur d’écran, la propriété Nom du contrôle d’édition supérieur est « Nom : » et la propriété Nom du contrôle d’édition inférieur une chaîne vide («»). Le lecteur d’écran lit le contrôle d’édition supérieur en tant que « Nom », bien que l’utilisateur soit censé taper le prénom. Le lecteur d’écran lit le deuxième contrôle d’édition comme « aucun nom », de sorte que l’utilisateur n’a aucune idée de ce qu’il faut taper dans le deuxième contrôle d’édition. Le lecteur d’écran ne peut pas aider l’utilisateur à entrer des données dans ce formulaire simple.

Un autre problème avec le formulaire est qu’aucune touche de raccourci n’est attribuée à l’un des contrôles d’édition. L’utilisateur est obligé de tabuler vers les contrôles ou d’utiliser la souris.

Les sections suivantes décrivent la source de ces problèmes et fournissent des instructions pour les corriger.

Comment MSAA obtient la propriété Nom

Microsoft Active Accessibility obtient la chaîne de la propriété Nom à partir de différents emplacements en fonction du type de l’élément d’interface utilisateur. Pour la plupart des éléments d’interface utilisateur qui ont du texte de fenêtre associé, Microsoft Active Accessibility utilise le texte de fenêtre comme chaîne de la propriété Nom. Par exemple, ce type d’élément d’interface utilisateur inclut des contrôles tels que des boutons, des éléments de menu et des info-bulles.

Pour les contrôles suivants, Microsoft Active Accessibility ignore le texte de fenêtre et recherche plutôt une étiquette de texte statique (ou étiquette de zone de groupe) qui précède immédiatement le contrôle dans l’ordre de tabulation.

  • Zones de liste modifiable
  • Sélecteur de date et d’heure
  • Modifier et enrichir des contrôles de modification
  • Contrôles d’adresses IP
  • Zones de liste
  • Modes Liste
  • Barres de progression
  • Barres de défilement
  • Contrôles statiques avec le style SS_ICON ou SS_BITMAP
  • Barres de suivi
  • Arborescences

Si les contrôles précédents ne sont pas accompagnés d’étiquettes de texte statiques ou si les étiquettes ne sont pas implémentées correctement, Microsoft Active Accessibility ne peut pas fournir la propriété Nom correcte aux applications clientes.

La plupart des contrôles précédents ont effectivement du texte de fenêtre associé. L’éditeur de ressources génère automatiquement le texte de fenêtre, qui se compose d’une chaîne générique telle que « edit1 » ou « listbox3 ». Bien que les développeurs puissent remplacer le texte de fenêtre généré par du texte plus pertinent, la plupart ne le font jamais. Étant donné que le texte de fenêtre généré n’a aucune signification pour l’utilisateur, Microsoft Active Accessibility l’ignore et utilise plutôt l’étiquette de texte statique associée.

Comment rechercher et corriger les problèmes relatifs au nommage

Dans le formulaire d’entrée de nom indiqué dans la section Comment un nommage incorrect provoque des problèmes, la cause des problèmes repose sur le mauvais ordre de tabulation des contrôles. L’examen de l’interface utilisateur avec un outil de test tel que Inspect révélerait des problèmes relatifs à la hiérarchie d’objets. La capture d’écran suivante montre la hiérarchie d’objets rompue du formulaire d’entrée de nom tel qu’il apparaît dans Inspect.

capture d’écran de l’outil inspect montrant une hiérarchie d’objets incorrecte du formulaire de saisie de nom

Dans la capture d’écran précédente, notez que la hiérarchie d’objets ne correspond pas à la structure des contrôles tels qu’ils apparaissent dans l’interface utilisateur du formulaire d’entrée de nom. Notez également qu’Inspect a attribué le nom incorrect à l’avant-dernier élément (il s’agit du contrôle d’édition pour entrer le prénom ; il doit être nommé « Prénom : »). Enfin, notez qu’Inspect n’a pas pu trouver de nom pour le dernier élément (il s’agit du contrôle d’édition pour entrer le nom ; il doit être nommé « Nom : »).

L’exemple suivant montre le contenu du fichier de ressources pour le formulaire d’entrée de nom. Notez que l’ordre de tabulation n’est pas cohérent avec la structure logique des contrôles tels qu’ils apparaissent dans l’interface utilisateur. Notez également qu’aucune touche de raccourci n’est spécifiée pour les deux contrôles d’édition.

IDD_INPUTNAME DIALOGEX 22, 17, 312, 118
STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "Enter your name"
FONT 8, "System", 0, 0, 0x0
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,179,35,30,11,WS_GROUP
    LTEXT           "First Name:",IDC_STATIC,8,16,43,8
    LTEXT           "Last Name:",IDC_STATIC,8,33,43,8
    EDITTEXT        IDC_EDIT1,53,15,120,12,ES_AUTOHSCROLL
    EDITTEXT        IDC_EDIT2,53,34,120,12,ES_AUTOHSCROLL
END

Pour corriger les problèmes relatifs au formulaire d’entrée de nom, le fichier de ressource (.rc) doit être modifié afin de spécifier des raccourcis clavier, et les contrôles doivent être placés dans l’ordre suivant :

  1. L’étiquette de texte statique « &First Name: ».
  2. Contrôle d’édition pour entrer le prénom (IDC_EDIT1).
  3. L’étiquette de texte statique « &Last Name: ».
  4. Contrôle d’édition pour entrer le nom (IDC_EDIT2).
  5. Bouton de commande par défaut « OK ».

L’exemple suivant montre le fichier de ressources corrigé pour le formulaire d’entrée de nom :

IDD_INPUTNAME DIALOGEX 22, 17, 312, 118
STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "Enter your name"
FONT 8, "System", 0, 0, 0x0
BEGIN
    LTEXT           "&First Name:",IDC_STATIC,8,16,43,8
    EDITTEXT        IDC_EDIT1,53,15,120,12,ES_AUTOHSCROLL
    LTEXT           "&Last Name:",IDC_STATIC,8,33,43,8
    EDITTEXT        IDC_EDIT2,53,34,120,12,ES_AUTOHSCROLL
    DEFPUSHBUTTON   "OK",IDOK,179,35,30,11,WS_GROUP
END

Pour apporter des corrections à un fichier de ressources, vous pouvez modifier le fichier directement ou utiliser l’outil Ordre de tabulation dans Microsoft Visual Studio. Vous pouvez accéder à l’outil Ordre de tabulation dans Visual Studio en appuyant sur Ctrl+D ou en sélectionnant Ordre de tabulation dans le menu Format.

Après avoir corrigé et régénéré l’application, l’interface utilisateur du formulaire d’entrée de nom se présente comme avant. Toutefois, Microsoft Active Accessibility fournit désormais les propriétés Nom adéquates aux applications clientes et définit la concentration correctement lorsque l’utilisateur appuie sur les raccourcis clavier Alt+F ou Alt+L. En outre, Inspect affiche la hiérarchie d’objets correcte, comme le montre la capture d’écran suivante.

capture d’écran de l’outil accessible explorer montrant une hiérarchie d’objets correcte du formulaire de saisie de nom

Comment nommer correctement une barre de suivi

Lors de la définition d’une barre de suivi (ou d’un curseur), faites en sorte que l’étiquette de texte statique principale de la barre de suivi s’affiche avant la barre et que les étiquettes de texte statiques pour les plages minimales et maximales apparaissent après. N’oubliez pas que Microsoft Active Accessibility utilise l’étiquette de texte statique qui précède immédiatement un contrôle en tant que propriété Nom pour le contrôle. Le placement de l’étiquette de texte statique principale juste avant la barre de suivi et les autres étiquettes après garantit que Microsoft Active Accessibility fournit la propriété Nom correcte à un client.

L’illustration suivante montre une barre de suivi classique avec une étiquette de texte statique principale appelée « Vitesse » et des étiquettes de texte statiques pour les plages minimales (« min ») et maximales (« max »).

illustration d’un contrôle de barre de défilement avec une étiquette principale et des étiquettes pour les plages minimale et maximale

L’exemple suivant montre la bonne façon de définir une barre de suivi et ses étiquettes de texte statiques dans le fichier de ressources :

BEGIN
    ...

    LTEXT           "&Speed",IDC_STATIC,47,20,43,8
    CONTROL         "",IDC_SLIDER1,"msctls_trackbar32",
                    TBS_AUTOTICKS | TBS_BOTH | WS_TABSTOP,
                    32,32,62,23
    LTEXT           "min",IDC_STATIC,16,37,15,8
    LTEXT           "max",IDC_STATIC,94,38,43,8

    ...
END

Comment utiliser des étiquettes invisibles pour nommer des contrôles

Il n’est pas toujours possible ou souhaitable d’avoir une étiquette visible pour chaque contrôle. Par exemple, l’ajout d’étiquettes peut parfois entraîner des modifications indésirables dans l’apparence de l’interface utilisateur. Dans ce cas, vous pouvez utiliser des étiquettes invisibles. Microsoft Active Accessibility récupère toujours le texte associé à une étiquette invisible, mais l’étiquette n’apparaît pas ni n’interfère avec l’interface utilisateur visuelle.

Comme pour les étiquettes visibles, une étiquette invisible doit immédiatement précéder le contrôle dans l’ordre de tabulation. Pour rendre une étiquette invisible dans un fichier de ressources (.rc), ajoutez NOT WS_VISIBLE ou |~WS_VISIBLE à la partie style du contrôle de texte statique. Si vous utilisez l’éditeur de ressources dans Visual Studio, vous pouvez définir la propriété Visible sur False.

Comment utiliser l’annotation directe pour spécifier la propriété Nom

Les proxys par défaut inclus dans le composant d’exécution de Microsoft Active Accessibility, Oleacc.dll, fournissent automatiquement un objet IAccessible pour tous les contrôles Windows standard. Si vous personnalisez un contrôle Windows standard, les proxys par défaut font de leur mieux pour fournir avec précision toutes les propriétés IAccessible pour votre contrôle personnalisé. Vous devez tester soigneusement un contrôle personnalisé pour vous assurer que les proxys par défaut fournissent des valeurs de propriété précises et complètes. Si les tests révèlent des valeurs de propriété inexactes ou incomplètes, vous pouvez utiliser la technique d’annotation dynamique appelée annotation directe pour fournir des valeurs de propriété correctes et ajouter celles manquantes.

Notez que l’annotation dynamique n’est pas uniquement destinée aux contrôles pris en charge par les proxys Microsoft Active Accessibility. Vous pouvez également l’utiliser pour modifier ou fournir des propriétés pour tout contrôle qui fournit sa propre implémentation IAccessible.

Cette section porte sur l’utilisation de l’annotation directe afin de fournir une valeur correcte pour la propriété Nom de l’objet IAccessible pour un contrôle. Vous pouvez également utiliser l’annotation directe pour fournir d’autres valeurs de propriétés. En outre, d’autres techniques d’annotation dynamique en plus de l’annotation directe sont disponibles. Par ailleurs, les fonctionnalités et les capacités de l’API d’annotation dynamique s’étendent bien au-delà de ce qui est décrit dans cette section. Pour plus d’informations sur l’annotation dynamique, consultez l’API Annotation dynamique.

Étapes d’annotation de la propriété Nom

L’utilisation d’une annotation directe pour modifier la propriété Nom d’un contrôle implique les étapes suivantes.

  1. Incluez les fichiers d’en-tête suivants :

    • Initguid.h
    • Oleacc.h

    Remarque

    Pour définir des GUID, vous devez inclure Initguid.h avant Oleacc.h dans le même fichier.

     

  2. Initialisez la bibliothèque COM (Component Object Model) en appelant la fonction CoInitializeEx, généralement pendant le processus d’initialisation de l’application.

  3. Peu après la création du contrôle cible (généralement pendant le message WM_INITDIALOG), créez une instance du gestionnaire d’annotations et obtenez un pointeur vers son pointeur IAccPropServices.

  4. Annotez la propriété Nom du contrôle cible à l’aide de la méthode IAccPropServices::SetHwndPropStr.

  5. Relâchez le pointeur IAccPropServices.

  6. Avant la destruction du contrôle cible (généralement lors de la gestion du message WM_DESTROY), créez une instance du gestionnaire d’annotations et obtenez un pointeur vers son interface IAccPropServices.

  7. Utilisez la méthode IAccPropServices::ClearHwndProps pour effacer les annotations de la propriété Nom du contrôle cible.

  8. Relâchez le pointeur IAccPropServices.

  9. Avant de quitter votre application (généralement lors du traitement du message WM_DESTROY), relâchez la bibliothèque COM en appelant la fonction CoUninitialize.

La fonction IAccPropServices::SetHwndPropStr prend en charge cinq paramètres. Les trois premiers (hwnd, idObject et idChild) se combinent pour identifier le contrôle. Le quatrième paramètre, idProp, spécifie l’identificateur de la propriété à modifier. Pour modifier la propriété Nom, définissez idProp sur PROPID_ACC_Nom. (Pour obtenir une liste des autres propriétés que vous pouvez définir via l’annotation directe, consultez Utilisation de l’annotation directe.) Le dernier paramètre de SetHwndPropStr, str, est la nouvelle chaîne à utiliser comme propriété Nom.

Exemple d’annotation de la propriété Nom

L’exemple de code suivant montre comment utiliser l’annotation directe afin de modifier la propriété Nom de l’objet IAccessible pour un contrôle. En bref, l’exemple utilise une chaîne codée en dur (« Nouveau nom de contrôle ») pour définir la propriété Nom. Les chaînes codées en dur ne doivent pas être utilisées dans la version finale de votre application, car elles ne peuvent pas être localisées. Au lieu de cela, chargez toujours des chaînes à partir de votre fichier de ressources. En outre, l’exemple ne montre pas les appels aux fonctions CoInitializeEx et CoUninitialize .

#include <initguid.h>
#include <oleacc.h>

// AnnotateControlName - Uses direct annotation to change the Name property 
// of the IAccessible object for a control.
//
// hDlg - Handle of the dialog box that contains the control.
// hwndCtl - Handle of the control whose Name property is to be changed.
HRESULT AnnotateControlName(HWND hDlg, HWND hwndCtl)
{
    HRESULT hr;        

    IAccPropServices *pAccPropSvc = NULL;  

    // Create an instance of the annotation manager and retrieve the 
    // IAccPropServices pointer.
    hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, 
        IID_IAccPropServices, (void **) &pAccPropSvc);

    if (hr != S_OK || pAccPropSvc == NULL)
        return hr;

    // Set the Name property for the control.
    // Note: A hard-coded string is used here to keep the example simple.
    // Always use localizable string resources in your applications. 
    hr = pAccPropSvc->SetHwndPropStr(hwndCtl, OBJID_CLIENT, CHILDID_SELF, 
        PROPID_ACC_NAME, L"New Control Name");

    pAccPropSvc->Release();
    
    return hr;
}

// RemoveAnnotatedNameFromControl - Removes the annotated name from the 
// Name property of the IAccessible object for a control.
//
// hDlg - Handle of the dialog box that contains the control.
// hwndCtl - Handle of the control whose annotated name is to be removed.
HRESULT RemoveAnnotatedNameFromControl(HWND hDlg, HWND hwndCtl)
{
    HRESULT hr;

    IAccPropServices *pAccPropSvc = NULL;

    // Create an instance of the annotation manager and retrieve the 
    // IAccPropServices pointer.
    hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, 
        IID_IAccPropServices, (void **) &pAccPropSvc);

    if (hr != S_OK || pAccPropSvc == NULL)
        return hr;

    // Remove the annotated name from the Name property for the control.
    MSAAPROPID propid = PROPID_ACC_NAME;
    hr = pAccPropSvc->ClearHwndProps(hwndCtl, OBJID_CLIENT, CHILDID_SELF, 
        &propid, 1);

    // Release the annotation manager.
    pAccPropSvc->Release();

    return hr;
}