Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Nochmal StringGridkomponente, Canvas Rect
trm - So 27.05.12 01:23
Titel: Nochmal StringGridkomponente, Canvas Rect
Mit meinem StringGrid komme ich recht gut voran, einen Schönheitsfehler bekomme ich leider nicht weg.
Wenn ein Text in eine Spalte gezeichnet wird, der Text aber zu lang für die Spalte ist, wird dieser auf die Gitterlinie gezeichnet.
Ich müsste einen Weg finden, um ein Canvas in der Breite zü ändern, jedoch komme ich über ClipRect nicht weiter, da dies eine Konstante ist.
Um einen einheitlichen Rand innerhalb der Zelle zu erreichen, habe ich folgendes nach der Textausgabe gemacht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| CanvasTextOut(zCanvas, txtX, txtY, Cells[ACol, ARow]); x := TextWidth(Cells[ACol, ARow]); if x >= ColWidths[ACol] then begin Brush.Style := bsSolid; ARect.Left := ARect.Right - 4; FillRect(ARect); end; |
Aber, wie schon geschrieben, der Text auf der Gitterlinie bleibt.
Wie könnte ich auf zCanvas.Rect.Right (gibt es nicht, nur theoretischer Wert, der geändert werden soll) einwirken, um dies um 2 Pixel zu verkleinern ?
bummi - So 27.05.12 07:41
ich habe keine Delphi 7 zu Hand, kann Dir daher nicht sagen wie dort DrawText(Ex) genau parametrisiert werden musste und ob und wie in Graphis TTextFormats definiert ist, bzw. ob es dort bereits TCanvas.TextRect gab welches DrawText(Ex) verwendet.
Generell ist es so dass Du die Dimensionen des Canvas nicht ändern kannst. Das Canvas bezieht sich immer auf das ganze Grid (nicht auf eine Zelle) und Du musst selbst darauf achten nicht "aus dem Rahmen" zu fallen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var aText:String; fmt:Integer; begin
fmt := 8 + 15; aText := 'Viel zu lang'; InflateRect(Rect,-4,-4); DrawText(StringGrid1.Canvas.Handle, aText, Length(aText), Rect, fmt); end; |
jaenicke - So 27.05.12 09:51
Um die Fläche zu begrenzen gibt es auch die Möglichkeit des Clipping, das du ja auch schon angesprochen hast. Dafür gibt es entsprechende Clipping Funktionen wie ExtSelectClipRgn:
http://msdn.microsoft.com/en-us/library/dd162712(v=VS.85).aspx
Die anderen ähnlichen siehst du dort ja links in der Liste.
Mit dem genannten DrawText sollte das aber gar nicht nötig sein.
Delphi-Laie - So 27.05.12 09:54
Mit folgendem Code läßt sich ein StringGrid bezüglich der Spaltenbreiten skalieren:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| for l:=0 to pred(StringGrid.ColCount) do begin biggestwidth:=StringGrid.Canvas.TextWidth(StringGrid.Cells[l,0]); for m:=1 to pred(StringGrid.RowCount) do if StringGrid.Canvas.TextWidth(StringGrid.Cells[l,m])>biggestwidth then biggestwidth:=StringGrid.Canvas.TextWidth(StringGrid.Cells[l,m]); StringGrid.ColWidths[l]:=biggestwidth+Zellenbreitenzuschlag end |
Zellenbreitenzuschlag ist eine Größe, die so gewählt werden kann, daß zwischen Text und Stringgridlinien noch Platz sich befindet.
trm - So 27.05.12 10:43
Danke an euch.
Thomas, DrawText war die Lösung. Dadurch zeichne ich tatsächlich innerhalb meines Rechteckes, welches ich selbst ändern kann (ARect). Und ARect ist nun einmal die Zelle und nicht das ganze Grid :D
Sebastian, mit SelectClipRgn eine Region festzulegen, um dann die Breite des Canvas zu beeinflussen, ist glaube ich schwieriger und greift tiefer in die Materie ein, als ich es benötige. Verucht hatte ich das schon vorher, leider bezieht sich zCanvas, wie schon angesprochen, auf das gesamte Grid und nicht, wie ich dachte, auf die aktuelle Zelle.
Delphi-Laie, danke für den Hinweis, leider benötige ich dies nicht, ich habe im Prinzip fast das Gegenteil gesucht ;)
Im Anhang meine neue Unit. Wenn jemand Lust hat, kann er die gern einmal versuchen in einer anderen Delphi-Version als 7 zu benutzen, ob die Kompatibel ist :)
Euch allen ein schönes Pfingstfest,
liebe Grüße
trm - Mo 28.05.12 14:10
Eine neue Version ist fertig. Ich habe die Komponente ein wenig optimiert und neue Funktionen hinzugefügt.
Was mich jetzt im Moment noch stört, ist folgendes:
Bei einer Vergrößerung der Form, auf der das Grid (alClient) drauf ist, wird es nur neu gezeichnet, wenn die Zellen neu gezeichnet werden müssen. Daher kann es passieren, dass, wenn die Form vertical verkleinere, das Grid nicht neu gezeichnet wird und ein Srollbalken entsteht, obwohl ich eine Eigenschaft eingebaut habe, mit der alle Zeilen auf die maximal beste Zeilenhöhe pro Grid.ClientHeight umgerechnet wird, anscheinend TStringGrid.ClientHeight nicht aktualisiert wird.
(Sorry für den Spaghettisatz)
Wie kann man den Fehler umgehen ?
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!