FIX: TnmpThumbView – Designer-Crash beim Platzieren der Komponente
TnmpThumbView – Designer-Crash beim Platzieren der Komponente (Canvas.TextHeight ohne Handle)
Beschreibung des Problems
-------------------------
Beim Platzieren meiner Komponente TnmpThumbView im Lazarus-Designer kam es zu folgendem Fehler:
Control "nmpThumbView1" has no parent window.
TWinControl.CreateWnd ... ERROR WndParent=0
Canvas.TextHeight → HandleNeeded → CreateWnd
Der Designer brach sofort ab mit:
"Fehler beim Verschieben der Komponente TnmpThumbView…"
Zur Laufzeit funktionierte die Komponente einwandfrei. Der Fehler trat ausschließlich beim Erzeugen im Designer auf.
Ursache
-------
Der Lazarus-Designer erzeugt Komponenten in mehreren Schritten:
1. Instanz wird erstellt
2. Bounds werden gesetzt
3. Resize wird aufgerufen
4. UpdateScrollBar wird aufgerufen
5. CalcLayoutPerfectFit wird aufgerufen
6. ABER: das Fensterhandle existiert zu diesem Zeitpunkt noch nicht
In meiner Komponente wurden jedoch in CalcLayoutPerfectFit und Paint folgende Canvas-Operationen ausgeführt:
- Canvas.Font.Assign(...)
- Canvas.TextHeight(...)
- Canvas.TextWidth(...)
- Canvas.StretchDraw(...)
Diese Operationen benötigen ein gültiges Fensterhandle. Da der Designer das Handle erst später erzeugt, führte das zu einem Crash.
Fix
---
Ich habe die Komponente design-sicher gemacht, indem ich Canvas-Zugriffe blockiere, solange:
- csDesigning in ComponentState ODER
- not HandleAllocated
gilt.
Fix in CalcLayoutPerfectFit (kompletter Block):
if (csDesigning in ComponentState) or (not HandleAllocated) then
begin
TotalWidth := ClientWidth - FScrollBarWidth - (FThumbSpacing * 2);
Cols := TotalWidth div (FThumbWidth + FThumbSpacing);
if Cols < 1 then
Cols := 1;
AvailableWidth := TotalWidth - (Cols - 1) * FThumbSpacing;
ThumbWidthEff := AvailableWidth div Cols;
CaptionHeight := 20; // feste Höhe im Designer
Exit;
end;
Fix in UpdateScrollBar:
if (csDesigning in ComponentState) or (not HandleAllocated) then Exit;
Fix in Resize:
if (csDesigning in ComponentState) or (not HandleAllocated) then Exit;
Fix in Paint:
if not HandleAllocated then Exit;
Ergebnis
--------
- Die Komponente lässt sich wieder problemlos im Designer platzieren
- Keine Canvas-Exceptions mehr
- Dummy-Thumbnails werden wieder nebeneinander angezeigt
- Laufzeitverhalten unverändert
- Komponente ist jetzt vollständig design-sicher
Hinweis
-------
Der Fix ist unabhängig von Lazarus-Version und GTK-Version.
Getestet unter:
- Lazarus 4.2 und 4.4
- Linux Mint 21.x und Mint 22 „Tera“
- GTK2
Wenn jemand denselben Fehler hat:
Canvas niemals benutzen, bevor das Handle existiert. Das gilt besonders für TextHeight, TextWidth, Font.Assign, StretchDraw usw.
TnmpThumbView – Designer-Crash beim Platzieren der Komponente
-
Nora Madeleine
- Beiträge: 7
- Registriert: Mo 5. Jan 2026, 16:44
- OS, Lazarus, FPC: Linux Lazarus (L 4.4.0 FPC 3.2.2)
- CPU-Target: AMD
TnmpThumbView – Designer-Crash beim Platzieren der Komponente
Zuletzt geändert von Nora Madeleine am Sa 10. Jan 2026, 12:06, insgesamt 1-mal geändert.
Re: TnmpThumbView – Designer-Crash beim Platzieren der Komponente
Genau. Als Ausweg kann man ein temporäres Bitmap erzeugen, dessen Canvas den gewünschten Font zuweisen und dann Bitmap.Canvas.TextHeight und Bitmap.Canvas.TextWidth verwenden.Nora Madeleine hat geschrieben: Do 8. Jan 2026, 17:18 Canvas niemals benutzen, bevor das Handle existiert. Das gilt besonders für TextHeight, TextWidth, Font.Assign, StretchDraw usw.