Automatisering av användargränssnitt och skärmskalning
Kommentar
Den här dokumentationen System.Windows.Automation är avsedd för .NET Framework-utvecklare som vill använda de hanterade UI Automation-klasserna som definierats i namnområdet. Den senaste informationen om UI Automation finns i Windows Automation API: UI Automation.
Från och med Windows Vista gör Windows det möjligt för användare att ändra inställningen punkter per tum (dpi) så att de flesta användargränssnittselement på skärmen visas större. Även om den här funktionen länge har varit tillgänglig i Windows måste skalningen implementeras av program i tidigare versioner. Från och med Windows Vista utför Skrivbordsfönsterhanteraren standardskalning för alla program som inte hanterar sin egen skalning. UI Automation-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 programfönster från skärmens övre och vänstra kanter ökar med 25 procent. Om programskalning är aktiverat och programmet inte är dpi-medvetet ökar storleken på fönstret i samma proportion, tillsammans med förskjutningar och storlekar för alla gränssnittselement som det innehåller.
Kommentar
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 Cursor.Position returnerar 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 UI Automation-klienter
Api:et för UI Automation använder inte logiska koordinater. Följande metoder och egenskaper returnerar antingen fysiska koordinater eller tar dem som parametrar.
Som standard kan ett UI Automation-klientprogram som körs i en icke-96-dpi-miljö inte få rätt resultat från dessa metoder och egenskaper. Eftersom markörens position till exempel är i logiska koordinater kan klienten inte bara skicka koordinaterna till FromPoint för att hämta elementet som finns under markören. Dessutom kommer programmet inte att kunna placera fönster på rätt sätt utanför klientområdet.
Lösningen finns i två delar.
Börja med att göra klientprogrammet dpi-medvetet. Det gör du genom att anropa funktionen
SetProcessDPIAware
Win32 vid start. I hanterad kod gör följande deklaration den här funktionen tillgänglig.[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
Den här funktionen gör hela processen dpi-medveten, vilket innebär att alla fönster som tillhör processen är oskalade. I highlighter-exemplet finns till exempel de fyra fönster som utgör markeringsrektangeln vid de fysiska koordinater som hämtas från UI Automation, inte de logiska koordinaterna. Om exemplet inte var dpi-medvetet ritas markningen vid de logiska koordinaterna på skrivbordet, vilket skulle resultera i felaktig placering i en icke-96-dpi-miljö.
Om du vill hämta markörkoordinater anropar du funktionen
GetPhysicalCursorPos
Win32 . I följande exempel visas hur du deklarerar och använder den här funktionen.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
Varning
Använd inte Cursor.Position. Beteendet för den här egenskapen utanför klientfönster i en skalad miljö är odefinierat.
Om ditt program utför direkt korsprocesskommunikation med icke-dpi-medvetna program kan du ha konverterat mellan logiska och fysiska koordinater med hjälp av Funktionerna Win32 PhysicalToLogicalPoint
och LogicalToPhysicalPoint
.