Have an amazing solution built in RAD Studio? Let us know. Looking for discounts? Visit our Special Offers page!
BeiträgeC++DelphiIDERAD Studio

HighDPI Entwicklung unter Windows

cg dach highdpi newsletter blog 1200x675

Es gab mal Zeiten, da waren 1024×768 das Maß aller Dinge bei der Auflösung von Bildschirmen. Kleinere Monitore mit 800×600 Punkten und die „Luxusmodelle“ betrieb man mit 1280×1024.

Diese Zeiten sind längst vorbei. Heute gibt es ein breites Spektrum an Displaygrößen, physikalischen Auflösungen und Pixeldichten. Die eigentliche Displaygröße (zumeist gemessen in Zoll) korreliert aber nicht oder nicht zwangsläufig mit der physikalischen Auflösung (gemessen in Pixeln X×Y). So sind typische Vertreter von Full-HD-Fernsehern mit 55 oder gar 65 Zoll mit Auflösungen von 1920×1080 üblich. Auf der anderen Seite hat das aktuelle iPhone 12 Pro Max auf 6,7 Zoll eine physikalische Auflösung von 2778×1295 Pixeln. Circa ein Zehntel der Displaydiagonale bei höherer Auflösung.

Natürlich hat dies auch etwas mit dem Betrachtungsabstand zu: Ein Fernseher ist typisch einige Meter von meinen Augen entfernt. Ein Smartphone eher im Bereich der zweistelligen Zentimeter. Im Nahbereich kann das menschliche Auge „höher auflösen“. Apple nennt das „Retina Display“ oder gar „Super Retina Display“.

Eine massgebliche Zahl, die diese Bildschirme beschreibt, sind die DPI: Dots per Inch. Früher waren das zumeist (die 1024x768er-Zeiten) 96 DPI: Also auf einem Quadratzoll (2,54×2,54 cm) waren das 96×96 Pixel. Da war die Welt noch in Ordnung beziehungsweise für den Windows Desktop-Entwickler einfach. Heute gibt es auf Smartphones, Tablets aber auch auf dem Desktop mit Windows Bildschirme mit 300 und mehr DPI: Notebooks mit 13 Zoll Display und 3840×2160 Pixeln (331 DPI).

Bemerkung: Ich mache hier keinen Unterschied zwischen DPI und PPI, was bei der Druckausgabe durchaus einen Unterschied macht. DPI und PPI werden hier synonym verwandt.
Betrachtet wird hier auch ausschliesslich Windows 10 (in neueren Editionen; ab 1703 Creators Update), da diese das Skalieren von Anwendungen beherrschen. Über Monitor / Per Monitor (v1) wird ab Windows 8.1 unterstützt.
Icons von Icons8

Wo liegt die Problematik?

Benutzer können Monitore in vielerlei Hinsicht einsetzen. Mit unterschiedlichen Konfigurationen und Setups

  • Personen, die größere Schriftarten gegenüber mehr Inhalt bevorzugen (höhere Skalierung)
  • Personen, die mehrer Monitore einsetzen (zB ein 24″ Gerät mit nativen 1920×1080 und ein 30″ Display mit 3840×2160) mit unterschiedlichen Skalierungsfaktoren in Windows (100% vs 200%)
  • Umschalten vom internen Display eines Notebooks zu einem externen Display (Docking) mit höherer Auflösung
  • Remote-Sessions über Remotedesktop, Teamviewer, AnyDesk, VNC, ….. mit unterschiedlichen Skalierungen
  • Die Dynamik beim temporären Umschalten der DPI Skalierung: Reagiert die Anwendung darauf?

Windows Anwendungen auf Basis der klassischen Win32/Win64-API (wie zB Delphi/C++Builder) können Informationen darüber beinhalten, ob diese sich an die Skalierung anpassen können. Der Windows Task-Manager kann dieses sogar anzeigen:

dpitaskmanager

Was beutetet das nun?

Dazu mal eine Tabelle. Bilder sind „klickbar“ zum Vergrößern.

