How to determine when the Select File Dialog is active? - autohotkey

I'm trying to determine when the file selection dialog is active, but I can't.
SetTitleMatchMode,1
FileSelectFile, SelectedFile
Winwaitactive,Select File -
Msgbox,File Select Dialog is active ; This is never fired
if (SelectedFile = "")
MsgBox, The user didn't select anything.
else
MsgBox, The user selected the following:`n%SelectedFile%
Could you please tell me what I'm doing wrong?

On that thread, code execution stops on the FileSelectFile line until a file has been selected. So your code will never get past the WinWaitActive command, because by the time that command runs, the window you're trying to match isn't open anymore.
And by the looks of things, you can't interrupt that thread without breaking the FileSelectFile command's functionality.
So the exact thing you're trying to do isn't possible without true multithreading.
But maybe you'd be fine to just make a simple assumption like this:
MsgBox, % "File select will begin after you click OK"
FileSelectFile, output
MsgBox, % "File select ended"

Related

WinActivate does not work as expected. Re-activating focus to the starting window

I am having some serious struggles fully grasping the control on activating windows and forcing their focus and foremost position.
In order to debug a larger script I made a separate script to test the use of WinActivate and again I am observing frustrating behaviour as it either all together ignores the title I have defined or is failing in some other way. In the smaller test script I am simply requesting that the window in which the hotkey was triggered be set as active after another action, specifically an input box
Below is the simple code for testing:
F10::
SetTitleMatchMode, 1
DetectHiddenWindows, Off
WinGetTitle, startTitle, A
msgbox % "Start Title = <" . startTitle . ">"
;WinActivate, startTitle
inputbox, mode, Test box, Testing,,260,160
sleep 500
WinActivate, startTitle
Return
This code does not properly activate the starting window. For example I execute the hotkey in an empty notepad window and upon submitting blank into the input box the focus becomes notepad++ on my second monitor. The second time I press the hotkey from within notepad (or another application) notepad does not lose focus. In a third execution I begin from notepad again and after the input box appears I switch the focus to another window. I again submit blank to the inputbox but that new window remains the focus and notepad is not activated or brought to the foremost position.
Can someone please explain to me what is going on with WinActivate?
I was having similar frustration with unexpected results making a windows script host file and I think I must be missing some fundamental detail in windows.
You are trying to activate a window that start with the literal text "startTitle".
You forgot(?) to either enter expression syntax with % or use the legacy way of referring to a variable %startTitle% (please don't use legacy).
Extra stuff:
You shouldn't specify SetTitleMatchMode and DetectHiddenWindows inside your hotkey statement. There is no need (unless there actually is) to set those every time you hit the hotkey. Just specify them at the top of your script once.
Both of them are useless for you though, below I'll show why. Also DetectHiddenWindows is already off by default.
WinGetTitle is not good to use for this. What you actually want to do is get the hwnd of the window you wish by using e.g. WinExist().
And then refer to the window by its hwnd. Much better than working with window titles, and impossible to match the wrong window as well. To refer to a window by its hwnd, you specify ahk_id followed by the hwnd on a WinTitle parameter.
And lastly, the concatenation operator . is redundant. Of course you may prefer to use it, but in case you didn't know, it can just be left out.
Here's your revised code:
F10::
_HWND := WinExist("A")
MsgBox, % "Start hwnd = <" _HWND ">"
InputBox, mode, Test box, Testing,,260,160
Sleep, 500
WinActivate, % "ahk_id " _HWND
Return

Auto Hotkey WinExist does not find open cmd

I am testing the following piece of code with auto hot key. I want to open a cmd console if one is has not already been opened. Each time i run it a new console is created, ignoring the previous one that have been already opened.
#z::Run https://autohotkey.com ; Win+Z
^!n:: ; Ctrl+Alt+N
if WinExist("Untitled - cmd"){
WinActivate
MsgBox GUI "MyGui" already exists.
}
else{
Run cmd
MsgBox GUI "MyGui" does not exist.
}
return
Another question that i have is that when i use the following code, everything works as expected, but when i change untitled - Notepad to untitled - notepad the same thing as in the first excerpt happens, a notepad is created although a previous one is still active. Any advises on why this happen would be really helpful, thank you.
#z::Run https://autohotkey.com ; Win+Z
^!n:: ; Ctrl+Alt+N
if WinExist("Untitled - Notepad"){
WinActivate
MsgBox GUI "MyGui" already exists.
}
else{
Run Notepad
MsgBox GUI "MyGui" does not exist.
}
return
Place this at the top of your script:
SetTitleMatchMode 2
Documentation
This allows you to use commands like WinExist with a partial window name match.

Automatically reload AutoHotkey script when modified

When testing AutoHotkey scripts, I sometimes forget to reload my scripts after making changes. This leads to me accidentally testing old, outdated versions of my scripts.
Instead of manually reloading the script, I would like to have scripts automatically reload if they have been modified.
How can I make AutoHotkey reload the current script any time a .ahk file is modified?
Somewhere near start of the script, in the auto-execute section
#SingleInstance force
FileGetTime ScriptStartModTime, %A_ScriptFullPath%
SetTimer CheckScriptUpdate, 100, 0x7FFFFFFF ; 100 ms, highest priority
Anywhere in the script (usually somewhere at the bottom):
CheckScriptUpdate() {
global ScriptStartModTime
FileGetTime curModTime, %A_ScriptFullPath%
If (curModTime == ScriptStartModTime)
return
SetTimer CheckScriptUpdate, Off
Loop
{
reload
Sleep 300 ; ms
MsgBox 0x2, %A_ScriptName%, Reload failed. ; 0x2 = Abort/Retry/Ignore
IfMsgBox Abort
ExitApp
IfMsgBox Ignore
break
} ; loops reload on "Retry"
}
This is how I've done it:
#If WinActive("AHK.ahk - Notepad") or WinActive("*AHK.ahk - Notepad")
~^s::
Reload
Return
#If
Checks if the current window is the script that I want autoreloaded whenever I hit Ctrl-S.
The ~ means the default action of Ctrl-S (saving the file) is preserved, and then we simply reload it.
I'm still new at AHK but here's what I've come with.
If you're using Notepad++ to edit AHKS this will run any ahk that's open and currently in focus in Notepad++ on saving with Ctrl-S and won't effect any other file types.
This script only has to be in one running ahk to work on all ahks being modified in Notepad++.
This can be used on multiple text editor programs too like win Notepad just get rid of the ++ associated with Notepad++
~^s:: ; Saves and Runs ANY AHK open in Notepad++
Sleep 150
WinGetTitle, Title, A
Needle := "ahk - Notepad++"
IfInString, Title, %Needle%
{
StringReplace, xxx, Title,- Notepad++, , All
run %xxx%
return
}
else
return

traytip when window becomes active?

I want to simply display a tooltip when a window becomes active.
Why doesn't this work? It launches the tooltip as soon as the script is loaded.
#IfWinActive, Untitled - Notepad
{
TrayTip, Notepad Has Focus, test
Tab::
MsgBox Window Found
return
}
Tab detection works as expected, it shows the Message Box only if the window is active.
As per the #If... docs, #IfWinActive creates context-sensitive hotkeys and hotstrings. To be a bit more precise, this is what happens when you use #IfWin...:
Whenever you press a hotkey or type a hotstring, AHK looks up the corresponding #IfWin... definition (if available) and evaluates it (e.g. "Is notepad active?"). If it is true, the hotkey/hotstring label will be executed, otherwise the native key will be sent.
Looking at this procedure, you will recognize that executing arbitrary code below a #IfWin... statement won't work; AHK doesn't fire an event when a specified window becomes active/existent etc, it rather checks the conditions when a corresponding hotkey/hotstring is fired.
Ergo, you will have to write code that waits for notepad, shows a notification and possibly repeats this procedure:
#Persistent
SetTimer, WaitForNotepad, -1
Exit
WaitForNotepad:
WinWaitActive, ahk_class Notepad
TrayTip, Warning, Notepad is active!
WinWaitNotActive
SetTimer, WaitForNotepad, -1
return
Please note that this would also work without SetTimer in some kind of loop. But whenever you're waiting a potentially large amount of time, it is reasonable to use timers, since they virtually allow other threads to run in between.
You also noticed that I used the window class (ahk_class) instead of the window title, since it's usually more reliable.

AHK script to monitor changes to a window title

AHK noob here. I'm looking to monitor 1-4 programs which run minimised for a specific change to the window title using autohotkey. When the change is detected in any of the programs, an alert pops up to alert the user of the change or the script could bring the program to the front.
The change in the window title (extracted using the AutoIt Spy tool) is from:
Lab - [Workspace... after this point the title text is dynamic
to either:
Lab - [Results ...etc
or simply
WARNING
The 4 programs are identical so as they're running out of separate folders stored as follows:
c:\program1\program.exe
c:\program2\program.exe
c:\program3\program.exe
c:\program4\program.exe
Could the PID be retrieved for each program so that the script can distinguish between the 4 and bring the correct one to the front? Any help from the community would be much appreciated.
Here is something, (not tested) to get you started...
SetTitleMatchMode, 1 ; A window's title must start with the specified WinTitle to be a match.
Settimer, CheckWindow, 1000
Return
CheckWindow:
Ifwinexists, ahk_class...... check the class first
{
IfWinExist, Lab - [Results
GoSub, MyAlert
IfWinExist, WARNING
GoSub, MyAlert
}
Return
MyAlert:
SoundBeep, 1000, 1000
Return
I see that you have expanded your question with the part discussing 4 similar .exe files. If you want to differentiate based on PID, you can use:
WinGet, active_id, ID, A ; A = active window...
WinMaximize, ahk_id %active_id%
MsgBox, The active window's ID is "%active_id%".
The fact that you ask this question is worrisome. one Google search AutoHotKey PID directs you to the answer. I am willing to help, but not your programmer!
Warning: If you edit your original question, we get no alert UNLESS you also write a new comment!