Using GUI Checkbox Controls to Set Hotstring Options (AutoHotkey Technique)

AutoHotkey Hotstrings Use a String of Characters to Turn Options On and Off—GUI Checkbox Controls Offer a Visual Display for the Active Options along with a Method for Enabling/Disabling Each Feature

Previously (in “The Coming Instant Hotstring Script (AutoHotkey App)“), we reviewed the work still needed in the InstantHotstring.ahk script. This time we implement Hotstring options using the Hotstring() function.

Converting GUI (Graphical User Interface) Checkbox controls into Hotstring options codes (and back again) involves adept programming tricks. We use GUI windows and their controls to make applications user-friendly. People find it much easier to push discreet buttons and check separate boxes than work directly with often enigmatic programming codes. That means we must build a method for translating between the user-friendly input in a GUI window and the required code.

AutoHotkey Hotstring Options

Library BenefitsHotstring options appear as a string of alphanumeric characters between the first two colons in the Hotstring statement:

:CB0*:GUI:: (Graphical User Interface)

When loading the Hotstring, AutoHotkey parses that character string to implement each option individually. The basic Hotstring includes no options (empty double-colon ::) but if we want it to do anything special, we implement features by adding option characters.

Note: Commonly, many Windows objects save attributes and other settings in a character string. For example, when accessing file attributes, we capture them as a string.

The InstantHotstrings.ahk script uses GUI Checkbox controls to add or remove Hotstring options. By checking a particular Checkbox and clicking the Set Hotstring button, we include specific Hotstring options in the active Hotstring (as displayed in the GUI DropDownList control shown below). Conversely, when we select another active Hotstring from the DropDownList control, AutoHotkey searches the option string and checks (or unchecks) the associated Checkbox controls. It’s a two-way street: the Checkbox controls to make it easy for the user to select/deselect Hotstring options and the options string embedded in the Hotstring statement from the selected DropDownList control works with the AutoHotkey Hotstring() function.

instanthotstringoptions2
When clicking the Set Hotstring button, each Hotstring Options Checkbox control adds its character(s) to the options string found between the first two colons in the Hotstring statement. Note the space at the beginning of the Text Replacement to ensure its inclusion whenever typing the characters “GUI” to cause Hotstring activation.

This reciprocal procedure requires two separate subroutines: one for writing the options string from the active Checkbox controls and another for setting the respective Checkbox controls with the options string when selecting (or adding) a DropDownList entry.

Using a GroupBox Control to Contain Checkbox Controls

In “Create Instant Hotstrings Using the AutoHotkey Hotstring() Function” and “Using the AutoHotkey Hotstring() Function to Disable/Enable Hotstrings“, we wrote a barebones script for activating instant standard Hotstrings. This time we implement Hotstring option codes in the InstantHotstrings.ahk script.

First, we add the various option Checkbox controls to our Hotstring GUI highlighted by a GroupBox control:

Gui, Hotstring:Add, GroupBox, section w400 h110
   , Hotstring Options
Gui, Hotstring:Add, CheckBox, vCaseSensitive xp+15 yp+25
   , Case Sensitive (C)
Gui, Hotstring:Add, CheckBox, vNoBackspace xp+210 yp+0
   , No Backspace (B0)
Gui, Hotstring:Add, CheckBox, vImmediate xp-210 yp+20
   , Immediate Execute (*)
Gui, Hotstring:Add, CheckBox, vInsideWord xp+210 yp+0
   , Inside Word (?)
Gui, Hotstring:Add, CheckBox, vNoEndChar xp-210 yp+20
   , No End Char (O)
Gui, Hotstring:Add, CheckBox, vRaw xp+210 yp+0
   , Raw Text (R)
Gui, Hotstring:Add, CheckBox, vExecute xp-120 yp+20
   , Labels/Functions (X)

I’ve enclosed the Checkbox controls in a GroupBox control for two reasons:

  1. Display purposes. The GroupBox control sets off the Checkbox controls by adding a heading and a light outline around the controls.
  2. Convenience when relocating the entire set of controls. While the GroupBox control actually does nothing to contain the Checkbox controls, since each Checkbox uses relative positioning in placement (e.g. xp+210 yp+0), whenever we move the GroupBox control, the entire set of Checkbox controls moves with it. (Discussed in more detail in Chapter Thirteen of my book AutoHotkey Application.)

I’ve assigned a vVariable options to each CheckBox control to hold its value (1 for checked or 0 for unchecked).

Note: I’ve only included the most used Hotstring option codes in InstantHotstrings.ahk. If needed, you can add more by adding the appropriate code as shown in this blog.

Writing the Hotstring Options String from the Checkbox Controls

In the script, wherever AutoHotkey needs to write the Hotstring options string, I inserted a call to the OptionsString subroutine:

GoSub OptionString  ; Writes the Hotstring options string

