비고
이 설명서는 System.Windows.Automation 네임스페이스에 정의된 관리되는 UI 자동화 클래스를 사용하려는 .NET Framework 개발자를 위한 것입니다. UI 자동화에 대한 최신 정보는 Windows Automation API: UI 자동화참조하세요.
Windows Vista부터는 사용자가 화면의 대부분의 UI(사용자 인터페이스) 요소가 더 크게 표시되도록 dpi(인치당 점 수) 설정을 변경할 수 있습니다. 이 기능은 오랫동안 Windows에서 사용할 수 있었지만 이전 버전에서는 애플리케이션에서 크기 조정을 구현해야 했습니다. Windows Vista부터 Desktop Window Manager는 자체 크기 조정을 처리하지 않는 모든 애플리케이션에 대해 기본 크기 조정을 수행합니다. UI 자동화 클라이언트 애플리케이션은 이 기능을 고려해야 합니다.
Windows Vista에서 크기 조정
기본 dpi 설정은 96입니다. 즉, 96픽셀은 1개의 명목상 인치의 너비 또는 높이를 차지합니다. "인치"의 정확한 측정값은 모니터의 크기와 물리적 해상도에 따라 달라집니다. 예를 들어 모니터 너비가 12인치이고 가로 해상도가 1280픽셀인 모니터에서는 96픽셀의 가로 선이 약 9/10인치까지 확장됩니다.
dpi 설정을 변경하는 것은 화면 해상도를 변경하는 것과 다릅니다. dpi 크기 조정을 사용하면 화면의 실제 픽셀 수가 동일하게 유지됩니다. 그러나 크기 조정은 UI 요소의 크기와 위치에 적용됩니다. 이 크기 조정은 데스크톱용 DWM(데스크톱 창 관리자)과 명시적으로 크기를 조정하지 않도록 요청하지 않는 애플리케이션에 대해 자동으로 수행할 수 있습니다.
실제로 사용자가 배율 인수를 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는 논리 좌표를 사용하지 않습니다. 다음 메서드와 속성은 실제 좌표를 반환하거나 매개 변수로 사용합니다.
기본적으로 96이 아닌 dpi 환경에서 실행되는 UI 자동화 클라이언트 애플리케이션은 이러한 메서드 및 속성에서 올바른 결과를 얻을 수 없습니다. 예를 들어 커서 위치가 논리 좌표에 있으므로 클라이언트는 커서 아래에 있는 요소를 가져오기 위해 FromPoint 이러한 좌표를 단순히 전달할 수 없습니다. 또한 애플리케이션은 클라이언트 영역 외부에 창을 올바르게 배치할 수 없습니다.
솔루션은 두 부분으로 구성됩니다.
먼저 클라이언트 애플리케이션 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를 인식하게 합니다. 즉, 프로세스에 속하는 모든 창의 크기가 조정되지 않습니다. 예를 들어 형광펜 샘플에서 강조 사각형을 구성하는 네 개의 창은 논리 좌표가 아니라 UI 자동화에서 가져온 물리적 좌표에 있습니다. 샘플이 dpi를 인식하지 않는 경우 강조 표시는 데스크톱의 논리적 좌표에 그려지며, 이로 인해 96이 아닌 dpi 환경에서 잘못된 배치가 발생합니다.
커서 좌표를 얻으려면 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 함수 PhysicalToLogicalPoint
와 LogicalToPhysicalPoint
을(를) 사용하여 논리 좌표와 물리적 좌표 간에 변환할 수 있습니다.