• Offizieller Beitrag

    Hi,
    da ich für meine Oberflächen auf Arbeit viel mit Datumsfeldern arbeite, habe ich mir jetzt mal eigene Datum-Inputs erstellt.
    Der Nachteil beim GUICtrlCreateDate ist, dass man bei der Eingabe immer in einer der 3 Gruppen (TT, MM od. JJJJ) hängt und nicht fortlaufend schreiben kann.
    Da ich den Date-Picker sowieso nie benutze, ist mir ein vorformatiertes Input lieber. Die Eingaben werden während des Schreibens auf Richtigkeit geprüft. Bei Eingabe eines falschen Wertes wird die Anzeige auf den Stand vor der Eingabe zurückgesetzt. Rein optisch bleibt der Cursor stehen. Beim Verlassen des Inputs wird nochmals validiert (falls unvollständige Eingabe). Liegt ein Fehler vor, bleibt der Fokus auf dem Input. Man kann das Input nur bei korrektem oder wieder gelöschtem Datum verlassen.
    Überprüft wird der Datumszeitraum von 01.01.1900 bis 31.12.2999 (Da das Pattern bis 2099 unwesentlich kürzer als bis 2999 ist, habe ich den gesamten Zeitraum verwendet.). Löschen ist nicht mit Backspace möglich, sondern über: Markieren - Entfernen.
    Zur Verwendung:
    Die Inputs, wie im Bsp. erstellen und deren ID's im $arDateInput der Funktion MY_WM_COMMAND() hinterlegen.
    Geschrieben werden kann nur, wenn ein Bereich markiert ist (also überschreibbar). Das ist gewollt, da immer der noch nicht geschriebene Teil des Datums markiert wird. Deshalb am Besten per TAB zu den Inputs bewegen, dann ist sofort alles markiert.

    Edit: Oops, da hatte ich einen Fehler in die Validierungsfunktion reinkopiert... Ist nun behoben.

    Spoiler anzeigen
    [autoit]

    #include <Editconstants.au3>
    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    Global $GUI, $Input1, $Input2, $Input3, $Input4
    $GUI = GUICreate('TEST')
    $Input1 = GUICtrlCreateInput("__.__.____", 20, 50, 62, 21, $ES_NUMBER)
    $Input2 = GUICtrlCreateInput("__.__.____", 20, 80, 62, 21, $ES_NUMBER)
    $Input3 = GUICtrlCreateInput("__.__.____", 20, 110, 62, 21, $ES_NUMBER)
    $Input4 = GUICtrlCreateInput("__.__.____", 20, 140, 62, 21, $ES_NUMBER)
    GUISetState()
    GUIRegisterMsg($WM_COMMAND, 'MY_WM_COMMAND')

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

    While 1
    $msg = GUIGetMsg()
    Switch $msg
    Case $GUI_EVENT_CLOSE
    Exit
    Case Else
    ; ...
    EndSwitch
    WEnd

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

    Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $nNotifyCode = BitShift($wParam, 16)
    Local $hCtrl = $lParam
    Local $arDateInput[4] = [$Input1,$Input2,$Input3,$Input4] ; Array mit den ID der zu prüfenden Inputs
    If $nNotifyCode = 1024 Then
    For $i = 0 To UBound($arDateInput) -1
    If $hCtrl = GUICtrlGetHandle($arDateInput[$i]) Then
    _CheckDateInput($hWnd, $arDateInput[$i])
    ExitLoop
    EndIf
    Next
    ElseIf $nNotifyCode = 512 Then
    For $i = 0 To UBound($arDateInput) -1
    If $hCtrl = GUICtrlGetHandle($arDateInput[$i]) Then
    _CheckByFocusLost($hWnd, $arDateInput[$i])
    ExitLoop
    EndIf
    Next
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func _CheckDateInput($hWnd, $ID)
    Local $current = StringReplace(GUICtrlRead($ID),'.',''), $str = '__.__.____'
    Local $num = StringRegExp($current, '\d', 3)
    If @error Then Return GUICtrlSetData($ID, $str)
    Local $ub = UBound($num)
    Local $arPattern[8] = [ _
    "[0-3]", "(0[1-9]|[12][0-9]|3[01])", "(0[1-9]|[12][0-9]|3[01])[0-1]", _
    "(((0[1-9]|[12][0-9])02)|((0[1-9]|[12][0-9]|30)(0[469]|11))|(0[1-9]|[12][0-9]|3[01])(0[13578]|1[02]))", _
    "(((0[1-9]|[12][0-9])02)|((0[1-9]|[12][0-9]|30)(0[469]|11))|(0[1-9]|[12][0-9]|3[01])(0[13578]|1[02]))[12]", _
    "(((0[1-9]|[12][0-9])02)|((0[1-9]|[12][0-9]|30)(0[469]|11))|(0[1-9]|[12][0-9]|3[01])(0[13578]|1[02]))[12][09]", _
    "(((0[1-9]|[12][0-9])02)|((0[1-9]|[12][0-9]|30)(0[469]|11))|(0[1-9]|[12][0-9]|3[01])(0[13578]|1[02]))[12][09]\d", _
    "((((0[1-9]|1[0-9]|2[0-8])02)|((0[1-9]|[12][0-9]|30)(0[469]|11))|(0[1-9]|[12][0-9]|3[01])(0[13578]|1[02]))" & _
    "((19|2[0-9])([02468][1235679]|[13579][01345789])|(19|2[1235679])00))|((((0[1-9]|1[0-9]|2[0-9])02)|((0[1-9]|[12][0-9]|30)" & _
    "(0[469]|11))|(0[1-9]|[12][0-9]|3[01])(0[13578]|1[02]))((19|2[0-9])(04|08|[2468][048]|[13579][26])|(20|24|28)00))"]
    If Not StringRegExp($current, $arPattern[$ub-1]) Then $ub -= 1
    Switch $ub
    Case 0
    GUICtrlSetData($ID, $str)
    Case 1
    GUICtrlSetData($ID, $num[0] & StringRight($str, 9))
    Case 2
    GUICtrlSetData($ID, $num[0] & $num[1] & StringRight($str, 8))
    Case 3
    GUICtrlSetData($ID, $num[0] & $num[1] & '.' & $num[2] & StringRight($str, 6))
    $ub += 1
    Case 4
    GUICtrlSetData($ID, $num[0] & $num[1] & '.' & $num[2] & $num[3] & StringRight($str, 5))
    $ub += 1
    Case 5 to 8
    Local $sYear = ''
    For $i = 4 To $ub -1
    $sYear &= $num[$i]
    Next
    GUICtrlSetData($ID, $num[0] & $num[1] & '.' & $num[2] & $num[3] & '.' & $sYear & StringRight($str, 8 -$ub))
    $ub += 2
    EndSwitch
    ControlSend($hWnd, '', $ID, '{END}{SHIFTDOWN}{HOME}{RIGHT ' & $ub & '}{SHIFTUP}')
    EndFunc

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

    Func _CheckByFocusLost($hWnd, $ID)
    If StringLen(StringReplace(StringReplace(GUICtrlRead($ID),'.',''),'_','')) = 0 Then Return
    If Not StringRegExp(StringReplace(StringReplace(GUICtrlRead($ID),'.',''),'_',''), "((((0[1-9]|1[0-9]|2[0-8])02)|((0[1-9]|[12][0-9]|30)(0[469]|11))|(0[1-9]|[12][0-9]|3[01])(0[13578]|1[02]))" & _
    "((19|2[0-9])([02468][1235679]|[13579][01345789])|(19|2[1235679])00))|((((0[1-9]|1[0-9]|2[0-9])02)|((0[1-9]|[12][0-9]|30)" & _
    "(0[469]|11))|(0[1-9]|[12][0-9]|3[01])(0[13578]|1[02]))((19|2[0-9])(04|08|[2468][048]|[13579][26])|(20|24|28)00))") Then _
    ControlFocus($hWnd, '', $ID)
    EndFunc

    [/autoit]
  • Ich öffne dein Testtool und klicke mit der Maus in das zweite Feld (egal an welche Stelle) und schon kann ich nichts mehr eintippen.

    Ich öffne dein Testtool und klicke mit der Maus und trage 01.02.2000 ein, setze den Cursor anschließend zwischen 0 und 1 und drücke entfernen. Damit werden die folgenden Stellen eingerückt und zeigen ein völlig anderes Datum.


    Insgesamt finde ich den Umgang sehr ungewohnt und nicht intuitiv für den Nutzer. Ich persönlich finde führende Nullen in einem Ausdruck wesentlich schöner als ein Datum wie 4.5.2000, aber die Eingabe eines solchen Datum sollte schon möglich sein.