KeyHolder

Post gaming related scripts
User avatar
Holle
Posts: 187
Joined: 01 Oct 2013, 23:19

KeyHolder

09 Dec 2013, 08:04

This Script can hold or repeat a Key.

It´s very easy to use.

Press "F9 + Key" to hold down "Key" (incl. auto-repeat)
Press "F10 + Key" to press "Key" every 30 ms (key is repeating down and "up")
Press "Key" or F9 or F10 again to stop holding down oder repeating.

If you change "Sleep 30" to "Sleep 5000", the key will pressed every 5 seconds. On this way you can refresh you Browser (F10 + F5) every 5 seconds.
...and much more...

Here is the script:

Code: Select all

*F9:: ; keep pressed
*F10:: ; repeat pressing
    if Timer_pressed
        return
    StringTrimLeft, Mode, A_ThisHotkey, 1  
    if GetKeyState(Mode , "P")
    {
        SetTimer, Pressed, 50
        Timer_pressed := true      
        gosub Pressed
    }
return

Pressed:
   if !GetKeyState(Mode , "P")
    {
        SetTimer, Pressed, off
        Timer_pressed := false
        return
    }
    keys = LButton|RButton|MButton|XButton1|XButton2|WheelUp|WheelDown|WheelLeft|WheelRight|Up|Down|Left|Right|Space|Enter|Escape|BackSpace|F1|F2|F3|F4|F5|F6|F7|F8|F11|F12|Tab|LShift|RShift|LControl|RControl|LAlt|RAlt|LWin|RWin|CapsLock|NumLock|ScrollLock|Home|End|Del|Ins|PgUp|PgDn|Numpad1|Numpad2|Numpad3|Numpad4|Numpad5|Numpad6|Numpad7|Numpad8|Numpad9|Numpad0|NumpadDot|NumpadDiv|NumpadMult|NumpadAdd|NumpadSub|NumpadEnter|NumpadIns|NumpadUp|NumpadDown|NumpadLeft|NumpadRight|NumpadEnd|NumpadHome|NumpadPgDn|NumpadPgUp|NumpadClear|NumpadDel|Joy1|Joy2|Joy3|Joy4|Joy5|Joy6|Joy7|Joy8|Joy9|Joy10|Joy11|Joy12|Joy13|Joy14|Joy15|Joy16|Joy17|Joy18|Joy19|Joy20|Joy21|Joy22|Joy23|Joy24|Joy25|Joy26|Joy27|Joy28|Joy29|Joy30|Joy31|Joy32
    key =
    Loop, parse, keys, |
    {
        if GetKeyState(A_LoopField , "P") {
            key := A_LoopField
            break
        }
    }
    if !key {
        Loop, 224 {
            if GetKeyState(chr(a_index + 31) , "P") {
                key := chr(a_index + 31)
                break
            }
        }  
    }
    if key {
        if (Asc(key) > 64) && (Asc(key) < 91) && !GetKeyState("CapsLock" , "T") ; A-Z --> a-z
            key := chr(Asc(key) + 32)
        else if !GetKeyState("CapsLock" , "T")
			StringLower, key, key
        KeyWait, %Mode%, U
        Loop
        {
            if (Mode = "F9")
                Send {%key% down}
            else if (Mode = "F10")
                send {%key%}
            Sleep 30
        } Until (GetKeyState(key , "P") || GetKeyState("F9" , "P") || GetKeyState("F10" , "P"))
    }
return
Last edited by Holle on 13 Dec 2013, 00:51, edited 1 time in total.
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: KeyHolder

11 Dec 2013, 14:37

You might consider using A_PriorKey to catch all the keypresses. It will not get other input devices like the mouse but it should help catch all the keyboard keys with out having to list them all explicitly.

Code: Select all

#InstallKeybdHook ; ADDED LINE

*F9:: ; keep pressed
*F10:: ; repeat pressing
    if Timer_pressed
        return
    StringTrimLeft, Mode, A_ThisHotkey, 1   
    if GetKeyState(Mode , "P")
    {
        SetTimer, Pressed, 50
        Timer_pressed := true       
        gosub Pressed
    }
