durchlaufender Text im Fenster

Anfängerfragen zum Programmieren mit PureBasic.
der-sigi
Beiträge: 39
Registriert: 07.04.2006 12:22

Beitrag von der-sigi »

> btw: benutz den EDIT-Button....

Ähm, nigges verstehen. Für was?
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

um zu vermeiden posten 2 postings in 2 minuten....
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
der-sigi
Beiträge: 39
Registriert: 07.04.2006 12:22

Beitrag von der-sigi »

Tut mir leid, wenn ich das falsch gemacht habe, Kaeru Gaman. Ist das so schlimm, wenn man so schnell hintereinander reinpostet? Da das an zwei verschiedene Leute mit total verschiedenen Inhalten war, hielt ich es für gerechtfertigt (wie das nächste auch). :)
der-sigi
Beiträge: 39
Registriert: 07.04.2006 12:22

Beitrag von der-sigi »

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.

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++
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.

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
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
der-sigi
Beiträge: 39
Registriert: 07.04.2006 12:22

Beitrag von der-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. ;)
Benutzeravatar
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

Beitrag von PureLust »

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. :D
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)
der-sigi
Beiträge: 39
Registriert: 07.04.2006 12:22

Beitrag von der-sigi »

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.

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
Viele Grüße
Sigi
Benutzeravatar
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

Beitrag von PureLust »

Hey, .... hast Dich da ja richtig gut eingelesen !!! :allright:
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
der-sigi
Beiträge: 39
Registriert: 07.04.2006 12:22

Beitrag von der-sigi »

Hab mich auch angestrengt. :)

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
Antworten