(Eine Windows Desktopanwendung mit Delphi. Eine Toolbar mit Icons (16×16) und eine Grafik (Cat content!) in 150×150 Pixeln ohne Stretched-Property- Die DPI Unterstützung ist eine Projektoption in Delphi/C++Builder unter Project | Optionen -> Anwendung -> Manifest -> DPI Unterstützung // „Per Monitor v2“ == „Über Monitor v2“)

DPI Unterstützung 
/ Keiner Per Monitor v2 GDI Skalierung
 100%   dpikeiner100 dpiperm100 dpigdi100
 200% dpikeiner200 dpiperm200 dpigdi200

Bei 100% Skalierung (von Windows) sieht das alles erwartungsgemäß gut aus. Problematisch werden dann hohe DPI (200%) Konfigurationen:

  • Mit „Keiner“ DPI Unterstützung sehen die Schrift und die Icons schlecht aus
  • Mit „Per Monitor v2“ sieht die Schrift gut aus, aber die Icons und die Grafik werden nicht hochskaliert (das liegt daran, daß die Grundlage der Grafiken weiterhin bei 16×16 bzw 150×150 Pixeln bleibt)
  • Mit „GDI Skalierung“ sieht der Text gut aus und die Grafiken (Icons, Bild) werden hochskaliert….. immerhin.

Dabei bedeuten die Einstellungen folgendes:

Keiner / DPI Unaware:

Dies sind Apps, die immer unter der Annahme von 100 % Skalierung (96 DPI) gerendert werden. Es wird kein Versuch unternommen, die Skalierung durch die App selbst auszugleichen.

Unbekannt:

Keine explizite Einstellungen für die DPI Darstellung

System bekannt / System DPI Aware:

Dies sind Apps, die den DPI des Hauptbildschirms zum Zeitpunkt der Anmeldung des Benutzers an seinem Computer kennen (genannt „System-DPI“). Diese Apps skalieren gut auf dem Hauptdisplay, sehen aber auf einem sekundären Display mit einer anderen DPI unscharf aus.

Über Monitor / Per Monitor (v2):

Dies sind Apps, die Inhalte mit unterschiedlichen DPI rendern und die DPI-Skalierung on the fly ändern können, wenn die Anwendungen zwischen Monitoren mit unterschiedlichen DPI verschoben werden. Wenn sie gut gemacht sind, sehen diese Apps unabhängig von der DPI des Monitors gut aus.
– Die Anwendung wird benachrichtigt, wenn sich die DPI ändert (sowohl die Top-Level- als auch die Child-HWNDs)
– Die Anwendung sieht die rohen Pixel jeder Anzeige
– Die Anwendung wird nie von Windows als Bitmap skaliert
– Automatische DPI-Skalierung von Nicht-Client-Bereichen (Fensterbeschriftung, Bildlaufleisten usw.) durch Windows
– Win32-Dialoge (aus CreateDialog) werden von Windows automatisch DPI-skaliert
– Bitmaps aus Windows Controls (Checkboxen, Radiobuttons, etc) werden automatisch mit dem entsprechenden DPI-Skalierungsfaktor gerendert
Wichtiger Hinweis: Microsoft hat „Per Monitor V2“ nicht für MDI Anwendungen und deren untergeordneten Formulare angepasst. Das sieht das alles wieder anders aus. Im wahrsten Sinne des Wortes.

GDI Skalierung:

Skalierung über GDI. Verbessert die Lesbarkeit von Texten enorm. Kann aber „Clipping“ und „Kerning Probleme“ verursachen: Schrift wird nicht richtig dargestellt und kann unterschiedliche Lauflängen haben (Kerning) oder in dem vorgesehen Platz nicht mehr reinpassen (Clipping)

Die Problematik der Grafiken liegt darin begründet, daß es keine hochauflösenden Bilder und/oder Icons als Ressourcen gibt, die von Windows skaliert werden können. Dabei ist das nicht nur auf „echte Grafiken“ beschränkt, sondern auch auf GUI-Elemente:

100% / 200% mit per Monitor V2 / 200% mit GDI Skalierung

dpiwincontrol100dpiwincontrolpmv2200dpiwincontrolgdi200

NB: Die Einstellungen, die man in den Projekteigenschaften machen kann, kann man auch innerhalb von Windows überschreiben. In den Eigenschaften einer Anwendung. Interessanterweise ist dieser Windows-Dialog selbst nicht skalierend; er hat auf 200% verschwommenen Text:

dpiappproperties

Dabei entspricht das „System (Enhanced)“ der GDI Skalierung.

Wie hilft einem Delphi / C++Builder / RAD Studio?

Generell empfiehlt es sich, die „Per Monitor v2“ Skalierung zu benutzen. Grafiken / Icons können über die Kompontnen der ImageCollection/VirtualImageList und VirtualImage auch passend („mit mehr Grafikinformation“) vorgehalten und richtig skaliert werden. Siehe dazu das Video von Olaf Monien (siehe unten).

Auf der obersten Ebene wurden in der Unit VCL.Classes von 10.3, und mit 10.4 verbessert, die folgenden Änderungen vorgenommen, um dieses Feature zu unterstützen:

  • Die globale Funktion GetSystemMetricsForWindow kapselt einen Aufruf der neuen Funktion GetSystemMetricsForDPI, falls verfügbar, ansonsten der herkömmlichen Funktion GetSystemMetrics. Sie hat einen Handle-Parameter, der an die API übergeben wird. Wir empfehlen Ihnen, diese neue Funktion anstelle der herkömmlichen Funktion WinApi.GetSystemMetrics zu verwenden, wenn Sie Per Monitor V2 unterstützen möchten.
  • Die Methode TControl.GetSystemMetrics (nIndex: Integer) gibt den Wert der Systemmetriken für die Steuerelemente zurück, die die neue globale Funktion GetSystemMetricsForWindow aufrufen.
  • TControl.GetCurrentPPI gibt abhängig vom aktuellen Bildschirm die DPI für das Steuerelement zurück und TControl.CurrentPPI ist eine schreibgeschützte Eigenschaft, die dieser Funktion zugeordnet ist.

In RAD Studio 10.4 wurde die Architektur der VCL-Stile zur Unterstützung von High-DPI-Grafik und 4K-Monitoren wesentlich erweitert.

In früheren Versionen von RAD Studio wurde ein einzelnes Bild für alle grafischen Elemente eines Stils und spezifische Informationen zu den Größen der Elemente verwendet.

Jetzt werden alle grafischen Elemente automatisch für die richtige Auflösung des Monitors skaliert, auf dem das Element angezeigt wird. Das bedeutet, dass die Skalierung von der DPI-Auflösung des Zielcomputers bzw. des aktuellen Monitors bei Mehrmonitorsystemen abhängt.

Mit dem Stil-Designer können jetzt weitere Bilder für bestimmte Objekte und verschiedene Auflösungen einbezogen werden.

Für die Namen der neuen Elemente wird die Konvention „Name des Objekts + DPI-Information“ verwendet, mit einem Unterstrich zwischen dem Namen und der Größeninformation im folgenden Format:

  • [Name]_15x (für 150% DPI)
  • [Name]_20x (für 200% DPI)

RAD Studio 10.4 fügt nur Elemente für 150% und 200% DPI für die meisten der im Produkt vorhandenen VCL-Stile hinzu.

Weitere Infos / Referenzen unter

A Delphi Developers Guide for 4K Displays: http://download.ec-software.com/delphi-developers-guide-4k.zip
High DPI Desktop Application Development on Windows https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
GDI Scaling https://blogs.windows.com/windowsdeveloper/2017/05/19/improving-high-dpi-experience-gdi-based-desktop-apps/
Olaf Monien / Developer Experts https://www.youtube.com/watch?v=f17XJDkeCUs

 


Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.
Start Free Trial   Upgrade Today

   Free Delphi Community Edition   Free C++Builder Community Edition

Kommentieren

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

IN THE ARTICLES