return

Pressed:
    if !GetKeyState(Mode , "P")
    {
        SetTimer, Pressed, off
        Timer_pressed := false
        return
    }
    keys = LButton|RButton|MButton|XButton1|XButton2|WheelUp|WheelDown|WheelLeft|WheelRight|Joy1|Joy2|Joy3|Joy4|Joy5|Joy6|Joy7|Joy8|Joy9|Joy10|Joy11|Joy12|Joy13|Joy14|Joy15|Joy16|Joy17|Joy18|Joy19|Joy20|Joy21|Joy22|Joy23|Joy24|Joy25|Joy26|Joy27|Joy28|Joy29|Joy30|Joy31|Joy32
    key =
    Loop, parse, keys, |
    {
        if GetKeyState(A_LoopField , "P") {
            key := A_LoopField
            break
        }
    }
    if !(A_PriorKey = "F9" or A_PriorKey = "F10" or key)  ; ADDED LINE
	      key := A_PriorKey                                         ; ADDED LINE
    if key {
        KeyWait, %Mode%, U
        Loop
        {
            if (Mode = "F9")
                Send {%key% down}
            else if (Mode = "F10")
                send {%key%}
            Sleep 30
        } Until (GetKeyState(key , "P") || GetKeyState("F9" , "P") || GetKeyState("F10" , "P"))
    }
return
I have not tested this hardly at all but just a thought to show a different way that make it easier not to miss a key.

Too bad A_PriorKey does not pickup everything that GetKetState does then there would be no requirement for explicitly checking for anything.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
Holle
Posts: 187
Joined: 01 Oct 2013, 23:19

Re: KeyHolder

12 Dec 2013, 00:30

Thank you, but I found a error in your script.

When I run the script and then I press backspace, after that I press "F10 + a", then the backspace is repeating.

Another problem is, that your script only repeats uppercase, that could a problem in some games. OK, my script works only with lowercase.
It´s possible to check the caps-status and change the repeating key.

But you´re right, in my script are only the keys for the german keyboard layout. Some keys are missing. Which keys I´ve forgot?
I can alternative use a Loop from 32 to 255 and use the ascii-code. On this way all Keys (incl. upper-/lowercase) are included.
User avatar
Holle
Posts: 187
Joined: 01 Oct 2013, 23:19

Re: KeyHolder

12 Dec 2013, 08:26

OK, this is the new Version with ascii numbers.
In the first posting is the old version, because the new version needs addes functions (StrReplace() and StdErr_Write()).

if you miss some case sensitive keys, you can add them in this row:

Code: Select all

key := StrReplace(key,"Ö,ö,Ä,ä,Ü,ü")
--> pairs needed (CharToReplace , ReplaceWith , CharToReplace , ReplaceWith , ...)

Code: Select all

*F9:: ; keep pressed
*F10:: ; repeat pressing
    if Timer_pressed
        return
    StringTrimLeft, Mode, A_ThisHotkey, 1  
    if GetKeyState(Mode , "P")
    {
        SetTimer, Pressed, 50
        Timer_pressed := true      
        gosub Pressed
    }
return

