Kommunikation mit AutoIt

  • Hallo,
    bin neu hier und würde meine AutoIt Kenntnisse als "ambitionierter Laie" einstufen. Da ich mich zur Zeit auch mit EventGhost befasse, suchete ich nach einer Möglichkeit die beiden miteinander "reden" zu lassen. Ziel: ich will FS 20 Komponenten steuern ( über FHZ Plugin von EventGhost), aber mit AutoIt meine eigene GUI bauen. Nach diversen Ansätzen bin ich bei folgendem Konzept gelandet: Sowohl AutoIt als auch EventGhost können über serielle Schnittstelle Daten übertragen. Die Verbindung zwischen beiden wird über com0com hergestellt.

    Als erstes com0com herunterladen und installieren. Das Programm erstellt ein Virtual Port Pair 0. Dieses habe ich auf COM5: und COM6: eingestellt.

    Zum Test dient dieses script:

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include 'CommMG.au3';or if you save the commMg.dll in the @scripdir use #include @SciptDir & '\commmg.dll'
    #include <GuiEdit.au3>
    #include <GuiComboBox.au3>
    #include <GUIConstants.au3>
    local $sportSetError

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

    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("Event Ghost Test", 376, 267, 233, 229)
    $ButtonEIN = GUICtrlCreateButton("EIN", 40, 32, 137, 57)
    $ButtonAUS = GUICtrlCreateButton("AUS", 200, 32, 137, 57)
    $InputSENDETEXT = GUICtrlCreateInput("SENDETEXT", 40, 112, 137, 21)
    $InputEMPFANGSTEXT = GUICtrlCreateInput("", 40, 168, 297, 21)
    $ButtonSENDEN = GUICtrlCreateButton("Senden", 200, 112, 137, 25)
    Dim $FlowType[3] = ["XOnXoff", "Hardware (RTS, CTS)", "NONE"]
    _CommSetPort(5, $sportSetError, 19200, 8, 0, 1, 2)
    GUISetState(@SW_SHOW)
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $ButtonEIN
    _CommSendstring("EIN" & @CR)
    Case $ButtonAUS
    _CommSendstring("AUS" & @CR)
    Case $ButtonSENDEN
    _CommSendstring(GUICtrlRead ($InputSENDETEXT) & @CR)
    EndSwitch
    $instr = _CommGetString()
    If $instr <> '' Then
    GUICtrlSetData($InputEMPFANGSTEXT,$instr)
    EndIf
    WEnd
    _Commcloseport()
    GUIDelete()

    [/autoit]


    Im EventGhost brauchts als Gegenstück dann das Plugin "Serieller Anschluss". Einstellungen:

    Spoiler anzeigen


    • Anschluss: COM6
    • Bits pro Sekunde: 19200
    • Datenbits: 8
    • Parität: Keine
    • Stopbits: 1
    • Flusssteuerung: Keine
    • Generiere Ereignisse bei eintreffenden Daten: Haken gesetzt
    • Endzeichen: \r
    • Ereignis-Prefix: Serieal
    • Zeichenkodierung: System code page


    Für die, die das gleiche Problem haben als Anregung.
    Für die, die sich mit AutoIt besser auskennen: Gerne Kritik und Verbesserungsvorschläge, denn ich hab hier nur im Internet gewildert und obiges zusammengeflickt.

    Gruss Dieter

  • Ich hatte da auch mal was über WM_Command erstellt (als .py in einem neuen Ordner im Pluginverzeichnis von Eventghost abspeichern)

    Spoiler anzeigen

    Lässt sich im autoit Skript dann über GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") auswerten.

  • danke für die Antworten - ich versuch das jetzt über WM_COMMAND nachzubauen bekomms aber nicht hin:
    Wenn ich im EventGhost das Plugin hinzufüge und einen Befehl absetzen will, bekomme ich als Antwort: "Programm ist nicht gestartet"

    Das AutoIt Gegnstück schaut so aus:

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GuiEdit.au3>
    #include <GuiComboBox.au3>
    #include <GUIConstants.au3>
    #include <WinAPI.au3>

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

    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("AutoIt v3 GUI", 376, 267, 233, 229)
    $ButtonEIN = GUICtrlCreateButton("EIN", 40, 32, 137, 57)
    $ButtonAUS = GUICtrlCreateButton("AUS", 200, 32, 137, 57)
    $InputSENDETEXT = GUICtrlCreateInput("SENDETEXT", 40, 112, 137, 21)
    $InputEMPFANGSTEXT = GUICtrlCreateInput("", 40, 168, 297, 21)
    $ButtonSENDEN = GUICtrlCreateButton("Senden", 200, 112, 137, 25)

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

    GUIRegisterMsg($WM_COMMAND, "EG_Command")

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

    GUISetState(@SW_SHOW)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $ButtonEIN
    Case $ButtonAUS
    Case $ButtonSENDEN
    EndSwitch
    WEnd

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

    Func EG_Command($hWnd, $Msg, $wParam, $lParam)
    GUICtrlSetData($InputEMPFANGSTEXT,$MSg)
    EndFunc ;==>MY_WM_COMMAND

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

    GUIDelete()

    [/autoit]


    hmmmm .....

  • Ah ok dann wird das Fenster nicht gefunden und du landest in dieser Zeile:

    Code
    raise self.Exceptions.ProgramNotRunning
    Spoiler anzeigen
    [autoit]


    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    Opt("GUIOnEventMode", 1)

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

    Global $eventCount = 0
    $Form1 = GUICreate("wm_command_autoit", 633, 454, 193, 115)
    GUICtrlCreateButton("Test", 10, 10)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_ende')
    GUISetState(@SW_SHOW)
    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

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

    While 1
    Sleep(100)
    WEnd

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

    Func _ende()
    Exit
    EndFunc ;==>_ende

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

    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $hWndEdit
    $iIDFrom = BitAND($iwParam, 0xFFFF) ; Low Word
    $iCode = BitShift($iwParam, 16) ; Hi Word
    ConsoleWrite( @MSEC&" $ilParam :"&$ilParam & @CRLF)
    ConsoleWrite( @MSEC&" $iIDFrom :"&$iIDFrom& @CRLF)
    ConsoleWrite( @MSEC&" $iCode :"&$iCode& @CRLF)

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

    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_COMMAND

    [/autoit]

    Funktioniert mit diesem EG-Plugin

    Spoiler anzeigen
    [autoit]


    eg.RegisterPlugin(
    name = "wm_command_autoit",
    author = "Nuts",
    version = "1.0.",
    kind = "program",
    createMacrosOnAdd = True,
    )

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

    # die actions je nach Bedarf definieren. ich hatte da mit verschiedenen Werten experimentiert
    ACTIONS = (
    (eg.ActionGroup, 'GroupMainControls', 'Main controls', None, (
    ('Exit', 'Quit Application', None, 1000),
    ('PlayPause', 'Play/Pause', None, 1001),
    ('Play', 'Play', None, 1002),
    ('Next', 'Next', None, 1003),
    ('Prev', 'Prev', None, 1004),
    ('Stop', 'Stop', None, 1005),
    ('Visualisierung', 'Visualisierung', None, 1006),
    ('Repeate', 'Repeate', None, 1007),
    ('Shuffle', 'Shuffle', None, 1008),
    ('Vol+', 'Vol+', None, 1009),
    ('Vol-', 'Vol-', None, 1010),
    ('Mute', 'Mute', None, 1011),
    ('Up', 'Up', None, 1012),
    ('Down', 'Down', None, 1013),
    ('Right', 'Right', None, 1014),
    ('Left', 'Left', None, 1015),
    ('Enter', 'Enter', None, 1016),
    )),
    )

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

    from eg.WinApi import FindWindow, SendMessageTimeout, WM_COMMAND

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

    class ActionPrototype(eg.ActionClass):
    # findwindow muss man ans autoit Skript anpassen
    def __call__(self):
    try:
    hWnd = FindWindow("AutoIt v3 GUI", "wm_command_autoit")
    return SendMessageTimeout(hWnd, WM_COMMAND, self.value, 0)
    except:
    raise self.Exceptions.ProgramNotRunning

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

    class Nuts(eg.PluginClass):

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

    def __init__(self):
    self.AddActionsFromList(ACTIONS, ActionPrototype)

    [/autoit]

    Bin mir nur nicht so sicher ob das eine ganz saubere Lösung ist.
    Irgendwie klappt es nicht der Nachricht mitzugeben vom wem die Nachricht kommt.
    Allerdings verzichten darauf auch andere Plugins, die mit Sendmessage arbeiten (s. Mediaplayerclassic Plugin).

    Vielleicht kann Progandy dazu noch was sagen?

  • jooh danke das funktioniert jetzt. Da ich mich mit Programmierung unter Windows nicht so gut auskenne (ich hab unter CP/M angefangen kleine Programme zu schreiben) kommen gleich neue Fragen auf:

    Es scheint sich hier um einen Prozess zu handeln, mit dem Windows Fenster unterinender vordefinierte Codes / Befehle austauschen.
    Könnt ihr mir eine (möglichst deutschsprachige Seite) empfehlen, wo das für Anfänger erklärt wird.

    Vorteil so weit ich das bis jetzt sehe: Mehr oder weniger alle Windows Programme könnten so angesprochen werden.
    Nachteil: es gibt nur die vordefinierten Codes, man kann keine Strings übertragen.

    Gruss Dieter

  • Strings kann man mit WM_COPYDATA übertragen. Such auch mal nach MessageReceiver bei Eventghost. Da müsste es irgend was geben, um damit auch Nachrichten von AutoIt empfangen zu können. Mehr kann ich jetzt leider ohne EG nicht helfen.