Determine length of time keys are pressed - time

Can below script be modified so that the keys
"cl" fires "www.google.com" just if the "cl" keys
are both pressed for 500 milliseconds ?
Reason for this is that as part typing text sometimes the keys "cl" are pressed in rapid succession which then fires "www.google.com"
~l::
If (GetKeyState("c","p") && GetKeyState("l","p")) {
Send, {Backspace Down}{Backspace Up}{Backspace Down}{Backspace Up}
Run, "www.google.com"
}
Return

Using A_TickCount may be a good option.
~l::
duration := 0
If (GetKeyState("c","p") && GetKeyState("l","p"))
{
start := A_TickCount
While (GetKeyState("c") && GetKeyState("l"))
Sleep, 1
duration := A_TickCount - start
}
if (duration > 500)
Run, "www.google.com"
Return

This appears to do the trick :
~c::
~l::
If (GetKeyState("c","p") && GetKeyState("l","p")) {
Send, {Backspace Down}{Backspace Up}{Backspace Down}{Backspace Up}
sleep, 100
If (GetKeyState("c","p") && GetKeyState("l","p")) {
Run, "www.google.com"
}
Return
}
Return

Per this AutoHotKey forum post:
[T]he only way to program a key down for a specific duration is to use the down command and then a wait function with a (manually entered time) and then the up command[.]
So, you could solve this problem by putting a timer and then another if block inside your current if block, although it sounds like a bad idea.

A 500 millisecond delay could cause uncontrolled key repetition sothat we can't reliably delete the pressed keys anymore. So my suggestion is to find the repeat delay and only wait for so long minus ~150 milliseconds:
~c::
~l::
If (GetKeyState("c","p") && GetKeyState("l","p")) {
If (!GetKeyState("c","p") || !GetKeyState("l","p"))
Return
DllCall("SystemParametersInfo", UInt, 0x16, UInt, 0, UIntP, RepeatDelay, UInt, 0) ;get the key repeat delay
Sleep % (RepeatDelay+1)*250-150
If (GetKeyState("c","p") && GetKeyState("l","p")) {
SendInput, {c up}{l up}{BS}{BS}
Run, www.google.com
}
}
Return
SystemParametersInfo - SPI_GETKEYBOARDDELAY

Related

Jump to the next function by pressing Ctrl-C

Assume that there are some functions which they do different jobs. I want to be able to press Ctrl-C to jump to the next function instead of canceling all the script at once.
I tried trap ctrl_c INT but it didn't work. FYI, I use curl in some of the functions.
How can I do it?
function first {
# do the first job
}
function second {
# do the second job
}
function third {
# do the third job
}
first &&
second &&
third &&
rm *.del
Hooking Ctrl+C to return 0 seems to work fine. Like:
# define first, second, and third here
trap 'return 0' INT
first &&
second &&
third &&
trap - INT &&
rm *.del

Pressing a key twice quickly to trigger a function in AutoHotKey

I want to bind 'jj' to Esc using AutoHotkey in my Rstudio application. Is there any way we can map 'jj' to trigger Escape in a selected windows application?
I found a solution, that worked.
#IfWinActive ahk_exe rstudio.exe
l::
{
count++
settimer, actions, 150
}
return
actions:
{
if (count = 1)
{
Send j
}
else if (count = 2)
{
Send {Esc}
}
count := 0
}
return

how to fix my AutoHotkey active window checker (fileappend)

It is supposed to put an entry in a text file each time a new window is active, instead it constantly loops and puts thousands of entries while the window is active, if anyone is capable of rectifying this I would be grateful.
loop
{
if new_window = %window_title%
new_window = diff
else
{
WinGetActiveTitle, window_title
fileappend, %window_title%`n, C:\mydirectory\myname.txt
new_window = %window_title%
}
}
Any help able to be provided would be more than welcome.
This uses a timer to check for a new window every 0.5 seconds.
#Persistent
prev_window := ""
settimer, check_window, 500
return
check_window:
WinGetActiveTitle, active_window
if (active_window != prev_window) {
fileappend, %active_window%`n, myname.txt
prev_window := active_window
}
return
The same could be accomplished in a loop:
prev_window := ""
loop
{
WinGetActiveTitle, active_window
if (active_window != prev_window) {
fileappend, %active_window%`n, myname.txt
prev_window := active_window
}
sleep, 500
}
return
You should probably put a SetTimer that checks active window title in some time interval (100ms or something) and compare to previously checked window tile - and if it has changed then write to file.

Making a timer in Arduino whilst checking for input

I need to wait for a period of time while checking whether a button is pressed (so whether an input is HIGH or LOW).
The delay function is annoying to use for this because it cannot check whether something is happening while being delayed, so it would have to wait for 1 ms, check, wait, check, wait, check etc...
Can you help me with the coding I would need to check and pause for a set amount of time, at the same time?
You can realize that with a second condition-controlled loop.
If you want to wait in each arduino main loop as an example for 20 seconds and execute in this time span further code you can do this as follows:
unsigned long startTime = millis(); // Number of milliseconds since the program started (unsigned long)
unsigned long intervalTime = 20000UL; // equals 20 seconds
int buttonPin = 3; // used button pin
void loop()
{
while(millis() - startTime < intervalTime){
if(digitalRead(buttonPin)==HIGH){
//...
}
else {
//...
}
}
//...
}

Looking for thread IDs in AutoHotkey

I thought the following code may work but did not. The reason probably lies in the fact that the Throw command is executed in the hotkey thread, not in the auto-execution section thread.
try
{
count := 0
loop {
tooltip % ++count
sleep 200
}
} catch {
}
msgbox done
Exitapp
Esc::ExitAPp
^1::throw
So is there a way to know to which thread the flow of control belongs? Does AutoHotkey have a variable for thread IDs or something similar to it?
The below code shows that the both (pseudo) threads return the same number. So I need to know the thread IDs within AutoHotkey if there are. I've read somewhere that an AutoHotkey thread is merely a function call. But I'm expecting that there might be a way to identify the pseudo threads.
try
{
count := 0
loop {
tooltip % ++count "`nThread ID: " DllCall("GetWindowThreadProcessId", "Int", A_ScriptHwnd, "Int", "0")
sleep 200
}
} catch {
}
msgbox done
Exitapp
Esc::ExitAPp
^1::
MsgBox, % DllCall("GetWindowThreadProcessId", "Int", A_ScriptHwnd, "Int", "0")
throw
Return
Is this what you are looking for?
^w::
WinGet, WinID,, A
ThreadID:=DllCall("GetWindowThreadProcessId", "Int", WinID, "Int", "0")
MsgBox, %ThreadID%
Return

Resources