Listen to keystrokes during script execution

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
eitatetaata
Posts: 23
Joined: 28 Mar 2019, 05:27

Listen to keystrokes during script execution

01 Apr 2019, 06:20

Hi! I have a script which I want to execute in the background every now and then. However, the script needs to switch to a different (hidden) window for a couple of seconds, which is irritating, as I would like to be able to type in my original window at the same time. A workaround that I thought of would be to make the script record what I type when the hidden window is activated, and just paste it when it switches back to the original window. Problem is - I don’t know how to implement it.

Is there a way to listen to keystrokes during script execution if they appear (as opposed to waiting until a key is pressed)?
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Listen to keystrokes during script execution

01 Apr 2019, 10:35

You would need to declare a hotkey to every key on the keyboard.
When wishing to send input to an inactive window, the first port of call should be the ControlSend command.
Be aware though that ControlSend does not work with all apps
To bind a hotkey to all keys, you can use this code:

Code: Select all

#SingleInstance force

kb := new AllKeyBinder(Func("MyFunc"))
return

MyFunc(code, name, state){
	Tooltip % "Key Code: " code ", Name: " name ", State: " state
}

class AllKeyBinder{
	__New(callback, pfx := "~*"){
		keys := {}
		this.Callback := callback
		Loop 512 {
			i := A_Index
			code := Format("{:x}", i)
			n := GetKeyName("sc" code)
			if (!n || keys.HasKey(n))
				continue
			
			keys[n] := code
			
			fn := this.KeyEvent.Bind(this, i, n, 1)
			hotkey, % pfx n, % fn, On
			
			fn := this.KeyEvent.Bind(this, i, n, 0)
			hotkey, % pfx n " up", % fn, On		
		}
	}
	
	KeyEvent(code, name, state){
		this.Callback.Call(code, name, state)
	}
}
eitatetaata
Posts: 23
Joined: 28 Mar 2019, 05:27

Re: Listen to keystrokes during script execution

01 Apr 2019, 11:58

I am actually using ControlSend, but the script doesn’t work properly without activating the window anyway (it’s Chrome, and I guess it doesn’t always work great with AHK). I’ll be looking for other workarounds, but thanks a lot for this code.
User avatar
tidbit
Posts: 1273
Joined: 29 Sep 2013, 17:15
Location: USA

Re: Listen to keystrokes during script execution

01 Apr 2019, 17:08

chrome is a browser. Websites typically don't have "controls" as normal windows (like notepad) have them.
the website container itself is usually the control, everything in it is just... there. you need COM/selenium to directly interact with the site contents, or possibly SEND for the hacky brute-force but simpler method.
rawr. fear me.
*poke*
Is it December 21, 2012 yet?
gregster
Posts: 9035
Joined: 30 Sep 2013, 06:48

Re: Listen to keystrokes during script execution

01 Apr 2019, 17:28

For automation of the Chrome browser, there is also Geekdude's Chrome.ahk library available: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=42890
eitatetaata
Posts: 23
Joined: 28 Mar 2019, 05:27

Re: Listen to keystrokes during script execution

02 Apr 2019, 06:48

I’ll check this out too, thanks!
K0MPOT1K
Posts: 8
Joined: 05 Mar 2018, 15:04

Re: Listen to keystrokes during script execution

18 Nov 2020, 21:32

evilC wrote:
01 Apr 2019, 10:35
You would need to declare a hotkey to every key on the keyboard.
When wishing to send input to an inactive window, the first port of call should be the ControlSend command.
Be aware though that ControlSend does not work with all apps
To bind a hotkey to all keys, you can use this code:

Code: Select all

#SingleInstance force

kb := new AllKeyBinder(Func("MyFunc"))
return

MyFunc(code, name, state){
	Tooltip % "Key Code: " code ", Name: " name ", State: " state
}

class AllKeyBinder{
	__New(callback, pfx := "~*"){
		keys := {}
		this.Callback := callback
		Loop 512 {
			i := A_Index
			code := Format("{:x}", i)
			n := GetKeyName("sc" code)
			if (!n || keys.HasKey(n))
				continue
			
			keys[n] := code
			
			fn := this.KeyEvent.Bind(this, i, n, 1)
			hotkey, % pfx n, % fn, On
			
			fn := this.KeyEvent.Bind(this, i, n, 0)
			hotkey, % pfx n " up", % fn, On		
		}
	}
	
