w-mousekey 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/.editorconfig +9 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.js +55 -0
  4. package/.jsdoc +25 -0
  5. package/AutoHotkey_2.0.19/AutoHotkey.chm +0 -0
  6. package/AutoHotkey_2.0.19/AutoHotkey32.exe +0 -0
  7. package/AutoHotkey_2.0.19/AutoHotkey64.exe +0 -0
  8. package/AutoHotkey_2.0.19/Install.cmd +2 -0
  9. package/AutoHotkey_2.0.19/UX/Templates/Minimal for v2.ahk +6 -0
  10. package/AutoHotkey_2.0.19/UX/WindowSpy.ahk +246 -0
  11. package/AutoHotkey_2.0.19/UX/inc/CommandLineToArgs.ahk +12 -0
  12. package/AutoHotkey_2.0.19/UX/inc/CreateAppShortcut.ahk +37 -0
  13. package/AutoHotkey_2.0.19/UX/inc/EnableUIAccess.ahk +246 -0
  14. package/AutoHotkey_2.0.19/UX/inc/GetGitHubReleaseAssetURL.ahk +26 -0
  15. package/AutoHotkey_2.0.19/UX/inc/HashFile.ahk +96 -0
  16. package/AutoHotkey_2.0.19/UX/inc/README.txt +3 -0
  17. package/AutoHotkey_2.0.19/UX/inc/ShellRun.ahk +7 -0
  18. package/AutoHotkey_2.0.19/UX/inc/bounce-v1.ahk +3 -0
  19. package/AutoHotkey_2.0.19/UX/inc/common.ahk +21 -0
  20. package/AutoHotkey_2.0.19/UX/inc/config.ahk +13 -0
  21. package/AutoHotkey_2.0.19/UX/inc/identify.ahk +29 -0
  22. package/AutoHotkey_2.0.19/UX/inc/identify_regex.ahk +4 -0
  23. package/AutoHotkey_2.0.19/UX/inc/launcher-common.ahk +78 -0
  24. package/AutoHotkey_2.0.19/UX/inc/spy.ico +0 -0
  25. package/AutoHotkey_2.0.19/UX/inc/ui-base.ahk +129 -0
  26. package/AutoHotkey_2.0.19/UX/install-ahk2exe.ahk +53 -0
  27. package/AutoHotkey_2.0.19/UX/install-version.ahk +109 -0
  28. package/AutoHotkey_2.0.19/UX/install.ahk +1056 -0
  29. package/AutoHotkey_2.0.19/UX/launcher.ahk +430 -0
  30. package/AutoHotkey_2.0.19/UX/reload-v1.ahk +22 -0
  31. package/AutoHotkey_2.0.19/UX/reset-assoc.ahk +38 -0
  32. package/AutoHotkey_2.0.19/UX/ui-dash.ahk +200 -0
  33. package/AutoHotkey_2.0.19/UX/ui-editor.ahk +238 -0
  34. package/AutoHotkey_2.0.19/UX/ui-launcherconfig.ahk +195 -0
  35. package/AutoHotkey_2.0.19/UX/ui-newscript.ahk +296 -0
  36. package/AutoHotkey_2.0.19/UX/ui-setup.ahk +175 -0
  37. package/AutoHotkey_2.0.19/UX/ui-uninstall.ahk +68 -0
  38. package/AutoHotkey_2.0.19/WindowSpy.ahk +2 -0
  39. package/AutoHotkey_2.0.19/license.txt +351 -0
  40. package/AutoHotkey_2.0.19/zclick.ahk +5 -0
  41. package/AutoHotkey_2.0.19/zrun_click.bat +2 -0
  42. package/AutoHotkey_2.0.19/zrun_send.bat +2 -0
  43. package/AutoHotkey_2.0.19/zsend.ahk +4 -0
  44. package/LICENSE +21 -0
  45. package/README.md +23 -0
  46. package/SECURITY.md +5 -0
  47. package/_tmp/view.all.png +0 -0
  48. package/_tmp/view.det.png +0 -0
  49. package/babel.config.js +16 -0
  50. package/dist/action.umd.js +32 -0
  51. package/dist/action.umd.js.map +1 -0
  52. package/dist/ck-pic.umd.js +7 -0
  53. package/dist/ck-pic.umd.js.map +1 -0
  54. package/dist/compare.umd.js +7 -0
  55. package/dist/compare.umd.js.map +1 -0
  56. package/dist/get-settings.umd.js +7 -0
  57. package/dist/get-settings.umd.js.map +1 -0
  58. package/dist/mousekey.umd.js +7 -0
  59. package/dist/mousekey.umd.js.map +1 -0
  60. package/dist/screen.umd.js +7 -0
  61. package/dist/screen.umd.js.map +1 -0
  62. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  63. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  64. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  65. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  66. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  67. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  68. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  69. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  70. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  71. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
  72. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  73. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  74. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  75. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  76. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
  77. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  78. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  79. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  80. package/docs/index.html +84 -0
  81. package/docs/scripts/collapse.js +39 -0
  82. package/docs/scripts/commonNav.js +28 -0
  83. package/docs/scripts/linenumber.js +25 -0
  84. package/docs/scripts/nav.js +12 -0
  85. package/docs/scripts/polyfill.js +4 -0
  86. package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
  87. package/docs/scripts/prettify/lang-css.js +2 -0
  88. package/docs/scripts/prettify/prettify.js +28 -0
  89. package/docs/scripts/search.js +99 -0
  90. package/docs/styles/jsdoc.css +776 -0
  91. package/docs/styles/prettify.css +80 -0
  92. package/g.mjs +46 -0
  93. package/g.test_opencv.mjs +36 -0
  94. package/package.json +41 -0
  95. package/pic/view.png +0 -0
  96. package/script.txt +17 -0
  97. package/src/action.mjs +132 -0
  98. package/src/ckPic.mjs +95 -0
  99. package/src/compare.mjs +201 -0
  100. package/src/getSettings.mjs +17 -0
  101. package/src/mousekey.mjs +95 -0
  102. package/src/screen.mjs +62 -0
  103. package/test/WMousekey.test.mjs +11 -0
  104. package/toolg/addVersion.mjs +4 -0
  105. package/toolg/cleanFolder.mjs +4 -0
  106. package/toolg/gDistRollup.mjs +33 -0
  107. package/toolg/modifyReadme.mjs +4 -0
