Timer runs only once - autohotkey

Below script works fine.
It sends mouse clicks every 4 seconds
to KingSoft Writer.
But when I change the Timer length to -4000
instead of 4000 so that the timer will run only once
the script no longer works even once.
I am no longer able to send mouse clicks to
KingSoft Writer.
What am I doing wrong?
#Persistent
#SingleInstance
SetTimer, CheckApp, 4000
Return
CheckApp:
IfWinActive, ahk_class QWidget
{
sleep 2000
Click 486, 15
Click 570, 93
}
Return

Before I answer this question. Would you be so kind as to go back to the previous question and mark the answer you received there, by clicking on the WHITE check-mark to turn it GREEN.
I once tried the minus values and was not happy with the results, so I decided to always turn the timer off instead of using negative values.
#Persistent
#SingleInstance
SetTimer, CheckApp, 4000
Return
CheckApp:
IfWinActive, ahk_class QWidget
{
SetTimer, CheckApp, Off
Click 486, 15
Click 570, 93
}
Return
I removed your Sleep, 2000. Adding this sleep command blocks ahk 50% of the time (sleeping 50%) and adds nothing useful. It even makes the chance that another application steals the focus in those 2 seconds larger, so the mouse clicks could go to another application...
Do you have to use mouse clicks or can you use keyboard shortcuts. Mouse positions tend to be unreliable as menus move or expand/contract.
Update
#Persistent
#SingleInstance
Return ; Prevent the [Win]+w from executing on startup of script.
#w:: ; [Win]+w launches PolyEdit, waits for window and sends two mouse clicks.
Run, path to the PolyEdit window.exe
WinWaitActive, ahk_class QWidget
Sleep, 1000
Click 486, 15
Click 570, 93
Return
Now you can put the ahk script in the windows start menu and launch PolyEdit through [Win]+w (or any other key you define...)
Update 2
Not sure why you want to do this, because launching the app takes an action (clicking an icon or pressing a shortcut), which could be used to trigger the script. Now you have to constantly run checks in the background. You can create an icon that looks like KingSoft, but in reality is an ahk script.
But here you go!
#Persistent
#SingleInstance
SetTimer, CheckApp, 400
Return
InitiateKS := true
CheckApp:
IfWinExist, ahk_class QWidget
{
If InitiateKS
{
InitiateKS := false
WinActivate, ahk_class QWidget
TrayTip, KingSoft, Started, 1
;Click 486, 15
;Click 570, 93
}
}
Else ; if no KingSoft is running
{
InitiateKS := true
}
Return

Related

how to timeout a script when it runs into an event it can't handle autohotkey

I have a script that opens a browser and saves a webpage and I want it to cancel the job on a time out. If it's waiting for a window that doesn't show up to stop running and start over. How would I go about this? Here's my short script:
Run, www.google.com
WinWaitActive ahk_exe firefox.exe
Sleep, 1000
Send ^s
WinWait, Save As
Send ^{Backspace}
Sleep, 1000
SendRaw www.google.com.html
Sleep, 500
ControlClick, Button2, Save As,, Left, 1, NA
We can use the Timeout parameter of WinWaitActive:
From the docs:
WinWaitActive / WinWaitNotActive
Waits until the specified window is active or not active.
WinWaitActive , WinTitle, WinText, Timeout, ExcludeTitle, ExcludeText
If it takes longer than the value in the Timeout parameter, then the script continues and the variable ErrorLevel is set to 1/True.
By putting this entire script under a Label (here called savePageSubroutine), we can go back to this point with a goto statement.
savePageSubroutine:
Run, www.google.com
WinWaitActive ahk_exe firefox.exe,,1000 ; Tune this value to taste
if (ErrorLevel)
goto savePageSubroutine
Sleep, 1000
Send ^s
WinWait, Save As
Send ^{Backspace}
Sleep, 1000
SendRaw www.google.com.html
Sleep, 500
ControlClick, Button2, Save As,, Left, 1, NA
return

LButton Hotkey seems to prevent Send, {LButton}

