TForm.PixelsPerInch ist in OnCreate und OnShow unterschiedlich, Fehler?

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
Antworten
Soner
Beiträge: 816
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

TForm.PixelsPerInch ist in OnCreate und OnShow unterschiedlich, Fehler?

Beitrag von Soner »

Bei der Anpassung meines Programmes ist mir aufgefallen, dass TForm.PixelsPerInch ist in OnCreate und OnShow unterschiedlich. In OnShow nimmt es den Wert des Screen.PixelsPerInch an, sollte das nicht von Anfang an geschehen? Weil TForm.PixelsPerInch und ScaleDesignToForm bis dahin nutzlos sind. Ich habe auf Basis von ScaleDesignToForm eigene Funktion geschrieben, damit funktionieren Anpassungen.

Sollte ich das als Fehler melden oder habe ich etwas Falsch verstanden?

Screenshot:
screenshot.png
screenshot.png (77.09 KiB) 182 mal betrachtet
Testprogramm ist als Anhang beigefügt.

Edit:
Mir ist eben gerade einfallen, wann wird bei Multimonitorsysteme entschieden auf welchem Monitor es angezeigt wird, das sollte man auch bei Fehlerkorrektur berücksichtigen.
Dateianhänge
FormPPIOnCreateBug-pub.zip
(48.09 KiB) 9-mal heruntergeladen

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7443
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: TForm.PixelsPerInch ist in OnCreate und OnShow unterschiedlich, Fehler?

Beitrag von af0815 »

Ich verwende OnCreate nur sehr wenig, da zu diesem Zeitpunkt nicht alles so 100% initialisiert sein braucht. Ich verwende immer das erste OnActivate vom Mainform um meine Initialisierungen zu machen. Weil zu diesen Zeitpunkt sind sicher alle Initialisierungen durch (auch alle automatischen Forms erzeugt) und alles stabil.
Vor allen hat man hier einen Zeitpunkt, wo man die Applikation auch sauber gleich wieder herunterfahren kann, wenn bei den eigenen Initialisierungen was schiefläuft (Server oder DBs nicht erreichbar, Laufwerke nicht gemountet,....).

Ich vermute bei deinem Problem einen solchen Hintergrund, das OnCreate etwas zu früh ist, für manche Abfragen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

wp_xyz
Beiträge: 5490
Registriert: Fr 8. Apr 2011, 09:01

Re: TForm.PixelsPerInch ist in OnCreate und OnShow unterschiedlich, Fehler?

Beitrag von wp_xyz »

Die Umschaltung der PPI erfolgt in AutoAdjustLayout das erstmals in TCustomFrom.AfterConstruction aufgerufen wird, und zwar NACH DoCreate, wo das OnCreate-Event feuert:

Code: Alles auswählen

procedure TCustomForm.AfterConstruction;
var
  MonPPI: Integer;
begin
  SetRestoredBounds(Left, Top, Width, Height, True);
  DoCreate;
  EndFormUpdate; // the BeginFormUpdate is in CreateNew
  inherited AfterConstruction;

  if Monitor <> nil then
    MonPPI := Monitor.PixelsPerInch
  else
    MonPPI := Screen.PixelsPerInch;
  if Application.Scaled and Scaled and (MonPPI > 0) and (MonPPI <> PixelsPerInch)
  and not (csDesigning in ComponentState) then
    AutoAdjustLayout(lapAutoAdjustForDPI, PixelsPerInch, MonPPI,
                     Width, MulDiv(Width, MonPPI, PixelsPerInch));
end;
Abgesehen davon, wird AutoAdjustLayout immer dann aufgerufen, wenn sich die PPI ändern (wie das bei einem Mehr-Monitor-System ist, weiß ich nicht, weil mein Schreibtisch nur Platz für einen hat...). Die Arbeitsmethode ist dann DoAutoAdjustLayout, das man überschreiben sollte, um besondere Skalierungen unterzubringen (z.B. bei internen Abmessungen von eigenen Controls). Durchsuche den LCL-Code nach "DoAutoAdjustLayout" - das wird an einer Vielzahl von Stellen aufgerufen.

