[DelphiCon 요약] High DPI 고해상도를 VCL에서 활용하기


High DPI 고해상도 활용하기 (Leveraging High DPI in VCL Applications) 를 요약했습니다. (이 요약 번역은 원본 비디오와 내용이 일부 다르거나, Q&A등 일부 생략되었을 수 있습니다.)

애플리케이션이 서로 다른 다중 모니터 특히 최근에 부쩍 많아진 High DPI 모니터를 지원하는 검토한 적이 있다면, 이 세션을 통해 해결책을 찾아보세요. 마이크로소프트 윈도우에서 High DPI를 충분히 지원하게 된 것은 윈도우10부터 입니다. 이 세션에서는 High DPI 체계를 살펴보고, 윈도우10부터 제공하는 스케일링(Scaling) 즉, High DPI 비례 확대/축소 능력으 VCL 애플리케이션에서 어떻게 잘 활용하는 지를 설명합니다.

  • High DPI 관련 핵심 개념
  • 개발자 입장에서 DPI를 하나로 미리 고정하기 어려워졌다
  • 개발자가 DPI를 미리 고정할 수 없다 왜냐하면?
  • (데모) 다중 모니터의 표현 이해하기
  • 윈도우에서 High DPI 다루기가 어려운 이유
  • 개발자는 High DPI에서도 보기 좋은 화면을 제공해야 한다
  • 픽셀 크기의 기준을 정하고, 윈도우10 에서 제공하는 DPI 배율 확대/축소(Scaling) 기능을 활용하자
  • 델파이의 DPI Awareness 옵션 5가지 (2020.12 현재)
  • (데모) 델파이에서 DPI Awareness 옵션별 결과
  • TImageCollection
  • TVirtualImageList
  • (데모) Per Monitor V2 옵션에서 TImageCollection와 TVirtualImageList를 추가하고 이슈 해소하기
  • Per Monitor V2 옵션에서 UI 콘트롤을 동적으로 생성할 때 알맞게 표현하기 위한 VCL 함수들
  • (데모) Per Monitor V2 옵션에서, UI 콘트롤을 동적으로 생성할 때 알맞게 표현하기)
  • 마무리

발표자 (Ray Konopka)는 레이즈 소프트웨어 창업자이며, 코드사이트(CodeSite)와 코놉카 시스너처 VCL 컴포넌트(구. 레이즈 컴포넌트) 제작자입니다. 도서 “델파이 컴포넌트 개발하기(Developing Custom Delphi Component)” 저자입니다. 또한 레이는 월트 디즈니 어트렉션 기술의 수석 소프트웨어 엔지니어로서, 디즈니리조트, 디즈니랜드 등의 소프트웨어도 개발합니다.

원본 비디오 시청: https://delphicon.embarcadero.com/talks/leveraging-high-dpi-in-vcl-applications/

High DPI 관련 핵심 개념

  • DPI – Dots Per Inch
  • PPI – Pixels Per Inch
  • 아주 오래전부터 “윈도우의 표준 DPI는 96이다”라고 간주하면 안전했다. (그래픽의 사실 상 표준이었던 픽셀 기반인 VGA 부터 sVGA, XGA…로 이어져 오면서 계속 지켜져왔다).
  • DPI와 “해상도(Resolution)는 같지 않다 (물론 서로 관련있다, 얼마전까지는 해상도가 커져도 인치 당 DPI는 대체로 유지되면서 화면의 크기만 계속 커져왔지만, 최근에는 높은 DPI를 가진 장비가 많아졌다)

개발자 입장에서 DPI를 하나로 미리 고정하기 어려워졌다

스크린 해상도 DPI 해당 물리적 화면 크기
1024 x 769 96 10.7” x 8″
1440 x 900 96 15” x 9”.375
2560 x 1440 109 23.4” x 13.2”
3074 x 1920 226
(현격히 높다)
13.6” x 8.”5
(얼마전 구입한 노트북)
  • 디스플레이 배율 인자 (Display Scale Factor)1024, 1440 등 예정에는 해상도가 커져도 UI 작성에는 영향이 없었다.
    • 96 dpi가 유지되는 한,해상도가 커지면 사용할 수 있는 공간이 늘어난 다는 점만 고려하면 되었다.
    • 16 x 16 아이콘은 어느 해상도에서도 잘 맞았다. 하지만, ( 226 dpi인 새 노트북에서는 아이콘 크기가 3mm로 너무 작게 표현되므로 거의 보이지 않는다.)
    • 이제는 이런 요소들이 High DPI 화면에서도 잘 보이도록 조치 해야 한다.