Pressed:
    if !GetKeyState(Mode , "P")
    {
        SetTimer, Pressed, off
        Timer_pressed := false
        return
    }
    keys = LButton|RButton|MButton|XButton1|XButton2|WheelUp|WheelDown|WheelLeft|WheelRight|Up|Down|Left|Right|Space|Enter|Escape|BackSpace|F1|F2|F3|F4|F5|F6|F7|F8|F11|F12|Tab|LShift|RShift|LControl|RControl|LAlt|RAlt|LWin|RWin|CapsLock|NumLock|ScrollLock|Home|End|Del|Ins|PgUp|PgDn|Numpad1|Numpad2|Numpad3|Numpad4|Numpad5|Numpad6|Numpad7|Numpad8|Numpad9|Numpad0|NumpadDot|NumpadDiv|NumpadMult|NumpadAdd|NumpadSub|NumpadEnter|NumpadIns|NumpadUp|NumpadDown|NumpadLeft|NumpadRight|NumpadEnd|NumpadHome|NumpadPgDn|NumpadPgUp|NumpadClear|NumpadDel|Joy1|Joy2|Joy3|Joy4|Joy5|Joy6|Joy7|Joy8|Joy9|Joy10|Joy11|Joy12|Joy13|Joy14|Joy15|Joy16|Joy17|Joy18|Joy19|Joy20|Joy21|Joy22|Joy23|Joy24|Joy25|Joy26|Joy27|Joy28|Joy29|Joy30|Joy31|Joy32
    key =
    Loop, parse, keys, |
    {
        if GetKeyState(A_LoopField , "P") {
            key := A_LoopField
            break
        }
    }
	if !key {
		Loop, 224 {
			if GetKeyState(chr(a_index + 31) , "P") {
				key := chr(a_index + 31)
				break
			}
		}	
	}
    if key {
		if (Asc(key) > 64) && (Asc(key) < 91) && !GetKeyState("CapsLock" , "T") ; A-Z --> a-z
			key := chr(Asc(key) + 32)
		else if !GetKeyState("CapsLock" , "T")
			key := StrReplace(key,"Ö,ö,Ä,ä,Ü,ü")
        KeyWait, %Mode%, U
        Loop
        {
            if (Mode = "F9")
                Send {%key% down}
            else if (Mode = "F10")
                send {%key%}
            Sleep 30
        } Until (GetKeyState(key , "P") || GetKeyState("F9" , "P") || GetKeyState("F10" , "P"))
    }
return
What do you say? Should I replace th first posting with the new version?
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: KeyHolder

12 Dec 2013, 14:26

This is trickier than I at first thought.

What if I want to repeat Control+A or Control+Alt+1. Not just capitalization is problematic but all key modifiers.

It is more than just academic. In many games I will often make toolbars with keys like Control+1 or Control+Alt+1 especially if I plan for those items to be used by a script.

Off the top of my head I don't know a good solution. I don't know of an easy way to get all the keys currently being pressed at any moment. And I don't know of an easy way to get the last key received with all its modifiers.

As far as your latest script version it is an improvement but I don't like the StrReplace dependency. It appears the same thing could be done with StringUpper and StringLower. Things like Ö and ö can be converted back and forth with those and not add a library dependency to the script and also hopefully make things more versatile.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: KeyHolder

12 Dec 2013, 18:15

This is a stripped down version to experiment with handling key modifiers.

Code: Select all

SendMode Input
#InstallKeybdHook

Mods_List := ["LShift","RShift","LAlt","RAlt","LWin","RWin","LControl","RControl"]
Press_Sleep := 50

F9::
    Mods_Pressed := {}
    Loop
    {
        for index, Mod in Mods_List
        {
            if GetKeyState(Mod)
                Mods_Pressed[Mod] := true
        }
    } Until !GetKeyState("F9")
    if GetKeyState("CapsLock" , "T")
        Mods_Pressed["Shift"] := true
    StringLower, Key, A_PriorKey
    if !(Key = "f9")
        Loop
        {
            for Mod in Mods_Pressed
                Send {%Mod% Down}
            Send {%Key% Down}
            for Mod in Mods_Pressed
                Send {%Mod% Up}
            Sleep %Press_Sleep%
        } Until GetKeyState("F9")
return
It only handles keyboard input, not a mouse or joystick. That could be added but I mainly was just experimenting with handling key modifiers.

It also only does the keep pressed while repeating.

I am not sure what the deal was with Backspace and using A_PriorKey before but this script does not seem to have a problem with Backspace.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
Holle
Posts: 187
Joined: 01 Oct 2013, 23:19

Re: KeyHolder

13 Dec 2013, 00:46

FanaticGuru wrote:I don't like the StrReplace dependency. It appears the same thing could be done with StringUpper and StringLower.
Omg :shock:
I´m coding in many programming languages, so that I was searching for a wrong command name.
StringUpper/Lower is exactly the needed.
Thank you

I have edit the code. In the first posting is now the new code.

Return to “Gaming Scripts (v1)”

Who is online

Users browsing this forum: No registered users and 52 guests