Close GUI but continue script in AHK - autohotkey

I'm trying to have a gui close but leave the script running. This is because I want to do other actions if the user chooses to escape the GUI by either hitting esc or simply clicking the 'X' in the upper right. I don't understand how I would leave the script running but close the gui. GUI close doesn't seem to do anything when clicking esc or the X. I've scanned through the GUI docs and cannot figure it out. They always run exitapp, but I'm not ready to exitapp, I need to do other things.
Gui, Add, Text, ,To cancel, press ESCAPE or close this window.
Gui, Show, w320 h80, Downloads
GuiClose:
GuiEscape:
; Continue on to do other things here!!!!
WinActivate ahk_exe notepad++.exe
; do things...
exitapp

What you're describing sounds like what I wanted to do, too. It was a lot of slogging and piecemealing but I think what you are looking for is Gui, Cancel Take a look at the code below and see if that doesn't solve your problem.
It doesn't use ExitApp and it doesn't destroy the window if you want to pop it up later. You'll have to figure how to place the rest of your code, but I believe this is what you are asking.
;Set the GUI window
Gui, Add, Text,, Hit Escape to Clear window when it is active
#F9:: ;show the window with WindowsKey-F9
Gui, Show,
return
;set the escape key to clear GUI window
GuiEscape: ; Note: single colon here, not double
Gui, Cancel
Return
It's a little trickier if you have multiple GUI windows. You must name each:
;Set the two GUI windows. In example, First is labeled as FirstGUI and second as SecondGUI. Notice how you separate with single colon.
Gui, FirstGUI:Add, Text,, Hit Escape to Clear FirstGUI window when it is active
Gui, SecondGUI:Add, Text,, Hit Escape to Clear SecondGUI window when it is active
#F9:: ;show the two windows ("xCenter y700" is used to prevent the windows from stacking.)
Gui, FirstGUI:Show, xCenter y700, Window Title of First GUI
Gui, SecondGUI:Show, xCenter y900, Window Title of Second GUI
return
;set the escape key to clear for each Gui independently.
FirstGUIGuiEscape: ; Note that you must add the Gui Name (FirstGUI) to the beginning of the "GuiEscape:" command and also name it in the following:
Gui, FirstGUI:Cancel
Return
SecondGUIGuiEscape: ; And here you must add SecondGUI as noted above.
Gui, SecondGUI:Cancel
Return
Answering a little late but hope this works for you or someone else!

They assume in the documentation that by clicking x, you'd want the script to close.
So they show ExitApp as an example.
If you don't want to do that though, of course no need to do it.
I think what you're after is destroying the gui:
GuiClose:
GuiEscape:
Gui, Destroy
return

Related

How to make it so you could change the hotkey in the GUI? - AutoHotkey

Code:
Gui, Add, Text,, ------------------------------------------Key Delay------------------------------------------
Gui, Add, Edit, w300 vKeyDelay, 100
Gui, Add, Text,, ------------------------------------------Key Input------------------------------------------
Gui, Add, Edit, R10 w300 vKeyPlayer
Gui, Add, Text,, ------------------------------------------Key Start------------------------------------------
Gui, Add, Edit, w300 vStartKey, F2
Gui, Show
F2::
!F2::
Gui, Submit, Nohide
SetKeyDelay, %KeyDelay%
Send, %KeyPlayer%
return
GuiClose:
ExitApp
The start key is set to F2, i want to make it so people are able to change it to whatever, (F1, F2, F3, A, B, C, 1-10, etc)
How to make it so you could change the hotkey in the gui?
You'd use the Hotkey command to create a hotkey during runtime.
And to choose the hotkey in the gui, the easiest (but not best) option would be the hotkey control.
It's surely the easiest one that's also convenient for the end user, but it doesn't support anything beyond just regular hotkeys. For better approaches, you'd need a custom one.
This was the first custom one I found with a Google search. Haven't used it myself, but it might be good stuff.
A very easy, but powerful, custom one you could also use is just a Edit control. Works very well if you expect your end users to be smart enough to type stuff like !F1, +#k, d & o, or whatever.
Anyway, I'll demonstrate here the usage of the built in hotkey control. Stop reading now if you want to figure it out yourself.
First, create the gui and associate a variable and a g-label to the hotkey control.
Though, I'm going to use a function instead of a label, I don't like writing legacy AHK.
Gui, Add, Hotkey, % "x50 y25 w90 h30 vChosenHotkey gHotkeyChanged"
Gui, Show, % "w200 h100"
Return
Then the g-label HotkeyChanged needs to be defined, and I'll use a function instead of a label, as said above.
HotkeyChanged()
{
global ChosenHotkey
Gui, Submit, NoHide
Hotkey, % ChosenHotkey, MyHotkey, On
}
And when using a function, you have to worry about scopes, which is why global ChosenHotkey is specified.
There I'm telling the function that I'll use a variable defined outside of its scope.
If scopes are something you don't yet know of, and don't yet want to to learn about them, you can write legacy AHK and use a label and forget about all this.
To learn about scopes in programming in general, you can probably find something good from Google.
And to learn about them in AHK specifically, I have a previous answer about them here and here's the relevant documentation page.
Then I get the make the script update its associated variables with Gui, Submit, you already seem to know about this.
And then I get to the Hotkey command.
First parameter takes the hotkey to use, that's stored in the ChosenHotkey variable.
Second parameter a label/function name, or a function object. I'll use a function name MyHotkey.
And in the third parameter On is specified to turn the hotkey on and possibly replace any previous any previous hotkey that was in its place.
Then the function or label MyHotkey needs to be defined:
MyHotkey()
{
MsgBox, % "Hotkey pressed!"
}
And that's it.
If you want to save the previously used hotkey and then use it again when the script is restarted, there are many options all of which basically just boil down the idea of saving the hotkey to some file.
Here's the full script:
Gui, Add, Hotkey, % "x50 y25 w90 h30 vChosenHotkey gHotkeyChanged"
Gui, Show, % "w200 h100"
return
HotkeyChanged()
{
global ChosenHotkey
Gui, Submit, NoHide
Hotkey, % ChosenHotkey, MyHotkey, On
}
MyHotkey()
{
MsgBox, % "Hotkey pressed!"
}
GuiClose()
{
ExitApp
}

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

