Sicherstellen, dass UI-Elemente ordnungsgemäß benannt sind

In diesem Thema wird die richtige Methode beschrieben, um die Namen der UI-Elemente in Ihren Microsoft Win32-Anwendungen anzugeben, damit Microsoft Active Accessibility die Namen über die IAccessName-Eigenschaft genau verfügbar machen kann.

Die Informationen in diesem Abschnitt gelten nur für Microsoft Active Accessibility. Es gilt nicht für Anwendungen, die Microsoft Benutzeroberflächenautomatisierung oder diese basierend auf Markupsprachen wie HTML, Dynamic HTML (DHTML) oder XML verwenden.

Übersicht

In Microsoft Active Accessibility wird jedes UI-Element in einer Anwendung durch ein Objekt dargestellt, das die I Access-Schnittstelle verfügbar macht. Clientanwendungen verwenden die Eigenschaften und Methoden der IAccessible-Schnittstelle , um mit dem UI-Element zu interagieren und Informationen darüber abzurufen. Eine der wichtigsten Eigenschaften, die über die IAccessible-Schnittstelle verfügbar gemacht werden, ist die Name-Eigenschaft. Clientanwendungen basieren auf der Name-Eigenschaft, um ein UI-Element für den Benutzer zu finden, zu identifizieren oder anzugeben. Wenn Microsoft Active Accessibility die Name-Eigenschaft eines bestimmten UI-Elements nicht ordnungsgemäß verfügbar machen kann, können Clientanwendungen dieses UI-Elements nicht dem Benutzer präsentieren, und das UI-Element ist für Benutzer mit Behinderungen nicht zugänglich.

Wie falsche Benennung Probleme verursacht

Um die Probleme zu veranschaulichen, die durch falsche Benennung von UI-Elementen verursacht werden, sollten Sie das in der folgenden Abbildung gezeigte Namenseintragsformular berücksichtigen.

illustration of a simple form for entering first and last name

Obwohl die UI-Elemente im Formular okay aussehen, ist die programmgesteuerte Implementierung falsch. Für einen Microsoft Active Accessibility-Client wie z. B. eine Sprachausgabe ist die Name-Eigenschaft des oberen Bearbeitungssteuerelements "Nachname:", und die Name-Eigenschaft des unteren Bearbeitungssteuerelements ist eine leere Zeichenfolge (""). Die Sprachausgabe liest das oberste Bearbeitungssteuerelement als "Nachname", obwohl der Benutzer den Vornamen eingeben soll. Die Sprachausgabe liest das zweite Bearbeitungssteuerelement als "kein Name", sodass der Benutzer keine Idee hat, was in das zweite Bearbeitungssteuerelement eingegeben werden soll. Die Sprachausgabe kann dem Benutzer nicht helfen, Daten in dieses einfache Formular einzugeben.

Ein weiteres Problem mit dem Formular besteht darin, dass keine Tastenkombinationen einem der Bearbeitungssteuerelemente zugewiesen werden. Der Benutzer wird gezwungen, entweder auf der Registerkarte auf die Steuerelemente zu wechseln oder die Maus zu verwenden.

In den folgenden Abschnitten werden die Quelle dieser Probleme erläutert und Richtlinien für die Korrektur bereitgestellt.

So ruft MSAA die Name-Eigenschaft ab.

Microsoft Active Accessibility ruft die Name-Eigenschaftszeichenfolge von verschiedenen Speicherorten abhängig vom Typ des UI-Elements ab. Für die meisten UI-Elemente, die den zugeordneten Fenstertext haben, verwendet Microsoft Active Accessibility den Fenstertext als Name-Eigenschaftszeichenfolge. Beispiele für dieses Ui-Element enthalten Steuerelemente wie Schaltflächen, Menüelemente und QuickInfos.

Für die folgenden Steuerelemente ignoriert Microsoft Active Accessibility den Fenstertext und sucht stattdessen direkt vor dem Steuerelement in der Registerkartenreihenfolge nach einer statischen Textbezeichnung (oder Gruppenfeldbezeichnung).

  • Kombinationsfelder
  • Datums- und Uhrzeitauswahl
  • Steuerelemente "Bearbeiten" und "Rich Edit"
  • IP-Adresssteuerelemente
  • Listenfelder
  • Listenansichten
  • Statusanzeigen
  • Bildlaufleisten
  • Statische Steuerelemente mit SS_ICON oder SS_BITMAP Formatvorlage
  • Trackbars
  • Strukturansichten

