Thank you swagfag. I am pretty sure this can't be done, at least not without starting my script from scratch, but I would be happy for a second opinion.
My script is supposed to be a text expansion and replacement app. It draws these replacements from the strings.txt file. Each (non empty) line in that file contains a trigger string, a group of optional settings to determine how the app handles the replacement for that string, and the text to be inserted. There can also be instruction tags for inserting date, time user input and clipboard content.
As it is now the code includes a number of subroutines and functions that are not at all relevant to what I was trying to do. Some of them are outright broken, but again that's not relevant. The code is also messy, with useless remnants left behind from stuff I stripped out for testing and to post on the forum.
The only code that matters is the main Input Loop near the top, and left/right mouse hotkey below it.
When that code is run in AHK_H the triggers are added to the matchlist variable, a "strings" associative array us created using trigger strings as keys and the insertion text as values, and an "options" associative array is created using trigger strings as keys and the options that go with those strings as values.
when the Input triggers, the code checks if the string variable contains a legitimate trigger string by seeing if there is an array value associated with that array key. It also checks any options for that string. If the string matches and there is no endkey option for it the script sends backspace a number of times equal to the length of the trigger string then sends the replacement text associated with that string. If the string matches but there is an endkey option the script does nothing, waiting for further input. This is where I need the A option under AHK_H. Since the Input's variable isn't overwritten if you then hit any endkey the code can see that the trigger string still matches, AND that the required endkey was hit. When that happens the script sends backspace equal to the trigger string + 1 for the end key, then sends the replacement text. There is also a case where one trigger may be identical to the beginning of a second trigger, such as "test" and "testing". In this case you must set an endkey for the shorter trigger, else the longer trigger will never be executed. It is this special case that I cannot work around with code AFTER the Input command. It simply requires the Input command to still have the correct trigger in its variable when the endkey is hit. I can't see any way around that.
As I said, I don't see a way around needing _H without completely starting over and doing EVERYTHING in code instead of relying on matchlist and endkey for the Input command.
LONG STORY. Input/InputHook(), Hotstring(), AHK_H, ETC
- dmg
- Posts: 287
- Joined: 02 Oct 2013, 01:43
- Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
- Contact:
Re: LONG STORY. Input/InputHook(), Hotstring(), AHK_H, ETC
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
- dmg
- Posts: 287
- Joined: 02 Oct 2013, 01:43
- Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
- Contact:
Re: LONG STORY. Input/InputHook(), Hotstring(), AHK_H, ETC
Ok... I thought about what would be needed to convert my code to not rely on the Input command as much. I realized a couple of things, and wrote a little test code... Then modified my script, and it looks like it works??? It can't be that easy!
All I did was eliminate the matchlist, add L1 as an option so Input triggers on each character, add a middleman variable that appends each time the Input triggers, and add a backspace hotkey to allow removal of typed characters from the middleman variable... that's it! I have not tested it much but it already seems to work better than my previous attempts. If anybody can see a flaw I'd like to know. The above code should run in the current version of AHK standard, along with the settings and strings files I previously posted.
Cheers!
Code: Select all
#singleinstance, ignore
#installkeybdhook
setbatchlines, -1
setworkingdir, %a_scriptdir%
menu, tray, nostandard
menu, tray, tip, Auctus
menu, tray, add, Strings, manage_strings
menu, tray, add, Settings, settings_gui_show
menu, tray, add, About, about_gui
menu, tray, add
menu, tray, add, Exit, exit
menu, tray, default, strings
global format_time, format_date, sound, prompt
gosub, get_strings
gosub, get_settings
gosub, strings_gui_create
gosub, settings_gui_create
loop
{
input, characters, l1iv, {space}{tab}{enter}{left}{up}{right}{down}
string .= characters
key := substr(errorlevel, 8)
e := instr(options["" . string], "e")
s := instr(options["" . string], "s")
t := instr(options["" . string], "t")
x := instr(options["" . string], "x")
;msgbox, String: %string% `nErrorLevel: %errorlevel% `nKey: %key%
if (strings["" . string])
{
if (options["" . string] = "")
{
gosub, set_settings
send, % "{bs " . (strlen(string)) . "}" . _insert(_replace(strings["" . string], 1), 1)
string := ""
}
else if (e && key = "enter") or (s && key = "space") or (t && key = "tab")
{
gosub, set_settings
send, % "{bs " . (strlen(string)) + 1 . "}" . _insert(_replace(strings["" . string], 1), 1) . "{" . (x ? "" : key) . "}"
}
}
if (key)
{
string := ""
}
}
~rbutton::
~lbutton::
{
input
}
return
~backspace::
{
string := substr(string, 1, strlen(string) - 1)
}
return
get_strings:
{
fileread, text, strings.txt
options := {}, strings := {}, match := ""
loop, parse, text, `n, `r
{
if (a_loopfield != "")
{
pos1 := instr(a_loopfield, "|", 0, 1, 1)
pos2 := instr(a_loopfield, "|", 0, 1, 2)
options.insert("" . substr(a_loopfield, 1, pos1 - 1), substr(a_loopfield, pos1 + 1, pos2 - pos1 - 1))
strings.insert("" . substr(a_loopfield, 1, pos1 - 1), substr(a_loopfield, pos2 + 1))
}
}
match := rtrim(match, ",")
}
return
strings_gui_create:
{
gui, 1:font, s8
gui, 1:+delimiter`,
gui, 1:add, listbox, sort x10 y10 w100 h230 vstrings_list gselected_string
gui, 1:add, edit, x120 y10 w330 h160 vsel_insert
gui, 1:add, edit, x10 y240 w100 h20 vsel_string
gui, 1:add, groupbox, x120 y180 w155 h50 , Triggers
gui, 1:add, checkbox, x130 y200 w50 h20 vtrig_e, Enter
gui, 1:add, checkbox, x180 y200 w50 h20 vtrig_s, Space
gui, 1:add, checkbox, x230 y200 w40 h20 vtrig_t, Tab
gui, 1:add, groupbox, x285 y180 w165 h50 , Options
gui, 1:add, checkbox, x295 y200 w60 h20 vopt_c, Use Clip
gui, 1:add, checkbox, x355 y200 w86 h20 vopt_x, Exclude trigger
gui, 1:add, button, x120 y240 w60 h20 gstrings_clear, Clear
gui, 1:add, button, x270 y240 w60 h20 , Delete
gui, 1:add, button, x330 y240 w60 h20 gstrings_save, Save
gui, 1:add, button, x390 y240 w60 h20 gstrings_done, Done
}
return
manage_strings:
{
guicontrol, 1:, strings_list, ,%match%
gui, 1:show, w460 h270, Manage strings
}
return
selected_string:
{
gui, 1:submit, nohide
sel_insert := strings["" . strings_list]
e := instr(options["" . strings_list], "e")
s := instr(options["" . strings_list], "s")
t := instr(options["" . strings_list], "t")
c := instr(options["" . strings_list], "c")
x := instr(options["" . strings_list], "x")
guicontrol, 1:, trig_e, % e ? 1 : 0
guicontrol, 1:, trig_s, % s ? 1 : 0
guicontrol, 1:, trig_t, % t ? 1 : 0
guicontrol, 1:, opt_c, % c ? 1 : 0
guicontrol, 1:, opt_x, % x ? 1 : 0
guicontrol, 1:, sel_insert, %sel_insert%
guicontrol, 1:, sel_string, %strings_list%
}
return
strings_clear:
{
guicontrol, 1:, strings_list, ,%match%
guicontrol, 1:, trig_e, 0
guicontrol, 1:, trig_s, 0
guicontrol, 1:, trig_t, 0
guicontrol, 1:, opt_c, 0
guicontrol, 1:, opt_x, 0
guicontrol, 1:, sel_insert
guicontrol, 1:, sel_string
}
return
guiclose:
strings_done:
{
gui, 1:cancel
gosub, strings_clear
}
return
strings_save:
{
gui, 1:submit
e := trig_e ? "e" : ""
s := trig_s ? "s" : ""
t := trig_t ? "t" : ""
c := opt_c ? "c" : ""
x := opt_x ? "x" : ""
new_string := sel_string . "|" . e s t c x . "|" . sel_insert
;msgbox, % new_string
fileappend, %new_string%, strings.txt
}
return
settings_gui_create:
{
gui, 2:font, s8
gui, 2:add, groupbox, x10 y10 w70 h85, Method
gui, 2:add, radio, x20 y30 w40 h20 vmethod1, Input
gui, 2:add, radio, x20 y50 w50 h20 vmethod2, Event
gui, 2:add, radio, x20 y70 w40 h20 vmethod3, Play
gui, 2:add, checkbox, x20 y100 w50 h20 vsound, Sound
gui, 2:add, groupbox, x90 y10 w210 h50, Press
gui, 2:add, text, x100 y30 w40 h20 , Delay:
gui, 2:add, edit, x140 y30 w45 h20 vdelay
gui, 2:add, text, x195 y30 w50 h20 , Duration:
gui, 2:add, edit, x245 y30 w45 h20 vduration
gui, 2:add, groupbox, x90 y70 w210 h50, Formats
gui, 2:add, text, x100 y90 w30 h20 , Date:
gui, 2:add, edit, x130 y90 w60 h20 vformat_date
gui, 2:add, text, x200 y90 w30 h20 , Time:
gui, 2:add, edit, x230 y90 w60 h20 vformat_time
gui, 2:add, button, x10 y130 w50 h20 gsettings_default, Default
gui, 2:add, button, x200 y130 w50 h20 gcancel_settings, Cancel
gui, 2:add, button, default x250 y130 w50 h20 gsave_settings, Save
}
return
settings_gui_show:
{
guicontrol, 2:, format_date, %format_date%
guicontrol, 2:, format_time, %format_time%
guicontrol, 2:, sound, %sound%
guicontrol, 2:, method%method%, 1
guicontrol, 2:, delay, %delay%
guicontrol, 2:, duration, %duration%
gui, 2:show, w310 h160, Settings
}
return
get_settings:
{
iniread, format_date, settings.ini, settings, date, dd-MM-yy
iniread, format_time, settings.ini, settings, time, h:mmtt
iniread, sound, settings.ini, settings, sound, 1
iniread, method, settings.ini, settings, method, 1
iniread, delay, settings.ini, settings, delay, -1
iniread, duration, settings.ini, settings, duration, -1
format_time := format_time = "" ? "h:mmtt" : format_time
format_date := format_date = "" ? "dd-MM-yy" : format_date
sound := sound = "" ? 1 : sound
method := method = "" ? 1 : method > 3 ? 1 : method
delay := delay = "" ? -1 : delay
duration := duration = "" ? -1 : duration
gosub, set_settings
}
return
set_settings:
{
if (method = 1)
{
sendmode, input
}
else if (method = 2)
{
sendmode, event
}
else if (method = 3)
{
sendmode, play
}
if (method = 2)
{
setkeydelay, %delay%, %duration%
}
else if (method = 3)
{
setkeydelay, %delay%, %duration%, play
}
}
return
save_settings:
{
gui, 2:submit
iniwrite, %format_date%, settings.ini, settings, date
iniwrite, %format_time%, settings.ini, settings, time
iniwrite, %sound%, settings.ini, settings, sound
method := method1 ? 1 : method2 ? 2 : method3 ? 3 : ""
iniwrite, %method%, settings.ini, settings, method
iniwrite, %delay%, settings.ini, settings, delay
iniwrite, %duration%, settings.ini, settings, duration
gosub, set_settings
}
return
settings_default:
{
guicontrol, 2:, format_date, dd-MM-yy
guicontrol, 2:, format_time, h:mmtt
guicontrol, 2:, sound, 1
guicontrol, 2:, method1, 1
guicontrol, 2:, delay, -1
guicontrol, 2:, duration, -1
}
return
2guiclose:
cancel_settings:
{
gui, 2:cancel
}
return
about_gui:
{
if (about_gui != 1)
{
gosub, get_about
gui, 3:font, s8
gui, 3:add, button, x340 y275 w60 h20 ghome_site, Home
gui, 3:add, button, default x400 y275 w60 h20 g3guiclose, OK
gui, 3:add, edit, +readonly vscroll x10 y10 w450 h260, %about%
gui, 3:show, center w470 h300, About Auctus
about_gui := 1
}
else
{
gui, 3:destroy
about_gui := 0
}
}
return
get_about:
{
about :=
(
""
)
}
return
home_site:
{
msgbox, Home page not yet created...
;run, http://crzyinc.weebly.com/Auctus.html
}
return
3guiclose:
{
gui, 3:destroy
about_gui := 0
}
return
_replace(text, flag)
{
if (flag)
{
stringreplace, text, text, ``n, `n, 1
stringreplace, text, text, #, {#}, 1
stringreplace, text, text, !, {!}, 1
stringreplace, text, text, ^, {^}, 1
stringreplace, text, text, +, {+}, 1
}
else
{
stringreplace, text, text, ``n, `r`n, 1
}
return text
}
_insert(text, flag)
{
stringreplace, na, text, {prompt}, , useerrorlevel
total := errorlevel
loop, % total
{
prompt := ""
gui, 4:font, s8
gui, 4:add, edit, x10 y10 w270 h120 vprompt
gui, 4:add, button, x180 y140 w50 h20 gprompt_skip, Skip
gui, 4:add, button, default x230 y140 w50 h20 gprompt_go, Go
gui, 4:show, w290 h170, Input %a_index% of %total%
winwaitclose, Input %a_index% of %total%
}
formattime, time, , %format_time%
formattime, date, , %format_date%
stringreplace, text, text, {clip}, %clipboard%, 1
if (flag)
{
stringreplace, text, text, `r`n, `n, 1
}
stringreplace, text, text, {time}, %time%, 1
stringreplace, text, text, {date}, %date%, 1
if (sound)
{
soundplay, sound.wav
}
return text
4guiclose:
prompt_skip:
{
gui, 4:destroy
stringreplace, text, text, {prompt}, %prompt%, 0
}
return
prompt_go:
{
gui, 4:submit
gui, 4:destroy
stringreplace, text, text, {prompt}, %prompt%, 0
}
return
}
exit:
exitapp
Cheers!
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
Who is online
Users browsing this forum: Chunjee, dinodragon, Google [Bot], mikeyww and 284 guests