durchlaufender Text im Fenster
-
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
Hallo PureLust
da ich nicht nur abschreiben, sondern auch verstehen will und mit deinem netten Beitrag noch Probleme habe, noch eine Nachfrage.
1) Müßte man bei deinem "SpaceWidth" nicht ein kleines "i" nehmen, da das wohl den kleinsten horizontalen Abstand im Zeichensatz hat? Sonst wird die Zeile nicht voll, falls jemand lauter "iiii"'s verwendet. :)
2) Bei mir macht das Teil was es will. Dein Muster funktioniert allerdings, was ich nicht verstehe. Mein Fenster ist 310 Pixel breit. Und einen Font habe ich nicht eingestellt. Wenn ich in "DrawingFont()" den "#PB_Default" nehme, wird es noch schlimmer. Jedenfalls nutzt es nicht die Breite des Fensters, selbst wenn ich die Breite direkt reinschreibe, also ohne "GadgetWidth()". Es sieht so aus, wie wenn das irgendwie per Zufall die Breite ermittelt.
Das ist eine Beispielausgabe, wobei ich die Separatorzeichen auf ein Space reduziert habe. Das "++123++" hinten an der Zeile habe ich angefügt um zu sehen was der bastelt und besteht aus "TextLength(Left(WorkText, n)". Aussehen müßte das wir folgt.
Hast du eine Idee, wo das klemmt? Das ist sonst genau dein Kode, ich habe nur den Separator und das "++123++" geändert.
Viele Grüße
Sigi
da ich nicht nur abschreiben, sondern auch verstehen will und mit deinem netten Beitrag noch Probleme habe, noch eine Nachfrage.
1) Müßte man bei deinem "SpaceWidth" nicht ein kleines "i" nehmen, da das wohl den kleinsten horizontalen Abstand im Zeichensatz hat? Sonst wird die Zeile nicht voll, falls jemand lauter "iiii"'s verwendet. :)
2) Bei mir macht das Teil was es will. Dein Muster funktioniert allerdings, was ich nicht verstehe. Mein Fenster ist 310 Pixel breit. Und einen Font habe ich nicht eingestellt. Wenn ich in "DrawingFont()" den "#PB_Default" nehme, wird es noch schlimmer. Jedenfalls nutzt es nicht die Breite des Fensters, selbst wenn ich die Breite direkt reinschreibe, also ohne "GadgetWidth()". Es sieht so aus, wie wenn das irgendwie per Zufall die Breite ermittelt.
Code: Alles auswählen
# 127.0.0.1 connected - ++294++
2006-04-20 22:28:37
#127.0.0.1 - 2006-04-20 ++300++
22:28:44
hier kommt ein text
> 127.0.0.1 - ++284++
2006-04-20 22:29:04
und hier kommt ein ganz ++304++
langer text damit wir den zeilenumbruch auch ++299++
sehen
++48++
Code: Alles auswählen
# 127.0.0.1 connected - 2006-04-20 22:28:37
#127.0.0.1 - 2006-04-20 22:28:44
hier kommt ein text
> 127.0.0.1 - 2006-04-20 22:29:04
und hier kommt ein ganz langer text damit wir den
zeilenumbruch auch sehen
Viele Grüße
Sigi
Also, hab das Problem gefunden. Wenn in dem Text schon Zeilenvorschübe drin sind, dessen Zeile kleiner als das Fenster ist, wird das nicht von "WordWrap()" erfasst und es kommt zu solch komischen Ausführungen. Dein Muster funktioniert, weil es immer auf maximale Breite geht und keine kleineren Zeilen drin sind. Es müßten also bestehende Zeilenvorschübe erfaßt, rausgelöscht und die Zeile wieder so eingebaut werden. Mal sehen ob ich das hinbekomme. ;)
- PureLust
- Beiträge: 1145
- Registriert: 21.07.2005 00:02
- Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
- Wohnort: am schönen Niederrhein
Hi Sigi, ....
also aus Deinem oberen Post werde ich leider nicht ganz schlau.
Aber die Anwendung der Prozeduren waren in Deinem Falle eigentlich so gedacht, dass Du:
- die neu hinzuzufügende Zeile zuerst durch die WordWrap-Funktion jagst
- das Ergebnis davon and den bestehenden Text anhängst und
- dieses dann wiederum komplett durch den LineLimitter schickst um den Anfang abzuschneiden.
Wenn Du meinen Beispielcode vom Prinzip her einfach nur so übernommen hast (also zuerst die neue Zeile angefügt und dann alles zusammen umgebrochen und beschnitten), dann kann es nicht funktionieren.
Aber wie gesagt, mit den Angaben in Deinem letzten Post kann ich nicht viel anfangen und Dir von daher auch nicht sagen was genau Du falsch gemacht hast.
Gruß und nochmals viel Glück !!!
PureLust.
[Edit] Nachtrag:
Na, da haben sich unsere beiden Posts wohl überschnitten.
Aber genau das (was Du nun also zuletzt gepostest hattest) hatte ich vermutet, da der WordWrapper bestehende Zeilenumbrüche nicht berücksichtigt.
Mach's also einfach wie oben beschrieben (also immer nur die neuen Zeilen umbrechen und anhängen) - dann sollte es klappen.
also aus Deinem oberen Post werde ich leider nicht ganz schlau.
Aber die Anwendung der Prozeduren waren in Deinem Falle eigentlich so gedacht, dass Du:
- die neu hinzuzufügende Zeile zuerst durch die WordWrap-Funktion jagst
- das Ergebnis davon and den bestehenden Text anhängst und
- dieses dann wiederum komplett durch den LineLimitter schickst um den Anfang abzuschneiden.
Wenn Du meinen Beispielcode vom Prinzip her einfach nur so übernommen hast (also zuerst die neue Zeile angefügt und dann alles zusammen umgebrochen und beschnitten), dann kann es nicht funktionieren.
Aber wie gesagt, mit den Angaben in Deinem letzten Post kann ich nicht viel anfangen und Dir von daher auch nicht sagen was genau Du falsch gemacht hast.
Gruß und nochmals viel Glück !!!

