Grundlegendes zu Problemen bei der Bildschirmskalierung
Windows Mit Vista und höheren Versionen des Betriebssystems können Benutzer die DPI-Einstellung (Dots per Inch) ändern, sodass die meisten Benutzeroberflächenelemente auf dem Bildschirm größer angezeigt werden. In früheren Versionen von Windows musste die Skalierung von Anwendungen implementiert werden. In Windows Vista und höher führt der Desktopfenster-Manager (DWM) die Standardskalierung für alle Anwendungen durch, die ihre eigene Skalierung nicht verarbeiten. Microsoft Benutzeroberflächenautomatisierung-Clientanwendungen müssen dieses Feature berücksichtigen.
Dieses Thema enthält folgende Abschnitte:
Skalieren in Windows Vista und höher
Die dpi-Standardeinstellung ist 96, was bedeutet, dass 96 Pixel eine Breite oder Höhe von einem notionalen Zoll belegen. 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 entspricht nicht dem Ändern der Bildschirmauflösung. Bei der DPI-Skalierung bleibt die Anzahl der physischen Pixel auf dem Bildschirm unverändert. Die Skalierung wird jedoch auf die Größe und Position von Benutzeroberflächenelementen angewendet. Diese Skalierung kann automatisch vom DWM für den Desktop und für Anwendungen ausgeführt werden, die nicht explizit eine Skalierung anfordern.
Wenn der Benutzer den Skalierungsfaktor auf 120 dpi festlegt, wird ein vertikaler oder horizontaler Zoll auf dem Bildschirm um 25 Prozent größer. Alle Dimensionen werden entsprechend skaliert. Der Offset eines Anwendungsfensters vom oberen und linken Rand des Bildschirms nimmt um 25 Prozent zu. Wenn die Anwendungsskalierung aktiviert ist und die Anwendung nicht dpi-fähig ist, nimmt die Größe des Fensters im gleichen Verhältnis zu, zusammen mit den Offsets und Größen aller darin enthaltenen Benutzeroberflächenelemente.
Hinweis
Standardmäßig führt dwm keine Skalierung für Nicht-DPI-fähige Anwendungen durch, wenn der Benutzer den DPI auf 120 festlegt, aber führt die Skalierung aus, wenn der dpi auf einen benutzerdefinierten Wert von 144 oder höher festgelegt ist. 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 sind der tatsächliche Offset in Pixel von der oberen linken Seite des Ursprungspunkts. 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 dem Standardwert von 96 dpi angezeigt wird, befindet sich die Schaltfläche an physischen Koordinaten von (100, 48). Bei 120 dpi befindet er sich an physischen Koordinaten von (125, 60). Die logischen Koordinaten sind jedoch bei jeder DPI-Einstellung identisch: (100, 48).
Logische Koordinaten sind wichtig, da sie das Verhalten des Betriebssystems und der Anwendungen unabhängig von der DPI-Einstellung konsistent machen. In der Regel gibt die GetCursorPos-Funktion beispielsweise die logischen Koordinaten zurück. Wenn Sie den Cursor über ein Element in einem Dialogfeld bewegen, werden unabhängig von der DPI-Einstellung die gleichen Koordinaten zurückgegeben. Wenn Sie ein Steuerelement bei (100, 100) zeichnen, wird es auf diese logischen Koordinaten gezeichnet und nimmt bei jeder DPI-Einstellung die gleiche relative Position ein.
Skalierung in Benutzeroberflächenautomatisierungs-Clients
Die Benutzeroberflächenautomatisierung-API verwendet keine logischen Koordinaten. Die folgenden Methoden und Eigenschaften geben physische Koordinaten zurück oder nehmen physische Koordinaten als Parameter an.
- IUIAutomation::ElementFromPoint
- IUIAutomation::ElementFromPointBuildCache
- IUIAutomationElement::GetClickablePoint
- IUIAutomationElement::CurrentBoundingRectangle
- IUIAutomationElement::CachedBoundingRectangle
- IRawElementProviderFragment::BoundingRectangle
Standardmäßig erhalten Benutzeroberflächenautomatisierung Anwendungen, die in einer Umgebung ausgeführt werden, die nicht auf 96 dpi festgelegt ist, keine richtigen Ergebnisse von diesen Methoden und Eigenschaften. Da sich die Cursorposition beispielsweise in logischen Koordinaten befindet, kann der Client diese Koordinaten nicht an IUIAutomation::ElementFromPoint übergeben, um das Element abzurufen, das sich unter dem Cursor befindet. Darüber hinaus ist die Anwendung nicht in der Lage, Fenster außerhalb seines Clientbereichs ordnungsgemäß zu platzieren.
Die Lösung hat zwei Teile.
Machen Sie zunächst die Clientanwendung dpi-fähigen. Rufen Sie hierzu beim Start die SetProcessDPIAware-Funktion auf. Diese Funktion macht den gesamten Prozess dpi-fähigen, d.h., alle Fenster, die zum Prozess gehören, sind nicht skaliert.
Rufen Sie zum Abrufen von Cursorkoordinaten die GetPhysicalCursorPos-Funktion auf.