Paste into custom GUI with AHK

I have been working on this for a while and I have no idea how to fix this issue. I want to create a custom GUI in AutoHotKey (AHK), I would post ont he AHK Forums but I haven't been able to get my account to work so I am posting here (sorry if this is the wrong place). The ideal state is that I can paste in a list of indiscriminate length from a list, it is almost always return delimited, see the picture below. I would be happy with pasting 10 items in. I have built the GUI but I can not paste the values in with the shortcut Ctrl+v. All that happens is the first value goes into the first cell and I cannot figure out how to get the rest to paste in.
I need to be able to read the values into an array in the AHK when I click continue. Thanks for your help in advance. Below is my code to create the GUI.
Gui, Add, Text,, Please add the List that you want (10 Max at once)
Gui Add, Edit, vButton1,
Gui Add, Edit, vButton2,
Gui Add, Edit, vButton3,
Gui Add, Edit, vButton4,
Gui Add, Edit, vButton5,
Gui Add, Edit, vButton6,
Gui Add, Edit, vButton7,
Gui Add, Edit, vButton8,
Gui Add, Edit, vButton9,
Gui Add, Edit, vButton0,
Gui Add, Button, x200 y270 w88 h26 vButton02 gGoCont, Continue
Gui Add, Button, x290 y270 w88 h26 vButton03 gGoQuit, Cancel
Gui Show
return
GoCont:
{
MsgBox %Button1%
MsgBox %Button2%
}
return
GoQuit:
Gui Destroy
return
If you can stand a txt file with one name per line, called "names.txt" in the same folder as your ahk script, try something like this:
Add this to the top (it reads in your names.txt file one line at a time):
Loop, Read, names.txt
x%A_Index% := A_LoopReadLine
START EDIT (per comments):
Alternatively, if you already copied to the clipboard the several names from a spreadsheet or website table or other list, then put it this way:
Loop, parse, Clipboard, `n, `r
x%A_Index% := A_LoopField
Either way,
END EDIT
Then, replace all 10 of your edit box lines with these two lines:
Loop, 10 ; or more?
Gui Add, Edit, vButton%A_Index%, % x%A_Index%
The rest is just as you had it.
Let us know, Have fun,
Big thanks to #PGilm
Gui, PasteGUI:Add, Text,, Please add the Names that you want to Process.
Counter := 0
Loop, parse, Clipboard, `n, `r
{
x%A_Index% := A_LoopField
Counter++
}
Counter--
Loop, %Counter% ; Dynamic List length
Gui PasteGUI:Add, Edit, vButton%A_Index%, % x%A_Index%
Gui PasteGUI:Add, Button, x200 y270 w88 h26 vButton02 gGoCont Default, Continue
Gui PasteGUI:Add, Button, x290 y270 w88 h26 vButton03 gGoQuit, Cancel
Gui, PasteGUI:Show
}
Return
GoCont:
{
Loop, %Counter%
{
CODE TO PROCESS MY EACH NAME
}
MsgBox Done!
Gui Destroy
}
Return
GoQuit:
Gui Destroy
Return
Lastly if I want to add a keyboard shortcut to work then I mapped in one where I put the below line at the top of the code
PasteIn:
{
And then close the bracket at the end of the code and then add the shortcut. (the below can be added to the bottom of the code to work) this uses the Ctrl+v keyboard shortcut.
}
^v:: GoTo, PasteIn

