Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   TLabel.AutoSize und High DPI (https://www.delphipraxis.net/217127-tlabel-autosize-und-high-dpi.html)

Alucard 3. Mai 2025 13:29

TLabel.AutoSize und High DPI
 
Liste der Anhänge anzeigen (Anzahl: 2)
Ich bin es mal wieder mit einem High DPI-Problem... Dieses Mal betrifft es das AutoSize von TLabel.

Ausgangsszenario:
  • gegeben sei eine Tabellen-artige Struktur, die zur Laufzeit zeilenweise erzeugt wird
  • jede Zeile besteht aus einem TPanel, auf dem mehrere TLabels liegen
  • den Labels wird Text zugewiesen
  • abschließend werden die Labels links- oder rechtsbündig ausgerichtet, wobei TLabel.Width die wesentliche Eigenschaft ist
Code:
procedure TFormBib.AddTrackGridEntry;
const TrackGridEntry : integer = 22;
var i : byte;
begin
//Trackgrid verlängern
SetLength(TrackGrid, Length(TrackGrid) + 1);

With TrackGrid[High(TrackGrid)] do
     begin
     Track  := TPanel.Create(Self);
     Nummer := TLabel.Create(Self);
     {...}

     Track.Parent  := ScrollBoxPlayTracks;
     Nummer.Parent := Track;
     {...}
     end;

With TrackGrid[High(TrackGrid)].Track do
     begin
     ParentBackground := false;

     BevelOuter := bvNone;
     BevelInner := bvNone;

     Top    := TrackGridEntry * High(TrackGrid);
     Height := TrackGridEntry;

     If High(TrackGrid) mod 2 <> 0
        then Color := clGray
        else Color := clMedGray;
     end;

With TrackGrid[High(TrackGrid)] do
     For i := 0 to Track.ControlCount - 1 do
         If Track.Controls[i] is TLabel
            then With (Track.Controls[i] as TLabel) do
                       begin
                       Top := 2;
                       Font.Color := clBlack;
                         
                       Transparent := false;  //nur für den Test
                       Color       := clTeal; //nur für den Test
                       end;
end;
Ich nutze das Programm entweder auf einem Monitor mit 200%-Skalierung oder auf einem Monitor ohne Skalierung, daher ist "Projekt -> Optionen -> Manifest -> DPI-Unterstützung" auf "GDI-Skalierung" gesetzt (Ist das sinnvoll?!). Leider wird das gewünschte Ergebnis (siehe Anhang "gut") nur auf dem Monitor ohne Skalierung erreicht, auf dem skalierten Monitor sind die Labels manchmal zu klein, manchmal zu groß, manchmal auch passend - was final natürlich die Ausrichtung verhagelt (siehe Anhang "schlecht"). Alternativ kann ich die DPI-Unterstützung auch auf "Keine" setzen, dann passen die Labels auch auf dem skalierten Monitor - allerdings sieht dann das ganze Programm wie verpixelte Moppelkotze aus :-/

Irgendwelche Ideen, warum AutoSize sich hier so erratisch verhält? :roll:

P.S.: Vermutlich fehlt zu einer geistreichen Beantwortung hier mal wieder wichtiger Input... Ich weiß nur nicht, wo ich da anfangen soll, einfach nachfragen bitte :thumb:

Uwe Raabe 4. Mai 2025 00:02

AW: TLabel.AutoSize und High DPI
 
Das Problem scheint hier die GDI-Skalierung zu sein. In diesem Mode wird dem Programm eine 100% Skalierung vorgegaukelt, aber Windows verwendet für die Textdarstellung eine höher auflösende Schrift. Dabei kann es je nach verwendeten Zeichen vorkommen, dass die Breite des Labels für das Programm (100%) nicht zu der realen (200%), aber runterskalierten, Breite passt.

Willst du echte HighDPI Unterstützung dann solltest du per Monitor/V2 verwenden. Dann bekommt das Programm die reale Skalierung des Monitors mitgeteilt und kann bzw. muss dazu passend agieren. Das meiste davon tut die VCL aber bereits von sich aus.

Alucard 4. Mai 2025 09:32

AW: TLabel.AutoSize und High DPI
 
Danke für den Hinweis, der das AutoSize-Problem auch tatsächlich behebt.

Leider zerhagelt mir die Einstellung per Monitor/V2 die komplette Darstellung des restlichen Programms :evil: :evil:

Das Projekt ist sprichwörtlich Jahrzehnte-alt... Das scheint sich langsam zu rächen :-(

Gausi 4. Mai 2025 14:41

AW: TLabel.AutoSize und High DPI
 
Zitat:

Zitat von Alucard (Beitrag 1548409)
Das Projekt ist sprichwörtlich Jahrzehnte-alt... Das scheint sich langsam zu rächen :-(

Das kann ich grade sehr gut nachvollziehen. Arbeite grade auch wieder an einem Programm, für das ich zum 20-jährigen Namens-Jubiläum Unterstützung für High-DPI einbauen möchte. Hört sich einfach an, ist aber dann doch ein Fass (fast) ohne Boden. (Wobei ich in dem Kontext auch ein paar andere Dinge im Code aufräume, die damit nur am Rande was zu tun haben.)

Das ist je nach Originalzustand mehr oder weniger viel Arbeit, aber es lohnt sich, imho.

Alucard 4. Mai 2025 14:56

AW: TLabel.AutoSize und High DPI
 
Um ehrlich zu bleiben, muss ich leider auch zugeben, dass das ziemliches Rumgestümper ist, das ich schon immer veranstalte... Ich mache Programmierung nur nebenher und mit Sicherheit wird keiner mit professionellen Kenntnissen meine Art und Weise zu arbeiten, auch nur im Ansatz gutheißen (können) - zu Recht vermutlich.

Ob ich die aktuell aus der Option von Uwe erwachsenden Probleme überhaupt angehen kann, hängt davon ab, ob ich eine Möglichkeit finde, das mein Programm am Ende auf dem skalierten und auch dem unskalierten Monitor vernünftig aussieht.

dummzeuch 4. Mai 2025 16:30

AW: TLabel.AutoSize und High DPI
 
Nur so am Rande bemerkt: Testet Eure High DPI Änderungen unbedingt auch auf Systemen mit unterschiedlichen Scaling-Einstellungen. Ich habe immer wieder sehr viel Spaß damit, erst mit GExperts und jetzt auch mit zwei "normalen" Programmen. Die VCL macht definitiv nicht alles richtig. Und dann funktioniert endlich mit zwei Monitoren mit unterschiedlichem Scaling und ich denke, ich habe das Problem gelöst, da kommt dann der erste Kollege, der "nur" zwei Monitore mit 100% Scaling hat und beschwert sich, dass die Formulare völlig kaputt sind.

Gausi 4. Mai 2025 19:41

AW: TLabel.AutoSize und High DPI
 
Ich stelle hier am Entwicklungsrechner regelmäßig die Skalierung auf dem zweiten Monitor um, vor der Laufzeit, während der Laufzeit, hin- und her verschieben zwischen den beiden Monitoren ... ja, da kann einiges bei schief gehen. Spaßig können auch Formnulare sein, die bei der Änderung der Skalierung grade nicht sichtbar sind.

Zitat:

Zitat von dummzeuch (Beitrag 1548422)
Die VCL macht definitiv nicht alles richtig.

Was ich aktuell am ärgerlichsten finde ist, dass Constraints (also z.B. MinWidth/MaxWidth) anscheinend bei Verwendung von VCL-Styles nicht automatisch skaliert werden beim Wechsel. :?

Und, @Alucard: Jeder hat mal "klein" angefangen, und niemand ist perfekt. Was ich bei meinem aktuellen Refactoring für Klöpse im Code von "früher" gefunden habe, möchte ich lieber gar nicht erzählen. :lol:

Alucard 5. Mai 2025 07:23

AW: TLabel.AutoSize und High DPI
 
Nochmal zur Sicherheit, ob ich den Unterschied bzw. die Konsequenzen daraus zwischen GDI und Monitor/V2 richtig verstehe...

Beispiel - ein Monitor mit 200%-Skalierung
a) Ich lege im Designer ein Panel auf meine Form mit Koordinaten (x,y)=(8,8) und Größe (w,h)=(30,10).
b) Das gleiche Panel, nur erzeuge ich es dynamisch zur Laufzeit über TPanel.Create mit den gleichen Werten.

Im Fall von GDI wird die Skalierung automatisch erzeugt, das Ergebnis ist für (a) und (b) optisch das gleiche.
Im Fall von Monitor/V2 werden nur die "statischen" Komponenten skaliert (a), alles was dynamisch erzeugt wird (b), muss sich Gedanken um die aktuelle Skalierung machen. Um also (a) wie (b) aussehen zu lassen, muss ich dynamisch das Panel mit (16,16) und (60,20) erzeugen.
Richtig?

Uwe Raabe 5. Mai 2025 09:07

AW: TLabel.AutoSize und High DPI
 
Zitat:

Zitat von Alucard (Beitrag 1548429)
Im Fall von Monitor/V2 werden nur die "statischen" Komponenten skaliert (a), alles was dynamisch erzeugt wird (b), muss sich Gedanken um die aktuelle Skalierung machen. Um also (a) wie (b) aussehen zu lassen, muss ich dynamisch das Panel mit (16,16) und (60,20) erzeugen.
Richtig?

Nein, aber du musst eventuell die Zuweisung des Parent erst nach dem Setzen der Größe machen. Jedes TControl wird mit 96dpi erzeugt und beim Zuweisen des Parent wird es entsprechend skaliert. Du kannst das einfach mal in einem kleinen VCL-Programm ausprobieren.

Für Anpassungen nach dem Zuweisen des Parents müssen alle hart-codierten oder auf 96dpi bezogenen Werte umgerechnet werden. Dabei helfen aber die verschiedenen ScaleValue Overloads des Controls.

Den möglicherweise größeren Aufwand hat mein bei der Umstellung aber eher mit den Icons.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:27 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz