HotKeySet - AutoIt soll Taste gedrückt halten

  • Hi,
    ich möchte mit dem HotKey {NUMPAD5}, die Shift-Taste dauerhaft runtergedrückt haben.
    Und beim erneuten betätigen von {NUMPAD5}, soll die Shift-Taste wieder losgelassen werden.

    Mein laienhafter Versuch schaut so aus:

    [autoit]


    HotKeySet("{NUMPAD5}","shift")
    HotKeySet("{NUMPAD8}","ende")

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

    Dim $shiftrunter = False
    Func shift()
    If $shiftrunter = False Then
    $shiftrunter = True
    Send("{SHIFTDOWN}")
    Else
    $shiftrunter = False
    Send("{SHIFTUP}")
    EndIf
    EndFunc

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

    Func ende()
    Exit
    EndFunc

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

    While 1
    Sleep(100)
    WEnd

    [/autoit]

    Aber irgendwie lässt sich {SHIFTDOWN} dann nicht mehr lösen und ist dauerhaft aktiviert ;(

    Ich würde mich riesig freuen, wenn ihr mir helfen könntet.

    Gruß
    Nasenbär

    Einmal editiert, zuletzt von Nasenbär (15. April 2010 um 10:39)

    • Offizieller Beitrag
    [autoit]

    Opt("SendCapslockMode",0)
    HotKeySet("{NUMPAD5}", "shift")
    HotKeySet("{NUMPAD8}", "ende")

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

    Func shift()
    Send("{CAPSLOCK toggle}")
    EndFunc ;==>shift

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

    Func ende()
    Exit
    EndFunc ;==>ende

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

    While 1
    Sleep(100)
    WEnd

    [/autoit]
  • Hehe.. das mit Capslock ist eine lustige Idee.
    Leider unterscheidet die Anwendung zwischen Shift und Capslock.

    Aber vielen Dank, dass du den Code so ordentlich gestalltet hast!

    • Offizieller Beitrag

    Du mußt das KeyEvent direkt auslösen.
    Das Aufrufen dieser Funktion klappt aber nicht in jedem Fall über HotKeys. Wenn SHIFTDOWN aktiv ist, wird der HotKey zum Aufheben nicht mehr registriert. Deshalb muß auch die HotKey-Abfrage innerhalb der Hook-Prozedur erfolgen.:

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <WindowsConstants.au3>

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

    OnAutoItExitRegister('_OnExit')
    HotKeySet('#!e', '_Exit') ; Win+Alt+e zum Programm beenden
    Opt('MustDeclareVars', 1)
    Global $hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
    Global $hmod = _WinAPI_GetModuleHandle(0)
    Global $hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hStub_KeyProc), $hmod)
    Global $isShift = False

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

    While 1
    Sleep(100)
    WEnd

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

    Func _Exit()
    Exit
    EndFunc

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

    Func _OnExit()
    If $isShift Then _keybd_event(0x10, 0x2) ; beim Programmende auf jeden Fall Shift zurücksetzen
    _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hStub_KeyProc)
    Exit
    EndFunc

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

    Func _KeyProc($nCode, $wParam, $lParam)
    Local $tKEYHOOKS, $vkCode
    $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    $vkCode = DllStructGetData($tKEYHOOKS, "vkCode")
    If $wParam = $WM_KEYDOWN Then
    Switch $vkCode
    Case 101 ; NUMPAD 5
    If $isShift Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    _keybd_event(0x10)
    $isShift = True
    Return -1
    Case 104 ; NUMPAD 8
    If Not $isShift Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    _keybd_event(0x10, 0x2)
    $isShift = False
    Return -1
    EndSwitch
    EndIf
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    EndFunc

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

    Func _keybd_event($vkCode, $Flag=0)
    DllCall('user32.dll', 'int', 'keybd_event', 'int', $vkCode, 'int', 0, 'int', $Flag, 'ptr', 0)
    EndFunc

    [/autoit]
  • Wow :thumbup:
    Ich hätte nie gedacht, dass es wegen einer Taste so kompliziert werden kann.

    Dankeschön für die tolle Hilfe.