Share via


UI 자동화 및 화면 크기 조정

참고 항목

이 설명서는 System.Windows.Automation 네임스페이스에 정의된 관리되는 UI 자동화 클래스를 사용하려는 .NET Framework 개발자를 위한 것입니다. UI 자동화에 대한 최신 정보는 Windows 자동화 API: UI 자동화를 참조하세요.

Windows Vista부터 화면의 대부분의 UI(사용자 인터페이스) 요소가 더 크게 표시되도록 사용자는 dpi(인치당 도트 수) 설정을 변경할 수 있습니다. 이 기능은 Windows에서 오래 전부터 사용할 수 있었지만, 이전 버전에서는 스켕일링을 애플리케이션에서 구현해야 했습니다. Windows Vista부터 바탕 화면 창 관리자는 자체 스케일링을 처리하지 않는 모든 애플리케이션에 기본 스케일링을 수행합니다. UI 자동화 클라이언트 애플리케이션에서는 이 기능을 고려해야 합니다.

Windows Vista에서 크기 조정

기본 dpi 설정은 96이며, 96픽셀이 1인치의 추상적 너비 또는 높이를 차지한다는 의미입니다. "인치"의 정확한 측정값은 모니터의 크기와 실제 해상도에 따라 달라집니다. 예를 들어, 12인치 너비의 모니터에서 1280픽셀의 수평 해상도의 경우 96픽셀의 가로줄은 1인치의 약 9/10입니다.

dpi 설정을 변경하는 것은 화면 해상도를 변경하는 것과 같지 않습니다. dpi 스케일링을 통해, 화면의 실제 픽셀 수는 동일하게 유지됩니다. 하지만 스케일링은 UI 요소의 크기와 위치에 적용됩니다. 크기를 조정하지 말라는 메시지가 명시적으로 표시되지 않는 데스크톱 및 애플리케이션에 대해서는 바탕 화면 창 관리자가 이 크기 조정을 자동으로 수행할 수 있습니다.

실제로, 사용자가 배율 인수를 120dpi로 설정하면 화면의 가로 또는 세로 인치가 25% 커집니다. 그에 따라 모든 치수가 적절하게 조정됩니다. 화면 위쪽에서 왼쪽 가장자리까지 애플리케이션 창의 오프셋이 25% 늘어납니다. 애플리케이션 스케일링을 사용하고 있고 이 애플리케이션에서 dpi가 인식되지 않으면, 창 크기는 여기에 포함된 모든 UI 요소의 오프셋과 크기와 함께 동일한 비율로 증가됩니다.

참고 항목

기본적으로 DWM은 사용자가 dpi를 120으로 설정하면 비 dpi 인식 애플리케이션에 대해 크기 조정을 수행하지 않지만 dpi가 144 이상의 사용자 지정 값으로 설정되면 크기 조정을 수행합니다. 그러나 사용자는 기본 동작을 재정의할 수 있습니다.

화면 크기 조정 어떤 방식으로든 화면 좌표와 관련된 애플리케이션에 대한 새로운 문제를 만듭니다. 이제 화면에는 물리적 좌표와 논리적 좌표 두 개가 포함됩니다. 점의 물리적 좌표는 원점의 왼쪽 상단에서의 픽셀 단위의 실제 오프셋입니다. 논리적 좌표는 픽셀 자체의 크기가 조정된 경우 발생되는 오프셋입니다.

좌표 (100, 48)에서 단추가 있는 대화 상자를 설계한다고 가정해 보세요. 이 대화 상자가 기본 96dpi에서 표시되면 단추는 물리적 좌표 (100, 48)에 위치합니다. 120dpi에서 표시되면 단추는 물리적 좌표 (125, 60)에 위치합니다. 하지만 논리적 좌표는 모든 dpi 설정에서 (100, 48)로 동일합니다.

논리적 좌표는 dpi 설정과 관계없이 운영 체제와 애플리케이션의 동작을 일관적으로 유지하기 때문에 중요합니다. 예를 들어, Cursor.Position 은 일반적으로 논리적 좌표를 반환합니다. 대화 상자에서 요소 위에 커서를 놓으면 dpi 설정과 관계 없이 동일한 좌표가 반환됩니다. 좌표 (100, 100)에서 컨트롤을 그리면 논리적 좌표로 그려지고 모든 dpi 설정에서 동일한 상대적 위치를 차지합니다.

UI 자동화 클라이언트의 크기 조정

UI 자동화 API는 논리 좌표를 사용하지 않습니다. 다음 메서드 및 속성은 물리적 좌표를 반환하거나 매개 변수로 간주합니다.

기본적으로, 96dpi가 아닌 환경에서 실행되는 UI 자동화 클라이언트 애플리케이션은 이러한 메서드와 속성에서 올바른 결과를 얻을 수 없습니다. 예를 들어, 커서 위치는 논리적 좌표에 있기 때문에 클라이언트가 이러한 좌표를 FromPoint 에 간단히 전달하여 커서 아래에 있는 요소를 가져올 수 없습니다. 또한 애플리케이션이 클라이언트 영역 외부에 창을 올바르게 배치할 수 없습니다.

솔루션은 두 부분으로 구성됩니다.

  1. 먼저 클라이언트 애플리케이션이 dpi를 인식하도록 설정합니다. 이렇게 하려면 시작 시에 Win32 함수 SetProcessDPIAware를 호출합니다. 관리 코드에서, 다음 선언을 통해 이 함수를 사용할 수 있습니다.

    [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
    

    이 함수를 사용하면 전체 프로세스 dpi가 인식되므로 프로세스에 속하는 모든 창이 실제 크기로 유지됩니다. 예를 들어 형광펜 샘플에서, 강조 표시 사각형을 구성하는 4개의 창은 논리적 좌표가 아닌 UI 자동화에서 가져온 물리적 좌표에 있습니다. 샘플에서 dpi가 인식되지 않으면 강조 표시가 데스크톱의 논리적 좌표에 그려지며, 그에 따라 96dpi 이외 환경에서 배치가 잘못될 수 있습니다.

  2. 커서 좌표를 가져오려면 Win32 함수 GetPhysicalCursorPos를 호출합니다. 다음 예제에서는 이 함수를 선언하고 사용하는 방법을 보여 줍니다.

    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
    

주의

Cursor.Position는 사용하지 마세요. 크기가 조정된 환경에서 클라이언트 창 외부에서의 이 속성 동작이 정의되지 않았습니다.

사용하는 애플리케이션에서 비 dpi 인식 애플리케이션과 직접 크로스 프로세스 통신을 수행하는 경우 Win32 함수 PhysicalToLogicalPointLogicalToPhysicalPoint를 사용하여 논리적 좌표와 물리적 좌표 간을 변환했을 수 있습니다.

참고 항목