Aktive Barrierefreiheit und Windows Vista-Bildschirmskalierung
Mit Windows Vista können Benutzer die Dpi-Einstellung (Dots-per-Inch) ändern, sodass die meisten Benutzeroberflächenelemente auf dem Bildschirm größer erscheinen. Obwohl dieses Feature seit langem in Microsoft Windows verfügbar ist, musste die Skalierung in früheren Versionen von Anwendungen implementiert werden. In Windows Vista führt der Desktopfenster-Manager die Standardskalierung für alle Anwendungen aus, die keine eigene Skalierung verarbeiten. Microsoft Active Accessibility-Clientanwendungen müssen dieses Feature berücksichtigen.
Skalierung in Windows Vista
Die DPI-Standardeinstellung ist 96, d. h. 96 Pixel belegen eine Breite oder Höhe eines angenommenen Zolls. Das genaue Maß für ein „Zoll“ ist abhängig von der Größe und der physischen Auflösung des Monitors. Auf einem Monitor mit einer Breite von 12 Zoll bei einer horizontalen Auflösung von 1280 Pixel erstreckt sich eine horizontale Linie von 96 Pixeln beispielsweise über etwas 9/10 eines Zolls.
Das Ändern der DPI-Einstellung ist nicht dasselbe wie das Ändern der Bildschirmauflösung. Mit der DPI-Skalierung bleibt die Anzahl der physischen Pixel auf dem Bildschirm unverändert. Die Skalierung wird jedoch auf die Größe und Position der Benutzeroberflächenelemente angewendet. Diese Skalierung kann vom Desktopfenster-Manager (DWM) für den Desktop und für Anwendungen automatisch durchgeführt werden , die nicht ausdrücklich danach verlangen, nicht skaliert zu werden.
Wenn der Benutzer den Skalierungsfaktor auf 120 DPI festlegt, wird ein vertikales oder horizontales Zoll auf dem Bildschirm um 25 Prozent vergrößert. Alle Dimensionen werden entsprechend skaliert. Der Offset eines Fensters vom oberen und linken Bildschirmrand nimmt um 25 Prozent zu. Die Größe des Fensters nimmt im gleichen Verhältnis zu, zusammen mit den Offsets und Größen aller darin enthaltenen UI-Elemente.
Standardmäßig führt der Desktopfenster-Manager keine Skalierung für nicht DPI-fähige Anwendungen durch, wenn der Benutzer für DPI den Wert 120 festlegt. Die Skalierung wird jedoch ausgeführt, wenn für DPI ein benutzerdefinierter Wert von 144 oder höher festgelegt wird. Das Standardverhalten kann vom Benutzer jedoch außer Kraft gesetzt werden.
Die Bildschirmskalierung stellt an Anwendungen neue Herausforderungen, die sich in irgendeiner Weise mit Bildschirmkoordinaten befassen. Der Bildschirm enthält jetzt zwei Koordinatensysteme: ein physisches und ein logisches. Die physischen Koordinaten eines Punkts stellen den tatsächlichen Offset in Pixeln vom oberen linken Rand des Ursprungs dar. Die logischen Koordinaten sind die Offsets, die sich ergeben würden, wenn die Pixel selbst skaliert würden.
Angenommen, Sie entwerfen ein Dialogfeld mit einer Schaltfläche an den Koordinaten (100, 48). Wenn dieses Dialogfeld mit den standardmäßigen 96 DPI angezeigt wird, befindet sich die Schaltfläche an den physischen Koordinaten (100, 48). Bei 120 DPI befindet sie sich an den physischen Koordinaten (125, 60). Aber die logischen Koordinaten sind bei jeder DPI-Einstellung dieselben: (100, 48).
Logische Koordinaten sind wichtig, da sie für Betriebssystem und Anwendungen unabhängig von der DPI-Einstellung für ein konsistentes Verhalten sorgen. System.Windows.Forms.Cursor.Position gibt beispielsweise normalerweise die logischen Koordinaten zurück. Wenn Sie den Cursor über ein Element in einem Dialogfeld bewegen, werden unabhängig von der DPI-Einstellung dieselben Koordinaten zurückgegeben. Wenn Sie ein Steuerelement an den Koordinaten (100, 100) darstellen, wird es an diesen logischen Koordinaten angezeigt und belegt bei einer beliebigen DPI-Einstellung dieselbe relative Position.
Skalieren von Clients für aktive Barrierefreiheit
Microsoft Active Accessibility verwendet keine logischen Koordinaten. Die folgenden Methoden und Funktionen geben entweder physische Koordinaten zurück oder nehmen sie als Parameter.
Standardmäßig kann eine Microsoft Active Accessibility-Clientanwendung, die in einer Nicht-96-dpi-Umgebung ausgeführt wird, keine korrekten Ergebnisse aus diesen Aufrufen erhalten. Da sich die Cursorposition beispielsweise in logischen Koordinaten befindet, kann der Client diese Koordinaten nicht einfach an AccessibleObjectFromPoint übergeben, um das Element abzurufen, das sich unter dem Cursor befindet.
Darüber hinaus erstellt eine Anwendung, die ein Fenster außerhalb ihres Clientbereichs erstellt, z. B. eine Barrierefreiheitsanwendung, die fokussierte UI-Elemente hervorhebt, das Fenster nicht an der richtigen Bildschirmposition, da das Fenster an den logischen Koordinaten platziert wird, nicht an den physischen Koordinaten, die von IAccessible::accLocation zurückgegeben werden.
Die Lösung besteht aus zwei Teilen:
- Stellen Sie die Clientanwendung "dpi-fähig" fest. Rufen Sie hierzu die SetProcessDPIAware-Funktion beim Start auf. Diese Funktion sorgt dafür, dass der gesamte Prozess DPI-fähig ist, d. h. alle zum Prozess gehörenden Fenster werden nicht skaliert.
- Verwenden Sie Funktionen, die dpi-fähig sind. Um beispielsweise Cursorkoordinaten abzurufen, rufen Sie die GetPhysicalCursorPos-Funktion auf. Verwenden Sie nicht GetCursorPos. sein Verhalten in dpi-fähigen Anwendungen ist undefiniert.
Wenn Ihre Anwendung eine direkte prozessübergreifende Kommunikation mit Nicht-DPI-fähigen Anwendungen ausführt, müssen Sie möglicherweise mithilfe der Funktionen PhysicalToLogicalPoint und LogicalToPhysicalPoint zwischen logischen und physischen Koordinaten konvertieren.