Delen via


Ui-automatisering en schermschalen

Notitie

Deze documentatie is bedoeld voor .NET Framework-ontwikkelaars die de beheerde UI Automation-klassen willen gebruiken die zijn gedefinieerd in de System.Windows.Automation naamruimte. Zie Windows Automation-API: UI Automation voor de meest recente informatie over UI Automation.

Vanaf Windows Vista kunnen gebruikers de dpi-instelling (dots per inch) wijzigen, zodat de meeste elementen van de gebruikersinterface (UI) op het scherm groter worden weergegeven. Hoewel deze functie al lang beschikbaar is in Windows, moest de schaal in eerdere versies worden geïmplementeerd door toepassingen. Vanaf Windows Vista voert Windows Window Manager standaardschalen uit voor alle toepassingen die niet omgaan met hun eigen schaalaanpassing. Ui Automation-clienttoepassingen moeten rekening houden met deze functie.

Schalen in Windows Vista

De standaard dpi-instelling is 96, wat betekent dat 96 pixels een breedte of hoogte van één notional inch innemen. De exacte meting van een "inch" is afhankelijk van de grootte en fysieke resolutie van de monitor. Op een monitor van 12 inch breed, bijvoorbeeld bij een horizontale resolutie van 1280 pixels, breidt een horizontale lijn van 96 pixels ongeveer 9/10 van een inch uit.

Het wijzigen van de dpi-instelling is niet hetzelfde als het wijzigen van de schermresolutie. Met dpi-schaalaanpassing blijft het aantal fysieke pixels op het scherm hetzelfde. Schaalaanpassing wordt echter toegepast op de grootte en locatie van UI-elementen. Deze schaalaanpassing kan automatisch worden uitgevoerd door Desktop Window Manager (DWM) voor het bureaublad en voor toepassingen die niet expliciet vragen om niet te worden geschaald.

Wanneer de gebruiker de schaalfactor instelt op 120 dpi, wordt een verticale of horizontale inch op het scherm met 25 procent groter. Alle dimensies worden dienovereenkomstig geschaald. De verschuiving van een toepassingsvenster vanaf de boven- en linkerranden van het scherm neemt met 25 procent toe. Als het schalen van toepassingen is ingeschakeld en de toepassing niet dpi-bewust is, neemt de grootte van het venster in dezelfde verhouding toe, samen met de verschuivingen en grootten van alle UI-elementen die deze bevat.

Notitie

De DWM voert standaard geen schaalaanpassing uit voor niet-dpi-compatibele toepassingen wanneer de gebruiker de dpi instelt op 120, maar wel wanneer de dpi is ingesteld op een aangepaste waarde van 144 of hoger. De gebruiker kan echter het standaardgedrag overschrijven.

Schermschalen creëert nieuwe uitdagingen voor toepassingen die op elke manier betrokken zijn met schermcoördinaten. Het scherm bevat nu twee coördinatensystemen: fysiek en logisch. De fysieke coördinaten van een punt zijn de werkelijke verschuiving in pixels linksboven van de oorsprong. De logische coördinaten zijn de offsets zoals ze zouden zijn als de pixels zelf werden geschaald.

Stel dat u een dialoogvenster ontwerpt met een knop op coördinaten (100, 48). Wanneer dit dialoogvenster wordt weergegeven met de standaardwaarde van 96 dpi, bevindt de knop zich op fysieke coördinaten van (100, 48). Bij 120 dpi bevindt het zich op fysieke coördinaten van (125, 60). Maar de logische coördinaten zijn hetzelfde bij elke dpi-instelling: (100, 48).

Logische coördinaten zijn belangrijk, omdat ze het gedrag van het besturingssysteem en de toepassingen consistent maken, ongeacht de dpi-instelling. Retourneert bijvoorbeeld Cursor.Position normaal gesproken de logische coördinaten. Als u de cursor over een element in een dialoogvenster verplaatst, worden dezelfde coördinaten geretourneerd, ongeacht de dpi-instelling. Als u een besturingselement tekent op (100, 100), wordt het getekend op die logische coördinaten en zal deze dezelfde relatieve positie innemen bij een dpi-instelling.

Schalen in UI Automation-clients

De UI Automation-API maakt geen gebruik van logische coördinaten. Met de volgende methoden en eigenschappen worden fysieke coördinaten geretourneerd of als parameters gebruikt.

Standaard kan een UI Automation-clienttoepassing die wordt uitgevoerd in een niet-96 dpi-omgeving, geen juiste resultaten verkrijgen van deze methoden en eigenschappen. Omdat de cursor zich bijvoorbeeld in logische coördinaten bevindt, kan de client deze coördinaten niet gewoon doorgeven om FromPoint het element te verkrijgen dat zich onder de cursor bevindt. Bovendien kan de toepassing vensters buiten het clientgebied niet correct plaatsen.

De oplossing bestaat uit twee delen.

  1. Maak eerst de dpi-bewuste clienttoepassing. Hiervoor roept u de Win32-functie SetProcessDPIAware aan bij het opstarten. In beheerde code maakt de volgende declaratie deze functie beschikbaar.

    [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
    

    Deze functie maakt het hele proces dpi-bewust, wat betekent dat alle vensters die deel uitmaken van het proces niet worden geschaald. In het markeerstiftvoorbeeld bevinden bijvoorbeeld de vier vensters waaruit de rechthoek met markeringen bestaat, zich op de fysieke coördinaten die zijn verkregen uit UI Automation, niet de logische coördinaten. Als het voorbeeld niet dpi-bewust was, zou de markering worden getekend op de logische coördinaten op het bureaublad, wat zou leiden tot onjuiste plaatsing in een niet-96 dpi-omgeving.

  2. Als u cursorcoördinaten wilt ophalen, roept u de Win32-functie GetPhysicalCursorPosaan. In het volgende voorbeeld ziet u hoe u deze functie declareert en gebruikt.

    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
    

Let op

Niet gebruiken Cursor.Position. Het gedrag van deze eigenschap buiten clientvensters in een geschaalde omgeving is niet gedefinieerd.

Als uw toepassing directe communicatie tussen processen uitvoert met niet-dpi-compatibele toepassingen, hebt u mogelijk conversie tussen logische en fysieke coördinaten met behulp van de Win32-functies PhysicalToLogicalPoint en LogicalToPhysicalPoint.

Zie ook