Suche Send-Funktion um Prozesse im Hintergrund zu steuern.

  • Hallo Community^^

    ich bin seit ein paar Monaten Gelegenheits-AutoIT-Bastler, bis jetzt hat es immer gereicht ein paar Funktionen zusammen zu googlen & ein wenig zu verändern.. allerdings bin ich jetzt an einem Punkt, wo ich bis jetzt seit 2 Wochen in keinem Forum oder bei Google eine Lösung finden konnte..

    Also das Problem selbst wird bekannt sein, ich möchte einen Prozess im Hintergrund mit einfachen Tasten wie Buchtaben, Zahlen, etc steuern & zwar so, dass ich nebenbei noch Surfen, Spielen oder ähnliches kann.

    Oft habe ich davon gelesen, einfach die Funktion "ControlSend" zu benutzen, damit war es bei den meisten dann auch schon getan. Allerdings ist es bei mir so, dass sich das Fenster trotzdem weiterhin maximiert (habs auch mit SW_HIDE versucht, dabei werden aber alle anderen aktiven Fenster "unaktiv", so dass ich sie zum weiterbenutzen erst einmal anklicken muss.)

    Also mein Code sieht bis jetzt wiefolgt aus:

    Code
    While 1
    	sleep (2000)
    	ControlSend("Testfenster", "", "", "1")
    Wend

    Hier ist halt mein Problem, dass sich der Prozess "Testfenster" immer wieder öffnet, bei Minimierung nicht reagiert und beim verstecken andere Programme bis zum nächsten Anklicken "unbrauchbar" macht.

    Hoffentlich fällt euch eine Lösung ein^^

  • Moin,

    meinst Du soetwas in dieser Richtung?

    Spoiler anzeigen
    [autoit]

    #cs ----------------------------------------------------------------------------

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

    AutoIt Version: 3.3.0.0
    Author: Jens Kröger (McPoldy)

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

    Script Function:
    Beispielskript, wie man auch Fenster steuern kann, die auf @SW_HIDE
    gesetzt wurden.

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

    F1 = Fenster verstecken
    F2 = Fenster anzeigen
    F3 = Etwas anderes schreiben
    F4 = Skript beenden und aufräumen

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

    Was mache ich hier?
    ===================
    Ich prüfe ob eine Datei mit dem Namen versteck.txt in meinem Skript Verzeichnis
    vorhanden ist, falls nein, erstelle ich sie. Dann rufe ich Notepad mit dieser
    Datei auf. Wenn das Fenster vom Notepad da ist, hole ich mir den Titel des Fensters
    und Verstecke es dann. Wenn der Titel bereits bekannt ist, kann man sich das
    sparen und ihn direkt in der Variablen $titel speichern und das betreffende
    Programm auch gleich mit @SW_HIDE starten.
    Dann lasse ich eine Schleife laufen, welche im Sekundentakt immer die Uhrzeit
    in das Notepad-Fenster mittels ControlSend schreibt. Nun kann man mit den
    oben stehenden Tastenkombis Aktionen ausführen: verstecken, anzeigen, was
    anderes schreiben oder das Programm beenden.
    Wenn das Programm beendet wird, wird auch die Datei versteck.txt wieder gelöscht,
    damit alles schön sauber ist.

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

    Wozu ist das nun gut?
    =====================
    So, oder so ähnlich, könnte man das mit anderen Programmen auch machen, sie sind
    zwar nicht sichtbar, können aber trozdem gesteuert werden.

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

    #ce ----------------------------------------------------------------------------

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

    ; Umschalt und F-Tasten
    HotKeySet('+{F1}','hWin')
    HotKeySet('+{F2}','sWin')
    HotKeySet('+{F3}','schreibwas')
    HotKeySet('+{F4}','ProgEnde')

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

    #Region Wenn man den Fenstertitel auslesen will
    ;#cs
    ; Prüfe ob Datei vorhanden ist, sonst erstelle sie
    checkFile()
    ; Starte Notepad
    Local $pid = run("notepad.exe versteck.txt",@ScriptDir,@SW_SHOWMAXIMIZED)
    ; Warten bis Programm gestartet ist
    Sleep(1000)
    ; Den Fenstertitel in $titel speichern
    local $titel = WinGetTitle("[active]")
    ; Fenster ausblenden
    hWin()
    ;#ce
    #EndRegion <== Wenn man den Fenstertitel auslesen will

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

    #Region Wenn der Fenstertitel direkt in einer Variablen gespeichert wird
    #cs
    ; Prüfe ob Datei vorhanden ist, sonst erstelle sie
    checkFile()
    ; Starte Notepad
    Local $pid = run("notepad.exe versteck.txt",@ScriptDir,@SW_HIDE)
    ; Den Fenstertitel in $titel speichern
    local $titel = 'versteck.txt - Editor'
    #ce
    #EndRegion <== Wenn der Fenstertitel direkt in einer Variablen gespeichert wird

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

    ; Schleife, die jede Sekunde die Zeit schreibt
    While True
    $zeit = StringFormat('%s:%s:%s',@HOUR,@MIN,@SEC) & @CR
    ControlSend($titel,'','[CLASS:Edit; INSTANCE:1]',$zeit)
    Sleep(1000)
    WEnd

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

    ; Fenster verstecken = Umschalttaste und F1
    Func hWin()
    WinSetState($titel,'',@SW_HIDE)
    EndFunc

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

    ; Fenster anzeigen = Umschalttaste und F2
    Func sWin()
    WinSetState($titel,'',@SW_SHOW)
    EndFunc

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

    ; Etwas anderes schreiben = Umschalttaste und F3
    Func schreibwas()
    ControlSend($titel,'','[CLASS:Edit; INSTANCE:1]','Mal etwas anderes....' & @CR)
    EndFunc

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

    ; Prozess beenden, die Datei löschen und das Skript beenden = Umschalttaste und F4
    Func ProgEnde()
    ProcessClose($pid)
    FileDelete('versteck.txt')
    Exit
    EndFunc

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

    ; Funktion zum prüfen ob die Datei vorhanden ist, ggf. erzeugen der Datei.
    Func checkFile()
    If Not FileExists('versteck.txt') Then
    $f = FileOpen('versteck.txt',10)
    FileClose($f)
    EndIf
    EndFunc

    [/autoit]

    Mfg
    Jens (McPoldy)

    Twitter: jkroeger

    Denn die Dinge, die wir erst lernen müssen, bevor wir sie tun, lernen wir beim Tun.(Aristoteles)

  • Also das Grundprinzip ist so, wie ich es haben will, es wird ein verstecktes Fenster kontrolliert. Mit ControlSend hab ich auch schon gearbeitet, allerdings hatte ich dabei immer das Problem, dass sich das Fenster maximiert wenns minimiert ist, oder sich aktiviert, wenns Versteckt ist. Und wenn sich das kontrollierte Fenster dann aktiviert, wird das Fenster in dem ich gerade arbeiten will (nehmen wir mal an es sei ICQ), grau hinterlegt, dass ich es erst anklicken muss, um darin weiter zu arbeiten.. und das sollte nicht passieren.


    Falls du das Problem in deinem Skript schon behoben haben solltest, müsste ich meinen Skript nurnoch anpassen^^

  • mach halt so was, vielleicht reicht das ja ;)

    [autoit]

    $handle = WinGetHandle("") ; aktives Fenster holen
    Control...
    WinActivate($handle)

    [/autoit]
  • Wenn ich das jetzt recht verstanden habe, soll ich mein ICQ-Fenster per Script wieder aktivieren.. glaube das wäre aber ein wenig umständlich, vorallem wenn ich nicht nur in ICQ, sondern auch mal in Firefox oder ähnliches bin^^

  • Mach vor dem Controlsend ein WinGetHandle(""), dann bekommst du das gerade aktive Fenster, egal von welchem Programm. Dann führst du deine Befehle aus und am Ende reicht ein WinActvate, um das zuvor gespeicherte Fenster wieder zu aktivieren.

  • Also mit dem WinGetHandle(""), wechselt er schon seltener zurück ins Fenster, aber es geschieht trotzdem.. und wenn ich WinActivate dazu setze, hab ich Probleme beim Fensterwechsel in Windows, da er manchmal einfach in das vorherige zurück springt.

  • Vielleicht ist es das was du suchst.

    Spoiler anzeigen
    [autoit]


    ; #FUNCTION# ====================================================================================================================
    ; Name...........: SimulKey
    ; Description ...: Simulate a Key-Send to a specified handle in the Background
    ; Author ........: Felix Lehmann (eF_Hacks)
    ; Modified.......: If you modify this Script, please enter your name here
    ; Remarks .......: http://www.elitepvpers.de
    ; Related .......: -
    ; Parameters ....: $hwnd = Specified Window to Send to
    ; ...............: $key = Key or String to Send (If String $string have to be enabled [see $string])
    ; ...............: $string = Set this to 1 If your "$key" is a string
    ; ...............: $state = Set this to 'up' or 'down' if u want a special event | Default is press the Key 1 Time
    ; ...............: $delay = The delay to hold the key down
    ; Return Values .: 1 = Done | -1 = Couldn't load user32.dll
    ; Link ..........; -
    ; ===============================================================================================================================
    Func SimulKey($hWnd, $key, $string = 0, $state = 'skip', $delay = 10)
    ;//Open DLL (user32)
    $user32 = DllOpen('user32.dll')
    If $user32 = -1 Then
    SetError(-1, 1, -1)
    EndIf

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

    ;//Handle Special Keys
    Switch StringLower($key)
    Case 'enter'
    $WM_ENTER = 0x0d
    $dCall = DllCall($user32, 'int', "MapVirtualKey", 'int', $WM_ENTER, 'int', 0)
    $lParam = BitOR(BitShift($dCall[0], -16), 1)
    Case 'space'
    $WM_SPACE = 0x20
    $dCall = DllCall($user32, 'int', "MapVirtualKey", 'int', $WM_SPACE, 'int', 0)
    $lParam = BitOR(BitShift($dCall[0], -16), 1)
    Case 'tab'
    $WM_TAB = 0x09
    $dCall = DllCall($user32, 'int', "MapVirtualKey", 'int', $WM_TAB, 'int', 0)
    $lParam = BitOR(BitShift($dCall[0], -16), 1)
    ;//Handle Standard Keys
    Case Else
    ;//Stringmode 1
    If $string = 1 Then
    $split = StringSplit($key, "")
    For $ctn = 1 To $split[0]
    $split[$ctn] = Asc(StringLower($split[$ctn]))
    Next
    For $ctn = 1 To $split[0]
    $dCall = DllCall($user32, 'int', "VkKeyScan", 'int', $split[$ctn])
    $lParamAsc = DllCall($user32, 'int', "MapVirtualKey", 'int', $dCall[0], 'int', 0)
    $lParam = BitOR(BitShift($lParamAsc[0], -16), 1)
    $lUpParam = BitOR($lParam, 0xC0000000)
    DllCall($user32, 'int', "PostMessage", 'hwnd', $hWnd, 'int', $WM_KEYDOWN, 'int', $dCall[0], 'int', $lParam)
    Sleep($delay)
    DllCall($user32, 'int', "PostMessage", 'hwnd', $hWnd, 'int', $WM_KEYUP, 'int', $dCall[0], 'int', $lUpParam)
    Sleep(100)
    Next
    ;//Stringmode 0
    ElseIf $string = 0 Then
    $key = Asc(StringLower($key))
    $dCall = DllCall($user32, 'int', "VkKeyScan", 'int', $key)
    $lParamAsc = DllCall($user32, 'int', "MapVirtualKey", 'int', $dCall[0], 'int', 0)
    $lParam = BitOR(BitShift($lParamAsc[0], -16), 1)
    EndIf
    EndSwitch
    $lUpParam = BitOR($lParam, 0xC0000000)
    If $string = 0 Then
    Switch StringLower($state)
    Case 'skip'
    DllCall($user32, 'int', "PostMessage", 'hwnd', $hWnd, 'int', $WM_KEYDOWN, 'int', $dCall[0], 'int', $lParam)
    Sleep($delay)
    DllCall($user32, 'int', "PostMessage", 'hwnd', $hWnd, 'int', $WM_KEYUP, 'int', $dCall[0], 'int', $lUpParam)
    Case 'down'
    DllCall($user32, "int", "PostMessage", "hwnd", $hWnd, "int", $WM_KEYDOWN, "int", $dCall[0], "int", $lParam)
    Case 'up'
    DllCall($user32, "int", "PostMessage", "hwnd", $hWnd, "int", $WM_KEYUP, "int", $dCall[0], "int", $lParam)
    EndSwitch
    EndIf
    DllClose($user32)
    Return 1
    EndFunc ;==>SimulKey

    [/autoit]