Wenn die vorherigen Steuerelemente nicht mit statischen Textbeschriftungen begleitet werden oder die Bezeichnungen nicht ordnungsgemäß implementiert werden, kann Microsoft Active Accessibility die richtige Name-Eigenschaft nicht für Clientanwendungen bereitstellen.

Die meisten der vorherigen Steuerelemente verfügen tatsächlich über zugeordneten Fenstertext. Der Ressourcen-Editor generiert automatisch den Fenstertext, der aus einer generischen Zeichenfolge wie "edit1" oder "listbox3" besteht. Obwohl Entwickler den generierten Fenstertext durch aussagekräftigeren Text ersetzen können, tun die meisten nie. Da der generierte Fenstertext für den Benutzer keine Bedeutung hat, ignoriert Microsoft Active Accessibility es und verwendet stattdessen die zugehörige statische Textbeschriftung.

Suchen und Korrigieren von Benennungsproblemen

Im Nameneintragsformular, das in "Fehler beim Benennen" angezeigt wird, ist die Ursache der Probleme, dass die Registerkartenreihenfolge der Steuerelemente falsch ist. Das Untersuchen der Benutzeroberfläche mit einem Testtool, z. B. Inspect , zeigt die Probleme mit der Objekthierarchie auf. Im folgenden Screenshot wird die gebrochene Objekthierarchie des Nameneintragsformulars angezeigt, wie sie in "Überprüfen" angezeigt wird.

screen shot of the inspect tool showing an incorrect object hierarchy of the name entry form

