Freigeben über


Benutzeroberflächenautomatisierung und Bildschirmskalierung

Hinweis

Diese Dokumentation richtet sich an .NET Framework-Entwickler, die die verwalteten Benutzeroberflächenautomatisierungs-Klassen verwenden möchten, die im System.Windows.Automation-Namespace definiert sind. Die neuesten Informationen zur Benutzeroberflächenautomatisierung finden Sie unter Windows Automation API: Benutzeroberflächenautomatisierung.

Ab Windows Vista können Benutzer die Dpi-Einstellung (Dots per Inch) ändern, sodass die meisten Ui-Elemente auf dem Bildschirm größer angezeigt werden. Obwohl dieses Feature schon lange in Windows verfügbar war, musste die Skalierung in früheren Versionen von Anwendungen implementiert werden. Ab Windows Vista führt der Desktopfenster-Manager die Standardskalierung für alle Anwendungen aus, die keine eigene Skalierung behandeln. Benutzeroberflächenautomatisierungs-Clientanwendungen müssen dieses Feature berücksichtigen.

Skalieren in Windows Vista

Die Standard-DPI-Einstellung ist 96, was bedeutet, dass 96 Pixel eine Breite oder Höhe von einem Notional inch belegen. Das genaue Maß eines "Zolls" hängt von der Größe und physischen Auflösung des Monitors ab. Beispielsweise erstreckt sich auf einem Monitor 12 Zoll breit bei einer horizontalen Auflösung von 1280 Pixeln eine horizontale Linie von 96 Pixeln um 9/10 zoll.

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 gleich. Die Skalierung wird jedoch auf die Größe und Position von UI-Elementen angewendet. Diese Skalierung kann automatisch vom Desktop Window Manager (DWM) für den Desktop und für Anwendungen ausgeführt werden, die nicht explizit bitten, nicht skaliert zu werden.

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 Bildschirmrand 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 zusammen mit den Offsets und Größen aller darin enthaltenen UI-Elemente zu.

Hinweis

Standardmäßig führt der DWM keine Skalierung für Anwendungen ohne DPI-Bewusstsein aus, wenn der Benutzer den DPI-Wert auf 120 festlegt. Bei einem benutzerdefinierten Wert von 144 oder höher wird die Skalierung jedoch durchgeführt. Der Benutzer kann jedoch das Standardverhalten außer Kraft setzen.

Die Bildschirmskalierung schafft neue Herausforderungen für Anwendungen, die sich auf irgendeine Weise mit Bildschirmkoordinaten befassen. Der Bildschirm enthält nun zwei Koordinatensysteme: physisch und logisch. Die physischen Koordinaten eines Punkts sind der tatsächliche Versatz in Pixeln von der oberen linken Ecke des Ausgangspunkts. Bei den logischen Koordinaten handelt es sich um die Offsets, so, wie sie wären, wenn die Pixel selbst skaliert würden.

Angenommen, Sie entwerfen ein Dialogfeld mit einer Schaltfläche an Koordinaten (100, 48). Wenn dieses Dialogfeld mit 96 dpi standardmäßig angezeigt wird, befindet sich die Schaltfläche an physischen Koordinaten von (100, 48). Bei 120 dpi befindet es 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. Gibt beispielsweise Cursor.Position normalerweise die logischen Koordinaten zurück. Wenn Sie den Cursor über ein Element in einem Dialogfeld bewegen, werden die gleichen Koordinaten unabhängig von der DPI-Einstellung zurückgegeben. Wenn Sie ein Steuerelement an den Koordinaten (100, 100) zeichnen, wird es an diese logischen Koordinaten gezeichnet und nimmt dieselbe relative Position bei jeder DPI-Einstellung ein.

Skalierung in Benutzeroberflächenautomatisierungs-Clients

Die Benutzeroberflächenautomatisierungs-API verwendet keine logischen Koordinaten. Die folgenden Methoden und Eigenschaften geben entweder physische Koordinaten zurück oder nehmen sie als Parameter.

Standardmäßig kann eine Clientanwendung für die Benutzeroberflächenautomatisierung, die in einer Nicht-96-DPI-Umgebung ausgeführt wird, keine korrekten Ergebnisse aus diesen Methoden und Eigenschaften abrufen. Da sich die Cursorposition beispielsweise in logischen Koordinaten befindet, kann der Client diese Koordinaten nicht einfach an FromPoint übergeben, um das Element abzurufen, das sich unter dem Cursor befindet. Darüber hinaus ist die Anwendung nicht in der Lage, Fenster außerhalb des Clientbereichs korrekt zu platzieren.

Die Lösung befindet sich in zwei Teilen.

  1. Sorgen Sie dafür, dass die Clientanwendung DPI-fähig ist. Rufen Sie dazu die Win32-Funktion SetProcessDPIAware beim Start auf. In verwaltetem Code stellt die folgende Deklaration diese Funktion zur Verfügung.

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    internal static extern bool SetProcessDPIAware();
    
    <System.Runtime.InteropServices.DllImport("user32.dll")> _
    Friend Shared Function SetProcessDPIAware() As Boolean
    End Function
    

    Diese Funktion macht den gesamten Prozess dpi-fähig, was bedeutet, dass alle Fenster, die zum Prozess gehören, nicht skaliert sind. Im Textmarkerbeispiel befinden sich beispielsweise die vier Fenster, aus denen das Hervorhebungsrechteck besteht, an den physischen Koordinaten, die von der Benutzeroberflächenautomatisierung abgerufen werden, nicht an den logischen Koordinaten. Wenn das Beispiel nicht DPI-fähig wäre, würde die Hervorhebung an den logischen Koordinaten auf dem Desktop dargestellt werden. Dies würde zu einer falschen Platzierung in einer Umgebung mit einer anderen Einstellung als 96 DPI führen.

  2. Rufen Sie zum Abrufen von Cursorkoordinaten die Win32-Funktion GetPhysicalCursorPosauf. Das folgende Beispiel zeigt, wie Sie diese Funktion deklarieren und verwenden.

    public struct CursorPoint
    {
        public int X;
        public int Y;
    }
    
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    internal static extern bool GetPhysicalCursorPos(ref CursorPoint lpPoint);
    
    private bool ShowUsage()
    {
        CursorPoint cursorPos = new CursorPoint();
        try
        {
            return GetPhysicalCursorPos(ref cursorPos);
        }
        catch (EntryPointNotFoundException) // Not Windows Vista
        {
            return false;
        }
    }
    
    Structure CursorPoint
        Public X As Integer
        Public Y As Integer
    End Structure
    
    <System.Runtime.InteropServices.DllImport("user32.dll")> _
    Friend Shared Function GetPhysicalCursorPos(ByRef lpPoint As CursorPoint) As Boolean
    End Function
    
    Private Function ShowUsage() As Boolean
    
        Dim cursorPos As New CursorPoint()
        Try
            Return GetPhysicalCursorPos(cursorPos)
        Catch e As EntryPointNotFoundException ' Not Windows Vista
            Return False
        End Try
    
    End Function
    

Vorsicht

Verwenden Sie nicht Cursor.Position. Das Verhalten dieser Eigenschaft außerhalb von Clientfenstern in einer skalierten Umgebung ist nicht definiert.

Wenn Ihre Anwendung eine direkte prozessübergreifende Kommunikation mit nicht-dpi-fähigen Anwendungen durchführt, können Sie mithilfe der Win32-Funktionen PhysicalToLogicalPoint und LogicalToPhysicalPoint zwischen logischen und physischen Koordinaten konvertieren.

Siehe auch