It maybe seem unnecessary, but I want to reopen a spezific program after it is closed by ahk - autohotkey

This is how far i got:
#IfWinActive ahk_exe zotero.exe
f7::
WinGetTitle, Title, A
WinClose, A
Sleep 1000
IfWinNotExist(zotero)
{
Run, zotero.exe , , Min
}
Return
I am unsure about the if statement in an if statement. How can I make it work?

I would suggest to use:
Loop {
Sleep, 1000 ; just 1 second delay between any check
process, Exist, "Zotero.exe"
if ErrorLevel
Run, zotero.exe , , Min
}

Related

Auto Hot Key - can't interrupt a loop

Here is an example auto hot key script:
^j::
WinActivate, MyWindow
WinWaitActive, MyWindow
Loop
{
If GetKeyState("Shift", "P")
Break
Click, 44, 55
Sleep, 1000
Click, 144, 155
Sleep, 1000
}
return
Everything works fine but I can't interrupt the loop by pressig "Shift". What is wrong ?
You have to hold the Shift key for more than 2 seconds pressed, because of the sleep times.
Or try something like this:
^j::
Loop
{
If !WinActive("MyWindow")
{
WinActivate, MyWindow
WinWaitActive, MyWindow
}
Click, 44, 55
Sleep_1000()
Click, 144, 155
Sleep_1000()
}
return
Sleep_1000(){
Loop 10
{
Sleep, 100
If GetKeyState("Shift", "P")
exit ; terminate the hotkey's thread
}
}
Using a loop inside a hotkey definition is bad practice.
AHK doesn't provide true multithreading, so long running loops are generally a really bad idea.
Using a timer fixes this, and usage of a timer is anyway always what you want for something like this.
And it'll be much more simple as well.
So, with Ctrl+j we activate the desired window and create the timer and tell it to run our function TimerCallback (which we will shortly create) every 2secs:
^j::
WinActivate, MyWindow
WinWaitActive, MyWindow ;shouldn't be needed, but if you find it helpful, fair enough
TimerCallback() ;run the function once, since the timer is going to
;run it for the first time only after 2secs
SetTimer, TimerCallback, 2000
return
And then we make shift be a hotkey for turning off the timer. And we for sure want to use the ~ modifier to not consume the key when the hotkey is fired:
~Shift::SetTimer, koira, Off
And now lets also define our function TimerCallback:
TimerCallback()
{
Click, 44, 55
Sleep, 1000
Click, 144, 155
}
So here's again the script in full if something was somehow left unclear:
^j::
WinActivate, MyWindow
WinWaitActive, MyWindow ;shouldn't be needed, but if you find it helpful, fair enough
TimerCallback() ;run the function once, since the timer is going to
;run it for the first time only after 2secs
SetTimer, TimerCallback, 2000
return
~Shift::SetTimer, TimerCallback, Off
TimerCallback()
{
Click, 44, 55
Sleep, 1000
Click, 144, 155
}

How to activate a Script only if a specific Window is active?