Soner
Beiträge: 816
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: TForm.PixelsPerInch ist in OnCreate und OnShow unterschiedlich, Fehler?

Beitrag von Soner »

@af0815
Ich hatte vor Jahren angeschaut, bei OnCreate ist alles schon da, deshalb benutze ich auch bei Frames AfterConstruction weil OnCreate dort fehlt. Es gibt sehr seltene Fälle wo man aufOnShow oder in deinem Fall auf OnActivate ausweichen muss, wie z.B. ActiveX-Container.
Vorteil von OnCreate ist, dass die Größenangaben von Controls nicht an OS weitergeleitet werden (siehe LockRealizeBounds/UnlockRealizeBounds), bei Verwendung von OnActivate/OnShow ist das Fenster schon aufgebaut, wenn man jetzt etwas ändert, dann wird alles mehrfach neu berechnet und gezeichnet.

@wp
Der Tipp mit AutoAdjustLayout ist gut, ich verwende das jetzt in meiner Komponente und es funktioniert.
Multi-Monitor-System kannst du mit Fernseher simulieren. Ich mache das immer, ich habe an den Fernseher ein MiniPC angeschlossen, den ich als MediaPC verwende, darauf habe ich NoMachine installiert, damit verbinde ich zum MiniPC, da muss nicht mal Fernseher eingeschaltet sein. Vorteil von NoMachine ist, dass es die Auflösung von MiniPC beibehält während RemoteDekstop es auf dein Monitor anpassen würde. Man könnte sein Computer auch direkt an den Fernseher anschließen.

Ich frage mich wie Lazarusprogramme bei wahren Multi-Monitor-System mit unterschiedliche Auflösungen aussehen würde. D.h. wenn Monitore nebeneinander aufgestellt und bei Windows "Desktop erweitern" eingestellt ist. Dann sollte man ein Fenster von einem Monitor zum anderem Monitor verschieben und halb auf dem linken Monitor und halb auf dem rechten loslassen. Ich teste das mal nachher.

Ich habe mal PixelsPerInch von Anfang richtig gesetzt und ausprobiert, dann funktionierte die automatische Skalierung nicht richtig. Hier wird es gesetzt:

Code: Alles auswählen

constructor TCustomDesignControl.Create(TheOwner: TComponent);
begin
  //...
  //soner es war so: FPixelsPerInch := FDesignTimePPI;
  FPixelsPerInch := Screen.PixelsPerInch;
  //..
end;
Also scheinen meine Funktion für OnCreate und AutoAdjustLayout für die selbsterstellte Komponenten der richtiger Weg zu sein.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7443
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: TForm.PixelsPerInch ist in OnCreate und OnShow unterschiedlich, Fehler?

Beitrag von af0815 »

Du kannst bei Multimonitoren "Löst Windows" haben, wenn du die Position zB. speicherst und dann auf ein Single Environment umschaltet. Beispiel Laptop von der Dockingstation runter nimmst. Vorher 2 Bildschirme mit hoher Auflösung und plötzlich nur Laptop Bildschirm.

Das war immer schon frickelig dann die Fenster außerhalb des Bildschirm Bereichs einzusammeln. Ist aber nicht Lazarus spezifisch, sondern Design spezifisch. Blöd war nur, wenn das Layout nach einem neuen Start des Programms noch immer falsch war.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Soner
Beiträge: 816
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: TForm.PixelsPerInch ist in OnCreate und OnShow unterschiedlich, Fehler?

Beitrag von Soner »

Das kenne bei uns von Arbeitsplätzen mit verschiedenen Monitoraufläsungen. Ich speichere die Einstellungen zentral in Datenbank, damit man alles bei anderem Arbeitstisch gleich vorfindet. Jetzt rechne ich die Größen und Positionen vor dem Speichern auf DesignTimePPI.

Antworten