[현대화] 윈도우 테마, 제대로 활용하고 있나요?
- 2021-05-25
- Posted by: Narae Kim
- Categories: 기술자료, 메인 노출
- 원문 링크: https://blogs.embarcadero.com/modernize-your-app-are-you-handling-windows-themes-correctly/
- 작성자: 이안 바커 (Ian Barker)
최신 버전의 마이크로소프트 윈도우는 분명 화면 구성, 디자인 등 시각적인 부분이 훨씬 더 좋아졌습니다. 회색 메뉴바 라던가 두툼한 버튼의 시대는 갔죠. 마이크로소프트가 플루언트 UI 인터페이스를 채택하면서 색상 팔레트는 더욱 풍성해졌고, 폰트는 깨끗하고 날렵해졌습니다. Serif 계열의 곡선이 없는 글꼴들도 추가되었죠. 이를 통해 우리는 앱을 현대화 할 수 있는 다양한 기능들과 사용자 편의 관련 기술들을 활용할 수 있게 되었습니다: high DPI, 알림, “light”와 “dark” 모드에 맞게 설계된 테마 등이 그것이죠.
High DPI 적용하기
RAD스튜디오와 델파이는 이미 high DPI의 변경된 내용들을 처리할 수 있는 기능들을 제공하고 있습니다. IDE에서 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 “properties” 선택 후 “manifest” 섹션을 클릭합니다. 그럼 “per monitor v2” 옵션을 확인할 수 있습니다. 이 항목을 선택하면, 개발한 앱이 윈도우에서 high DPI를 지원하며, 이를 처리할 수 있는 자산들과 API 처리 기능들까지 제공함을 알려주는 것입니다. VCL 런타임 시, per monitor v2 설정이 사용되도록 설정한 경우라면 백그라운드에서 상당히 많은 양의 작업이 수행됩니다. 하지만 여러분이나 저와 같은 일반 개발자들에게는 이런 작업이 전혀 영향을 주지는 않습니다.
per monitor v2를 지원하지 않는 이전 버전의 컴파일러로 컴파일한 프로그램과 비교해보면, 그 차이점을 확실하게 알 수 있을텐데요. 고해상도의 모니터에서 이 프로그램을 실행해보면 흐릿하게 보일 수 있습니다. 그 이유는 설정 가능한 항목들이 제한적이기 때문인데요. 일단 “manifest” 파일 설정 항목이 없고, 내부 API 호출이 ‘이전 버전과 호환이 가능한’ 정도의 수준만 활용할 수 있기 때문입니다. 즉 최신 디스플레이 기술의 최대한으로 활용하는 앱을 애초에 만들 수가 없는거죠. 이렇게 보면 됩니다. 4K OLED TV에서 1970년대 영화를 보는 기분? 상상이 되시죠?
최신 VCL이 아직 완벽하게 지원하지 못한 기능? 하지만 해결방법은 있다!
윈도우 10의 눈에 띄는 변화 중 하나는 “dark 모드”의 도입이었습니다. 지난 수 년, 우리는 흰색 배경 & 회색 버튼만이 우리가 할 수 있는 유일한 선택이었죠. 그리고 드디어 마이크로소프트는 “dark 모드”를 선보이게 되었습니다. dark 모드에서는 윈도우 모든 항목들이 이에 맞추어 색상이 변경됩니다. dark (이름 정말 잘 지었어요!) 모드로 설정하면 앱이 이 설정을 이해하고 전환하게 되는데요. 아쉽게도 아직 VCL이 이 부분까지는 완벽하게 지원하고 있지는 못합니다.
dark 모드 감지
프로그램을 실행하면 윈도우의 “dark 모드” 또는 “light 모드” 중 어떤 모드를 선택할 지를 감지할 수 있어야 합니다. 이 기능은 현재 VCL에서는 지원 되지 않는 일련의 API 호출에 의해 처리됩니다. 다행히 이를 확인할 수 있는 레지스트리 키가 있습니다.
프로그램이 “dark” 를 감지한다면, 델파이로 개발한 프로그램에 ‘dark’ 테마를 불러오라고 전해줘야 합니다. 반대로 ‘light’ 모드를 감지하면, VCL 테마를 밝은 색상으로 구성할 수 있도록 해주어야겠죠.
VCL앱에서 ‘dark’ 모드를 쉽게 감지할 수 있는 방법
어려운 일이라고 해서, 해결할 수 없다면 그건 델파이가 아니죠. 하지만 심지어 델파이는 쉬운 방법까지 제공합니다! 작은 유닛 하나만 있으면 됩니다. 직접 작성한 유닛(unit) 인데요. 윈도우 dark 또는 light 모드를 감지해서 알맞은 테마를 불러오도록 하는 유닛이죠 – 물론 무료이고, 오픈 소스로 배포중입니다.
델파이 Dark 모드 유닛
깃허브(GitHub) 리파지토리에 올려놓았습니다: https://github.com/checkdigits/delphidarkmode
여러분의 로컬 PC에 복제하세요.
개발한 델파이 프로젝트에서 “Add to Project” (shift + F11)을 누르고 DelphiDarkMode 유닛을 복제해 놓은 위치로 이동합니다.
DelphiDarkMode 유닛과 윈도우 DARK 모드에 대한 더욱 자세한 내용은 블로그에서 확인할 수 있습니다 (CodeRage에서 다뤘던 내용들, 영문): https://www.codedotshow.com/blog/coderage-2019-vcl-the-dark-side/
델파이 Dark 모드로 델파이 테마를 자동으로 변경하기
먼저 두 개의 VCL 테마를 선택하고 앱에 적용해야 합니다.
프로젝트를 열고, 옵션에서 “appearance”를 선택하세요.
두 가지 테마 “light mode”와 “dark mode”가 있을텐데요. 잠시 후 필요하니까 테마 이름을 정확하게 적어두세요.
저는 “ Windows10 “과 “ Windows10 Dark “라고 이름을 지어줬습니다. VCL에는 멋진 VCL 테마들이 정말 많습니다. 겟잇(GetIt)에서 다운로드 받을 수도 있습니다. Delphi Styles 페이지에서 커스터마이징된 테마들을 받아서 사용할 수도 있죠: https://www.delphistyles.com/vcl/index.html
여러분의 프로그램으로 돌아가서 다음의 코드를 작성하세요:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// ... add to your form's definition private procedure HandleThemes; end; uses WindowsDarkMode; procedure TForm1.FormCreate(Sender: TObject); begin HandleThemes; end; procedure TForm1.HandleThemes; begin SetAppropriateThemeMode('Windows10 Dark', 'Windows10'); end; |
이제 프로그램을 실행하세요. 윈도우가 dark 모드로 설정되어 있다면, 앱은 “ Windows10 Dark ” 테마를 실행하게 됩니다.
꼭 dark와 light만 설정할 수 있는 건 아닙니다. 원하는 어떤 테마로든 설정할 수 있습니다. 단 한 가지 꼭 주의해야 할 점은 appearance 섹션에 나타날 수 있는 이름으로 설정해야 한다는 것입니다.
앱이 실행되는 동안 윈도우의 dark 또는 light 모드 전환 감지하기
앱이 실행중인 상태에서 사용자가 light에서 dark로 모드를 전환하거나 그 반대로 변경하는 상황이 발생한다면 어떻게 해야 할까요? 윈도우에서는 WM_SETTINGSCHANGE 메시지를 실행중인 모든 최상위 윈도우에 알려줍니다. 이 메시지의 ‘section’ 파라메터는 ImmersiveColorSet 입니다. WM_SETTINGSCHANGE 메시지가 오는 것을 테스트하고, 해당 매개변수를 찾아보면 사용자가 윈도우 테마를 light 또는 dark로 모드 전환하는 것을 알 수 있습니다.
윈도우 dark 또는 light 모드 변경을 감지하는 코드 추가하기
메인 폼에 다음 코드를 추가하세요:
1 |
procedure WMSettingChange(var Message: TWMSettingChange); message WM_SETTINGCHANGE; |
구현 단에 다음 코드를 넣습니다:
1 2 3 4 5 |
procedure TForm1.WMSettingChange(var Message: TWMSettingChange); begin if SameText('ImmersiveColorSet', String(Message.Section)) then HandleThemes; end; |
샘플 앱 실행해보기
델파이 Dark 모드로, 델파이 테마를 자동으로 변경하기
RAD스튜디오, 델파이의 일반적인 경우처럼, 윈도우 설정 변경 메시지를 인식할 수 있는 방법에는 여러가지가 있습니다.
TApplicationEvents 컨트롤을 활용할 수도 있고, OnSettingChange 이벤트 핸들러에 다음과 같이 코드를 추가할 수도 있습니다.
이벤트에 코드를 추가해볼까요.
1 2 3 4 5 6 7 8 |
procedure TForm1.ApplicationEvents1SettingChange(Sender: TObject; Flag: Integer; const Section: string; var Result: Integer); begin if SameText('ImmersiveColorSet', String(Section)) then HandleThemes; end; |
이 컨트롤을 동적으로 만들 수도 있습니다. 개인적으로는 예제에서도 볼 수 있듯이 WMSettingChange 메시지를 활용하는 게 저에게는 더 쉽기는 합니다.
[전체 코드] VCL 앱에서 윈도우 Dark 모드 탐지하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
type TForm1 = class(TForm) Image1: TImage; procedure FormCreate(Sender: TObject); private procedure WMSettingChange(var Message: TWMSettingChange); message WM_SETTINGCHANGE; procedure HandleThemes; end; var Form1: TForm1; implementation {$R *.dfm} uses WindowsDarkMode; procedure TForm1.FormCreate(Sender: TObject); begin HandleThemes; end; procedure TForm1.HandleThemes; begin SetAppropriateThemeMode('Windows10 Dark', 'Windows10'); end; procedure TForm1.WMSettingChange(var Message: TWMSettingChange); begin if SameText('ImmersiveColorSet', String(Message.Section)) then HandleThemes; end; |
테마와 관련된 더 많은 이야기
테마 변경 사항을 올바르게 처리하기 위해서는 더 많은 요소들을 고려해야 합니다. 예를 들어, 테마 설정 중에 accent color 가 있는데, 앱이 인식 및 활용이 가능한 위치에 있어야 합니다. 테두리 색상에 대한 설정도 있습니다. 테마가 변경되면 ‘테마 인식’이 되지 않는 오래된 컨트롤들도 제어해야 합니다. dark 또는 light 모드를 감지하는 것은 여러분이 개발한 프로그램이 윈도우 10에서도 어색하지 않게 잘 융화되어 보일 수 있도록 하는 가장 큰 요소입니다. 실제로 매우 중요하죠.
파이어몽키에서는 Dark 모드를 어떻게 적용할 수 있나요?
크로스 플랫폼 앱에서 Dark 모드를 감지하는 건 조금 더 복잡합니다. iOS에 대해서는 파이어몽키가 이미 이 부분을 지원하고 있습니다. 다만 안드로이드, 맥OS, 리눅스는 좀 까다롭습니다. 특히 리눅스가 정말 까다로워요. 위에서 다루었던 코드는 윈도우 용 프로그램을 개발할 때 사용 가능합니다. 파이어몽키 스타일을 불러오도록 조정할 수는 있지만, 파이어몽키 앱에서의 메시징은 다르기 때문에 같은 코드로 적용하기에는 알맞지 않습니다.
12.0 12.1 AI AWS C++ c++빌더 chatgpt DelphiCon ios rad서버 RAD스튜디오 UI UIUX UX uxsummit vcl 개발 개발사례 고객사례 기술레터 기술백서 데브옵스 데이터 데이터베이스 델파이 리눅스 마이그레이션 맥 머신러닝 모바일 새버전 샘플 세미나 안드로이드 웹 윈도우 인공지능 인터베이스 출시 커뮤니티에디션 코드 클라우드 파이썬 파이어몽키 현대화