Alternativ till dynamisk anteckning
Det finns andra sätt att tillhandahålla anpassade IAccessible stöd för gränssnittselement, och i vissa fall är de rätt lösning. Före dynamisk anteckning var dessa alternativa tekniker de enda tillgängliga alternativen för utvecklare. De omfattar implementering av alla IAccessible- gränssnitt och programmeringstekniker.
Implementera allt IAccessible-gränssnitt
En alternativ teknik är att implementera alla IAccessible-gränssnittet. Den här metoden är ofta nödvändig för anpassade kontroller eller radikalt olika gränssnittselement. Utvecklings- och testkostnaderna är dock tillräckligt stora för att undvikas om det inte verkligen är nödvändigt. Om målet är att ändra en enskild egenskap är kostnaden svår att motivera.
Programmeringstekniker
Ett annat alternativ är att använda underklassnings- och omslutningstekniker för att ändra informationen som exponeras för en specifik egenskap. Det här är den teknik som dynamisk anteckning är avsedd att ersätta. Om du vill åsidosätta en enskild egenskap med hjälp av underklass och omslutning måste utvecklaren utföra följande steg:
- UnderklassA HWND för objektet IAccessible.
- Fånga upp WM_GETOBJECT meddelande för rätt IParam/OBJID-värde.
- Vidarebefordra meddelandet WM_GETOBJECT till basklassen med hjälp av funktionen CallWndProc motringning. Om noll returneras anropar du CreateStdAccessibleObject; Annars anropar du LresultFromObject på det returnerade värdet för att hämta kontrollens interna IAccessible gränssnittspekare.
- Skapa en omslutningsklass som implementerar IAccessible och omsluter den IAccessible- gränssnittspekaren som returnerades från föregående steg. Den här omslutningsklassen skickar alla metoder och egenskaper till den ursprungliga IAccessible- gränssnittspekare, förutom de som ska åsidosättas. Detta innebär att skriva vidarebefordran av kod för alla IAccessible gränssnittets 21 egenskaper och metoder, oavsett hur många som faktiskt åsidosättas.
Utvecklare måste också kontrollera följande villkor:
- Den åsidosatta metoden eller egenskapen får endast hantera nödvändiga underordnade ID:er och vidarebefordra alla andra till den ursprungliga IAccessible gränssnittspekare.
- Omslutning måste också vidarebefordra IEnumVARIANT- och IOleWindow-gränssnitt endast om det ursprungliga objektet stöder dem.
- Referensräkning måste hanteras korrekt, särskilt om andra gränssnitt stöds.
- IDispatch returvärden måste hanteras korrekt, särskilt med metoden ITypeInfo::Invoke, som måste anropas med en gränssnittspekare till omslutningsgränssnittet, inte en pekare till det ursprungliga IAccessible-gränssnittet.
Dessa tekniker kräver en betydande mängd arbete, även om endast en eller två egenskaper måste åsidosättas. Merparten av den resulterande koden handlar om underklass och omslutning, och endast en liten del tillhandahåller faktiskt den åsidosatta informationen.
Det finns dock scenarier där dessa tekniker behövs. Om du till exempel gör strukturella ändringar för att skapa ett platshållargränssnittselement bör du använda dessa tekniker i stället för dynamisk anteckning.
Åtgärda namn som härletts från etiketter
Vissa vanliga Microsoft Win32-kontroller, till exempel redigeringsrutekontrollen, används nästan alltid med en etikett (en LTEXT-post i resursfilen) eller en gruppruta (GROUPBOX i resursfilen). Microsoft Active Accessibility härleder automatiskt namnegenskapen för kontrollen från etiketten. För sådana kontroller ignoreras fönstertexten (som visas i Microsoft Visual Studio som egenskapen Namn eller ID) eftersom den vanligtvis genereras automatiskt och sällan är mycket beskrivande. till exempel "IDC_EDIT1".
Om användargränssnittet för programmet inte är korrekt utformat kanske Microsoft Active Accessibility inte kan ange namnet korrekt. För att associeras med en kontroll måste etiketten eller grupprutan placeras omedelbart före den dynamiska kontrollen i tabbordningen.
Tabbordningen kan ändras med hjälp av verktyget i Visual Studio (på menyn Format när resursredigeraren är öppen) eller genom att redigera resursfilen direkt.
I följande exempel visas en resursfils beskrivning av en dialogruta som innehåller två etiketterade redigeringsrutor.
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_EDITFIRSTNAME,53,15,120,12,ES_AUTOHSCROLL
EDITTEXT IDC_EDITLASTNAME,53,34,120,12,ES_AUTOHSCROLL
END
I det här exemplet visas inte etiketterna och kontrollerna i rätt flikordning. Därför tilldelar Microsoft Active Accessibility namnet "Efternamn" till förnamnsredigeringsrutan och inget namn alls till redigeringsrutan för efternamn.
I följande exempel visas rätt resurslista. Observera också att kortkommandon har angetts i etiketterna.
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_EDITFIRSTNAME,53,15,120,12,ES_AUTOHSCROLL
LTEXT "&Last Name:",IDC_STATIC,8,33,43,8
EDITTEXT IDC_EDITLASTNAME,53,34,120,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,179,35,30,11,WS_GROUP
END
När kontroller har kompletterande etiketter, till exempel för lägsta och högsta värden i ett spårfält, bör dessa etiketter placeras efter kontrollen i tabbordningen. Kontrollens huvudetikett måste visas omedelbart före själva kontrollen.
Namngivningskontroller utan etiketter
Det är inte alltid möjligt eller önskvärt att ha en synlig etikett för varje kontroll. Du kan dock fortfarande ange ett namn för kontrollen genom att lägga till en osynlig etikett. Som alltid måste den osynliga etiketten omedelbart föregå kontrollen i tabbordningen.
Om du använder resursredigeraren i Microsoft Visual Studio .NET kan du ange egenskapen Visible till False. Om du vill göra etiketten osynlig när du redigerar resursfilen (.rc) lägger du till NOT WS_VISIBLE eller till formatdelen av etikettkontrollen, som du ser i följande exempel.
LTEXT "&FullName:",IDC_STATIC,111,23,44,8,NOT WS_VISIBLE
Observera att alla avsedda kortkommandon fungerar även om etiketten är osynlig.