I'm at a loss here. As soon as I add the LButton hotkey, the Send, {LButton} doesn't seem to work, but they show up in recently executed lines.
Env. Windows 7x64, Disabled Touchpad, AHK v1.1.31.01.
I try to emulate the Wink application (from DebugMode) to capture screenshots for training purposes. For that reason, I want to capture a screenshot just before a mouse click. This looks easy, and I even vaguely remember doing similar mouse hotkeys in the past. However I can't get this to work.
Step 1: I just reduced it to this simple script:
#InstallKeybdHook
#InstallMouseHook
#UseHook
#Persistent
Return
a::
Send, {LButton}
Return
q::
ExitApp
When using this script, I can simulate clicking the Left Mouse Button through the a key. Nothing special.
However as soon as I add either a line with "Hotkey, $LButton, MySendClick", or "$LButton::" the previously working a hotkey no longer works. In the recently executed lines, you can see the "Send, {LButton}" lines, but nothing is being send. Unexpectedly, the a hotkey actually causes the "$LButton::" hotkey to trigger (without it sending {LButton}). When I change the a hotkey to send "RButton" and the $LButton:: to $RButton::, then Send {Click} works perfectly (eventhough the a hotkey should never be able to trigger $RButton::).
Originally I just wanted to have the following HotKey:
$LButton::
SoundBeep, 300, 150 ; For testing only
; Send, ^{PrintScreen} ; To trigger Greenshot in the background
Sleep, 100
Send, {LButton}
Return
I upgraded from AHK v1.1.22.04 to v1.1.31.01. No improvement.
I tried "Click", "sendInput, {LButton}", "Send {Click}", "MouseClick, Left".
I tried "$LButton::", "vk01sc000::", "Hotkey, $LButton, MyClick".
Is this an issue with my specific Windows 7 configuration or an "undocumented AHK feature"?
#InstallKeybdHook
#InstallMouseHook
#UseHook
#Persistent
Return
a::
Send, {LButton}
Return
$LButton::
SoundBeep, 300, 150 ; Should be Send, ^{PrintScreen} ; To trigger Greenshot in the background
MouseClick, Left
Return
q::
ExitApp
In this last test example, When $LButton:: is disabled, the a hotkey works like a charm, but as soon as I enable $LButton::, the a hotkey triggers $LButton:: and no mouse click is being sent to the windows applications.
I would appreciate it when other Windows 7 users could quickly test this issue.
In my experience, using keys that you still want the input to pass through need the Tilde prefix.
https://www.autohotkey.com/docs/Hotkeys.htm#Tilde
~LButton::
SoundBeep, 300, 150 ; Should be Send, ^{PrintScreen} ; To trigger Greenshot in the background
KeyWait, LButton ; Wait for lbutton to be released.
Return

Writing a Simple AutoHotkey Script (press a key every X second on desktop)

