Nach jeden 4. Zeichen ein "-" setzen

  • UEZ: Bei Deinem Script muss man den Bindestrich extra löschen. Mein Script löscht den Bindestrich, sobald man den Buchstaben danach löscht.

    Oscar du bist der Meister! :thumbup:

    Ferner enthält meine Version noch ein Bug! X(

    Fies ist es, wenn man Seriennummer eingibt und anschließend irgend wo in der Mitte ein Zeichen löscht, weil man eine Veränderung machen möchte (auch in deiner Version) ... ;)

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (4. Januar 2010 um 00:15)

    • Offizieller Beitrag
    Zitat

    Fies ist es, wenn man Seriennummer eingibt und anschließend irgend wo in der Mitte ein Zeichen löscht, weil man eine Veränderung machen möchte (auch in deiner Version) ... ;)

    Das ist wahrscheinlich der Grund, warum alle Softwarehersteller mehrere Inputs benutzen, für die SN Eingabe. :D

  • Irgendwie komme ich von diesem Thema nicht weg!

    Hier nun mit der Sperre der Cursor Tasten:

    Spoiler anzeigen
    [autoit]


    ;by UEZ
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <Misc.au3>
    Opt("GUIOnEventMode", 1)

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

    $dll = DllOpen("user32.dll")
    $hGUI = GUICreate("Seriennummer", 232, 90)
    $input = GUICtrlCreateInput("", 42, 30, 140)
    $Label = GUICtrlCreateLabel("Format: XXXX-XXXX-XXXX-XXXX", 32, 8, 163, 17)
    GUICtrlSetLimit($input, 19)
    $Button = GUICtrlCreateButton("Weiter", 144, 56, 75, 25, $WS_GROUP)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()
    $iLen_prev = 0
    $iCurPos = 0
    GUIRegisterMsg($WM_COMMAND, '_WM_COMMAND')
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

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

    While Sleep(10)
    $aCaret_pos = WinGetCaretPos()
    If _IsPressed("25", $dll) Or _IsPressed("26", $dll) Then ;left or up
    Send("{RIGHT}")
    ElseIf _IsPressed("27", $dll) Or _IsPressed("28", $dll) Then ;right or down
    DllCall("User32.dll", 'int', 'SetCaretPos', 'int', $aCaret_pos[0], 'int', $aCaret_pos[1])
    EndIf
    $aPos = GUIGetCursorInfo($hGUI)
    If $aPos[2] And $aPos[4] = $input Then
    ControlFocus("", "", $input)
    Send("{Right 50}")
    EndIf

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

    WEnd

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

    Func _Exit()
    DllClose($dll)
    Exit
    EndFunc

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

    Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    If BitAND($wParam, 0x0000FFFF) = $input Then
    GUICtrlSetData($input, StringUpper(GUICtrlRead($input))) ;upper letters
    $i = GUICtrlRead($input)
    $iLen = StringLen($i) + 1
    If Mod($iLen, 5) = 0 And $iLen > $iLen_prev And $iLen < 20 Then GUICtrlSetData($input, $i & "-")
    If Mod($iLen, 5) = 0 And $iLen < $iLen_prev Then GUICtrlSetData($input, StringLeft($i, $iLen - 2))
    $iLen_prev = $iLen
    If $iLen = 20 Then
    GUICtrlSetState($Button, $GUI_ENABLE)
    Else
    GUICtrlSetState($Button, $GUI_DISABLE)
    EndIf
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit]

    Gruß,
    UEZ

  • UEZ: Deins funzt auch noch nicht so einwandfrei, wenn du schreibst kannst du zwar mit der Backspace die Zeichen löschen und neu schreiben. Aber sagen wir mal du hast alles geschrieben und dir fällt auf im 3. Block ist das 2. Zeichen falsch, also gehst du mit dem Cursor dahin und löscht es, wenn du dann deinen Cursor gesetzt hast und Backspace klickst, löscht er das Zeichen und springt ans Ende der ganzen Nummer und wenn du dann das richtige Zeichen eingibst schreibt er es ans Ende, dann besteht der 3. Block aus 3 Zeichen und der 4. aus 5 Zeichen.

  • Hab das jetzt mal mit 4 Controls und WM_Command umgesetzt.

    Spoiler anzeigen
    [autoit]


    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <ListViewConstants.au3>
    #include <Guilistview.au3>
    #include <WindowsConstants.au3>

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

    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("Form1", 633, 438, 192, 132)
    $ListView1 = GUICtrlCreateListView("Input1|Input2|Input3|Input4", 16, 16, 601, 265)
    Global $hLVHandle = GUICtrlGetHandle($ListView1)
    _GUICtrlListView_SetColumn($hLVHandle, 0, "Input1", 130, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 1, "Input2", 130, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 2, "Input3", 130, 0)
    _GUICtrlListView_SetColumn($hLVHandle, 3, "Input4", 130, 0)
    $Input1 = GUICtrlCreateInput("", 16, 320, 129, 24)
    GUICtrlSetLimit(-1, 4)
    $Input2 = GUICtrlCreateInput("", 168, 320, 129, 24)
    GUICtrlSetLimit(-1, 4)
    $Input3 = GUICtrlCreateInput("", 328, 320, 137, 24)
    GUICtrlSetLimit(-1, 4)
    $Input4 = GUICtrlCreateInput("", 496, 320, 121, 24)
    GUICtrlSetLimit(-1, 4)

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

    GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")

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

    $button = GUICtrlCreateButton("ADD", 250, 350, 100, 50)

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

    Global $hCM = GUICtrlCreateContextMenu($ListView1) ; ein Kontextmenü für das Listview erstellen
    Global $hCMDel = GUICtrlCreateMenuItem("Markierte Einträge löschen", $hCM) ; der 3. Kontextmenüeint

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

    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $button
    _NewItem()
    Case $hCMDel
    _GUICtrlListView_DeleteItemsSelected($hLVHandle)
    EndSwitch
    WEnd

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

    Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    $nNotifyCode = BitShift($wParam, 16)
    If $nNotifyCode = $EN_UPDATE Then
    Switch ControlGetFocus("Form1")
    Case "Edit1"
    If StringLen(GUICtrlRead($Input1)) = 4 Then GUICtrlSetState($Input2, $gui_focus)
    Case "Edit2"
    If StringLen(GUICtrlRead($Input2)) = 4 Then GUICtrlSetState($Input3, $gui_focus)
    Case "Edit3"
    If StringLen(GUICtrlRead($Input3)) = 4 Then GUICtrlSetState($Input4, $gui_focus)
    Case "Edit4" ;Vorsicht es droht eine Endlosschleife
    If StringLen(GUICtrlRead($Input4)) = 4 Then
    ConsoleWrite("Achtung - Dieser Befehl muss gut durchdacht sein" & @CRLF & "Soll der Fokus wieder auf Input1 gesetzt werden müssen die Controls zuerst wieder zurückgesetzt werden, da das Skript sonst in einer Endlosschleife hängt")
    _NewItem()
    GUICtrlSetData($Input1, "")
    GUICtrlSetData($Input2, "")
    GUICtrlSetData($Input3, "")
    GUICtrlSetData($Input4, "")
    GUICtrlSetState($Input1, $gui_focus)
    EndIf

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

    EndSwitch
    EndIf
    EndFunc ;==>MY_WM_COMMAND

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

    Func _NewItem() ; Funktion zum auslesen der Eingabefelder (Neuer Eintrag bzw. Eintrag bearbeiten)
    GUICtrlCreateListViewItem(GUICtrlRead($Input1) & "|" & GUICtrlRead($Input2) & "|" & GUICtrlRead($Input3) & "|" & GUICtrlRead($Input4), $ListView1)
    EndFunc ;==>_NewItem

    [/autoit]

    edit \ verbesserte Version

    Einmal editiert, zuletzt von nuts (9. Januar 2010 um 12:47)

  • UEZ: Deins funzt auch noch nicht so einwandfrei, wenn du schreibst kannst du zwar mit der Backspace die Zeichen löschen und neu schreiben. Aber sagen wir mal du hast alles geschrieben und dir fällt auf im 3. Block ist das 2. Zeichen falsch, also gehst du mit dem Cursor dahin und löscht es, wenn du dann deinen Cursor gesetzt hast und Backspace klickst, löscht er das Zeichen und springt ans Ende der ganzen Nummer und wenn du dann das richtige Zeichen eingibst schreibt er es ans Ende, dann besteht der 3. Block aus 3 Zeichen und der 4. aus 5 Zeichen.

    Genau das ist doch das Fiese dran! Deshalb habe ich doch in Post 25 die Cursor Tasten abgefragt, so dass der Cursor nich mehr per Cursor Tasten nach links bewegt werden kann!

    D.h. mit Backspace geht nur noch das Löschen und somit muss man alles löschen, wenn man am Anfang einen Fehler gemacht hat!

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hab das jetzt mal mit 4 Controls und WM_Command umgesetzt.

    2 Sachen sind mir aufgefallen:

    • Wie kann ich in das Feld zurück, damit ich die Eingabe ändern kann?
    • Nach der Eingabe des letzten Zeichens wird die Seriennummer automatisch in die Liste eingefügt. Was ist, wenn das letzte Zeichen falsch ist?

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Ich hätte noch eine Alternative für die Kontrolle ;)

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <Misc.au3>
    $Form = GUICreate("Seriennummer", 232, 83)
    $edtSerial = GUICtrlCreateInput("", 48, 30, 136)
    $Label = GUICtrlCreateLabel("Format: XXXX-XXXX-XXXX-XXXX", 32, 8, 163, 17)
    GUICtrlSetLimit($edtSerial, 19)
    $Button = GUICtrlCreateButton("Weiter", 144, 56, 75, 25, $WS_GROUP)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()
    $iLen_prev = 0
    GUIRegisterMsg($WM_COMMAND, '_WM_COMMAND')

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

    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    WEnd

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

    Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    If BitAND($wParam, 0x0000FFFF) = $edtSerial And BitAND($wParam, 0xFFFF0000) = 0x04000000 Then
    Local $oldText = GUICtrlRead($edtSerial)
    Local $text = StringLeft(StringRegExpReplace(StringRegExpReplace(StringUpper($oldText), "[^A-Z0-9]", ''), '(.{4})', '\1-', 4),19)
    If StringCompare($text, $oldText, 1) <> 0 Then
    Local $sStruct = DllStructCreate("uint;uint")
    GUICtrlSendMsg($edtSerial, 0x00B0, DllStructGetPtr($sStruct,1), DllStructGetPtr($sStruct, 2))
    GUICtrlSetData($edtSerial, $text)
    GUICtrlSendMsg($edtSerial, 0x00B1, DllStructGetData($sStruct,1), DllStructGetData($sStruct, 2))
    EndIf
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit]
  • Ich hätte noch eine Alternative für die Kontrolle ;)

    Sehr interessanter Ansatz! Wie nuts schon erwähnte, werden Zeichen der Eingabe vor den Cursor verschoben, wenn man "schnell" eingibt!

    Vielleicht kann man da noch ein bisschen tunen!

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Das Problem liegt nicht daran, dass der Cursor verschoben wird, wenn man schnell eingibt, sondern, dass der Cursor vor dem Bindestrich stehen bleibt. Und so die Verschiebung beim Weiterschreiben zustande kommt.

    MfG


    Stimmt, hab ich ausgebessert:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <Misc.au3>
    $Form = GUICreate("Seriennummer", 232, 83)
    $edtSerial = GUICtrlCreateInput("", 48, 30, 136)
    $Label = GUICtrlCreateLabel("Format: XXXX-XXXX-XXXX-XXXX", 32, 8, 163, 17)
    GUICtrlSetLimit($edtSerial, 19)
    $Button = GUICtrlCreateButton("Weiter", 144, 56, 75, 25, $WS_GROUP)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()
    $iLen_prev = 0
    GUIRegisterMsg($WM_COMMAND, '_WM_COMMAND')

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

    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    WEnd

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

    Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    If BitAND($wParam, 0x0000FFFF) = $edtSerial And BitAND($wParam, 0xFFFF0000) = 0x04000000 Then
    Local $oldText = GUICtrlRead($edtSerial)
    Local $text = StringLeft(StringRegExpReplace(StringRegExpReplace(StringUpper($oldText), "[^A-Z0-9]", ''), '(.{4})', '\1-', 4),19)
    If StringCompare($text, $oldText, 1) <> 0 Then
    Local $sStruct = DllStructCreate("uint;uint")
    GUICtrlSendMsg($edtSerial, 0x00B0, DllStructGetPtr($sStruct,1), DllStructGetPtr($sStruct, 2))
    Local $iStart =DllStructGetData($sStruct,1), $iEnd = DllStructGetData($sStruct, 2)
    GUICtrlSetData($edtSerial, $text)
    If $iStart = $iEnd And StringMid($text, $iStart+1, 1) = '-' Then
    $iStart +=1
    $iEnd +=1
    EndIf
    GUICtrlSendMsg($edtSerial, 0x00B1, $iStart, $iEnd)
    EndIf
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit]
  • Bei mir geht in Deiner letzten Version folgendes nicht:

    - "weiter" nach Eingabe von 16 Zeichen
    - Backspace nur um die letzten 4 Zeichen

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

  • Weiter nach 16 Zeichen hab ich nicht eingebaut, das war mir unwichtig ;)
    Backspace geht, aber über die striche musst du mit den Cursortasten drüber.

  • Nein, Ich meinte der "Weiter"-Button ist bei mir nicht anwählbar.

    Edit: Ich sehe gerade, der "SetState" für den Button ist gar nicht umgesetzt.

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

  • Nein, Ich meinte der "Weiter"-Button ist bei mir nicht anwählbar.
    Edit: Ich sehe gerade, der "SetState" für den Button ist gar nicht umgesetzt.


    Genau das hab ich gemeint. Aber so kannst du es machen:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <Misc.au3>
    $Form = GUICreate("Seriennummer", 232, 83)
    $edtSerial = GUICtrlCreateInput("", 48, 30, 136)
    $Label = GUICtrlCreateLabel("Format: XXXX-XXXX-XXXX-XXXX", 32, 8, 163, 17)
    GUICtrlSetLimit($edtSerial, 19)
    $Button = GUICtrlCreateButton("Weiter", 144, 56, 75, 25, $WS_GROUP)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()
    $iLen_prev = 0
    GUIRegisterMsg($WM_COMMAND, '_WM_COMMAND')

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

    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    WEnd

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

    Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    If BitAND($wParam, 0x0000FFFF) = $edtSerial And BitAND($wParam, 0xFFFF0000) = 0x04000000 Then
    Local $oldText = GUICtrlRead($edtSerial)
    Local $text = StringLeft(StringRegExpReplace(StringRegExpReplace(StringUpper($oldText), "[^A-Z0-9]", ''), '(.{4})', '\1-', 4),19)
    If StringCompare($text, $oldText, 1) <> 0 Then
    Local $sStruct = DllStructCreate("uint;uint")
    GUICtrlSendMsg($edtSerial, 0x00B0, DllStructGetPtr($sStruct,1), DllStructGetPtr($sStruct, 2))
    Local $iStart =DllStructGetData($sStruct,1), $iEnd = DllStructGetData($sStruct, 2)
    GUICtrlSetData($edtSerial, $text)
    If $iStart = $iEnd And StringMid($text, $iStart+1, 1) = '-' Then
    $iStart +=1
    $iEnd +=1
    EndIf
    GUICtrlSendMsg($edtSerial, 0x00B1, $iStart, $iEnd)
    If StringLen($text) = 19 And _SerialIsValid($text) Then
    GUICtrlSetState($Button, $GUI_ENABLE)
    Else
    GUICtrlSetState($Button, $GUI_DISABLE)
    EndIf
    EndIf
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func _SerialIsValid($sSerial)
    Return StringRegExp($sSerial, "^([A-Z0-9]{4}-){3}[A-Z0-9]{4}$")
    EndFunc

    [/autoit]