EIn Feld für Ein- und Ausgabe

  • Hi, zusammen,

    ich bin nur Gelegenheits-Coder, habe zwar vor einger Zeit schon 'mal
    zwei Installations-Skripte mit AutoIt erstellt, für mein derzeitiges Thema
    muss ich mir aber wieder alles neu erschließen.

    Die Aufgabe ist eigentlich ganz einfach:
    Die Eingabe einer Zahl soll dazu führen, dass über ein festes Verhältnis ein
    Ergebnis in einem anderen Feld ausgegeben wird ( 44.100 x 60 / Input ).

    Ich habe mir entsprechende Beispiele in diversen Foren, auch in Eurem, angeschaut.
    Die arbeiten aber meistens mit einem oder mehreren Eingabefenstern und einer
    Ausgabe in einem neuen Fenster über MsgBox. Das sieht in der Anwendung nicht
    sehr professionell und eher unübersichtlich aus. Ich habe mir ein GUI vergestellt,
    in dem man beide Felder ( Ein- und Ausgabe ) sieht. Also bei Änderung des Wertes
    im Eingabefeld automatisch das Ausgabefeld angepasst wird.

    Bei den ersten Schritten in diese Richtung, fiel mir dann recht schnell eine
    Optimierungsmöglichkeit des Programms ein: Es wäre toll, wenn man in dem
    ursprünglichen Ausgabefeld auch Änderungen machen könnte und dann durch
    eine entsprechende Umkehrrechnung der Wert für das erste ( ursprüngliche
    Eingabe- ) Feld berechnet wird.
    ... also etwa wie bei einem Währungsrechner der entsprechend einem festen
    Faktor in beide Richtungen rechnet ( D-Mark zu Euro ).

    ... seht Ihr dazu eine Möglichkeit?

    Ich habe etwas Code zusammenkopiert und modifiziert, allerdings noch keine
    Rechnung hinterlegt, damit Ihr es Euch optisch vorstellen könnt:

    #include <GUIConstants.au3>

    GUICreate("JamMan Tempo Rechner", 285, 150)
    GUICtrlCreateInput("100", 10, 20, 30, 20)
    GUICtrlCreateLabel("bpm", 45, 24)
    GUICtrlCreateLabel("( 'Beats per minute' von Mono Loops mit 44 kHz, 16 bit )", 10, 50)
    GUICtrlCreateLabel("'Tempo'-Wert", 10, 90)
    GUICtrlCreateInput("Ausgabe", 170, 96, 40, 20)
    GUICtrlCreateLabel("Einheit ?", 230, 100)
    GUICtrlCreateLabel("zum Eintragen in 'Loop.xml':", 10, 110)
    GUISetState(@SW_SHOW)

    While 1
    $msg = GUIGetMsg()

    Select
    Case $msg = $GUI_EVENT_CLOSE
    ExitLoop
    EndSelect
    WEnd

    2 Mal editiert, zuletzt von ArnieK (1. Januar 2010 um 17:39)

    • Offizieller Beitrag

    Wenn du wechselseitig rechnen willst kannst du nicht das Ereignis des Werteintragens in das Input nutzen, da dann die Rechenrichtung nicht klar wird.
    Du benötigst also einen Start-Button der dann die Berechnung für das jeweils leere Feld ausführt.
    Die Logik ist in einem einfachen If-Statement unterzubringen. (Abfragen, welches Feld ist leer - zugehörige Rechenoperation ausführen)

  • Oh, da hast Du mich ja noch übertroffen:
    5 Minuten vor Jahreswechsel antwortend im Forum ... Respekt!

    ... und danke für Deine schnelle Reaktion.

    Gibt es keine Möglichkeit zu überwachen, welches Feld gerade editiert wird,
    unabhängig davon, ob in dem anderen schon etwas steht, und das dann
    automatisch anzupassen?

    Das wäre doch vom Handling optimal.

    2 Mal editiert, zuletzt von ArnieK (1. Januar 2010 um 01:17)

  • Du könntest schauen ob auf einem Control (In deinem Fall eine der beiden Inputboxen) der Focus gesetzt ist.

    Edit: Wäre mit ControlGetFocus() und einer If Abfrage zu lösen

    • Offizieller Beitrag

    Gibt es keine Möglichkeit zu überwachen, welches Feld gerade editiert wird,
    unabhängig davon, ob in dem anderen schon etwas steht, und das dann
    automatisch anzupassen?

    Das wäre doch vom Handling optimal.


    Doch, das geht. Nur bedenke: Auch das Löschen eines Inhaltes ist eine Änderung. Wenn zeitgleich noch ein weiteres Input leer ist, ist keine Rechenoperation möglich.
    Die einzige Variante, die für mich sinnvoll erscheint: Jedem Input ein Radio-Ctrl zuordnen und damit das Rechenziel festlegen. Änderungen in den anderen Inputs bewirken dann nur eine Berechnung in diesem Ziel-Input. Hat irgendein Input noch keinen Wert, so wird auch nicht gerechnet.

  • Mein Ziel ist eigentlich, das ganze so ergonomisch wie möglich zu machen.
    Für mich heißt das: So wenig Knöpfe und Eingaben wie möglich.
    Deshalb habe ich ja auch schon bewusst auf 'Abbrechen' und 'Tschüss'-
    Buttons verzichtet. Entweder habe ich etwas zu berechnen und mache
    eine oder nacheinander mehrere Eingaben, die unmittelbar berechnet werden
    oder ich schließe das Fenster.

    Ich hatte schon vor, vielleicht 100 bpm vorzugeben und damit eine
    erste Beispielberechnung zu starten, um Durchschnittswerte vorzugeben.
    Beide Felder leer sind ein Sonderfall.
    Den muss ich eben programmiertechnisch abfangen.
    Wenn in einem der beiden Felder alles gelöscht oder auf Null gesetzt
    wird, gibt es in dem anderen eben keine Anzeige.
    Wenn dann wieder in das andere Feld gesprungen wird und dort alles
    gelöscht oder eine 0 eingegeben wird, gibt es eben in dem ersteren
    keine Anzeige ... auch wenn vorher dort schon nichts war.

    Das Programm macht ja nur Sinn, wenn es wirklich etwas zu berechnen
    gibt. Also in dem Fall sinnvolle Konfigurationsdaten für den Looper
    entstehen.

    • Offizieller Beitrag

    Bei nur zwei Eingabefeldern kannst du natürlich problemlos hin- und herrechnen, da ist die Richtung klar. Bei 3 Feldern brauchst du eine Zielmarkierung.

    Ich hab mal ein Bsp. für Widerstandsberechnung eingefügt. Dadran kannst du dich orientieren.

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <EditConstants.au3>
    $gui = GUICreate('R = U / I')
    GUICtrlCreateLabel('Berechne', 80, 3, 60, 17)
    GUICtrlCreateLabel('R', 10, 23, 20, 17)
    $inR = GUICtrlCreateInput('', 40, 20, 40, 20)
    $rR = GUICtrlCreateRadio('', 90, 20, 20, 20)
    GUICtrlSetState(-1, $GUI_CHECKED)
    GUICtrlCreateLabel('U', 10, 53, 20, 17)
    $inU = GUICtrlCreateInput('', 40, 50, 40, 20)
    $rU = GUICtrlCreateRadio('', 90, 50, 20, 20)
    GUICtrlCreateLabel('I', 10, 83, 20, 17)
    $inI = GUICtrlCreateInput('', 40, 80, 40, 20)
    $rI = GUICtrlCreateRadio('', 90, 80, 20, 20)
    GUISetState()
    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

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

    While 1
    $msg = GUIGetMsg()
    Switch $msg
    Case -3
    Exit
    EndSwitch
    WEnd

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

    Func _getTarget()
    If BitAND(GUICtrlRead($rR), $GUI_CHECKED) Then
    Return 'R'
    ElseIf BitAND(GUICtrlRead($rU), $GUI_CHECKED) Then
    Return 'U'
    Else
    Return 'I'
    EndIf
    EndFunc

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

    Func _getVal()
    Local $aOut[3] = [GUICtrlRead($inR),GUICtrlRead($inU),GUICtrlRead($inI)]
    Return $aOut
    EndFunc

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

    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $hWndEdit, $aRead
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF)
    $iCode = BitShift($iwParam, 16)
    Switch $iCode
    Case $EN_CHANGE
    Switch $hWndFrom
    Case GUICtrlGetHandle($inR)
    $aRead = _getVal()
    Switch _getTarget()
    Case 'R'
    Return $GUI_RUNDEFMSG
    Case 'U'
    If $aRead[0] = '' Or $aRead[2] = '' Then Return $GUI_RUNDEFMSG
    GUICtrlSetData($inU, $aRead[0]*$aRead[2]) ; U = R*I
    Case 'I'
    If $aRead[0] = '' Or $aRead[1] = '' Then Return $GUI_RUNDEFMSG
    GUICtrlSetData($inI, $aRead[1]/$aRead[0]) ; I = U/R
    EndSwitch
    Case GUICtrlGetHandle($inU)
    $aRead = _getVal()
    Switch _getTarget()
    Case 'R'
    If $aRead[1] = '' Or $aRead[2] = '' Then Return $GUI_RUNDEFMSG
    GUICtrlSetData($inR, $aRead[1]/$aRead[2]) ; R = U/I
    Case 'U'
    Return $GUI_RUNDEFMSG
    Case 'I'
    If $aRead[0] = '' Or $aRead[1] = '' Then Return $GUI_RUNDEFMSG
    GUICtrlSetData($inI, $aRead[1]/$aRead[0]) ; I = U/R
    EndSwitch
    Case GUICtrlGetHandle($inI)
    $aRead = _getVal()
    Switch _getTarget()
    Case 'R'
    If $aRead[1] = '' Or $aRead[2] = '' Then Return $GUI_RUNDEFMSG
    GUICtrlSetData($inR, $aRead[1]/$aRead[2]) ; R = U/I
    Case 'U'
    If $aRead[0] = '' Or $aRead[2] = '' Then Return $GUI_RUNDEFMSG
    GUICtrlSetData($inU, $aRead[0]*$aRead[2]) ; U = R*I
    Case 'I'
    Return $GUI_RUNDEFMSG
    EndSwitch
    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_COMMAND

    [/autoit]

    Hier mal noch das Bsp. für 2 Werte:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <EditConstants.au3>
    $gui = GUICreate('Seitenverhältnis')
    GUICtrlCreateLabel('Breite', 10, 23, 40, 17)
    $inB = GUICtrlCreateInput('', 60, 20, 80, 20, $ES_RIGHT)
    GUICtrlCreateLabel('Höhe', 10, 53, 40, 17)
    $inH = GUICtrlCreateInput('', 60, 50, 80, 20, $ES_RIGHT)
    GUICtrlCreateLabel('Breite : Höhe', 60, 90, 120, 17)
    $label1 = GUICtrlCreateLabel('', 60, 120, 80, 17)
    GUICtrlCreateLabel('Höhe : Breite', 200, 90, 120, 17)
    $label2 = GUICtrlCreateLabel('', 200, 120, 80, 17)
    GUISetState()
    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

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

    While 1
    $msg = GUIGetMsg()
    Switch $msg
    Case -3
    Exit
    EndSwitch
    WEnd

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

    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $hWndEdit
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF)
    $iCode = BitShift($iwParam, 16)
    Switch $iCode
    Case $EN_CHANGE
    Switch $hWndFrom
    Case GUICtrlGetHandle($inB), GUICtrlGetHandle($inH)
    Local $aRead[2], $aCtrl[2] = [$inB,$inH]
    For $i = 0 To 1
    $aRead[$i] = GUICtrlRead($aCtrl[$i])
    If Not StringRegExp($aRead[$i], '\A[\d.]*\z') Then
    GUICtrlSetData($aCtrl[$i], '')
    Return $GUI_RUNDEFMSG
    EndIf
    Next
    If $aRead[0] = '' Or $aRead[1] = '' Then Return $GUI_RUNDEFMSG
    GUICtrlSetData($label1, '1 : ' & StringFormat('%.2f', $aRead[0]/$aRead[1]))
    GUICtrlSetData($label2, '1 : ' & StringFormat('%.2f', $aRead[1]/$aRead[0]))
    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_COMMAND

    [/autoit]
  • Und hier ein Beispiel ohne WM_Command. Wir wollen ja die leute nicht gleich immer überfordern.

    Spoiler anzeigen
    [autoit]

    ;https://autoit.de/index.php?page=Thread&threadID=16733

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

    #include <GUIConstants.au3>
    Global $bpm_alt, $tempo_alt
    GUICreate("JamMan Tempo Rechner", 285, 150)
    $bpm = GUICtrlCreateInput("100", 10, 20, 30, 20)
    GUICtrlCreateLabel("bpm", 45, 24)
    GUICtrlCreateLabel("( 'Beats per minute' von Mono Loops mit 44 kHz, 16 bit )", 10, 50)
    GUICtrlCreateLabel("'Tempo'-Wert", 10, 90)
    $tempo = GUICtrlCreateInput("Ausgabe", 170, 96, 40, 20)
    GUICtrlCreateLabel("Einheit ?", 230, 100)
    GUICtrlCreateLabel("zum Eintragen in 'Loop.xml':", 10, 110)
    GUISetState(@SW_SHOW)

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

    While 1 * Sleep(10)
    $msg = GUIGetMsg()

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

    Select
    Case $msg = $GUI_EVENT_CLOSE
    ExitLoop
    EndSelect
    _Rechne()
    WEnd

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

    Func _Rechne()
    If ControlGetHandle("","",ControlGetFocus("")) = GUICtrlGetHandle($bpm) Then
    IF GUICtrlRead($bpm) <> $bpm_alt AND (GUICtrlRead($bpm) <> "" AND Number(GUICtrlRead($bpm)) <> 0) Then
    GUICtrlSetData($tempo,GUICtrlRead($bpm)*2) ; Hier einmal rechnung anpassen
    $bpm_alt = GUICtrlRead($bpm)
    EndIf
    ElseIf ControlGetHandle("","",ControlGetFocus("")) = GUICtrlGetHandle($tempo) Then
    IF GUICtrlRead($tempo) <> $tempo_alt AND (GUICtrlRead($tempo) <> "" AND Number(GUICtrlRead($tempo)) <> 0) Then
    GUICtrlSetData($bpm,GUICtrlRead($tempo)/2) ; Hier einmal rechnung anpassen
    $tempo_alt = GUICtrlRead($tempo)
    EndIf
    EndIf
    EndFunc

    [/autoit]