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.
- package/.editorconfig +9 -0
- package/.eslintignore +3 -0
- package/.eslintrc.js +55 -0
- package/.jsdoc +25 -0
- package/AutoHotkey_2.0.19/AutoHotkey.chm +0 -0
- package/AutoHotkey_2.0.19/AutoHotkey32.exe +0 -0
- package/AutoHotkey_2.0.19/AutoHotkey64.exe +0 -0
- package/AutoHotkey_2.0.19/Install.cmd +2 -0
- package/AutoHotkey_2.0.19/UX/Templates/Minimal for v2.ahk +6 -0
- package/AutoHotkey_2.0.19/UX/WindowSpy.ahk +246 -0
- package/AutoHotkey_2.0.19/UX/inc/CommandLineToArgs.ahk +12 -0
- package/AutoHotkey_2.0.19/UX/inc/CreateAppShortcut.ahk +37 -0
- package/AutoHotkey_2.0.19/UX/inc/EnableUIAccess.ahk +246 -0
- package/AutoHotkey_2.0.19/UX/inc/GetGitHubReleaseAssetURL.ahk +26 -0
- package/AutoHotkey_2.0.19/UX/inc/HashFile.ahk +96 -0
- package/AutoHotkey_2.0.19/UX/inc/README.txt +3 -0
- package/AutoHotkey_2.0.19/UX/inc/ShellRun.ahk +7 -0
- package/AutoHotkey_2.0.19/UX/inc/bounce-v1.ahk +3 -0
- package/AutoHotkey_2.0.19/UX/inc/common.ahk +21 -0
- package/AutoHotkey_2.0.19/UX/inc/config.ahk +13 -0
- package/AutoHotkey_2.0.19/UX/inc/identify.ahk +29 -0
- package/AutoHotkey_2.0.19/UX/inc/identify_regex.ahk +4 -0
- package/AutoHotkey_2.0.19/UX/inc/launcher-common.ahk +78 -0
- package/AutoHotkey_2.0.19/UX/inc/spy.ico +0 -0
- package/AutoHotkey_2.0.19/UX/inc/ui-base.ahk +129 -0
- package/AutoHotkey_2.0.19/UX/install-ahk2exe.ahk +53 -0
- package/AutoHotkey_2.0.19/UX/install-version.ahk +109 -0
- package/AutoHotkey_2.0.19/UX/install.ahk +1056 -0
- package/AutoHotkey_2.0.19/UX/launcher.ahk +430 -0
- package/AutoHotkey_2.0.19/UX/reload-v1.ahk +22 -0
- package/AutoHotkey_2.0.19/UX/reset-assoc.ahk +38 -0
- package/AutoHotkey_2.0.19/UX/ui-dash.ahk +200 -0
- package/AutoHotkey_2.0.19/UX/ui-editor.ahk +238 -0
- package/AutoHotkey_2.0.19/UX/ui-launcherconfig.ahk +195 -0
- package/AutoHotkey_2.0.19/UX/ui-newscript.ahk +296 -0
- package/AutoHotkey_2.0.19/UX/ui-setup.ahk +175 -0
- package/AutoHotkey_2.0.19/UX/ui-uninstall.ahk +68 -0
- package/AutoHotkey_2.0.19/WindowSpy.ahk +2 -0
- package/AutoHotkey_2.0.19/license.txt +351 -0
- package/AutoHotkey_2.0.19/zclick.ahk +5 -0
- package/AutoHotkey_2.0.19/zrun_click.bat +2 -0
- package/AutoHotkey_2.0.19/zrun_send.bat +2 -0
- package/AutoHotkey_2.0.19/zsend.ahk +4 -0
- package/LICENSE +21 -0
- package/README.md +23 -0
- package/SECURITY.md +5 -0
- package/_tmp/view.all.png +0 -0
- package/_tmp/view.det.png +0 -0
- package/babel.config.js +16 -0
- package/dist/action.umd.js +32 -0
- package/dist/action.umd.js.map +1 -0
- package/dist/ck-pic.umd.js +7 -0
- package/dist/ck-pic.umd.js.map +1 -0
- package/dist/compare.umd.js +7 -0
- package/dist/compare.umd.js.map +1 -0
- package/dist/get-settings.umd.js +7 -0
- package/dist/get-settings.umd.js.map +1 -0
- package/dist/mousekey.umd.js +7 -0
- package/dist/mousekey.umd.js.map +1 -0
- package/dist/screen.umd.js +7 -0
- package/dist/screen.umd.js.map +1 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/docs/index.html +84 -0
- package/docs/scripts/collapse.js +39 -0
- package/docs/scripts/commonNav.js +28 -0
- package/docs/scripts/linenumber.js +25 -0
- package/docs/scripts/nav.js +12 -0
- package/docs/scripts/polyfill.js +4 -0
- package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/scripts/prettify/lang-css.js +2 -0
- package/docs/scripts/prettify/prettify.js +28 -0
- package/docs/scripts/search.js +99 -0
- package/docs/styles/jsdoc.css +776 -0
- package/docs/styles/prettify.css +80 -0
- package/g.mjs +46 -0
- package/g.test_opencv.mjs +36 -0
- package/package.json +41 -0
- package/pic/view.png +0 -0
- package/script.txt +17 -0
- package/src/action.mjs +132 -0
- package/src/ckPic.mjs +95 -0
- package/src/compare.mjs +201 -0
- package/src/getSettings.mjs +17 -0
- package/src/mousekey.mjs +95 -0
- package/src/screen.mjs +62 -0
- package/test/WMousekey.test.mjs +11 -0
- package/toolg/addVersion.mjs +4 -0
- package/toolg/cleanFolder.mjs +4 -0
- package/toolg/gDistRollup.mjs +33 -0
- package/toolg/modifyReadme.mjs +4 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
#requires AutoHotkey v2.0
|
|
2
|
+
|
|
3
|
+
#NoTrayIcon
|
|
4
|
+
#SingleInstance Off
|
|
5
|
+
|
|
6
|
+
#include inc\common.ahk
|
|
7
|
+
#include inc\ui-base.ahk
|
|
8
|
+
|
|
9
|
+
class NewScriptGui extends AutoHotkeyUxGui {
|
|
10
|
+
__new(path:="") {
|
|
11
|
+
super.__new("New Script")
|
|
12
|
+
|
|
13
|
+
SplitPath path,, &dir,, &name
|
|
14
|
+
if this.ExplorerHwnd := WinActive("ahk_class CabinetWClass") {
|
|
15
|
+
this.Opt '+Owner' this.ExplorerHwnd
|
|
16
|
+
if dir = ""
|
|
17
|
+
dir := GetPathForExplorerWindow(this.ExplorerHwnd)
|
|
18
|
+
}
|
|
19
|
+
if dir = ""
|
|
20
|
+
dir := ConfigRead('New', 'DefaultDir', A_MyDocuments "\AutoHotkey")
|
|
21
|
+
|
|
22
|
+
name := this.AddEdit('vName w272', name != "New AutoHotkey Script" ? name : "")
|
|
23
|
+
static EM_SETCUEBANNER := 0x1501
|
|
24
|
+
SendMessage(EM_SETCUEBANNER, true, StrPtr("Untitled"), name)
|
|
25
|
+
|
|
26
|
+
static IconSize := SysGet(49) ; SM_CXSMICON
|
|
27
|
+
|
|
28
|
+
static BrowseIcon := LoadPicture("imageres.dll", 'Icon-1025 w' IconSize, &imgtype)
|
|
29
|
+
this.AddIconButton('vBrowse x+0 yp-1 w28 hp+2', BrowseIcon, "&Browse")
|
|
30
|
+
.OnEvent('Click', 'Browse')
|
|
31
|
+
|
|
32
|
+
this.AddEdit('vDir xm w300 r1 ReadOnly -TabStop', dir)
|
|
33
|
+
|
|
34
|
+
static LVS_SHOWSELALWAYS := 8 ; Seems to have the opposite effect with Explorer theme, at least on Windows 11.
|
|
35
|
+
lv := this.AddListMenu("vLV xm w300 -" LVS_SHOWSELALWAYS, ["Name", "Desc", "Path", "Exec"])
|
|
36
|
+
lv.OnEvent('DoubleClick', 'DoubleClicked')
|
|
37
|
+
lv.OnEvent('ContextMenu', 'RightClicked')
|
|
38
|
+
|
|
39
|
+
deft := GetDefaultTemplate()
|
|
40
|
+
lv.Add(deft = "" ? 'Select Focus' : '', "Empty", "Clean slate")
|
|
41
|
+
for ,t in this.Templates := GetScriptTemplates() {
|
|
42
|
+
if ConfigRead('New\HideTemplate', t.name, false)
|
|
43
|
+
continue
|
|
44
|
+
lv.Add(deft = t.name ? 'Select Focus' : '', t.name, t.desc)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
lv.AutoSize(8)
|
|
48
|
+
lv.GetPos(&x, &y, &w, &h)
|
|
49
|
+
|
|
50
|
+
static DefaultsIcon := LoadPicture("imageres.dll", 'Icon-114 w' IconSize, &imgtype)
|
|
51
|
+
this.AddIconButton('vDefaults r1 w28 xm y' y + h + this.MarginY, DefaultsIcon, "&Defaults")
|
|
52
|
+
.OnEvent('Click', 'ChangeDefaults')
|
|
53
|
+
|
|
54
|
+
this.AddButton('vCreate yp w75 x150', "&Create").OnEvent('Click', 'Confirm')
|
|
55
|
+
this.AddButton('vEdit Default yp wp xm+225', "&Edit").OnEvent('Click', 'Confirm')
|
|
56
|
+
if ConfigRead('New', 'DefaultButton', 'Edit') = 'Create'
|
|
57
|
+
this['Create'].Opt('Default')
|
|
58
|
+
|
|
59
|
+
if this.ExplorerHwnd {
|
|
60
|
+
this.Show('AutoSize Hide')
|
|
61
|
+
WinGetPos(,, &gw, &gh, this)
|
|
62
|
+
WinGetPos(&x, &y, &ew, &eh)
|
|
63
|
+
WinMove(x + (ew - gw) // 2, y + (eh - gh) // 2,,, this)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static __new() {
|
|
68
|
+
OnMessage(WM_KEYDOWN := 0x100, KeyDown)
|
|
69
|
+
KeyDown(wParam, lParam, nmsg, hwnd) {
|
|
70
|
+
static VK_UP := 0x26
|
|
71
|
+
static VK_DOWN := 0x28
|
|
72
|
+
if !(wParam = VK_UP || wParam = VK_DOWN)
|
|
73
|
+
return
|
|
74
|
+
gc := GuiCtrlFromHwnd(hwnd)
|
|
75
|
+
if gc.Gui is NewScriptGui && gc is Gui.Edit {
|
|
76
|
+
PostMessage nmsg, wParam, lParam, gc.Gui['LV']
|
|
77
|
+
return true
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
Browse(*) {
|
|
83
|
+
path := this.FileSelect('S', this['Dir'].Value "\" this['Name'].Value, this.Title, "Script Files (*.ahk)")
|
|
84
|
+
if path = ""
|
|
85
|
+
return
|
|
86
|
+
SplitPath path, &name, &dir
|
|
87
|
+
this['Name'].Value := name
|
|
88
|
+
this['Dir'].Value := dir
|
|
89
|
+
this['LV'].Focus()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
ChangeDefaults(btn, *) {
|
|
93
|
+
lv := this["LV"]
|
|
94
|
+
|
|
95
|
+
m := Menu()
|
|
96
|
+
m.Add "Default to Create", setDefBtn, "Radio"
|
|
97
|
+
m.Add "Default to Edit", setDefBtn, "Radio"
|
|
98
|
+
m.Add "Stay open", toggleStayOpen
|
|
99
|
+
if stayOpen := ConfigRead('New', 'StayOpen', false)
|
|
100
|
+
m.Check "Stay open"
|
|
101
|
+
m.Add
|
|
102
|
+
m.Add "Set folder as default", (*) => SetDefaultDir(this['Dir'].Value)
|
|
103
|
+
if this['Dir'].Value = GetDefaultDir()
|
|
104
|
+
m.Check "Set folder as default"
|
|
105
|
+
m.Add "Open templates folder", (*) => OpenTemplatesFolder()
|
|
106
|
+
|
|
107
|
+
static DM_GETDEFID := 0x400
|
|
108
|
+
m.Check (1 + (SendMessage(DM_GETDEFID,,, this) & 0xFFFF = DllCall('GetDlgCtrlID', 'ptr', this['Edit'].Hwnd))) "&"
|
|
109
|
+
|
|
110
|
+
this.Opt "-DPIScale"
|
|
111
|
+
btn.GetPos &x, &y, &w, &h
|
|
112
|
+
;btn.Focus ; This would also apply the "default" style, which would not revert correctly.
|
|
113
|
+
ControlFocus btn
|
|
114
|
+
m.Show x, y + h
|
|
115
|
+
|
|
116
|
+
setDefBtn(itemname, itempos, *) {
|
|
117
|
+
itemname := SubStr(itemname, 12)
|
|
118
|
+
this[itemname].Opt('Default')
|
|
119
|
+
ConfigWrite(itemname, 'New', 'DefaultButton')
|
|
120
|
+
}
|
|
121
|
+
toggleStayOpen(*) {
|
|
122
|
+
ConfigWrite(stayOpen := !stayOpen, 'New', 'StayOpen')
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
Confirm(btn, *) {
|
|
127
|
+
lv := this['LV']
|
|
128
|
+
if !index := lv.GetNext()
|
|
129
|
+
return MsgBox("You need to select a template first.",, 'icon!')
|
|
130
|
+
t := index = 1 ? '' : this.Templates[lv.GetText(index)]
|
|
131
|
+
|
|
132
|
+
stayOpen := GetKeyState('Ctrl') || ConfigRead('New', 'StayOpen', false)
|
|
133
|
+
|
|
134
|
+
DirCreate dir := this['Dir'].Value
|
|
135
|
+
basename := this['Name'].Value
|
|
136
|
+
(basename != '') || basename := "Untitled"
|
|
137
|
+
SubStr(basename, -4) = ".ahk" && basename := SubStr(basename, 1, -4)
|
|
138
|
+
newPath := dir "\" basename ".ahk"
|
|
139
|
+
while FileExist(newPath)
|
|
140
|
+
newPath := dir "\" basename "-" A_Index ".ahk"
|
|
141
|
+
|
|
142
|
+
if t && t.execute
|
|
143
|
+
RunWait Format('"{1}" "{2}" {3}', t.path, newPath, btn.Name), dir
|
|
144
|
+
else {
|
|
145
|
+
code := t = '' ? '' : FileRead(t.path)
|
|
146
|
+
code := RegExReplace(code, 'si)/\*\s+\[NewScriptTemplate\].*\*/\R?')
|
|
147
|
+
FileOpen(newPath, 'w', 'UTF-8').Write(code)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if this.ExplorerHwnd && (xp := GetExplorerByHwnd(this.ExplorerHwnd))
|
|
151
|
+
|| dir = A_Desktop && (xp := GetExplorerForDesktop()) {
|
|
152
|
+
SplitPath newPath, &basename
|
|
153
|
+
SelectExplorerItem xp, basename
|
|
154
|
+
}
|
|
155
|
+
else if btn.Name != 'Edit'
|
|
156
|
+
Run 'explorer /select,"' newPath '"'
|
|
157
|
+
|
|
158
|
+
if btn.Name = 'Edit'
|
|
159
|
+
Run 'edit "' newPath '"'
|
|
160
|
+
|
|
161
|
+
if !stayOpen
|
|
162
|
+
this.Hide
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
RightClicked(lv, item, isRClick, x, y) {
|
|
166
|
+
if !item
|
|
167
|
+
return
|
|
168
|
+
t := item > 1 ? this.Templates[lv.GetText(item)] : {name: ''}
|
|
169
|
+
|
|
170
|
+
m := Menu()
|
|
171
|
+
if item > 1 {
|
|
172
|
+
m.Add "&Edit template", (*) => EditTemplate(t)
|
|
173
|
+
m.Add "&Hide template", hideTemplate
|
|
174
|
+
}
|
|
175
|
+
m.Add "Set as &default", (*) => SetDefaultTemplate(t.name)
|
|
176
|
+
if t.name = GetDefaultTemplate()
|
|
177
|
+
m.Check "Set as &default"
|
|
178
|
+
m.Show x, y
|
|
179
|
+
|
|
180
|
+
hideTemplate(*) {
|
|
181
|
+
ConfigWrite(true, 'New\HideTemplate', t.name)
|
|
182
|
+
lv.Delete item
|
|
183
|
+
static LVM_ARRANGE := 0x1016
|
|
184
|
+
SendMessage LVM_ARRANGE,,, lv ; Fill in any gap left by item (in Tile view).
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
DoubleClicked(lv, row) {
|
|
189
|
+
if row
|
|
190
|
+
this.Confirm(this.GetDefaultButton())
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
GetDefaultButton() {
|
|
194
|
+
static DM_GETDEFID := 0x400
|
|
195
|
+
hwnd := DllCall("GetDlgItem", "ptr", this.hwnd, "int", SendMessage(DM_GETDEFID,,, this) & 0xFFFF, "uint")
|
|
196
|
+
return hwnd && this[hwnd]
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
class NewScriptTemplate {
|
|
201
|
+
__new(path, name:="", description:="") {
|
|
202
|
+
this.path := path
|
|
203
|
+
if name = ""
|
|
204
|
+
SplitPath path,,,, &name
|
|
205
|
+
this.name := name
|
|
206
|
+
this.desc := IniRead(path, 'NewScriptTemplate', 'Description', description)
|
|
207
|
+
this.execute := false
|
|
208
|
+
switch IniRead(path, 'NewScriptTemplate', 'Execute', false) {
|
|
209
|
+
case true, "true": this.execute := true
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
OpenTemplatesFolder() {
|
|
215
|
+
dir := GetUserTemplateFolder(true)
|
|
216
|
+
if dir != ""
|
|
217
|
+
Run dir "\"
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
GetUserTemplateFolder(checkAndPrompt:=false) {
|
|
221
|
+
static dir := A_MyDocuments "\AutoHotkey\Templates"
|
|
222
|
+
if checkAndPrompt && !FileExist(dir) {
|
|
223
|
+
if MsgBox("User-created templates should be placed in the following folder, "
|
|
224
|
+
"which does not yet exist:`n`n" dir "`n`nCreate it now?",, "YesNo") = "No"
|
|
225
|
+
return
|
|
226
|
+
DirCreate dir
|
|
227
|
+
}
|
|
228
|
+
return dir
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
EditTemplate(t) {
|
|
232
|
+
dir := GetUserTemplateFolder(true)
|
|
233
|
+
if dir = ""
|
|
234
|
+
return
|
|
235
|
+
userPath := dir "\" t.name ".ahk"
|
|
236
|
+
if !FileExist(userPath) {
|
|
237
|
+
FileCopy t.path, userPath
|
|
238
|
+
t.path := userPath
|
|
239
|
+
}
|
|
240
|
+
Run 'edit "' userPath '"'
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
GetScriptTemplates() {
|
|
244
|
+
tmap := Map(), tmap.CaseSense := "off"
|
|
245
|
+
sources := [
|
|
246
|
+
A_ScriptDir "\Templates",
|
|
247
|
+
GetUserTemplateFolder()
|
|
248
|
+
]
|
|
249
|
+
if FileExist(t := A_WinDir '\ShellNew\Template.ahk')
|
|
250
|
+
tmap["Legacy"] := NewScriptTemplate(t, "Legacy", "From " A_WinDir "\ShellNew")
|
|
251
|
+
for source in sources {
|
|
252
|
+
loop files source "\*.ahk" {
|
|
253
|
+
t := NewScriptTemplate(A_LoopFilePath)
|
|
254
|
+
tmap[t.name] := t
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return tmap
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
SetDefaultTemplate(t) => ConfigWrite(t = "Empty" ? "" : t, 'New', 'DefaultTemplate')
|
|
261
|
+
GetDefaultTemplate() => ConfigRead('New', 'DefaultTemplate', "")
|
|
262
|
+
|
|
263
|
+
SetDefaultDir(dir) => ConfigWrite(dir, 'New', 'DefaultDir')
|
|
264
|
+
GetDefaultDir() => ConfigRead('New', 'DefaultDir', A_MyDocuments "\AutoHotkey")
|
|
265
|
+
|
|
266
|
+
SelectExplorerItem(e, name) {
|
|
267
|
+
sfv := e.Document
|
|
268
|
+
if fi := sfv.Folder.ParseName(name)
|
|
269
|
+
sfv.SelectItem(fi, 1|4|8|16)
|
|
270
|
+
return e
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
GetExplorerByHwnd(hwnd) {
|
|
274
|
+
for window in ComObject("Shell.Application").Windows
|
|
275
|
+
if window.hwnd = hwnd
|
|
276
|
+
return window
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
GetExplorerForDesktop() {
|
|
280
|
+
hwndBuf := Buffer(4, 0), hwndRef := ComValue(0x4003, hwndBuf.Ptr)
|
|
281
|
+
return ComObject("Shell.Application").Windows.FindWindowSW(0, "", 8, hwndRef, 1)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
GetPathForExplorerWindow(hwnd) {
|
|
285
|
+
try return GetExplorerByHwnd(hwnd).Document.Folder.Self.Path
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
GetExplorerByPath(path) {
|
|
289
|
+
for window in ComObject("Shell.Application").Windows
|
|
290
|
+
try if window.Document.Folder.Self.Path = path
|
|
291
|
+
return window
|
|
292
|
+
return ""
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if A_ScriptFullPath = A_LineFile
|
|
296
|
+
NewScriptGui.Show(A_Args.Length ? A_Args[1] : "")
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
; This script shows the initial setup GUI.
|
|
2
|
+
; It is not intended for use after installation.
|
|
3
|
+
#requires AutoHotkey v2.0
|
|
4
|
+
|
|
5
|
+
#NoTrayIcon
|
|
6
|
+
#SingleInstance Force
|
|
7
|
+
|
|
8
|
+
#include inc\ui-base.ahk
|
|
9
|
+
|
|
10
|
+
A_ScriptName := "AutoHotkey Setup"
|
|
11
|
+
SetRegView 64
|
|
12
|
+
InstallGui.Show()
|
|
13
|
+
|
|
14
|
+
class InstallGui extends AutoHotkeyUxGui {
|
|
15
|
+
__new() {
|
|
16
|
+
super.__new(A_ScriptName, '-MinimizeBox -MaximizeBox')
|
|
17
|
+
|
|
18
|
+
DllCall('uxtheme\SetWindowThemeAttribute', 'ptr', this.hwnd, 'int', 1 ; WTA_NONCLIENT
|
|
19
|
+
, 'int64*', 3 | (3<<32), 'int', 8) ; WTNCA_NODRAWCAPTION=1, WTNCA_NODRAWICON=2
|
|
20
|
+
|
|
21
|
+
static TitleBack := 'BackgroundWhite'
|
|
22
|
+
static TitleFore := 'c3F627F'
|
|
23
|
+
static TotalWidth := 350
|
|
24
|
+
this.AddText('x0 y0 w' TotalWidth ' h84 ' TitleBack)
|
|
25
|
+
this.AddPicture('x32 y16 w32 h32 ' TitleBack, A_AhkPath)
|
|
26
|
+
this.SetFont('s12', 'Segoe UI')
|
|
27
|
+
this.AddText('x+20 yp+4 ' TitleFore ' ' TitleBack, "AutoHotkey v" A_AhkVersion)
|
|
28
|
+
this.SetFont('s9')
|
|
29
|
+
|
|
30
|
+
; SS_SUNKEN := 0x1000 ; 4096
|
|
31
|
+
this.AddText('x-4 y84 w' TotalWidth+4 ' h188 0x1000 -Background')
|
|
32
|
+
|
|
33
|
+
this.AddText('xm yp+16', 'Install &to:')
|
|
34
|
+
dirEdit := this.AddEdit('vInstallDir w' TotalWidth - (2 * this.MarginX) - 88)
|
|
35
|
+
this.AddButton('vBrowseButton w80 x+8 yp-1', '&Browse')
|
|
36
|
+
.OnEvent('Click', 'Browse')
|
|
37
|
+
|
|
38
|
+
rect := Buffer(16, 0)
|
|
39
|
+
DllCall('GetClientRect', 'ptr', dirEdit.hwnd, 'ptr', rect)
|
|
40
|
+
NumPut('int', 4, 'int', 2, rect)
|
|
41
|
+
; DllCall('InflateRect', 'ptr', rect, 'int', 0, 'int', )
|
|
42
|
+
EM_SETRECT := 0xB3 ; 179
|
|
43
|
+
SendMessage 0xB3, 0, rect.ptr, dirEdit
|
|
44
|
+
|
|
45
|
+
this.AddGroupBox('xm y+0 w' TotalWidth - (2 * this.MarginX) ' h44')
|
|
46
|
+
this.AddText('xp+8 yp+16', "Install mode:")
|
|
47
|
+
this.AddRadio('vModeAll x+m yp Checked', "&All users")
|
|
48
|
+
.OnEvent('Click', 'ModeChange')
|
|
49
|
+
this.AddRadio('vModeUser x+4', "&Current user")
|
|
50
|
+
.OnEvent('Click', 'ModeChange')
|
|
51
|
+
this.AddRadio('vModePortable x+4 Disabled', "Portable")
|
|
52
|
+
.OnEvent('Click', 'ModeChange')
|
|
53
|
+
|
|
54
|
+
this.AddButton('vInstallButton x' (TotalWidth - 80) // 2 ' w80 y+36 Default', "&Install")
|
|
55
|
+
.OnEvent('Click', 'Install')
|
|
56
|
+
|
|
57
|
+
this.ModeChange()
|
|
58
|
+
|
|
59
|
+
this.MarginY := -1
|
|
60
|
+
this.Show('Hide w' TotalWidth)
|
|
61
|
+
this['InstallButton'].Focus()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
Browse(*) {
|
|
65
|
+
if ControlGetStyle(this['InstallDir']) & 0x800 { ; ES_READONLY
|
|
66
|
+
rootKey := this['ModeAll'].Value ? 'HKLM' : 'HKCU'
|
|
67
|
+
message := "Changing the installation directory is not recommended."
|
|
68
|
+
if InStr(RegRead(rootKey '\Software\AutoHotkey', 'Version', ''), '1.') = 1
|
|
69
|
+
message .= "`n`nThis installation package is designed to allow both v1 and v2 to be associated with .ahk files, but only if they are installed in the same directory."
|
|
70
|
+
message .= "`n`nExisting files will not be moved."
|
|
71
|
+
if MsgBox(message,, "OKCancel Icon!") != "OK"
|
|
72
|
+
return
|
|
73
|
+
this['InstallDir'].Opt('-ReadOnly')
|
|
74
|
+
}
|
|
75
|
+
dir := this.FileSelect('D', this['InstallDir'].Value '\', "Select installation directory")
|
|
76
|
+
if dir != '' {
|
|
77
|
+
this['InstallDir'].Value := dir
|
|
78
|
+
this.InstallDirChange()
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
ModeChange(p*) {
|
|
83
|
+
if !this.CheckAlreadyInstalled(p.Length = 0, true) {
|
|
84
|
+
; Ensure InstallDir makes sense for the new mode
|
|
85
|
+
installDir := this['InstallDir'].Value
|
|
86
|
+
if this['ModeAll'].Value {
|
|
87
|
+
if installDir = '' || installDir = InstallUtil.DefaultUserDir
|
|
88
|
+
this['InstallDir'].Value := InstallUtil.DefaultAllDir, this['InstallDir'].Opt('-ReadOnly')
|
|
89
|
+
} else
|
|
90
|
+
if installDir = '' || IsInProgramFiles(installDir)
|
|
91
|
+
this['InstallDir'].Value := InstallUtil.DefaultUserDir, this['InstallDir'].Opt('-ReadOnly')
|
|
92
|
+
}
|
|
93
|
+
this.UpdateShield()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
InstallDirChange(*) {
|
|
97
|
+
this.UpdateShield()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
UpdateShield() {
|
|
101
|
+
requireAdmin := this['ModeAll'].Value && !A_IsAdmin
|
|
102
|
+
SendMessage 0x160C, 0, requireAdmin, this['InstallButton'] ; BCM_SETSHIELD
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
CheckAlreadyInstalled(setMode:=false, setDir:=false) {
|
|
106
|
+
for rootKey in setMode ? ['HKCU', 'HKLM'] : [this['ModeAll'].Value ? 'HKLM' : 'HKCU'] {
|
|
107
|
+
dir := RegRead(rootKey '\Software\AutoHotkey', 'InstallDir', '')
|
|
108
|
+
if dir != '' {
|
|
109
|
+
if setDir {
|
|
110
|
+
this['InstallDir'].Value := dir
|
|
111
|
+
this['InstallDir'].Opt('+ReadOnly')
|
|
112
|
+
}
|
|
113
|
+
if setMode
|
|
114
|
+
this[A_Index = 1 ? 'ModeUser' : 'ModeAll'].Value := true
|
|
115
|
+
return dir
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return ''
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
Install(*) {
|
|
122
|
+
problem := ''
|
|
123
|
+
requireAdmin := this['ModeAll'].Value
|
|
124
|
+
installDir := this['InstallDir'].Value
|
|
125
|
+
buf := Buffer(260*2)
|
|
126
|
+
n := DllCall('GetFullPathName', 'str', installDir, 'uint', 260, 'ptr', buf, 'ptr', 0)
|
|
127
|
+
if !n || n > 259 {
|
|
128
|
+
MsgBox "Please enter a valid path.",, 'Icon!'
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
fullPath := StrGet(buf)
|
|
132
|
+
if installDir != fullPath {
|
|
133
|
+
problem .= '"' installDir '" resolves to "' fullPath '".`n`n'
|
|
134
|
+
installDir := fullPath
|
|
135
|
+
}
|
|
136
|
+
dir := this.CheckAlreadyInstalled()
|
|
137
|
+
if dir && dir != installDir
|
|
138
|
+
problem .= 'The existing installation in "' dir '" will not be moved or integrated with the new installation.`n`n'
|
|
139
|
+
if requireAdmin && !IsInProgramFiles(installDir) && dir != installDir
|
|
140
|
+
problem .= 'Enabling UI Access will not be possible because the installation directory is not a sub-directory of Program Files. Without UI Access, non-elevated scripts cannot interact with windows of elevated programs.`n`n'
|
|
141
|
+
if problem && MsgBox(problem,, 'OKCancel Default2 Icon!') = 'Cancel'
|
|
142
|
+
return
|
|
143
|
+
if A_IsCompiled && IsSet(Installation)
|
|
144
|
+
cmd := Format('"{1}" /to "{2}"', A_ScriptFullPath, installDir)
|
|
145
|
+
else
|
|
146
|
+
cmd := Format('"{1}" /script "{2}\install.ahk" /to "{3}"', A_AhkPath, A_ScriptDir, installDir)
|
|
147
|
+
if !requireAdmin
|
|
148
|
+
cmd .= ' /user'
|
|
149
|
+
else if !A_IsAdmin
|
|
150
|
+
cmd := '*RunAs ' cmd
|
|
151
|
+
try
|
|
152
|
+
Run cmd,,, &pid
|
|
153
|
+
catch as e {
|
|
154
|
+
if A_LastError != 1223 ; ERROR_CANCELLED
|
|
155
|
+
MsgBox e.Message "`n`n" e.Extra,, 'IconX'
|
|
156
|
+
} else {
|
|
157
|
+
this['InstallButton'].Enabled := false
|
|
158
|
+
this['InstallButton'].Text := "Installing..."
|
|
159
|
+
ProcessWaitClose pid
|
|
160
|
+
ExitApp
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
class InstallUtil {
|
|
166
|
+
static DefaultAllDir := (EnvGet('ProgramW6432') || A_ProgramFiles) '\AutoHotkey'
|
|
167
|
+
static DefaultUserDir := EnvGet('LocalAppData') '\Programs\AutoHotkey'
|
|
168
|
+
static DefaultDir := A_IsAdmin ? this.DefaultAllDir : this.DefaultUserDir
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
IsInProgramFiles(path) {
|
|
172
|
+
other := EnvGet(A_PtrSize=8 ? "ProgramFiles(x86)" : "ProgramW6432")
|
|
173
|
+
return InStr(path, A_ProgramFiles "\") = 1
|
|
174
|
+
|| other && InStr(path, other "\") = 1
|
|
175
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
; This script shows a GUI for uninstalling AutoHotkey or specific versions.
|
|
2
|
+
#include inc\bounce-v1.ahk
|
|
3
|
+
/* v1 stops here */
|
|
4
|
+
#requires AutoHotkey v2.0
|
|
5
|
+
|
|
6
|
+
#include inc\ui-base.ahk
|
|
7
|
+
#include install.ahk
|
|
8
|
+
|
|
9
|
+
#NoTrayIcon
|
|
10
|
+
#SingleInstance Force
|
|
11
|
+
|
|
12
|
+
A_ScriptName := "AutoHotkey Setup"
|
|
13
|
+
SetRegView 64
|
|
14
|
+
ModifySetupGui.Show()
|
|
15
|
+
|
|
16
|
+
class ModifySetupGui extends AutoHotkeyUxGui {
|
|
17
|
+
__new() {
|
|
18
|
+
super.__new(A_ScriptName, '-MinimizeBox -MaximizeBox')
|
|
19
|
+
|
|
20
|
+
this.inst := Installation()
|
|
21
|
+
this.inst.ResolveInstallDir()
|
|
22
|
+
versions := this.inst.GetComponents()
|
|
23
|
+
|
|
24
|
+
this.AddText(, "Remove which versions?")
|
|
25
|
+
iv := this.AddListView('vComponents Checked -Hdr R10 w248', ["Version"])
|
|
26
|
+
iv.OnEvent('ItemCheck', 'Checked')
|
|
27
|
+
for v, files in versions
|
|
28
|
+
iv.Add(files.HasProp('superseded') ? 'Check' : '', v)
|
|
29
|
+
|
|
30
|
+
anyChecked := iv.GetNext(0, 'C')
|
|
31
|
+
this.AddButton('vRemoveAll w120 ' (anyChecked ? '' : 'Default'), "Remove &all")
|
|
32
|
+
.OnEvent('Click', 'ClickedRemove')
|
|
33
|
+
this.AddButton('vRemove w120 yp ' (anyChecked ? 'Default' : 'Disabled'), "Remove &checked")
|
|
34
|
+
.OnEvent('Click', 'ClickedRemove')
|
|
35
|
+
|
|
36
|
+
if !this.inst.UserInstall && !A_IsAdmin {
|
|
37
|
+
SendMessage 0x160C,, true, 'Button1', this ; BCM_SETSHIELD := 0x160C
|
|
38
|
+
SendMessage 0x160C,, true, 'Button2', this
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
ClickedRemove(btn, *) {
|
|
43
|
+
cmd := ''
|
|
44
|
+
if btn.Name = 'Remove' {
|
|
45
|
+
n := 0, iv := this['Components'], count := 0
|
|
46
|
+
while n := iv.GetNext(n, 'C')
|
|
47
|
+
cmd .= ',' iv.GetText(n), ++count
|
|
48
|
+
if count = iv.GetCount()
|
|
49
|
+
cmd := '' ; All are selected - do a full uninstall
|
|
50
|
+
else
|
|
51
|
+
cmd := ' "' SubStr(cmd, 2) '"'
|
|
52
|
+
}
|
|
53
|
+
cmd := Format('"{1}" "{2}\install.ahk" /uninstall{3}', A_AhkPath, A_ScriptDir, cmd)
|
|
54
|
+
if (!this.inst.UserInstall || A_Args.Length && A_Args[1] = '/elevate') && !A_IsAdmin
|
|
55
|
+
cmd := '*RunAs ' cmd
|
|
56
|
+
try {
|
|
57
|
+
Run cmd
|
|
58
|
+
ExitApp
|
|
59
|
+
}
|
|
60
|
+
catch as e
|
|
61
|
+
if !InStr(e.Message e.Extra, 'cancel')
|
|
62
|
+
throw e
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
Checked(iv, *) {
|
|
66
|
+
this['Remove'].Enabled := iv.GetNext(0, 'C')
|
|
67
|
+
}
|
|
68
|
+
}
|