개발자가 DPI를 미리 고정할 수 없다 왜냐하면?

  • 다중 모니터
    • 각 모니터가 서로 다른 DPI인 상황에서
    • 사용자가, 구동 중인 앱을 드래그하여 한 모니터에서 다른 모니터로 드래그 할 때
    • 예전 윈도우는 미리 정의된 해상도에 맞추어야 모니터를 연결할 수 있었지만, 이제는 다중 모니터 지원에 거의 제한이 없다.
  • 사용자가 노트북에 외부 모니터를 연결하거나 풀 때
  • 사용자가 원격 데스트톱을 통해 연결할 때
  • 사용자가 컴퓨터 사용 중에 화면 배율(Display Scale Factor)를 변경할 때

(데모) 다중 모니터의 표현 이해하기

(비디오 7분 30초 부터 시청)

  • DPI가 거의 같은 모니터에서,
    • (윈도우 메모장 처럼) High DPI를 잘 지원하는 앱은 배율에 맞게 선명하게 표현된다.
    • 글자 폰트도 전반적으로 선명하다.
    • 하지만, 잘보면, 메뉴 간의 간격 등이 미세하게 다르고, 본문의 문장의 길이는 현격히 다르다.
    • 폰트 스케일링이 완벽하게 되지 않기 때문이다. 만약 High DPI에서 이미지를 다루어야 한다면 더 힘들어진다.

윈도우에서 High DPI 다루기가 어려운 이유

  • Dialog Unit(윈도우에서 여러 디스플레이 장비를 다루기 위해 설계될 당시 마이크로소프트가 고안한 단위)
    • 1 DLU = 윈도우 시스템 폰트 너비 평균의 1/4
    • 논리적인 단위이므로 장비 의존성이 없다. 하지만 (이로 인해) 물리적 면적에 맵핑되지도 않는다.
    • 수직 Dialog Unit는 수평 Dialog Unit와 일치하지 않을 수도 있다.
    • 문제는 더이상 아무도 Dialog Unit을 사용하지 않는다는 점이다.
  • (마이크로소프트 등) 개발툴들은 대부분 픽셀(Pixel)을 사용한다.
    • 마이크로소프트의 닷넷, 윈폼, XAML 등도 Dialog Unit을 사용하지 않는다.
    • 픽셀은 물리적 크기가 고정되어있지 않다.
    • 96 dpi 세상일 때는 물리적 크기가 고정된 것과 마찬가지였으나, 이제는 아니다.
    • High DPI를 가진 4K 모니터와 일반 모니터에서 픽셀의 물리적 크기는 다르다. (픽셀 크기와 실제 화면의 물리적 크기를 연결할 방법이 필요하다)
  • 그런데, 마이크로소프트와 달리 애플은 면적 당 포인트 (Point for dimension)를 사용한다.
    • 애플은 (인치당 표현되는 점 즉 DPI가 중요한)그래픽 인쇄 분야에서 오래 전부터 독보적이었다.
    • 이런 역사적 기반 하에 애플은 픽셀이 아닌 실제 물리적 표현 단위인 포인트를 사용한다.
    • 1인치 당 72 포인트를 표준으로 지킨다. 화면이 커지거나 작아지면 해당 배율을 적용한다.
    • 맥 OS와 iOS에서 PPI는 Point Per Inch를 의미한다. (Pixel Per Inch가 아님)

개발자는 High DPI에서도 보기 좋은 화면을 제공해야 한다

  • 우리가 아무 조치도 하지 않아도, 윈도우가 알아서 화면을 표현한다.
  • 이 경우, (데모에서 본 것 처럼) 각 요소들의 크기와 간격 등이 어색할 수 있다.
  • 언젠간 윈도우가 High DPI를 100% 지원한다면 문제없겠지만, 그렇게 되기 전까지는 우리가 조치 해야 한다.