@@ -0,0 +1,200 @@
1
+ ; Dash: AutoHotkey's "main menu".
2
+ ; Run the script to show the GUI.
3
+ #include inc\bounce-v1.ahk
4
+ /* v1 stops here */
5
+ #requires AutoHotkey v2.0
6
+
7
+ #NoTrayIcon
8
+ #SingleInstance Force
9
+
10
+ #include inc\ui-base.ahk
11
+ #include ui-launcherconfig.ahk
12
+ #include ui-editor.ahk
13
+ #include ui-newscript.ahk
14
+
15
+ DashRegKey := 'HKCU\Software\AutoHotkey\Dash'
16
+
17
+ class AutoHotkeyDashGui extends AutoHotkeyUxGui {
18
+ __new() {
19
+ super.__new("AutoHotkey Dash")
20
+
21
+ lv := this.AddListMenu('vLV LV0x40 w250', ["Name", "Desc"])
22
+ lv.OnEvent("Click", "ItemClicked")
23
+ lv.OnEvent("ItemFocus", "ItemFocused")
24
+ lv.OnNotify(-155, "KeyPressed")
25
+
26
+ this.AddButton("xp yp wp yp Hidden Default").OnEvent("Click", "EnterPressed")
27
+
28
+ il := IL_Create(,, true)
29
+ lv.SetImageList(il, 0)
30
+ il2 := IL_Create(,, false)
31
+ lv.SetImageList(il2, 1)
32
+ addIcon(p*) =>(IL_Add(il, p*), IL_Add(il2, p*))
33
+
34
+ lv.Add("Icon" addIcon(A_AhkPath, 2)
35
+ , "New script", "Create a script or manage templates")
36
+ lv.Add("Icon" addIcon("imageres.dll", -111)
37
+ , "Compile", "Open Ahk2Exe - convert .ahk to .exe")
38
+ lv.Add("Icon" addIcon("imageres.dll", -99)
39
+ , "Help files (F1)")
40
+ lv.Add("Icon" addIcon(A_ScriptDir '\inc\spy.ico', 1)
41
+ , "Window spy")
42
+ lv.Add("Icon" addIcon("imageres.dll", -116)
43
+ , "Launch settings", "Configure how .ahk files are opened")
44
+ lv.Add("Icon" addIcon("notepad.exe", 1)
45
+ , "Editor settings", "Set your default script editor")
46
+ ; lv.Add("Icon" addIcon("mmc.exe")
47
+ ; , "Maintenance", "Repair settings or add/remove versions")
48
+ ; lv.Add(, "Auto-start", "Run scripts automatically at logon")
49
+ ; lv.Add(, "Downloads", "Get related tools")
50
+
51
+ lv.AutoSize()
52
+ lv.GetPos(,,, &h)
53
+
54
+ if !RegRead(DashRegKey, 'SuppressIntro', false) {
55
+ this.SetFont('s12')
56
+ this.AddText('yp x+m', "Welcome!")
57
+ this.SetFont('s9')
58
+ this.AddText('xp', "This is the Dash. It provides access to tools, settings and help files.")
59
+ this.AddText('xp', "To learn how to use AutoHotkey, refer to:")
60
+ this.AddLink('xp', "
61
+ (
62
+ `s • <a href="Program.htm">Using the Program</a>
63
+ • <a href="howto/WriteHotkeys.htm">How to Write Hotkeys</a>
64
+ • <a href="howto/SendKeys.htm">How to Send Keystrokes</a>
65
+ • <a href="howto/RunPrograms.htm">How to Run Programs</a>
66
+ • <a href="howto/ManageWindows.htm">How to Manage Windows</a>
67
+ • <a href="index.htm#Quick_Reference">Quick Reference</a>
68
+ )").OnEvent('Click', 'LinkClicked')
69
+
70
+ checkBox := this.AddCheckbox('Checked', "Show this info next time")
71
+ checkBox.GetPos(,,, &hc)
72
+ checkBox.Move(, h - hc)
73
+ checkBox.OnEvent('Click', 'SetIntroPref')
74
+ }
75
+
76
+ this.Show("Hide h" (h + this.MarginY*2))
77
+ }
78
+
79
+ LinkClicked(ctrl, id, href) {
80
+ if FileExist(chm := ROOT_DIR '\v2\AutoHotkey.chm')
81
+ Run 'hh.exe "ms-its:' chm '::docs/' href '"'
82
+ else
83
+ Run 'https://www.autohotkey.com/docs/v2/' href
84
+ }
85
+
86
+ SetIntroPref(checkBox, *) {
87
+ if checkBox.Value { ; Show intro
88
+ try RegDelete(DashRegKey, 'SuppressIntro')
89
+ } else
90
+ RegWrite(true, 'REG_DWORD', DashRegKey, 'SuppressIntro')
91
+ }
92
+
93
+ KeyPressed(lv, lParam) {
94
+ switch NumGet(lParam, A_PtrSize * 3, "Short") {
95
+ case 0x70: ; F1
96
+ ShowHelpFile()
97
+ }
98
+ }
99
+
100
+ EnterPressed(*) {
101
+ lv := this["LV"]
102
+ this.ItemClicked(lv, lv.GetNext(,'F'))
103
+ }
104
+
105
+ ItemClicked(lv, item) {
106
+ switch item && RegExReplace(lv.GetText(item), ' .*') {
107
+ case "New":
108
+ NewScriptGui.Show()
109
+ case "Compile":
110
+ if WinExist("Ahk2Exe ahk_class AutoHotkeyGUI")
111
+ WinActivate
112
+ else if FileExist(ROOT_DIR '\Compiler\Ahk2Exe.exe')
113
+ Run '"' ROOT_DIR '\Compiler\Ahk2Exe.exe"'
114
+ else
115
+ Run Format('"{1}" /script "{2}\install-ahk2exe.ahk"', A_AhkPath, A_ScriptDir)
116
+ case "Help":
117
+ ShowHelpFile()
118
+ case "Window":
119
+ try {
120
+ Run '"' A_MyDocuments '\AutoHotkey\WindowSpy.ahk"'
121
+ return
122
+ }
123
+ static AHK_FILE_WINDOWSPY := 0xFF7A ; 65402
124
+ static WM_COMMAND := 0x111 ; 273
125
+ SendMessage WM_COMMAND, AHK_FILE_WINDOWSPY, 0, A_ScriptHwnd
126
+ if WinWait("Window Spy ahk_class AutoHotkeyGUI",, 1)
127
+ WinActivate
128
+ case "Launch":
129
+ LauncherConfigGui.Show()
130
+ case "Editor":
131
+ DefaultEditorGui.Show()
132
+ }
133
+ }
134
+
135
+ ItemFocused(lv, item) {
136
+ static WM_CHANGEUISTATE := 0x127 ; 295
137
+ SendMessage WM_CHANGEUISTATE, 0x10001, 0, lv
138
+ }
139
+ }
140
+
141
+ ShowHelpFile() {
142
+ SetWorkingDir ROOT_DIR
143
+ main := Map(), sub := Map()
144
+ other := Map(), other.CaseSense := "off"
145
+ hashes := ReadHashes('UX\installed-files.csv', item => item.Path ~= 'i)\.chm$')
146
+ Loop Files "*.chm", "FR" {
147
+ SplitPath A_LoopFilePath,, &dir,, &name
148
+ if name = "AutoHotkey" {
149
+ if !(f := hashes.Get(A_LoopFilePath, false))
150
+ continue
151
+ v := GetMajor(f.Version)
152
+ if !(cur := main.Get(v, false)) || VerCompare(cur.Version, f.Version) < 0
153
+ main[v] := f
154
+ sub[f.Version] := f
155
+ }
156
+ else
157
+ other[A_LoopFilePath] := name (dir != "" && name != dir ? " (" dir ")" : "")
158
+ }
159
+
160
+ if sub.Count = 1 && other.Count = 0 {
161
+ for , f in main { ; Don't bother showing online options in this case.
162
+ Run f.Path
163
+ return
164
+ }
165
+ }
166
+
167
+ m := Menu()
168
+ if main.Count {
169
+ m.Add "Offline help", (*) => 0
170
+ m.Disable "1&"
171
+ }
172
+ for , f in main {
173
+ m.Add "v&" f.Version, openIt.Bind(f.Path)
174
+ sub.Delete(f.Version)
175
+ }
176
+ if sub.Count {
177
+ subm := Menu()
178
+ for , f in sub
179
+ subm.Insert "1&", "v" f.Version, openIt.Bind(f.Path)
180
+ m.Add "More", subm
181
+ }
182
+
183
+ m.Add "Online help", (*) => 0
184
+ m.Disable "Online help"
185
+ prefix := main.Count ? "v" : "v&"
186
+ m.Add prefix "1.1", (*) => Run("https://www.autohotkey.com/docs/v1/")
187
+ m.Add prefix "2.0", (*) => Run("https://www.autohotkey.com/docs/v2/")
188
+
189
+ if other.Count {
190
+ m.Add "Other files", (*) => 0
191
+ m.Disable "Other files"
192
+ }
193
+ for f, t in other
194
+ m.Add t, openIt.Bind(f)
195
+
196
+ m.Show
197
+ openIt(f, *) => Run(f)
198
+ }
199
+
200
+ AutoHotkeyDashGui.Show()
@@ -0,0 +1,238 @@
1
+ ; This script shows a GUI for setting the default .ahk editor.
2
+ #requires AutoHotkey v2.0
3
+
4
+ #NoTrayIcon
5
+ #SingleInstance Off
6
+
7
+ #include launcher.ahk
8
+ #include inc\CommandLineToArgs.ahk
9
+
10
+ class EditorSelectionGui extends AutoHotkeyUxGui {
11
+ __new(cmdLine) {
12
+ super.__new("Select an editor")
13
+
14
+ lv := this.AddListMenu('vEds LV0x40 w300', ["Editor"])
15
+ this.IconList := il := IL_Create(,, true)
16
+ lv.SetImageList(il, 0)
17
+ for app in this.Apps := GetEditorApps() {
18
+ try
19
+ icon := IL_Add(il, app.exe)
20
+ catch
21
+ icon := -1
22
+ lv.Add('Icon' icon, app.name)
23
+ }
24
+ this.SelectEditorByCmd(cmdLine)
25
+ lv.AutoSize(8)
26
+ lv.GetPos(&x, &y, &w, &h)
27
+ x += w
28
+ y += h
29
+
30
+ this.AddText('xm w' w ' y' y, "Command line")
31
+ this.AddEdit('xm wp r2 -WantReturn vCmd', cmdLine).OnEvent('Change', 'CmdChanged')
32
+
33
+ this.AddText('xm h25 18 w' w)
34
+ this.AddPicture('x56 Icon-81 w16 yp+4', "imageres.dll")
35
+ this.AddLink('x76 yp-1', "<a>Editors with AutoHotkey support</a>")
36
+ .OnEvent('Click', 'ShowHelpEditors')
37
+
38
+ this.AddButton('xm w80', "&Browse").OnEvent('Click', 'Browse')
39
+ this.AddButton('Default yp w80 x' x - 160 - this.MarginY, "&OK").OnEvent('Click', 'Confirm')
40
+ this.AddButton('yp w80 x' x - 80, "&Cancel").OnEvent('Click', (c, *) => c.Gui.Hide())
41
+
42
+ this["Eds"].OnEvent("ItemFocus", "EditorSelected")
43
+ this.CmdChanged()
44
+ }
45
+
46
+ ShowHelpEditors(*) {
47
+ if FileExist(chm := ROOT_DIR '\v2\AutoHotkey.chm')
48
+ Run 'hh.exe "ms-its:' chm '::docs/misc/Editors.htm"'
49
+ else
50
+ Run 'https://www.autohotkey.com/docs/v2/misc/Editors.htm'
51
+ }
52
+
53
+ Browse(*) {
54
+ app := this.FileSelect(3,,, "Apps (*.exe; *.ahk)")
55
+ if app = ""
56
+ return
57
+ this['Cmd'].Value := this.GetAppCmd(app)
58
+ this.CmdChanged()
59
+ }
60
+
61
+ GetAppCmd(app) {
62
+ SplitPath app,,, &ext
63
+ if ext != "ahk"
64
+ return Format('"{1}" "%l"', app)
65
+ lp := GetLaunchParameters(app, true)
66
+ if !lp.exe
67
+ return ""
68
+ ; Try to use a path that will work if the user installs a new version and removes this one
69
+ ; (rather than invoking the launcher every time the edit verb is executed).
70
+ adaptivePath := RegExReplace(lp.exe.Path, lp.v = 1 ? '\\v1[^\\]*(?=\\[^\\]*$)' : '\\v2\K[^\\]+(?=\\[^\\]*$)')
71
+ trace '![Launcher] ' adaptivePath
72
+ try
73
+ adaptiveExe := GetExeInfo(adaptivePath)
74
+ if !IsSet(adaptiveExe) || VerCompare(adaptiveExe.Version, lp.v) < 0
75
+ adaptivePath := ""
76
+ cmd := Format('"{}"', FileExist(adaptivePath) ? adaptivePath : lp.exe.Path)
77
+ for sw in lp.switches
78
+ cmd .= ' ' sw
79
+ return cmd .= Format(' "{}" "%l"', app)
80
+ }
81
+
82
+ EditorSelected(lv, index) {
83
+ this['Cmd'].Value := this.Apps[index].cmd
84
+ this.CmdChanged()
85
+ }
86
+
87
+ CmdChanged(ctrl:=unset, *) {
88
+ if IsSet(ctrl) && n := this['Eds'].GetNext()
89
+ this['Eds'].Modify(n, '-Select')
90
+ cmd := this['Cmd'].Value
91
+ this['OK'].Enabled := cmd != "" && FindExecutable(CommandLineToArgs(cmd)[1]) != ""
92
+ }
93
+
94
+ SelectEditorByCmd(cmd) {
95
+ if cmd = ""
96
+ return
97
+ for app in this.Apps {
98
+ if app.cmd = cmd {
99
+ this['Eds'].Modify(A_Index, 'Focus Select')
100
+ return
101
+ }
102
+ }
103
+ ; App not in the list, so add it.
104
+ args := CommandLineToArgs(cmd)
105
+ try {
106
+ exe := GetExeInfo(FindExecutable(args.RemoveAt(1)))
107
+ app := {cmd: cmd, exe: exe.Path, name: exe.Description}
108
+ if SubStr(app.name, 1, 10) = "AutoHotkey" && (ahk := ahkArg(args)) {
109
+ ; The app itself appears to be a script, so show the script name.
110
+ app.name := ahk
111
+ }
112
+ this.Apps.Push(app)
113
+ try
114
+ icon := IL_Add(this.IconList, app.exe, IsSet(ahk) && ahk ? 2 : 1)
115
+ catch
116
+ icon := -1
117
+ this['Eds'].Add('Focus Select Icon' icon, app.name)
118
+ }
119
+
120
+ ahkArg(args) {
121
+ for arg in args {
122
+ if SubStr(arg, 1, 1) = '/'
123
+ continue
124
+ return SubStr(arg, -4) = '.ahk' ? arg : ''
125
+ }
126
+ return ''
127
+ }
128
+ }
129
+
130
+ Confirm(*) {
131
+ this.Hide()
132
+ this.OnConfirm(this['Cmd'].Value)
133
+ }
134
+ }
135
+
136
+ class DefaultEditorGui extends EditorSelectionGui {
137
+ __new(scriptToEdit:=unset) {
138
+ cmd := RegRead('HKCR\AutoHotkeyScript\shell\edit\command',, '')
139
+ if InStr(cmd, A_LineFile)
140
+ cmd := ''
141
+ super.__new(cmd)
142
+ if IsSet(scriptToEdit)
143
+ this.ScriptToEdit := scriptToEdit
144
+ }
145
+
146
+ OnConfirm(cmd) {
147
+ RegWrite(cmd, 'REG_SZ', 'HKCU\Software\Classes\AutoHotkeyScript\shell\edit\command')
148
+ if this.HasProp('ScriptToEdit')
149
+ Run('edit "' this.ScriptToEdit '"')
150
+ }
151
+ }
152
+
153
+ GetEditorApps() {
154
+ apps := []
155
+ apps.byName := Map(), apps.byName.CaseSense := 'off'
156
+ addAssoc(assoc, flag, src) {
157
+ static ASSOCSTR_COMMAND := 1
158
+ static ASSOCSTR_EXECUTABLE := 2
159
+ static ASSOCSTR_FRIENDLYAPPNAME := 4
160
+ try {
161
+ name := AssocQueryString(flag, ASSOCSTR_FRIENDLYAPPNAME, assoc)
162
+ exe := AssocQueryString(flag, ASSOCSTR_EXECUTABLE, assoc)
163
+ }
164
+ if !IsSet(exe) || name ~= 'i)^AutoHotkey|^Ahk2Exe'
165
+ return
166
+ try
167
+ cmd := AssocQueryString(flag, ASSOCSTR_COMMAND, assoc)
168
+ catch
169
+ cmd := '"' exe '" "%l"'
170
+ else if cmd = ""
171
+ return
172
+ if !(InStr(cmd, "%1") || InStr(cmd, "%l"))
173
+ cmd .= ' "%l"'
174
+ if name = "NOTEPAD.EXE"
175
+ name := "Notepad"
176
+ if apps.byName.Has(name)
177
+ return
178
+ app := {cmd: cmd, exe: exe, name: name}
179
+ apps.byName[name] := app
180
+ apps.Push(app)
181
+ }
182
+ addAppExe(app, src) {
183
+ static ASSOCF_INIT_BYEXENAME := 2 ; 0x2
184
+ addAssoc app, ASSOCF_INIT_BYEXENAME, src
185
+ }
186
+ addProgId(app, src) {
187
+ addAssoc app, 0, src
188
+ }
189
+
190
+ for ext in ["ahk", "txt"] {
191
+ owl := "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\." ext "\OpenWithList"
192
+ mru := RegRead(owl, "MRUList", "")
193
+ Loop Parse mru {
194
+ if app := RegRead(owl, A_LoopField, "")
195
+ addAppExe app, "Explorer\." ext "\OWL"
196
+ }
197
+ Loop Reg "HKCR\." ext "\OpenWithProgIds", "V" {
198
+ addProgId A_LoopRegName, "HKCR\." ext "\OWPI"
199
+ }
200
+ Loop Reg "HKCR\." ext "\OpenWithList", "K" {
201
+ if !InStr(A_LoopRegName, "Ahk2Exe")
202
+ addAppExe A_LoopRegName, "HKCR\." ext "\OWL"
203
+ }
204
+ }
205
+ addAppExe "notepad.exe", "explicit"
206
+ return apps
207
+ }
208
+
209
+ ; Return the path of an executable file, if given something that could be executed
210
+ ; in a shell verb (excluding args). Although shell verb commands require an exe,
211
+ ; they do also look in \App Paths\, like ShellExecute, unlike CreateProcess.
212
+ FindExecutable(name) {
213
+ if SubStr(name, -4) != ".exe" ; For odd cases like 'notepad "%1"'
214
+ name .= ".exe"
215
+ if FileExist(name)
216
+ return name
217
+ if InStr(name, "\") || InStr(name, ":")
218
+ return ""
219
+ buf := Buffer(260*2)
220
+ if DllCall("shell32\FindExecutable", "str", name, "ptr", 0, "ptr", buf, "uint") > 32 ; "Returns a value greater than 32 if successful"
221
+ return StrGet(buf)
222
+ static AppPaths := '\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\'
223
+ path := RegRead('HKCU' AppPaths name,, '') || RegRead('HKLM' AppPaths name,, '')
224
+ ; The system permits quotes, and some applications are registered that way.
225
+ return StrReplace(path, '"')
226
+ }
227
+
228
+ AssocQueryString(flags, strtype, assoc) {
229
+ DllCall("shlwapi\AssocQueryStringW", "int", flags, "int", strtype, "wstr", assoc
230
+ , "ptr", 0, "ptr", 0, "uint*", &bufsize := 0, "hresult")
231
+ buf := Buffer(bufsize * 2)
232
+ DllCall("shlwapi\AssocQueryStringW", "int", flags, "int", strtype, "wstr", assoc
233
+ , "ptr", 0, "ptr", buf, "uint*", &bufsize, "hresult")
234
+ return StrGet(buf, "UTF-16")
235
+ }
236
+
237
+ if A_LineFile = A_ScriptFullPath
238
+ DefaultEditorGui.Show(A_Args*)
@@ -0,0 +1,195 @@
1
+ ; This script shows a GUI for configuring the launcher.
2
+ #requires AutoHotkey v2.0
3
+
4
+ #NoTrayIcon
5
+
6
+ #include inc\launcher-common.ahk
7
+ #include inc\ui-base.ahk
8
+
9
+ GetVersions() {
10
+ vmap := Map(1, Map(), 2, Map())
11
+ vmap.UIA := false ; Just detect whether any are present for now, to cover the most common cases (UIA supported by all or none).
12
+ for ,f in GetUsableAutoHotkeyExes() {
13
+ try {
14
+ vmap[GetMajor(f.Version)][f.Version] := true
15
+ if SubStr(f.Path, -8) = "_UIA.exe"
16
+ vmap.UIA := true
17
+ }
18
+ catch as e
19
+ trace "-[Launcher] " type(e) " checking file " A_LoopFileName ": " e.message
20
+ }
21
+ vmap[1] := [vmap[1]*]
22
+ vmap[2] := [vmap[2]*]
23
+ return vmap
24
+ }
25
+
26
+ class LauncherConfigGui extends AutoHotkeyUxGui {
27
+ __new() {
28
+ super.__new("AutoHotkey Launch Config")
29
+
30
+ cmd := RegRead('HKCR\AutoHotkeyScript\shell\open\command',, '')
31
+ usingLauncher := InStr(cmd, 'UX\launcher.ahk') != 0
32
+ currentExe := !usingLauncher && RegExMatch(cmd, '^"(.*?)"(?= )', &m) ? m.1 : ""
33
+ try
34
+ if currentExe && GetExeInfo(currentExe).Description = "AutoHotkey Launcher" ; Support compiled launcher
35
+ usingLauncher := true, currentExe := ""
36
+ if InStr(currentExe, '\AutoHotkeyUX.exe')
37
+ currentExe := "" ; Don't default to AutoHotkeyUX.exe when disabling launcher
38
+
39
+ versions := GetVersions()
40
+
41
+ ; this.AddCheckbox("Checked", "Enable drag && drop on .ahk files")
42
+
43
+ this.AddRadio('vUseLauncher Checked' usingLauncher, "Auto-detect version when launching script")
44
+ .OnEvent('Click', 'ChangedMode')
45
+ this.AddRadio('vUseSpecific Checked' (!usingLauncher), "Run all scripts with a specific interpreter")
46
+ .OnEvent('Click', 'ChangedMode')
47
+
48
+ tab := this.AddTab('w0 h0 y+0 vTab -TabStop', ["Launcher", "Specific"])
49
+
50
+ tab.UseTab(1)
51
+ this.AddText('xm yp+12 Section', "Preferred interpreter by major version")
52
+ this.AddDDL('vVersion1 y+3 w110 Choose1', ["Latest 1.x", versions[1]*])
53
+ .OnEvent('Change', "ChangedVersion")
54
+ this.AddComboBox('vBuild1 yp w150', ["Unicode 64-bit", "Unicode 32-bit", "ANSI 32-bit"])
55
+ .OnEvent('Change', 'ChangedBuild')
56
+ this.AddCheckBox('vUIA1 x+m yp+2 Disabled' (!versions.UIA), "UI Access")
57
+ .OnEvent('Click', 'ChangedUIA')
58
+ this.AddDDL('vVersion2 xs w110 Choose1', ["Latest 2.x", versions[2]*])
59
+ .OnEvent('Change', 'ChangedVersion')
60
+ this.AddComboBox('vBuild2 yp w150', ["64-bit", "32-bit"])
61
+ .OnEvent('Change', 'ChangedBuild')
62
+ this.AddCheckBox('vUIA2 x+m yp+2 Disabled' (!versions.UIA), "UI Access")
63
+ .OnEvent('Click', 'ChangedUIA')
64
+ this.AddText('xs y+m+8', "When detection fails")
65
+ this.AddDDL('vFallback y+3 w110 Choose3', ["Use v1.x", "Use v2.x", "Ask the user"])
66
+ .OnEvent('Change', "ChangedFallback")
67
+ this.AddCheckbox('vIdentify xs y+m+8 Checked', "Try to identify version based on syntax")
68
+ .OnEvent('Click', (c, *) => ConfigWrite(c.Value, 'Launcher', 'Identify'))
69
+ this.AddCheckbox('vLauncherUTF8 xs Checked', "Default to UTF-8 even for v1 scripts")
70
+ .OnEvent('Click', (c, *) => ConfigWrite(c.Value, 'Launcher\v1', 'UTF8'))
71
+
72
+ tab.UseTab(2)
73
+ exeBox := this.AddEdit('vExePath xs ys w326 ReadOnly')
74
+ if currentExe
75
+ exeBox.Text := currentExe
76
+ else if FileExist(f := ROOT_DIR '\v2\AutoHotkey' (A_Is64bitOS ? '64' : '32') '.exe')
77
+ exeBox.Text := f
78
+
79
+ static BrowseIcon := LoadPicture("imageres.dll", 'Icon-1025 w' SysGet(49), &imgtype)
80
+ this.AddIconButton('vBrowse x+0 yp-1 w28 hp+2', BrowseIcon, "&Browse")
81
+ .OnEvent('Click', 'BrowseForExe')
82
+
83
+ this.AddCheckBox('vCustomUTF8 xm y+m+4 Hidden', "Default to UTF-8")
84
+ .OnEvent('Click', 'UpdateVerbs')
85
+
86
+ tab.UseTab()
87
+ this.AddButton('vClose x292 w70 Default', "&Close")
88
+ .OnEvent('Click', (ctrl, *) => ctrl.Gui.Hide())
89
+
90
+ ; size := 32 * A_ScreenDPI // 96
91
+ ; DllCall("comctl32\LoadIconWithScaleDown", "ptr", 0, "int", 32514, "int", size, "int", size, "ptr*", &icon:=0, "hresult")
92
+ ; help := this.AddButton('0x40 x322 ym w' 40 ' h' 40)
93
+ ; SendMessage(0xF7, 1, icon, help)
94
+
95
+ tab.Choose(usingLauncher ? 1 : 2)
96
+
97
+ Loop 2 {
98
+ section := 'Launcher\v' A_Index
99
+ v := ConfigRead(section, 'Version', '')
100
+ try this['Version' A_Index].Text := v || 'Latest ' A_Index '.x'
101
+ try this['Build' A_Index].Text := ConfigRead(section, 'Build', '')
102
+ try this['UIA' A_Index].Value := ConfigRead(section, 'UIA', false)
103
+ if this['Build' A_Index].Text = ""
104
+ ControlChooseIndex(1, this['Build' A_Index])
105
+ }
106
+ v := ConfigRead('Launcher', 'Fallback', '')
107
+ IsInteger(v) && this['Fallback'].Value := v
108
+ this['Identify'].Value := ConfigRead('Launcher', 'Identify', true)
109
+ this['LauncherUTF8'].Value := ConfigRead('Launcher\v1', 'UTF8', false)
110
+
111
+ this.ChangedMode()
112
+ this.ChangedExe()
113
+ }
114
+
115
+ ChangedMode(sourceCtrl:=false, *) {
116
+ usingLauncher := this['UseLauncher'].Value
117
+ this['Tab'].Choose(usingLauncher ? 1 : 2)
118
+ this[usingLauncher ? 'LauncherUTF8' : 'CustomUTF8'].GetPos(, &y1, , &h1)
119
+ this['Close'].GetPos(,,, &h2)
120
+ this['Close'].Move(, y1)
121
+ this.Show('h' (y1 + h2 + 10))
122
+ if sourceCtrl
123
+ this.UpdateVerbs()
124
+ }
125
+
126
+ ChangedExe() {
127
+ exe := this['ExePath'].Text
128
+ if exe = ""
129
+ return
130
+ try
131
+ exeVersion := FileGetVersion(exe)
132
+ catch {
133
+ MsgBox "The selected EXE appears to be invalid.`n`nSpecifically: " exe,, 'Icon!'
134
+ return
135
+ }
136
+ if !this['CustomUTF8'].Visible && this['LauncherUTF8'].Value
137
+ this['CustomUTF8'].Value := true
138
+ this['CustomUTF8'].Visible := VerCompare(exeVersion, '2') < 0
139
+ }
140
+
141
+ ChangedVersion(ctrl, *) =>
142
+ ConfigWrite(ctrl.Value = 1 ? '' : ctrl.Text, 'Launcher\v' SubStr(ctrl.Name, -1), 'Version')
143
+
144
+ ChangedBuild(ctrl, *) =>
145
+ ConfigWrite(ctrl.Text, 'Launcher\v' SubStr(ctrl.Name, -1), 'Build')
146
+
147
+ ChangedUIA(ctrl, *) =>
148
+ ConfigWrite(ctrl.Value, 'Launcher\v' SubStr(ctrl.Name, -1), 'UIA')
149
+
150
+ ChangedFallback(ctrl, *) =>
151
+ ConfigWrite(ctrl.Value = 3 ? '' : ctrl.Value, 'Launcher', 'Fallback')
152
+
153
+ BrowseForExe(*) {
154
+ exe := this.FileSelect('3', this['ExePath'].Text, "Select an AutoHotkey.exe", "EXE Files (*.exe)")
155
+ if exe = ""
156
+ return
157
+ this['ExePath'].Text := exe
158
+ this.ChangedExe()
159
+ this.UpdateVerbs()
160
+ }
161
+
162
+ UpdateVerbs(*) {
163
+ ; FIXME: reg key and FriendlyAppName should be defined in only one place
164
+ static key := 'HKCU\Software\Classes\AutoHotkeyScript\Shell\'
165
+ if this['UseLauncher'].Value {
166
+ cmd := Format('"{1}" "{2}\launcher.ahk" "%1" %*', A_AhkPath, A_ScriptDir)
167
+ appname := "AutoHotkey Launcher"
168
+ } else {
169
+ exe := this['ExePath'].Text
170
+ if exe = ""
171
+ return
172
+ if !FileExist(exe)
173
+ throw
174
+ exe_uia := SubStr(exe, 1, -4) "_UIA.exe"
175
+ switches := this['CustomUTF8'].Visible && this['CustomUTF8'].Value ? '/cp65001 ' : ''
176
+ cmd := Format('"{1}" {2}"%1" %*', exe, switches)
177
+ ; Deleting FriendlyAppName from HKCU won't work if the installer uses HKLM,
178
+ ; so explicitly set it to the file's description
179
+ appname := GetExeInfo(exe).Description
180
+ }
181
+ RegWrite appname, 'REG_SZ', key 'Open', 'FriendlyAppName'
182
+ RegWrite cmd, 'REG_SZ', key 'Open\Command'
183
+ RegWrite cmd, 'REG_SZ', key 'RunAs\Command'
184
+ if RegRead('HKCR\AutoHotkeyScript\Shell\UIAccess\Command',, '') {
185
+ if IsSet(exe_uia) && FileExist(exe_uia)
186
+ cmd := StrReplace(cmd, exe, exe_uia)
187
+ else
188
+ cmd := Format('"{1}" "{2}\launcher.ahk" /runwith UIA "%1" %*', A_AhkPath, A_ScriptDir)
189
+ RegWrite cmd, 'REG_SZ', key 'UIAccess\Command'
190
+ }
191
+ }
192
+ }
193
+
194
+ if A_ScriptFullPath = A_LineFile
195
+ LauncherConfigGui.Show()