DllCallbackRegister: Skript stürzt ab?

  • Guten Abend,

    ich bin (wie in meinem anderen Thread schon erwähnt) dabei ein kleines Applet für den Bildschirm meiner Tastatur zu schreiben. Dazu habe ich mir der Einfachheit halber "AdvanceLCD" [KLICK MICH] runtergeladen und mir mal die Dokumentation sowie ein paar C-Beispiele angeschaut. Alles funktioniert prächtig bis auf die Funktion "LcdSetEventHandler". Die brauche ich, damit mein Script eine Funktion ausführt, wenn eine Taste gedrückt wurde.

    So sieht die Funktion zur Zeit aus:

    [autoit]

    ; $hApplet: Handle des Applets
    ; $EventHandler: Name der Funktion, die ausgeführt werden soll
    ; $hContext: Keine Ahnung, im C-Beispiel aber auch 0
    Func LcdSetEventHandler($hApplet, $EventHandler, $hContext = 0)
    $callback = DllCallbackRegister($EventHandler, "int", "int;ptr;int")
    $ret = DllCall($dll, "int", "LcdSetEventHandler", "ptr", $hApplet, "ptr", DllCallbackGetPtr($callback), "ptr", $hContext)
    DllCallbackFree($callback)
    Return $ret[0]
    EndFunc ;==>LcdSetEventHandler

    [/autoit]

    Der Aufruf sieht so aus:

    [autoit]

    LcdSetEventHandler($hApplet, "Callback", 0)

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

    Func Callback($iEvent, $hContext, $iData)
    MsgBox(0, "Hurra", "Es funktioniert :)")
    Return 1
    EndFunc ;==>Callback

    [/autoit]

    Sobald ich auf meiner Tastatur das Applet aufrufe stürzt das Skript einfach ab. Ohne Fehlermeldung, einfach nur "AutoIt funktioniert nicht mehr und muss beendet werden bla bla bla.".
    Ich bastel an dieser Stelle nun schon ne halbe Ewigkeit, bekomme es aber einfach nicht hin :(

    Ich hoffe ihr könnt mir hier weiterhelfen.

    Vielen Dank im Vorraus,
    Carsten

    PS: Solltet ihr noch was brauchen, Teile des Codes oder sonst was, sagt bitte bescheid.

  • ich bin (wie in meinem anderen Thread schon erwähnt) dabei ein kleines Applet für den Bildschirm meiner Tastatur zu schreiben


    dieser Thread wurde von Oscar geclosed:

    Zitat

    Wenn ein AutoIt-Skript alle Tastatureingaben abfangen kann, bevor ein anderes Programm diese bekommt oder eben auch nicht, dann fehlt nur ein ganz kleiner Schritt zu einem Keylogger.
    Und genau das wollen wir hier nicht supporten. Sorry!

    Edit: Damit verschaffst Du Dir auch schon wieder einen Vorteil (= Bot). Ich denke es ist Zeit: [Thread closed]


    und dieser sollte aus dem gleichen Grund auch geclosed werden und da du wiederholt gegen die Forenregeln verstösst eine Verwarnung erhalten,

    mfg (Auto)Bert

  • Oh man was bitte ist hier denn schon wieder ein Verstoß? Es gibt mir weder einen unfairen Vorteil (da es schon etwas ähnliches von offizieller Seite gibt, das genau das selbe macht) noch ist das ein Keylogger. Wie bitte soll der LCD meiner Tastatur als Keylogger fungieren? Ich bitte dich.. man kann es auch übertreiben.

    Einmal editiert, zuletzt von Carsten8 (24. Juli 2010 um 21:12)

  • autoBert: Dieser Thread verstößt nicht gegen die Forenregeln.
    Carsten8: Du darfst das Callback nicht wieder freigeben

    [autoit]

    ; $hApplet: Handle des Applets
    ; $EventHandler: Name der Funktion, die ausgeführt werden soll
    ; $hContext: Benutzerdefinierter Parameter, kann so belegt werden, wie du willst. Z.B. zur Unterscheidung, wenn die Funktion für mehrere unterschiedliche Applets / Callbacks verwendet wird
    Func LcdSetEventHandler($hApplet, $EventHandler, $hContext = 0)
    ; Authors: Carsten8, ProgAndy
    Local Static $hEventHandler = 0
    If $hEventHandler Then DllCallbackFree($hEventHandler)
    $hEventHandler = DllCallbackRegister($EventHandler, "int", "int;ptr;int")
    Local $ret = DllCall($dll, "int", "LcdSetEventHandler", "ptr", $hApplet, "ptr", DllCallbackGetPtr($callback), "ptr", $hContext)
    If @error Then Return SetError(1, @errror, 0)
    Return $ret[0]
    EndFunc ;==>LcdSetEventHandler

    [/autoit]
  • Hurra, funktioniert, vielen Dank progandy ! :thumbup:

    Dachte das passt so, da es in der Hilfe auch so stand:

    [autoit]

    $handle = DLLCallbackRegister ("_EnumWindowsProc", "int", "hwnd;lparam")
    DllCall("user32.dll", "int", "EnumWindows", "ptr", DllCallbackGetPtr($handle), "lparam", 10)
    DllCallbackFree($handle)

    [/autoit]
  • Ja, hier wird das Callback auch nach der EnumWindows-Funktion nicht mehr benötigt. Aber du brauchst es auch später noch.

    Och man, ich wünsch mir auch eine G19 :( Warum muss die nur so teuer sein.

  • Gibt's auf Amazon zur zeit für ca. 110€, schonmal billiger, als zu dem Zeitpunkt, als ich die gekauft hab -.-

    Jetzt hat sich aber eben noch ein Problem aufgetan.

    Folgender Code:

    [autoit]

    Func LcdWaitActivation($hApplet)
    $ret = DllCall($dll, "int", "LcdWaitActivation", "ptr", $hApplet)
    Return $ret[0]
    EndFunc ;==>LcdWaitActivation

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

    Func LcdUpdate($hApplet, $bSync = 0)
    $ret = DllCall($dll, "int", "LcdUpdate", "ptr", $hApplet, "int", $bSync)
    Return $ret[0]
    EndFunc ;==>LcdUpdate

    [/autoit]

    Manchmal (und auch nur manchmal) sagt mir AutoIt, dass $ret bei den beiden Funktionen (evtl. auch bei anderen) kein Array wäre. Wenn ich @error und $ret in einer MsgBox ausgeben lasse, ist beides 0.
    Wieso denn das? :(

    Achja, noch eine Frage nebenbei, wenn ich LcdWaitActivation aufrufe, wartet das Skript dann auch wirklich?

  • Ich weiß nicht, warum beides 0 ist. Vielleicht funkt ein Callback dazwischen, weil du die Variable nicht als Local deklariert hast. Eine DLLCall-Funktion sollte immer so aussehen:

    [autoit]

    Func _XYZ(...)
    Local $ret = DllCall($dll, ...)
    If @error Then Return SetError(1, @error, 0)
    Return $ret[0]
    EndFunc ;==>LcdUpdate

    [/autoit]

    Wenn LcdWaitActivation wartet, wartet auch dein Skript.

  • Habs geändert, scheint zu funktionieren. Jetzt stürzt aber manchmal das ganze Script ab, jedes Mal kurz nachdem mehrere Male "Callback" aufgerufen wird. Wieder mit der Meldung "AutoIt hat ein Problem festgestellt bla..."

    Gerade hatte ich auch

    Code
    C:\Program Files (x86)\AutoIt3\Include\G19.au3 (118) : ==> Variable used without being declared.:
    Return $ret[0]
    Return ^ ERROR

    Was ich gar nicht verstehe, da 118 in der Funktion steckt:

    [autoit]

    Func LcdUpdate($hApplet, $bSync = 0)
    Local $ret = DllCall($dll, "int", "LcdUpdate", "ptr", $hApplet, "int", $bSync)
    If @error Then Return SetError(1, @error, 0)
    Return $ret[0]
    EndFunc ;==>LcdUpdate

    [/autoit]

    Edit: Wenn du Teamviewer hast, kann ich dir das ganze auch gerne mal vorführen.

    Edit 2: Scheint nur aufzutreten, wenn ich die Knöpfe häufig hintereinander drücke. Ohne die MsgBox Anzeige im Callback funktionierts aber auch so :)

    Edit 3: Ok, doch nicht. Verabschiedet sich immernoch ab und zu. Teils geht's sogar einfach zu, ohne irgendwelche Meldungen. Das mit dem "$ret ist nicht definiert" tritt jetzt häufig in der Func LcdUpdate auf.. ich bin am Verzweifeln :S

    Edit 4: Oh mann, ein wenig weiter getestet und jetzt kackt das Skript bei jeden Druck auf die "OK"-Taste ab (mit der Windows Fehlermeldung). Ich geh erstmal schlafen, mal sehn, was sich morgen ergibt. Wie gesagt, wenn du mir per Teamviewer mal über die Schultern schauen könntest, wäre das klasse. Gute Nacht erstmal!

    3 Mal editiert, zuletzt von Carsten8 (24. Juli 2010 um 22:56)

    • Offizieller Beitrag

    Hab ich das jetzt richtig verstanden, du hast in der CallBack Funktion eine Messagebox?
    Wenn ja dann kill die mal ganz schnell. Zum Überprüfen kannst du auch ConsoleWrite benutzen.

  • Die MsgBox hab ich schon wieder rausgenommen, jetzt tritt der Fehler seltener auf. In der Callback Funktion ist jetzt nurnoch eine einfache If und eine Switch Abfrage, die je nach Tastendruck eine Variable verändert und ein paar Hotkeys registriert bzw. unregistriert. Ich habe im Script dann noch ne While 1 Schleife laufen die eine Grafik erstellt und anzeigt. Ich werde das ganze Script nachher mal posten, muss nur etwas aufräumen, ist etwas unordentlich :)

    Edit: Ok, gerade nochmal getestet, folgender Fehler kam:

    Code
    ==> Variable used without being declared.:
    Return 1
    Return ^ ERROR


    Seit wann gibt's denn sowas ?(

    Edit 2: Ok, danke BugFix, scheint zu funktionieren. Einige Variablen waren scheinbar nicht Global.
    Ich habe hier mal ein Video aufgenommen, das veranschaulicht, was genau passiert. In der "Konsole" unten wird immer dann "Okay" ausgegeben, wenn ich Okay drücke.
    http://www.youtube.com/watch?v=Iv1jfjWv6dA

    2 Mal editiert, zuletzt von Carsten8 (25. Juli 2010 um 10:36)

  • Setz mal Tracelines (Scite/Extras/Add tracelines) und schau mal nach, welche wirklich die letzte Zeile vor dem "Abflug" ist.

  • Ja, es ist liegt scheinbar wirklich am Callback. Ich habe das ganze jetzt so umgeschrieben, dass in der Endlosschleife des Scripts geprüft wird, ob eine Taste gedrückt wird, also nicht mehr mit einem Callback und alles funktioniert wunderbar. Wenn ich die UDF fertig habe, werde ich die hier mal hochladen.

    Danke an alle, die mir geholfen haben :)

    Wenn euch noch Ideen kommen, könnt ihr die natürlich gerne posten.

  • Bin schon sehr an der UDF interessiert. Kannst schon etwas sagen wann man mit der ersten Version rechnen kann?

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.