I need to press any useless key (like F11) every 5 minutes or less to keep the windows active (if it became inactive for 10 minutes it will lock-out).
But I need the key to be pressed on the desktop (so it doesn't effect any open windows).
I have tried
Loop
{
ControlSend, {F11}, WindowsApplication1
Sleep, 100000
}
but doesn't seem to work.
thanks.
edit: my current script:
#NoTrayIcon
NumLock::Run Calc.exe
PrintScreen::Run "C:\Windows\Sysnative\SnippingTool.exe"
; When I press Insert, I want to Show Desktop
Insert::Run, "%A_APPDATA%\Microsoft\Internet Explorer\Quick Launch\Shows Desktop.lnk"
; When I press Pause/ Break, I want to Lock the Computer
Pause::DllCall("LockWorkStation")
#IfWinActive, ahk_class CabinetWClass
~MButton::Send !{Up}
#IfWinActive
Return
Just move the cursor every X minutes:
#Persistent
SetTimer, MoveMouse
MoveMouse:
If ( A_TimeIdle > 300000 ) {
MouseMove, 1 , 1,, R
MouseMove, -1,-1,, R
}
Return
Code adopted from here.
This is definitely nothing that should require Autohotkey.
Just disable your screensaver.
Rightclick your desktop
Click Personalize (Vista/7/8) or Properties (XP)
Go to the screensaver options
Disable the screensaver
You might also wanna disable stuff like "turn off display after x minutes", "go to sleep after x minutes" and "turn of harddrives after x minutes".
You'll find that in the poweroptions. There is a button in the screensaver options to get there...
edit: Another way of disabling the screensaver using autohotkey would be the following script:
#Persistent
Menu, Tray, Icon, User32.dll, 4
Menu, Tray, Tip, Screen Saver Disabled !!!
OnExit, ScreenSaveActivate
DllCall("SystemParametersInfo", Int,17, Int,0, UInt,NULL, Int,2)
SetTimer, CheckScreenSaveActive, 999
Return
CheckScreenSaveActive:
DllCall("SystemParametersInfo", Int,16, UInt,NULL, "UInt *",SSACTIVE, Int,0)
If SSACTIVE
DllCall("SystemParametersInfo", Int,17, Int,0, UInt,NULL, Int,2)
Return
ScreenSaveActivate:
DllCall("SystemParametersInfo", Int,17, Int,1, UInt,NULL, Int,2)
ExitApp
Return
which was created by SKAN from the ahk forums.

Why does script stop working and need to be reloaded?

I have a script that I use to open Firefox that contains customized shortcuts and that closes when I close the browser. Lately when I first open it and try to use a shortcut, it does not work until I reload the script, even though the script is still running. I haven't changed anything in the script in a while. Can anyone tell me what's going on?
Thanks,
Ellen
Menu, Tray, Icon, C:\Program Files\Mozilla Firefox\firefox.exe
SetTitleMatchMode, 2
runwait C:\Program Files\Mozilla Firefox\firefox.exe, , max
IfWinExist ahk_class MozillaWindowClass
Return
ExitApp
Return
#SingleInstance Force
#installKeybdHook
#Persistent
Return
#ifWinActive Mozilla Firefox
^!b::send, ^+b
^b::send, ^d ; bookmark page]
^n::send, ^t ; open new tab
!c::send, ^w ; close current tab
^d::send, ^!t ; duplicate tab
^u::send, ^+t ; undo close tab
!d::send, ^j ; open downloads
^e::
MouseClick, left, 33, 44
Sleep, 100
MouseClick, left, 33, 230
Sleep, 100
return
^r:: ; recent pages
MouseClick, left, 79, 76
return
!a:: ; click on address bar
MouseClick, left, 368, 73
return
^q:: ; roboform
MouseClick, left, 864, 722
return
^BS::send, +{Backspace} ; forward
Up::send, ^{+} ;zoom in
Down::send, ^{-} ;zoom in
::abc::about:config
#ifWinActive
To me the problem with your script seems to be that the runwait makes the script stop the the current thread that is running firefox.
That thread then waits for firefox to close giving you the "STILL WAITING"... then when it closes the next line is IfWinExist ahk_class MozillaWindowClass and it will not exist making the script skip to Exitapp
While RunWait is in a waiting state, new threads can be launched via hotkey, custom menu item, or timer.
When using RunWait some programs will appear to return immediately even though they are still running, these programs spawn another process. With the way your script is setup it may stop RunWait from going into this waiting state once in a while.
And this will make you unable to launch new threads as autohotkey is not multi threaded...
So I say use something like WinWaitClose as that will also let you launch new threads
While WinWaitClose is in a waiting state, new threads can be launched via hotkey, custom menu item, or timer.
Something like this:
Run, C:\Program Files\Mozilla Firefox\firefox.exe, , max
WinWait, ahk_class MozillaWindowClass
WinWaitClose ; Wait for the exact window found by WinWait to be closed.
Exitapp
Hope it helps

How can I make the script run automatically, without a hotkey being defined?

I want to create a "PolyEdit" script.
Below is the script.
!M::
IfWinActive, ahk_class TMainForm
{
sleep 2000
Send Now is the time
Return
}
The purpose of the script is to:
Send keystrokes and mouse clicks to my default program for opening text files.
That default program is called "PolyEdit".
But I need the script to run without a hotkey being defined.
Right now, in it's present form, with a hotkey defined, it runs just fine.
My question is:
How can I make the script run automatically, without a hotkey being defined?
As Armin already wrote, use #Persistent. Also, If you want to create hotkeys that are only active when a specific application is in focus you can do the following: In this case the script will no longer execute on startup, only when you press the hotkey though...
#Persistent
#SingleInstance
#IfWinActive, ahk_class TMainForm
!M::
sleep 2000
Send Now is the time
Return
!n::SoundBeep, 500, 500
!o::MsgBox, OK
#IfWinActive
This way all 3 (dummy) hotkeys will only be active when your application is in focus! You can define the same hotkeys for another application, just repeat the code but use the ID if the other application in the #IfWinActive, ahk_class TMainForm line.
If you want to send a message every 2 seconds when your application is active do the following:
#Persistent
#SingleInstance
SetTimerMatchMode, CheckApp, 2000
Return
CheckApp:
IfWinActive, ahk_class TMainForm
{
Send, Now is the time
}
Return
If you want to execute a script every time you (re)activate (put in focus) your application (so not every two seconds) then use the following:
#Persistent
#installKeybdHook
#SingleInstance
Gui +LastFound
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,Hwnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return
ShellMessage( wParam )
{
If (wParam = 4)
{
IfWinActive ahk_class TMainForm
{
Send, Now is the time
}
}
}
Return
Take a look at #Persistent which will keep script running.
If this directive is present anywhere in the script, that script will stay running after the auto-execute section (top part of the script) completes