I have written a bunch of helper functions that give you an alternative to InputBox.
Some are alternatives to MsgBox and I use them for debugging.
Some of the functions I wrote for users in the Ask For Help section, others i have not posted yet.
I took inspiration from many forum members to write these functions.
I recently cleaned up the code and I want to share the result.
I hope that someone will find them useful. Enjoy!
Most recent update
BetterBox
Code: Select all
;-------------------------------------------------------------------------------
BetterBox(Title := "", Prompt := "", Default := "", Pos := -1) {
;-------------------------------------------------------------------------------
; custom input box allows to choose the position of the text insertion point
; return the entered text
;
; Title is the title for the GUI
; Prompt is the text to display
; Default is the text initially shown in the edit control
; Pos is the position of the text insertion point
; Pos = 0 => at the start of the string
; Pos = 1 => after the first character of the string
; Pos = -1 => at the end of the string
;---------------------------------------------------------------------------
static Result ; used as a GUI control variable
; create GUI
Gui, BetterBox: New, +LastFound, %Title%
Gui, -MinimizeBox
Gui, Margin, 30, 18
Gui, Add, Text,, %Prompt%
Gui, Add, Edit, w290 vResult, %Default%
Gui, Add, Button, x80 w80 Default, &OK
Gui, Add, Button, x+m wp, &Cancel
; main loop
Gui, Show
SendMessage, 0xB1, %Pos%, %Pos%, Edit1, A ; EM_SETSEL
WinWaitClose
Return, Result
;-----------------------------------
; event handlers
;-----------------------------------
BetterBoxButtonOK: ; "OK" button
Gui, Submit ; get Result from GUI
Gui, Destroy
Return
BetterBoxButtonCancel: ; "Cancel" button
BetterBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
BetterBoxGuiEscape: ; {Esc} pressed
Result := "BetterBoxCancel"
Gui, Destroy
Return
}
BtnBox
Code: Select all
;-------------------------------------------------------------------------------
BtnBox(Title := "", Prompt := "", List := "", Seconds := "") {
;-------------------------------------------------------------------------------
; show a custom MsgBox with arbitrarily named buttons
; return the text of the button pressed
;
; Title is the title for the GUI
; Prompt is the text to display
; List is a pipe delimited list of captions for the buttons
; Seconds is the time in seconds to wait before timing out
;---------------------------------------------------------------------------
; create GUI
Gui, BtnBox: New, +LastFound, %Title%
Gui, -MinimizeBox
Gui, Margin, 30, 18
Gui, Add, Text,, %Prompt%
Loop, Parse, List, |
Gui, Add, Button, % (A_Index = 1 ? "" : "x+10") " gBtn", %A_LoopField%
; main loop
Gui, Show
WinWaitClose,,, %Seconds%
If (ErrorLevel = 1) {
Result := "TimeOut"
Gui, Destroy
}
Return, Result
;-----------------------------------
; event handlers
;-----------------------------------
Btn: ; all the buttons come here
Result := A_GuiControl
Gui, Destroy
Return
BtnBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
Result := "WinClose"
Gui, Destroy
Return
BtnBoxGuiEscape: ; {Esc} pressed
Result := "EscapeKey"
Gui, Destroy
Return
}
EditBox
Code: Select all
;-------------------------------------------------------------------------------
EditBox(VarName, X := "", Y := "", Width := 400, Height := 200) {
;-------------------------------------------------------------------------------
; display a variable in an edit box
; no return value
;
; VarName is the name of the variable to show
; VarName is also the title for the GUI
; X is the initial x coord of the GUI
; Y is the initial y coord of the GUI
; Width is the initial width of the GUI
; Height is the initial height of the GUI
;---------------------------------------------------------------------------
Coords := (X = "" ? "" : "x" X) (Y = "" ? "" : " y" Y)
; create GUI
Gui, EditBox: New, +LastFound, %VarName%
Gui, +Resize -MinimizeBox -MaximizeBox
Gui, Margin, 0, 0
Gui, Font, s12, Fixedsys Excelsior 3.01
Gui, Add, Edit, w%Width% h%Height% Multi, % %VarName% ; dynamic reference
; main loop
Gui, Show, %Coords%
SendMessage, 0xB1, -1,, Edit1, A ; EM_SETSEL
WinWaitClose
Return
;-----------------------------------
; event handlers
;-----------------------------------
EditBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
EditBoxGuiEscape: ; {Esc} pressed
Gui, Destroy
Return
EditBoxGuiSize:
GuiControl, Move, Edit1, w%A_GuiWidth% h%A_GuiHeight%
Return
}
IconBox
Code: Select all
;-------------------------------------------------------------------------------
IconBox(Title := "", Prompt := "", List := "", Icon := "", Owner := 0) {
;-------------------------------------------------------------------------------
; show a custom MsgBox with arbitrarily named buttons and an icon
; return the text of the button pressed
;
; Title is the title for the GUI
; Prompt is the text to display
; List is a pipe delimited list of buttons
; (a button starting with * is the default button)
; Icon I = info, Q = question, E = error, or a number from Shell32.dll
; Owner the GUI number or the GUI handle of the owner
;---------------------------------------------------------------------------
_DefaultGui := A_DefaultGui ; remember
Icon := Icon = "I" ? 222 : Icon = "Q" ? 24 : Icon = "E" ? 110 : Icon
; create GUI
Gui, IconBox: New, +LastFound, %Title%
Gui, -MinimizeBox
Gui, Margin, 30, 18
If Icon
Gui, Add, Picture, Icon%Icon%, Shell32.dll
Gui, Add, Text, % Icon ? "x+10" : "", %Prompt%
Loop, Parse, List, |
Gui, Add, Button
, % (A_Index = 1 ? "x+10" : "y+6") " w100 gBtn"
. (SubStr(A_LoopField, 1, 1) = "*" ? " Default" : "")
, % LTrim(A_LoopField, "*")
If Owner {
Gui, %Owner%: +Disabled
Gui, +Owner%Owner%
}
; main loop
Gui, Show
WinWaitClose
If Owner
Gui, %Owner%: -Disabled
Gui, %_DefaultGui%: Default ; restore
Return, Result
;-----------------------------------
; event handlers
;-----------------------------------
Btn: ; all the buttons come here
Result := A_GuiControl
Gui, Destroy
Return
IconBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
Result := "WinClose"
Gui, Destroy
Return
IconBoxGuiEscape: ; {Esc} pressed
Result := "EscapeKey"
Gui, Destroy
Return
}
ListBox
Code: Select all
;-------------------------------------------------------------------------------
ListBox(Title := "", Prompt := "", List := "", Select := 0) {
;-------------------------------------------------------------------------------
; show a custom input box with a ListBox control
; return the text of the selected item
;
; Title is the title for the GUI
; Prompt is the text to display
; List is a pipe delimited list of choices
; Select (if present) is the index of the preselected item
;---------------------------------------------------------------------------
static Result ; used as a GUI control variable
; create GUI
Gui, ListBox: New, +LastFound, %Title%
Gui, -MinimizeBox
Gui, Margin, 30, 18
Gui, Add, Text,, %Prompt%
Gui, Add, ListBox, w190 r10 vResult Choose%Select%, %List%
Gui, Add, Button, w80 Default, &OK
Gui, Add, Button, x+m wp, &Cancel
; main loop
Gui, Show
WinWaitClose
Return, Result
;-----------------------------------
; event handlers
;-----------------------------------
ListBoxButtonOK: ; "OK" button, {Enter} pressed
Gui, Submit ; get Result from GUI
Gui, Destroy
Return
ListBoxButtonCancel: ; "Cancel" button
ListBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
ListBoxGuiEscape: ; {Esc} pressed
Result := "ListBoxCancel"
Gui, Destroy
Return
}
LoginBox
Code: Select all
;-------------------------------------------------------------------------------
LoginBox(Title := "") {
;-------------------------------------------------------------------------------
; show a custom input box for credentials
; return an object with Username and Password
;
; Title is the title for the GUI
;---------------------------------------------------------------------------
static Name, Pass ; used as a GUI control variables
; create GUI
Gui, LoginBox: New, +LastFound, %Title%
Gui, -MinimizeBox
Gui, Margin, 30, 18
Gui, Add, Text, ym+4 w55, Username:
Gui, Add, Edit, x+10 yp-4 w100 vName
Gui, Add, Text, xm y+10 w55, Password:
Gui, Add, Edit, x+10 yp-4 w100 vPass Password
Gui, Add, Button, w80 Default, &OK
; main loop
Gui, Show
WinWaitClose
Return, Result
;-----------------------------------
; event handlers
;-----------------------------------
LoginBoxButtonOK: ; "OK" button, {Enter} pressed
Gui, Submit
Result := {Username: Name, Password: Pass}
Gui, Destroy
Return
LoginBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
Result := "WinClose"
Gui, Destroy
Return
LoginBoxGuiEscape: ; {Esc} pressed
Result := "EscapeKey"
Gui, Destroy
Return
}
MonoBox
Code: Select all
;-------------------------------------------------------------------------------
MonoBox(Title := "", Prompt := "", Font := "Consolas", Size := 11) {
;-------------------------------------------------------------------------------
; show a custom message box with monospaced font
; no return value
;
; Title is the title for the GUI
; Prompt is the text to display
; Font is the name of the font to use
; Size is the font size to use
;
; Note: The user may choose a non-monospaced font for displaying the text,
; but the function was written with monospaced fonts in mind.
;---------------------------------------------------------------------------
; create GUI
Gui, MonoBox: New, +LastFound, %Title%
Gui, -MinimizeBox
Gui, Margin, 30, 18
Gui, Font, s%Size%, %Font%
Gui, Add, Text,, %Prompt%
Gui, Font ; default
Gui, Add, Button, w80 Default, &OK
; main loop
Gui, Show
WinWaitClose
Return
;-----------------------------------
; event handlers
;-----------------------------------
MonoBoxButtonOK: ; "OK" button, {Enter} pressed
MonoBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
MonoBoxGuiEscape: ; {Esc} pressed
Gui, Destroy
Return
}
MultiBox
Code: Select all
;-------------------------------------------------------------------------------
MultiBox(Title := "", Prompt := "", Default := "") {
;-------------------------------------------------------------------------------
; show a multi-line input box
; return the entered text
;
; Title is the title for the GUI
; Prompt is the text to display
; Default is shown in the edit control
;---------------------------------------------------------------------------
static Result ; used as a GUI control variable
; create GUI
Gui, MultiBox: New, +LastFound, %Title%
Gui, -MinimizeBox
Gui, Margin, 30, 18
Gui, Add, Text,, %Prompt%
Gui, Add, Edit, w640 r10 vResult, %Default%
Gui, Add, Button, w80 Default, &OK
Gui, Add, Button, x+m wp, &Cancel
; main loop
Gui, Show
SendMessage, 0xB1, -1,, Edit1, A ; EM_SETSEL
WinWaitClose
Return, Result
;-----------------------------------
; event handlers
;-----------------------------------
MultiBoxButtonOK: ; "OK" button, {Enter} pressed
Gui, Submit ; get Result from GUI
Gui, Destroy
Return
MultiBoxButtonCancel: ; "Cancel" button
MultiBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
MultiBoxGuiEscape: ; {Esc} pressed
Result := "MultiBoxCancel"
Gui, Destroy
Return
}
NumberBox
Code: Select all
;-------------------------------------------------------------------------------
NumberBox(Title := "", Prompt := "") {
;-------------------------------------------------------------------------------
; show a custom input box for numbers incl. decimals and/or negative numbers
; return the entered number
;
; Title is the title for the GUI
; Prompt is the text to display
;---------------------------------------------------------------------------
static Result ; used as a GUI control variables
; create GUI
Gui, NumberBox: New, +LastFound, %Title%
Gui, -MinimizeBox
Gui, Margin, 30, 18
Gui, Add, Text,, %Prompt%
Gui, Add, Edit, w100 vResult gEditHandler
Gui, Add, Button, w80 Default, &OK
; main loop
Gui, Show
WinWaitClose
Return, Result
;-----------------------------------
; event handlers
;-----------------------------------
NumberBoxButtonOK: ; "OK" button, {Enter} pressed
Gui, Submit ; get Result from GUI
Gui, Destroy
Return
NumberBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
Result := "WinClose"
Gui, Destroy
Return
NumberBoxGuiEscape: ; {Esc} pressed
Result := "EscapeKey"
Gui, Destroy
Return
}
;-------------------------------------------------------------------------------
EditHandler(hEdit) { ; check for number incl. decimal point
;-------------------------------------------------------------------------------
static PrevNumber := [], Warning := "You can only enter a number!"
, BadNeedle := "[^\d\.-]|^.+-" ; allow negative numbers
ControlGet, Pos, CurrentCol,,, ahk_id %hEdit%
GuiControlGet, NewNumber,, %hEdit%
StrReplace(NewNumber, ".",, DotCount)
If NewNumber ~= BadNeedle Or DotCount > 1 { ; BAD
ControlGetPos, x, y,,,, ahk_id %hEdit%
ToolTip, %Warning%, x, y-20
SetTimer, ToolTipOff, -2000
GuiControl,, %hEdit%, % PrevNumber[hEdit]
SendMessage, 0xB1, % Pos-2, % Pos-2,, ahk_id %hEdit%
}
Else ; GOOD
PrevNumber[hEdit] := NewNumber
Return
ToolTipOff:
ToolTip ; off
Return
}
PassBox
Code: Select all
;-------------------------------------------------------------------------------
PassBox(Title := "", Prompt := "") {
;-------------------------------------------------------------------------------
; show a custom input box for a password
; return the entered password
;
; Title is the title for the GUI
; Prompt is the text to display
;---------------------------------------------------------------------------
static Result ; used as a GUI control variables
; create GUI
Gui, PassBox: New, +LastFound, %Title%
Gui, -MinimizeBox
Gui, Margin, 30, 18
Gui, Add, Text,, %Prompt%
Gui, Add, Edit, w100 vResult Password
Gui, Add, Button, w80 Default, &OK
; main loop
Gui, Show
WinWaitClose
Return, Result
;-----------------------------------
; event handlers
;-----------------------------------
PassBoxButtonOK: ; "OK" button, {Enter} pressed
Gui, Submit ; get Result from GUI
Gui, Destroy
Return
PassBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
Result := "WinClose"
Gui, Destroy
Return
PassBoxGuiEscape: ; {Esc} pressed
Result := "EscapeKey"
Gui, Destroy
Return
}
RadioBox
Code: Select all
;-------------------------------------------------------------------------------
RadioBox(Title := "", Prompt := "", List := "", WantNumeric := False) {
;-------------------------------------------------------------------------------
; show a custom input box with Radio buttons
; return the text/index of the selected choice
;
; Title is the title for the GUI
; Prompt is the text to display
; List is a pipe delimited list of choices
; WantNumeric determines if the result is numeric or textual
;
; Note: If the user clicks on the OK button without having made a choice,
; the function returns an empty string or 0.
;---------------------------------------------------------------------------
static Index ; used as a GUI control variable
; create GUI
Gui, RadioBox: New, +LastFound, %Title%
Gui, -MinimizeBox
Gui, Margin, 30, 18
Gui, Add, Text,, %Prompt%
Loop, Parse, List, |
Gui, Add, Radio, % A_Index = 1 ? "vIndex" : "", %A_LoopField%
Gui, Add, Button, w80 Default, &OK
Gui, Add, Button, x+m wp, &Cancel
; main loop
Gui, Show
WinWaitClose
Return, WantNumeric ? Index : Text
;-----------------------------------
; event handlers
;-----------------------------------
RadioBoxButtonOK: ; "OK" button, {Enter} pressed
Gui, Submit ; get Index from GUI
GuiControlGet, Text,, Button%Index%, Text
Gui, Destroy
Return
RadioBoxButtonCancel: ; "Cancel" button
RadioBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
RadioBoxGuiEscape: ; {Esc} pressed
Index := 0
Gui, Destroy
Return
}
TreeBox
Code: Select all
;-------------------------------------------------------------------------------
TreeBox(ArrName, X := "", Y := "", Width := 240, Height := 400, Wait := True) {
;-------------------------------------------------------------------------------
; display an array as tree, no return value
;
; ArrName is the name of the array to show
; X is the initial x coord of the GUI
; Y is the initial y coord of the GUI
; Width is the initial width of the GUI
; Height is the initial height of the GUI
;---------------------------------------------------------------------------
Coords := (X = "" ? "" : "x" X) (Y = "" ? "" : " y" Y)
; create GUI
Gui, TreeBox: New, +LastFound, TreeBox
Gui, +Resize -MinimizeBox -MaximizeBox
Gui, Margin, 0, 0
Gui, Add, TreeView, w%Width% h%Height%
; get the details
If IsCircular(%ArrName%)
TV_Add("Circular reference", TV_Add(ArrName,, "Expand"))
Else
PopulateTree(ArrName) ; recursive
; main loop
Gui, Show, %Coords%
IfEqual, Wait, %True%, WinWaitClose
Return
;-----------------------------------
; event handlers
;-----------------------------------
TreeBoxGuiClose: ; {Alt+F4} pressed, [X] clicked
TreeBoxGuiEscape: ; {Esc} pressed
Gui, Destroy
Return
TreeBoxGuiSize:
GuiControl, Move, SysTreeView321, w%A_GuiWidth% h%A_GuiHeight%
Return
}
;-------------------------------------------------------------------------------
PopulateTree(ArrName, ParentID := 0, Key := "") { ; populate the tree
;-------------------------------------------------------------------------------
static Value
Root := TV_Add(Key ? Key : ArrName, ParentID, "Expand")
For Key, Value in %ArrName%
If IsObject(Value)
PopulateTree("Value", Root, Key)
Else
TV_Add(Value, TV_Add(Key, Root, "Expand"))
}
;-------------------------------------------------------------------------------
IsCircular(oArray, Objs := 0, dummy := 0) { ; return true if oArray is circular
;-------------------------------------------------------------------------------
If Not Objs
Objs := {}
For each, Value in oArray
If IsObject(Value)
If Objs[&Value] Or IsCircular(Value, Objs, Objs[&Value] := 1)
Return, True
Return, False
}