	KeyEvent(code, name, state){
		this.Callback.Call(code, name, state)
	}
}
Great class!
Only I had a question.
Can I make it so that doesn't overwrite existing keyboard shortcuts ?
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Listen to keystrokes during script execution

19 Nov 2020, 09:22

By default it won't block the keys (Allowing existing shortcuts to work)

There's an optional 2nd parameter ("pfx") that is used as a prefix for all hotkeys it declares, and it defaults to ~

This can be overridden in the constructor

eg

kb := new AllKeyBinder(Func("MyFunc"), "*") to make keys block and use the * modifier
K0MPOT1K
Posts: 8
Joined: 05 Mar 2018, 15:04

Re: Listen to keystrokes during script execution

19 Nov 2020, 10:30

evilC wrote:
19 Nov 2020, 09:22
By default it won't block the keys (Allowing existing shortcuts to work)

There's an optional 2nd parameter ("pfx") that is used as a prefix for all hotkeys it declares, and it defaults to ~

This can be overridden in the constructor

eg

kb := new AllKeyBinder(Func("MyFunc"), "*") to make keys block and use the * modifier
Apparently this is due to the fact that some of the keyboard shortcuts I have are defined in #IfWinActive, ahk_group OtherGroup
I saw the pfx parameter, but I couldn't get the script to work properly.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Listen to keystrokes during script execution

19 Nov 2020, 10:41

Oh, you mean AHK hotkeys, not normal windows shortcuts - totally different thing.
If the AHK hotkey definitions you have are context sensitive, then if the context is active, they will override the ones declared by AllKeyBinder
K0MPOT1K
Posts: 8
Joined: 05 Mar 2018, 15:04

Re: Listen to keystrokes during script execution

19 Nov 2020, 10:44

It doesn't seem to work.
Here is a simple example:

Code: Select all

kb := new AllKeyBinder(Func("KeyPress"), "~+")

KeyPress(type, code, name, state) {
	Tooltip % "Type: " type ", Code: " code ", Name: " name ", State: " state
}

#IfWinActive ahk_class Notepad++
F1::
	MsgBox, F1 Pressed
return
#IfWinActive
In this example, when you press F1, the message does not appear, although it seems like it should.
K0MPOT1K
Posts: 8
Joined: 05 Mar 2018, 15:04

Re: Listen to keystrokes during script execution

24 Nov 2020, 08:23

evilC wrote:
19 Nov 2020, 10:51
With that code, KeyPress() is never getting called because you changed the signature - you have 4 parameters (extra type parameter) instead of 3
Looks like I have slightly different class from another thread.

Code: Select all

class AllKeyBinder{
    __New(callback, pfx := "~*"){
        static mouseButtons := ["LButton", "RButton", "MButton", "XButton1", "XButton2"]
        keys := {}
        this.Callback := callback
        Loop 512 {
            i := A_Index
            code := Format("{:x}", i)
            n := GetKeyName("sc" code)
            if (!n || keys.HasKey(n))
                continue
            keys[n] := code
            
            fn := this.KeyEvent.Bind(this, "Key", i, n, 1)
            hotkey, % pfx "SC" code, % fn, On
            
            fn := this.KeyEvent.Bind(this, "Key", i, n, 0)
            hotkey, % pfx "SC" code " up", % fn, On             
        }
        
        for i, k in mouseButtons {
            fn := this.KeyEvent.Bind(this, "Mouse", i, n, 1)
            hotkey, % pfx k, % fn, On
            
            fn := this.KeyEvent.Bind(this, "Mouse", i, n, 0)
            hotkey, % pfx k " up", % fn, On             
        }
    }
    
    KeyEvent(type, code, name, state){
        this.Callback.Call(type, code, name, state)
    }
}


Last bumped by K0MPOT1K on 24 Nov 2020, 08:23.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], mikeyww and 370 guests