Autor |
Beitrag |
Stefan S.
      
Beiträge: 184
D5
|
Verfasst: Fr 01.09.06 12:40
In einem Programm habe ich an mehreren Stellen Panels und Edits, die als Caption bzw. Text einen String zugewiesen bekommen, den der Benutzer eingeben kann. Damit der Text nicht über die Width des Panels bzw. Edits hinausragt, hab ich mit der "MaxLength"-Eigenschaft des Edits, in das man den Text eingibt, schon ein Limit gesetzt, aber das Problem ist ja, dass man damit zwar die Menge der Zeichen begrenzt, die Zeichen aber alle unterschiedlich lang sind. Zum Beispiel kommen bei der Schriftart "Arial" auf 10 Ms 36 Is. Und wenn man jetzt deshalb das Limit auf 10 setzt, kann man wiederum auch nur 10 Is eingeben, obwohl eigentlich noch viel mehr reinpassen.
Eine unschöne Lösung wäre, eine Schriftart zu nehmen, bei der alle Zeichen gleich breit sind, aber gibt es auch eine Methode, die tatsächliche Länge eines Strings, also quasi in Pixeln oder so zu bestimmen? Dann könnte ich zum Beispiel ein Limit der Länge, nicht ein Limit der Zeichenmenge, einrichten oder ich programmier es so, dass sich die Schriftgröße bei einem zu langen String automatisch verkleinert, damit der String nirgendwo hinausragt.
|
|
iKilledKenny
      
Beiträge: 394
Erhaltene Danke: 8
Win XP
D5 Prof, C# Express 2005
|
Verfasst: Fr 01.09.06 12:54
schau dir mal Canvas.TextWidth an, das gibt dir breite eines textes für einen canvas in pixel zurück.
grüße
alex
|
|
rizla
      
Beiträge: 417
Erhaltene Danke: 2
XP
FPC mit Lazarus
|
Verfasst: Fr 01.09.06 12:58
mist, alex war schneller.. 
_________________ if you have what they want - they'll find a way to take it (bruce sterling)
WOW - 10 JAHRE Mitglied beim Delphi-Forum. Wie die Zeit vergeht, Freunde.
|
|
jaenicke
      
Beiträge: 19313
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 01.09.06 13:01
Aber Vorsicht: Du musst das dann nach jeder Eingabe eines Zeichens erneut prüfen! Bzw. die Eingabe selbst abbrechen, sobald das gerade eingegebene Zeichen nicht mehr passt (in OnKey...), eben weil die einzelnen Zeichen nicht gleich lang sind...
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Fr 01.09.06 13:16
Hallo,
verwende zur Anzeige der Strings doch Komponenten die einen Zeilenumbruch unterstützen, wenn das in Dein Programm-Layout passt.
Panel > Label
Edit > Memo
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
Stefan S. 
      
Beiträge: 184
D5
|
Verfasst: Fr 01.09.06 14:05
OK, danke. Damit wäre das schon geklärt.
|
|
Stefan S. 
      
Beiträge: 184
D5
|
Verfasst: Fr 01.09.06 15:12
Sorry wegen dem Doppelpost, aber es ist doch noch ein Problem aufgekommen.
In meinem Programm wird jetzt die Schriftgröße eines Panels angepasst, je nachdem wie lang der String ist, der darauf angezeigt werden soll (hatte meine Gründe, dass ich das nicht mit Labels und Zeilenumbrüchen gemacht habe). Allerdings hab ich festgestellt, dass ein und der selbe String in zwei verschiedenen Formularen jeweils einen anderen Canvas.TextWidth-Wert hat: Im einen irgendwas mit 500 und im anderen irgendwas mit 400. Die Strings scheinen generell im zweiten Formular immer einen niedrigeren Wert zu haben. Wie kann das sein? Die beiden Panel in den unterschiedlichen Formularen sind gleich groß und haben die gleiche Schriftart, aber das dürfte ja sowieso keine Rolle spielen. Eigentlich geht es doch nur um den String, und wie kann bei dem der TextWidth-Wert variieren?
|
|
iKilledKenny
      
Beiträge: 394
Erhaltene Danke: 8
Win XP
D5 Prof, C# Express 2005
|
Verfasst: Fr 01.09.06 16:24
das hängt davon ab, welcher canvas zur ermittlung der schriftgröße genommen wird.
da du an den canvas eines panels nicht drankommst, wird mit der anweisung canvas.textwidth der canvas der parent-form genommen...
grüße
alex
|
|
Stefan S. 
      
