Automatyzacja interfejsu użytkownika a skalowanie ekranu

Uwaga

Ta dokumentacja jest przeznaczona dla deweloperów programu .NET Framework, którzy chcą używać zarządzanych klas automatyzacja interfejsu użytkownika zdefiniowanych w System.Windows.Automation przestrzeni nazw. Aby uzyskać najnowsze informacje na temat automatyzacja interfejsu użytkownika, zobacz Interfejs API usługi Windows Automation: automatyzacja interfejsu użytkownika.

Począwszy od systemu Windows Vista, system Windows umożliwia użytkownikom zmianę ustawienia kropek na cal (dpi), aby większość elementów interfejsu użytkownika na ekranie wydawała się większa. Chociaż ta funkcja od dawna jest dostępna w systemie Windows, w poprzednich wersjach skalowanie musiało zostać zaimplementowane przez aplikacje. Począwszy od systemu Windows Vista, Menedżer okien klasycznych wykonuje domyślne skalowanie dla wszystkich aplikacji, które nie obsługują własnego skalowania. automatyzacja interfejsu użytkownika aplikacje klienckie muszą uwzględniać tę funkcję.

Skalowanie w systemie Windows Vista

Domyślne ustawienie dpi to 96, co oznacza, że 96 pikseli zajmuje szerokość lub wysokość jednego cala. Dokładna miara "cala" zależy od rozmiaru i fizycznej rozdzielczości monitora. Na przykład na monitorze o szerokości 12 cali w rozdzielczości poziomej 1280 pikseli linia pozioma 96 pikseli rozciąga się około 9/10 cala.

Zmiana ustawienia dpi nie jest taka sama jak zmiana rozdzielczości ekranu. W przypadku skalowania dpi liczba pikseli fizycznych na ekranie pozostaje taka sama. Jednak skalowanie jest stosowane do rozmiaru i lokalizacji elementów interfejsu użytkownika. To skalowanie można wykonać automatycznie za pomocą programu Desktop Window Manager (DWM) dla pulpitu i aplikacji, które nie pytają jawnie o nie skalowanie.

W efekcie, gdy użytkownik ustawia współczynnik skalowania na 120 dpi, pionowy lub poziomy cal na ekranie staje się większy o 25 procent. Wszystkie wymiary są odpowiednio skalowane. Przesunięcie okna aplikacji z góry i lewej krawędzi ekranu zwiększa się o 25 procent. Jeśli skalowanie aplikacji jest włączone, a aplikacja nie obsługuje dpi, rozmiar okna zwiększa się w tej samej proporcji wraz z przesunięciami i rozmiarami wszystkich elementów interfejsu użytkownika, które zawiera.

Uwaga

Domyślnie usługa DWM nie wykonuje skalowania dla aplikacji niezwiązanych z dpi, gdy użytkownik ustawia dpi na wartość 120, ale wykonuje ją, gdy dpi jest ustawiona na niestandardową wartość 144 lub wyższą. Jednak użytkownik może zastąpić domyślne zachowanie.

Skalowanie ekranu tworzy nowe wyzwania dla aplikacji, które są zainteresowane w dowolny sposób ze współrzędnymi ekranu. Ekran zawiera teraz dwa systemy współrzędnych: fizyczny i logiczny. Współrzędne fizyczne punktu są rzeczywistym przesunięciem w pikselach od lewego górnego rogu punktu początkowego. Współrzędne logiczne są przesunięciami, tak jak gdyby same piksele zostały przeskalowane.

Załóżmy, że projektujesz okno dialogowe z przyciskiem o współrzędnych (100, 48). Gdy to okno dialogowe jest wyświetlane w domyślnym rozdzielczości 96 dpi, przycisk znajduje się na współrzędnych fizycznych (100, 48). Przy rozdzielczości 120 dpi znajduje się na współrzędnych fizycznych (125, 60). Jednak współrzędne logiczne są takie same w każdym ustawieniu dpi: (100, 48).

Współrzędne logiczne są ważne, ponieważ sprawiają, że zachowanie systemu operacyjnego i aplikacji jest spójne niezależnie od ustawienia dpi. Na przykład Cursor.Position zwykle zwraca współrzędne logiczne. Jeśli kursor zostanie przeniesiony na element w oknie dialogowym, te same współrzędne są zwracane niezależnie od ustawienia dpi. Jeśli narysujesz kontrolkę (100, 100), zostanie ona narysowana na tych współrzędnych logicznych i będzie zajmować tę samą pozycję względną w dowolnym ustawieniu dpi.

Skalowanie w klientach automatyzacja interfejsu użytkownika

Interfejs API automatyzacja interfejsu użytkownika nie używa współrzędnych logicznych. Poniższe metody i właściwości zwracają współrzędne fizyczne lub przyjmują je jako parametry.

Domyślnie aplikacja kliencka automatyzacja interfejsu użytkownika uruchomiona w środowisku innej niż 96 dpi nie będzie mogła uzyskać poprawnych wyników z tych metod i właściwości. Na przykład ponieważ położenie kursora znajduje się we współrzędnych logicznych, klient nie może po prostu przekazać tych współrzędnych, aby FromPoint uzyskać element, który znajduje się pod kursorem. Ponadto aplikacja nie będzie mogła poprawnie umieścić okien poza obszarem klienta.

Rozwiązanie znajduje się w dwóch częściach.

  1. Najpierw należy pamiętać o dpi aplikacji klienckiej. W tym celu wywołaj funkcję SetProcessDPIAware Win32 podczas uruchamiania. W kodzie zarządzanym następująca deklaracja udostępnia tę funkcję.

    [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
    

    Ta funkcja sprawia, że cały proces obsługujący dpi, co oznacza, że wszystkie okna należące do procesu są nieskalowane. Na przykład w przykładzie wyróżniania cztery okna tworzące prostokąt wyróżnienia znajdują się na współrzędnych fizycznych uzyskanych z automatyzacja interfejsu użytkownika, a nie współrzędnych logicznych. Gdyby próbka nie uwzględniała dpi, wyróżnienie zostałoby narysowane na współrzędnych logicznych na pulpicie, co spowodowałoby nieprawidłowe umieszczenie w środowisku innej niż 96 dpi.

  2. Aby uzyskać współrzędne kursora, wywołaj funkcję GetPhysicalCursorPosWin32 . W poniższym przykładzie pokazano, jak zadeklarować i użyć tej funkcji.

    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
    

Uwaga

Nie używaj polecenia Cursor.Position. Zachowanie tej właściwości poza oknami klienta w skalowanym środowisku jest niezdefiniowane.

Jeśli aplikacja wykonuje bezpośrednią komunikację między procesami z aplikacjami bez rozpoznawania dpi, może istnieć konwersja między współrzędnymi logicznymi i fizycznymi przy użyciu funkcji PhysicalToLogicalPoint Win32 i LogicalToPhysicalPoint.

Zobacz też