By containing the subroutine with a separate Label name (OptionString), I can add it to the script wherever its needed without writing redundant code. Currently, the script only uses the subroutine once. However, future expansion may require its separate use—plus, I find it easier to work on individual subroutines—especially as the complication inevitably grows.

In the OptionString subroutine, the variable Options contains the growing string while appending the option characters. This script uses the ternary operator (?:) to check the value of each Checkbox and concatenate the appropriate character(s) to the string:

OptionString:

Options := ""

Options := CaseSensitive = 1 ? Options . "C"
     : (Instr(OldOptions,"C1")) ?  Options . "C0"
     : (Instr(OldOptions,"C0")) ?  Options
     : (Instr(OldOptions,"C")) ? Options . "C1" : Options

Options := NoBackspace = 1 ?  Options . "B0" 
   : (NoBackspace = 0) and (Instr(OldOptions,"B0"))
   ? Options . "B" : Options

Options := (Immediate = 1) ?  Options . "*" 
     : (Instr(OldOptions,"*0")) ?  Options
     : (Instr(OldOptions,"*")) ? Options . "*0" : Options

Options := InsideWord = 1 ?  Options . "?" : Options

Options := (NoEndChar = 1) ?  Options . "O"
     : (Instr(OldOptions,"O0")) ?  Options
     : (Instr(OldOptions,"O")) ? Options . "O0" : Options
 
Options := Raw = 1 ?  Options . "R" 
     : (Instr(OldOptions,"R0")) ?  Options
     : (Instr(OldOptions,"R")) ? Options . "R0" : Options
Options := Execute = 1 ?  Options . "X" : Options

Return

The original code I wrote used a series of If conditional statements to perform the same function as the above ternary statements. (See the blogs “AutoHotkey Toggles and the Ternary Operator (Beginning Hotkeys Part 18)” or “Use the Ternary Operator to Create Conditional Case Statements or Switches (AutoHotkey Tip)” for more information on the ternary operator.) The AddHotstring routine which calls the OptionString subroutine uses the Gui, Submit command to load the Options values built from the Checkbox controls into the respective Hotstring.

Plus, if AutoHotkey finds the same Hotstring in the DropDownList, then it saves its options string to the variable OldOptions. We need the old options to know how to change the new options string. (See the AddHotstring subroutine discussed in “Create Instant Hotstrings Using the AutoHotkey Hotstring() Function” with the OldOptions variable as shown in the current InstantHotstring.ahk script.)

