Vorgaben in Input-Felder mit Enter übernehmen

  • Hallo

    In einer GUI gibts mehrere Eingabefelder:

    [autoit]

    $input1 = GUICtrlCreateInput(....)
    $input2 = GUICtrlCreateInput(....)

    [/autoit]

    Jetzt wird durch Eingaben und Berechnungen des öfteren der Wert des nächsten Eingabefeldes ermittelt und als Vorschlag angeboten - das funktioniert auch. Nun soll der Vorschlag (meistens) durch drücken der Enter-Taste übernommen werden. Das löst aber nicht die Fortsetzung des Programms (im Beispiel nach "Case $input2") aus - also [weitere Berechnungen] bzw. die Weitergabe des Focus an Input3.


    [autoit]

    .
    Switch $nMsg
    Case $input1
    $wert1 = GUICtrlRead($input1)
    [Berechnungen]
    .
    .
    $wert2 = (wurde berechnet)
    GUICtrlSetData($input2, $wert2)
    GUICtrlSetState($input2, $GUI_FOCUS)
    Case $input2
    $wert2 = GUICtrlRead($input2)
    [weitere Berechnungen]
    .
    .
    GUICtrlSetData($input3, $wert3)
    GUICtrlSetState($input3, $GUI_FOCUS)

    [/autoit]

    Könnt Ihr mir auf die Sprünge helfen?

    Schöne Grüße,
    entsel
    AutoLisp(eln) geht ganz gut, aber AutoIt nur mit Dictionary. 
    Das Problem - man sollte wissen, welche Vokabel man sucht.

  • Danke mal für die Antwort.

    Auf den ersten Blick verstehe ich davon allerdings nur viel "Bahnhof". ?(
    Ich werde mich aber noch ausgiebiger damit beschäftigen - vielleicht geht mir ja dann das eine oder andere Licht auf - melde mich dann später wieder.

    Danke

    Schöne Grüße,
    entsel
    AutoLisp(eln) geht ganz gut, aber AutoIt nur mit Dictionary. 
    Das Problem - man sollte wissen, welche Vokabel man sucht.

  • Hallo BugFix

    Die ersten Zeilen glaube ich in etwa zu durchschauen:
    ich vermute, es werden 2 GUI's erstellt, eine Art "Identität" abgefragt, und das 2. angezeigt.

    Mit

    [autoit]

    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

    [/autoit]


    und

    [autoit]

    Case -3

    [/autoit]


    kann ich leider gar nix anfangen ...

    Die Funktion WM_COMMAND sollte (nach meinem Verständnis) irgendwo (mit 4 Argumenten ?) aufgerufen werden ?
    Passiert das damit ???:

    [autoit]

    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

    [/autoit]

    ?
    Was ist dann mit der Anzahl der Argumente ?
    $hWnd, $iMsg, $iwParam, $ilParam: wird denen nie ein Wert zugewiesen? (wie etwa $hWnd = ... ?)


    Nach

    [autoit]

    Case $hWndFrom = $hIn And $iCode = $EN_CHANGE

    [/autoit]


    bzw.

    [autoit]

    Case $iCode = 0x0

    [/autoit]


    wird dann jeweils das andere GUI angezeigt/verborgen bzw. mit Daten beschickt und der Focus gesetzt,
    wenn ich's richtig verstanden hab?
    Aber was die beiden Zeilen selber bedeuten kann ich leider nicht entschlüsseln, das ist ganz offensichtlich noch zu hoch für mich.

    Würd' mich freuen, wenn Du mir das anhand meines Beispiels noch genauer erklären könntest?:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>

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

    $hGUI = GUICreate('TEST')
    $input1 = GUICtrlCreateInput('1', 40, 30, 60, 20)
    $input2 = GUICtrlCreateInput('', 40, 60, 60, 20)
    $input3 = GUICtrlCreateInput('', 40, 90, 60, 20)
    $input4 = GUICtrlCreateInput('', 40, 120, 60, 20)
    GUISetState(@SW_SHOW, $hGUI)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $input1
    $wert1 = GUICtrlRead($input1)
    GUICtrlSetData($input2, 2)
    GUICtrlSetState($input2, $GUI_FOCUS)
    Case $input2
    $wert2 = GUICtrlRead($input2)
    GUICtrlSetData($input3, 3)
    GUICtrlSetState($input3, $GUI_FOCUS)
    Case $input3
    $wert3 = GUICtrlRead($input3)
    GUICtrlSetData($input4, 4)
    GUICtrlSetState($input4, $GUI_FOCUS)
    Case $input4
    $wert4 = GUICtrlRead($input4)
    EndSwitch
    WEnd

    [/autoit]

    Wenn ich einen Wert eingebe, läufts ja weiter, ich will aber oft den Vorschlag nur mit Enter übernehmen.

    Schöne Grüße,
    entsel
    AutoLisp(eln) geht ganz gut, aber AutoIt nur mit Dictionary. 
    Das Problem - man sollte wissen, welche Vokabel man sucht.

    • Offizieller Beitrag

    Ich hab mal die Lösung erstellt und etwas kommentiert.

    Spoiler anzeigen
    [autoit]

    #Include <GUIConstantsEx.au3>
    #include <WinAPI.au3>
    #include <Array.au3>

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

    Global Const $WM_COMMAND = 0x0111

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

    $hGUI = GUICreate('TEST')
    $input1 = GUICtrlCreateInput('1', 40, 30, 60, 20)
    $input2 = GUICtrlCreateInput('', 40, 60, 60, 20)
    $input3 = GUICtrlCreateInput('', 40, 90, 60, 20)
    $input4 = GUICtrlCreateInput('', 40, 120, 60, 20)
    $btArray = GUICtrlCreateButton('Zeige Werte-Array', 20, 200, 150, 25)

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

    Global $aInput[4][2] = [[$input1],[$input2],[$input3],[$input4]] ; == alle Input in einem Array verwalten, Werte werden in das Array gelesen

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

    GUISetState(@SW_SHOW, $hGUI)

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

    GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND') ; == registriert Windows-Message "WM_COMMAND" und weist dieser Msg die gleichnamige Funktion zu

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $btArray
    _ArrayDisplay($aInput)
    EndSwitch
    WEnd

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

    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode, $iNext, $fFound = False
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF) ; Low Word
    $iCode = BitShift($iwParam, 16) ; Hi Word
    Select
    Case $iCode = 0x0
    Local $ID = _WinAPI_GetDlgCtrlID(ControlGetHandle($hGUI, '', ControlGetFocus($hGUI)))
    For $i = 0 To UBound($aInput) -1
    If $aInput[$i][0] = $ID Then
    $fFound = True
    ExitLoop
    EndIf
    Next
    If Not $fFound Then Return $GUI_RUNDEFMSG ; == Control-ID gehört nicht zu den überwachten Input
    $iNext = $i +1
    If $iNext = UBound($aInput) Then $iNext = 0 ; == Array-Index für nächstes Control, bei Ende wieder zum ersten
    $aInput[$i][1] = GUICtrlRead($aInput[$i][0]) ; == Wert auslesen und in das Array schreiben
    ControlFocus($hGUI, '', $aInput[$iNext][0]) ; == Fokus auf nächstes Input setzen
    EndSelect
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_COMMAND

    [/autoit]
  • Hallo BugFix

    Danke für Deine Mühe.
    Mit Deiner Lösung komme ich zwar mit Enter ins nächste Feld, aber was mir jetzt fehlt ist, was ich mit

    Case $input1
    GUICtrlSetData($input2, 2)

    dargestellt habe.
    Wenn ich also in Feld1 z.B. eine Baustellenadresse eingebe, könnte man davon eine zuständige Behörde ableiten (natürlich aus weiteren vorhandenen Daten) und in Feld 2 als Vorgabe eintragen, die dann meist mit Enter bestätigt werden könnte (für die Ausnahmen bleibt die Überschreibmöglichkeit). Kennt man weiters die Art des Auftrags, könnte man vielleicht den Sachbearbeiter ermitteln. Termine sind vielleicht abhängig von anderen Terminen, usw.
    Die Daten (hier als Wert 2) müssten natürlich in jedem "Case $Inputx" anders berechnet werden.

    Wenn ich aber kein "Case $input..." habe, wie kann ich da wissen, was ich grade eingegeben (welches Feld in grade befüllt) habe?
    Oder bin ich noch zu "neu" um es zu durchschauen?

    Schöne Grüße,
    entsel
    AutoLisp(eln) geht ganz gut, aber AutoIt nur mit Dictionary. 
    Das Problem - man sollte wissen, welche Vokabel man sucht.

  • Hallo BugFix

    Was den Wert betrifft - das hast Du ja kommentiert:
    $aInput[$i][1] = GUICtrlRead($aInput[$i][0]) ; == Wert auslesen und in das Array schreiben
    Aber -
    angenommen ich starte das Programm, gebe etwas in Input2 ein - wie könnte ich dann feststellen, dass es eben in Input2, und nicht in Input1 oder 4, 7 oder 12 eingegeben wurde.
    Oder anders gesagt, wie weiß ich (programmtechnisch), ob ich eine Adresse, den Namen des Auftraggebers oder den eines Sachbearbeiters eingegeben habe. Und abhängig davon sollten ja auch verschiedene Funktionen angestoßen werden ...

    Ich fürchte, Deine Mühe dürfte umsonst gewesen zu sein und eine Lösung scheint nicht möglich.
    Und falls doch, ist sie für mich wahrscheinlich schon zu kompliziert.

    Schöne Grüße,
    entsel
    AutoLisp(eln) geht ganz gut, aber AutoIt nur mit Dictionary. 
    Das Problem - man sollte wissen, welche Vokabel man sucht.

    • Offizieller Beitrag

    Ich fürchte, Deine Mühe dürfte umsonst gewesen zu sein und eine Lösung scheint nicht möglich.


    (Fast) Nichts ist unmöglich. :D
    Hier inkl. "Anschieben" weiteren Codes:

    Spoiler anzeigen
    [autoit]

    #Include <WinAPI.au3>
    #Include <Array.au3>
    #Include <GUIConstantsEx.au3>
    #Include <WindowsConstants.au3>

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

    Global $fID_Changed = False, $iID_Current, $iIndex_Current

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

    $hGUI = GUICreate('TEST')
    $input1 = GUICtrlCreateInput('1', 40, 30, 60, 20)
    $input2 = GUICtrlCreateInput('', 40, 60, 60, 20)
    $input3 = GUICtrlCreateInput('', 40, 90, 60, 20)
    $input4 = GUICtrlCreateInput('', 40, 120, 60, 20)
    $btArray = GUICtrlCreateButton('Zeige Werte-Array', 20, 200, 150, 25)

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

    Global $aInput[4][2] = [[$input1],[$input2],[$input3],[$input4]] ; == alle Input in einem Array verwalten, Werte werden in das Array gelesen

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

    GUISetState(@SW_SHOW, $hGUI)

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

    GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND') ; == registriert Windows-Message "WM_COMMAND" und weist dieser Msg die gleichnamige Funktion zu

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

    While 1
    If $fID_Changed Then
    $fID_Changed = False
    _Event()
    EndIf
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $btArray
    _ArrayDisplay($aInput)
    EndSwitch
    WEnd

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

    Func _Event()
    Switch $iID_Current
    Case $input1
    MsgBox(0, '', 'Hier dein Code für Input-1' & @CRLF & 'Wert: ' & $aInput[$iIndex_Current][1])
    Case $input2
    MsgBox(0, '', 'Hier dein Code für Input-2' & @CRLF & 'Wert: ' & $aInput[$iIndex_Current][1])
    Case $input3
    MsgBox(0, '', 'Hier dein Code für Input-3' & @CRLF & 'Wert: ' & $aInput[$iIndex_Current][1])
    Case $input4
    MsgBox(0, '', 'Hier dein Code für Input-4' & @CRLF & 'Wert: ' & $aInput[$iIndex_Current][1])
    EndSwitch
    EndFunc

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

    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode, $iNext, $fFound = False
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF) ; Low Word
    $iCode = BitShift($iwParam, 16) ; Hi Word
    Select
    Case $iCode = 0x0
    Local $ID = _WinAPI_GetDlgCtrlID(ControlGetHandle($hGUI, '', ControlGetFocus($hGUI)))
    For $i = 0 To UBound($aInput) -1
    If $aInput[$i][0] = $ID Then
    $fFound = True
    ExitLoop
    EndIf
    Next
    If Not $fFound Then Return $GUI_RUNDEFMSG ; == Control-ID gehört nicht zu den überwachten Input
    $iNext = $i +1
    If $iNext = UBound($aInput) Then $iNext = 0 ; == Array-Index für nächstes Control, bei Ende wieder zum ersten
    $aInput[$i][1] = GUICtrlRead($aInput[$i][0]) ; == Wert auslesen und in das Array schreiben
    ControlFocus($hGUI, '', $aInput[$iNext][0]) ; == Fokus auf nächstes Input setzen
    $iID_Current = $ID ; == aktuelle ID in Globale Variable schreiben (für Weiterverarbeitung)
    $iIndex_Current = $i ; == Array-Index der ID in Globale Variable schreiben (für Weiterverarbeitung)
    $fID_Changed = True ; == Triggerwert zum Start der Weiterverarbeitung
    EndSelect
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_COMMAND

    [/autoit]