Beiträge: 184
D5
|
Verfasst: Sa 02.09.06 23:33
Hm? Sorry, aber das musst du mir jetzt erklären.
Ich hab ja sowieso schon immer FormX.Canvas.Textwidth genommen, aber warum wird für die Bestimmung der Länge eines Textes überhaupt irgendein Wert des übergeordneten Formulars mit einbezogen? Ich hab ja ohnehin schon gemerkt, dass Canvas.Textwidth nicht exakt das ist, was ich gemeint hab, weil Schriftgröße und Schriftart für den Wert keine Rolle spielen, obwohl diese natürlich entscheidend dafür sind, wie Lang ein Text ist, wenn er auf einem Panel angezeigt wird. Was hat es jetzt genau mit der Eigenschaft "Canvas.Textwidth" auf sich? Woraus ergibt sie sich genau und warum muss man ein Formular mit einbeziehen?
Ach ja, die beiden Formulare, in denen jeweils der selbe Code zur Bestimmung der Länge eines Strings verwendet wurde, sind übrigens genau gleich breit und hoch. Falls das für die Werte eine Rolle spielt. Aber ich kapier die Funktion grad allgemein nicht.
EDIT: Hab mal ein bisschen die Suchfunktion genutzt und verstehe jetzt, dass es an unterschiedlichen Canvas.Font lag, weil die Schriftgröße beim einen Formular anders war. Könnte aber trotzdem mal eine umfassende Erklärung gebrauchen. ^^
|
|
jaenicke
      
Beiträge: 19313
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 03.09.06 22:15
Na ja, Canvas.TextWidth gibt zurück wie breit der übergebene Text auf dem benutzten Canvas selbst wäre, wenn dort Text ausgegeben wird, also natürlich mit der beim Canvas eingestellten Schriftart.
|
|
Stefan S. 
      
Beiträge: 184
D5
|
Verfasst: Sa 23.09.06 11:43
OK, ich habe mittlerweile eine Lösung gefunden:
Ich stelle die Schriftgröße von der Form so hoch, wie die Schrift auf dem Panel maximal groß sein darf. Dann teste ich, ob der Text mit Form2.Canvas.Textwidth in Pixeln länger wäre als der Panel. Wenn ja, dann wird in einer Schleife solange von der Schriftgröße der Form eins abgezogen, bis der Text auf den Panel passt oder ein Mindeswert erreicht wurde (in diesem Fall ragt der Text eben über den Panel hinaus, aber der User muss eben darauf achten, keinen zu langen Text einzugeben). Am Ende wird dem Panel die Schriftgröße der Form zugewiesen und diese wird dann zurückgesetzt auf den normalen Wert.
Das ist wie sich die meisten denken werden eine ziemlich unschöne Lösung, aber ich hätte mich damit zufrieden gegeben, wenn alles einwandfrei funktioniert hätte. Geklappt hat es auch, dass die Schriftgröße immer so groß wie möglich war, dass der Text auf den Panel passt. Aber jetzt ist mir aufgefallen, dass es in der Form jedesmal, wenn so ein Text geprüft wird, aufflimmert. Nicht unglaublich auffällig, aber doch störend. Und die Ursache dafür ist zweifelsfrei das viele Form.Font.Size-ändern. Darum wollte ich fragen: Kann man das noch irgendwie schöner lösen? Welche Komponente hat außer den Formularen ein Canvas.Textwidth, sodass ich an ihr quasi die Schriftgröße austesten kann? Wenn das irgendwie mit einer unsichtbaren Komponente ginge oder ich noch besser auch ohne eine Experimentier-Komponente feststellen kann, wie lang ein Text in einer bestimmten Schriftart in einer bestimmten Schriftgröße ist, dann hätte ich das Flimmer-Problem nicht mehr.
Zuletzt bearbeitet von Stefan S. am Sa 23.09.06 11:48, insgesamt 2-mal bearbeitet
|
|
jakobwenzel
      
Beiträge: 1889
Erhaltene Danke: 1
XP home, ubuntu
BDS 2006 Prof
|
Verfasst: Sa 23.09.06 11:47
Kannste nich nen TBitmap nehmen? Das hat doch auch nen Canvas.
_________________ I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
|
|
Stefan S. 
      
Beiträge: 184
D5
|
Verfasst: Sa 23.09.06 11:51
Aber ein TBitmap hat doch keine Font-Eigenschaft, oder? Und ich bräuchte ja etwas mit einer Font-Eigenschaft, um festzustellen, wie lang ein Text in einer festgelegten Schriftart ist.
|
|
Marco D.
      
Beiträge: 2750
Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
|
Verfasst: Sa 23.09.06 11:58
Bietet Canvas nicht direkt Font an?:
Delphi-Quelltext
?
_________________ Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
|
|
Stefan S. 
      
