ELayoutException - Wie debuggen ?
- af0815
- Lazarusforum e. V.
- Beiträge: 6209
- 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:
ELayoutException - Wie debuggen ?
Hallo,
ich habe plötzlich ein Problem mit einem komplexen Layout. Dabei sind Frames in Frames in Frames in Frames.... verschachtelt. Das hat jahrelang funktioniert. Jetzt plötzlich hat die Applikation einen Fehler. Ich habe das jetzt einkreisen können, es ist in einem Frame, das 2 Panels übereinander beinhaltet, das obere Panel1 enthält Navigationselemente aus Label, Edits, Button,... Dieses Panel hat oben, links und rechts Anchors die es am Frame festmachen.
Das untere Panel2 ist oben am Panel1 festgemacht, die restlichen Seiten am Frame. Auf diesen Frame befinden sich 2 Elemente, ein TabControl und ein WorkSheetgrid. Das WorkSheetGrid ist oben am TabControl festgemacht und die restlichen Seiten am Panel2. Jetzt kommt etwas was ich nicht ganz verstehe:
Das TabControl1 ist oben und links am Panel2 festgemacht.
-> Das funktioniert soweit, nur wenn ich jetzt die rechte Seite an das Panel2 binde, so kommt die obige Fehlermeldung. Nehme ich den Anchor weg so geht es wieder.
Ich gehe davon aus, das es im TabSheet zu einer Situation kommt, das das Layout sich versucht in einer Loop zu aktualisieren, weil die Werte dürften in Schritten von 2 px ändern. Das ist plötzlich bei mir auf Win10 auf diversen Rechnern aufgetreten, die alle mitsamt die aktuellen Patches von M$ erhalten. Weil vor ca. 14 Tagen hat der Code ohne Probleme funktioniert. Daher habe ich auch ein Installationspaket gemacht und das hat Probleme gemacht. Und der Originalcode plötzlich auch. Ich würde auf einen Fix im Widgetset von Win10 tippen, der das in dieser speziellen Kombination auslöst.
Es dürfte kein großes Problem sein, nur ist die Frage, wie kann ich das in der LCL am besten debuggen.
Oder sieht wer in dem Layout noch etwas was ich übersehen habe ?
------ Hinweise -----
Lazarus 2.1.0 r65130 FPC 3.2.2 i386-win32-win32/win64 - da habe ich das Problem nicht gesehen. Wenn ich das Projekt mit der Version rekompiliere dann gibt es keine Fehlermeldung.
Lazarus 2.3.0 rmain-2_3-342-gc44d729ba2 FPC 3.2.3 i386-win32-win32/win64 - da mit lief das Programm bis vor ca. 2 Wochen. Gestern wieder probiert -> Fehler
Lazarus 2.3.0 (rev main-2_3-674-gdda96a3864) FPC 3.2.2 i386-win32-win32/win64 gestern erstellt -> Fehler
ich habe plötzlich ein Problem mit einem komplexen Layout. Dabei sind Frames in Frames in Frames in Frames.... verschachtelt. Das hat jahrelang funktioniert. Jetzt plötzlich hat die Applikation einen Fehler. Ich habe das jetzt einkreisen können, es ist in einem Frame, das 2 Panels übereinander beinhaltet, das obere Panel1 enthält Navigationselemente aus Label, Edits, Button,... Dieses Panel hat oben, links und rechts Anchors die es am Frame festmachen.
Das untere Panel2 ist oben am Panel1 festgemacht, die restlichen Seiten am Frame. Auf diesen Frame befinden sich 2 Elemente, ein TabControl und ein WorkSheetgrid. Das WorkSheetGrid ist oben am TabControl festgemacht und die restlichen Seiten am Panel2. Jetzt kommt etwas was ich nicht ganz verstehe:
Das TabControl1 ist oben und links am Panel2 festgemacht.
-> Das funktioniert soweit, nur wenn ich jetzt die rechte Seite an das Panel2 binde, so kommt die obige Fehlermeldung. Nehme ich den Anchor weg so geht es wieder.
Ich gehe davon aus, das es im TabSheet zu einer Situation kommt, das das Layout sich versucht in einer Loop zu aktualisieren, weil die Werte dürften in Schritten von 2 px ändern. Das ist plötzlich bei mir auf Win10 auf diversen Rechnern aufgetreten, die alle mitsamt die aktuellen Patches von M$ erhalten. Weil vor ca. 14 Tagen hat der Code ohne Probleme funktioniert. Daher habe ich auch ein Installationspaket gemacht und das hat Probleme gemacht. Und der Originalcode plötzlich auch. Ich würde auf einen Fix im Widgetset von Win10 tippen, der das in dieser speziellen Kombination auslöst.
Es dürfte kein großes Problem sein, nur ist die Frage, wie kann ich das in der LCL am besten debuggen.
Oder sieht wer in dem Layout noch etwas was ich übersehen habe ?
------ Hinweise -----
Lazarus 2.1.0 r65130 FPC 3.2.2 i386-win32-win32/win64 - da habe ich das Problem nicht gesehen. Wenn ich das Projekt mit der Version rekompiliere dann gibt es keine Fehlermeldung.
Lazarus 2.3.0 rmain-2_3-342-gc44d729ba2 FPC 3.2.3 i386-win32-win32/win64 - da mit lief das Programm bis vor ca. 2 Wochen. Gestern wieder probiert -> Fehler
Lazarus 2.3.0 (rev main-2_3-674-gdda96a3864) FPC 3.2.2 i386-win32-win32/win64 gestern erstellt -> Fehler
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- af0815
- Lazarusforum e. V.
- Beiträge: 6209
- 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: ELayoutException - Wie debuggen ?
Das debuggen ist gar nicht so schwer. Einfach bei Lazarus "Tools->Configure Build Lazarus" aufrufen und dort bei Profile "Debug IDE" auswählen, ein clear rebuild und es geht schon los mit dem Debuggen.
Ich habe in der Lazarus\lcl\include\control.inc in Zeile 685 mal folgendes aktiviert
Darauf hin wird die Loop laut Log (tmp.txt) ersichtlicher. Das Hauptframe ist XXXBasisFrameXXX, da sieht man wie das jeden Durchlauf um 2 Pixel breiter wird, bis die Überprüfung auf eine Schleife anspricht. Alle anderen Controls werden nachgeführt, eines nach dem anderen. Ist das fertig ist die breite des Frames geändert und der Sch.... beginnt von vorne.
Nehme ich beim TabControl1:TTabControl den rechten Anchor weg und setze den anders (per Programm) so wird das Layout einmal eingerichtet und ist dann stabil - daher keine Loop.
Das kann ich aber nur in der einen speziellen Konfiguration beobachten. Ich habe nur keine Idee warum das Frame bei jeden durchlauf um 2 Pixel breiter wird.
Ich habe in der Lazarus\lcl\include\control.inc in Zeile 685 mal folgendes aktiviert
Code: Alles auswählen
DebugLn(['TControl.ChangeBounds A ',DbgSName(Self),
' Old=',Left,',',Top,',',Width,',',Height,
' New=',ALeft,',',ATop,',',AWidth,',',AHeight,
' KeepBase=',KeepBase]);
Nehme ich beim TabControl1:TTabControl den rechten Anchor weg und setze den anders (per Programm) so wird das Layout einmal eingerichtet und ist dann stabil - daher keine Loop.
Das kann ich aber nur in der einen speziellen Konfiguration beobachten. Ich habe nur keine Idee warum das Frame bei jeden durchlauf um 2 Pixel breiter wird.
- Dateianhänge
-
- Temp.txt
- Log der Loop
- (850.34 KiB) 79-mal heruntergeladen
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1435
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: ELayoutException - Wie debuggen ?
Ich hab das mal nachgebaut. Bei mir gibt es keine Fehlermeldungen.
Lazarus 2.3.0 r65479 FPC 3.3.1 x86_64-win64-win32/win64
Kannst du mal einen Codeschnipsel hochladen, der das provoziert?
Lazarus 2.3.0 r65479 FPC 3.3.1 x86_64-win64-win32/win64
Kannst du mal einen Codeschnipsel hochladen, der das provoziert?
Re: ELayoutException - Wie debuggen ?
So toll das Anchoring von Lazarus ist, so schwierig ist es, die Ursache zu finden, wenn es sich irgendwo verhakt hat. Da ist irgendwo noch ein Häkchen gesetzt, das nicht sein sollte, und schon funktioniert es nicht.
Mein Ausweg ist immer, einen Schritt zurückzugehen und das Anchoring wieder herauszunehmen, wo es geht. In deinem Fall - Panel1 links, oben und rechts am Frame verankert, Panel2 links/rechts/unten am Frame und oben an Panel1 verankert - kann man sich ganz einfach behelfen, in dem man so tut als wäre man bei Delphi: Panel1.Align := alTop, Panel2.Align := alClient (dazu alle Verankerungen von Panel1/Panel2 lösen).
Was ich in der Beschreibung nicht verstanden habe: "Das WorkSheetGrid ist oben am TabControl festgemacht und die restlichen Seiten am Panel2" - meiner Meinung nach sollte das Grid IM TabControl sein, nicht unter ihm.
Mein Ausweg ist immer, einen Schritt zurückzugehen und das Anchoring wieder herauszunehmen, wo es geht. In deinem Fall - Panel1 links, oben und rechts am Frame verankert, Panel2 links/rechts/unten am Frame und oben an Panel1 verankert - kann man sich ganz einfach behelfen, in dem man so tut als wäre man bei Delphi: Panel1.Align := alTop, Panel2.Align := alClient (dazu alle Verankerungen von Panel1/Panel2 lösen).
Was ich in der Beschreibung nicht verstanden habe: "Das WorkSheetGrid ist oben am TabControl festgemacht und die restlichen Seiten am Panel2" - meiner Meinung nach sollte das Grid IM TabControl sein, nicht unter ihm.
- af0815
- Lazarusforum e. V.
- Beiträge: 6209
- 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: ELayoutException - Wie debuggen ?
@fliegermichl
Ein Codeschnippsel zum testen gibt es nicht, sonst wäre das schon in einem Bugreport AUsserdem handelt es sich immer um einen 32 Bit Lazarus.
@wp_xyz
Das TabControl dient zur Auswahl was gerade im WorkSheetGrid angezeigt wird. Vom TabControl werden nur die Pages-Reiter verwendet, die dynamisch erzeugt werden. Das WorkSheetGrid ist absichtlich darunter befestigt, damit sich die Höhe dynamisch anpassen kann, falls die Pages-Reiter mal zweireihig werden.
Ich habe die ganzen Anchors und Aligns mal herausgenommen und langsam nochmals NUR Anchors gesetzt. Das geht alles super, bis ich den letzten rechten Anchor setze. Was mir nur aufgefallen ist, das der Versatz genau der Standardrand vom TabControl ist. Laut Sourcen sind das 2 Pixel. Was auffällig ist, das das ganze im Frame abspielt, jede iteration der Schleife macht das Frame um genau 2 Punkte auf der rechten Seite größer. So als würde der Anchor erzwingen, das der Parent sich vergrößern muss.
Das mit dem Delphi Ansatz werde ich morgen mal probieren. Bei dem Layout sollte das kein Problem sein.
-----
Grundlegend ist das Arbeiten mit dynamischen Frames und den ganzen Anchor echt steil. Die Frames erzwingen eine absolute Trennung und wieder Verwendbarkeit im Code und mit den Anchors ist das Layout total dynamisch. Egal ob die dann unter Windows oder Linux läuft. Wenn man jetzt auch noch mit Vererbungen im Frame arbeitet, hat man einen Baukasten vor sich, der echt stark ist.
Ein Codeschnippsel zum testen gibt es nicht, sonst wäre das schon in einem Bugreport AUsserdem handelt es sich immer um einen 32 Bit Lazarus.
@wp_xyz
Das TabControl dient zur Auswahl was gerade im WorkSheetGrid angezeigt wird. Vom TabControl werden nur die Pages-Reiter verwendet, die dynamisch erzeugt werden. Das WorkSheetGrid ist absichtlich darunter befestigt, damit sich die Höhe dynamisch anpassen kann, falls die Pages-Reiter mal zweireihig werden.
Ich habe die ganzen Anchors und Aligns mal herausgenommen und langsam nochmals NUR Anchors gesetzt. Das geht alles super, bis ich den letzten rechten Anchor setze. Was mir nur aufgefallen ist, das der Versatz genau der Standardrand vom TabControl ist. Laut Sourcen sind das 2 Pixel. Was auffällig ist, das das ganze im Frame abspielt, jede iteration der Schleife macht das Frame um genau 2 Punkte auf der rechten Seite größer. So als würde der Anchor erzwingen, das der Parent sich vergrößern muss.
Das mit dem Delphi Ansatz werde ich morgen mal probieren. Bei dem Layout sollte das kein Problem sein.
-----
Grundlegend ist das Arbeiten mit dynamischen Frames und den ganzen Anchor echt steil. Die Frames erzwingen eine absolute Trennung und wieder Verwendbarkeit im Code und mit den Anchors ist das Layout total dynamisch. Egal ob die dann unter Windows oder Linux läuft. Wenn man jetzt auch noch mit Vererbungen im Frame arbeitet, hat man einen Baukasten vor sich, der echt stark ist.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- af0815
- Lazarusforum e. V.
- Beiträge: 6209
- 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: ELayoutException - Wie debuggen ?
So, ich habe ein Beispiel zusamengebracht. Es ist recht tricky gewesen, da der Fehler nur im Verbund Frame in Frame auftritt.
Die Ursache habe ich auch eingrenzen können. In der \lazarus\lcl\include\tabcontrol.inc wird beim setzen der TabPosition tpTop auch die Breite mitgeändert. Es wird dort für die Breite die TabControl.ClientWidth genommen. Diese ist aber um die Breite des Randes korrigiert. Meiner Meinung nach müsste dort der Wert von FNoteBook.Width genommen werden, da das FNoteBook geändert werden soll und dabei die Breite ja gleich sein soll.
Das System sollte ja überall gleich sein.
Genaugenommen solllte das auch für tpLeft und tpRigth gelten. dort wird IMHO auch geändert.
Auffallen tut das ganze deswegen, weil das Layout mit dem Frames wesentlich 'weicher' (=dynamisch änderbar) ist.
Was sagt ihr dazu ?!
Edit: Issue: https://gitlab.com/freepascal.org/lazar ... sues/39478
Die Ursache habe ich auch eingrenzen können. In der \lazarus\lcl\include\tabcontrol.inc wird beim setzen der TabPosition tpTop auch die Breite mitgeändert. Es wird dort für die Breite die TabControl.ClientWidth genommen. Diese ist aber um die Breite des Randes korrigiert. Meiner Meinung nach müsste dort der Wert von FNoteBook.Width genommen werden, da das FNoteBook geändert werden soll und dabei die Breite ja gleich sein soll.
Das System sollte ja überall gleich sein.
Genaugenommen solllte das auch für tpLeft und tpRigth gelten. dort wird IMHO auch geändert.
Auffallen tut das ganze deswegen, weil das Layout mit dem Frames wesentlich 'weicher' (=dynamisch änderbar) ist.
Code: Alles auswählen
procedure TTabControlNoteBookStrings.TabControlBoundsChange;
var
NewHeight: LongInt;
NewWidth: LongInt;
begin
inherited TabControlBoundsChange;
FNoteBook.TabPosition:=TabControl.TabPosition;
case TabControl.TabPosition of
tpTop,tpBottom:
begin
NewHeight:=TabControl.TabHeight;
if NewHeight<=0 then
NewHeight:=FNoteBook.GetMinimumTabHeight;
NewHeight:=Min(TabControl.ClientHeight,NewHeight);
if TabControl.TabPosition=tpTop then
FNoteBook.SetBounds(0,0,TabControl.ClientWidth,NewHeight) // <-- hier
else
FNoteBook.SetBounds(0,TabControl.ClientHeight-NewHeight,
TabControl.ClientWidth,NewHeight); // <-- hier
end;
Edit: Issue: https://gitlab.com/freepascal.org/lazar ... sues/39478
- Dateianhänge
-
- layoutproblem.zip
- (108.04 KiB) 82-mal heruntergeladen
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: ELayoutException - Wie debuggen ?
Ja, wenn ich in den gekennzeichneten Zeilen das TabControl.ClientWidth durch FNotebook.Width ersetze, gibt es keinen Absturz mehr. Keine Ahnung, welche Seiteneffekte das hat...
Du solltest das auf jeden Fall im Bug-Tracker melden, ich glaube, es gibt ein paar Leute, die sich um das kümmern könnten. Nimm aber bitte die Abhängigkeit von fpspreadsheet aus dem Beispiel-Projekt, das hat nichts mit dem Problem zu tun, und schafft für einen, der fpspreadsheet nicht hat, nur eine unnötige Hürde, sich mit dem Problem zu befassen.
P.S.
Sehe gerade, du hast es ja schon gemeldet. Gut. Den Lösungsvorschlag würde ich auch dazuschreiben, oder am besten gleich als Patch-Datei einreichen.
Du solltest das auf jeden Fall im Bug-Tracker melden, ich glaube, es gibt ein paar Leute, die sich um das kümmern könnten. Nimm aber bitte die Abhängigkeit von fpspreadsheet aus dem Beispiel-Projekt, das hat nichts mit dem Problem zu tun, und schafft für einen, der fpspreadsheet nicht hat, nur eine unnötige Hürde, sich mit dem Problem zu befassen.
P.S.
Sehe gerade, du hast es ja schon gemeldet. Gut. Den Lösungsvorschlag würde ich auch dazuschreiben, oder am besten gleich als Patch-Datei einreichen.
- af0815
- Lazarusforum e. V.
- Beiträge: 6209
- 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: ELayoutException - Wie debuggen ?
Abhängigkeit zu fpspreadsheet entfernt und auch einen Kommentar zu eventuellen Lösung gegeben, nur das muss sich ein Wissender ansehen, damit es nicht zu Regressionen kommt.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- af0815
- Lazarusforum e. V.
- Beiträge: 6209
- 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: ELayoutException - Wie debuggen ?
Neue Info Martin hat es sich angesehen. Das Problem ist, das das Frame in Frame in eine Scrollbox gebunden ist und die Scrollbox die untergeordneten Element als Gruppe fragt, wie hättet ihr es gerne. Und das TabControl sagt halt, bitte um 2 px größer. -> Loop und Boom.
Nur wer der Adressat für den Fix ist , verstehe ich nicht. Irgendwie bekomme ich mit meinem englisch Verständnis das nicht auf die Reihe.
https://gitlab.com/freepascal.org/lazar ... _745368981
Wenn es an mich geht - so verstehe ich den Fix nicht, denn der wäre ja nicht allgemeingültig. Der nächste der ein Frame in eine Scrollbox einbaut, steht ja dann genauso auch den Schlauch. Vor allen weis das Frame in Frame ja nicht, wo sein endgültiger Bestimmungsort ist.
Nur wer der Adressat für den Fix ist , verstehe ich nicht. Irgendwie bekomme ich mit meinem englisch Verständnis das nicht auf die Reihe.
https://gitlab.com/freepascal.org/lazar ... _745368981
Wenn es an mich geht - so verstehe ich den Fix nicht, denn der wäre ja nicht allgemeingültig. Der nächste der ein Frame in eine Scrollbox einbaut, steht ja dann genauso auch den Schlauch. Vor allen weis das Frame in Frame ja nicht, wo sein endgültiger Bestimmungsort ist.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 830
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: ELayoutException - Wie debuggen ?
Das ist 'ne allgemeine Beschreibung wie es zu fixen wäre, sie ist nicht direkt an dich gerichtet.af0815 hat geschrieben: ↑Mo 29. Nov 2021, 08:54Nur wer der Adressat für den Fix ist , verstehe ich nicht. Irgendwie bekomme ich mit meinem englisch Verständnis das nicht auf die Reihe.
https://gitlab.com/freepascal.org/lazar ... _745368981
FPC Compiler Entwickler