Automatischer Zeilenumbruch

  • Hi.

    Ich versuche, einem Text, den ich über eine EditBox in eine Variable geschrieben habe, den Zeilenumbruch an der richtigen Stelle beizubringen.
    Habe schon überlegt, meine Zeile soll maximal 140 Zeichen lang sein. D.h. ich fang zuerst mal am Anfang an und schaue mir die ersten 140 Zeichen an, ob ein Zeilenumbruch dabei ist. Ist einer dabei, fang ich ab dem Zeilenumbruch, also beim zeichen danach wieder von vorne mit meinem "Alrogithmus" an, hat mit der neuen Stelle. Wenn dort kein Zeilenumbruch kommt, fang ich wiederum vom 160. Zeichen aus an, rückwärts zu gehen, bis ein leerzeichen kommt, und füge dort einen Zeilenumbruch statt des Leerzeichens ein. Alles natürlich immeer unter der Vorraussetzung, es sind noch 160 zeichen übrig, sonst bin ich fertig. Stimmt die Theorie soweit? Mit welchen Funktionen bekomme ich das am einfachsten gebacken? Hatte schon mal angefangen zu überlegen, dann wurde es mir zu komplex, an welcher Stelle ich mit welcher Variablen wohl welche Position speichere und dann in welche andere Variable schreibe usw, daher hatte ich das erstmal aufgeschoben, aber nun will ichs umsetzen.

    Über Tipps bin ich dankbar, da ich noch nicht so den Durchblick habe :(

    Einmal editiert, zuletzt von Weisgarnix (28. Dezember 2010 um 16:09)

  • Hallo Weisgarnix,

    herzlich willkommen im Forum und viel Spass mit AutoIt.

    Hier kannst du dir die Hilfe herunterladen.
    Hier gibt es ein AutoIt-Tutorial: http://wiki.autoit.de/wiki/index.php/TutorialSehr hilfreich ist auch das Buch von peethebee

    und jetzt zu deinem Problem, erstelle dein Input-Control folgendermassen:

    [autoit]

    $idEdtBem = GUICtrlCreateInput("" , 2, 405, 713, 105, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL, $ES_MULTILINE, $ES_WANTRETURN))
    GUICtrlSetFont(-1, 10,10,Default,"Courier New")

    [/autoit]

    dadurch solltest du einen automatischen Zeilenumbruch hinbekommen. Die Breite musst du noch anpassen,

    Edit: fehlende )) ergänzt, sorry Kopier-Fehler
    mfg autoBert

    Einmal editiert, zuletzt von autoBert (28. Dezember 2010 um 06:07)

  • Zitat

    kann ich an der Stelle $ES_CENTER nicht verwenden?


    Klar kannst du das, du musst das nur bei BitOR als weiteren Parameter hinzufügen ;).

    Zitat

    Der meldet mir beim kompiliieren dabei einen Fehler


    Das könnte auch an den fehlenden Klammern liegen :whistling: .

    [autoit]

    $idEdtBem = GUICtrlCreateInput("" , 2, 405, 713, 105, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL, $ES_MULTILINE, $ES_WANTRETURN))

    [/autoit]
  • schlau ja, die eine habe ich zugemacht, die andere habe ich übersehen ... danke dir ;)

    Ok, so leicht kann ichs mir wohl nicht machen.
    Ich will den Text nachher in einer Ausgabedatei mittig speichern. Zum mittig machen hab ich mir ne kleine Funktion gebastelt, allerdings nur für "Einzeiler", d.h., ich muss mir den Inhalt meiner Variablen doch Häppchenweise aufstückeln... :(

    Einmal editiert, zuletzt von Weisgarnix (28. Dezember 2010 um 03:15)

  • Ich hab da mal was versucht, aber ich bin leider zu müde um das jetzt noch zu optimieren :sleeping: .
    Vielleicht hilft es dir ja trotzdem weiter...

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <GDIPlus.au3>
    #include <String.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $sTest = ""
    For $i = 1 To 100
    $sTest &= Chr(Random(65, 90, 1))
    Next

    [/autoit] [autoit][/autoit] [autoit]

    $iMaxWidth = 150

    [/autoit] [autoit][/autoit] [autoit]

    $hWnd = GUICreate("Test", 400, 400)
    $cEdit = GUICtrlCreateEdit("", 5, 5, 390, 390)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd)

    [/autoit] [autoit][/autoit] [autoit]

    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    $hFont = _GDIPlus_FontCreate($hFamily, 10)

    [/autoit] [autoit][/autoit] [autoit]

    $tMeasureTmp = _GDIPlus_GraphicsMeasureString($hGraphic, $sTest, $hFont, _GDIPlus_RectFCreate(), $hFormat)

    [/autoit] [autoit][/autoit] [autoit]

    $iWidthText = DllStructGetData($tMeasureTmp[0], "width")
    $iStringLen = StringLen($sTest)
    $iLines = Ceiling($iWidthText / $iMaxWidth)
    $iCPL = Ceiling($iStringLen / $iLines)

    [/autoit] [autoit][/autoit] [autoit]

    $sNewText = ""
    $i = 1
    $iWidthRemainingText = $iWidthText
    While $iWidthRemainingText > $iMaxWidth
    $sNewText &= StringLeft($sTest, $iCPL) & @CRLF
    $sTest = StringTrimLeft($sTest, $iCPL)
    $tMeasureTmp = _GDIPlus_GraphicsMeasureString($hGraphic, $sTest, $hFont, _GDIPlus_RectFCreate(), $hFormat)
    $iWidthRemainingText = DllStructGetData($tMeasureTmp[0], "width")
    $i += 1
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetData($cEdit, $sNewText)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_Shutdown()
    Exit
    EndSwitch
    WEnd

    [/autoit]
  • &quot;nur ein kleiner Ansatz zum trimmen der Zeilenlänge&quot;
    [autoit]

    #include <array.au3>
    $sString = 'Habe schon überlegt, meine Zeile soll maximal 140 Zeichen lang sein. D.h. ich fang zuerst mal am Anfang an und schaue mir die ersten 140 Zeichen an, ob ein Zeilenumbruch dabei ist. Ist einer dabei, fang ich ab dem Zeilenumbruch, also beim zeichen danach wieder von vorne mit meinem "Alrogithmus" an, hat mit der neuen Stelle. Wenn dort kein Zeilenumbruch kommt, fang ich wiederum vom 160. Zeichen aus an, rückwärts zu gehen, bis ein leerzeichen kommt, und füge dort einen Zeilenumbruch statt des Leerzeichens ein. Alles natürlich immeer unter der Vorraussetzung, es sind noch 160 zeichen übrig, sonst bin ich fertig. Stimmt die Theorie soweit? Mit welchen Funktionen bekomme ich das am einfachsten gebacken? Hatte schon mal angefangen zu überlegen, dann wurde es mir zu komplex, an welcher Stelle ich mit welcher Variablen wohl welche Position speichere und dann in welche andere Variable schreibe usw, daher hatte ich das erstmal aufgeschoben, aber nun will ichs umsetzen.'
    $iCount = 100
    $sString = StringStripWS(StringReplace($sString, @CRLF, " "), 7)
    $aResult = StringRegExp($sString, "(.{0," & $iCount & "}\b)", 3, 1)
    ConsoleWrite(_ArrayToString($aResult, @crlf) & @CRLF)

    [/autoit]
  • Oh je, nun habe ich die ganze zeit zu coden versucht, nun sehe ich, dass ich euch fleißig gewesen seid.
    habe weder euren, noch meinen Code getestet, ich hau mich nun für ein paar Stündchen aufs Ohr, bitte Meinungen zu mienem vermutlich viel zu komplizierten Code. Es werden noch Wetten angenommen, ob er das tut was er soll hehe

    PS: Die 3 unteren Minifunktionen tun das, was sie sollen. Die beiden oberen sind die spannenden^^

    Spoiler anzeigen
    [autoit]

    ; Funktion _edithelp($inputstring)
    ; Erstellt eine mit korrekten Zeilenumbrüchen gespickte
    ; Ausgabe des Inputtextes.

    [/autoit] [autoit][/autoit] [autoit]

    Func _edithelp($inputstring)
    $outputstring = StringReplace($inputstring, @CRLF, @CRLF)
    $countcrlf = @extended
    $stringarray = _StringExplode($outputstring, @CRLF, 0)
    $i = 0 ; zählt Arrayeinträge hoch
    While ( $i < $countcrlf)
    While ( StringLen($stringarray[$i]) > 150 )
    $j=150 ; merkt sich aktuelle Testposition
    $isspace = _isspace($stringarray[$i],$j)
    While ( $isspace = False )
    $j = $j - 1
    $isspace = _isspace($stringarray[$i],$j)
    WEnd
    _makespaces($j)
    $textline = StringMid($stringarray[$i],1,$j)
    $ausgabetext = $ausgabetext&$textline
    _makecorrectspaces($j)
    _crlf()
    $stringarray[$i]=StringMid($stringarray[$i],$j+1)
    WEnd
    _makespaces(StringLen($stringarray[$i]))
    $ausgabetext = $ausgabetext&$stringarray[$i]
    _makecorrectspaces(StringLen($stringarray[$i]))
    $i = $i + 1
    WEnd
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktion _findfirstspace($inputstring)
    ; Findet beim 150. Zeichen beginnend rückwärts laufend das erste Leerzeichen
    Func _isspace($inputstring, $position)
    If ( StringInStr($inputstring, " ", 0, 1, $position, $position) = 0) Then
    Return False
    Else
    Return True
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktion _crlf()
    ; Erstellt einen Zeilenumbruch.

    [/autoit] [autoit][/autoit] [autoit]

    Func _crlf()
    $ausgabetext = $ausgabetext&@CRLF
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktion _makespaces()
    ; Erstellt die größere Hälfte der Leerzeichen.

    [/autoit] [autoit][/autoit] [autoit]

    Func _makespaces($j)
    $i=0
    While $i<((156-$j)/2)
    $ausgabetext = $ausgabetext&" "
    $i = $i+1
    WEnd
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktion _makecorrectspaces()
    ; Erstellt die gleich große/kleinere zweite Hälfte der Leerzeichen.

    [/autoit] [autoit][/autoit] [autoit]

    Func _makecorrectspaces($j)
    If Mod($j, 2) = 1 Then
    $j=$j+1
    EndIf
    $i=0
    While $i<((156-$j)/2)
    $ausgabetext = $ausgabetext&" "
    $i = $i+1
    WEnd
    EndFunc

    [/autoit]
    • Offizieller Beitrag

    Hallo,

    das Problem mit dem Zeilenumbruch hatten wir doch schon mal -> @LF nach Anzahl zeichen mit GUICtrlSetTip

  • Hab mir den verlinkten Code rekonstruiert und angeschaut.
    Ist mein Code denn garnciht zu retten? So wie er da steht, tut er das nicht, was er soll.

    Habe mal testhalber einen langen Text mit mehreren Absätzen und langen vor allem benutzt. Er trennt im Allgemeinen korrekt (Mehrere CLRFs direkt hintereinander muss ich noch iwie bugfixen, vlt mit if StringLen($bla) != 0... das soll also nicht das Problem sein.
    Problem ist, dass er an irgendeiner Stelle entweder in der Funktion _isspace($bla,$blabla) oder in meiner _edithelp($blablabla) nicht das tut was er macht, und zwar trennt er nicht am ersten vom 150sten zeichen aus rückwärts gefundenen Leerzeichen, sondern einfach immer genau am 150sten Leerzeichen. Sieht zufällig jemand den Fehler?

    Edit: Den ersten der genannten Bugs bin ich losgeworden, hab einfach an einer Stelle vergessen, einen Zeilenumbruch einzufügen.

    zum nervigeren Fehler: kanns sein, dass der Fehler bereits in der Funktion liegt, die mir sagen soll, ob das momentan getestete zeichen ein leerzeichen ist?

    Spoiler anzeigen
    [autoit]

    ; Funktion _findfirstspace($inputstring)
    ; Findet beim 150. Zeichen beginnend rückwärts laufend das erste Leerzeichen
    Func _isspace($inputstring, $position)
    If ( StringInStr($inputstring, " ", 0, 1, $position, $position) = 0) Then
    Return False
    Else
    Return True
    EndIf
    EndFunc

    [/autoit]

    Edit, der letzte: Nun tuts so wie es soll! ;)

    [autoit]

    StringInStr($inputstring, " ", 0, 1, $position, 1)

    [/autoit]


    Macht mehr Sinn, "$count" (siehe Hilfe) sagt, wie weit von der Anfangsposition gesucht werden soll, nicht absolut, bis zur wievielten Stelle im String gesucht werden soll.

    Thx @ all, werde das Gesamtpaket, wenn gewünscht, hier posten ;)

    2 Mal editiert, zuletzt von Weisgarnix (28. Dezember 2010 um 15:27)

  • Ich hoffe, ich hab beim Zusammenstellen des benötigten Codes keine Fehler gemacht, wenn doch, beschwert euch, ansosnten viel Spaß damit ;)
    PS: Ich weiß, mit Returns wärs schöner geworen, aber das kann ja derjenige, ders braucht, selber noch reinbasteln ;)

    Spoiler anzeigen
    [autoit]

    #cs ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    AutoIt Version: 3.3.6.1
    Author: Weisgarnix

    [/autoit] [autoit][/autoit] [autoit]

    Script Function:
    Gibt einen Text zentriert aus
    Zur freien Verwendung für jedermann freigegeben!

    [/autoit] [autoit][/autoit] [autoit]

    #ce ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #Include <String.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $Breite = 150 ; Hier kann die Breite, auf die zentriert werden soll, angegeben werden.
    Dim $ausgabetext

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktionsaufruf, das Ergebnis steht nachher in $ausgabetext
    _edithelp("DeinString")
    ClipPut($ausgabetext)

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktion _edithelp($inputstring)
    ; Erstellt eine mit korrekten Zeilenumbrüchen gespickte
    ; Ausgabe des Inputtextes.

    [/autoit] [autoit][/autoit] [autoit]

    Func _edithelp($inputstring)
    $outputstring = StringReplace($inputstring, @CRLF, @CRLF)
    $countcrlf = @extended
    $stringarray = _StringExplode($outputstring, @CRLF, 0)
    $i = 0 ; zählt Arrayeinträge hoch
    While ( $i < $countcrlf)
    If ( StringLen($stringarray[$i]) > 0 ) Then
    While ( StringLen($stringarray[$i]) > $Breite )
    $j=$Breite ; merkt sich aktuelle Testposition
    $isspace = _isspace($stringarray[$i],$j)
    While ( $isspace = False )
    $j = $j - 1
    $isspace = _isspace($stringarray[$i],$j)
    WEnd
    _makespaces($j)
    $textline = StringMid($stringarray[$i],1,$j)
    $ausgabetext = $ausgabetext&$textline
    _makecorrectspaces($j)
    _crlf()
    $stringarray[$i]=StringMid($stringarray[$i],$j+1)
    WEnd
    _makespaces(StringLen($stringarray[$i]))
    $ausgabetext = $ausgabetext&$stringarray[$i]
    _makecorrectspaces(StringLen($stringarray[$i]))
    _crlf()
    EndIf
    $i = $i + 1
    WEnd
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktion _findfirstspace($inputstring)
    ; Findet beim 150. Zeichen beginnend rückwärts laufend das erste Leerzeichen
    Func _isspace($inputstring, $position)
    If ( StringInStr($inputstring, " ", 0, 1, $position, 1) = 0) Then
    Return False
    Else
    Return True
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;;;;;;;;;;;;;;;;;;;
    ; Ausgabemethoden ;
    ;;;;;;;;;;;;;;;;;;;

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktion _crlf()
    ; Erstellt einen Zeilenumbruch.

    [/autoit] [autoit][/autoit] [autoit]

    Func _crlf()
    $ausgabetext = $ausgabetext&@CRLF
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktion _makespaces()
    ; Erstellt die größere Hälfte der Leerzeichen.

    [/autoit] [autoit][/autoit] [autoit]

    Func _makespaces($j)
    $i=0
    While $i<(($Breite-$j)/2)
    $ausgabetext = $ausgabetext&" "
    $i = $i+1
    WEnd
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Funktion _makecorrectspaces()
    ; Erstellt die gleich große/kleinere zweite Hälfte der Leerzeichen.

    [/autoit] [autoit][/autoit] [autoit]

    Func _makecorrectspaces($j)
    If Mod($j, 2) = 1 Then
    $j=$j+1
    EndIf
    $i=0
    While $i<(($Breite-$j)/2)
    $ausgabetext = $ausgabetext&" "
    $i = $i+1
    WEnd
    EndFunc

    [/autoit]
  • Hallo,

    wenn Du Dich damit abfinden kannst, die Eingabe in einem Edit mit einem Font fester Laufweite zu machen (wie autoBert bereits vorgeschlagen hat), dann kannst Du die Zeilenumbrüche auch dem Edit überlassen:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <EditConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $SS_EDITCONTROL = 0x00002000

    [/autoit] [autoit][/autoit] [autoit]

    $FontName = "Courier New" ; Font mit fester Laufweite
    $FontSize = 9
    $FontWeight = -1
    $FontAttr = -1
    $MaxZeichenInZeile = 140
    $Zeile = ""

    [/autoit] [autoit][/autoit] [autoit]

    ; Wir bauen uns einen String mit der gewünschten Zeichenanzahl
    For $I = 1 To $MaxZeichenInZeile
    If Mod($I, 10) Then
    $Zeile &= Mod($I, 10)
    Else
    $Zeile &= " "
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; Wir erstellen ein DUMMY GUI
    GUICreate("DUMMY")
    ; Wir setzen den gewünschten Font mit fester Laufweite
    GUISetFont($FontSize, $FontWeight, $FontAttr, $FontName)
    ; Wir schauen mal, wie breit ein Label sein muss, um den String aufzunehmen
    GUICtrlCreateLabel($Zeile, 0, 0, -1, -1, $SS_EDITCONTROL)
    $aLabel = WinGetClientSize(GUICtrlGetHandle(-1))
    ; Wir erzeugen ein Edit gleicher Breite und holen uns die realen Abmessungen der Clientarea
    GUICtrlCreateEdit($Zeile, 0, 0, $aLabel[0], 40, $ES_WANTRETURN + $WS_VSCROLL)
    $aEdit = WinGetClientSize(GUICtrlGetHandle(-1))
    ; Das DUMMY GUI hat seine Schuldigkeit getan
    GUIDelete()

    [/autoit] [autoit][/autoit] [autoit]

    ; Die benötigte Breite des Edits entspricht der Breite des Labels
    ; zuzüglich der Differenz Labelbreite - Editbreite
    $EditW = $aLabel[0] + $aLabel[0] - $aEdit[0]

    [/autoit] [autoit][/autoit] [autoit]

    ; Jetzt erstellen wir das echte GUI
    $hGUI = GUICreate("Edit GUI", $EditW, 230)
    ; Das Edit wird in der korrekten Breite für $ZeichenInZeile erstellt
    $idInput = GUICtrlCreateEdit($Zeile, 0, 0, $EditW, 80, $ES_WANTRETURN + $WS_VSCROLL)
    ; Dem Edit wird der Font zugewiesen
    GUICtrlSetFont(-1, $FontSize, $FontWeight, $FontAttr, $FontName)
    ; Zum Spielen wird noch ein readonly Edit für die Anzeige des Editinhalts erstellt
    $idOutput = GUICtrlCreateEdit("", 0, 100, $EditW, 80, $ES_READONLY + $WS_VSCROLL)
    ; ... und ein Button, der den Inhalt übernimmt
    $idBtn = GUICtrlCreateButton("Text holen", 0, 200, 200, 25)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While True
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    ExitLoop
    Case $idBtn
    ; Das Edit soll die "weichen" Zeilenumbrüche durch CRCRLF markieren
    GUICtrlSendMsg($idInput, $EM_FMTLINES, True, 0)
    ; Wir holen uns den Inhalt
    $Text = GUICtrlRead($idInput)
    ; Das Edit kann jetzt wieder normal formatieren
    GUICtrlSendMsg($idInput, $EM_FMTLINES, False, 0)
    ; Die "weichen" Zeilenumbrüche werden durch echte ersetzt
    $Text = StringReplace($Text, @CR & @CRLF, @CRLF)
    ; Der Inhalt des Edits wird im readonly Edit ausgegeben
    GUICtrlSetData($idOutput, $Text)
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Exit

    [/autoit]
  • Kleiner Fehler bei der Arraygrenze...

    Korrigierte Funktion _edithelp($inputstring)
    [autoit]

    Func _edithelp($inputstring)
    $outputstring = StringReplace($inputstring, @CRLF, @CRLF)
    $countcrlf = @extended
    $stringarray = _StringExplode($outputstring, @CRLF, 0)
    $i = 0 ; zählt Arrayeinträge hoch
    While ( $i <= $countcrlf)
    If ( StringLen($stringarray[$i]) > 0 ) Then
    While ( StringLen($stringarray[$i]) > 150 )
    $j=150 ; merkt sich aktuelle Testposition
    $isspace = _isspace($stringarray[$i],$j)
    While ( $isspace = False )
    $j = $j - 1
    $isspace = _isspace($stringarray[$i],$j)
    WEnd
    _makespaces($j)
    $textline = StringMid($stringarray[$i],1,$j)
    $ausgabetext = $ausgabetext&$textline
    _makecorrectspaces($j)
    _crlf()
    $stringarray[$i]=StringMid($stringarray[$i],$j+1)
    WEnd
    _makespaces(StringLen($stringarray[$i]))
    $ausgabetext = $ausgabetext&$stringarray[$i]
    _makecorrectspaces(StringLen($stringarray[$i]))
    _crlf()
    EndIf
    $i = $i + 1
    WEnd
    EndFunc

    [/autoit]

    2 Mal editiert, zuletzt von Weisgarnix (2. Januar 2011 um 23:52)