Beiträge: 184
D5
|
Verfasst: Sa 23.09.06 12:12
Es gibt scheinbar auch ein allgemeines "Canvas", also eines das nicht zu einer Komponente gehört. Man kann auch "Canvas.Font.Size" beliebig ändern. Aber worauf bezieht sich dieses "Canvas" dann, wenn nicht auf ein Formular? Wozu braucht man das und was bewirkt man, wenn man da die Schriftgröße ändert? Denn wenn man da durch das Rumexperimentieren wieder irgendetwas anderes durcheinander bringt, gibts womöglich wieder einen Flimmereffekt oder so etwas.
|
|
jakobwenzel
      
Beiträge: 1889
Erhaltene Danke: 1
XP home, ubuntu
BDS 2006 Prof
|
Verfasst: Sa 23.09.06 12:14
Wenn man im Quelltext von nem Form Canvas.wasweißichwas benutzt, bezieht sich das auf self.Canvas.wasweißichwas und self ist gleich dem Form, also dann Form.Canvas.blablabla.
_________________ I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
|
|
Stefan S. 
      
Beiträge: 184
D5
|
Verfasst: Sa 23.09.06 12:17
Hm, ich hab aber in einem Testprojekt mal per Button-Knopfdruck die Länge eines Textes im Bezug auf Canvas.Textwidth abfragen lassen und der Wert war unverändert, wenn ich Form1.Font.Size verändert habe.
In meinem eigentlichen Projekt wieder hat er mir Canvas.Font.Size als undefinierten Bezeichner gemeldet. Also registriert er "Canvas.blablabla" nicht immer automatisch als "Form.Canvas.blablabla".
Hat die Button-Komponente etwa auch ein "Canvas"? Dann würde es Sinn machen, dass er bei OnButtonKlick im Testprojekt ein "Canvas.blablabla" kannte, das wäre dann das Canvas des Buttons gewesen.
|
|
jakobwenzel
      
Beiträge: 1889
Erhaltene Danke: 1
XP home, ubuntu
BDS 2006 Prof
|
Verfasst: Sa 23.09.06 12:37
Wenn er kein Canvas findet, dann stand der Code in ner Prozedur, die nicht zu einem Form gehörte.
_________________ I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
|
|
Stefan S. 
      
Beiträge: 184
D5
|
Verfasst: Sa 23.09.06 13:29
OK, das war tatsächlich der Fall wie ich gerade festgestellt habe.
Aber haben jetzt Buttons eigentlich auch ein Canvas? In der Hilfe steht eigentlich nichts davon, aber anders kann ich mir nicht erklären, dass ich in dem Testprojekt Form1.Font.Size beliebig ändern konnte und sich das nicht auf Canvas.Textwidth ausgewirkt hat. (Dagegen wennn ich Canvas.Font.Size geändert habe, hat das schon etwas geändert.) Dann könnte ich doch theoretisch auch einen (unsichtbaren) Button für meine Schriftgrößen-Experimente hernehmen, oder?
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Sa 23.09.06 23:37
Hallo
Stefan S. hat folgendes geschrieben: | Aber haben jetzt Buttons eigentlich auch ein Canvas? |
nein, aber man kann über TControlCanvas.create ein Canvas erzeugen und es mit Canvas.Control := Button verbinden.
Das ist aber nicht erforderlich um mit Textwidth zu arbeiten.
Stefan S. hat folgendes geschrieben: | In der Hilfe steht eigentlich nichts davon, aber anders kann ich mir nicht erklären, dass ich in dem Testprojekt Form1.Font.Size beliebig ändern konnte und sich das nicht auf Canvas.Textwidth ausgewirkt hat. (Dagegen wennn ich Canvas.Font.Size geändert habe, hat das schon etwas geändert.) |
Form1.Font und Form1.Canvas.Font sind grundsätzlich verschiedenene Dinge.
Verändert man Form1.Font, wird die Schrifft aller Komponenten die mit ParentFont = True eingestellt sind, entsprechend verändert.
Form1.Canvas.Font betrifft die Zeichefläche der Form. Veränderungen an Form1.Canvas.Font wirken sich dann aus, wenn auf das Canvas der Form mit TextOut, LineTo usw. gearbeitet wird.
Benutzt man die Zeichefläche der Form nicht für Grafikausgaben kann man das Canvas der Form zur Ermittlung von Schriftgrößen mit TextWidth und TextHeight benutzen. Dazu muss man zuvor Canvas.Font entsprechend z.B. Button.Font verändern.
Steht einem jedoch die Zeichenfläche nicht zur Verfügung benutzt man ein TBitmap, denn dieses bringt ein Canvas mit.
Ein Beispiel findest Du dort:
www.delphi-forum.de/....php?p=328261#328261
Stefan S. hat folgendes geschrieben: | Dann könnte ich doch theoretisch auch einen (unsichtbaren) Button für meine Schriftgrößen-Experimente hernehmen, oder? |
siehe oben.
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
|