화면 크기 조정 문제 이해
Windows Vista 이상 버전의 운영 체제를 사용하면 화면의 대부분의 UI 요소가 더 크게 표시되도록 사용자가 dpi(인치당 점 수) 설정을 변경할 수 있습니다. 이전 버전의 Windows에서는 애플리케이션에서 크기 조정을 구현해야 했습니다. Windows Vista 이상에서 DWM(데스크톱 창 관리자)은 자체 크기 조정을 처리하지 않는 모든 애플리케이션에 대해 기본 크기 조정을 수행합니다. Microsoft 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 설정에 관계없이 운영 체제 및 애플리케이션의 동작을 일관되게 만들기 때문에 중요합니다. 예를 들어 일반적으로 GetCursorPos 함수는 논리 좌표를 반환합니다. 대화 상자의 요소 위로 커서를 이동하면 dpi 설정에 관계없이 동일한 좌표가 반환됩니다. (100, 100)에서 컨트롤을 그리면 해당 논리 좌표에 그려지고 모든 dpi 설정에서 동일한 상대 위치를 차지합니다.
UI 자동화 클라이언트에서 크기 조정
UI 자동화 API는 논리 좌표를 사용하지 않습니다. 다음 메서드와 속성은 실제 좌표를 반환하거나 실제 좌표를 매개 변수로 사용합니다.
- IUIAutomation::ElementFromPoint
- IUIAutomation::ElementFromPointBuildCache
- IUIAutomationElement::GetClickablePoint
- IUIAutomationElement::CurrentBoundingRectangle
- IUIAutomationElement::CachedBoundingRectangle
- IRawElementProviderFragment::BoundingRectangle
기본적으로 96dpi로 설정되지 않은 환경에서 실행되는 UI 자동화 애플리케이션은 이러한 메서드 및 속성에서 올바른 결과를 얻지 않습니다. 예를 들어, 커서 위치가 논리 좌표에 있기 때문에 클라이언트는 이러한 좌표를 IUIAutomation::ElementFromPoint에 전달하여 커서 아래에 있는 요소를 가져올 수 없습니다. 또한 애플리케이션은 클라이언트 영역 외부에 창을 올바르게 배치할 수 없습니다.
솔루션에는 두 부분이 있습니다.
먼저 클라이언트 애플리케이션 dpi를 인식하게 합니다. 이렇게 하려면 시작 시 SetProcessDPIAware 함수를 호출합니다. 이 함수는 전체 프로세스 dpi를 인식하게 합니다. 즉, 프로세스에 속하는 모든 창의 크기가 조정되지 않습니다.
둘째, 커서 좌표를 얻으려면 GetPhysicalCursorPos 함수를 호출합니다.