PureLust.
[Edit] Nachtrag:
Na, da haben sich unsere beiden Posts wohl überschnitten.

Aber genau das (was Du nun also zuletzt gepostest hattest) hatte ich vermutet, da der WordWrapper bestehende Zeilenumbrüche nicht berücksichtigt.
Mach's also einfach wie oben beschrieben (also immer nur die neuen Zeilen umbrechen und anhängen) - dann sollte es klappen.

[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Hallo PureLust
> also aus Deinem oberen Post werde ich leider nicht ganz schlau
Macht nichts, wollte nur zeigen was das für einen "Müll" produzierte.
> Mach's also einfach wie oben beschrieben (also immer nur die neuen Zeilen umbrechen und anhängen)
Nur hat man eben nicht immer den Fall, daß man nur das Neue durchlassen kann. Es könnte ja auch mal sein, daß man mit neuer Breite formatieren möchte.
Ich habe das jetzt soweit, daß es funktioniert. Wenn das jemand interessiert, hier kommts.
Viele Grüße
Sigi
> also aus Deinem oberen Post werde ich leider nicht ganz schlau
Macht nichts, wollte nur zeigen was das für einen "Müll" produzierte.
> Mach's also einfach wie oben beschrieben (also immer nur die neuen Zeilen umbrechen und anhängen)
Nur hat man eben nicht immer den Fall, daß man nur das Neue durchlassen kann. Es könnte ja auch mal sein, daß man mit neuer Breite formatieren möchte.
Ich habe das jetzt soweit, daß es funktioniert. Wenn das jemand interessiert, hier kommts.
Code: Alles auswählen
; ---------------------------------------------------------
Procedure.s WordWrap(Text.s, MaxWidth.l, FontID.l, LineSplit.s)
; -------------------------------------------------------
; Diese Prozedur bricht einen Text wortweise um, wenn er laenger als
; 'MaxWidth' Pixel ist, unter beruecksichtigung der Schriftart und Groesse
; des Fonts mit der uebergebenen 'FontID'. Hierbei werden die Zeichen in
; der Variable 'Separators' als Wortseparatoren verwendet.
;
; Der Rueckgabewert beinhaltet den Umgebrochenen Text, wobei die einzelnen
; Zeilen durch die Zeichen in der Variable 'LineSplit' getrennt werden.
; Die oben erwaehnten Zeichen für die Wortseparation in der Variable
; 'Separators' koennen natuerlich nach Belieben angepasst werden.
;
; Text = Text, der umgebrochen werden soll.
; MaxWidth = Breite in Pixel, die der umgebrochenen Text maximal haben soll.
; FontID = ID des Fonts, auf dessen Basis die Berechnung der Textbreite durchgefuehrt
; wird (Achtung: es wird die FontID() benoetigt, nicht die #FontNummer.).
; LineSplit = Hier koennen die Zeichen uebergeben werden, die fuer einen 'Zeilenvorschub'
; verwendet werden sollen. Standardmaessig wird hierbei CR+LF - also
; Chr(13)+Chr(10) - verwendet.
; -------------------------------------------------------
Protected Separators.s, WorkText.s, ReturnText.s
Protected StartMaxChar.l, MaxChar.l, CurrentLength.l
Protected MinCharWidth.l, AktTextPos.l, DummyImage.l
; -------------------------------------------------------
; --- Wort-Separatoren - können nach belieben verändert werden
; Separators.s = " :;-_!§$%&/()={[]}?ß\+*#"
Separators.s = " "
; -------------------------------------------------------
; --- Wird benötigt um einen Dummy Ausgabekanal zum Setzen des Fonts zu öffnen.
DummyImage = CreateImage(#PB_Any, 1, 1)
If DummyImage
; -----------------------------------------------------
; --- den Dummy aktivieren
If StartDrawing(ImageOutput())
; ---------------------------------------------------
; --- das Ergebnis leeren
ReturnText = ""
; ---------------------------------------------------
; --- den richtigen Font aktivieren damit die Masse stimmen
DrawingFont(FontID)
; ---------------------------------------------------
; --- das kleinstmoegliche Zeichen ausmessen
MinCharWidth = TextLength("i")
; ---------------------------------------------------
; --- solange ein Zeilenvorschub gefunden wird
; --- oder noch Text da ist
While CountString(Text, LineSplit) > 0 Or Len(Text) > 0
; --- suche den naechsten Zeilenvorschub
AktTextPos = FindString(Text, LineSplit, 1)
; --- keiner gefunden ?
If AktTextPos = 0
; --- kompletten Text nehmen
WorkText = Text
; --- danach sind wir fertig
Text = ""
; --- doch - es ist was da
Else
; --- den Text bis zum Zeilenvorschub nehmen
WorkText = Left(Text, AktTextPos - 1)
; --- und den danach aufheben fuer die naechste Runde
Text = Mid(Text, AktTextPos + Len(LineSplit), Len(Text))
EndIf
; -------------------------------------------------
; --- wir haben jetzt eine Zeile (ohne Zeilenvorschuebe)
; -------------------------------------------------
; --- die maximale Zeichenmenge fuer die Fensterbreite ermitteln
; --- muss hier immer gemacht werden, da es pro Zeile eventuell angepasst wird
StartMaxChar = MaxWidth / MinCharWidth
; -------------------------------------------------
; --- die Zeile mal durch den Wrapper lassen
Repeat
; -----------------------------------------------
; --- wenn der Text weniger Zeichen hat als in die Zeile maximal reingehen
If Len(WorkText) < StartMaxChar
; --- die maximale Zeichenmenge pro Zeile darauf reduzieren
StartMaxChar = Len(WorkText)
EndIf
; --- die maximale Zeichenmenge festnageln fuer spaeter
MaxChar = StartMaxChar
; -----------------------------------------------
; --- ab maximaler Zeichenmenge durchgehen
For CurrentLength = StartMaxChar To 1 Step -1
; --- wenn die Zeichenbreite kleiner als die Vorgabe ist
If TextLength(Left(WorkText, CurrentLength)) <= MaxWidth
; --- wenn es der ganze Text ist
If CurrentLength = StartMaxChar
; --- hier mal aufhoeren zum Teilen
Break
; --- oder wenn ein Separator kommt
ElseIf FindString(Separators, Mid(WorkText, CurrentLength, 1), 1)
; --- hier mal aufhoeren zum Teilen
Break
EndIf
; --- es ist noch zu breit
Else
; --- ein Zeichen abziehen und nochmal von vorne
MaxChar = CurrentLength - 1
EndIf
Next CurrentLength
; -----------------------------------------------
; --- wir haben jetzt die passende Laenge
; -----------------------------------------------
; --- wenn das irgendwo in der Zeile ist
If CurrentLength > 0
ReturnText = ReturnText + Left(WorkText, CurrentLength) + LineSplit
WorkText = Mid(WorkText, CurrentLength + 1, Len(WorkText))
; -----------------------------------------------
; --- oder ueber die maximale Laenge hinaus
Else
ReturnText = ReturnText + Left(WorkText, MaxChar) + LineSplit
WorkText = Mid(WorkText, MaxChar + 1, Len(WorkText))
EndIf
; -----------------------------------------------
; --- bis die Zeile komplett durch ist
Until Len(WorkText) = 0
; -------------------------------------------------
; --- bis alle Zeilen des kompletten Texts durchgearbeitet ist
Wend
; ---------------------------------------------------
; --- den Dummy deaktivieren
StopDrawing()
EndIf
; -----------------------------------------------------
; --- den Speicher des Dummies freigeben
FreeImage(DummyImage)
; -----------------------------------------------------
; --- den fertigen Text ohne endenden Zeilenvorschub uebergeben
ProcedureReturn Left(ReturnText, Abs(Len(ReturnText) - Len(LineSplit)))
EndIf
EndProcedure
Sigi
- PureLust
- Beiträge: 1145
- Registriert: 21.07.2005 00:02
- Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
- Wohnort: am schönen Niederrhein
Hey, .... hast Dich da ja richtig gut eingelesen !!!

[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Hab mich auch angestrengt. :)
Vielleicht sollte ich auch mal so eine Signaturleiste einbringen, wie du sie hast:
Vielleicht sollte ich auch mal so eine Signaturleiste einbringen, wie du sie hast:
- CPUs - SC/MP, 6802, 6809, 68000, 6052, 8039, 8048, 8051, 8080, Z80, 8086, 8088, 80x86, PIC, Atmel, Sparc und mehr
- Systeme - CP/M, DOS, Flex, UniFlex, Atari ST, Amiga, Apple II, OS/2, Unix, Linux, Sun OS, Solaris, MS Windows, Mac OS-X, Embedded und mehr
- Sprachen - Maschinensprache, Assembler, DBase, Clipper, FoxPro, Pascal, Modula, Oberon, Delphi, Comal, SQL, C, C++, Forth, Perl, Lisp, Basic, Profan, VHDL, CNC, Java, Pike, PHP, HTML, CSS, Shell, Bash, Tcl, XSLT und mehr
- Rechner - 6502 Eigenbau, TRS80, Acorn, ZX-80, ZX-81, CBM-8032, Flex Eigenbau, Atari, PC, PDA, Sun, Embedded Eigenbau