Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Font, tatsächliche breite eines Buchstaben ermitteln?
ALF - Di 02.11.10 19:11
Titel: Font, tatsächliche breite eines Buchstaben ermitteln?
Meine Frage ziehlt darauf, das ich Text automatisch mit (Zeilenumbruch) versehen möchte, den ich auf einer Fläsche darstelle. Problem dabei ist die tatsächliche Breite eines Buchstaben zu erkennen!
zB "B" ist etwa dreimal so breit als "i" . Dadurch kann ich leider den Umbruch nicht genau bestimmen.
Meine Frage nun. Gibt es ne Möglichkeit dies zu errechen? Denn Font.Size sagt ja nichts über die tatsächliche Breite eines Buchstaben aus.
Gruss Alf
elundril - Di 02.11.10 19:13
Mittels Canvas.TextWidth(); kannst du die breite einer zeichenkette ermitteln.
lg elundril
ALF - Di 02.11.10 19:32
Ähm, bevor ich zeichne?
Der Text wird ja erst in einem Edit eingetragen und dann auf die Fläsche übertragen, wie soll ich das ermitteln?
Hier mal mein Code wie ich es jetzt mache:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| var S: String; Ss: Array[0..3] of String; X, Y, Fi, Ls, I : Integer; begin Y:= 0; S:= FGaugeCoText; Fi:= (Width div (Font.Size-4)+1); Ls:= length(S) div Fi; for I:= 0 to Ls do begin Ss[i]:= TrimLeft(LeftBStr(S, Fi)); Delete(S, 1, Fi); end; ..... ..... if ShowText then for I:= 0 to ls do begin X:= PaintRect.Left + Font.Size * 4; if I = 0 then Y:= PaintRect.Top + 24 else Y:= Y + Font.Size + 4;
TextRect(PaintRect, X, Y, Ss[I]); AnImage.Canvas.Draw(0, 0, OverRect); end; ....... |
Gruss Alf
elundril - Di 02.11.10 19:51
folgendes:
Delphi-Quelltext
1:
| breite := AnImage.Canvas.TextWidth(S); |
Das kannst du direkt unter die Zeile
S := FGaugeCoText; schmeißen. Canvas.TextWidth zeichnet ja nix, es misst nur. Das heißt, selbst wenn du gar keine Textausgabe hättest, könntest du das einsetzen.
lg elundril
jaenicke - Di 02.11.10 19:51
ALF hat folgendes geschrieben : |
Ähm, bevor ich zeichne? |
Ja, genau.
Es wird an Hand der gesetzten Einstellungen deiner Leinwand die Breite ermittelt, genau darum geht es dir doch. Ob du da schon was gezeichnet hast, hat damit ja nichts zu tun. Windows muss das nicht durch echtes Zeichnen ausprobieren wie breit es denn wird. :mrgreen:
ALF - Di 02.11.10 20:30
Chick, habe es verstanden, bin auch schon dabei das ganze umzuschreiben, nur der Zeilenumbruch mhhhh... da muss ich mir was neues ausdenken. Der funct natürlich so nicht mehr :?
Ich weiss ja nicht an welcher TextStelle der nun ist!??
Gruss ALf
jaenicke - Di 02.11.10 20:51
Lass doch das Umbrechen einfach automatisch machen. :nixweiss: DrawText mit DT_WORDBREAK und fertig. Ggf. noch vorher mit DT_CALCRECT das Zielrechteck ausrechnen lassen.
Und Canvas.TextRect sollte das auch können.
ALF - Di 02.11.10 21:07
Jo, wenn mans weiss ist es schön. Ich muss doch erst mal das alte Konzept aus den Gedanken löschen. Weil, es sind 2 unterschiedlich Texte in der Procedure. Einmal normales Caption und dann ebend noch der CoText. Beide werden aber in der gleichen Procedure angezeigt. Und, ich bin nun mal kein Schnelldenker :mrgreen:
Werd aber mit Deinen Hinweisen hoffentlich was anfangen können! Mal sehen wie weit ich komme.
Gruss ALf
ALF - Mi 03.11.10 12:47
Sorry, sind zwar erst 15h rum, möchte nur mitteilen wie ich es jetzt gelöst habe.
1. Alle gefundenen Beispiele mit DrawText, hier und anderswo, sei es auf einem Label oder in einem Image, konnte ich einfach nicht umsetzten! Es wurde nie eine neue Zeile gezeichnet :nixweiss:
2. Habe ich mir gedacht, wie würde DrawText das den intern lösen? Ergo selbst ist der man :wink:
Unter Berücksichtigung des vorhanden, habe ich es jetzt so umgesetzt
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58:
| procedure TGaugeButton.PaintAsText(AnImage: TBitmap; PaintRect: TRect); var S: String; Ss: Array[0..2] of String; X, Y, Ls, I: Integer; OverRect: TBltBitmap; TempFont: TFont; begin Y:= 0; ls:= 0;
OverRect:= TBltBitmap.Create; try OverRect.Width:= AnImage.Width; OverRect.Height:= AnImage.Height; OverRect.TransparentMode:= tmAuto; OverRect.Transparent:= True; with OverRect.Canvas do begin Font:= Self.Font; TextRect(PaintRect, PaintRect.Left + 2, PaintRect.Top, FGaugeCaption); AnImage.Canvas.Draw(0, 0, OverRect);
if ShowText then begin X:= PaintRect.Left + Font.Size * 3; Tempfont:= Self.Font; Font:= Self.FCoTextFont; for I:= 1 to length(FGaugeCoText) do begin S:= S + copy(FGaugeCoText, I, 1); Ss[Ls]:= TrimLeft(S); if OverRect.Canvas.TextWidth(Ss[Ls]) > OverRect.Width - X - Font.Size - FBorderWidth then begin S:= ''; inc(Ls); if Ls > 2 then break; end end; for I:= 0 to high(Ss) do begin if I = 0 then Y:= PaintRect.Top + 22 else Y:= Y + Font.Size + 4;
TextRect(PaintRect, X, Y, Ss[I]); AnImage.Canvas.Draw(0, 0, OverRect); end; end; Font:= TempFont; end; finally OverRect.Free; end; end; |
Ich weiss...., ist nicht die engl. Art zu Coden. Aber bevor ich mein ganzes Paint umändere, um DrawText doch nicht zugebrauchen wegen evtl Leerzeichen am Anfang der neuen Zeile, dürfte dies sicherlich ne Alternative sein :mrgreen:
THX an Euch.
Gruss Alf
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!