I have a problem with a Script which should just do the following:
- If a specific Window becomes active
- SetCapslockState, On
- If the Windows lost focus
- SetCapslockState, Off
I've tried:
#If WinActive("ahk_class blahblah")
SetCapslockState, On
and/or
#If !WinActive("ahk_class Chrome_WidgetWin_1")
SetCapslockState, Off
But it don't work.
Also I've tried:
WinWaitActive, (mytitleofwindow)
if ErrorLevel
{
SetCapslockState, On
return
}
else
It don't work either, else I would not ask for help here... hihihi
I hope someone can help me! :)
Instead of a loop (which takes up CPU cycles), you can also use Hardware Handles. See example:
#SingleInstance Force
#installKeybdHook
#Persistent
Menu, Tray, Tip, Medical Alert
SetKeyDelay, 50
Menu, Tray, Icon , Shell32.dll, 145, 1
TrayTip, Medical Alert, Started, 1
Gui +LastFound
hWnd := WinExist()
DllCall( "RegisterShellHookWindow", UInt,Hwnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
Return
ShellMessage( wParam ) ; Run on Window switch
{
If (wParam = 4) ; If Window Changed
{
WinGetActiveTitle, Title
if instr(Title, "Past Medical History") OR instr(Title, "Allergies Verified") ; TESTED WITH: if instr(Title, "NotePad")
MsgBox, 1, Allergies Verified, Please verify patient allergies
}
}
Return
The key is to combine WinWait[Not]Active with a Loop.
Loop {
WinWaitActive, mytitleofwindow
SetCapslockState, On
WinWaitNotActive, mytitleofwindow
SetCapslockState, Off
}

How to check if clipboard is equal to a predetermined number, or several numbers in AHK?

; Copy cell
var := clipboard
sleep, 1000
WinActivate, doesntmatter - Internet Explorer
IfEqual 30684047, %var%
{
sleep, 500
Send, inform
}
else
{
msgbox, nope
}
return
My problem is that even though I have the correct number (30684047) in the clipboard, the code still goes straight to the MsgBox and tells me that the clipboard (%var%) isnt equal to the predetermined code.
What am i missing? I am 100% sure that %var% contains my copied code from the clipboard because if i do a MsgBox with %var% after i copy it, it gives me a box containing that correct code.
Look back at the documentation for IfEqual...you switched var and value.
; Copy cell
var := clipboard
sleep, 1000
WinActivate, doesntmatter - Internet Explorer
IfEqual, var, 30684047
{
sleep, 500
Send, inform
}
else
{
msgbox, nope
}
return
There's really no need to save off the value of clipboard to a different variable unless you're wanting to re-use that value after clipboard has later changed. So the above could also be:
WinActivate, doesntmatter - Internet Explorer
If (clipboard = "30684047") {
sleep, 500
SendInput, inform
}
else
msgbox, nope
return

How do I return from inside an if/else block in Autohotkey?

Below is the code snippet I used. If you are doing something in a browser, it should detect that you are currently in a browser and copy the URL to the clipboard. If you are not in a browser, then since there is no URL there is no question of doing that.
Regardless what browser I am in, the first MessageBox is always outputting the value 0. However, the MessageBox inside the function never gets activated, that is "No browser detected" message is never displayed. The value therefore can't be zero, yet when I am in notepad the if function still gets processed.
if (Retrieve_Browser_Type <> 0)
{
Send, {F6}
Send, ^{ins}
URL = %clipboard%
MsgBox, % Retrieve_Browser_type
MsgBox, URL copied: %URL%
}
Retrieve_Browser_Type() {
IfWinActive, ahk_class MozillaWindowClass return 1
IfWinActive, ahk_class Maxthon3Cls_MainFrm return 2
IfWinActive, ahk_class IEFrame return 3
IfWinActive, ahk_class Chrome_WidgetWin_1 return 4
MsgBox, No browser detected
return 0
}
It was a syntax mistake that thee compiler didn't detect.
Instead of:
IfWinActive, ahk_class MozillaWindowClass return 1
You ought to write:
IfWinActive, ahk_class MozillaWindowClass
return 1

Autohotkey loop not working

My loop in my autohotkey script is only running through once. Can anyone tell me why? Thanks
Loop, 8
{
WinActivate, NDTr
ControlClick, Button3 ;Select Batch, enter info, start collecting data
WinWait, Batch Readings
ControlClick, Edit1
Send {BS}+{BS}+{BS}+{BS}+{BS}+{BS}
Send 1
ControlClick, Edit2
Send {BS}+{BS}+{BS}+{BS}+{BS}+{BS}
Send 15
if A_Index = 4
{
Sleep, 20000
}
else if A_Index = 7
{
Sleep, 20000
}
else if A_Index = 1
{
Sleep, 3000
}
else
{
Sleep, 15000
}
ControlClick, Button1
Sleep, 15000
}
WinWait looks like a likely culprit like anthv123 said. Double check your window's title and make sure it fits the TitleMatchMode that you're expecting.
Common debugging practices include adding different ToolTips in places along the problem code. For example tooltips above and below the WinWait line with texts "before" and "after" would tell you if it's pausing indefinitely at that part (if it never says "after").
Sleeping for 3-20 seconds isn't going to help your patience either.
Try using this to diagnose the issue. If "Batch Readings" takes longer than 5 seconds, you get an error letting you know and the loop continues
WinWait, Batch Readings,,5
if (errorLevel = 1)
Msgbox % "Batch Readings timed out"