픽셀 크기의 기준을 정하고, 윈도우10 에서 제공하는 DPI 배율 확대/축소(Scaling) 기능을 활용하자

  • 마이크로소프트에서는 최신 버전으로 오면서 High DPI를 더 잘 지원한 결과, 윈도우10에서 많은 향상이 있었다.
  • 각 앱에서 DPI 배율 확대/축소 지능 여부를 매니페스트(Manifest)에 적어서 윈도우에게 알려줄 수 있다.
  • 델파이에서 Project > Options > Application > Manifest > DPI Awareness 옵션 사용

델파이의 DPI Awareness 옵션 5가지 (2020.12 현재)

  • Unaware(인지 안함)
    • 기본값임: 앱은 96 dpi로 렌더링된다.
    • 윈도우 비트맵이 폼을 렌더링한다.
    • 폼이 화면에 맞게 늘어나므로 각 요소의 위치나 크기를 걱정할 필요가 없다.
    • 하지만, (특히 테두리 등) 표현이 깨끗하지 않다는 약점이 있다.
      • (특히 해상도 낮은) 이미지는 깔끔하지 않고 픽셀 표현이 그대로 들어난다.
    • 잘 작동하지만, 보기 좋지는 않기 때문에 최고의 선택이라고 할 수는 없다.
  • System aware
    • 윈도우는 사용자가 로그인 할 당시 인식한 주 모니터의 DPI로 앱을 렌더링한다.
    • 다른 모니터로 폼을 옮기거나 확대/축소가 변경되면, 윈도우에서 폼을 반대로 확대/축소하여 렌더링한다.
    • 활용할만 하지만 최고의 선택이라고 할 수는 없다.
  • Per Monitor (윈도우에서 연결된 모니터를 각각 따로 지원하기 시작함)
    • 윈도우8.1부터 도입됨
    • 상위의 윈도우 창에 DPI 변경이 공지됨 (윈도우가 임의로 확대/축소하지 않음)
  • GDI Scaling (배율 확대/축소)
    • 델파이10.4에 VCL용으로 추가됨 (10.3에서도 가능하긴 했지만 사용하기 불편했음)
    • 마이크로소프트가 윈도우10 Creators 업데이트 (1703)에서 도입함
    • GDI 프레임워크를 활용하여 기본 도형과 텍스트를 각 모니터 기반으로 DPI 스케일링을 적용할 수 있음
    • 디스플레이 배율값과 동일하게 오브젝트를 확대/축소 함
      • 원래 10pt 폰트에 @200% 텍스트가 적용되면 20pt 폰트를 사용하여 렌더링함
      • 즉, 모니터를 바꾸면, 앱이 사용하는 폰트가 모두 업데이트되고 멋지고 선명하게 표현됨
      • 윈도우 커널 이슈를 일으킬 수 있음
    • 이미지 표현, 요소 간 간격 등 미세한 이슈가 있지만) DPI 차이가 너무 크지만 않다면 꽤 쓸만하다.
  • Per Monitor V2
    • 마찬가지로, 윈도우10 Creators 업데이트 (1703)부터 도입됨
    • 상위의 윈도우 창에 DPI 변경이 공지됨 (앱에서 이 윈도우 메시지를 받아낼 수 있음)
    • 자동 스케일링을 통해 해당 DPI에 맞게 모든 것이 확대/축소 됨
      • 클라이언트 영역 밖에서, 테마가 공통 콘트롤과 운영체제 대화상자의 비트맵을 그림
    • 델파이 10.4부터 제공되며, 가장 권장하는 옵션

