Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Probleme mit Skalierung (DPI) bei - zur Laufzeit erstellter - Controls (https://www.delphipraxis.net/182598-probleme-mit-skalierung-dpi-bei-zur-laufzeit-erstellter-controls.html)

Kyro 3. Nov 2014 23:14

Probleme mit Skalierung (DPI) bei - zur Laufzeit erstellter - Controls
 
Ich versuche seit längerem eine Anwendung für höhere DPI-Skalierungen (120, 144, 192 dpi) fit zu machen...

Leider stellte ich jetzt erst heraus dass jedes Controls und sogar ganze Frames(!) die während der Laufzeit erstellt werden im Gegensatz zu den Design-Controls auf dem Formular (Mainform.Scaled=True) gar nicht auf die höhere DPI-Einstellung des Betriebssystems skaliert werden :-(

Hat jemand eine Idee wie ich Windows dazu bringe diese Controls nachträglich zu skalieren, oder muss ich etwas anderes beim erstellen der Controls achten? (siehe Beispiel)

1) Einen Button auf die Form legen - (Width=75, Height=25, Left=100, Top=5 Caption='Button #1')
2) Im FormCreate...
Code:
procedure TMainform.FormCreate(Sender: TObject);
var RuntimeButton: TButton;
begin
  RuntimeButton := TButton.Create(Mainform);
  RuntimeButton.top := 5;
  RuntimeButton.Left := 5;
  RuntimeButton.Height := 25;
  RuntimeButton.Width := 75;
  RuntimeButton.caption := 'Button #2';
  RuntimeButton.Parent := Mainform;
end;
3) Nun das ganze auf einem PC laufen lassen auf dem z.B.: 120dpi (125%) eingestellt sind
(Meine Erwartung wäre dass die beiden Buttons gleich groß sind, leider ist Button #2 bei mir kleiner bzw. nicht skaliert)

Die komplette Skalierung selbst zu übernehmen (Mainform.Scaled=False + ScaleBy? verwenden) wäre für mich auch OK bzw. sogar wünschenswert weil man damit ja auch während der Laufzeit "frei" skalieren könnte... Allerdings scheitern meine Versuche darin das dann etliche Controls - trotz richtig gesetzter Anchors - für mich nicht nachvollziehbar überlappen. (Was nicht passiert wenn Scaled=True und der Frame im Design eingebunden wurde)

(OS=Windows 7, Windows 8.1, Delphi XE2)

himitsu 3. Nov 2014 23:26

AW: Probleme mit Skalierung (DPI) bei - zur Laufzeit erstellter - Controls
 
Beim Laden der DFM wird, wenn die Skalierungsoption aktiv ist, nach dem Laden jeder Positions-Wert umgerechnet, also die Komponenten bekommen die skallierten Werte zugewiesen.

Wenn du nun manuell Komponenten erstellst, dann mußt du das ebenfalls selber entsprechend umrechnen.


Eventuell kann man die Delphi-Skalierungsfunktion für seine Komponenten manuell aufrufen, nach dem Erstellen. (falls sie auf einzelne Komponenten angewendet werden kann und vorallem wenn sie nicht privat ist)


Deine Erwartung ist also falsch, da man die Komponentenposition in physikalischen Pixeln und nicht in logischen Pixeln angibt.
Das ist vorallem krank, wenn man seinen Code versioniert und den auf einem anderem Rechner mit anderer Skalierung öffnet, dann wird die ganze DFM umgeschrieben, wenn man dort speichert.

Bei FMX mag das eventuell anders sein, da man dort einen Skalierungsfaktor "unabhängig" von den Positionsangaben einstellen kann, also dort mit einer logischen Position.

Kyro 4. Nov 2014 09:17

AW: Probleme mit Skalierung (DPI) bei - zur Laufzeit erstellter - Controls
 
Danke für die Antwort, allerdings weiß ich immer noch nicht so recht wie ich es richtig angehen soll.

Zitat:

Beim Laden der DFM wird, wenn die Skalierungsoption aktiv ist, nach dem Laden jeder Positions-Wert umgerechnet, also die Komponenten bekommen die skallierten Werte zugewiesen
... und genau das will ich während der Laufzeit für ein Control (z.B.: einem Frame) manuell auslösen!

Die Lösung kann aber doch nicht darin bestehen jedes einzelne Control manuell umzurechnen?!, da muss es doch eine Funktion, API, etc. geben die das für mich erledigt? (Das wird aber vermutlich nicht ScaleBy sein, denn damit komm ich nicht auf das gleiche Ergebnis?!)

Das mit den logischen und physikalischen Pixeln hab ich verstanden, allerdings ändere ich auch nicht die Größen oder Positionen der Controls auf dem Frame während der Laufzeit - Aber ich vermute das hilft mir hier auch nicht weiter?!

*hmmm* Die Antwort dazu habe ich wohl schon (hier ) gefunden... Verdammt!

Wie macht ihr das denn?

Ich will das wenn schon gleich "richtig" angehen, sodass ich eventuell auch das neue Feature unter Windows 8.1+ ("per monitor DPI Scaling") berücksichtige (damit ich nicht wieder alles von vorne machen muss) Hat schon jemand damit Erfahrung gemacht?

himitsu 4. Nov 2014 10:48

AW: Probleme mit Skalierung (DPI) bei - zur Laufzeit erstellter - Controls
 
Auf die Schnelle konnte ich jetzt nicht entdecken, wo Delphi das, beim Laden, umschreibt.

Bis auf die Stelle, wo Form.Font.Height angepasst wird.
Zitat:

Delphi-Quellcode:
procedure TCustomForm.ReadState(...
...
      if (sfFont in ScalingFlags) and (FPixelsPerInch <> Screen.PixelsPerInch) then
        Font.Height := MulDiv(Font.Height, Screen.PixelsPerInch, FPixelsPerInch);

Es wird ja nicht nur Left, Top, Width und Height angepasst, sondern auch die Margins, Font.Size, Constraints, BorderWidth usw.


PS: Du mußt es wohl nur machen, wenn Form.Scaled=True ist.

Insider2004 16. Nov 2014 15:07

AW: Probleme mit Skalierung (DPI) bei - zur Laufzeit erstellter - Controls
 
http://community.embarcadero.com/ind...rt-4k-displays


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:01 Uhr.

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