I am somewhat leery of using memory only to accomplish this, but, well, here it is.
Only jeeswg's help (https://autohotkey.com/boards/viewtopic.php?f=5&t=47472) got me this far. I was having real trouble with passing parameters to functions with hotstring().
MS Word caused problems for me, but I have included a workaround that you yourself may not need if your Word Options don't have "Options->Advanced->Smart Cut and Paste" checked. So far it has worked fine in Excel and Wordpad.
Feedback appreciated.
Alt-F1: Show hotstrings and replacements
Click once on Tray icon, or Alt-Win-H: Add a new hotstring and replacement
Right-click on Tray icon for more options (e.g. add text directly)
Spoiler
Code: Select all
; InstantHotStringsArray12 (yikes!!!)
; Creates Hotstrings on-the-fly for inserting text into any document or
; Edit field — Jack Dunning
; https://jacksautohotkeyblog.wordpress.com/
; Modified from InstantHotkeyArray by Jack Dunning
; http://www.computoredge.com/AutoHotkey/Downloads/InstantHotkeyArrays.ahk
;
; By burque505
; April 17, 2018.
/*
CAUTION: This script keeps hotstrings and replacement text in memory.
It may be possible to cripple your clipboard with excessive hotstrings
or replacement text.
ToDo: Set variable capacity for the array, with a test to make sure it hasn't been
exceeded???
ToDo: Use clipboard for larger replacement texts (DONE!)
Many thanks to jeeswg for explaining the mysteries Func().bind()
for me (https://autohotkey.com/boards/viewtopic.php?f=5&t=47472)
*/
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
/*
This first label acts as the auto-execute section for the script. It initializes the
variable IH_Count which tracks the number of GUIs and Menu items.
At first, only the menu item "Instant Hotstring" appears in the System Tray icon right-click
menu. Once clicked, "Instant Hotstring" becomes the parent menu for the new GUIs and Hotstrings.
Set as the default, a click of the System Tray icon launches a new Instant Hotstring.
Combine with another script by adding "GoSub, InstantHotstring" to the auto-execute section of
the combo script (???) and "#Include, [path]\InstantHotstringsArray2.ahk" somewhere after the auto-
execute section of the master script.
*/
InstantHotstring:
IH_Count := 0
; One of the following array declarations must appear before using an array.
InstantHotstring := []
; InstantHotstring := {}
; InstantHotstring := Object()
; InstantHotstring := Array() ; Must use Array(), otherwise AutoHotkey thinks it's a function.
Menu, Tray, UseErrorLevel ; prevents various strange errors from stopping the script
Menu, HotstringMenu, Add, New Instant Hotstring, AddNewHotstring
Menu, Tray, Add, Instant Hotstrings, AddNewHotstring
Menu, Tray, Icon, InstantHotstring.ico, 1
Menu, Tray, Icon, Instant Hotstrings, InstantHotstring.ico, 1
Menu, HotstringMenu, Icon, New Instant Hotstring, C:\Windows\System32\shell32.dll, 319
Menu, Tray, Default, Instant Hotstrings
Menu, Tray, Click, 1
Menu, Tray, Tip, Click for New Instant Hotstring!
Return
/*
The subroutine AddNewHotkey setup a new GUI for creating an Instant Hotstring. It uses
the name "InstantHotstring" with IH_Count concatenated to create a pseudo array for tracking
GUI pop-ups.
*/
AddNewHotstring:
IH_Count++ ; Instant Hotstring GUI number
If IH_Count = 1
Menu, Tray, Add, Instant Hotstrings, :HotstringMenu
; Create a GUIName variable for naming new GUIs and act as a two-deep variable.
GUIName := "InstantHotstring" . IH_Count
Gui, %GUIName%: new ; Create a new GUI
Gui, %GUIName%:Add, Text,, Enter Hotstring
; The following hidden edit field tracks the GUI/menu item number.
Gui, %GUIName%:Add, edit, hidden ys vGuiNum,%IH_Count%
Gui, %GUIName%:Add, Edit, vHstring ys
Gui, %GUIName%:Add, Edit, w400 r8 vTextInsert xs, <Enter Hotstring Text>
Gui, %GUIName%:Add, Button, gSetupString , Set Hotstring
; The "Insert" option places the new menu item before "New Instant Hotstring"
; which preserves the matchup between the GUI numbers and menu item numbers.
Menu, HotstringMenu, Insert, New Instant Hotstring, %GUIName%, ShowHotstring
Menu, HotstringMenu, Icon, %GUIName%, InstantHotstring.ico, 1
Menu, InsertText, Add, %GUIName%, TrayTextAdd
Menu, InsertText, Icon, %GUIName%, InstantHotstring.ico, 1
; On the first run, attach submenus to Tray menu items.
If IH_Count = 1
{
Menu, Tray, Add, Instant Hotstrings, :HotstringMenu
Menu, Tray, Insert, Instant Hotstrings, Add Text, :InsertText
Menu, Tray, Icon, Add Text, InstantHotstring.ico, 1
Menu, Tray, Add, New Instant Hotstring, AddNewHotstring
Menu, Tray, Icon, New Instant Hotstring, C:\Windows\System32\shell32.dll, 319
Menu, Tray, Default, New Instant Hotstring
}
Gui, Show, , Instant Hotstring %IH_Count%
Return
SetupString:
Gui, Submit
; The array InstantHotstring[] saves the Hotstring 'Hstring'
; and the insertion text TextInsert.
If (InstantHotstring[GuiNum] != "" ) ; Turn off OldHotstring
{
Hotstring(":X*R:"Hstring, Func("TextAdd").Bind(TextInsert), "Off") ; fix
}
If Hstring !=
Hotstring(":X*R:"Hstring, Func("TextAdd").Bind(TextInsert), "On") ;fix here
; Create pseudo-array variable value for insertion text using Hotstring combination as key.
If Hstring !=
InstantHotstring[Hstring] := TextInsert
; Save Hotstring combination to InstantHotstring[] array.
InstantHotstring[GuiNum] := Hstring
; An ampersand (&) appended to a menu number calls that menu item.
Menu, InsertText, Rename, %GuiNum%& , % TextInsert
Menu, HotstringMenu, Rename, %GuiNum%& , % Hstring . " " . TextInsert
Return
TrayTextAdd:
SendInput, !{Escape} ; Jump to last window
SendInput, {raw}%A_ThisMenuItem%
Return
; The Hotstring text insertion subroutine now uses InstantHotstring[] array to insert
; the text using the most recently entered Hotstring (A_ThisHotkey) as the array key.
TextAdd(TextInsert) {
oldclip := Clipboard
clipboard := ""
Sleep, 0.3
clipboard := TextInsert
clipwait, 1 ; this may be excessive.
If (WinActive("ahk_class OpusApp"))
;***********************
;There appears to be an issue with the MS Word
;clipboard that requires this, discovered by trial
;and (MUCH) error. My cursory experiments with
;Excel have not required this, so perhaps it is
;not Office, but MS Word that requires it.
;Another possibility is my "Paste" settings in
;Word: I have "Use Smart Cut and Paste" checked
;in Options -> Advanced. This has created problems
;for me with other automation programs.
;***********************
{
send, ^c
send, ^c
}
Send, ^v
sleep, 1
clipboard := oldclip
}
Return
ShowHotstring:
Gui, InstantHotstring%A_ThisMenuItemPos%:show
Return
; Help window: active Hotstrings and their replacement text.
^F1::
HotstringHelp := "Hotstring: Insertion Text"
for index, element in InstantHotstring ; Recommended approach in most cases.
{
; Using "for", both the index (or "key") and its associated value
; are provided, and the index can be *any* value of your choosing.
; MsgBox % "Element number " . index . " is " . element
If index is integer
If element ; Hotstring not blank
HotstringHelp := % HotstringHelp . "`r" . Upper(element) . ": " . InstantHotstring[InstantHotstring[index]]
}
MsgBox % HotstringHelp
Return
;This code was adapted from Jack Dunnings's
;InstantHotkeyArrays at
;http://www.computoredge.com/AutoHotkey/Downloads/InstantHotkeyArrays.ahk
;The code below is a remnant, but needed for a function I didn't modify.
Upper(InputVar)
{
IfInString, InputVar, `+
StringReplace, InputVar, InputVar, `+ , SHIFT`+, all
IfInString, InputVar, `^
StringReplace, InputVar, InputVar, `^ , CTRL`+, all
IfInString, InputVar, `!
StringReplace, InputVar, InputVar, `! , ALT`+, all
StringUpper, OutputVar, InputVar
Return OutputVar
}
!#h::
gosub, AddNewHotString
return
Escape::ExitApp