Beachten Sie im vorherigen Screenshot, dass die Objekthierarchie nicht mit der Struktur der Steuerelemente übereinstimmt, da sie in der Benutzeroberfläche des Nameneintragsformulars angezeigt werden. Beachten Sie auch, dass Die Überprüfung den falschen Namen dem nächsten zu letzten Element zugewiesen hat (es ist das Bearbeitungssteuerelement für die Eingabe des Vornamens und sollte ein Name "Vorname:" sein. Beachten Sie schließlich, dass die Überprüfung keinen Namen für das letzte Element finden konnte (es ist das Bearbeitungssteuerelement für die Eingabe des Nachnamens und sollte einen Namen von "Nachname:" haben.

Im folgenden Beispiel wird der Inhalt der Ressourcendatei für das Nameneintragsformular dargestellt. Beachten Sie, dass die Registerkartenreihenfolge nicht mit der logischen Struktur der Steuerelemente konsistent ist, da sie in der Benutzeroberfläche angezeigt werden. Beachten Sie auch, dass für die beiden Bearbeitungssteuerelemente keine Tastenkombinationen angegeben werden.

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

Um die Probleme mit dem Nameneintragsformular zu beheben, sollte die Ressource (RC)-Datei bearbeitet werden, um Tastenkombinationen anzugeben, und die Steuerelemente sollten in der folgenden Reihenfolge platziert werden:

  1. Die statische Textbezeichnung "&Vorname:".
  2. Das Bearbeitungssteuerelement zum Eingeben des Vornamens (IDC_EDIT1).
  3. Die statische Textbezeichnung "&Nachname:"
  4. Das Bearbeitungssteuerelement zum Eingeben des Nachnamens (IDC_EDIT2).
  5. Die Standard-Pushschaltfläche "OK".

Im folgenden Beispiel wird die korrigierte Ressourcendatei für das Nameneintragsformular gezeigt:

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

Um Korrekturen an einer Ressourcendatei vorzunehmen, können Sie entweder die Datei direkt bearbeiten oder das Tabstoppreihenfolge-Tool in Microsoft Visual Studio verwenden. Sie können entweder auf das Tool "Tabstoppreihenfolge" in Visual Studio zugreifen, indem Sie STRG+D drücken oder die Tabstoppreihenfolge im Menü "Format" auswählen.

Nach der Korrektur und Neuerstellung der Anwendung sieht die Benutzeroberfläche des Nameneintragsformulars genauso aus wie zuvor. Microsoft Active Accessibility stellt nun jedoch die richtigen Nameneigenschaften für Clientanwendungen bereit und legt den Fokus richtig fest, wenn der Benutzer die TASTENkombinationEN ALT+F oder ALT+L drückt. Außerdem wird die richtige Objekthierarchie angezeigt, wie im folgenden Screenshot dargestellt wird.

screen shot of the accessible explorer tool showing a correct object hierarchy of the name entry form

So benennen Sie eine Trackleiste ordnungsgemäß

Stellen Sie beim Definieren einer Trackleiste (oder Schieberegler) sicher, dass die Haupttextbeschriftung für die Trackleiste vor der Trackleiste angezeigt wird, und dass die statischen Textbeschriftungen für die Mindest- und Maximalbereiche nach der Trackleiste angezeigt werden. Denken Sie daran, dass Microsoft Active Accessibility die statische Textbeschriftung verwendet, die sofort einem Steuerelement als Name-Eigenschaft für das Steuerelement vorausgeht. Wenn Sie die Haupttextbeschriftung unmittelbar vor der Trackleiste platzieren, und die anderen Bezeichnungen nach dieser Bezeichnung stellen sie sicher, dass Microsoft Active Accessibility die richtige Name-Eigenschaft für einen Client bereitstellt.

Die folgende Abbildung zeigt eine typische Trackleiste mit einer statischen Textbeschriftung namens "Geschwindigkeit" und statische Textbeschriftungen für die Mindestbereiche ("min") und maximal ("max").

illustration of a trackbar control that has a main label and labels for the minimum and maximum ranges

Das folgende Beispiel zeigt die richtige Methode zum Definieren einer Trackleiste und der statischen Textbeschriftungen in der Ressourcendatei:

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

So verwenden Sie unsichtbare Bezeichnungen zum Benennen von Steuerelementen

Es ist nicht immer möglich oder wünschenswert, eine sichtbare Bezeichnung für jedes Steuerelement zu haben. Das Hinzufügen von Bezeichnungen kann z. B. unerwünschte Änderungen an der Darstellung der Benutzeroberfläche verursachen. In diesem Fall können Sie unsichtbare Bezeichnungen verwenden. Microsoft Active Accessibility übernimmt weiterhin den Text, der einer unsichtbaren Bezeichnung zugeordnet ist, aber die Bezeichnung wird nicht in der visuellen Benutzeroberfläche angezeigt oder beeinträchtigt.

Wie bei sichtbaren Bezeichnungen muss eine unsichtbare Bezeichnung sofort dem Steuerelement in der Registerkartenreihenfolge vorangehen. Um eine Bezeichnung in einer Ressourcendatei (RC) unsichtbar zu machen, fügen NOT WS_VISIBLE Sie den Formatvorlagenteil des statischen Textsteuerelements hinzu oder |~WS_VISIBLE zu. Wenn Sie den Ressourcen-Editor in Visual Studio verwenden, können Sie die Visible-Eigenschaft auf False festlegen.

So verwenden Sie direct Annotation, um die Name-Eigenschaft anzugeben

Die standardmäßigen Proxies, die in der Microsoft Active Accessibility-Laufzeitkomponente enthalten sind, Oleacc.dll, stellen automatisch ein I Access-Objekt für alle standardmäßigen Windows Steuerelemente bereit. Wenn Sie ein Standard-Windows-Steuerelement anpassen, tun die Standard-Proxies ihr Bestes, um alle IAccessible-Eigenschaften für Ihr angepasstes Steuerelement genau bereitzustellen. Sie sollten ein angepasstes Steuerelement gründlich testen, um sicherzustellen, dass die Standardproxys genaue und vollständige Eigenschaftenwerte bereitstellen. Wenn Tests ungenaue oder unvollständige Eigenschaftenwerte anzeigt, können Sie möglicherweise die dynamische Anmerkungsmethode verwenden, die direkte Anmerkungen genannt wird, um korrekte Eigenschaftenwerte bereitzustellen und diese hinzuzufügen, die fehlen.

Beachten Sie, dass dynamische Anmerkungen nicht nur für Steuerelemente verwendet werden, die von den Microsoft Active Accessibility-Proxies unterstützt werden. Sie können es auch verwenden, um Eigenschaften für jedes Steuerelement zu ändern oder bereitzustellen, das eine eigene IAccessible-Implementierung bereitstellt.

Dieser Abschnitt konzentriert sich auf die Verwendung von direkten Anmerkungen, um einen richtigen Wert für die Name-Eigenschaft des IObject-Objekts für ein Steuerelement bereitzustellen. Sie können auch direkte Anmerkungen verwenden, um andere Eigenschaftenwerte bereitzustellen. Außerdem sind andere dynamische Anmerkungstechniken neben direkten Anmerkungen verfügbar, und die Features und Funktionen der Dynamischen Anmerkungs-API erweitern weit über das beschriebene Abschnitt hinaus. Weitere Informationen zu dynamischer Anmerkungen finden Sie unter Dynamic Annotation API.

Schritte zum Annotieren der Name-Eigenschaft

Die Direkte Anmerkung zum Ändern der Name-Eigenschaft eines Steuerelements umfasst die folgenden Schritte.

  1. Fügen Sie die folgenden Headerdateien ein:

    • Initguid.h
    • Oleacc.h

    Hinweis

    Um GUIDs zu definieren, müssen Sie Initguid.h vor Oleacc.h in derselben Datei einschließen.

     

  2. Initialisieren Sie die Komponentenobjektmodellbibliothek (COM), indem Sie die CoInitializeEx-Funktion aufrufen, in der Regel während des Anwendungs initialisierungsprozesses.

  3. Bald nachdem das Zielsteuerelement erstellt wurde (in der Regel während der WM_INITDIALOG Nachricht), erstellen Sie eine Instanz des Anmerkungen-Managers und erhalten einen Zeiger auf den IAccPropServices-Zeiger .

  4. Annotieren Sie die Name-Eigenschaft des Zielsteuerelements mithilfe der IAccPropServices::SetHwndPropStr-Methode .

  5. Freigeben des IAccPropServices-Zeigers .

  6. Bevor das Zielsteuerelement zerstört wird (in der Regel beim Behandeln der WM_DESTROY Nachricht), erstellen Sie eine Instanz des Anmerkungen-Managers und erhalten einen Zeiger auf die IAccPropServices-Schnittstelle .

  7. Verwenden Sie die IAccPropServices::ClearHwndProps-Methode , um die Namen-Eigenschaftsanmerkungen aus dem Zielsteuerelement zu löschen.

  8. Freigeben des IAccPropServices-Zeigers .

  9. Bevor Ihre Anwendung beendet wird (in der Regel während der Verarbeitung der WM_DESTROY Nachricht), veröffentlichen Sie die COM-Bibliothek, indem Sie die Funktion "CoUninitialize " aufrufen.

Die Funktion "IAccPropServices::SetHwndPropStr " verwendet fünf Parameter. Die ersten drei – hwnd, idObject und idChild – kombinieren, um das Steuerelement zu identifizieren. Der vierte Parameter, idProp, gibt den Bezeichner der zu ändernden Eigenschaft an. Um die Name-Eigenschaft zu ändern, legen Sie idProp auf PROPID_ACC_NAME fest. (Eine Liste anderer Eigenschaften, die Sie über direkte Anmerkungen festlegen können, finden Sie unter Verwenden von Direct Annotation.) Der letzte Parameter von SetHwndPropStr, str, ist die neue Zeichenfolge, die als Name-Eigenschaft verwendet werden soll.

Beispiel für die Annotierung der Name-Eigenschaft

Im folgenden Beispielcode wird gezeigt, wie Sie direkte Anmerkungen verwenden, um die Name-Eigenschaft des IObject-Objekts für ein Steuerelement zu ändern. Um dinge einfach zu halten, verwendet das Beispiel eine hart codierte Zeichenfolge ("Neuer Steuerelementname") zum Festlegen der Name-Eigenschaft. Hartcodierte Zeichenfolgen sollten nicht in der endgültigen Version Ihrer Anwendung verwendet werden, da sie nicht lokalisiert werden können. Laden Sie stattdessen immer Zeichenfolgen aus Ihrer Ressourcendatei. Außerdem zeigt das Beispiel die Aufrufe der Funktionen CoInitializeEx und CoUninitialize nicht an.

#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;
}

Konzept

Dynamische Anmerkungs-API

Bereitstellen der Name-Eigenschaft

Testtools