Auto Hot Key: Strange behavior on ControlClick after Gui Submit

I have the following script that sends ControlClick + ControlSend to a window in background (while I'm working in another window). It works ok as expected.
SetTitleMatchMode 2
$F1::
sleep 1000
ControlClick, x400 y470, Notepad
ControlSend,, text, Notepad
return
The problem is: when I add a Gui on the script, the ControlClick behavior becomes odd once I close the Gui (with Submit or Destroy): If I'm working in a window A (Chrome for example) the ControlClick don't work in background anymore: it activates the window B (Notepad) like in the WinActivate command instead.
Here's the script with the issue (same as the previous one but with a simple Gui):
SetTitleMatchMode 2
Gui, Add, Text,, box
Gui, Add, Button, default, OK
Gui, Show, W300 H300
return
GuiClose:
ButtonOK:
Gui, Submit
return
$F1::
sleep 1000
ControlClick, x400 y470, Notepad
ControlSend,, text, Notepad
return
I'm on Windows Vista 32 bits, Autohotkey v1.1.25.01
I can't understand why the Gui Submit is changing the ControlClick bahavior. How can I fix this and let the ControlClick run in background just like it was without the Gui Submit/Destroy?
ps: both windows were maximized.
ControlClick is known to not be very reliable in certain cases. Take a look at the Reliability section in the ControlClick documentation, there are some things you can try:
To improve reliability -- especially during times when the user is
physically moving the mouse during the ControlClick -- one or both of
the following may help:
Use SetControlDelay -1 prior to ControlClick. This avoids holding
the mouse button down during the click, which in turn reduces
interference from the user's physical movement of the mouse.
Specify the string NA anywhere in the sixth parameter (Options) as
shown below:
SetControlDelay -1
ControlClick, Toolbar321, WinTitle,,,, NA
NA avoids marking the target window as active and avoids
merging its input processing with that of the script, which may
prevent physical movement of the mouse from interfering (but usually
only when the target window is not active). However, this method might
not work for all types of windows and controls.

AutoHotkey ControlFocus fails for Edit Control

I have a window, created by AutoHotkey, with one button and one edit control on it.
What I am trying to do is to bring back the input focus to the Edit control after I click the button. By means of WinSpy (many thanks to Robert Kuster), I have the following information about the Edit control.
Handle : 0x00330786 (changes every time I start the application)
Control ID : 4
Class : Edit
Window Title : some window title
Parent Window Class : AutoHotkeyGUI
Below is the statement I am using in my script.
ControlFocus, MyEdit, some window title
BTW, AutoHotkey help suggests to leave the control name and replace the window title with HWND of the target control as an alternative. Please guide on how to accomplish this.
Below is a piece of Autohotkey script using
GuiControl, Focus, ControlName
in order to change the input focus to the Edit control (namely Completion) after button "Show My Progress" is clicked.
%WinTitle% = some window title
Gui, Add, Text, vLabel cWhite, Reading Completion
Gui, Add, Edit, vCompletion ym w40 ; The ym option starts a new column of controls.
Gui, Add, Progress, vMyProgress w300 h30 xp+50 yp-5
Gui, Add, Button, xp yp+50, Show My Progress
GuiControl,, Completion, %iniCompletion%
Gui, Show, h140, %WinTitle%
ControlClick, Show My Progress, %WinTitle%
**GuiControl, Focus, Completion**
return
ButtonShowMyProgress:
Gui, Submit, NoHide ; Save the input from the user to each control's associated variable.
MyCompletionPercentage:=(Completion / (PageEnd-PageStart+1)) * 100
PercentageRounded:=Round(MyCompletionPercentage,0)
GuiControl,, MyProgress, %PercentageRounded%
**GuiControl, Focus, Completion**
return
Many thanks to MCL and BGM for their comments ...
If I understand correctly, you have your own GUI built with AHK. Why
don't you use GuiControl, Focus? – MCL
MCL has a point. The GuiControl is autohotkey's way of working with it's own controls. You would only use ControlFocus if you are working with controls for
external windows. MCL - maybe you should present that as an answer. – BGM