(데모) 델파이에서 DPI Awareness 옵션별 결과

  • Unaware (비디오 25분 40초 부터 시청)
    • 모든 것이 배율에 맞게 늘어나서 제자리에 있음. 하지만, 글자와 이미지 등의 테두리와 표현이 깔끔하지 않음
  • System aware (비디오 28분 15초 부터 시청)
    • 이미지는 확대/축소가 적용되지 않음 – High DPI가 주 모니터일때, 앱을 DPI가 더 낮은 곳에서 보면 그 차이만큼 작게 표현됨
    • 따라서, 웬만해서 개발자가 선택하기에 좋지 않음
  • Per Monitor (비디오 30분 01초 부터 시청)
    • 이미지는 확대/축소가 적용되지 않으나, High DPI에서 깔끔하게 표현됨
    • 하지만, 더 낮은 DPI에서는 각 요소들의 크기가 알맞게 변하지 않아서, (스크롤 바 크기, 요소간 간격 등) 화면 구성이 틀어짐
  • GDI Scaling: (비디오 32분 11초 부터 시청)
    • 높은 해상도 모니터에서 모든 요소가 알맞게 늘어난다.
    • 자세히 보면 이미지는 늘어난 결과 매끈하게 표현되지는 않는다.
    • 폰트는 새로 더 큰 폰트가 적용되어서 깨끗하게 표현된다.
    • 하지만, 각 앱별로 매니페스트를 잘 적어주어야 한다.
  • Per Monitor V2: (비디오 35분 04초 부터 시청)
    • 델파이 10.4부터 제공되며, 가장 권장하는 옵션
    • 각 모니터의 DPI를 충분히 활용하면서도 배치와 구성이 틀어지지 않고, 글자도 선명함
    • 단, 이미지 크기가 알맞게 변하지 않음 (해소 방안은 뒤에서 설명)
    • UI 콘트롤을 동적으로 생성할 때에는 제대로 표현되지 않음 (해소 방안은 뒤에서 설명)

TImageCollection

  • 서로 다른 해상도를 가진 이미지들을 공유하는 저장소
  • 데이터 모듈에 올려두고 여러곳에서 사용할 수 있음
  • 명명 규칙을 활용하여 알맞은 이미지가 로딩되도록 도움
    • Size in the file name 옵션이 선택되어 있는 지 확인할 것
    • 다음 3가지 구분자 중 한가지 사용 가능 (-, _, @)
      • 파일명 예시: File-Open-16.png , Edit-Paste-48.png 

TVirtualImageList

  • 관련 TImageCollection에서 해당 폼의 DPI를 파악하여 각 폼에서 이미지를 포함하도록 도와줌
  • (각 폼이 어느 모니터에서 표현되는가에 따라 DPI가 다르게 적용될 수 있으므로) 폼들 간 공유되지 못함.
  • 즉, (다른 폼은 다른 모니터에서 표현될 수 있으므로) 데이터 모듈이나 메인폼에 올려두고 다른 폼에서 사용할 수 없음
  • AutoFill 프로퍼티: TImageCollection의 이미지를 한번에 가져온다. 

(데모) Per Monitor V2 옵션에서 TImageCollection와 TVirtualImageList를 추가하고 이슈 해소하기

  • (비디오 42분 01초 부터 시청) 

Per Monitor V2 옵션에서 UI 콘트롤을 동적으로 생성할 때 알맞게 표현하기 위한 VCL 함수들

  • VCL의 새 함수(들) 단, (윈도우10을 API를 활용하므로) 윈도우10 이후에서만 작동함
    • Vcl.Controls.GetSystemMetricsForWindow()
    • TControl.GetSystemMetrics()
      • GetSystemMetricsForWindow 호출
    • TControl.CurrentPPI 프로퍼티

(데모) Per Monitor V2 옵션에서, UI 콘트롤을 동적으로 생성할 때 알맞게 표현하기)

(비디오 50분 49초 부터 시청)

// 동적으로 처음에 한번 알맞은 크기와 위치로 생성되면 이후에 DPI가 다른 화면에서 표현될 때에도 알맞게 표현된다.

마무리


api C++ c++builder c++빌더 code database Delphi fmx IDE ideas interbase ios migration modernization news python radstudio RAD스튜디오 tips UI UIUX vcl windows 개발 개발사례 개발팁 교육 기술레터 기술백서 데이터 데이터베이스 델파이 마이그레이션 모바일 윈도우 윈도우11 인터베이스 출시 코드 파이썬 파이어몽키 프로그래밍 프로젝트 현대화