Active Accessibility och Windows Vista-skärmskalning
Med Windows Vista kan användarna ändra dpi-inställningen (dots-per-inch) så att de flesta gränssnittselement på skärmen visas större. Även om den här funktionen länge har varit tillgänglig i Microsoft Windows, var skalningen i tidigare versioner tvungen att implementeras av program. I Windows Vista utför Skrivbordsfönsterhanteraren standardskalning för alla program som inte hanterar sin egen skalning. Microsoft Active Accessibility-klientprogram måste ta hänsyn till den här funktionen.
Skalning i Windows Vista
Standardinställningen för dpi är 96, vilket innebär att 96 bildpunkter upptar en bredd eller höjd på en teoretisk tum. Det exakta måttet på en "tum" beror på bildskärmens storlek och fysiska upplösning. På en bildskärm som till exempel är 12 tum bred, med en vågrät upplösning på 1 280 bildpunkter, utökar en vågrät linje på 96 bildpunkter cirka 9/10 tum.
Att ändra dpi-inställningen är inte samma sak som att ändra skärmupplösningen. Med dpi-skalning förblir antalet fysiska pixlar på skärmen detsamma. Skalning tillämpas dock på storleken och platsen för gränssnittselement. Den här skalningen kan utföras automatiskt av Desktop Window Manager (DWM) för skrivbordet och för program som inte uttryckligen ber om att inte skalas.
När användaren i själva verket anger skalningsfaktorn till 120 dpi blir en lodrät eller vågrät tum på skärmen större med 25 procent. Alla dimensioner skalas därefter. Förskjutningen av ett fönster från skärmens övre och vänstra kanter ökar med 25 procent. Fönstrets storlek ökar i samma proportion, och även placeringar och storlekar för alla UI-element som det innehåller.
Som standard utför DWM inte skalning för icke-dpi-medvetna program när användaren anger dpi till 120, men utför det när dpi är inställt på ett anpassat värde på 144 eller högre. Användaren kan dock åsidosätta standardbeteendet.
Skärmskalning skapar nya utmaningar för program som på något sätt berörs av skärmkoordinater. Skärmen innehåller nu två koordinatsystem: fysiska och logiska. De fysiska koordinaterna för en punkt är den faktiska förskjutningen i bildpunkter uppifrån till vänster om ursprunget. De logiska koordinaterna är förskjutningarna som de skulle vara om själva bildpunkterna skalades.
Anta att du utformar en dialogruta med en knapp vid koordinater (100, 48). När den här dialogrutan visas med standardvärdet 96 dpi finns knappen vid fysiska koordinater på (100, 48). Vid 120 dpi finns den vid fysiska koordinater på (125, 60). Men de logiska koordinaterna är samma vid alla dpi-inställningar: (100, 48).
Logiska koordinater är viktiga eftersom de gör operativsystemets och programmens beteende konsekvent oavsett dpi-inställningen. Till exempel returnerar System.Windows.Forms.Cursor.Position normalt de logiska koordinaterna. Om du flyttar markören över ett element i en dialogruta returneras samma koordinater oavsett dpi-inställningen. Om du ritar en kontroll vid (100, 100) ritas den till de logiska koordinaterna och upptar samma relativa position vid valfri dpi-inställning.
Skalning i aktiva tillgänglighetsklienter
Microsoft Active Accessibility använder inte logiska koordinater. Följande metoder och funktioner returnerar antingen fysiska koordinater eller tar dem som parametrar.
Som standard kan ett Microsoft Active Accessibility-klientprogram som körs i en icke-96-dpi-miljö inte få rätt resultat från dessa anrop. Eftersom markörens position till exempel är i logiska koordinater kan klienten inte bara skicka koordinaterna till AccessibleObjectFromPoint för att hämta elementet som finns under markören.
Dessutom skapar ett program som skapar ett fönster utanför klientområdet, till exempel ett hjälpmedelsprogram som markerar fokuserade gränssnittselement, inte fönstret på rätt skärmplats, eftersom fönstret placeras vid de logiska koordinaterna, inte de fysiska koordinater som returneras av IAccessible::accLocation.
Lösningen är i två delar:
- Gör klientprogrammet "dpi-aware". Det gör du genom att anropa funktionen SetProcessDPIAware vid start. Den här funktionen gör hela processen dpi-medveten, vilket innebär att alla fönster som tillhör processen är oskalade.
- Använd funktioner som är dpi-medvetna. Om du till exempel vill hämta markörkoordinater anropar du funktionen GetPhysicalCursorPos. Använd inte GetCursorPos; dess beteende i dpi-medvetna program är odefinierat.
Om programmet utför direkt korsprocesskommunikation med icke-dpi-medvetna program kan du ha konverterat mellan logiska och fysiska koordinater med hjälp av funktionerna PhysicalToLogicalPoint och LogicalToPhysicalPoint.