ControlGet, Items, List,, ComboBox1, A
Loop, Parse, Items, `n
{
  If InStr(A_LoopField, ":" . NewString . "::", CaseSensitive)
  {
    HotString := StrSplit(A_LoopField, ":")
    OldOptions := HotString[2]
    Control, Delete, %A_Index% , ComboBox1
    Break
  }
}

Hotstring Option Peculiarities

First, by default, Hotstrings include no option characters. However, for most options, once you activate it using the Hotstring() function, you must first deactivate its effect before you can remove it from the options string. For example, you can add immediate execution by including the * character. However, you cannot undo that effect by merely removing the option from the Hotstring statement. First, you must deactivate it using the *0 option. Then, on any other reactivation, you can remove the *0 characters.

Depending on the options activated, the cascading ternary operators modify the option string in a progression. Any activated option requiring that you turn it off before completely removing it, first adds the deactivation option (e.g. *0). Then, in order to keep the option string as short as possible, AutoHotkey eliminates those characters on the next resetting of the Hotstring. This helps to keep the options string short by eliminating unnecessary characters.

Only the case sensitivity C option requires special handling. To add complete case insensitivity we use the option C1. (The default Hotstring yields an initial cap and all caps depending on the case of the keyed-in activating string.) To completely eliminate case sensitivity, use the C1 option. To restore the default behavior, use the C0 option. While I found it easy enough to add C1 for case insensitivity to the cascading ternary operator (C1C0[characters removed]), once set, retaining the C1 option when setting other options requires special considerations—now a topic for a future blog.

Second, per the online documentation, we must deactivate Hotstings including the C or ? option prior to resetting each:

However, since hotstrings with C or ? are considered distinct from other hotstrings, it is not possible to add or remove these options. Instead, turn off the existing hotstring and create a new one.

Before activating the altered C or ? Hotstring, I inserted the following code into the AddHotstring subroutine:

If (CaseSensitive or InsideWord or InStr(OldOptions,"C") 
   or InStr(OldOptions,"?"))
Hotstring(":" . OldOptions . ":" . NewString,TextInsert,"Off")

Third, by default, AutoHotkey backspaces to delete the activating text. Add the B0 option to turn off this default backspace. Use B to add it back. Opposite from how the other Hotstring options work, after returning backspacing to its default behavior, the backspace ternary operator removes the B on the second click of the Set Hotstring button.

Fourth, I don’t know if it’s a bug, but, before it takes effect, the X option requires setting the Hotstring() function twice for a new Hotstring. I eliminated the problem by adding a repeat call to the Hotstring() function for any X option. (A future blog will discuss how to use the X option with the Hotstring() function.)

Initially, the InstantHotstring.ahk script adds no options to the string. Only clicking one of the options Checkbox controls, then the Set Hotstring button activates an option.

Next, we write the subroutine for setting the Checkbox controls from the DropDownList control’s options string. The script uses this SetOptions subroutine twice: once when selecting another Hotstring from the DropDownList control and once when reading and loading Hotstrings from an external file.

Set CheckBox Controls from the DropDownList Hotstring Options String

When the InstantHotstring.ahk window contains any Hotstrings, the DropDownList control allows the user to access one of them by selecting it from the list. Upon selection, the script must load the various options settings (on or off) into the appropriate Checkbox controls. After parsing the selected Hotstring statement from the DropDownList control, the script loads the values into the respective GUI controls:

HotString := StrSplit(Select, ":")
GuiControl, , Edit1, % HotString[3]
GuiControl, , Edit2, % HotString[5]

GoSub SetOptions

The first two Edit controls load directly from the parsed Hotstring. The SetOptions subroutine marks each Checkbox controls as appropriate. The original SetOptions subroutine used a series of If-Else conditional statements:

SetOptions:

If Instr(Hotstring[2],"C")
  Control,Check, , Button2, A ; Case
Else
  Control,Uncheck, , Button2, A ; Case

If Instr(Hotstring[2],"B0")
  Control,Check, , Button3, A ; No Backspace
Else
  Control,Uncheck, , Button3, A ; Backspace

If Instr(Hotstring[2],"*0") or (InStr(Hotstring[2],"*") = 0)
  Control, Uncheck, , Button4, A ; Not Immediate
Else
  Control, Check, , Button4, A ; Immediate

If Instr(Hotstring[2],"?")
  Control,Check, , Button5, A ; Inside Word
Else
  Control,Uncheck, , Button5, A ; Inside Word

If Instr(Hotstring[2],"O0") or (InStr(Hotstring[2],"O") = 0)
  Control, Uncheck, , Button6, A ; No EndChar
Else
  Control, Check, , Button6, A ; EndChar

If Instr(Hotstring[2],"R0") or (InStr(Hotstring[2],"R") = 0)
  Control, Uncheck, , Button7, A ; Raw
Else
  Control, Check, , Button7, A ; No Raw

If Instr(Hotstring[2],"X0") or (InStr(Hotstring[2],"X") = 0)
  Control, Uncheck, , Button8, A ; Execute
Else
  Control, Check, , Button8, A ; No Execute

Return

To shorten the amount of required code (while fixing a couple of other issues), I switched the SetOptions subroutine to a series of ternary conditionals calling a function which sets each button appropriately:

SetOptions:

OptionSet := ((Instr(Hotstring[2],"C0")) or (Instr(Hotstring[2],"C1")) 
    or (Instr(Hotstring[2],"C") = 0)) 
    ? CheckOption("No",2) : CheckOption("Yes",2)
OptionSet := Instr(Hotstring[2],"B0") ? CheckOption("Yes",3) 
    : CheckOption("No",3)
OptionSet := Instr(Hotstring[2],"*0") or InStr(Hotstring[2],"*") = 0 
    ? CheckOption("No",4) : CheckOption("Yes",4)
OptionSet := Instr(Hotstring[2],"?") ? CheckOption("Yes",5) 
    : CheckOption("No",5)
OptionSet := (Instr(Hotstring[2],"O0") or (InStr(Hotstring[2],"O") = 0)) 
    ? CheckOption("No",6) : CheckOption("Yes",6)
OptionSet := (Instr(Hotstring[2],"X0") or (InStr(Hotstring[2],"X") = 0)) 
    ? CheckOption("No",8) : CheckOption("Yes",8)

Return

The CheckOption() function:

CheckOption(State,Button)
{
If (State = "Yes") 
Control, Check, , Button%Button%, A
Else 
Control, Uncheck, , Button%Button%, A
}

The ternary operators and CheckOption() function replace the redundant use of the Control, Check/Uncheck command in the original subroutine.

You can find the current InstantHotstring.ahk script in its entirety at the ComputorEdge Free AutoHotkey Scripts page.

Next time, I plan to demonstrate a couple of beginning tricks using Hotstring options.

Click the Follow button at the top of the sidebar on the right of this page for e-mail notification of new blogs. (If you’re reading this on a tablet or your phone, then you must scroll all the way to the end of the blog—pass any comments—to find the Follow button.)

jack

This post was proofread by Grammarly
(Any other mistakes are all mine.)

(Full disclosure: If you sign up for a free Grammarly account, I get 20¢. I use the spelling/grammar checking service all the time, but, then again, I write a lot more than most people. I recommend Grammarly because it works and it’s free.)

Advertisements

One thought on “Using GUI Checkbox Controls to Set Hotstring Options (AutoHotkey Technique)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s