├── .gitattributes
├── DocumentTemplates
├── DocumentTemplatesExamples.zip
└── readme.md
├── F4MiniMenu.ahk
├── F4TCIE.ahk
├── changelog.md
├── img
├── f4-configure-editors.png
├── f4-confirm-maximum.png
├── f4-editor-setttings.png
├── f4-foreground-menu.png
└── f4-general-settings.png
├── inc
├── CLIParser.ahk
├── Editors.ahk
├── FilteredMenu.ahk
├── HelperFunctions.ahk
├── LoadSettings1.ahk
├── LoadSettings2.ahk
├── Menu.ahk
├── Settings.ahk
└── TotalCommanderPath.ahk
├── lib
├── AutoXYWH.ahk
├── DoubleCommander.ahk
├── DropFiles.ahk
├── Everything.ahk
├── Explorer.ahk
├── GetPos.ahk
├── QDir.ahk
├── XA.ahk
├── XYPlorer.ahk
├── class_lv_rows.ahk
├── dpi.ahk
├── iob.ahk
├── log.ahk
├── osdtip.ahk
└── tc.ahk
├── license.txt
├── readme.md
└── res
└── f4.ico
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/DocumentTemplates/DocumentTemplatesExamples.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hi5/F4MiniMenu/34d131ef7b47bef92dd4e120032674ac249ce5b3/DocumentTemplates/DocumentTemplatesExamples.zip
--------------------------------------------------------------------------------
/DocumentTemplates/readme.md:
--------------------------------------------------------------------------------
1 | # Document Templates for F4TCIE.ahk
2 |
3 | Note that this is an additional functionality, if you don't place any template.* files
4 | in this folder F4TCIE will not use it.
5 |
6 | ## Introduction
7 |
8 | By default you can use the keyboard shortcut Shift+F4 or the
9 | *cm_EditNewFile* command to create a new text file and open this in your defined text
10 | editor.
11 |
12 | By setting F4TCIE.ahk as editor:
13 |
14 | TC, Configuration, Edit/View, Editor:
15 | drive:\path-to\F4TCIE.ahk "%1"
16 |
17 | you can extend this functionality to the programs you defined in F4MiniMenu.
18 |
19 | Unlike text editors, many program simply don't accept or understand the new empty
20 | file Total Commander creates. They may not start correctly or generate an error message.
21 | Here is where F4TCIE comes in. It checks if there is a "template.ext" file for the new
22 | file you just created, if so it copies that template to your current active panel and
23 | start your preferred program which you defined in F4MiniMenu.
24 |
25 | So instead of opening your text editor when you create a new "MyImageFile.PNG" it
26 | can start your preferred Graphics program for PNG files.
27 |
28 | If it can't find a template, it will simply launch your default editor.
29 |
30 | When you add new templates to this folder you need to Update (scan) the
31 | available templates via the "Scan Document Templates" in the Tray or Foreground
32 | menu OR restart F4MiniMenu.
33 |
34 | You can find two examples in DocumentTemplatesExamples.zip to illustrate how it
35 | works (RTF, PNG) - you can of course replace these with your own Template files.
36 |
37 | ## Limitation(s)
38 |
39 | * It won't work in/with ZIP files (but will copy file to Active panel)
40 | * Shift+F4 doesn't work in FTP panels (default TC behaviour)
41 |
42 |
--------------------------------------------------------------------------------
/F4MiniMenu.ahk:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Script : F4MiniMenu.ahk for Total Commander - AutoHotkey 1.1+ (Ansi and Unicode)
4 | Version : v1.47
5 | Author : hi5
6 | Last update : 09 February 2025
7 | Purpose : Minimalistic clone of the F4 Menu program for Total Commander (open selected files in editor(s))
8 | Source : https://github.com/hi5/F4MiniMenu
9 |
10 | Note : ; % used to resolve syntax highlighting feature bug of N++
11 |
12 | */
13 |
14 | #Requires AutoHotkey v1.1.31+
15 | #SingleInstance, Force
16 | #UseHook
17 | #NoEnv
18 | SetBatchlines, -1
19 | SetWorkingDir, %A_ScriptDir%
20 | SetTitleMatchMode, 2
21 | ; Setup variables, menu, hotkeys etc
22 |
23 | F4Version:="v1.47"
24 |
25 | ;
26 | ;@Ahk2Exe-SetFileVersion 1.47
27 | ;@Ahk2Exe-SetProductName F4MiniMenu
28 | ;@Ahk2Exe-SetDescription F4MiniMenu: Open files from TC
29 | ;@Ahk2Exe-SetProductVersion Compiled with AutoHotkey v%A_AhkVersion%
30 | ;@Ahk2Exe-SetCopyright MIT License - (c) https://github.com/hi5
31 | ;
32 |
33 | ;
34 | IfNotExist, %A_ScriptDir%\res
35 | FileCreateDir, %A_ScriptDir%\res
36 | FileInstall, res\f4.ico, %A_ScriptDir%\res\f4.ico
37 | ;
38 |
39 | global AllExtensions:=""
40 | global TmpFileList:=""
41 | global Commander_Path:=""
42 | global Commander_Ini:=""
43 | MatchList:=""
44 | MenuPadding:=" "
45 | DefaultShortName:=""
46 |
47 | EnvGet, TmpFileList, temp
48 |
49 | If (TmpFileList = "")
50 | TmpFileList:=A_ScriptDir
51 |
52 | TmpFileList .= "\$$f4mtmplist$$.m3u"
53 |
54 | ; shared with F4TCIE
55 | #Include %A_ScriptDir%\inc\LoadSettings1.ahk
56 |
57 | GroupAdd, TCOnly, ahk_class TTOTAL_CMD ahk_exe TOTALCMD.EXE
58 | GroupAdd, TCOnly, ahk_class TTOTAL_CMD ahk_exe TOTALCMD64.EXE
59 |
60 | FileDelete, % TmpFileList
61 |
62 | Try
63 | Menu, tray, icon, res\f4.ico
64 | Menu, tray, Tip , F4MiniMenu - %F4Version%
65 | Menu, tray, NoStandard
66 | Menu, tray, Add, F4MiniMenu - %F4Version%, DoubleTrayClick
67 | Try
68 | Menu, tray, icon, F4MiniMenu - %F4Version%, res\f4.ico
69 | Menu, tray, Default, F4MiniMenu - %F4Version%
70 | Menu, tray, Click, 1 ; this will show the tray menu because we send {rbutton} at the DoubleTrayClick label
71 | Menu, tray, Add,
72 | Menu, tray, Add, &Open, MenuHandler
73 | Menu, tray, Add, &Reload this script, MenuHandler
74 | Menu, tray, Icon,&Reload this script, shell32.dll, 239
75 |
76 | Menu, tray, Add, &Edit this script, MenuHandler
77 | Try
78 | Menu, tray, Icon,&Edit this script, comres.dll, 7
79 | If A_IsCompiled
80 | Menu, tray, Disable, &Edit this script
81 |
82 | Menu, tray, Add,
83 | Menu, tray, Add, &Suspend Hotkeys, MenuHandler
84 | Try
85 | Menu, tray, Icon,&Suspend Hotkeys, %A_AhkPath%, 3
86 | Menu, tray, Add, &Pause Script, MenuHandler
87 | Try
88 | Menu, tray, Icon,&Pause Script, %A_AhkPath%, 4
89 | Menu, tray, Add,
90 | Menu, tray, Add, Settings, Settings
91 | Try
92 | Menu, tray, Icon, Settings, shell32.dll, 170
93 | Menu, tray, Add, Configure editors, ConfigEditors
94 | Try
95 | Menu, tray, Icon, Configure Editors, shell32.dll, 70
96 | Menu, tray, Add, Scan Document Templates, DocumentTemplatesScan
97 | Try
98 | Menu, tray, Icon, Scan Document Templates, shell32.dll, 172
99 | Menu, tray, Add,
100 | Menu, tray, Add, Exit, ExitSettings
101 | Try
102 | Menu, tray, Icon, Exit, shell32.dll, 132
103 |
104 | If !FileExist(F4ConfigFile) and !FileExist(F4ConfigFile ".bak") ; most likely first run, no need to show error message
105 | Gosub, CreateNewConfig
106 |
107 | ; shared with F4TCIE
108 | #Include %A_ScriptDir%\inc\LoadSettings2.ahk
109 |
110 | If (Error = 1)
111 | {
112 | ErrorText=
113 | (Join`n LTRIM
114 | There seems to be an error with the settings file.
115 | F4MiniMenu will try to create default configuration and restart.
116 | Be sure to check the last backup of your settings in "%F4ConfigFile%"
117 | Be sure to exit F4MiniMenu before trying to restore any backup settings.
118 | )
119 |
120 | MsgBox, 16, F4MiniMenu, %ErrorText%
121 | Reload
122 | }
123 |
124 | ; Create backup file
125 | FileCopy, %F4ConfigFile%, %F4ConfigFile%.bak, 1
126 |
127 | ; Hotkey groups (menus)
128 | GroupAdd, TCF4Windows, ahk_class TTOTAL_CMD ahk_exe TOTALCMD.EXE
129 | GroupAdd, TCF4Windows, ahk_class TTOTAL_CMD ahk_exe TOTALCMD64.EXE
130 | GroupAdd, TCF4Windows, ahk_class TQUICKSEARCH
131 |
132 | If MatchList.settings.Lister
133 | GroupAdd, TCF4Windows, ahk_class TLister
134 | If MatchList.settings.FindFiles
135 | GroupAdd, TCF4Windows, ahk_class TFindFile
136 |
137 |
138 | ; Add other file managers if any
139 | If MatchList.settings.Explorer
140 | {
141 | GroupAdd, TCF4Windows, ahk_class CabinetWClass
142 | GroupAdd, TCF4Windows, ahk_class ExploreWClass
143 | }
144 |
145 | If MatchList.settings.Everything
146 | {
147 | GroupAdd, TCF4Windows, ahk_exe Everything.exe
148 | GroupAdd, TCF4Windows, ahk_exe Everything64.exe
149 | }
150 |
151 | If (MatchList.settings.DoubleCommander <> "") ; note that some versions of DC report ahk_class TTOTAL_CMD ahk_exe doublecmd.exe
152 | {
153 | GroupAdd, TCF4Windows, ahk_class DClass ahk_exe doublecmd.exe ; v0.9
154 | GroupAdd, TCF4Windows, ahk_class TTOTAL_CMD ahk_exe doublecmd.exe ; v1.0
155 | }
156 |
157 | If (MatchList.settings.XYPlorer <> "")
158 | {
159 | GroupAdd, TCF4Windows, ahk_exe XYPlorer.exe
160 | GroupAdd, TCF4Windows, ahk_exe XYPlorerFree.exe
161 | }
162 |
163 | If (MatchList.settings.QDir <> "")
164 | {
165 | GroupAdd, TCF4Windows, ahk_exe Q-Dir.exe
166 | GroupAdd, TCF4Windows, ahk_exe Q-Dir_x64.exe
167 | }
168 |
169 | ; /Add other file managers if any
170 |
171 | If (MatchList.settings.TCStart = 2) and !WinExist("ahk_class TTOTAL_CMD")
172 | {
173 | If FileExist(MatchList.settings.TCPath)
174 | Run % MatchList.settings.TCPath,,UseErrorLevel,TCOutputVarPID ; %
175 | WinWait, ahk_class TTOTAL_CMD
176 | }
177 |
178 | If (MatchList.settings.TCStart = 3)
179 | {
180 | If FileExist(MatchList.settings.TCPath)
181 | Run % MatchList.settings.TCPath,,UseErrorLevel,TCOutputVarPID ; %
182 | WinWait, ahk_class TTOTAL_CMD
183 | }
184 |
185 | #Include %A_ScriptDir%\inc\CLIParser.ahk
186 |
187 |
188 | ; shared with F4MM
189 | #Include %A_ScriptDir%\inc\TotalCommanderPath.ahk
190 |
191 | Gosub, DocumentTemplatesScan
192 |
193 | Gosub, BuildMenu
194 |
195 | ; Build master list to quickly open in default program if not found
196 | Gosub, GetAllExtensions
197 |
198 | HotKeyState:="On"
199 | Gosub, SetHotkeys
200 |
201 | ; Clear tmp file(s)
202 | OnExit, ExitSettings
203 |
204 | If CLI_Editors
205 | {
206 | Gosub, ConfigEditors
207 | WinWaitClose, F4MiniMenu - Editor Settings ahk_class AutoHotkeyGUI
208 | Sleep 1000
209 | ExitApp
210 | }
211 |
212 | If CLI_Settings
213 | {
214 | Gosub, Settings
215 | WinWaitClose, F4MiniMenu - Settings ahk_class AutoHotkeyGUI
216 | Sleep 1000
217 | ExitApp
218 | }
219 |
220 | If CLI_ShowMenu
221 | {
222 | Gosub, ShowMenu
223 | Sleep 1000
224 | ExitApp
225 | }
226 |
227 | If CLI_FilteredMenu
228 | {
229 | Gosub, FilteredMenu
230 | Sleep 1000
231 | ExitApp
232 | }
233 |
234 | If CLI_Exit and ((CLI_ShowMenu <> 1) and (CLI_FilteredMenu <> 1))
235 | {
236 | Gosub, Process
237 | Sleep 1000
238 | MsgBox
239 | ExitApp
240 | }
241 |
242 | ; End of Auto-execute section
243 | If (Matchlist.settings.F4MMCloseAll = 1)
244 | {
245 | WinWaitClose, ahk_class TTOTAL_CMD
246 | ExitApp
247 | }
248 | Else If (Matchlist.settings.F4MMClosePID = 1)
249 | {
250 | Sleep 5000
251 | WinWaitClose, ahk_pid %TCOutputVarPID%
252 | ExitApp
253 | }
254 | Return
255 |
256 | Process:
257 | ProcessFiles(MatchList)
258 | MatchList.Temp.Files:="",MatchList.Temp.SelectedExtensions:="",MatchList.Delete("Temp")
259 | If CLI_Exit
260 | ExitApp
261 | Return
262 |
263 | ; Function executed by background hotkey (open directly)
264 | ProcessFiles(MatchList, SelectedEditor = "-1")
265 | {
266 | Global ArchiveExtentions
267 | Done:=[]
268 | Stop:=0
269 | If (MatchList.Temp.Files = "")
270 | Files:=GetFiles() ; Get list of selected files in TC, one per line
271 | else
272 | Files:=MatchList.Temp.Files
273 | MatchList.Temp.Files:=""
274 |
275 | ; Check if we possibly have selected file(s) from an archive
276 | If RegExMatch(Files,"iUm)" ArchiveExtentions)
277 | {
278 | Files:=StrReplace(Files,"`r","")
279 | If InStr(Files,"`n")
280 | Check:=SubStr(Files,1,InStr(Files,"`n")-1)
281 | Else
282 | Check:=Files
283 |
284 | If WinActive("ahk_class TTOTAL_CMD ahk_exe TOTALCMD.EXE") or WinActive("ahk_class TTOTAL_CMD ahk_exe TOTALCMD64.EXE")
285 | {
286 | IfNotExist, %check% ; additional check, if the file is from an archive it won't exist
287 | { ; therefore we resort to the internal TC Edit command - added for v0.51
288 | SendMessage 1075, 904, 0, , ahk_class TTOTAL_CMD ; Edit (Notepad)
289 | Return
290 | }
291 | }
292 |
293 | If MatchList.settings.DoubleCommander and DoubleCommander_Active()
294 | {
295 | IfNotExist, %check% ; additional check, if the file is from an archive it won't exist
296 | { ; therefore we resort to sending enter, now user can choose what to do (close or edit using default program)
297 | Send {enter}
298 | Return
299 | }
300 | }
301 |
302 | If MatchList.settings.Explorer and Explorer_Active()
303 | {
304 | IfNotExist, %check% ; additional check, if the file is from an archive it won't exist
305 | { ; don't allow it and return for Explorer
306 | MsgBox, 16, F4MiniMenu, You can not edit files from Archives when using Explorer.
307 | Return
308 | }
309 | }
310 |
311 | }
312 |
313 | SelectedFiles:=CountFiles(Files)
314 |
315 | If (SelectedFiles > MatchList.settings.MaxFiles)
316 | {
317 | ; Technique from http://www.autohotkey.com/docs/scripts/MsgBoxButtonNames.htm
318 | SetTimer, ChangeButtonNames, 10
319 | MsgBox, 4150, Maximum files, % "Number of selected files: [" SelectedFiles "]`nDo wish to process them all`nor stop at the maximum?: [" MatchList.settings.MaxFiles "]" ; %
320 | IfMsgBox, Cancel
321 | Return
322 | else IfMsgBox, Continue
323 | Stop:=1
324 | }
325 |
326 | Loop, parse, Files, `n, `r
327 | {
328 | If (Stop = 1) and (A_Index > Matchlist.settings.MaxFiles)
329 | Break
330 | open:=A_LoopField
331 | SplitPath, A_LoopField, , , OutExtension
332 |
333 | ; TODO: check for "checked" (= active) editor from settings
334 | for k, v in MatchList
335 | {
336 | Index:=A_Index
337 | CheckFileExt:=RegExExtensions(v.ext)
338 | If CheckFile(done,open) ; safety check - otherwise each file would be processed for all editors
339 | Break
340 | If (SelectedEditor < 0) ; Find out which editor to use, first come first serve
341 | {
342 | ;If OutExtension not in %AllExtensions% ; Open in default program
343 | If !RegExMatch(OutExtension,AllExtensions) ; Open in default program - v0.9 allow for wildcards
344 | {
345 | FileList1 .= open "`n"
346 | Done.Insert(open)
347 | }
348 | ;Else If OutExtension in % v.ext ; Open in defined program %
349 | Else If RegExMatch(OutExtension,CheckFileExt) ; Open in defined program - v0.9 allow for wildcards
350 | {
351 | FileList%Index% .= open "`n"
352 | Done.Insert(open)
353 | }
354 | }
355 | Else If (SelectedEditor > 0) ; Use selected editor from the Menu (Foreground option)
356 | {
357 | FileList%SelectedEditor% .= open "`n"
358 | Done.Insert(open)
359 | }
360 | }
361 | }
362 |
363 | for k, v in MatchList
364 | {
365 | Index:=A_Index
366 | list:=Trim(FileList%Index%,"`n")
367 | If (list = "")
368 | Continue
369 | If (v.Method = "cmdline")
370 | {
371 | cmdfiles:=""
372 | Loop, parse, list, `n, `r
373 | cmdfiles .= """" A_LoopField """" A_Space ; " fix highlighting
374 | OpenFile(v, cmdfiles, MatchList.Settings.MaxWinWaitSec)
375 | If MatchList.Settings.log
376 | Log(A_Now " : ProcessFiles, cmdline -> " v.exe "|" cmdfiles "|" MatchList.Settings.MaxWinWaitSec,MatchList.Settings.logFile)
377 | cmdfiles:=""
378 | }
379 | else If (v.Method = "FileList")
380 | {
381 | FileDelete, % TmpFileList
382 | FileAppend, %list%, %TmpFileList%, UTF-8-RAW
383 | OpenFile(v, TmpFileList, MatchList.Settings.MaxWinWaitSec)
384 | If MatchList.Settings.log
385 | Log(A_Now " : ProcessFiles, FileList -> " v.exe "|" TmpFileList "|" MatchList.Settings.MaxWinWaitSec,MatchList.Settings.logFile)
386 | }
387 | Else If (v.Method <> "Files")
388 | {
389 | Loop, parse, list, `n
390 | {
391 | If (A_LoopField = "")
392 | Continue
393 | OpenFile(v, A_LoopField, MatchList.Settings.MaxWinWaitSec)
394 | If MatchList.Settings.log
395 | Log("`n" A_Now " : ProcessFiles, Files -> " v.exe "|" A_LoopField "|" MatchList.Settings.MaxWinWaitSec,MatchList.Settings.logFile)
396 | }
397 | }
398 | }
399 | PostMessage 1075, 524, 0, , ahk_class TTOTAL_CMD ; Unselect all (files+folders)
400 | }
401 |
402 | ; Get a list of extensions from selected files we can use to build filtered menu
403 | GetExt(Files)
404 | {
405 | Global MatchList
406 | Loop, parse, files, `n, `r
407 | {
408 | SplitPath, A_LoopField,,, OutExtension
409 | Ext .= OutExtension "|"
410 | }
411 | MatchList.Temp["SelectedExtensions"]:=Trim(Ext,"|")
412 | }
413 |
414 | ; Process other applications and windows first (find files, lister)
415 | ; Get a list of selected files using internal TC commands (see totalcmd.inc for references)
416 | GetFiles()
417 | {
418 | Global MatchList, CLI_Exit, CLI_File, ListerWindowClose
419 |
420 | If CLI_Exit
421 | {
422 | FileRead, Files, %CLI_File%
423 | MatchList.Temp["Files"]:=Files
424 | If MatchList.Settings.log
425 | Log(A_Now " : GetFiles, CLI_Exit ->`n" Files "`n-----------------------",MatchList.Settings.logFile)
426 | Return Files
427 | }
428 |
429 | If MatchList.settings.Explorer and Explorer_Active()
430 | {
431 | Files:=Explorer_GetSelection()
432 | MatchList.Temp["Files"]:=Files
433 | If MatchList.Settings.log
434 | Log(A_Now " : GetFiles, Explorer ->`n" Files "`n-----------------------",MatchList.Settings.logFile)
435 | Return Files
436 | }
437 |
438 | If MatchList.settings.Everything and Everything_Active()
439 | {
440 | Files:=Everything_GetSelection()
441 | MatchList.Temp["Files"]:=Files
442 | If MatchList.Settings.log
443 | Log(A_Now " : GetFiles, Everything ->`n" Files "`n-----------------------",MatchList.Settings.logFile)
444 | Return Files
445 | }
446 |
447 | If MatchList.settings.DoubleCommander and DoubleCommander_Active()
448 | {
449 | Files:=DoubleCommander_GetSelection()
450 | MatchList.Temp["Files"]:=Files
451 | If MatchList.Settings.log
452 | Log(A_Now " : GetFiles, DoubleCommander ->`n" Files "`n-----------------------",MatchList.Settings.logFile)
453 | Return Files
454 | }
455 |
456 | If MatchList.settings.XYPlorer and XYPlorer_Active()
457 | {
458 | Files:=XYPlorer_GetSelection()
459 | MatchList.Temp["Files"]:=Files
460 | If MatchList.Settings.log
461 | Log(A_Now " : GetFiles, XYPlorer ->`n" Files "`n-----------------------",MatchList.Settings.logFile)
462 | Return Files
463 | }
464 |
465 | If MatchList.settings.QDir and QDir_Active()
466 | {
467 | Files:=QDir_GetSelection()
468 | MatchList.Temp["Files"]:=Files
469 | If MatchList.Settings.log
470 | Log(A_Now " : GetFiles, QDir ->`n" Files "`n-----------------------",MatchList.Settings.logFile)
471 | Return Files
472 | }
473 |
474 | If WinActive("ahk_class TLister")
475 | {
476 | WinGetActiveTitle, Files
477 | ; check once if ListerWindowClose was already read in case F4MM was started before TC
478 | ; to obtain environment variable Commander_Ini_Path) and read value from wincmd.ini
479 | If (ListerWindowClose = "") or (ListerWindowClose = "ERROR")
480 | ListerWindowClose()
481 | Files:=RegExReplace(Files,"U)^.*\[(.*).$","$1")
482 | If ListerWindowClose in 2,3
483 | WinClose, A
484 | If MatchList.Settings.log
485 | Log(A_Now " : GetFiles, Lister ->`n" Files "`n-----------------------",MatchList.Settings.logFile)
486 | Return Files
487 | }
488 |
489 | If MatchList.settings.QuickView
490 | {
491 | WinGetText, Files, ahk_class TTOTAL_CMD, Lister
492 | If (Files <> "")
493 | {
494 | RegExMatch(Files,"U) - \K\[(.*)\]`r?`n",Files)
495 | If MatchList.Settings.log
496 | Log(A_Now " : GetFiles, QuickView ->`n" Files "`n-----------------------",MatchList.Settings.logFile)
497 | Return Files1
498 | }
499 | }
500 |
501 | If WinActive("ahk_class TFindFile") ; class names may change between versions, below for TC11
502 | {
503 | ; ControlGet, Files, Choice,, TWidthListBox1, ahk_class TFindFile; for TC10
504 | ControlGet, Files, Choice,, TMyListBox2, ahk_class TFindFile
505 | If (ErrorLevel = 1) or (Files = "")
506 | ControlGet, Files, Choice,, LCLListbox2, ahk_class TFindFile
507 | IfNotInString, Files,[ ; make sure you haven't selected a directory or the first line
508 | {
509 | If MatchList.Settings.log
510 | Log(A_Now " : GetFiles, Find files ->`n" Files "`n-----------------------",MatchList.Settings.logFile)
511 | Return Files
512 | }
513 | }
514 |
515 | ClipboardSave:=ClipboardAll
516 | Clipboard:=""
517 | PostMessage 1075, 2018, 0, , ahk_class TTOTAL_CMD ; Copy names with full path to clipboard
518 | Sleep 100
519 | Files:=Clipboard
520 | Clipboard:=ClipboardSave
521 | ClipboardSave:=""
522 | ; PostMessage 1075, 524, 0, , ahk_class TTOTAL_CMD ; Unselect all (files+folders)
523 | MatchList.Temp["Files"]:=Files
524 | If MatchList.Settings.log
525 | Log(A_Now " : GetFiles, TC File Panel ->`n" Files "`n-----------------------",MatchList.Settings.logFile)
526 | Return Files
527 | }
528 |
529 | ; Function to determine which method to use to open a file
530 | ; normal: filepath\file1.ext
531 | ; cmdline: "filepath\file1.ext" "filepath\file2.ext" "filepath\file3.ext"
532 | ; filelist: %temp%\$$f4mtmplist$$.m3u OR %A_ScriptDir%\$$f4mtmplist$$.m3u
533 | ; drag&drop: filepath\file1.ext
534 | OpenFile(Editor,open,MaxWinWaitSec=2)
535 | {
536 | If (MaxWinWaitSec = "") or (MaxWinWaitSec < 2) or (MaxWinWaitSec = "ERROR")
537 | MaxWinWaitSec:=2
538 | func:=Editor.Method
539 | title:="ahk_exe " Editor.Exe
540 | If (func = "FileList")
541 | {
542 | ; if GetInput() was cancelled don't process windowmode below
543 | result:=Normal(Editor.Exe,open,Editor.Delay,Editor.Parameters,Editor.StartDir)
544 | }
545 | Else If IsFunc(func) ; takes care of normal, drag & drop, and cmdline
546 | {
547 | ; if GetInput() was cancelled don't process windowmode below
548 | result:=%func%(Editor.Exe,open,Editor.Delay,Editor.Parameters,Editor.StartDir)
549 | }
550 |
551 | ; Moved above window actions in v1.1
552 | ; Added WinExist check to give program some time to start first
553 | ; before proceeding - similar to Delay
554 | If !WinExist(title)
555 | Sleep % Editor.open
556 |
557 | ; Program was started so we can continue.
558 | ; Result can be > 1 if defined program was not found
559 | ; and we resorted to default editor as a fall back, see normal()
560 | if (result = 1)
561 | {
562 | If (Editor.windowmode = 1) ; normal (activate)
563 | {
564 | WinWait, %title%,, % MaxWinWaitSec
565 | WinActivate, %title%
566 | }
567 | Else If (Editor.windowmode = 2) ; maximize
568 | {
569 | WinWait, %title%,, % MaxWinWaitSec
570 | WinMaximize, %title%
571 | }
572 | Else If (Editor.windowmode = 3) ; minimize
573 | {
574 | WinWait, %title%,, % MaxWinWaitSec
575 | WinMinimize, %title%
576 | }
577 | }
578 |
579 | ;@Ahk2Exe-IgnoreBegin
580 | #include *i %A_ScriptDir%\inc\WinActivatePrivateRules.ahk
581 | ;@Ahk2Exe-IgnoreEnd
582 |
583 | Return open
584 | }
585 |
586 | Normal(program,file,delay,parameters,startdir)
587 | {
588 | ; Run, Target, WorkingDir, Max|Min|Hide
589 | Global MatchList
590 | ;program:=GetTCCommander_Path(program)
591 | program:=GetPath(program)
592 | execute:=1
593 | GetInput(parameters,file,startdir,execute,program)
594 | if !execute
595 | Return execute
596 | startdir:=GetPath(startdir)
597 | if (file = "")
598 | Try
599 | {
600 | Run, %program% %parameters%, %startdir%
601 | }
602 | Catch
603 | {
604 | ;program:=GetTCCommander_Path(MatchList[1].Exe)
605 | program:=GetPath(MatchList[1].Exe)
606 | startdir:=GetPath(startdir)
607 | Run, %program% %parameters%, %startdir%
608 | execute++
609 | }
610 | else
611 | Try
612 | {
613 | if (file <> "")
614 | Run, %program% %parameters% "%file%", %startdir%
615 | else
616 | Run, %program% %parameters%, %startdir%
617 | }
618 | Catch
619 | {
620 | ;program:=GetTCCommander_Path(MatchList[1].Exe)
621 | program:=GetPath(MatchList[1].Exe)
622 | startdir:=GetPath(startdir)
623 | Run, %program% %parameters% "%file%", %startdir%
624 | ; OSDTIP_Pop(MainText, SubText, TimeOut, Options, FontName, Transparency)
625 | OSDTIP_Pop("F4MiniMenu", "Defined editor/program not found`nReverting to default editor", -750,"W230 H80 U1")
626 | execute++
627 | }
628 | Return execute
629 | }
630 |
631 | cmdline(program,file,delay,parameters,startdir)
632 | {
633 | ; Run, Target, WorkingDir, Max|Min|Hide
634 | ;program:=GetTCCommander_Path(program)
635 | program:=GetPath(program)
636 | execute:=1
637 | GetInput(parameters,file,startdir,execute,program)
638 | if !execute
639 | Return execute
640 | startdir:=GetPath(startdir)
641 | Run, %program% %parameters% %file%, %startdir%
642 | Return execute
643 | }
644 |
645 | DragDrop(program,file,delay,parameters,startdir)
646 | {
647 | ; Run, Target, WorkingDir, Max|Min|Hide
648 | ;program:=GetTCCommander_Path(program)
649 | program:=GetPath(program)
650 | title:="ahk_exe " program
651 | IfWinNotExist, %title%
652 | {
653 | startdir:=GetPath(startdir)
654 | Run, %program% %parameters% "%file%", %startdir%
655 | ; in case there are more files to be processed we need the extra time after
656 | ; first startup as some programs are sloooooow and we have to make sure it
657 | ; can accept drag & drop files. It is is only for the first file in the list
658 | Sleep %delay%
659 | Return 1
660 | }
661 |
662 | ;@Ahk2Exe-IgnoreBegin
663 | #include *i %A_ScriptDir%\inc\DragDropPrivateRules.ahk
664 | ;@Ahk2Exe-IgnoreEnd
665 |
666 | Return 1
667 | }
668 |
669 | ; Helper functions & Labels
670 |
671 | CheckCmdLine(Method,CountFiles)
672 | {
673 | If (Method <> "cmdline")
674 | Return 1
675 | StrReplace(CountFiles, Chr(34) A_Space Chr(34), , OutputVarCount)
676 | If (OutputVarCount > 1)
677 | Return 0
678 | Return 1
679 | }
680 |
681 | GetInput(byref parameters, byref file, byref startdir, byref execute, program)
682 | {
683 | WinGetActiveStats, A, W, H, X, Y
684 | X:=X+(W/2)-205
685 | Y:=Y+(H/2)-110
686 | if InStr(parameters,"?")
687 | {
688 | AskParameters:=1
689 | StringReplace, parameters, parameters, ?,, All
690 | }
691 | if InStr(startdir,"?")
692 | {
693 | AskStartDir:=1
694 | StringReplace, startdir, startdir, ?,, All
695 | }
696 | if InStr(parameters,"%p")
697 | parameters:=StrReplace(parameters,"%p",GetTCFields("%p"))
698 | if InStr(parameters,"%t")
699 | parameters:=StrReplace(parameters,"%t",GetTCFields("%t"))
700 | if InStr(parameters,"%o")
701 | parameters:=StrReplace(parameters,"%o",GetTCFields("%o",file))
702 | if InStr(parameters,"%n")
703 | parameters:=StrReplace(parameters,"%n",GetTCFields("%n",file))
704 | if InStr(parameters,"%m")
705 | parameters:=StrReplace(parameters,"%m",GetTCFields("%m",file))
706 | if InStr(parameters,"%$date")
707 | {
708 | DateTimeObject:=GetTCFields(parameters)
709 | parameters:=StrReplace(parameters,DateTimeObject[1],DateTimeObject[2])
710 | DateTimeObject:=""
711 | }
712 |
713 | if InStr(parameters,"%e")
714 | parameters:=StrReplace(parameters,"%e",GetTCFields("%e",file))
715 | ; %f4? placeholders for optional parameters:
716 | ; %f41 placeholder to alter position of filenames on the command line.
717 | ;
718 | if InStr(parameters,"%f41")
719 | {
720 | parameters:=StrReplace(parameters, "%f41", file)
721 | file:=""
722 | }
723 |
724 | if InStr(startdir,"%p")
725 | startdir:=StrReplace(startdir,"%p",GetTCFields("%p"))
726 | if InStr(startdir,"%t")
727 | startdir:=StrReplace(startdir,"%t",GetTCFields("%t"))
728 |
729 | if (AskParameters = 1) or (AskStartDir = 1)
730 | {
731 | Gui, AskInput: +AlwaysOnTop +ToolWindow
732 | Gui, AskInput: Margin, 5, 5
733 | if (AskParameters = 1)
734 | {
735 | Gui, AskInput:Add, Text, xp y5 , Command line parameters:
736 | Gui, AskInput:Add, Edit, xp yp+20 w400 h20 , %parameters%
737 | }
738 | if (AskParameters <> 1) and (parameters <> "")
739 | {
740 | Gui, AskInput:Add, Text, xp y58 , Command line parameters:
741 | Gui, AskInput:Add, Edit, xp yp+20 w400 h20 ReadOnly , %parameters%
742 | }
743 |
744 | ; if (file <> "")
745 | ; {
746 | ; Gui, AskInput:Add, Text, x5 yp+30 , File(s):
747 | ; Gui, AskInput:Add, Edit, x5 yp+20 w400 h20 , %file%
748 | ; }
749 |
750 | if (AskStartDir = 1)
751 | {
752 | Gui, AskInput:Add, Text, xp yp+30 , Start directory:
753 | Gui, AskInput:Add, Edit, xp yp+20 w400 h20 , %startdir%
754 | }
755 | if (AskStartDir <> 1) and (startdir <> "")
756 | {
757 | Gui, AskInput:Add, Text, xp yp+30 , Start directory:
758 | Gui, AskInput:Add, Edit, xp yp+20 w400 h20 ReadOnly , %startdir%
759 | }
760 |
761 | ; Gui, AskInput:Add, Text, x5 yp+30 w400 h20, Will run as:
762 | ; Gui, AskInput:Add, Edit, x5 yp+20 w400 h50 ReadOnly, %program% %parameters% %file%, %startdir%
763 |
764 | Gui, AskInput:Add, Button, xp+110 yp+60 w100 h25 gAskInputOK Default, &OK
765 | Gui, AskInput:Add, Button, xp+110 yp w100 h25 gAskInputCancel, &Cancel
766 | Gui, AskInput:Show, w410 x%X% y%Y%,F4MiniMenu Input
767 | }
768 | While (WinExist("F4MiniMenu Input ahk_class AutoHotkeyGUI"))
769 | {
770 | Sleep 100
771 | }
772 | Return
773 |
774 | AskInputGuiEscape:
775 | AskInputGuiClose:
776 | AskInputCancel:
777 | Gui, AskInput:Destroy
778 | execute:=0
779 | Return
780 |
781 | AskInputOK:
782 | Gui, AskInput:Default
783 | GuiControlGet, parameters, , Edit1
784 | ; GuiControlGet, file , , Edit2
785 | GuiControlGet, startdir , , Edit2 ; edit3 if file is uncommented above
786 | StringReplace, startdir, startdir,",,All ; remove quotes just to be sure ;"
787 | Gui, AskInput:Destroy
788 | execute:=1
789 | Return
790 | }
791 |
792 | CheckFile(list,file)
793 | {
794 | For k, v in list
795 | If (v = file)
796 | Return 1
797 | Return 0
798 | }
799 |
800 | CountFiles(Files)
801 | {
802 | StringReplace, Files, Files, `n, `n, UseErrorLevel
803 | Return ErrorLevel+1
804 | }
805 |
806 | GetTCFields(opt,file="")
807 | {
808 | ; %P causes the source path to be inserted into the command line, including a backslash (\) at the end.
809 | ; %T inserts the current target path. Especially useful for packers.
810 |
811 | ; first we deal with non TC
812 |
813 | if MatchList.settings.Explorer or MatchList.settings.XYPlorer or MatchList.settings.QDir or MatchList.settings.Everything
814 | {
815 | if (opt = "%p") or (opt = "%t")
816 | {
817 | SplitPath, file, , OutDir ; panel
818 | Return OutDir
819 | }
820 | }
821 |
822 | ; SP = Source Path, TP = Target Path
823 | if (opt = "%p") or (opt = "%t")
824 | {
825 | /*
826 | ; cm_CopySrcPathToClip=2029 ; Copy source path to clipboard
827 | ; cm_CopyTrgPathToClip=2030 ; Copy target path to clipboard
828 | ; % (panel = "%p") ? "source" : "target"
829 | ClipSaveAll:=ClipboardAll
830 | Clipboard:=""
831 | SendMessage 1075, % (opt = "%p") ? 2029 : 2030, 0, , ahk_class TTOTAL_CMD
832 | panel:=Clipboard "\"
833 | Clipboard:=ClipSaveAll
834 | */
835 | panel:=TC_SendData((opt = "%p") ? "SP" : "TP")
836 | Return panel
837 | }
838 |
839 | ; SN = Source Name Caret, TN = Target Name Caret
840 | if (opt = "%n") or (opt = "%m")
841 | {
842 | NameCaret:=TC_SendData((opt = "%n") ? "SN" : "TN")
843 | Return NameCaret
844 | }
845 |
846 |
847 | ; %O places the current filename without extension into the command line.
848 | ; %E places the current extension (without leading period) into the command line.
849 | if (opt = "%o") or (opt = "%e")
850 | {
851 | if InStr(file,""" """) ; we have multiple files so we need to parse them to get all names + ext
852 | {
853 | StringReplace, file, file, " ",|, All
854 | Loop, parse, % Trim(file,""""), | ; """ fix for highlighting issue in editor
855 | {
856 | SplitPath, A_LoopField, , , OutExtension, OutNameNoExt
857 | filenames .= """" OutNameNoExt """" A_Space ; " fix for highlighting issue in editor
858 | fileext .= """" OutExtension """" A_Space ; " fix for highlighting issue in editor
859 | }
860 | }
861 | else
862 | {
863 | SplitPath, file, , , OutExtension, OutNameNoExt
864 | filenames .= OutNameNoExt
865 | fileext .= OutExtension
866 | }
867 | Return % (opt = "%o") ? filenames : fileext
868 | }
869 |
870 | if InStr(opt, "%$date")
871 | {
872 |
873 | /* TC HELP
874 |
875 | %$DATE% Inserts the 24 hour date and time in the form YYYYMMDDhhmmss -> A_Now in AutoHotkey
876 |
877 | %$DATE:placeholders%
878 | Inserts the date in the form specified by placeholders.
879 | Same as in multi-rename tool: -> AHK
880 | y Paste year in 2 digit form -> yy
881 | Y Paste year in 4 digit form -> yyyy
882 | M Paste month, always 2 digit -> MM
883 | D Paste day, always 2 digit -> dd
884 | h Paste hours, always in 24 hour 2 digit format (0-23) -> H
885 | H Paste hours, always in 12 hour 2 digit format (1-12) -> hh
886 | i1 same but 1 character a/p only -> t
887 | i am/pm indicator in English -> tt
888 | m Paste minutes, always in 2 digit format -> mm
889 | s Paste seconds, always in 2 digit format -> ss
890 | any non-alpha character like a dot or dash will be added directly
891 |
892 | F4MM addition: |value|timeunit
893 |
894 | */
895 |
896 | DateTimeObject:=[]
897 |
898 | ; output entire string, output1 time formatting options
899 | RegExMatch(opt,"Ui)%\$date:*([^%]*)%",output)
900 |
901 | if (output = "%$DATE%")
902 | {
903 | FormatTime, DateTime, , %A_Now%
904 | DateTimeObject[1]:="%$DATE%"
905 | DateTimeObject[2]:=DateTime
906 | return % DateTimeObject
907 | }
908 | else ; output1 -> we have placeholders
909 | {
910 | OutputData:=StrSplit(output1,"|")
911 | ; 1 placeholder, 2 value, 3 time units
912 | ; the order in which we process the format is important (y before Y, h-zzzzz-H, i1 before i)
913 | OutputData[1]:=RegExReplace(OutputData[1],"y","yy")
914 | OutputData[1]:=RegExReplace(OutputData[1],"Y","yyyy")
915 | OutputData[1]:=RegExReplace(OutputData[1],"M","MM")
916 | OutputData[1]:=RegExReplace(OutputData[1],"D","dd")
917 | OutputData[1]:=RegExReplace(OutputData[1],"h","zzzzz") ; we need to swap lower case h for temp char z
918 | OutputData[1]:=RegExReplace(OutputData[1],"H","hh") ; we we can safely process H hh conversion
919 | OutputData[1]:=RegExReplace(OutputData[1],"zzzzz","H") ; and now use char z for h->H conversion
920 | OutputData[1]:=RegExReplace(OutputData[1],"i1","t")
921 | OutputData[1]:=RegExReplace(OutputData[1],"i","tt")
922 | OutputData[1]:=RegExReplace(OutputData[1],"m","mm")
923 | OutputData[1]:=RegExReplace(OutputData[1],"s","ss")
924 | DateTimeFormat:=OutputData[1]
925 |
926 | FormatTime, DateTime,, yyyyMMddHHmmss
927 | EnvAdd, DateTime, % OutputData[2], % OutputData[3] ; do math if any
928 | FormatTime, DateTime, %DateTime%, %DateTimeFormat% ; format the time
929 | DateTimeObject[1]:=output
930 | DateTimeObject[2]:=DateTime
931 | return % DateTimeObject
932 | }
933 | }
934 | }
935 |
936 | SetHotkeys:
937 |
938 | Hotkey, IfWinActive, ahk_group TCONLY
939 |
940 | ;If MatchList.settings.EVDirTree
941 | ; Hotkey, % MatchList.settings.EVDirTree, Everything_DirectoryTree, %HotKeyState% ; %
942 |
943 | Hotkey, IfWinActive,
944 |
945 | Hotkey, IfWinActive, ahk_group TCF4Windows
946 |
947 | ; ~ native function will not be blocked
948 | ; $ prefix forces the keyboard hook to be used to implement this hotkey
949 |
950 | If (MatchList.settings.ForegroundHotkey <> "ERROR") and (MatchList.settings.ForegroundHotkey <> "")
951 | {
952 | hk_prefix:="$"
953 | ;If (RegExMatch(MatchList.settings.ForegroundHotkey,"[\^\+\!\# \&]"))
954 | ; hk_prefix:="~"
955 | FGHKey:=MatchList.settings.ForegroundHotkey
956 | StringReplace, FGHKey, FGHKey, &`;amp`;, & , All
957 | StringReplace, FGHKey, FGHKey, &`;, &, All
958 | If (InStr(FGHKey,"ESC"))
959 | hk_prefix:="~"
960 |
961 | Hotkey, % hk_prefix FGHKey, ShowMenu, %HotKeyState% ; %
962 | ; MsgBox % "Show Menu: " hk_prefix . FGHKey ; debug
963 | }
964 |
965 | If (MatchList.settings.BackgroundHotkey <> "ERROR") and (MatchList.settings.BackgroundHotkey <> "")
966 | {
967 | hk_prefix:="$"
968 | ;If (RegExMatch(MatchList.settings.BackgroundHotkey,"[\^\+\!\# \&]")) ; for example if hotkey is Esc & F4 not adding the ~ would mean Esc is actually disabled in "in place rename" (shift-f6) operations in a panel, or at least that is my experience.
969 | ; hk_prefix:="~"
970 | BGHKey:=MatchList.settings.BackgroundHotkey
971 | StringReplace, BGHKey, BGHKey, &`;amp`;, & , All
972 | StringReplace, BGHKey, BGHKey, &`;, &, All
973 | If (InStr(BGHKey,"ESC"))
974 | hk_prefix:="~"
975 |
976 | Hotkey, % hk_prefix BGHKey, Process, %HotKeyState% ; %
977 | ; MsgBox % "OpenItDirectly: " hk_prefix . BGHKey ; debug
978 | }
979 |
980 | If (MatchList.settings.FilteredHotkey <> "ERROR") and (MatchList.settings.FilteredHotkey <> "")
981 | {
982 | hk_prefix:="$"
983 | TMHKey:=MatchList.settings.FilteredHotkey
984 | StringReplace, TMHKey, TMHKey, &`;amp`;, & , All
985 | StringReplace, TMHKey, TMHKey, &`;, &, All
986 | If (InStr(TMHKey,"ESC"))
987 | hk_prefix:="~"
988 |
989 | Hotkey, % hk_prefix . TMHKey, FilteredMenu, %HotKeyState% ; %
990 | }
991 |
992 | If (InStr(FGHKey BGHKey TMHKey,"Esc"))
993 | EscHotkeys:=1
994 |
995 | Hotkey, IfWinActive
996 | Return
997 |
998 | #If EscHotkeys and MatchList.settings.Everything and Everything_Active()
999 | $Esc::
1000 | if (A_PriorHotkey <> "$Esc" or A_TimeSincePriorHotkey > 400)
1001 | {
1002 | Keywait Esc
1003 | Return
1004 | }
1005 | Else
1006 | {
1007 | WinClose ahk_exe everything.exe
1008 | WinClose ahk_exe everything64.exe
1009 | }
1010 | Return
1011 | #If
1012 |
1013 | /*
1014 |
1015 | ; use *Enter to open folders in TC panels, disable for now 20250209
1016 |
1017 | #If MatchList.settings.Everything and Everything_Active()
1018 |
1019 | Enter:: ; open in source panel/tab
1020 | TCCD(MatchList.settings.TCPath," /O /S ",Everything_GetSelection(dir="1"))
1021 | Return
1022 |
1023 | ^Enter:: ; open in source panel, new tab foreground
1024 | TCCD(MatchList.settings.TCPath," /O /S /T ",Everything_GetSelection(dir="1"))
1025 | Return
1026 |
1027 | ^+Enter:: ; open in source panel, new tab background
1028 | TCCD(MatchList.settings.TCPath," /O /S /B",Everything_GetSelection(dir="1"))
1029 | Return
1030 |
1031 | !Enter:: ; open in target panel/tab
1032 | TCCD(MatchList.settings.TCPath," /O /S /R=",Everything_GetSelection(dir="1"))
1033 | Return
1034 |
1035 | !^Enter:: ; open in target panel, new tab foreground
1036 | TCCD(MatchList.settings.TCPath," /O /S /T /R=",Everything_GetSelection(dir="1"))
1037 | Return
1038 |
1039 | !+Enter:: ; open in target panel, new tab background
1040 | TCCD(MatchList.settings.TCPath," /O /S /B /R=",Everything_GetSelection(dir="1"))
1041 | Return
1042 |
1043 | #If
1044 |
1045 | TCCD(tc,par,dir)
1046 | {
1047 | WinClose ahk_exe everything.exe
1048 | WinClose ahk_exe everything64.exe
1049 | If !InStr(par,"/R=")
1050 | Run, %tc% %par% "%dir%\"
1051 | Else
1052 | Run, %tc% %par%"%dir%\"
1053 | }
1054 |
1055 | */
1056 |
1057 | SaveSettings:
1058 | MatchList.Temp.Files:="",MatchList.Temp.SelectedExtensions:="",MatchList.Delete("Temp")
1059 | %F4Save%("MatchList", F4ConfigFile)
1060 | FileDelete, % TmpFileList
1061 | Return
1062 |
1063 | ExitSettings:
1064 | FileDelete, % TmpFileList
1065 | If CLI_MenuPos
1066 | MatchList.settings.MenuPos:=CLI_MenuPos
1067 |
1068 | If (Error = 1) ; we can't read settings so create a new clean version
1069 | {
1070 | FileDelete, %F4ConfigFile%
1071 | Gosub, CreateNewConfig
1072 | }
1073 | ExitApp
1074 | Return
1075 |
1076 | ; Used in ProcessFiles() - Technique from http://www.autohotkey.com/docs/scripts/MsgBoxButtonNames.htm
1077 | ChangeButtonNames:
1078 | IfWinNotExist, Maximum files ahk_class #32770
1079 | Return ; Keep waiting...
1080 | SetTimer, ChangeButtonNames, off
1081 | ; WinActivate
1082 | ControlSetText, Button2, Process All, Maximum files ahk_class #32770
1083 | ControlSetText, Button3, Stop at Max., Maximum files ahk_class #32770
1084 | Return
1085 |
1086 | GetAllExtensions:
1087 | AllExtensions:=""
1088 | ; Loop % MatchList.MaxIndex() ; %
1089 | for k, v in MatchList
1090 | AllExtensions .= v.ext ","
1091 | AllExtensions:=Trim(AllExtensions,",")
1092 | AllExtensions:=RegExExtensions(AllExtensions)
1093 | Return
1094 |
1095 | CreateNewConfig:
1096 | if InStr(F4ConfigFile,"xml")
1097 | {
1098 | FileDelete, F4MiniMenu.xml
1099 | FileAppend,
1100 | (
1101 |
1102 |
1103 |
1104 | F4
1105 | Esc & F4
1106 |
1107 | 1
1108 | 30
1109 | 3
1110 | c:\totalcmd\TotalCmd.exe
1111 |
1112 | 1
1113 | 0
1114 | 0
1115 | z
1116 | 0
1117 | 0
1118 | 2
1119 | 1
1120 | 1
1121 | 1
1122 | 0
1123 | %A_ScriptDir%\logfile.txt
1124 |
1125 |
1126 | c:\WINDOWS\notepad.exe
1127 | txt,xml
1128 | Normal
1129 | 1
1130 |
1131 |
1132 | ), F4MiniMenu.xml, UTF-8
1133 | }
1134 | else ; INI
1135 | {
1136 | FileDelete, F4MiniMenu.ini
1137 | FileAppend,
1138 | (
1139 | [settings]
1140 | BackgroundHotkey=F4
1141 | ForegroundHotkey=Esc & F4
1142 | FilteredHotkey=
1143 | MaxFiles=30
1144 | MenuPos=3
1145 | FilteredMenuAutoEdit=1
1146 | TCPath=c:\totalcmd\TotalCmd.exe
1147 | TCStart=1
1148 | TCIniPath=
1149 | F4MMCloseAll=0
1150 | F4MMClosePID=0
1151 | FullMenu=z
1152 | Explorer=0
1153 | Everything=0
1154 | MaxWinWaitSec=2
1155 | Lister=1
1156 | FindFiles=1
1157 | QuickView=1
1158 | log=0
1159 | logfile=%A_ScriptDir%\logfile.txt
1160 | [1]
1161 | delay=0
1162 | exe=c:\WINDOWS\notepad.exe
1163 | ext=txt,xml
1164 | method=Normal
1165 | windowmode=1
1166 | ), F4MiniMenu.ini, UTF-16
1167 | }
1168 | Return
1169 |
1170 |
1171 | ; Check DocumentTemplates\ - this setting can be used in F4TCIE.ahk (not required)
1172 | DocumentTemplatesScan:
1173 | If (FileExist(A_ScriptDir "\DocumentTemplates\") = "D") ; " fix highlighting
1174 | {
1175 | templatesExtBeforeScan:=MatchList.Settings["templatesExt"]
1176 | Loop, %A_ScriptDir%\DocumentTemplates\template.*
1177 | {
1178 | SplitPath, A_LoopFileName, , , TemplatesOutExtension
1179 | templatesExt .= TemplatesOutExtension ","
1180 | }
1181 | ; only update when its has been changed
1182 | If (templatesExtBeforeScan <> Trim(templatesExt,","))
1183 | {
1184 | MatchList.Settings["templatesExt"]:=Trim(templatesExt,",")
1185 | %F4Save%("MatchList", F4ConfigFile)
1186 | }
1187 | templatesExt:="",TemplatesOutExtension:="",templatesExtBeforeScan:=""
1188 | }
1189 | Return
1190 |
1191 | ; Includes
1192 |
1193 | #include %A_ScriptDir%\inc\Menu.ahk
1194 | #include %A_ScriptDir%\inc\FilteredMenu.ahk
1195 | #include %A_ScriptDir%\inc\Settings.ahk
1196 | #include %A_ScriptDir%\inc\Editors.ahk
1197 | #include %A_ScriptDir%\inc\HelperFunctions.ahk ; shared with F4TCIE
1198 | #include %A_ScriptDir%\lib\XA.ahk ; shared with F4TCIE
1199 | #include %A_ScriptDir%\lib\iob.ahk ; shared with F4TCIE
1200 | #include %A_ScriptDir%\lib\class_lv_rows.ahk
1201 | #include %A_ScriptDir%\lib\DropFiles.ahk
1202 | #include %A_ScriptDir%\lib\GetPos.ahk
1203 | #include %A_ScriptDir%\lib\dpi.ahk
1204 | #include %A_ScriptDir%\lib\tc.ahk ; wm_copydata
1205 | #include %A_ScriptDir%\lib\log.ahk
1206 | #include %A_ScriptDir%\lib\AutoXYWH.ahk
1207 |
1208 | ;@Ahk2Exe-IgnoreBegin
1209 | #include *i %A_ScriptDir%\..\ButtonBarKeyboard\ButtonBarKeyboard.ahk
1210 | ;@Ahk2Exe-IgnoreEnd
1211 |
--------------------------------------------------------------------------------
/F4TCIE.ahk:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Script : F4TCIE.ahk for Total Commander - AutoHotkey 1.1+ (Ansi and Unicode)
4 | Version : 1.3
5 | Author : hi5
6 | Last update : 30 October 2023
7 | Purpose : Helper script for F4MiniMenu program to allow internal editor to function
8 | now you can edit files from within Archives and FTP (and have TC update/upload them)
9 | Notes : It will always use the "normal" method to open programs, so the "drag & drop", "filelist"
10 | and "cmdline" methods will not be used (TC doesn't see file changes when using these methods)
11 | If you are using INI make sure to rename "F4TCIE" to end with an "i" (same method as F4MiniMenu)
12 | Source : https://github.com/hi5/F4MiniMenu
13 |
14 | Setup : TC, Configuration, Edit/View, Editor:
15 | drive:\path-to\F4TCIE.ahk "%1"
16 |
17 | Templates : Create a DocumentTemplates\ folder and place files for each template you'd like to use for
18 | the Shift-F4 'enter file name to edit' function of TC. File names are template.ext
19 | This will copy the template.ext to the panel with the new name so you can work on it the
20 | defined editor. Not all programs allow empty files at start up so this will resolve that
21 | problem for say Office applications or Graphics programs.
22 | See DocumentTemplates\readme.md for more info.
23 |
24 | */
25 |
26 | #Requires AutoHotkey v1.1.31+
27 | #NoTrayIcon
28 | #NoEnv
29 |
30 | ;
31 | ;@Ahk2Exe-SetFileVersion 1.3
32 | ;@Ahk2Exe-SetProductName F4MiniMenu (IE)
33 | ;@Ahk2Exe-SetDescription F4MiniMenu (IE): Open files from TC
34 | ;@Ahk2Exe-SetProductVersion Compiled with AutoHotkey v%A_AhkVersion%
35 | ;@Ahk2Exe-SetCopyright MIT License - (c) https://github.com/hi5
36 | ;
37 |
38 | SetWorkingDir, %A_ScriptDir%
39 |
40 | File=%1% ; cmd line parameter "%1" it receives from TC
41 | SplitPath, File, , , OutExtension
42 | StringUpper, OutExtension, OutExtension
43 |
44 | If !File ; if empty
45 | ExitApp
46 |
47 | ; shared with F4MM
48 | #Include %A_ScriptDir%\inc\LoadSettings1.ahk
49 | #Include %A_ScriptDir%\inc\LoadSettings2.ahk
50 |
51 | If Error
52 | {
53 | MsgBox, 16, F4MiniMenu/F4TCIE, Couldn't load configuration file (%F4ConfigFile%), closing script and starting default Windows editor.`n`nMay not work if there is no "Edit" defined for this filetype:`n`n%OutExtension%`n`nNote: do check if F4MiniMenu/F4TCIE have the same naming convention (for INI both program names have to end with an "i")`nSee "XML or INI" https://github.com/hi5/F4MiniMenu/blob/master/readme.md
54 | Try
55 | Run edit "%file%" ; run Windows editor for this filetype
56 | Catch
57 | Run %A_WinDir%\notepad.exe "%file%" ; alas no type defined so run notepad as a last resort
58 | ExitApp
59 | }
60 |
61 | templateExt:=MatchList.Settings.templatesExt
62 |
63 | ; shared with F4MM
64 | #Include %A_ScriptDir%\inc\TotalCommanderPath.ahk
65 |
66 | for k, v in MatchList
67 | {
68 | if (k = "settings")
69 | continue
70 | if (v.ext = "") ; reported by Ovg if EXT is empty it would not launch the default editor
71 | continue
72 | if RegExMatch(OutExtension,RegExExtensions(v.ext)) ; Open in defined program - v0.9 allow for wildcards
73 | {
74 | ;editor:=GetTCCommander_Path(v.exe)
75 | editor:=GetPath(v.exe)
76 | If OutExtension in %templateExt%
77 | {
78 | IfExist, %file% ; file is already present, this could be that TC created it just now (0 bytes) or that is already existed.
79 | {
80 | FileGetSize, NewFileSize, %file%
81 | If (NewFileSize = 0) ; TC created it, so overwrite with our template, otherwise don't. This to avoid overwriting existing documents.
82 | FileCopy, %A_ScriptDir%\DocumentTemplates\template.%OutExtension%, %file%, 1
83 | }
84 | }
85 | if editor
86 | {
87 | Sleep % v.delay
88 | Try
89 | {
90 | Run "%editor%" "%file%"
91 | Sleep 100 ; added explicit Exit as compiled version sometimes kept running 30/10/2023
92 | ExitApp
93 | }
94 | Catch
95 | {
96 | editor:=GetPath(matchlist[1].exe)
97 | Run "%editor%" "%file%"
98 | ; OSDTIP_Pop(MainText, SubText, TimeOut, Options, FontName, Transparency)
99 | OSDTIP_Pop("F4MiniMenu/F4TCIE", "Defined editor/program not found`nReverting to default editor", -750,"W230 H80 U1")
100 | Sleep 100 ; added explicit Exit as compiled version sometimes kept running 30/10/2023
101 | ExitApp
102 | }
103 | }
104 | ExitApp ; we only have one file to process so we're done
105 | }
106 | }
107 |
108 | ; We couldn't find a defined Editor so launch the default Editor [1]
109 | editor:=GetPath(matchlist[1].exe)
110 | Run "%editor%" "%file%"
111 | Sleep 100 ; added explicit Exit as compiled version sometimes kept running 30/10/2023
112 | ExitApp
113 |
114 | ; shared with F4MM
115 | #include %A_ScriptDir%\inc\HelperFunctions.ahk
116 |
117 | ; just for loading the Matchlist object, we don't need all the rest
118 | #include %A_ScriptDir%\lib\xa.ahk
119 | #include %A_ScriptDir%\lib\iob.ahk
120 |
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | ## Changelog
2 |
3 | * 20250209 - v1.47 a) Allow resizing of Configure Editors GUI (browse list) using AutoXYWH()
4 | b) Some code cleanup re Enter shortcuts; add everything64.exe to Esc Winclose routine
5 | c) Trace menu steps and result of GetFiles in log
6 |
7 | * 20250209 - v1.46 a) Finetuning Everything_GetSelection() to check for selected rows in listview (if none get first result only)
8 |
9 | * 20250208 - v1.45 a) Finetuning Everything_Active() (using "A" not "Everything" in WinGet to detect active window)
10 | b) Use TXT as default extension for default editor if user doesn't set one - otherwise it would not match correctly for defined extensions https://www.ghisler.ch/board/viewtopic.php?p=468305#p468305
11 | c) log option (manual setting, don't document)
12 |
13 | * 20250208 - v1.44 a) Add Everything64.exe to ahk_group TCF4Windows; updated Everything-functions to check for Everything.exe or Everything64.exe - added notes to help tip and docs
14 |
15 | * 20250111 - v1.43 a) Fix: moved INI selection routine introduced in v1.42 as it interferred with selecting a (new) editor https://www.ghisler.ch/board/viewtopic.php?p=466621#p466621
16 | b) Additional hint in "Other programs" section re Hotkey to "Copy File Name(s) with Full Path"
17 | c) Added two ;@Ahk2Exe-Set* for compiled script properties (incl. AutoHotkey version)
18 |
19 | * 20240130 - v1.42 a) New: Enable/Disable using F4MM in Lister, Find Files and QuickView (Use elsewhere in TC)
20 | Fix: Resort to reading multiple locations in the registry + settings option to locate `wincmd.ini` to be able to read `F4Edit` setting
21 | and additional setting `INI Path`
22 | Hopefully this is now correctly handled in all cases (F4MM starts before TC, TC starts before F4MM)
23 |
24 | * 20240127 - v1.41 a) Fix: Check to see if TC is running in order to be able to read F4Edit= correctly (using environment variable %Commander_ini_Path%)
25 |
26 | * 20240123 - v1.4 a) New: enable/disable F4MM for Lister and Find Files (search results) windows (see settings). If Lister setting is active and F4Edit>1 in wincmd.ini: close Lister
27 | In TC 11.03 the press "F4 to open currently viewed file in Lister" was added.
28 | (See F4Edit= options in TC help file on how to handle F4 in lister via wincmd.ini. F4TCIE _could_ be used.)
29 |
30 | * 20231121 - v1.3
31 | a) Fix: `%N` and `%M` now processed correctly
32 | b) Added "#Requires AutoHotkey v1.1.31+" directive for users with v1 & v2 installed, added note in documention about using v1 AutoHotkey.exe in setup
33 |
34 | * 20231030 - v1.2
35 | a) Updated class name for Find Results control class (TMyListBox2, 32bit) for TC11
36 | b) Added: Help MsgBox-es in Settings Gui now Task Modal (32+8192=8224)
37 | c) Added: Settings label to Gui to better handle closing the Gui https://github.com/hi5/F4MiniMenu/issues/24#issuecomment-1573127847
38 | d) Added: GuiEscape for Add/Modify editors dialog to allow Esc to exit (next to Alt+c) https://github.com/hi5/F4MiniMenu/issues/24#issuecomment-1573127847
39 | e) Fix: no longer require full path for programs in PATH e.g. `write.exe` v `c:\windows\write.exe`, bug introduced in v1.1 due to GetFullPathName() https://github.com/hi5/F4MiniMenu/issues/24#issuecomment-1573127847
40 | f) Fix: use SplitPath for `%p` parameter when not using TC https://github.com/hi5/F4MiniMenu/issues/24#issuecomment-1573127847
41 | g) Change: `%p` and `%t` now use wm_copydata
42 | h) New: `%N` and `%M` to place filename under the cursor into the command line (source and target directory) using wm_copydata
43 | i) New: Added support for `%$DATE%`, `%$DATE:YMD%` + offset calculations via `%$DATE:YMD|value|timeunits%`
44 | j) Fix: F4TCIE quote file path for `%file%` to resolve paths\files with spaces
45 | k) Fix: F4TCIE `Run notepad` changed to `Run %A_WinDir%\notepad.exe` to avoid any potential path issues. Added ExitApp after Run command
46 |
47 | * 20230402 - v1.1
48 | a) Fix: TRY to catch all empty hotkeys to avoid errors at startup
49 | b) Change: Double click on an "editor" in Configure Editors listview now opens modify window
50 | c) Change: Settings - replace Radio controls for Esc/Win with DropDownLists (not thoroughly tested)
51 | d) Fix: WinMin/Hide/Maximize and Sleep function should work better (or again)
52 | e) Fix: additional check to prevent Modify Gui throwing "The same variable cannot be used for more than one control" error; modify window now always on top of editors window (); sysmenu removed
53 | f) New: TRY, catch -> revert to standard editor if defined editor can not be found, show notification using OSDTIP_Pop() for both F4MiniMenu and F4TCIE
54 | g) New: support `%windir%`, `%A_ScriptDir%` and other path variables (see list "Path variables" in readme.md) https://github.com/hi5/F4MiniMenu/issues/25
55 | h) New: Filtered foreground Menu - setting to launch program directly if only one program is found https://github.com/hi5/F4MiniMenu/issues/26
56 | i) New: Global setting MaxWinWaitSec to prevent stalling F4MM
57 | j) Fix: INI when reading a global setting as "Error" set as empty (lib\iob.ahk)
58 | * 20220528 - v1.0
59 | a) Fix: "Start Total Commander if not running" feature #23 https://github.com/hi5/F4MiniMenu/issues/23
60 | b) Fix: Use another method to calculate Y for Position = 2 in GetPos (as this is now default for c))
61 | c) Rudimentary support for Windows Explorer, Double Commander, XYPlorer, and Everything(e) (default foreground menu to center in Window)
62 | d) Passive mode using parameters to use F4MiniMenu via Button bar, Start Menu, or F4 Editor (start F4MM, processes files, close F4MM, so not a persistent script)
63 | e) Fix: Path from Lister Windows Title failed if file name started/ended with [ or ] characters e.g. "[2000] My Document.txt"
64 | f) remove stray file inc\inc.zip from repository
65 | * 20190622 - v0.97
66 | a) New option for filtered foreground menu: only show programs that match selected extensions. See Settings for setup. https://github.com/hi5/F4MiniMenu/issues/21
67 | b) Fix: correctly use %commander_path% in Editor listview IL_Add routine (if v.Icon isn't set)
68 | c) Fix: Editor - Set as Default should now work correctly
69 | d) Fix: Editor - cancel should now work more reliably by using .clone()
70 | e) Only save settings when actually changing them e.g. no longer at each start/exit of the script
71 | f) New: Option(s) to Close F4MiniMenu when TC closes
72 | * 20190607 - v0.96.2 - Fix: adding Try to all Menu, tray, icons to avoid startup error for compiled scripts and autohotkey.exe is not installed. https://www.ghisler.ch/board/viewtopic.php?p=356022#p356022
73 | * 20190606 - v0.96.1 - Fix: adding close F4MiniMenu setting to INI version (iob.ahk) https://www.ghisler.ch/board/viewtopic.php?p=355998#p355998
74 | * 20190527 - v0.96
75 | a) Added options to "Total Commander" startup settings on request https://www.ghisler.ch/board/viewtopic.php?p=355595#p355595 (always start, close F4MiniMenu)
76 | b) dpi + fix to avoid Gui error when calling New editor from menu while Browse Gui was active.
77 | c) tray menu: icons, left click opens tray menu, added "Open" to check key history etc.
78 | * 20170710 - v0.95 Added F4TCIE and introduced DocumentTemplates. #13 https://github.com/hi5/F4MiniMenu/issues/13
79 | New icon :-)
80 | * 20170607 - v0.94c Minor fix to empty file and quoted startdir variables in GetInput(). Fix for %ComSpec% in Editor names.
81 | * 20170106 - v0.94b Minor fix to ensure Commander_Path is not empty
82 | * 20170105 - v0.94a Minor fix for launching via Drag&Drop (no longer worked correctly/reliably in v0.94)
83 | * 20161231 - v0.94
84 | a) Added 4th method: cmdline -> program.exe file1 file2 file3 #14 https://github.com/hi5/F4MiniMenu/issues/14
85 | b) Accept TC Fields %P %T %O %E and ? in Parameters and Startdir. Introduced %f41. #15 https://github.com/hi5/F4MiniMenu/issues/15
86 | c) Build foreground menu only once vs delete/recreate (updating menu only after editing editors). Refactored menu code.
87 | d) Now use %TEMP%\$$f4mtmplist$$.m3u instead of ScriptFolder - [requested by Ovg](http://ghisler.ch/board/viewtopic.php?p=319773&sid=2e2472aec32f6906e699d095b4998ea3#319773)
88 | e) Fixed hotkeys - #12 https://github.com/hi5/F4MiniMenu/issues/12
89 | f) You can now specify an Icon and Menu name when you configure an Editor. #17 https://github.com/hi5/F4MiniMenu/issues/17
90 | g) %Commander_Path% now accepted in Editor and Icon paths.
91 | h) Removed F4MiniMenui.ahk - to use INI simply rename/copy the (compiled) script to end with "i".
92 | * 20161023 - v0.93 OpenFile: add WinWait before WinActivate, merge request @nameanyone #10 https://github.com/hi5/F4MiniMenu/issues/10
93 | * 20160618 - v0.92 Fix error checking on startup in case script is compiled - HT Ovg
94 | * 20160618 - v0.91 Fix for INI Editors include (save to INI not XML when making backup). Refinement of regular expression for wildcards - HT [Ovg](http://ghisler.ch/board/viewtopic.php?p=310538#310538)
95 | * 20160618 - v0.9 Added support for wildcards (? and *) in extensions #6 https://github.com/hi5/F4MiniMenu/issues/6. Added open delay (delay in ms between opening files)
96 | * 20160617 - v0.83 Adding specific #include path for lib files to avoid possible error for portable users when compiling. HT [Ovg](ghisler.ch/board/viewtopic.php?p=310187#310187)
97 | * 20151104 - v0.82 Further refinement of confusing error message at very first startup (missing configuration XML) - now also checks if BAK is present.
98 | * 20151103 - v0.81 Fixed confusing error message at very first startup (missing configuration XML)
99 | * 20141107 - v0.8 Added F4 functions to Lister (grabbing the filename from the Window title) and the search results in the Find Files dialog. Comment: if you use the Esc & Key as Foreground menu option it will fail as pressing Esc will close Lister and the Find Files dialog. The Winkey & Key combination does work - the menu will appear at the top of the window.
100 | * 20140806 - v0.7 replaced Loop, object.MaxIndex() with proper for-loop to parse each key-value pair in the MatchList object; Added &letter to foreground menu options (program names)
101 | * 20130731 - v0.61 added rudimentary backup & safety feature in case of a faulty/missing settings XML
102 | * 20130701 - v0.6 a) [Class LV_Rows](http://www.autohotkey.com/board/topic/94364-class-lv-rows-copy-cut-paste-and-drag-listviews/) by [Pulover](https://github.com/Pulover/) replaces [LV_MoveRow()](http://www.autohotkey.com/board/topic/56396-techdemo-move-rows-in-a-listview/).
103 | This resolves the problem with the listview not updating icons while moving the editors in the settings Gui;
104 | b) Added Unicode support for drag & drop method so F4MiniMenu should now be compatible with both Ansi and Unicode versions of AutoHotkey.
105 | * 20130607 - v0.51 Check if selected file(s) are archived, if so bypass F4MiniMenu all together and use internal TC Edit command to open file, this will only use the file under the cursor, not all selected files.
106 | * 20130330 - v0.5 a) Process entire file list first and open per program;
107 | b) Introduced [Filelist](readme.md#filelist) method;
108 | c) Removed "Open Mode".
109 | * 20121117 - v0.4 Configuration GUIs, tray menu. First editor now considered default editor.
110 | * 20121111 - v0.3 Added menu for "foreground" feature - open all selected files with specific editor (its behaviour may change in future).
111 | * 20121108 - v0.2 Added 0 (zero) entry in XML as default editor.
112 | * 20121101 - v0.1 Initial very basic version.
113 |
114 |
--------------------------------------------------------------------------------
/img/f4-configure-editors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hi5/F4MiniMenu/34d131ef7b47bef92dd4e120032674ac249ce5b3/img/f4-configure-editors.png
--------------------------------------------------------------------------------
/img/f4-confirm-maximum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hi5/F4MiniMenu/34d131ef7b47bef92dd4e120032674ac249ce5b3/img/f4-confirm-maximum.png
--------------------------------------------------------------------------------
/img/f4-editor-setttings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hi5/F4MiniMenu/34d131ef7b47bef92dd4e120032674ac249ce5b3/img/f4-editor-setttings.png
--------------------------------------------------------------------------------
/img/f4-foreground-menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hi5/F4MiniMenu/34d131ef7b47bef92dd4e120032674ac249ce5b3/img/f4-foreground-menu.png
--------------------------------------------------------------------------------
/img/f4-general-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hi5/F4MiniMenu/34d131ef7b47bef92dd4e120032674ac249ce5b3/img/f4-general-settings.png
--------------------------------------------------------------------------------
/inc/CLIParser.ahk:
--------------------------------------------------------------------------------
1 | /*
2 | CLIParser to start F4MiniMenu via F4 (editor), Buttonbar or Startmenu
3 |
4 | F4MiniMenu %L /P? /M?
5 |
6 | /P1 = Menu position at Mouse cursor
7 | /P2 = Menu position Centered in window
8 | (see GetPos.ahk)
9 |
10 | /M1 = Full menu
11 | /M2 = Filtered menu
12 |
13 | /SET = open settings
14 |
15 | /ED = open editors
16 |
17 | */
18 |
19 | If (A_Args.Length() <> 0)
20 | {
21 | CLI_Exit:=1
22 | CLI_File:=A_Args[1]
23 | for k, v in A_Args
24 | {
25 | if (v = "/P1")
26 | {
27 | CLI_MenuPos:=MatchList.settings.MenuPos
28 | MatchList.settings.MenuPos:=1
29 | }
30 | if (v = "/P2")
31 | {
32 | CLI_MenuPos:=MatchList.settings.MenuPos
33 | MatchList.settings.MenuPos:=2
34 | }
35 | if (v = "/M1")
36 | CLI_ShowMenu:=1
37 | if (v = "/M2")
38 | CLI_FilteredMenu:=1
39 | if (v = "/SET")
40 | CLI_Settings:=1
41 | if (v = "/ED")
42 | CLI_Editors:=1
43 | }
44 | If MatchList.Settings.log
45 | Log(A_Now " : CLI Params -> CLI_ShowMenu: " CLI_ShowMenu " CLI_FilteredMenu: " CLI_FilteredMenu "CLI_Settings: " CLI_Settings " CLI_Editors: " CLI_Editors,MatchList.Settings.logFile)
46 | }
47 |
--------------------------------------------------------------------------------
/inc/Editors.ahk:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Gui for managing Editors
4 | Include for F4MiniMenu.ahk
5 |
6 | */
7 |
8 | ; This label is used when "Add new Editor" is selected in the foreground menu,
9 | ; we only need to set a variable and the proceed with the regular editor Gui
10 |
11 | ConfigEditorsNew:
12 | New:=1
13 |
14 |
15 | ConfigEditors:
16 |
17 | ; Variables
18 |
19 | ; Backup Object so we can use this for CANCEL
20 | Backup:=MatchList.Clone()
21 |
22 | GetList:="Exe|Parameters|StartDir|WindowMode|Ext|Method|Delay|Open|Editor|Icon|Name"
23 |
24 | infotext=
25 | (join`n
26 | Important:
27 | 1 - The first editor will be considered to the default editor.
28 |
29 | Info:
30 | 1 - Delay (in miliseconds) D&&D = Drag && Drop, Open = startup.
31 | 2 - Sort using Ctrl+UP / Ctrl+DOWN or use Edit menu
32 | (multiple rows possible).
33 | )
34 |
35 | IfWinExist, F4MiniMenu - Editor Settings ahk_class AutoHotkeyGUI
36 | {
37 | WinActivate, F4MiniMenu - Editor Settings ahk_class AutoHotkeyGUI
38 | If New
39 | Gosub, NewEditor
40 | Return
41 | }
42 |
43 | Gui, Browse: +Resize +MinSize790x427
44 |
45 | Menu, EditMenu, Add, Move Up`tCtrl+Up, MoveUp
46 | Menu, EditMenu, Add, Move Down`tCtrl+Down, MoveDown
47 | Menu, MenuBar, Add, %A_Space%Edit, :EditMenu
48 | Gui, Browse:Menu, MenuBar
49 |
50 | ; INI Gui
51 | Gui, Browse:font, % dpi("s8")
52 | Gui, Browse:Add, ListView, % dpi("x6 y5 w780 h285 grid hwndhLV vLV gLVLabel"), Program|Parameters|Start Dir.|Window|Extensions|Method|D&D|Open|Editor|Icon|Name
53 | Gui, Browse:Add, GroupBox, % dpi("x6 yp+290 w390 h120 vGroupBoxInfo"), Comments
54 | Gui, Browse:Add, Text, % dpi("x16 yp+20 w340 vInfoText"), %infotext%
55 | Gui, Browse:Add, Button, % dpi("xp+445 yp w70 h24 gSettings vButtonSettings"), &Settings
56 | Gui, Browse:Add, Button, % dpi("xp+80 yp w70 h24 gAdd vButtonAdd"), &Add
57 | Gui, Browse:Add, Button, % dpi("xp+80 yp w70 h24 gModify vButtonModify"), &Modify
58 | Gui, Browse:Add, Button, % dpi("xp+80 yp w70 h24 gRemove vButtonRemove"), &Remove
59 | Gui, Browse:Add, Button, % dpi("xp-240 yp+40 w150 h24 gOK vButtonOK"), &OK
60 | Gui, Browse:Add, Button, % dpi("xp+160 yp w150 h24 gCancel vButtonCancel"), &Cancel
61 | Gui, Browse:Add, Link, % dpi("xp-160 yp+40 w310 h16 vLinkText"), F4MiniMenu %F4Version% -- More info at Github.com/hi5/F4MiniMenu
62 | Gosub, UpdateListview
63 | LvHandle := New LV_Rows(hLV)
64 | Gui, Browse:Show, % dpi("x261 y211 h427 w790 center"), F4MiniMenu - Editor Settings
65 |
66 | Sleep 100
67 |
68 | BrowseGuiSize:
69 | If (A_EventInfo = 1) ; The window has been minimized.
70 | Return
71 | AutoXYWH("w h" , "Lv")
72 | AutoXYWH("y" , "GroupBoxInfo")
73 | AutoXYWH("y" , "InfoText")
74 | AutoXYWH("x y" , "ButtonSettings")
75 | AutoXYWH("x y" , "ButtonAdd")
76 | AutoXYWH("x y" , "ButtonModify")
77 | AutoXYWH("x y" , "ButtonRemove")
78 | AutoXYWH("x y" , "ButtonOK")
79 | AutoXYWH("x y" , "ButtonCancel")
80 | AutoXYWH("x y" , "LinkText")
81 | ControlGetPos, , , OutWidth, , Syslistview321, F4MiniMenu - Editor Settings
82 | LV_ModifyCol(1, (dpifactor*250) + (OutWidth-780))
83 | Return
84 |
85 | NewEditor:
86 | If (New = 1) ; we choose "Add new Editor in foreground menu"
87 | {
88 | Gosub, Add
89 | ; get list of selected files so we can set the Extensions automatically
90 | SelectedExtensions:=""
91 | Files:=GetFiles()
92 | Loop, parse, Files, `n, `r
93 | {
94 | SplitPath, A_LoopField, , , OutExtension
95 | If OutExtension not in %SelectedExtensions%
96 | SelectedExtensions .= OutExtension ","
97 | }
98 | SelectedExtensions:=Rtrim(SelectedExtensions,",")
99 | GuiControl,Modify: , Ext, %SelectedExtensions%
100 | SelectedExtensions:=""
101 | Files:=""
102 | }
103 |
104 | New:=0
105 | Return
106 |
107 | ; Approved chances, read ListView to store new or changed data
108 | Ok:
109 | Backup:=[]
110 | Backup:=MatchList.settings
111 | MatchList:=[]
112 | MatchList.settings:=Backup
113 | Gui, Browse:Default
114 | Gui +LastFound
115 | Loop, % LV_GetCount() ; %
116 | {
117 | Row:=A_Index
118 | Loop, parse, GetList, |
119 | LV_GetText(%A_LoopField%, Row, A_Index)
120 | MatchList[Row,"Exe"]:=Exe
121 | MatchList[Row,"Parameters"]:=Parameters
122 | MatchList[Row,"StartDir"]:=StartDir
123 | MatchList[Row,"Method"]:=Method
124 | MatchList[Row,"WindowMode"]:=WindowMode
125 | MatchList[Row,"Ext"]:=Ext
126 | MatchList[Row,"Delay"]:=Delay
127 | MatchList[Row,"Open"]:=Open
128 | MatchList[Row,"Icon"]:=Icon
129 | MatchList[Row,"Name"]:=Name
130 | }
131 |
132 | If (Trim(MatchList.1.Ext,"`n`r`t ") = "")
133 | MatchList.1.Ext:="txt" ; safety as we need at least one extension for the default editor
134 |
135 | Backup:=""
136 | %F4Save%("MatchList",F4ConfigFile)
137 | Gui, Browse:Destroy
138 | Gosub, BuildMenu
139 | Gosub, GetAllExtensions
140 | Return
141 |
142 | BrowseGuiEscape:
143 | Cancel:
144 | MatchList:=[]
145 | MatchList:=Backup
146 | Backup:=""
147 | Gosub, BuildMenu
148 | Gosub, BrowseGuiClose
149 | Return
150 |
151 | Remove:
152 | Ask:=""
153 | Gui, Browse:Default
154 | Gui, Browse:Submit, NoHide
155 | SelItem := LV_GetNext()
156 | If (SelItem = 0)
157 | SelItem = 1
158 | LV_GetText(Ask, SelItem, 1)
159 | MsgBox, 52, Remove editor (one entry),Do you want to remove:`n%Ask%?
160 | IfMsgBox, Yes
161 | {
162 | LV_Delete(SelItem)
163 | MatchList.Remove(Editor)
164 | }
165 | Gosub, BuildMenu
166 | Return
167 |
168 | ; We can use the same Gui to ADD or MODIFY an editor we only need
169 | ; to set a variable and the proceed with the regular Modify Gui
170 |
171 | Add:
172 | New:=1
173 |
174 | Modify:
175 |
176 | Gui, Modify:Destroy ; https://www.ghisler.ch/board/viewtopic.php?p=423475#p423475
177 |
178 | ; Clear variables just to be sure
179 | Loop, parse, GetList, |
180 | %A_LoopField%:=""
181 |
182 | If New
183 | {
184 | Delay:=0
185 | Method:="Normal"
186 | WindowMode:=1
187 | }
188 |
189 | ; We want to modify existing entry, get info from listview and set variables for use in Gui
190 | If !New
191 | {
192 | Gui, Browse:Default
193 | Gui, Browse:Submit, NoHide
194 | SelItem := LV_GetNext()
195 | If (SelItem = 0)
196 | SelItem = 1
197 | Loop, parse, GetList, |
198 | {
199 | LV_GetText(%A_LoopField%, SelItem, A_Index)
200 | }
201 | }
202 |
203 | Gui, Modify:+OwnerBrowse -SysMenu
204 | Gui, Modify:font, % dpi("s8")
205 | Gui, Modify:Add, Text, % dpi("x10 y10 w77 h18"), &Exe
206 | Gui, Modify:Add, Edit, % dpi("x89 y8 w290 h20 vExe"), %Exe%
207 | Gui, Modify:Add, Button, % dpi("x386 y8 w30 h20 gSelectExe"), >>
208 | Gui, Modify:Add, Checkbox, % dpi("x426 y8 w200 h20 vDefault"), Set as &Default
209 |
210 | Gui, Modify:Add, Text, % dpi("x10 yp+32 w77 h18"), &Icon
211 | Gui, Modify:Add, Edit, % dpi("x89 yp-2 w170 h20 vIcon"), %Icon%
212 | Gui, Modify:Add, Button, % dpi("x266 yp w30 h20 gSelectIcon"), >>
213 | Gui, Modify:Add, Text, % dpi("xp+41 yp+2 w60 h18"), Menu &Name
214 | Gui, Modify:Add, Edit, % dpi("xp+70 yp-2 w150 h20 vName"), %Name%
215 |
216 | Gui, Modify:Add, Text, % dpi("x10 yp+32 w77 h16"), Para&meters
217 | Gui, Modify:Add, Edit, % dpi("x89 yp-2 w438 h20 vParameters"), %Parameters%
218 |
219 | Gui, Modify:Add, Text, % dpi("x10 yp+32 w77 h16"), &Start Dir
220 | Gui, Modify:Add, Edit, % dpi("x89 yp-2 w323 h20 vStartDir"), %StartDir%
221 | Gui, Modify:Add, Button, % dpi("xp+328 yp h20 w110 gCopyPath"), Copy path from Exe.
222 |
223 | Gui, Modify:Add, Text, % dpi("x10 yp+32 w78 h28"), &Method
224 | If (Method = "Normal")
225 | Method:=1
226 | Else If (Method = "DragDrop")
227 | Method:=2
228 | Else If (Method = "FileList")
229 | Method:=3
230 | Else If (Method = "cmdline")
231 | Method:=4
232 | Gui, Modify:Add, DropDownList, % dpi("x89 yp-3 w238 h21 R4 Choose" Method " vMethod AltSubmit"), 1 - Normal|2 - Drag & Drop|3 - FileList|4 - cmdline
233 |
234 | Gui, Modify:Add, Text, % dpi("xp+250 yp+3 h16"), [Delays] D&&D:
235 | Gui, Modify:Add, Edit, % dpi("xp+70 yp-3 h20 w40 vDelay Number"), %Delay%
236 | Gui, Modify:Add, Text, % dpi("xp+45 yp+3 h16"), Open:
237 | Gui, Modify:Add, Edit, % dpi("xp+32 yp-3 h20 w40 vOpen Number"), %Open%
238 |
239 | Gui, Modify:Add, Text, % dpi("x10 yp+32 w78 h28"), &Window
240 | Gui, Modify:Add, DropDownList, % dpi("x89 yp-3 w238 h21 R3 Choose" WindowMode " vWindowMode AltSubmit"), 1 - Normal|2 - Maximized|3 - Minimized
241 |
242 | ;Gui, Modify:Add, Text, x10 y160 w78 h16, &Open Mode
243 | ;Gui, Modify:Add, DropDownList, x89 y158 w438 h21 Choose%Mode% vMode AltSubmit, (not yet implemented)|
244 | ;Gui, Modify:Default
245 | ;GuiControl, Disable, Mode
246 |
247 | Gui, Modify:Add, Text, % dpi("x10 yp+32 w77 h80"), Ex&tensions (Default editor must have at least one ext.`nTXT is set if not defined)
248 | Gui, Modify:Add, Edit, % dpi("x89 yp-2 w438 h80 vExt"), %Ext%
249 |
250 | Gui, Modify:Add, Link, % dpi("x10 yp+100 w310 h16"), F4MiniMenu %F4Version% --- More info at Github.com/hi5/F4MiniMenu
251 |
252 | Gui, Modify:Add, Button, % dpi("x340 yp-5 w90 h24"), &OK
253 | Gui, Modify:Add, Button, % dpi("x437 yp w90 h24"), &Cancel
254 |
255 | Gui, Modify:Show, % dpi("w542 center"), Editor configuration
256 | Return
257 |
258 | SelectIcon:
259 | FileSelectFile, Icon, 3, , Select Icon, Icon (*.ico)
260 | if (Icon = "")
261 | Return
262 | GuiControl, Modify: ,Icon,%Icon%
263 |
264 | Return
265 |
266 | SelectExe:
267 | Exe:=""
268 | FileSelectFile, Exe, 3, , Select program, Executables (*.exe`;*.cmd`;*.bat`;*.com`;*.ahk)
269 | if (Exe = "")
270 | Return
271 |
272 | If WinActive("Editor configuration")
273 | {
274 | ; New program so no doubt new StartDir and Parameters, clear Gui controls
275 | GuiControl, Modify: ,Exe, %Exe%
276 | GuiControl, Modify: ,Icon,%Icon%
277 | GuiControl, Modify: ,Name,%Name%
278 | GuiControl, Modify: ,StartDir,
279 | GuiControl, Modify: ,Parameters,
280 | GuiControl, Modify: ,Delay,0
281 | GuiControl, Modify: ,Open,0
282 | }
283 | Else If WinActive("Settings") and (Exe)
284 | {
285 | GuiControl, ,TCPath, %Exe%
286 | }
287 | Return
288 |
289 | SelectIni:
290 | FileIni:=""
291 | FileSelectFile, FileIni, 3, , Select TC INI location, INI (*.ini)
292 | if (FileIni = "")
293 | Return
294 |
295 | If WinActive("Settings") and (FileIni)
296 | {
297 | GuiControl, ,TCIniPath, %FileIni%
298 | }
299 | Return
300 |
301 | ; Note: deactivated Everything Directory Tree settings for now
302 | /*
303 | SelectEv:
304 | FileSelectFile, EvPath, 3, c:\program files\everything\, Path to Everything, Executable (*.exe)
305 | if (EvPath = "")
306 | Return
307 |
308 | If WinActive("Settings")
309 | {
310 | GuiControl, ,EvPath, %EvPath%
311 | }
312 | Return
313 | */
314 |
315 | CopyPath:
316 | GuiControlGet, CopyPath, ,Exe
317 | SplitPath, CopyPath, , StartDir
318 | GuiControl, Modify: , StartDir, %StartDir%\
319 | CopyPath:=""
320 | Return
321 |
322 | ModifyButtonOK:
323 | Gui, Modify:Default
324 | Gui, Submit, NoHide
325 | If (Editor = "") ; we have a new editor
326 | Editor:=MatchList.MaxIndex() + 1
327 |
328 | MatchList[Editor,"Exe"]:=Exe
329 | MatchList[Editor,"Icon"]:=Icon
330 | MatchList[Editor,"Name"]:=Name
331 | MatchList[Editor,"Parameters"]:=Parameters
332 | MatchList[Editor,"StartDir"]:=StartDir
333 | If (Method = 1)
334 | Method:="Normal"
335 | Else If (Method = 2)
336 | Method:="DragDrop"
337 | Else If (Method = 3)
338 | Method:="FileList"
339 | Else If (Method = 4)
340 | Method:="cmdline"
341 | MatchList[Editor,"Method"]:=Method
342 | MatchList[Editor,"WindowMode"]:=WindowMode
343 |
344 | StringReplace, Ext, Ext, `r`n, , All
345 | StringReplace, Ext, Ext, `n, , All
346 | StringReplace, Ext, Ext, `r, , All
347 | MatchList[Editor,"Ext"]:=Ext
348 |
349 | If (Trim(MatchList.1.Ext,"`n`r`t ") = "")
350 | MatchList.1.Ext:="txt" ; safety as we need at least one extension for the default editor
351 |
352 | MatchList[Editor,"Delay"]:=Delay
353 | MatchList[Editor,"Open"]:=Open
354 | MatchList[Editor,"Editor"]:=Editor
355 |
356 | If Default
357 | {
358 | DefaultMatchEditor:=[]
359 | DefaultMatchEditor:=MatchList[Editor]
360 | DefaultMatchEditor["Editor"]:=""
361 | MatchList.Remove(Editor)
362 | MatchList.InsertAt(1,DefaultMatchEditor)
363 | DefaultMatchEditor:=""
364 | }
365 |
366 | Gui, Modify:Destroy
367 | Gui, Browse:Default
368 |
369 | If (Editor = Matchlist.MaxIndex()) or (Default)
370 | Gosub, UpdateListview
371 | Else
372 | LV_Modify(SelItem, "",Exe,Parameters,StartDir,WindowMode,Ext,Method,Delay,Open,Editor,Icon,Name)
373 | New:=0,Default:=0
374 | Gosub, BuildMenu
375 | Return
376 |
377 | ModifyGuiEscape:
378 | ModifyButtonCancel:
379 | ModifyGuiClose:
380 | New:=0
381 | Gui, Modify:Destroy
382 | Return
383 |
384 | BrowseGuiClose:
385 | Gui, Browse:Destroy
386 | Return
387 |
388 | UpdateListview:
389 | Gui, Browse:Default
390 |
391 | ; Icon wizardry comes directly from AutoHotkey Listview documentation
392 | ; It works with both Ansi & Unicode versions
393 | ; Calculate buffer size required for SHFILEINFO structure.
394 | sfi_size := A_PtrSize + 8 + (A_IsUnicode ? 680 : 340)
395 | VarSetCapacity(sfi, sfi_size)
396 |
397 | IL_Destroy(ImageListID1)
398 | ; Create an ImageList so that the ListView can display some icons:
399 | ImageListID1 := IL_Create(65, 10, IconSize)
400 | ; Attach the ImageLists to the ListView so that it can later display the icons:
401 | LV_SetImageList(ImageListID1)
402 | LV_Delete()
403 | Count=0
404 | ; Loop % MatchList.MaxIndex() ; Exe|Parameters|StartDir|WindowMode|Ext|Method|Delay|Editor|Icon|Name ; %
405 | for k, v in MatchList
406 | {
407 | If (k = "settings") or (k = "temp")
408 | Continue
409 | FileName := v.Exe ; Must save it to a writable variable for use below.
410 | If (FileName = "")
411 | Continue
412 | If (v.Icon <> "")
413 | ; FileName := StrReplace(v.Icon,"%Commander_Path%",Commander_Path)
414 | FileName := GetPath(v.Icon)
415 |
416 | If InStr(FileName,"%Commander_Path%")
417 | ; FileName := StrReplace(FileName,"%Commander_Path%",Commander_Path)
418 | FileName := GetPath(FileName)
419 |
420 | ; Build a unique extension ID to avoid characters that are illegal in variable names,
421 | ; such as dashes. This unique ID method also performs better because finding an item
422 | ; in the array does not require search-loop.
423 | SplitPath, FileName,,, FileExt ; Get the file's extension.
424 | FileName:=GetPath(FileName)
425 | if FileExt in EXE,ICO,ANI,CUR
426 | {
427 | ExtID := FileExt ; Special ID as a placeholder.
428 | IconNumber = 0 ; Flag it as not found so that these types can each have a unique icon.
429 | }
430 | else ; Some other extension/file-type, so calculate its unique ID.
431 | {
432 | ExtID = 0 ; Initialize to handle extensions that are shorter than others.
433 | Loop 7 ; Limit the extension to 7 characters so that it fits in a 64-bit value.
434 | {
435 | StringMid, ExtChar, FileExt, A_Index, 1
436 | if not ExtChar ; No more characters.
437 | break
438 | ; Derive a Unique ID by assigning a different bit position to each character:
439 | ExtID := ExtID | (Asc(ExtChar) << (8 * (A_Index - 1)))
440 | }
441 | ; Check if this file extension already has an icon in the ImageLists. If it does,
442 | ; several calls can be avoided and loading performance is greatly improved,
443 | ; especially for a folder containing hundreds of files:
444 | IconNumber := IconArray%ExtID%
445 | }
446 | if not IconNumber ; There is not yet any icon for this extension, so load it.
447 | {
448 | ; Get the high-quality small-icon associated with this file extension:
449 | if not DllCall("Shell32\SHGetFileInfo" . (A_IsUnicode ? "W":"A"), "str", FileName
450 | , "uint", 0, "ptr", &sfi, "uint", sfi_size, "uint", 0x101) ; 0x101 is SHGFI_ICON+SHGFI_SMALLICON
451 | IconNumber = 9999999 ; Set it out of bounds to display a blank icon.
452 | else ; Icon successfully loaded.
453 | {
454 | ; Extract the hIcon member from the structure:
455 | hIcon := NumGet(sfi, 0)
456 | ; Add the HICON directly to the small-icon and large-icon lists.
457 | ; Below uses +1 to convert the returned index from zero-based to one-based:
458 | IconNumber := DllCall("ImageList_ReplaceIcon", "ptr", ImageListID1, "int", -1, "ptr", hIcon) + 1
459 | DllCall("ImageList_ReplaceIcon", "ptr", ImageListID2, "int", -1, "ptr", hIcon)
460 | ; Now that it's been copied into the ImageLists, the original should be destroyed:
461 | DllCall("DestroyIcon", "ptr", hIcon)
462 | ; Cache the icon to save memory and improve loading performance:
463 | IconArray%ExtID% := IconNumber
464 | }
465 | }
466 |
467 | ; Create the new row in the ListView and assign it the icon number determined above:
468 | LV_Add("Icon" IconNumber , v.Exe, v.Parameters, v.StartDir, v.WindowMode, v.ext, v.Method, v.Delay, v.Open, A_Index, v.Icon, v.Name)
469 | }
470 | dpifactor:=dpi()
471 | LV_ModifyCol(1, dpifactor*250), LV_ModifyCol(2, dpifactor*70), LV_ModifyCol(3, dpifactor*70)
472 | LV_ModifyCol(4, dpifactor*50), LV_ModifyCol(5, dpifactor*165), LV_ModifyCol(6, dpifactor*70)
473 | LV_ModifyCol(7, dpifactor*40), LV_ModifyCol(8, dpifactor*40), LV_ModifyCol(9, 0)
474 | LV_ModifyCol(10, 0), LV_ModifyCol(11, 0) ; icon, name
475 | Return
476 |
477 | ; Hotkeys & Functions to move a listview row
478 | ; TODO: Fix icon which does not move with the listview row
479 |
480 | ; ListViews G-Label.
481 | LVLabel:
482 | ; Detect Drag event.
483 | If A_GuiEvent = D
484 | LvHandle.Drag() ; Call Drag function using the Handle.
485 | If A_GuiEvent = DoubleClick
486 | Gosub, Modify
487 | return
488 |
489 | MoveUp:
490 | LvHandle.Move(1) ; Move selected rows up.
491 | return
492 |
493 | MoveDown:
494 | LvHandle.Move() ; Move selected rows down.
495 | return
496 |
497 | #include
498 |
--------------------------------------------------------------------------------
/inc/FilteredMenu.ahk:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Foreground menu - show matching programs only based on .ext - uses lib\GetPos.ahk
4 | Shares code with menu.ahk (building menu, AddMenuEntry + AddMenuProgramOptions labels, menuhandler)
5 | Include for F4MiniMenu.ahk
6 |
7 | */
8 |
9 |
10 | FilteredMenu:
11 | GetExt(GetFiles())
12 | If debug
13 | {
14 | debug_ext:=MatchList.Temp.SelectedExtensions
15 | debug_files:=MatchList.Temp.Files
16 | }
17 | CoordMode, Menu, Client
18 | Gosub, BuildFilteredMenu
19 | ; MsgBox % MatchList.settings.FilteredMenuAutoEdit
20 | If (MenuCounter = 3) and (MatchList.Settings.FilteredMenuAutoEdit = 2)
21 | {
22 | ; only found one editor so run automatically
23 | ; TODO how to get from here to openfiles????
24 | ProcessFiles(Matchlist, MatchListReference[3])
25 | OSDTIP_Pop("F4MiniMenu", "Only found one editor.`nOpening file automatically", -750,"W230 H80 U1")
26 | ; MsgBox
27 | }
28 | Else
29 | {
30 | Coord:=GetPos(MatchList.settings.MenuPos,MatchList.MaxIndex())
31 | Menu, %MenuName%, Show, % Coord["x"], % Coord["y"]
32 | }
33 | MatchList.Temp.Files:="",MatchList.Temp.SelectedExtensions:="",MatchList.Delete("Temp")
34 | MenuCounter:=""
35 | Return
36 |
37 | ; Build menu based on defined editors
38 |
39 | BuildFilteredMenu:
40 | Menu, MyFilteredMenu, Add,
41 | Menu, MyFilteredMenu, DeleteAll
42 |
43 | MenuName:="MyFilteredMenu"
44 |
45 | MatchListReference:=[] ; Object and counter below used to keep track of the original position in MatchList so
46 | MenuCounter:=0 ; we select the correct editor in the filtered menu as we use A_ThisMenuItemPos in menuhandler
47 |
48 | for k, v in MatchList
49 | {
50 | If (k = "settings") or (k = "temp")
51 | Continue ; skip settings
52 | If RegExMatch(MatchList.Temp.SelectedExtensions,StrReplace(RegExExtensions(v.ext),",","|")) or (k = 1)
53 | {
54 | MenuCounter++
55 | ExeName:=v.exe
56 | SplitPath, ExeName, ShortName
57 | If (v.name <> "")
58 | ShortName:=v.name
59 |
60 | If InStr(ShortName,"&")
61 | ShortName:=MenuPadding ShortName
62 | else
63 | ShortName:=MenuPadding "&" ShortName
64 |
65 | MatchListReference[MenuCounter]:=A_Index
66 |
67 | If (k = 1) ; because we add a separator line we need to keep track of this
68 | MenuCounter++
69 |
70 | Gosub, AddMenuEntry
71 | }
72 | }
73 |
74 | Menu, MyFilteredMenu, Add,
75 | Menu, MyFilteredMenu, Add, % MatchList.settings.FullMenu ? "&" MatchList.settings.FullMenu " Full menu" : " Full menu", :MyMenu
76 | Try
77 | Menu, MyFilteredMenu, Icon, % MatchList.settings.FullMenu ? "&" MatchList.settings.FullMenu " Full menu" : " Full menu", res\f4.ico
78 |
79 | Gosub, AddMenuProgramOptions
80 |
81 |
82 |
83 | If (MenuCounter = 2) ; we haven't found any matches, so just show full menu
84 | MenuName:="MyMenu"
85 |
86 | Return
87 |
--------------------------------------------------------------------------------
/inc/HelperFunctions.ahk:
--------------------------------------------------------------------------------
1 | ; used in F4MiniMenu and F4TCIE
2 |
3 | GetPath(path)
4 | {
5 | global MyComSpec,Commander_Path,MyProgramFiles,MyProgramFilesx86,MyProgramW6432,A_UserProfile
6 | ; path:=StrReplace(path,"%ComSpec%",MyComSpec)
7 | if !InStr(path,"\") ; for programs in path environment e.g. wordpad, write
8 | Return path
9 | if !InStr(path,"%") ; no special treatment required
10 | Return GetFullPathName(path)
11 | Loop, parse, % "Commander_Path,A_ScriptDir,A_ComputerName,A_UserName,A_WinDir,A_ProgramFiles,ProgramFiles,A_AppData,A_AppDataCommon,A_Desktop,A_DesktopCommon,A_StartMenu,A_StartMenuCommon,A_Programs,A_ProgramsCommon,A_Startup,A_StartupCommon,A_MyDocuments,A_UserProfile", CSV
12 | path:=StrReplace(path,"%" A_LoopField "%",%A_LoopField%)
13 | ; special cases
14 | path:=StrReplace(path,"%WinDir%",A_WinDir)
15 | path:=StrReplace(path,"%ProgramFiles%",MyProgramFiles)
16 | path:=StrReplace(path,"%ProgramFiles(x86)%",MyProgramFilesx86)
17 | path:=StrReplace(path,"%ProgramW6432%",MyProgramW6432)
18 | Return GetFullPathName(path)
19 | }
20 |
21 | ; get absolute path from relative path
22 | ; https://www.autohotkey.com/boards/viewtopic.php?p=289536#p289536
23 | GetFullPathName(path) {
24 | cc := DllCall("GetFullPathName", "str", path, "uint", 0, "ptr", 0, "ptr", 0, "uint")
25 | VarSetCapacity(buf, cc*(A_IsUnicode?2:1))
26 | DllCall("GetFullPathName", "str", path, "uint", cc, "str", buf, "ptr", 0, "uint")
27 | return buf
28 | }
29 |
30 | xGetTCCommander_Path(editor)
31 | {
32 | global MyComSpec
33 | editor:=StrReplace(editor,"%Commander_Path%",Commander_Path)
34 | editor:=StrReplace(editor,"%ComSpec%",MyComSpec)
35 | Return editor
36 | }
37 |
38 | RegExExtensions(in)
39 | {
40 | out:="iU)\b(" StrReplace(StrReplace(StrReplace(in,",","|"),"?",".?"),"*",".*") ")\b" ; v0.9 allow for wildcards
41 | Return out
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/inc/LoadSettings1.ahk:
--------------------------------------------------------------------------------
1 | ; used in F4MiniMenu and F4TCIE
2 |
3 | SplitPath, A_ScriptName, , , , OutNameNoExt
4 | If (SubStr(OutNameNoExt,0) <> "i")
5 | {
6 | F4ConfigFile:="F4MiniMenu.xml"
7 | F4Load:="XA_Load"
8 | F4Save:="XA_Save"
9 | }
10 | else
11 | {
12 | F4ConfigFile:="F4MiniMenu.ini"
13 | F4Load:="iob"
14 | F4Save:="iob_save"
15 | }
16 |
17 | Error:=0
18 | ; http://en.wikipedia.org/wiki/List_of_archive_formats
19 | ArchiveExtentions:="\.(a|ar|cpio|shar|iso|lbr|mar|tar|bz2|F|gz|lz|lzma|lzo|rz|sfark|xz|z|infl|7z|s7z|ace|afa|alz|apk|arc|arj|ba|bh|cab|cfs|cpt|dar|dd|dgc|dmg|gca|ha|hki|ice|j|kgb|lzh|lha|lzx|pak|partimg|paq6|paq7|paq8|pea|pim|pit|qda|rar|rk|sda|sea|sen|sfx|sit|sitx|sqx|tar\.gz|tgz|tar\.Z|tar\.bz2|tbz2|tar\.lzma|tlz|uc|uc0|uc2|ucn|ur2|ue2|uca|uha|wim|xar|xp3|yz1|zip|zipx|zoo|zz)\\"
20 |
21 | ; get Environment variables
22 | EnvGet, MyComSpec, ComSpec
23 | EnvGet, MyProgramFiles, ProgramFiles
24 | EnvGet, MyProgramFilesx86, ProgramFiles(x86)
25 | EnvGet, MyProgramW6432, ProgramW6432
26 | EnvGet, A_UserProfile, UserProfile
27 |
--------------------------------------------------------------------------------
/inc/LoadSettings2.ahk:
--------------------------------------------------------------------------------
1 | ; used in F4MiniMenu and F4TCIE
2 |
3 | ; Load settings on MatchList Object
4 | Try
5 | {
6 | %F4Load%(F4ConfigFile)
7 | }
8 | Catch
9 | {
10 | Error:=1
11 | }
12 |
13 | If ((MatchList.MaxIndex() = 0) or (MatchList.MaxIndex() = ""))
14 | Error:=1
15 |
--------------------------------------------------------------------------------
/inc/Menu.ahk:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Foreground menu - uses lib\GetPos.ahk
4 | FilteredMenu.ahk makes use of various labels in Menu.ahk
5 | Include for F4MiniMenu.ahk
6 |
7 | */
8 |
9 | ShowMenu:
10 | CoordMode, Menu, Client
11 | Coord:=GetPos(MatchList.settings.MenuPos,MatchList.MaxIndex())
12 | Menu, MyMenu, Show, % Coord["x"], % Coord["y"]
13 | MatchList.Temp.Files:="",MatchList.Temp.SelectedExtensions:="",MatchList.Delete("Temp")
14 | Return
15 |
16 | ; Build menu based on defined editors
17 |
18 | BuildMenu:
19 | Menu, MyMenu, Add,
20 | Menu, MyMenu, DeleteAll
21 |
22 | MenuName:="MyMenu"
23 |
24 | for k, v in MatchList
25 | {
26 | If (k = "settings") or (k = "temp")
27 | Continue ; skip settings
28 | ExeName:=v.exe
29 | SplitPath, ExeName, ShortName
30 | If (v.name <> "")
31 | ShortName:=v.name
32 |
33 | If InStr(ShortName,"&")
34 | ShortName:=MenuPadding ShortName
35 | else
36 | ShortName:=MenuPadding "&" ShortName
37 |
38 | Gosub, AddMenuEntry
39 |
40 | }
41 |
42 | Gosub, AddMenuProgramOptions
43 |
44 | Return
45 |
46 | ; If the tray icon is double click we do not actually want to do anything
47 | DoubleTrayClick:
48 | Send {rbutton} ; show tray menu
49 | Return
50 |
51 |
52 | ; Tray menu
53 | MenuHandler:
54 | ; MsgBox % A_ThisMenu ":" A_ThisMenuItemPos-1 ":" MatchList[A_ThisMenuItemPos-1].exe ; debug
55 | If MatchList.Settings.log
56 | Log(A_Now " : Menuhandler, call -> A_ThisMenu=" A_ThisMenu "| A_ThisMenuItemPos-1=" A_ThisMenuItemPos-1 "| Exe=" A_ThisMenuItem,MatchList.Settings.logFile)
57 |
58 | ; Easy & Quick options first
59 | If (A_ThisMenuItem = "&Open")
60 | {
61 | ListHotkeys
62 | Return
63 | }
64 | Else If (A_ThisMenuItem = "&Reload this script")
65 | {
66 | Reload
67 | Return
68 | }
69 | Else If (A_ThisMenuItem = "&Edit this script")
70 | {
71 | Run Edit %A_ScriptName%
72 | Return
73 | }
74 | Else If (A_ThisMenuItem = "&Suspend Hotkeys")
75 | {
76 | Menu, tray, ToggleCheck, &Suspend Hotkeys
77 | Suspend
78 | Return
79 | }
80 | Else If (A_ThisMenuItem = "&Pause Script")
81 | {
82 | Menu, tray, ToggleCheck, &Pause Script
83 | Pause
84 | Return
85 | }
86 | Else If (A_ThisMenuItem = " Exit")
87 | Return
88 | Else If (A_ThisMenuItem = " Settings") ; Settings menu
89 | {
90 | Gosub, Settings
91 | Return
92 | }
93 | Else If (A_ThisMenuItemPos = 1) ; Default editor
94 | {
95 | If MatchList.Settings.log
96 | Log(A_Now " : Menuhandler, selected editor -> Default editor" ,MatchList.Settings.logFile)
97 | ProcessFiles(Matchlist, 1)
98 | Return
99 | }
100 | Else
101 | If (MatchList.Temp.SelectedExtensions = "") or (A_ThisMenu = "MyMenu") ; entire Foreground menu
102 | {
103 | If MatchList.Settings.log
104 | Log(A_Now " : Menuhandler, selected editor -> editor from entire menu, Exe=" A_ThisMenuItem,MatchList.Settings.logFile)
105 | ProcessFiles(Matchlist, A_ThisMenuItemPos-1) ; proceed with the selected editor. Menu order = editor order.
106 | MatchList.Temp.Files:="",MatchList.Temp.SelectedExtensions:="",MatchList.Delete("Temp"),MatchListReference:=""
107 | }
108 | else ; filtered Foreground menu
109 | {
110 | If MatchList.Settings.log
111 | Log(A_Now " : Menuhandler, selected editor -> editor from filtered menu, Exe=" A_ThisMenuItem,MatchList.Settings.logFile)
112 | ProcessFiles(Matchlist, MatchListReference[A_ThisMenuItemPos])
113 | MatchList.Temp.Files:="",MatchList.Temp.SelectedExtensions:="",MatchList.Delete("Temp"),MatchListReference:=""
114 | }
115 |
116 | Return
117 |
118 | AddMenuEntry:
119 |
120 | Menu, %MenuName%, Add, %ShortName%, MenuHandler
121 |
122 | Try
123 | {
124 | If (v.icon = "")
125 | Menu, %MenuName%, Icon, %ShortName%, % StrReplace(ExeName,"%Commander_Path%",Commander_Path)
126 | Else
127 | Menu, %MenuName%, Icon, %ShortName%, % StrReplace(v.icon,"%Commander_Path%",Commander_Path)
128 | }
129 | Catch ; it is not an EXE
130 | {
131 | Menu, %MenuName%, Icon, %ShortName%, shell32.dll, 3
132 | }
133 | If (k = 1) ; Add line after default editors
134 | Menu, %MenuName%, Add
135 |
136 | If debug
137 | {
138 | debug_menu .= MenuCounter " : " ShortName "`n"
139 | }
140 | Return
141 |
142 | AddMenuProgramOptions:
143 |
144 | ; Program options
145 | Menu, %MenuName%, Add
146 | Menu, %MenuName%, Add, %MenuPadding%Add new Editor, ConfigEditorsNew
147 | Menu, %MenuName%, Icon, %MenuPadding%Add new Editor, shell32.dll, 176
148 | Menu, %MenuName%, Add, %MenuPadding%Configure Editors, ConfigEditors
149 | Menu, %MenuName%, Icon, %MenuPadding%Configure Editors, shell32.dll, 70
150 | Menu, %MenuName%, Add, %MenuPadding%Scan Document Templates, DocumentTemplatesScan
151 | Menu, %MenuName%, Icon, %MenuPadding%Scan Document Templates, shell32.dll, 172
152 | Menu, %MenuName%, Add, %MenuPadding%Settings, MenuHandler
153 | Menu, %MenuName%, Icon, %MenuPadding%Settings, shell32.dll, 170
154 |
155 | Menu, %MenuName%, Add, %MenuPadding%Exit, MenuHandler
156 | Menu, %MenuName%, Icon, %MenuPadding%Exit, shell32.dll, 132
157 |
158 | Return
159 |
--------------------------------------------------------------------------------
/inc/Settings.ahk:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | General program settings GUI
4 | Include for F4MiniMenu.ahk
5 |
6 | */
7 |
8 | Settings:
9 |
10 | Gui, Browse:Destroy
11 |
12 | ; Variables
13 | ;SelectMenuPos:=MatchList.settings.MenuPos
14 | ;SelectTCStart:=MatchList.settings.TCStart
15 | ;SettingsFormat:=MatchList.settings.SettingsFormat
16 | ;If (SettingsFormat = "")
17 | ; SettingsFormat:=1
18 | ;OldSettingsFormat:=SettingsFormat
19 |
20 | If (MatchList.settings.FilteredMenuAutoEdit = "")
21 | MatchList.settings.FilteredMenuAutoEdit:=1
22 | FGHKey:=MatchList.settings.ForegroundHotkey
23 | BGHKey:=MatchList.settings.BackgroundHotkey
24 | TMHKey:=MatchList.settings.FilteredHotkey
25 |
26 |
27 | ; Turn hotkeys off to be sure
28 | HotKeyState:="Off"
29 | Gosub, SetHotkeys
30 |
31 | ; Gui for general program settings
32 | Gui, Settings: +OwnDialogs
33 | Gui, Settings: font, % dpi("s8")
34 | Gui, Settings: Add, GroupBox, % dpi("x16 y7 w540 h70"), Menu
35 | Gui, Settings: Add, Text, % dpi("x25 y25 w309 h16"), &Selection menu appears (TC only)
36 | Gui, Settings: Add, DropDownList, % dpi("x328 y20 w219 h25 r4 Choose" MatchList.settings.MenuPos " vMenuPos AltSubmit"), 1 - At Mouse cursor|2 - Centered in window|3 - Right next to current file|4 - Docked next to current file (opposite panel)
37 | Gui, Settings: Add, Text, % dpi("x25 yp+35 w309 h16"), &Accelerator key for full menu (for use in filtered menu, 1 char.)
38 | Gui, Settings: Add, Edit, % dpi("x328 yp-5 w30 h21 vFullMenu"), % MatchList.settings.FullMenu ; %
39 | Gui, Settings: Add, Text, % dpi("x365 yp+5 w70 h16"), If one result:
40 | Gui, Settings: Add, DropDownList, % dpi("x430 yp-5 w117 h25 r2 Choose" MatchList.settings.FilteredMenuAutoEdit " vFilteredMenuAutoEdit AltSubmit"), 1 - Show menu|2 - Edit directly
41 |
42 | Gui, Settings: Add, GroupBox, % dpi("x16 yp+40 w260 h45"), Files
43 | Gui, Settings: Add, Text, % dpi("x25 yp+20 w209 h16"), &Maximum number of files to be opened
44 | Gui, Settings: Add, Edit, % dpi("x227 yp-5 w40 h21 Number vMaxFiles"), % MatchList.settings.Maxfiles ; %
45 |
46 | Gui, Settings: Add, GroupBox, % dpi("x280 yp-15 w276 h45"), WinWait
47 | Gui, Settings: Add, Text, % dpi("x289 yp+20 w209 h16"), &Seconds (max) to wait for program window
48 | Gui, Settings: Add, Edit, % dpi("x507 yp-5 w40 h21")
49 | Gui, Settings: Add, UpDown, vMaxWinWaitSec Range2-10, % MatchList.Settings.MaxWinWaitSec ; %
50 |
51 |
52 | Gui, Settings: Add, GroupBox, % dpi("x16 yp+40 w540 h100"), Total Commander
53 | Gui, Settings: Add, DropDownList, % dpi("x25 yp+20 w240 h25 R3 Choose" MatchList.settings.TCStart " vTCStart AltSubmit"), 1 - Do not start TC (default)|2 - Start TC if not Running (set TC Path)|3 - Always start TC (set TC Path)
54 | Gui, Settings: Add, Text, % dpi("xp+250 yp+5 w50 h16"), TC Path
55 | If !FileExist(MatchList.settings.TCPath)
56 | MatchList.settings.TCPath:=""
57 | Gui, Settings: Add, Edit , % dpi("xp+53 yp-5 w180 h21 vTCPath"), % MatchList.settings.TCPath ; %
58 | Gui, Settings: Add, Button, % dpi("xp+187 yp w30 h20 gSelectExe"), >>
59 |
60 | Gui, Settings: Add, Text, % dpi("xp-238 yp+30 w50 h16"), INI Path
61 | If !FileExist(MatchList.settings.TCIniPath)
62 | MatchList.settings.TCIniPath:=""
63 |
64 | Gui, Settings: Add, Edit , % dpi("xp+51 yp-5 w180 h21 vTCIniPath"), % MatchList.settings.TCIniPath ; %
65 | Gui, Settings: Add, Button, % dpi("xp+187 yp w30 h20 gSelectIni"), >>
66 |
67 | Checked:=MatchList.settings.F4MMCloseAll
68 | Gui, Settings: Add, Checkbox, % dpi("x25 yp+3 w240 h16 Checked" checked " vF4MMCloseAll"), Close F4MM when all copies of TC close
69 | Checked:=MatchList.settings.F4MMClosePID
70 | Gui, Settings: Add, Checkbox, % dpi("x25 yp+25 w240 h16 Checked" checked " vF4MMClosePID"), Close F4MM when TC closes started by F4MM
71 | Gui, Settings: Font, % dpi("cGreen")
72 | Gui, Settings: Add, Text, % dpi("xp+240 yp gFMMCloseHelpText"), (?)
73 | Gui, Settings: Add, Text, % dpi("xp+260 yp gFMMPathsHelpText"), (?)
74 | Gui, Settings: Font, % dpi("cBlack")
75 | Gui, Settings: Font, ; needed as theme is stripped from control @ https://www.autohotkey.com/boards/viewtopic.php?p=399355#p399355
76 | Gui, Settings: Font, % dpi("s8")
77 |
78 | Gui, Settings: Add, GroupBox, % dpi("x16 yp+35 w395 h120"), Hotkeys
79 |
80 | Gui, Settings: Add, Text, % dpi("x25 yp+25 w150 h16"), &Background mode (direct)
81 | ;Gui, Settings: Add, Radio, % dpi("xp+130 yp w45 h16 vBEsc"), Esc
82 | ;Gui, Settings: Add, Radio, % dpi("xp+45 yp w45 h16 vBWin"), Win
83 | Gui, Settings: Add, DropDownList, % dpi("xp+140 yp-3 w70 R3 vBMod"), |Esc|Win
84 |
85 | ; Always annoying to work around Hotkey control limit, use boxes for Win & Esc keys
86 | Gui, Settings: Default
87 | If InStr(BGHKey,"#")
88 | {
89 | StringReplace, BGHKey, BGHKey, #, , All
90 | GuiControl, Choose, BMod, 3
91 | }
92 | If InStr(BGHKey,"Esc &")
93 | {
94 | StringReplace, BGHKey, BGHKey, Esc &, , All
95 | StringReplace, BGHKey, BGHKey, Esc &`;, , All
96 | StringReplace, BGHKey, BGHKey, Esc &, , All
97 | StringReplace, BGHKey, BGHKey, %A_Space%, , All
98 | GuiControl, Choose, BMod, 3
99 | }
100 |
101 | Gui, Settings: Add, Hotkey, % dpi("xp+90 yp w140 h20 vBGHKey"), %BGHKey%
102 |
103 | Gui, Settings: Add, Text, % dpi("x25 yp+35 w150 h16"), &Foreground mode (menu)
104 | ;Gui, Settings: Add, Radio, % dpi("xp+130 yp w45 h16 vFEsc"), Esc
105 | ;Gui, Settings: Add, Radio, % dpi("xp+45 yp w45 h16 vFWin"), Win
106 | Gui, Settings: Add, DropDownList, % dpi("xp+140 yp-3 w70 R3 vFMod"), |Esc|Win
107 |
108 | Gui, Settings: Default
109 |
110 | If InStr(FGHKey,"#")
111 | {
112 | StringReplace, FGHKey, FGHKey, #, , All
113 | GuiControl, Choose, FMod, 3
114 | }
115 |
116 | If InStr(FGHKey,"Esc &")
117 | {
118 | StringReplace, FGHKey, FGHKey, Esc &, , All
119 | StringReplace, FGHKey, FGHKey, Esc &`;, , All
120 | StringReplace, FGHKey, FGHKey, Esc &, , All
121 | StringReplace, FGHKey, FGHKey, %A_Space%, , All
122 | GuiControl, Choose, FMod, 2
123 | }
124 |
125 | Gui, Settings: Add, Hotkey, % dpi("xp+90 yp w140 h20 vFGHKey"), %FGHKey%
126 | ;Gui, Settings: Add, Button, % dpi("xp+110 yp w30 h20 gButtonClearFG"), clear
127 |
128 | Gui, Settings: Add, Text, % dpi("x25 yp+35 w150 h16"), Fil&tered mode (menu)
129 | ;Gui, Settings: Add, Radio, % dpi("xp+130 yp w45 h16 vTEsc"), Esc
130 | ;Gui, Settings: Add, Radio, % dpi("xp+45 yp w45 h16 vTWin"), Win
131 | Gui, Settings: Add, DropDownList, % dpi("xp+140 yp-3 w70 R3 vTmod"), |Esc|Win
132 |
133 | Gui, Settings: Default
134 |
135 | If InStr(TMHKey,"#")
136 | {
137 | StringReplace, TMHKey, TMHKey, #, , All
138 | GuiControl, Choose , Tmod, 3
139 | }
140 |
141 | If InStr(TMHKey,"Esc &")
142 | {
143 | StringReplace, TMHKey, TMHKey, Esc &, , All
144 | StringReplace, TMHKey, TMHKey, Esc &`;, , All
145 | StringReplace, TMHKey, TMHKey, Esc &, , All
146 | StringReplace, TMHKey, TMHKey, %A_Space%, , All
147 | GuiControl, Choose, Tmod, 2
148 | }
149 |
150 | Gui, Settings: Add, Hotkey, % dpi("xp+90 yp w140 h20 vTMHKey"), %TMHKey%
151 | ; Gui, Settings: Add, Button, % dpi("xp+110 yp w30 h20 gButtonClearTM"), clear
152 |
153 | Gui, Settings: Add, Button, % dpi("xp+170 yp-75 w120 h25 gButtonOK"), OK
154 | Gui, Settings: Add, Button, % dpi("xp yp+40 w120 h25 gButtonClear"), Clear All Hotkeys
155 | Gui, Settings: Add, Button, % dpi("xp yp+40 w120 h25 gSettingsGuiClose"), Cancel
156 |
157 | Gui, Settings: Add, GroupBox, % dpi("x16 yp+40 w260 h72"), Other prg. (Hotkey: Copy File Names w. Full Path)
158 |
159 | Gui, Settings: Add, Text, % dpi("x25 yp+20 w100 h20"), Dbl Cmd:
160 | Gui, Settings: Add, Hotkey, % dpi("xp+52 yp-3 w90 h20 vDoubleCommander"), % MatchList.settings.DoubleCommander
161 |
162 | Gui, Settings: Add, Text, % dpi("x25 yp+30 w50 h20"), XYPlorer:
163 | Gui, Settings: Add, Hotkey, % dpi("xp+52 yp-3 w90 h20 vXYPlorer"), % MatchList.settings.XYPlorer
164 |
165 | Checked:=MatchList.settings.Explorer
166 | Gui, Settings: Add, Checkbox, % dpi("xp+100 yp-25 w60 h16 Checked" checked " vExplorer"), Explorer
167 |
168 | Checked:=MatchList.settings.Everything
169 | Gui, Settings: Add, Checkbox, % dpi("xp yp+28 w80 h16 Checked" checked " vEverything"), Everything
170 |
171 | Gui, Settings: Font, % dpi("s8 cGreen")
172 | Gui, Settings: Add, Text, % dpi("xp+70 yp-28 gFMMFileManText"), (?)
173 | Gui, Settings: Font, % dpi("cBlack")
174 | Gui, Settings: Font, ; see note above, required to reset style
175 | Gui, Settings: Font, % dpi("s8")
176 |
177 | Gui, Settings: Add, GroupBox, % dpi("xp+35 yp-19 w270 h72"), Use elsewhere in TC (no menu)
178 |
179 | Checked:=MatchList.settings.Lister
180 | Gui, Settings: Add, Checkbox, % dpi("xp+10 yp+20 w220 h16 Checked" checked " vLister"), Lister (+ use F4Edit setting in wincmd.ini)
181 |
182 | Checked:=MatchList.settings.QuickView
183 | Gui, Settings: Add, Checkbox, % dpi("xp yp+28 w120 h16 Checked" checked " vQuickView"), QuickView (see ?)
184 |
185 | Checked:=MatchList.settings.FindFiles
186 | Gui, Settings: Add, Checkbox, % dpi("xp+160 yp w80 h16 Checked" checked " vFindFiles"), Find Files
187 |
188 | Gui, Settings: Font, % dpi("s8 cGreen")
189 | Gui, Settings: Add, Text, % dpi("xp+70 yp-28 gFMMTCElseWhere"), (?)
190 | Gui, Settings: Font, % dpi("cBlack")
191 | Gui, Settings: Font, ; see note above, required to reset style
192 | Gui, Settings: Font, % dpi("s8")
193 |
194 |
195 | ; Note: deactivated Everything Directory Tree and DocumentTemplates settings for now
196 | /*
197 | Gui, Settings: Add, Text, % dpi("xp+70 yp+1 w100 h20"), Ev. Dir Tree:
198 | Gui, Settings: Add, Hotkey, % dpi("xp+100 yp-3 w90 h20 vEVDirTree"), % MatchList.settings.EVDirTree
199 |
200 | Gui, Settings: Add, Text, % dpi("xp+100 yp+1 w50 h20"), Ev. Path:
201 | Gui, Settings: Add, Edit , % dpi("xp+50 yp-5 w160 h21 vEvPath"), % MatchList.settings.EvPath ; %
202 | Gui, Settings: Add, Button, % dpi("xp+165 yp w30 h20 gSelectEv"), >>
203 |
204 | Gui, Settings: Add, GroupBox, % dpi("x16 yp+45 w540 h70"), Currently Available Document Templates
205 | Gui, Settings: Add, Edit, % dpi("x25 yp+20 ReadOnly h40 w385 vDocumentTemplates"), % MatchList.Settings.templatesExt
206 | Gui, Settings: Add, Button, % dpi("xp+402 yp w120 h25 gButtonDocumentTemplates"), Update (scan)
207 | */
208 |
209 | ;Gui, Settings: Add, GroupBox, x16 yp+40 w395 h60 , Misc.
210 | ;perhaps in future versions
211 | ;Gui, Settings: Add, Text, x25 yp+25 w150 h16 , Store set&tings in:
212 | ;Gui, Settings: Add, DropDownList, xp+225 yp-5 w140 h25 r2 Choose%SettingsFormat% vSettingsFormat AltSubmit, 1 - XML Format|2 - INI format
213 |
214 | Gui, Settings: Add, Link, % dpi("x25 yp+60"), F4MiniMenu %F4Version%: Open selected file(s) from TC in defined editor(s). More info at Github.com/hi5/F4MiniMenu.
215 |
216 | ;Gui, Settings: Add, GroupBox, xp+400 yp-85 w122 h60
217 | ;Gui, Settings: Add, Link, xp+5 yp+13, Feedback welcome at`nTotal Commander forum`nor GitHub Issues.
218 |
219 | Gui, Settings: Show, % dpi("center w570"), F4MiniMenu - Settings
220 | Return
221 |
222 | ButtonDocumentTemplates:
223 | Gosub, DocumentTemplatesScan
224 | Gui, Settings: Default
225 | GuiControl,,DocumentTemplates, % MatchList.Settings.templatesExt
226 | Return
227 |
228 | ButtonOK:
229 | Gui, Settings: Submit, NoHide
230 | MatchList.settings.MenuPos:=MenuPos
231 | MatchList.settings.FilteredMenuAutoEdit:=FilteredMenuAutoEdit
232 | If (MaxFiles > 50)
233 | {
234 | MsgBox, 36, Confirm, Are you sure you want to`nset the maximum at %MaxFiles% files?`n(No will set the maximum to 50)
235 | IfMsgBox, No
236 | MaxFiles:=50
237 | }
238 | MatchList.settings.MaxFiles:=MaxFiles
239 | MatchList.settings.TCStart:=TCStart
240 | MatchList.settings.TCPath:=TCPath
241 | MatchList.settings.F4MMCloseAll:=F4MMCloseAll
242 | MatchList.settings.F4MMClosePID:=F4MMClosePID
243 | MatchList.settings.FullMenu:=trim(SubStr(FullMenu,1,1)," `t&")
244 | MatchList.settings.MaxWinWaitSec:=MaxWinWaitSec
245 |
246 | ;GuiControlGet, EscFG, , FEsc
247 | ;GuiControlGet, WinFG, , FWin
248 | ;GuiControlGet, EscBG, , BEsc
249 | ;GuiControlGet, WinBG, , BWin
250 | ;GuiControlGet, EscTM, , TEsc
251 | ;GuiControlGet, WinTM, , TWin
252 |
253 | ; Revert the boxes to the Hotkey def.
254 | If (FGHKey <> "")
255 | {
256 | If (FMod = "Win")
257 | FGHKey:="#" FGHKey
258 | If (FMod = "Esc" ) and (RegExMatch(FGHKey,"[\^\+\!\#]") = 0)
259 | FGHKey:="Esc & " FGHKey
260 | }
261 |
262 | If (BGHKey <> "")
263 | {
264 | If (BMod = "Win")
265 | BGHKey:="#" BGHKey
266 | If (BMod = "Esc") and (RegExMatch(BGHKey,"[\^\+\!\#]") = 0)
267 | BGHKey:="Esc & " BGHKey
268 | }
269 |
270 | If (TMHKey <> "")
271 | {
272 | If (TMod = "Win")
273 | TMHKey:="#" TMHKey
274 | If (TMod = "Esc") and (RegExMatch(TMHKey,"[\^\+\!\#]") = 0)
275 | TMHKey:="Esc & " TMHKey
276 | }
277 |
278 | MatchList.settings.ForegroundHotkey:=FGHKey
279 | MatchList.settings.BackgroundHotkey:=BGHKey
280 | MatchList.settings.FilteredHotkey:=TMHKey
281 |
282 | MatchList.settings.Explorer:=Explorer
283 | MatchList.settings.Everything:=Everything
284 | ;MatchList.settings.EvPath:=EvPath
285 | ;MatchList.settings.EVDirTree:=EVDirTree
286 | MatchList.settings.DoubleCommander:=DoubleCommander
287 | MatchList.settings.XYPlorer:=XYPlorer
288 | MatchList.settings.Lister:=Lister
289 | MatchList.settings.QuickView:=QuickView
290 | MatchList.settings.FindFiles:=FindFiles
291 |
292 | HotKeyState:="On"
293 | Gosub, SetHotkeys
294 | Gui, Settings:Destroy
295 | Gosub, SaveSettings
296 | Sleep 500
297 | Reload ; v0.96 we may have changed F4MMClose so we need to reload the script to (de)activate the WinWait in F4MiniMenu.ahk
298 | Sleep 500
299 | Return
300 |
301 | ButtonClear:
302 | Gui, Settings: Default
303 | GuiControl, Choose, BMod, 0
304 | GuiControl, Choose, FMod, 0
305 | GuiControl, Choose, TMod, 0
306 | GuiControl, , BGHKey,
307 | GuiControl, , FGHKey,
308 | GuiControl, , TMHKey,
309 | Return
310 |
311 | SettingsGuiEscape:
312 | SettingsGuiClose:
313 | Gui, Settings: Destroy
314 |
315 | HotKeyState:="On"
316 | Gosub, SetHotkeys
317 | Return
318 |
319 | FMMPathsHelpText:
320 | MsgBox, 8224, TC/INI Paths (experimental),
321 | (join`n
322 | TC Path: Attempt is made to read from the registry, can be set manually.
323 |
324 | INI Path: As F4MM can be launched first or used "portable", it may not be able to read one or more settings from wincmd.ini.
325 | Set manually if this is the case (see Lister/F4Edit setting).
326 |
327 | When set manually the registry will not be read.
328 |
329 | (Relative paths from the F4MM program folder).
330 | )
331 | Return
332 |
333 | FMMCloseHelpText:
334 | MsgBox, 8224, F4MMClose (experimental),
335 | (join`n
336 | F4MiniMenu - %F4Version% can automatically exit from memory using the following rules:
337 |
338 | [1] Close F4MM when all copies of TC close:
339 | waits until all running copies of Total Commander are closed.
340 |
341 | [2] Close F4MM when TC closes started by F4MM:
342 | If you have started (a new) Total Commander via F4MiniMenu, wait until that specific Total Commander closes.
343 |
344 | )
345 | Return
346 |
347 | FMMFileManText:
348 | MsgBox, 8224, Other file managers (experimental),
349 | (join`n
350 | F4MiniMenu can also work with other programs.`nTo activate, enter the keyboard shortcut to "Copy File Name(s) with Full Path"`n`
351 | Double Commander default:`tShift+Ctrl+C`n
352 | XYPlorer default:`t`t`tCtrl+p`n
353 | Explorer, Everything:`t`tCheckbox to use F4MM`n`n
354 | Notes:
355 | ℹ Everything >v1.5: F4 may override "Focus Next Selected"
356 | ⚠ Use at your own risk.
357 | )
358 | Return
359 |
360 | FMMTCElseWhere:
361 | MsgBox, 8224, Use elsewhere in TC (experimental),
362 | (join`n
363 | As of TC 11.03 it is natively possible to "Edit" files from Lister (see TC Help, especially [lister] F4Edit and Editor settings).
364 | F4MM also opens files that are shown using plugins whereas TC only when used in internal mode (no plugins).
365 |
366 | F4MM can read the F4Edit and also close the Lister window, or use TC's native "edit" feature by unchecking the Lister box.
367 |
368 | F4MM also works in the Find Files window by default, this can be turn off. Otherwise TC will use the Editor defined in the configuration (note F4TCIE could be used there).
369 |
370 | QuickView is experimental: when checked, it will try to open the file that is currently open in the QuickView panel, even if multiple files are selected in the active TC panel and
371 | the focus is NOT on the QuickView panel it self.
372 | The foreground and filtered menus can be opened in the QuickView panel, but here also only the one "viewed" file will be opened.
373 | When unchecked all selected files will be opened even when QuickView is being used.
374 |
375 | )
376 |
377 | ;Ev DirTree:`tReplace TC Dir Tree (Alt-F10)`n
378 | ;Ev Path:`t`tPath to eEverything.exe (required by DirTree)`n`n
379 | Return
380 |
--------------------------------------------------------------------------------
/inc/TotalCommanderPath.ahk:
--------------------------------------------------------------------------------
1 | ; used in F4MiniMenu and F4TCIE
2 |
3 | ; try to get Commander_Path and Commander_Ini,
4 | ; these will be empty if TC is not running (yet) or F4MM was started _before_ TC
5 | ; we check for values in settings first, if not available, try to read from the
6 | ; environment, fall back to registry
7 |
8 | If FileExist(MatchList.settings.TCPath)
9 | {
10 | Commander_Path:=StrReplace(MatchList.settings.TCPath,"\TOTALCMD.EXE")
11 | Commander_Path:=StrReplace(Commander_Path,"\TOTALCMD64.EXE")
12 | }
13 | else
14 | {
15 | EnvGet, Commander_Path, Commander_Path
16 | If (Commander_Path = "") ; try to read registry
17 | Commander_Path:=TCRegistryCheck("InstallDir")
18 | If FileExist(Commander_Path)
19 | MatchList.settings.TCPath:=Commander_Path "\TotalCmd.exe" ; assume 32bit, user can change this in settings
20 | }
21 |
22 | ; we only use Commander_Ini / MatchList.settings.TCIniPath for ListerWindowClose
23 | If FileExist(MatchList.settings.TCIniPath)
24 | Commander_Ini:=MatchList.settings.TCIniPath
25 | else
26 | {
27 | EnvGet, Commander_Ini, Commander_Ini
28 | If (Commander_Ini = "") ; try to read registry
29 | Commander_Ini:=TCRegistryCheck("IniFileName")
30 | If (Commander_Ini = ".\wincmd.ini")
31 | Commander_Ini:=Commander_Path "\wincmd.ini"
32 | If FileExist(Commander_Ini)
33 | MatchList.settings.TCIniPath:=Commander_Ini
34 | }
35 |
36 | ; TODO consider other method, also for non TC uers who now always get this warning
37 | ; Inform user just in case
38 | If (Commander_Path = "")
39 | {
40 | FileRead, check_for_path, %F4ConfigFile%
41 | If RegExMatch(check_for_path,"iU)(.*exe|TCPath=.*exe)")
42 | MsgBox, 16, F4MiniMenu: Not found, F4MiniMenu:`nThe Commander_Path environment variable can not be found.`nStarting applications may not work in some cases.`nStart TC first (and check the Settings).
43 | check_for_path:=""
44 | }
45 |
46 | ListerWindowClose()
47 | {
48 | Global
49 | IniRead, ListerWindowClose, % MatchList.settings.TCIniPath, Lister, F4Edit
50 | }
51 |
52 | TCRegistryCheck(key)
53 | {
54 | ; source: https://ghisler.ch/board/viewtopic.php?t=258
55 | ; Search in this order, the 1st key that exist should be used:
56 | ; 1. HKCU\Software\Ghisler\Total Commander
57 | ; 2. HKLM\Software\Ghisler\Total Commander
58 | ; 3. HKCU\Software\Ghisler\Windows Commander
59 | ; 4. HKLM\Software\Ghisler\Windows Commander
60 | ; Under each key there should be three values:
61 | ; 1. "InstallDir" - Path where TC/WC is installed
62 | ; 2. "IniFileName" - Relative* path to the "WinCmd.ini"
63 | ; 3. "FtpIniName" - Relative* path to the "wcx_ftp.ini"
64 | ;
65 | ; IniFileName=%AppData%\Ghisler\wincmd.ini (Option "Application Data")
66 | ; IniFileName=%UserProfile%\wincmd.ini (Option "Documents and Settings")
67 | ; under older systems: Windows directory
68 |
69 | Loop, parse, % "HKCU,HKLM", CSV
70 | {
71 | main:=A_LoopField
72 | Loop, parse, % "Total Commander,Windows Commander", CSV
73 | {
74 | program:=A_LoopField
75 | RegRead key, %main%, Software\Ghisler\%program%, %key%
76 | if (key <> "")
77 | break 2
78 | }
79 | }
80 | Return key
81 | }
82 |
--------------------------------------------------------------------------------
/lib/AutoXYWH.ahk:
--------------------------------------------------------------------------------
1 | ; =================================================================================
2 | ; Function: AutoXYWH
3 | ; Move and resize control automatically when GUI resizes.
4 | ; Parameters:
5 | ; DimSize - Can be one or more of x/y/w/h optional followed by a fraction
6 | ; add a '*' to DimSize to 'MoveDraw' the controls rather then just 'Move', this is recommended for Groupboxes
7 | ; cList - variadic list of ControlIDs
8 | ; ControlID can be a control HWND, associated variable name, ClassNN or displayed text.
9 | ; The later (displayed text) is possible but not recommend since not very reliable
10 | ; Examples:
11 | ; AutoXYWH("xy", "Btn1", "Btn2")
12 | ; AutoXYWH("w0.5 h 0.75", hEdit, "displayed text", "vLabel", "Button1")
13 | ; AutoXYWH("*w0.5 h 0.75", hGroupbox1, "GrbChoices")
14 | ; ---------------------------------------------------------------------------------
15 | ; Version: 2015-5-29 / Added 'reset' option (by tmplinshi)
16 | ; 2014-7-03 / toralf
17 | ; 2014-1-2 / tmplinshi
18 | ; requires AHK version : 1.1.13.01+
19 | ; =================================================================================
20 | AutoXYWH(DimSize, cList*){ ; http://ahkscript.org/boards/viewtopic.php?t=1079
21 | static cInfo := {}
22 |
23 | If (DimSize = "reset")
24 | Return cInfo := {}
25 |
26 | For i, ctrl in cList {
27 | ctrlID := A_Gui ":" ctrl
28 | If ( cInfo[ctrlID].x = "" ){
29 | GuiControlGet, i, %A_Gui%:Pos, %ctrl%
30 | MMD := InStr(DimSize, "*") ? "MoveDraw" : "Move"
31 | fx := fy := fw := fh := 0
32 | For i, dim in (a := StrSplit(RegExReplace(DimSize, "i)[^xywh]")))
33 | If !RegExMatch(DimSize, "i)" dim "\s*\K[\d.-]+", f%dim%)
34 | f%dim% := 1
35 | cInfo[ctrlID] := { x:ix, fx:fx, y:iy, fy:fy, w:iw, fw:fw, h:ih, fh:fh, gw:A_GuiWidth, gh:A_GuiHeight, a:a , m:MMD}
36 | }Else If ( cInfo[ctrlID].a.1) {
37 | dgx := dgw := A_GuiWidth - cInfo[ctrlID].gw , dgy := dgh := A_GuiHeight - cInfo[ctrlID].gh
38 | For i, dim in cInfo[ctrlID]["a"]
39 | Options .= dim (dg%dim% * cInfo[ctrlID]["f" dim] + cInfo[ctrlID][dim]) A_Space
40 | GuiControl, % A_Gui ":" cInfo[ctrlID].m , % ctrl, % Options
41 | } } }
42 |
--------------------------------------------------------------------------------
/lib/DoubleCommander.ahk:
--------------------------------------------------------------------------------
1 | /*
2 | DoubleCommander functions
3 | */
4 |
5 | DoubleCommander_Active()
6 | {
7 | IfWinActive ahk_exe doublecmd.exe
8 | Return 1
9 | }
10 |
11 | DoubleCommander_GetSelection()
12 | {
13 | global matchlist
14 | ClipboardSave:=ClipboardAll
15 | Clipboard:=""
16 | Send % MatchList.settings.DoubleCommander
17 | Result:=Clipboard
18 | Sleep 100
19 | Clipboard:=ClipboardSave
20 | Return Result
21 | }
22 |
--------------------------------------------------------------------------------
/lib/DropFiles.ahk:
--------------------------------------------------------------------------------
1 |
2 | /*
3 |
4 | DropFiles:
5 | combined from two functions - ideally they should be merged into one "smarter"
6 | function but this will do for now.
7 |
8 | - SKAN - http://www.autohotkey.com/board/topic/41467-make-ahk-drop-files-into-other-applications/#entry258810
9 | - nimda - http://www.autohotkey.com/board/topic/79145-help-converting-ahk-ahk-l/#entry502676
10 |
11 | Example:
12 |
13 | DropFiles( "C:\SomeName.txt", "ahk_class Notepad" )
14 |
15 | */
16 |
17 | DropFiles( FileList, wTitle="", Ctrl="", X=0, Y=0, NCA=0 ) {
18 | If (A_IsUnicode = 1)
19 | { ; from nimda - http://www.autohotkey.com/board/topic/79145-help-converting-ahk-ahk-l/#entry502676
20 | fns:=RegExReplace(FileList,"\n$")
21 | fns:=RegExReplace(fns,"^\n")
22 | hDrop:=DllCall("GlobalAlloc","UInt",0x42,"UPtr",20+StrLen(fns)+2)
23 | p:=DllCall("GlobalLock","UPtr",hDrop)
24 | NumPut(20, p+0) ;offset
25 | NumPut(x, p+4) ;pt.x
26 | NumPut(y, p+8) ;pt.y
27 | NumPut(0, p+12) ;fNC
28 | NumPut(0, p+16) ;fWide
29 | p2:=p+20
30 | Loop,Parse,fns,`n,`r
31 | {
32 | DllCall("RtlMoveMemory","UPtr",p2,"AStr",A_LoopField,"UPtr",StrLen(A_LoopField))
33 | p2+=StrLen(A_LoopField)+1
34 | }
35 | DllCall("GlobalUnlock","UPtr",hDrop)
36 | PostMessage, 0x233, hDrop, 0, %Ctrl%, %wTitle%
37 | }
38 | Else If (A_IsUnicode <> 1)
39 | { ; from DropFilesA - SKAN - http://www.autohotkey.com/board/topic/41467-make-ahk-drop-files-into-other-applications/#entry258810
40 | StringReplace, FileList, FileList, `r`n, `n , All
41 | VarSetCapacity( DROPFILES, 20, 32 ), DROPFILES .= FileList "`n`n", nSize:=StrLen(DROPFILES)
42 | StringReplace, DROPFILES, DROPFILES, `n, `n, UseErrorLevel
43 | Loop %ErrorLevel%
44 | NumPut( 0, DROPFILES, InStr(DROPFILES,"`n",0,0)-1, "Char" )
45 | pDP:=&DROPFILES, NumPut(20,pDP+0), NumPut(X,pDP+4), NumPut(Y,pDP+8), NumPut(NCA,pDP+12)
46 | NumPut(0,pDP+16), hDrop := DllCall( "GlobalAlloc", UInt, 0x42, UInt, nSize )
47 | pData := DllCall( "GlobalLock", UInt, hDrop )
48 | DllCall( "RtlMoveMemory", UInt, pData, UInt, pDP, UInt, nSize )
49 | DllCall( "GlobalUnlock", UInt, hDrop )
50 | PostMessage, 0x233, hDrop, 0, %Ctrl%, %wTitle%
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib/Everything.ahk:
--------------------------------------------------------------------------------
1 | /*
2 | Everything functions
3 | - Note: deactivated Everything_DirectoryTree() for now
4 | - 20250209 If there are no selected rows, get entire list and grab first one
5 | - 20250208 Added Everything64.exe; for 1.5 alpha the F4MM shortcut F4 overrides "F4 = Focus Next Selected"
6 | */
7 |
8 | Everything_Active()
9 | {
10 | WinGet, EverythingExe, ProcessName, A
11 | if EverythingExe in Everything.exe,Everything64.exe
12 | Return 1
13 | }
14 |
15 | Everything_GetSelection(dir="0")
16 | {
17 | WinGet, EverythingExe, ProcessName, Everything
18 | ControlGet, OutputVar, List, Selected, SysListView321, ahk_exe %EverythingExe%
19 | If (OutputVar = "") ; there was no selection so just grab the first result only
20 | {
21 | ControlGet, OutputVar, List, , SysListView321, ahk_exe %EverythingExe%
22 | OutputVar:=StrSplit(OutputVar,"`n").1
23 | }
24 | Loop, parse, OutputVar, `n, `r
25 | {
26 | filepath:=StrSplit(A_LoopField,A_Tab)
27 | result .= filepath[2] "\" filepath[1] "`n"
28 | }
29 | ; If dir
30 | ; Return % Trim(StrSplit(result,"`n").1,"`n") "\"
31 | ; else
32 | Return % Trim(result,"`n")
33 | }
34 |
35 | /*
36 | Everything_DirectoryTree()
37 | {
38 | global MatchList
39 | count:=0
40 | AutoTrim, Off
41 | SendMessage, 1074, 17, , , ahk_class TTOTAL_CMD
42 | WinGetText, PathInTC, ahk_id %ErrorLevel%
43 | drive:=SubStr(PathInTC,1,1) ":"
44 | dir:=Trim(PathInTC,"<>`r`n")
45 | StartSearch:=MatchList.settings.EvPath
46 | if InStr(StartSearch,"/dir")
47 | StartSearch:=StrReplace(StartSearch,"/drive")
48 | StartSearch:=StrReplace(StartSearch,"/drive",drive)
49 | StartSearch:=StrReplace(StartSearch,"/dir",dir)
50 | Run, % StartSearch
51 | WinWaitActive, ahk_exe Everything.exe ; note 20250209 everything64.exe v1.5 alpha
52 | ControlSend, Edit1, {space}, ahk_exe Everything.exe
53 | }
54 |
55 | Everything_DirectoryTree:
56 | Everything_DirectoryTree()
57 | Return
58 | */
59 |
--------------------------------------------------------------------------------
/lib/Explorer.ahk:
--------------------------------------------------------------------------------
1 | /*
2 | Explorer functions
3 | */
4 |
5 | Explorer_Active()
6 | {
7 | WinGetClass, winClass, % "ahk_id" . hWnd := WinExist("A")
8 | if winClass in CabinetWClass,ExploreWClass
9 | Return 1
10 | }
11 |
12 | Explorer_GetSelection() ; https://www.autohotkey.com/boards/viewtopic.php?t=60403#p255169
13 | {
14 | WinGetClass, winClass, % "ahk_id" . hWnd := WinExist("A")
15 | if winClass not in CabinetWClass,ExploreWClass
16 | Return
17 | for window in ComObjCreate("Shell.Application").Windows
18 | if (hWnd = window.HWND) && (oShellFolderView := window.document)
19 | break
20 | for item in oShellFolderView.SelectedItems
21 | result .= (result = "" ? "" : "`n") . item.path
22 | if !result
23 | result := oShellFolderView.Folder.Self.Path
24 | Return result
25 | }
26 |
27 | /*
28 | ; better? https://www.autohotkey.com/boards/viewtopic.php?p=462887#p462887
29 | Explorer_GetSelection() {
30 | WinGetClass, winClass, % "ahk_id" . hWnd := WinExist("A")
31 | if !(winClass ~= "^(Progman|WorkerW|(Cabinet|Explore)WClass)$")
32 | Return
33 |
34 | shellWindows := ComObjCreate("Shell.Application").Windows
35 | if (winClass ~= "Progman|WorkerW") ; IShellWindows::Item: https://goo.gl/ihW9Gm
36 | ; IShellFolderViewDual: https://goo.gl/gnntq3
37 | shellFolderView := shellWindows.Item( ComObject(VT_UI4 := 0x13, SWC_DESKTOP := 0x8) ).Document
38 | else {
39 | for window in shellWindows ; ShellFolderView object: https://is.gd/eyZ4zG
40 | if (hWnd = window.HWND) && (shellFolderView := window.Document)
41 | break
42 | }
43 | for item in shellFolderView.SelectedItems
44 | result .= (result = "" ? "" : "`n") . item.Path
45 | ;~ if !result
46 | ;~ result := shellFolderView.Folder.Self.Path
47 | Return result
48 | }
--------------------------------------------------------------------------------
/lib/GetPos.ahk:
--------------------------------------------------------------------------------
1 |
2 | /*
3 |
4 | GetPos() for Menu X,Y co-ordinates from Listbox position with alternatives
5 | by hi5 - developed for F4MiniMenu - https://github.com/hi5/
6 |
7 | Assumption:
8 |
9 | CoordMode, Menu|ToolTip, Client
10 |
11 | Returned position:
12 |
13 | 1: At Mouse cursor
14 | 2: Centered in window
15 | 3: Right next of current file
16 | 4: Docked next of current file (Opposite panel)
17 |
18 | */
19 |
20 | GetPos(Position="1", MenuSize="5", Offset=40)
21 | {
22 | Pos:=[]
23 | If (Position = 1) ; fastest method so deal with it first
24 | {
25 | MouseGetPos, X, Y
26 | Pos.Insert("x", X), Pos.Insert("y", Y-Offset)
27 | Return Pos
28 | }
29 |
30 | If Explorer_Active() or DoubleCommander_Active() or XYPlorer_Active() ; can't be bothered to figure it out for the time being so always center in explorer window
31 | Position = 2
32 |
33 | ; Get Active Window statistics
34 | WinGetPos, WinX, WinY, WinWidth, WinHeight, A
35 |
36 | If (Position = 2) ; second fastest method so deal with it first
37 | {
38 | X:=WinWidth/2-100, Y:=WinHeight/2-WinY ; Y:=WinHeight/2-(MenuSize*15)-50 ; Crude calculation
39 | Pos.Insert("x", X), Pos.Insert("y", Y)
40 | Return Pos
41 | }
42 |
43 | ; Get focused control info + Listbox properties to calculate Y position of popup menu
44 | ControlGetFocus, FocusCtrl, A
45 | ControlGetPos, CtrlX, CtrlY, CtrlWidth, CtrlHeight, %FocusCtrl%, A
46 | SendMessage, 0x1A1, 0, 0, %FocusCtrl%, A ; 0x1A1 is LB_GETITEMHEIGHT
47 | LB_GETITEMHEIGHT:=ErrorLevel ;
48 | SendMessage, 0x188, 0, 0, %FocusCtrl%, A ; 0x188 is LB_GETCURSEL
49 | LB_GETCURSEL:=ErrorLevel + 1 ; Convert from zero-based to one-based.
50 | SendMessage, 0x18E, 0, 0, %FocusCtrl%, A ; 0x18E is LB_GETTOPINDEX Gets the index of the first visible item in a list box. Initially the item with index 0 is at the top of the list box, but if the list box contents have been scrolled another item may be at the top. The first visible item in a multiple-column list box is the top-left item.
51 | LB_GETTOPINDEX:=ErrorLevel ;
52 | SendMessage, 0x18B, 0, 0, %FocusCtrl%, A ; 0x18B is LB_GETCOUNT Gets the number of items in a list box.
53 | LB_GETCOUNT:=ErrorLevel
54 |
55 | ; Start calculations
56 | YMulti:=LB_GETCURSEL-LB_GETTOPINDEX
57 | VisibleCount:=LB_GETCOUNT - LB_GETTOPINDEX ; Maximum number of visible rows
58 |
59 | If (LB_GETCURSEL > VisibleCount)
60 | YMulti:=VisibleCount
61 | If (LB_GETCURSEL < LB_GETTOPINDEX) or (YMulti < 1)
62 | YMulti:=1
63 |
64 | Y:=CtrlY + (YMulti * LB_GETITEMHEIGHT)
65 | If (Y > (CtrlHeight+CtrlY))
66 | Y:=CtrlHeight+CtrlY
67 | Y-=Offset ; We assume client mode for the menu so need some offset here
68 |
69 | If (Position = 3)
70 | {
71 | X:=CtrlX + 100
72 | Pos.Insert("x", X), Pos.Insert("y", Y)
73 | Return Pos
74 | }
75 | Else If (Position = 4)
76 | {
77 | X:= CtrlX + CtrlWidth - 5
78 | Pos.Insert("x", X), Pos.Insert("y", Y)
79 | Return Pos
80 | }
81 | }
82 |
83 |
--------------------------------------------------------------------------------
/lib/QDir.ahk:
--------------------------------------------------------------------------------
1 | /*
2 | Q-Dir functions
3 | */
4 |
5 | QDir_Active()
6 | {
7 | IfWinActive ahk_exe Q-Dir.exe
8 | Return 1
9 | IfWinActive ahk_exe Q-Dir_x64.exe
10 | Return 1
11 | }
12 |
13 | QDir_GetSelection()
14 | {
15 | global matchlist
16 | ClipboardSave:=ClipboardAll
17 | Clipboard:=""
18 | Send % MatchList.settings.QDir
19 | Result:=Clipboard
20 | Sleep 100
21 | Clipboard:=ClipboardSave
22 | Return Result
23 | }
24 |
--------------------------------------------------------------------------------
/lib/XA.ahk:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Save/Load Arrays - trueski - http://www.autohotkey.com/board/topic/85461-ahk-l-saveload-arrays/
4 |
5 | Examples:
6 |
7 | XA_Save("Array", Path) ; put variable name in quotes
8 | XA_Load(Path) ; the name of the variable containing the array is returned
9 |
10 | Note: indented code to personal pref.
11 |
12 | */
13 |
14 | XA_Save(Array, Path) {
15 | FileDelete, % Path
16 | FileAppend, % "`n<" . Array . ">`n" . XA_ArrayToXML(Array) . "`n" . Array . ">", % Path, UTF-8
17 | If (ErrorLevel)
18 | Return 1
19 | Return 0
20 | }
21 |
22 | XA_Load(Path) {
23 | Local XMLText, XMLObj, XMLRoot, Root1, Root2
24 |
25 | If (!FileExist(Path))
26 | Return 1
27 |
28 | FileRead, XMLText, % Path
29 | StringReplace, XMLText, XMLText, %A_Space%&%A_Space%, %A_Space%&%A_Space%, All ; dirty hack
30 |
31 | XMLObj := XA_LoadXML(XMLText)
32 | XMLObj := XMLObj.selectSingleNode("/*") ; */
33 | XMLRoot := XMLObj.nodeName
34 | %XMLRoot% := XA_XMLToArray(XMLObj.childNodes)
35 |
36 | Return XMLRoot
37 | }
38 |
39 | XA_XMLToArray(nodes, NodeName="") {
40 | Obj := Object()
41 |
42 | for node in nodes
43 | {
44 | if (node.nodeName != "#text") ;NAME
45 | {
46 | If (node.nodeName == "Invalid_Name" && node.getAttribute("ahk") == "True")
47 | NodeName := node.getAttribute("id")
48 | Else
49 | NodeName := node.nodeName
50 | }
51 |
52 | else ;VALUE
53 | Obj := node.nodeValue
54 |
55 | if node.hasChildNodes
56 | {
57 | ; Same node name was used for multiple nodes
58 | If ((node.nextSibling.nodeName = node.nodeName || node.nodeName = node.previousSibling.nodeName) && node.nodeName != "Invalid_Name" && node.getAttribute("ahk") != "True")
59 | {
60 | ; Create object
61 | If (!node.previousSibling.nodeName)
62 | {
63 | Obj[NodeName] := Object()
64 | ItemCount := 0
65 | }
66 | ItemCount++
67 |
68 | ; Use the supplied ID if available
69 | If (node.getAttribute("id") != "")
70 | Obj[NodeName][node.getAttribute("id")] := XA_XMLToArray(node.childNodes, node.getAttribute("id"))
71 |
72 | ; Use ItemCount if no ID was provided
73 | Else
74 | Obj[NodeName][ItemCount] := XA_XMLToArray(node.childNodes, ItemCount)
75 | }
76 |
77 | Else
78 | Obj.Insert(NodeName, XA_XMLToArray(node.childNodes, NodeName))
79 | }
80 | }
81 | Return Obj
82 | }
83 |
84 | XA_LoadXML(ByRef data){
85 | o := ComObjCreate("MSXML2.DOMdocument.6.0")
86 | o.async := false
87 | o.LoadXML(data)
88 | return o
89 | }
90 |
91 | XA_ArrayToXML(theArray, tabCount=1, NodeName="") {
92 | Local tabSpace, extraTabSpace, tag, val, theXML, root
93 | tabCount++
94 | tabSpace := ""
95 | extraTabSpace := ""
96 | theXML := ""
97 |
98 | if (!IsObject(theArray))
99 | {
100 | root := theArray
101 | theArray := %theArray%
102 | ; StringReplace, theArray, theArray, %A_Space%&%A_Space%, %A_Space%&%A_Space%, All ; dirty hack
103 | }
104 |
105 | While (A_Index < tabCount)
106 | {
107 | tabSpace .= "`t"
108 | extraTabSpace := tabSpace . "`t"
109 | }
110 |
111 | for tag, val in theArray
112 | {
113 | If (!IsObject(val))
114 | {
115 | If (XA_InvalidTag(tag))
116 | theXML .= "`n" . tabSpace . "" . XA_XMLEncode(val) . ""
117 | Else
118 | theXML .= "`n" . tabSpace . "<" . tag . ">" . XA_XMLEncode(val) . "" . tag . ">"
119 | }
120 |
121 | Else
122 | {
123 | If (XA_InvalidTag(tag))
124 | theXML .= "`n" . tabSpace . "" . "`n" . XA_ArrayToXML(val, tabCount, "") . "`n" . tabSpace . ""
125 | Else
126 | theXML .= "`n" . tabSpace . "<" . tag . ">" . "`n" . XA_ArrayToXML(val, tabCount, "") . "`n" . tabSpace . "" . tag . ">"
127 | }
128 | }
129 |
130 | theXML := SubStr(theXML, 2)
131 | Return theXML
132 | }
133 |
134 | XA_InvalidTag(Tag) {
135 | Char1 := SubStr(Tag, 1, 1)
136 | Chars3 := SubStr(Tag, 1, 3)
137 | StartChars := "~``!@#$%^&*()_-+={[}]|\:;""'<,>.?/1234567890 `n`r"
138 | Chars := """'<>=/ `n`r"
139 |
140 | Loop, Parse, StartChars
141 | {
142 | If (Char1 = A_LoopField)
143 | Return 1
144 | }
145 |
146 | Loop, Parse, Chars
147 | {
148 | If (InStr(Tag, A_LoopField))
149 | Return 1
150 | }
151 |
152 | If (Chars3 = "xml")
153 | Return 1
154 |
155 | Return 0
156 | }
157 |
158 | ; XA_XMLEncode references:
159 | ; https://en.wikipedia.org/wiki/XML#Escaping
160 | ; https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML
161 | ; added again as original source code posted at forum was lost due to forum upgrade
162 |
163 | XA_XMLEncode(Text) {
164 | StringReplace, Text, Text, &, &, All
165 | StringReplace, Text, Text, <, <, All
166 | StringReplace, Text, Text, >, >, All
167 | StringReplace, Text, Text, ", ", All
168 | StringReplace, Text, Text, ', ', All
169 | Return XA_CleanInvalidChars(Text) ; additional fix see below for reference
170 | }
171 |
172 | XA_CleanInvalidChars(text, replace="") {
173 | re := "[^\x09\x0A\x0D\x20-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]"
174 | Return RegExReplace(text, re, replace)
175 |
176 | /*
177 | Source: http://stackoverflow.com/questions/730133/invalid-characters-in-xml
178 | public static string CleanInvalidXmlChars(string text)
179 | {
180 | // From xml spec valid chars:
181 | // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
182 | // any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
183 | string re = @"[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-u10FFFF]";
184 | return Regex.Replace(text, re, "");
185 | }
186 | */
187 |
188 | }
189 |
--------------------------------------------------------------------------------
/lib/XYPlorer.ahk:
--------------------------------------------------------------------------------
1 | /*
2 | XYPlorer functions
3 | */
4 |
5 | XYPlorer_Active()
6 | {
7 | IfWinActive ahk_exe XYPLorer.exe
8 | Return 1
9 | IfWinActive ahk_exe XYPLorerFree.exe
10 | Return 1
11 | }
12 |
13 | XYPlorer_GetSelection()
14 | {
15 | global matchlist
16 | ClipboardSave:=ClipboardAll
17 | Clipboard:=""
18 | Send % MatchList.settings.XYPlorer
19 | Result:=Clipboard
20 | Sleep 100
21 | Clipboard:=ClipboardSave
22 | Return Result
23 | }
24 |
--------------------------------------------------------------------------------
/lib/class_lv_rows.ahk:
--------------------------------------------------------------------------------
1 | ; Source: https://gist.github.com/Pulover/5759637
2 | ; Forum : http://www.autohotkey.com/board/topic/94364-class-lv-rows-copy-cut-paste-and-drag-listviews/
3 |
4 | ;=======================================================================================
5 | ;
6 | ; Class LV_Rows
7 | ;
8 | ; Author: Pulover [Rodolfo U. Batista]
9 | ; rodolfoub@gmail.com
10 | ;
11 | ; Additional functions for ListView controls
12 | ;=======================================================================================
13 | ;
14 | ; This class provides an easy way to add functionalities to ListViews that are not
15 | ; supported by AutoHotkey built-in functions such as Copy, Cut, Paste, Drag and more.
16 | ;
17 | ;=======================================================================================
18 | ;
19 | ; Edit Functions:
20 | ; Copy()
21 | ; Cut()
22 | ; Paste(Row=0)
23 | ; Delete()
24 | ; Move(Up=False)
25 | ; Drag(DragButton="D", AutoScroll=True, ScrollDelay=100, LineThick=2, Color="Black")
26 | ;
27 | ; History Functions:
28 | ; Add()
29 | ; Undo()
30 | ; Redo()
31 | ;
32 | ;=======================================================================================
33 | ;
34 | ; Usage:
35 | ;
36 | ; You can call the function by preceding them with LV_Rows. For example:
37 | ; LV_Rows.Copy() <-- Calls function on active ListView.
38 | ;
39 | ; Or with a handle initialized via New meta-function. For example:
40 | ; MyListHandle := New LV_Rows() <-- Creates a new handle.
41 | ; MyListHandle.Add() <-- Calls function for that Handle.
42 | ;
43 | ; Like AutoHotkey built-in functions, these functions operate on the default gui,
44 | ; and active ListView control.
45 | ;
46 | ; Initializing is required for History functions or in case your ListView has icons.
47 | ; You can also use the same handle for the Edit functions or use different
48 | ; handles for extra copy and paste actions keeping independent data in memory.
49 | ;
50 | ; In order to keep row's icons you need to initialize the class passing the
51 | ; ListView's Hwnd. For example:
52 | ; Gui, Add, ListView, hwndhLV, Columns
53 | ; MyListHandle := New LV_Rows(hLV)
54 | ;
55 | ; You may keep an individual history of each ListView using different handles.
56 | ;
57 | ;=======================================================================================
58 |
59 | Class LV_Rows
60 | {
61 | ;=======================================================================================
62 | ; Meta-Functions By creating a new instance of the class via
63 | ; Handle := New LV_Rows() you can keep different History and
64 | ; Copy / Paste data for individual ListViews.
65 | ; Pass the Hwnd of the Listiview to keep row's icons.
66 | ;
67 | ; Properties:
68 | ; ActiveSlot: Contains the current entry position in the ListView History.
69 | ; HasChanged: The HasChanged property may optionally be used to check if the
70 | ; ListView has been changed. For this you must use a handle
71 | ; for all functions.
72 | ; Every time a function (except Copy) is called it will be set
73 | ; to True. The user may consult Handle.HasChanged to show
74 | ; a save dialog and set it to False after saving.
75 | ;=======================================================================================
76 | __New(Hwnd="")
77 | {
78 | If (Hwnd)
79 | this.LVHwnd := Hwnd
80 | this.Slot := [], this.ActiveSlot := 1
81 | }
82 |
83 | __Call(Func)
84 | {
85 | If (Func <> "Copy")
86 | this.HasChanged := True
87 | }
88 |
89 | __Delete()
90 | {
91 | this.Remove("", Chr(255))
92 | , this.SetCapacity(0)
93 | , this.base := ""
94 | }
95 | ;=======================================================================================
96 | ; Edit Functions: Edit ListView rows.
97 | ;=======================================================================================
98 | ; Function: LV_Rows.Copy()
99 | ; Description: Copy selected rows to memory.
100 | ; Return: Number of copied rows.
101 | ;=======================================================================================
102 | Copy()
103 | {
104 | this.CopyData := {}, LV_Row := 0
105 | Loop
106 | {
107 | LV_Row := LV_GetNext(LV_Row)
108 | If !LV_Row
109 | break
110 | RowData := this.RowText(LV_Row)
111 | , Row := [RowData*]
112 | , this.CopyData.Insert(Row)
113 | , CopiedLines := A_Index
114 | }
115 | return CopiedLines
116 | }
117 | ;=======================================================================================
118 | ; Function: LV_Rows.Cut()
119 | ; Description: Copy selected rows to memory and delete them.
120 | ; Return: Number of copied rows.
121 | ;=======================================================================================
122 | Cut()
123 | {
124 | this.CopyData := {}, LV_Row := 0
125 | Loop
126 | {
127 | LV_Row := LV_GetNext(LV_Row)
128 | If !LV_Row
129 | break
130 | RowData := this.RowText(LV_Row)
131 | , Row := [RowData*]
132 | , this.CopyData.Insert(Row)
133 | , CopiedLines := A_Index
134 | }
135 | this.Delete()
136 | return CopiedLines
137 | }
138 | ;=======================================================================================
139 | ; Function: LV_Rows.Paste()
140 | ; Description: Paste copied rows at selected position.
141 | ; Parameters:
142 | ; Row: If non-zero pastes memory contents into the specified row.
143 | ; Return: True if memory contains data or False if not.
144 | ;=======================================================================================
145 | Paste(Row=0)
146 | {
147 | If !this.CopyData.MaxIndex()
148 | return False
149 | TargetRow := Row ? Row : LV_GetNext()
150 | If !TargetRow
151 | {
152 | For each, Row in this.CopyData
153 | LV_Add(Row*)
154 | }
155 | Else
156 | {
157 | LV_Row := TargetRow - 1
158 | For each, Row in this.CopyData
159 | LV_Insert(LV_Row+A_Index, Row*)
160 | }
161 | return True
162 | }
163 | ;=======================================================================================
164 | ; Function: LV_Rows.Delete()
165 | ; Description: Delete selected rows.
166 | ; Return: Number of removed rows.
167 | ;=======================================================================================
168 | Delete()
169 | {
170 | If (LV_GetCount("Selected") = 0)
171 | return False
172 | LV_Row := 0
173 | Loop
174 | {
175 | LV_Row := LV_GetNext(LV_Row - 1)
176 | If !LV_Row
177 | break
178 | LV_Delete(LV_Row)
179 | , DeletedLines := A_Index
180 | }
181 | return DeletedLines
182 | }
183 | ;=======================================================================================
184 | ; Function: LV_Rows.Move()
185 | ; Description: Move selected rows down or up.
186 | ; Parameters:
187 | ; Up: If False or omitted moves rows down. If True moves rows up.
188 | ; Return: Number of rows moved.
189 | ;=======================================================================================
190 | Move(Up=False)
191 | {
192 | Selections := [], LV_Row := 0
193 | Critical
194 | If Up
195 | {
196 | Loop
197 | {
198 | LV_Row := LV_GetNext(LV_Row)
199 | If !LV_Row
200 | break
201 | If (LV_Row = 1)
202 | return
203 | Selections.Insert(LV_Row)
204 | }
205 | For each, Row in Selections
206 | {
207 | RowData := this.RowText(Row)
208 | , LV_Insert(Row-1, RowData*)
209 | , LV_Delete(Row+1)
210 | , LV_Modify(Row-1, "Select")
211 | If (A_Index = 1)
212 | LV_Modify(Row-1, "Focus Vis")
213 | }
214 | return Selections.MaxIndex()
215 | }
216 | Else
217 | {
218 | Loop
219 | {
220 | LV_Row := LV_GetNext(LV_Row)
221 | If !LV_Row
222 | break
223 | If (LV_Row = LV_GetCount())
224 | return
225 | Selections.Insert(1, LV_Row)
226 | }
227 | For each, Row in Selections
228 | {
229 | RowData := this.RowText(Row+1)
230 | , LV_Insert(Row, RowData*)
231 | , LV_Delete(Row+2)
232 | If (A_Index = 1)
233 | LV_Modify(Row+1, "Focus Vis")
234 | }
235 | return Selections.MaxIndex()
236 | }
237 | }
238 | ;=======================================================================================
239 | ; Function: LV_Rows.Drag()
240 | ; Description: Drag-and-Drop selected rows showing a destination bar.
241 | ; Must be called in the ListView G-Label subroutine when
242 | ; A_GuiEvent returns "D" or "d".
243 | ; Parameters:
244 | ; DragButton: If it is a lower case "d" it will be recognized as a
245 | ; Right-Click drag, otherwise will be recognized as a
246 | ; Left-Click drag. You may pass A_GuiEvent as the parameter.
247 | ; AutoScroll: If True or omitted the ListView will automatically scroll
248 | ; up or down when the cursor is above or below the control.
249 | ; ScrollDelay: Delay in miliseconds for AutoScroll. Default is 100ms.
250 | ; LineThick: Thickness of the destination bar in pixels. Default is 2px.
251 | ; Color: Color of destination bar. Defalt is "Black".
252 | ; Return: The destination row number.
253 | ;=======================================================================================
254 | Drag(DragButton="D", AutoScroll=True, ScrollDelay=100, LineThick=2, Color="Black")
255 | {
256 | Static LVIR_LABEL := 0x0002
257 | Static LVM_GETITEMCOUNT := 0x1004
258 | Static LVM_SCROLL := 0x1014
259 | Static LVM_GETTOPINDEX := 0x1027
260 | Static LVM_GETCOUNTPERPAGE := 0x1028
261 | Static LVM_GETSUBITEMRECT := 0x1038
262 | Static LV_currColHeight := 0
263 |
264 | SysGet, SM_CXVSCROLL, 2
265 |
266 | If InStr(DragButton, "d", True)
267 | DragButton := "RButton"
268 | Else
269 | DragButton := "LButton"
270 |
271 | CoordMode, Mouse, Window
272 | MouseGetPos,,, LV_Win, LV_LView, 2
273 | WinGetPos, Win_X, Win_Y, Win_W, Win_H, ahk_id %LV_Win%
274 | ControlGetPos, LV_lx, LV_ly, LV_lw, LV_lh, , ahk_id %LV_LView%
275 | VarSetCapacity(LV_XYstruct, 4 * A_PtrSize, 0)
276 |
277 | While, GetKeyState(DragButton, "P")
278 | {
279 | MouseGetPos, LV_mx, LV_my,, CurrCtrl, 2
280 | LV_mx -= LV_lx, LV_my -= LV_ly
281 |
282 | If (AutoScroll)
283 | {
284 | If (LV_my < 0)
285 | {
286 | SendMessage, LVM_SCROLL, 0, -LV_currColHeight, , ahk_id %LV_LView%
287 | Sleep, %ScrollDelay%
288 | }
289 | If (LV_my > LV_lh)
290 | {
291 | SendMessage, LVM_SCROLL, 0, LV_currColHeight, , ahk_id %LV_LView%
292 | Sleep, %ScrollDelay%
293 | }
294 | }
295 |
296 | If (CurrCtrl <> LV_LView)
297 | {
298 | LV_currRow := ""
299 | Gui, MarkLine:Cancel
300 | continue
301 | }
302 |
303 | SendMessage, LVM_GETITEMCOUNT, 0, 0, , ahk_id %LV_LView%
304 | LV_TotalNumOfRows := ErrorLevel
305 | SendMessage, LVM_GETCOUNTPERPAGE, 0, 0, , ahk_id %LV_LView%
306 | LV_NumOfRows := ErrorLevel
307 | SendMessage, LVM_GETTOPINDEX, 0, 0, , ahk_id %LV_LView%
308 | LV_topIndex := ErrorLevel
309 | , Line_W := (LV_TotalNumOfRows > LV_NumOfRows) ? LV_lw - SM_CXVSCROLL : LV_lw
310 |
311 | Loop, % LV_NumOfRows + 1
312 | {
313 | LV_which := LV_topIndex + A_Index - 1
314 | NumPut(LVIR_LABEL, LV_XYstruct, 0, "UInt")
315 | , NumPut(A_Index - 1, LV_XYstruct, 4, "UInt")
316 | SendMessage, LVM_GETSUBITEMRECT, %LV_which%, &LV_XYstruct, , ahk_id %LV_LView%
317 | LV_RowY := NumGet(LV_XYstruct, 4, "UInt")
318 | , LV_RowY2 := NumGet(LV_XYstruct, 12, "UInt")
319 | , LV_currColHeight := LV_RowY2 - LV_RowY
320 | If(LV_my <= LV_RowY + LV_currColHeight)
321 | {
322 | LV_currRow := LV_which + 1
323 | , LV_currRow0 := LV_which
324 | , Line_Y := Win_Y + LV_ly + LV_RowY
325 | , Line_X := Win_X + LV_lx
326 | If (LV_currRow > (LV_TotalNumOfRows+1))
327 | {
328 | Gui, MarkLine:Cancel
329 | LV_currRow := ""
330 | }
331 | Break
332 | }
333 | }
334 |
335 | If LV_currRow
336 | {
337 | Gui, MarkLine:Color, %Color%
338 | Gui, MarkLine:+LastFound +AlwaysOnTop +Toolwindow -Caption +HwndLineMark
339 | Gui, MarkLine:Show, W%Line_W% H%LineThick% Y%Line_Y% X%Line_X% NoActivate
340 | }
341 | }
342 | Gui, MarkLine:Cancel
343 |
344 | If LV_currRow
345 | {
346 | DragRows := new LV_Rows(this.LVHwnd)
347 | , Lines := DragRows.Copy()
348 | DragRows.Paste(LV_currRow)
349 | If (LV_GetNext() < LV_currRow)
350 | o := Lines+1, FocusedRow := LV_currRow-1
351 | Else
352 | o := 1, FocusedRow := LV_currRow
353 | DragRows.Delete()
354 | , DragRows := ""
355 | Loop, %Lines%
356 | {
357 | i := A_Index-o
358 | LV_Modify(LV_currRow+i, "Select")
359 | }
360 | LV_Modify(FocusedRow, "Focus")
361 | }
362 | return LV_currRow
363 | }
364 | ;=======================================================================================
365 | ; History Functions: Keep a history of ListView changes and allow Undo and Redo.
366 | ;=======================================================================================
367 | ; Function: Handle.Add()
368 | ; Description: Adds an entry on History. This function requires
369 | ; initializing: MyListHandle := New LV_Rows()
370 | ; Return: The total number of entries in history.
371 | ;=======================================================================================
372 | Add()
373 | {
374 | Row := []
375 | If (this.ActiveSlot < this.Slot.MaxIndex())
376 | this.Slot.Remove(this.ActiveSlot+1, this.Slot.MaxIndex())
377 | Loop, % LV_GetCount()
378 | {
379 | RowData := this.RowText(A_Index)
380 | , Row[A_Index] := [RowData*]
381 | }
382 | this.Slot.Insert(Row)
383 | , this.ActiveSlot := this.Slot.MaxIndex()
384 | return this.Slot.MaxIndex()
385 | }
386 | ;=======================================================================================
387 | ; Function: Handle.Undo()
388 | ; Description: Replaces ListView contents with previous entry state, if any.
389 | ; Return: Current entry position.
390 | ;=======================================================================================
391 | Undo()
392 | {
393 |
394 | If (this.ActiveSlot = 1)
395 | return this.ActiveSlot
396 | this.ActiveSlot -= 1
397 | , this.Load(this.ActiveSlot)
398 | return this.ActiveSlot
399 | }
400 | ;=======================================================================================
401 | ; Function: Handle.Redo()
402 | ; Description: Replaces ListView contents with next entry state, if any.
403 | ; Return: Current entry position.
404 | ;=======================================================================================
405 | Redo()
406 | {
407 | If (this.ActiveSlot = (this.Slot.MaxIndex()))
408 | return this.ActiveSlot
409 | this.ActiveSlot += 1
410 | , this.Load(this.ActiveSlot)
411 | return this.ActiveSlot
412 | }
413 | ;=======================================================================================
414 | ; Internal Functions: These functions are meant for internal use but can also
415 | ; be called if necessary.
416 | ;=======================================================================================
417 | ; Function: Handle.Load()
418 | ; Description: Loads a specified entry in History into ListView.
419 | ; Parameters:
420 | ; Number: Number of entry position to be loaded.
421 | ; Return: True if entry exists, False otherwise.
422 | ;=======================================================================================
423 | Load(Number)
424 | {
425 | If !IsObject(this.Slot[Number])
426 | return False
427 |
428 | LV_Delete()
429 | For each, Row in this.Slot[Number]
430 | LV_Add(Row*)
431 | return True
432 | }
433 | ;=======================================================================================
434 | ; Function: LV_Rows.RowText()
435 | ; Description: Creates an Array of values from each cell in a specified row.
436 | ; Parameters:
437 | ; Index: Index of the row to get contents from.
438 | ; Return: An Array with text from the cells and the row checked status.
439 | ;=======================================================================================
440 | RowText(Index)
441 | {
442 | Data := []
443 | , ckd := (LV_GetNext(Index-1, "Checked")=Index) ? 1 : 0
444 | , iIcon := this.GetIconIndex(this.LVHwnd, Index)
445 | , Data.Insert("Icon" iIcon " Check" ckd)
446 | Loop, % LV_GetCount("Col")
447 | {
448 | LV_GetText(Cell, Index, A_Index)
449 | , Data.Insert(Cell)
450 | }
451 | return Data
452 | }
453 | ;=======================================================================================
454 | ; Function: LV_Rows.GetIconIndex()
455 | ; Description: Retrieves the row's icon index.
456 | ; Parameters:
457 | ; Hwnd: Hwnd of the ListView.
458 | ; Row: 1-based Row number.
459 | ; Return: The 1-based icon index from specified row.
460 | ;=======================================================================================
461 | GetIconIndex(Hwnd, Row)
462 | {
463 | Static LVIF_IMAGE := 0x00000002
464 | Static LVM_GETITEMA := 0x1005
465 | Static LVM_GETITEMW := 0x104B
466 | Static LVM_GETITEM := A_IsUnicode ? LVM_GETITEMW : LVM_GETITEMA
467 |
468 | VarSetCapacity(LVITEM, 6 * 4 + (A_PtrSize * 2), 0)
469 | NumPut(LVIF_IMAGE, LVITEM, 0, "UInt") ; mask
470 | NumPut(Row-1, LVITEM, 4, "Int") ; iItem
471 | SendMessage, LVM_GETITEM, 0, &LVITEM,, ahk_id %Hwnd%
472 | return NumGet(LVITEM, 5 * 4 + (A_PtrSize * 2), "Int") + 1
473 | }
474 | }
475 |
476 |
--------------------------------------------------------------------------------
/lib/dpi.ahk:
--------------------------------------------------------------------------------
1 | /*
2 | Name : DPI
3 | Purpose : Return scaling factor or calculate position/values for AHK controls (font size, position (x y), width, height)
4 | Version : 0.31
5 | Source : https://github.com/hi5/dpi
6 | AutoHotkey Forum : https://autohotkey.com/boards/viewtopic.php?f=6&t=37913
7 | License : see license.txt (GPL 2.0)
8 | Documentation : See readme.md @ https://github.com/hi5/dpi
9 |
10 | History:
11 |
12 | * v0.31: refactored "process" code, just one line now
13 | * v0.3: - Replaced super global variable ###dpiset with static variable within dpi() to set dpi
14 | - Removed r parameter, always use Round()
15 | - No longer scales the Rows option and others that should be skipped (h-1, *w0, hwnd etc)
16 | * v0.2: public release
17 | * v0.1: first draft
18 |
19 | */
20 |
21 | DPI(in="",setdpi=1)
22 | {
23 | static dpi:=1
24 | if (setdpi <> 1)
25 | dpi:=setdpi
26 | RegRead, AppliedDPI, HKEY_CURRENT_USER, Control Panel\Desktop\WindowMetrics, AppliedDPI
27 | ; If the AppliedDPI key is not found the default settings are used.
28 | ; 96 is the default value.
29 | if (ErrorLevel=1) OR (AppliedDPI=96)
30 | AppliedDPI:=96
31 | if (dpi <> 1)
32 | AppliedDPI:=dpi
33 | factor:=AppliedDPI/96
34 | if !in
35 | Return factor
36 |
37 | Loop, parse, in, %A_Space%%A_Tab%
38 | {
39 | option:=A_LoopField
40 | if RegExMatch(option,"i)(w0|h0|h-1|xp|yp|xs|ys|xm|ym)$") or RegExMatch(option,"i)(icon|hwnd)") ; these need to be bypassed
41 | out .= option A_Space
42 | else if RegExMatch(option,"i)^\*{0,1}(x|xp|y|yp|w|h|s)[-+]{0,1}\K(\d+)",number) ; should be processed
43 | out .= StrReplace(option,number,Round(number*factor)) A_Space
44 | else ; the rest can be bypassed as well (variable names etc)
45 | out .= option A_Space
46 | }
47 | Return Trim(out)
48 | }
49 |
--------------------------------------------------------------------------------
/lib/iob.ahk:
--------------------------------------------------------------------------------
1 | ;[settings]
2 | ;BackgroundHotkey=F4
3 | ;ForegroundHotkey=Esc & F4
4 | ;MaxFiles=30
5 | ;MenuPos=3
6 | ;TCPath=c:\totalcmd\TotalCmd.exe
7 | ;TCStart=1
8 | ;MaxWinWaitSec=2
9 | ;[1]
10 | ;delay=0
11 | ;exe=c:\WINDOWS\notepad.exe
12 | ;ext=txt,xml
13 | ;method=Normal
14 | ;windowmode=1
15 |
16 | iob(Filename="")
17 | {
18 | Global MatchList:=[]
19 | SectionKeys:=iob_getkeys(1)
20 | Loop, parse, SectionKeys, CSV
21 | {
22 | IniRead, OutputVar, %Filename%, Settings, %A_LoopField%
23 | if (OutputVar = "ERROR")
24 | OutputVar:=""
25 | MatchList["Settings",A_LoopField]:=OutputVar
26 | }
27 | SectionKeys:=iob_getkeys(2)
28 | IniRead, OutputVarSectionNames, %Filename%
29 | StringReplace,OutputVarSectionNames,OutputVarSectionNames,Settings,,All
30 | StringReplace,OutputVarSectionNames,OutputVarSectionNames,`n,`,,All
31 | StringReplace,OutputVarSectionNames,OutputVarSectionNames,%A_Space%,,All
32 | Loop, parse,OutputVarSectionNames, CSV
33 | {
34 | Section:=A_LoopField
35 | Loop, parse, SectionKeys, CSV
36 | {
37 | IniRead, OutputVar, %Filename%, %section%, %A_LoopField%
38 | if (OutputVar = "ERROR")
39 | break
40 | MatchList[section,A_LoopField]:=OutputVar
41 | }
42 | }
43 | If (Trim(MatchList.1.Ext,"`n`r`t ") = "")
44 | MatchList.1.Ext:="txt" ; safety as we need at least one extension for the default editor
45 | ; Return MatchList
46 | }
47 |
48 | iob_save(ObjectName,Filename="") { ; Object parameter isn't used but just added to allow same function call as XA_Save
49 | global MatchList
50 | FileCopy, %Filename%, %Filename%.bak, 1
51 | FileDelete, %Filename%
52 | SectionKeys:=iob_getkeys(1)
53 | Loop, parse, SectionKeys, CSV
54 | IniWrite, % MatchList["Settings",A_LoopField], %Filename%, Settings, %A_LoopField%
55 | SectionKeys:=iob_getkeys(2)
56 | Loop
57 | {
58 | Index:=A_Index
59 | If !MatchList.HasKey(Index)
60 | Break
61 | Loop, parse, SectionKeys, CSV
62 | IniWrite, % MatchList[Index,A_LoopField], %Filename%, %Index%, %A_LoopField%
63 | }
64 | }
65 |
66 | iob_getkeys(section)
67 | {
68 | If (Section = 1)
69 | Return "BackgroundHotkey,ForegroundHotkey,MaxFiles,MenuPos,FilteredMenuAutoEdit,MaxWinWaitSec,TCPath,TCIniPath,TCStart,F4MMCloseAll,F4MMClosePID,FilteredHotkey,FullMenu,Explorer,Everything,DoubleCommander,XYPlorer,Lister,FindFiles,QuickView,log,logfile" ; ,EvPath,EVDirTree
70 | If (Section = 2)
71 | Return "Delay,Exe,Ext,Method,Open,Windowmode,StartDir,Parameters,Icon,Name"
72 | }
73 |
--------------------------------------------------------------------------------
/lib/log.ahk:
--------------------------------------------------------------------------------
1 | /*
2 | Loging function for debugging purposes, hidden settings (manual editing of settings file)
3 | */
4 |
5 | Log(logstring,logfile)
6 | {
7 | logfile:=StrReplace(logfile,"%A_ScriptDir%",A_ScriptDir)
8 | if (logfile = "")
9 | logfile:=A_ScriptDir "\logfile.txt"
10 | FileAppend, `n%logstring%, %logfile%, UTF-8-RAW
11 | }
--------------------------------------------------------------------------------
/lib/osdtip.ahk:
--------------------------------------------------------------------------------
1 | ; OSDTIP_Pop(MainText, SubText, TimeOut, Options, FontName, Transparency)
2 | ; OSDTIP_Pop("Notification", "Message", -3000) ; #Persistent required
3 | OSDTIP_Pop(P*) { ; OSDTIP_Pop v0.55 by SKAN on D361/D36E @ tiny.cc/osdtip
4 | Local
5 | Static FN:="", ID:=0, PM:="", PS:=""
6 |
7 | If !IsObject(FN)
8 | FN := Func(A_ThisFunc).Bind(A_ThisFunc)
9 |
10 | If (P.Count()=0 || P[1]==A_ThisFunc) {
11 | OnMessage(0x202, FN, 0), OnMessage(0x010, FN, 0) ; WM_LBUTTONUP, WM_CLOSE
12 | SetTimer, %FN%, OFF
13 | DllCall("AnimateWindow", "Ptr",ID, "Int",200, "Int",0x50004) ; AW_VER_POSITIVE | AW_SLIDE
14 | Progress, 10:OFF ; | AW_HIDE
15 | Return ID:=0
16 | }
17 |
18 | MT:=P[1], ST:=P[2], TMR:=P[3], OP:=P[4], FONT:=P[5] ? P[5] : "Segoe UI"
19 | Title := (TMR=0 ? "0x0" : A_ScriptHwnd) . ":" . A_ThisFunc
20 |
21 | If (ID) {
22 | Progress, 10:, % (ST=PS ? "" : PS:=ST), % (MT=PM ? "" : PM:=MT), %Title%
23 | OnMessage(0x202, FN, TMR=0 ? 0 : -1) ; v0.55
24 | SetTimer, %FN%, % Round(TMR)<0 ? TMR : "OFF"
25 | Return ID
26 | }
27 |
28 | If ( InStr(OP,"U2",1) && FileExist(WAV:=A_WinDir . "\Media\Windows Notify.wav") )
29 | DllCall("winmm\PlaySoundW", "WStr",WAV, "Ptr",0, "Int",0x220013) ; SND_FILENAME | SND_ASYNC
30 | ; | SND_NODEFAULT
31 | DetectHiddenWindows, % ("On", DHW:=A_DetectHiddenWindows) ; | SND_NOSTOP | SND_SYSTEM
32 | SetWinDelay, % (-1, SWD:=A_WinDelay)
33 | DllCall("uxtheme\SetThemeAppProperties", "Int",0)
34 | Progress, 10:C00 ZH1 FM9 FS10 CWF0F0F0 CT101010 %OP% B1 M HIDE,% PS:=ST, % PM:=MT, %Title%, %FONT%
35 | DllCall("uxtheme\SetThemeAppProperties", "Int",7) ; STAP_ALLOW_NONCLIENT
36 | ; | STAP_ALLOW_CONTROLS
37 | WinWait, %Title% ahk_class AutoHotkey2 ; | STAP_ALLOW_WEBCONTENT
38 | WinGetPos, X, Y, W, H
39 | SysGet, M, MonitorWorkArea
40 | WinMove,% "ahk_id" . WinExist(),,% MRight-W,% MBottom-(H:=InStr(OP,"U1",1) ? H : Max(H,100)), W, H
41 | If ( TRN:=Round(P[6]) & 255 )
42 | WinSet, Transparent, %TRN%
43 | ControlGetPos,,,,H, msctls_progress321
44 | If (H>2) {
45 | ColorMQ:=Round(P[7]), ColorBG:=P[8]!="" ? Round(P[8]) : 0xF0F0F0, SpeedMQ:=Round(P[9])
46 | Control, ExStyle, -0x20000, msctls_progress321 ; v0.55 WS_EX_STATICEDGE
47 | Control, Style, +0x8, msctls_progress321 ; PBS_MARQUEE
48 | SendMessage, 0x040A, 1, %SpeedMQ%, msctls_progress321 ; PBM_SETMARQUEE
49 | SendMessage, 0x0409, 1, %ColorMQ%, msctls_progress321 ; PBM_SETBARCOLOR
50 | SendMessage, 0x2001, 1, %ColorBG%, msctls_progress321 ; PBM_SETBACKCOLOR
51 | }
52 | DllCall("AnimateWindow", "Ptr",WinExist(), "Int",200, "Int",0x40008) ; AW_VER_NEGATIVE | AW_SLIDE
53 | SetWinDelay, %SWD%
54 | DetectHiddenWindows, %DHW%
55 | If (Round(TMR)<0)
56 | SetTimer, %FN%, %TMR%
57 | OnMessage(0x202, FN, TMR=0 ? 0 : -1), OnMessage(0x010, FN) ; WM_LBUTTONUP, WM_CLOSE
58 | Return ID:=WinExist()
59 | }
60 |
--------------------------------------------------------------------------------
/lib/tc.ahk:
--------------------------------------------------------------------------------
1 | ; TC_SendData() using WM_CopyData
2 | ; https://www.ghisler.ch/board/viewtopic.php?p=363391#p363391
3 |
4 | /*
5 | TESTED AND WORKING ON: AHK_L v 1.1.31.01 unicode & ansi version, Win 10 64bit and TC9.22
6 | modified by dindog
7 | -------------------------------------------------------------------------
8 | TC_SendData("em_FOO" , "EM") ; User Command
9 | TC_SendData("em_APPENDTABS C:\my.tab", "EM") ; User Command with parameters (usercmd.ini as following)
10 | ; [em_APPENDTABS]
11 | ; cmd=APPENDTABS
12 | ; param=%A
13 | TC_SendData("em_CD C:", "EM") ; User Command with parameters (usercmd.ini as following)
14 | ; [em_cd]
15 | ; cmd=cd
16 | ; param=%A
17 | TC_SendData("em_命令 *.exe", "EM") ; User Command with parameters (usercmd.ini as following) test for command name non-ASCII
18 | ; [em_命令]
19 | ; cmd=cd
20 | ; param=%A
21 |
22 | TC_SendData("cmd") ; Ask TC : (cmd one of the following varues:)
23 | ; A = Active Side
24 |
25 | ; LP = Left Path RP = Right Path
26 | ; LC = Left List Count RC = Right List Count
27 | ; LI = Left Caret Index RI = Right Caret Index
28 | ; LN = Left Name Caret RN = Right Name Caret
29 |
30 | ; SP = Source Path TP = Target Path
31 | ; SC = Source List Count TC = Target List Count
32 | ; SI = Source Caret Index TI = Target Caret Index
33 | ; SN = Source Name Caret TN = Target Name Caret
34 |
35 | TC_SendData("C:\tc" "`r" "D:\data", "CD") ; CD Command: (LeftDir - RightDir)
36 | TC_SendData("C:\tc" "`r" , "R") ; CD Command: (LeftDir) and activate Right panel
37 | TC_SendData( "`r" "D:\data", "LT") ; CD Command: ( RightDir) in new tab and activate left panel
38 |
39 | TC_SendData("C:\tc" "`r" "D:\data", "S") ; CD Command: (SourceDir - TargetDir)
40 | TC_SendData("C:\tc" "`r" , "SBT") ; CD Command: (SourceDir) in new background tab
41 | TC_SendData( "`r" "D:\data", "ST") ; CD Command: ( TargetDir) in new background tab
42 | S: Interpret the paths as source/target instead of left/right
43 | T: Open path(s) in new tabs
44 | B: Open tabs in background (do not activate them)
45 | L: Activate the left panel
46 | R: Activate the right panel
47 | A: Do not open archives as directories. Instead, open parent directory and place cursor on it.
48 | TC accepts more then 2 parameters here, so sending e.g. STBL is legitimate.
49 | */
50 |
51 | TC_SendData(Cmd, CmdType="", msg="", hwnd="") {
52 | Critical ; Define "OnMessage" as STATIC it is registered at Script startup.
53 | STATIC om:=OnMessage(0x4a, "TC_SendData"), TC_ReceiveDataValue:="", TC_DataReceived:="" ; 0x4a is WM_COPYDATA
54 |
55 | IF ((msg=0x4A) AND (hwnd=A_ScriptHwnd)) ; EnSure is trigered by this Script.
56 | EXIT (TC_ReceiveDataValue:=StrGet(NumGet(CmdType + A_PtrSize * 2)), TC_DataReceived:="1")
57 |
58 | VarSetCapacity(CopyDataStruct, A_PtrSize * 3), TC_ReceiveDataValue:=1, TC_DataReceived:=""
59 | if (CmdType="") ; Ask TC
60 | CmdType:=(A_IsUnicode ? "GW" : "GA"), TC_ReceiveDataValue:=""
61 | else if (CmdType="EM") or (CmdType="em") ; em command
62 | CmdType:="EM"
63 | else ; CD command STBALR
64 | DirType:=(CmdType="CD")?"":CmdType, CmdType:="CD"
65 |
66 | ;;;;;;VarSetCapacity need to request at least 5 more byte to allow 4 CD params
67 | VarSetCapacity(cmdA, StrPut(cmd, (A_IsUnicode ?"UTF-8":"CP0")) + (CmdType="CD" ? 5 : 0) * (A_IsUnicode ? 2 : 1), 0) , Len:=StrPut(cmd, &cmdA, (A_IsUnicode ?"UTF-8":"CP0"))
68 |
69 |
70 |
71 | NumPut( Asc(SubStr(CmdType,1,1)) + 256 * Asc(SubStr(CmdType,2,1)), CopyDataStruct,0 )
72 | NumPut( Len + (CmdType="CD" ? 5 : 0) * (A_IsUnicode ? 2 : 1) , CopyDataStruct, A_PtrSize )
73 | NumPut( &cmdA , CopyDataStruct, A_PtrSize * 2)
74 | Loop, % strlen(DirType) ;(CmdType=="CD" ? 2 : 0)
75 | {
76 | NumPut(Asc(SubStr(DirType,A_Index,1)), cmdA ,Len+A_Index-1, "Char")
77 | }
78 | SendMessage, 0x4A,%A_ScriptHwnd%, &CopyDataStruct,, ahk_class TTOTAL_CMD
79 |
80 | While (TC_ReceiveDataValue="") {
81 | IfEqual, TC_DataReceived, 1, Break
82 | IfGreaterOrEqual, A_Index, 500, Break
83 | Sleep,10
84 | }
85 | Return TC_ReceiveDataValue
86 | }
87 |
88 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2025 hi5
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # F4MiniMenu - v1.47
2 |
3 | A F4 Menu program for [Total Commander](http://www.ghisler.com/) to open selected file(s) in editor(s).
4 | (and experimental/rudimentary support for Windows Explorer, Double Commander, XYPlorer, and Everything - only [when activated](#other-programs)).
5 |
6 | It is a *standalone* program which runs separatly from Total Commander. See Getting Started.
7 |
8 | ## Features
9 |
10 | * Open selected files in defined Editor(s) - on a first come, first serve basis
11 | * Optional: Show menu with:
12 | a. All Editors (full menu)
13 | b. Matching Editors based on extension (filtered menu)
14 | * Various methods to open selected files: "[regular](#normal)", "[Drag & Drop](#drag-drop)", [Filelist](#filelist), [cmdline](#cmdline)
15 | * Document Templates to create new files for file types other than "text" - [DocumentTemplates README](DocumentTemplates/readme.md)
16 | * Open source - written in [AutoHotkey](https://www.autohotkey.com/) (v1.1)
17 |
18 | ## Discussion
19 |
20 | * [F4MiniMenu TC Forum thread](http://ghisler.ch/board/viewtopic.php?t=35721).
21 | * [GH Issues](https://github.com/hi5/F4MiniMenu/issues)
22 |
23 | # Introduction
24 |
25 | F4 is the shortcut key used in [Total Commander](http://www.ghisler.com/) - a file manager
26 | for Windows - for opening selected files in a pre-defined editor. In TC only one program can
27 | be assigned to F4 making it impossible to define or select other editors for different file
28 | types. Several tools have been made to solve this problem, these include:
29 |
30 | * [ChoiceEditor](http://www.totalcmd.net/plugring/ChoiceEditor.html)
31 | * [Open File shell for TC](http://www.totalcmd.net/plugring/OpenFileTC.html)
32 | * [Total Commander Edit Redirector](http://ghisler.ch/board/viewtopic.php?t=27573)
33 | * [Total Editor](https://www.ghisler.ch/board/viewtopic.php?t=81215)
34 | * and of course [F4Menu](http://ghisler.ch/board/viewtopic.php?t=17003) - TC Forum thread
35 |
36 | While the original F4Menu[1] has quite a few options, this "clone" started out as a minimalistic
37 | program with only the basic functionality: opening multiple file types in various editors.
38 |
39 | There are various methods to open selected files: regular, "[Drag & Drop](#drag--drop)", [Filelist](#filelist)
40 | or by making use of a [cmdline](#cmdline) option.
41 |
42 | There is a helper script to use F4MiniMenu settings as the "internal editor" defined in
43 | Total Commander and use so called **DocumentTemplates** for creating new files.
44 | See [F4TCIE](#helper-script-f4tcieahk).
45 |
46 | There are *two* foreground menus:
47 |
48 | 1. Show all programs in the menu
49 | 2. Show matching programs (filtered): only show those programs which match the extensions
50 | of the selected files. Access the full menu by using the 'full menu' option
51 | that is shown in this filtered menu. The default editor will remain the first menu
52 | entry. If a matching program can not be found, the full menu is shown instead. (See settings)
53 |
54 | Passive mode, F4MiniMenu doesn't have to remain in memory for it to work, see [passive](#passive).
55 |
56 | ## First come, first serve
57 |
58 | __F4MiniMenu__ will open a file in the __first__ editor it finds a match for based on the
59 | __extension__. If there is no match, it will open the file(s) in the default editor.
60 | The default editor is the first editor listed in the [*Configure editors*](#screenshots)
61 | window and in the configuration file (XML or INI) it will be the first entry.
62 | To open the file(s) in another program use the [*Foreground* menu](#screenshots) option.
63 | See screenshot below.
64 |
65 | Add or modify editors via the tray menu or by bringing up the Foreground menu.
66 | `%Commander_Path%` and other variables can be used in the path(s) to the editors and icons.
67 |
68 | ### Tip(s)
69 |
70 | In principle F4Menu (or other tools) and F4MiniMenu can be run side by side as long as
71 | there are no conflicting keyboard shortcuts. In case of the same hotkey setup, F4MiniMenu
72 | will take precedence. Set the F4MiniMenu shortcuts via the tray menu, right click, Settings option.
73 |
74 | In general: be careful opening with opening large numbers of files at once, programs can crash
75 | and your computer could become unstable requiring a reboot.
76 |
77 | Do not edit the `F4MiniMenu.xml` or `F4MiniMenu.ini` settings file while the script is running, any
78 | changes made will be overwritten when the script exits. A backup is made at startup and saved as
79 | `F4MiniMenu.xml.bak` or `F4MiniMenu.ini.bak`
80 |
81 | ### Disclaimer
82 |
83 | Use at your own risk.
84 |
85 | # Getting Started
86 |
87 | Start `F4MiniMenu.ahk` (or `F4MiniMenu-64.exe`, `F4MiniMenu-32.exe`, available in [Releases](https://github.com/hi5/F4MiniMenu/releases)).
88 |
89 | Note that F4MiniMenu is a program that runs on its **own** and sits in the tray menu waiting
90 | for Total Commander windows (and others if set up) to be _Active_ and the defined hotkeys to be
91 | pressed to take action (e.g. _Edit files_, default: F4; or _Show a menu_ default: Esc+F4).
92 | Access the settings and define(d) editors via the tray menu or [foreground menu](https://github.com/hi5/F4MiniMenu#screenshots) - Esc+F4.
93 |
94 | No changes to the TC settings are required, although there is a helper script (program), see [F4TCIE](#helper-script-f4tcieahk),
95 | which does need to be defined as `editor` in the TC Settings for working with files in archives and FTP.
96 |
97 | Once F4MiniMenu is started, the Global settings and new editors with a variety of options (as outlined below) can be changed and added.
98 |
99 | (Additional information in the "Setup" section below.)
100 |
101 | # Settings
102 |
103 | ## Global configuration
104 |
105 | * Menu
106 | - Position of Menu
107 | - Accelerator key for full menu when using the filtered menu
108 | - Show Menu or Edit file directly when using the filtered menu
109 | * Files (Maximum number of files to be opened, will ask for confirmation if more are selected)
110 | * WinWait -- see below
111 | * Total Commander
112 | - TC Start (Start Total Commander when F4MM is started, or not)
113 | - TC Path, TC INI Path (for F4Edit settings, see "Use elsewhere in TC")
114 | - Close F4MM options (Exit F4MM when Total Commander closes)
115 | * Hotkeys (Note: when using F4MM with other programs it may be that the hotkeys do not work as expected, especially for programs running as Administrator)
116 | - Background (open files directly, do not show a menu)
117 | - Foreground menu (select program (from all programs) to open all selected files with)
118 | - Filtered menu (select program (filtered programs based on matching extensions) to open all selected files with)
119 | * Other programs (1)
120 | - Explorer, Double Commander, XYPlorer, Everything.
121 | * Use elsewhere in TC
122 | - Lister(2), Find Files, QuickView(3)
123 |
124 | (1) Support for other programs may stop or change at any time when new versions of those programs are being used.
125 | (1a) In Everything >v1.5+ F4 is assigned to "Focus Next Selected", F4MM will overrule this functionality - select another shortcut (either in F4MM or Everything) is this is not desired behaviour. (Settings in Everything may change during the programs development, still Alpha Feb. 2025)
126 |
127 | (2) If **Lister** setting is active _and_ `F4Edit>1` in wincmd.ini: _close Lister window_ - See `F4Edit=` options in TC help file on how to handle F4 in lister via wincmd.ini (Introduced in TC v11.03).
128 |
129 | (3) **QuickView** is experimental:
130 | `[x]` when checked, it will try to open the file that is currently open in the QuickView panel, _even_ if multiple files are selected in the active TC panel and the focus is NOT on the QuickView panel it self. The foreground and filtered menus can be opened in the QuickView panel, but here also only the one "viewed" file will be opened.
131 | `[ ]` when unchecked all selected files will be opened even when QuickView is being used.
132 |
133 | __WinWait__ Set the maximum time in seconds to wait for the selected program window to appear before applying the selected Window Mode (Normal, Maximized, Minimized -- see Editor configuration). This should also prevent any unexpected "waiting" in case a program launch failed (crash, very slow program start etc).
134 | As soon as the window appears it will continue to apply the Window mode and no longer wait.
135 | It may not be possible to edit (open) a new document during this defined waiting period.
136 |
137 | ## Editor configuration
138 |
139 | The following options can be set for each editor:
140 |
141 | * Path to Program executable. See Path variables.
142 | * Extensions as a comma separated list
143 | * Parameters to pass on -- if any, see Parameters/Options.
144 | * Start directory (if any)
145 | * Method (normal, drag & drop, filelist, cmdline) -- see Methods below
146 | * Window Mode (Normal (often last used window size and position), Maximized, Minimized)
147 | * Icon to use in the menu as alternative to program's icon (if any)
148 | * Name to use in the menu as alternative to the program.exe (if any)
149 | * Drag & Drop delay in millisecond (time to wait before sending drag & drop command so program can start)
150 | * Open delay in milliseconds (time to wait before opening the first file so program can start)
151 |
152 | ## Path variables
153 |
154 | All path variables should be wrapped in `%` signs, examples:
155 |
156 | * `%Commander_Path%\tools\lister.exe`
157 | * `%WinDir%\write.exe`
158 | * `%A_ScriptDir%\..\..\Portable\CudaText\cudatext.exe`
159 |
160 | TC Environment variable:
161 |
162 | * Commander_Path
163 |
164 | AutoHotkey path variables:
165 |
166 | * A_ScriptDir
167 | * A_ComputerName
168 | * A_UserName
169 | * A_WinDir
170 | * A_ProgramFiles
171 | * A_AppData
172 | * A_AppDataCommon
173 | * A_Desktop
174 | * A_DesktopCommon
175 | * A_StartMenu
176 | * A_StartMenuCommon
177 | * A_Programs
178 | * A_ProgramsCommon
179 | * A_Startup
180 | * A_StartupCommon
181 | * A_MyDocuments
182 |
183 | Environment path variables:
184 |
185 | * ComSpec
186 | * WinDir
187 | * ProgramFiles
188 | * ProgramFiles(x86)
189 | * ProgramW6432
190 |
191 | From the [AutoHotkey documentation](https://www.autohotkey.com/docs/v1/Variables.htm#os):
192 |
193 | The Program Files directory (e.g. `C:\Program Files` or `C:\Program Files (x86)`). This is usually the same as the `ProgramFiles` environment variable.
194 |
195 | On 64-bit systems (and not 32-bit systems), the following applies:
196 |
197 | * If the executable (EXE) that is running the script is 32-bit, `A_ProgramFiles` returns the path of the "Program Files (x86)" directory.
198 | * For 32-bit processes, the `ProgramW6432` environment variable contains the path of the 64-bit Program Files directory. On Windows 7 and later, it is also set for 64-bit processes.
199 | * The `ProgramFiles(x86)` environment variable contains the path of the 32-bit Program Files directory.
200 |
201 | # Methods
202 |
203 | There are four methods to start a program and open the selected file(s).
204 |
205 | ## Normal
206 |
207 | This works in many cases and is similar to opening a file in TC by pressing enter or double click (or traditional F4).
208 | When multiple files are selected and the program(s) needs to be started first, a delay per editor can be set before
209 | attemping to open the second and other files: Delay for Open. A similar delay can be set for Drag & Drop. Normal is the default method.
210 |
211 | ## Drag & Drop
212 |
213 | When the program is already running F4MM attempts to Drag & Drop the selected files into the application.
214 | If the program is not running, it is started using the normal method for the first file, then subsquent
215 | files are Drag & Dropped. In order to give the application some time to start, before D&D the second and
216 | other files a delay can be set per editor - Delay for Drag & Drop. A simlar delay can be set for Normal.
217 |
218 | Many programs support Drag & Drop, but not all programs will respond well to the Drag & Drop
219 | method used in this script. If it does not seem to work with a particular program, try
220 | the Normal or cmdline method(s).
221 |
222 | ## Filelist
223 |
224 | Some programs can open files which are listed in a (temporary) file. In Total Commander
225 | there is something similar in the _Button bar_ and in the _Start Menu_ where a file list --
226 | the `%L` parameter -- can be used to create a list with the names of the selected files and
227 | directories, one file per line. __F4MiniMenu__ can do the same. A temporary file named
228 | `$$f4mtmplist$$.m3u` is created which is passed on to the target program.
229 |
230 | *Example Filelist usage:*
231 |
232 | Program: C:\Program Files\XnView\xnview.exe
233 | Parameters: -filelist
234 | Method: 3 - Filelist
235 |
236 | Result: Selected files will be opened in the XnView browser.
237 |
238 | Program: C:\Program Files\IDMComp\UltraEdit\uedit64.exe
239 | Parameters: /f
240 | Method: 3 - Filelist
241 |
242 | Result: Selected files will be opened in UltraEdit. /f is the command line parameter required for UltraEdit.
243 |
244 | ## cmdline
245 |
246 | To pass the selected files to the program on the command line `"program.exe" "file1" "file2" "etc"`.
247 | Paths to the program and files are quoted automatically.
248 |
249 | *Examples cmdline usage:*
250 |
251 | Program: C:\Program Files\Meld\Meld.exe
252 | Method: 4 - cmdline
253 |
254 | Result: Selected files will be opened in Meld (diff program) [Discussion](https://github.com/hi5/F4MiniMenu/issues/14)
255 |
256 | Program: c:\tools\mp3wrap\mp3wrap.exe
257 | Parameters: ?output.mp3
258 | Startdir: %p
259 | Method: 4 - cmdline
260 |
261 | Result: Selected MP3 files will be merged into one larger MP3 file asking the user for a filename
262 | (output.mp3 would be default)
263 |
264 | Program: c:\Portable\vscodium\VSCodium.exe
265 | Parameters: -filelist
266 | Method: 3 - Filelist
267 |
268 | Result: Selected files will be opened in VSCodium (works the same for Microsoft Visual Studio Code)
269 |
270 | *Notes:*
271 |
272 | * The reason for the .m3u extension is simple: it enables playlist support for WinAmp: Select
273 | multiple music files and press the hotkey to play the selected files. If the temporary file
274 | didn't have the .m3u extension WinAmp wouldn't recognize it as a playlist.
275 | * The temporary file `$$f4mtmplist$$.m3u` is __not__ deleted directly after use to avoid
276 | problems with slow programs. It is deleted when __F4MiniMenu__ starts or closes.
277 |
278 | ## Parameters/Options
279 |
280 | (The TC file manager has two file panels side by side referred to as Source and Target)
281 |
282 | |Parameter|Meaning|
283 | |---------|-------|
284 | |`%P` |insert the source path into the command line, including a backslash \ at the end.|
285 | |`%T` |insert the current target path, including a backslash \ at the end. (TC only, see notes)|
286 | |`%O` |places the current filename without extension into the command line.|
287 | |`%E` |places the current extension (without leading period) into the command line.|
288 | |`?` |as the first parameter causes a Dialog box to be displayed before starting the program, containing the parameters that follow. This allows the parameters to be changed before starting the program or prevent the programs execution.|
289 | |`%N` |places the filename under the cursor into the command line.|
290 | |`%M` |places the current filename in the target directory into the command line.|
291 | |`%$DATE:placeholders%`|See TC help, "Environment variables". Valid placeholders: y,Y,M,D,h,H,i1,i,m,s.|
292 | |**F4MM specific options:**|-------|
293 | |`%f41` |placeholder to alter position of filenames on the command line. (see notes and example below)|
294 | |`%$DATE:placeholders\|Value\|TimeUnits%`|if _Value_ and _TimeUnits_ are present, these parameters allow for "Date & Time Math" to add or substract TimeUnits. TimeUnits can be either `Seconds`, `Minutes`, `Hours`, or `Days`. See TimeUnits of the https://www.autohotkey.com/docs/v1/lib/EnvAdd.htm command.|
295 |
296 | Notes:
297 |
298 | 1. More _%f4_ fields may be added in the future.
299 | 2. %T for other file managers %T will use the same value as %P
300 |
301 | *Example: %f41*
302 |
303 | F4MiniMenu starts programs as follows:
304 |
305 | _ProgramName.exe Parameters File(s) Startdir_
306 |
307 | But for some programs the _parameter(s)_ - the additional command(s) that need to be passed
308 | on to the program - have the come _AFTER_ the _File(s)_. So by using %f41 as a placeholder
309 | in the parameters field it will instruct F4MiniMenu where to place the files on the
310 | "command line"
311 |
312 | Program: pdftk.exe
313 | Parameters: %f41 burst
314 |
315 | So the program now starts as _pdftk.exe file.pdf burst_ (instead of _pdftk.exe burst file.pdf_)
316 |
317 | *Example: %$DATE:placeholders|Value|TimeUnits%*
318 |
319 | `%$DATE:Y-M-D|7|Days%` -> A week from now e.g. add 7 Days ahead. -7 would be last week.
320 |
321 | # Helper script: F4TCIE.ahk
322 |
323 | Use F4TCIE for editing files in:
324 |
325 | * an Archived file (e.g. ZIP panel)
326 | * FTP connection
327 | * Create new file (Shift+F4)
328 |
329 | Rename the script or exe to to end with an "i" to an INI setup, e.g. `F4TCIEi.ahk` or `F4TCIEi.exe`.
330 | (see 'XML or INI')
331 |
332 | ## Setup F4TCIE
333 |
334 | When F4MiniMenu sees the selected files are in an archive or in an FTP panel,
335 | it uses the default Total Commander Edit command. It will only use the first
336 | file if multiple files have been selected in the archive or FTP panel.
337 |
338 | To configure Total Commander to use F4TCIE.ahk:
339 |
340 | TC, Configuration, Edit/View, Editor (xml):
341 | drive:\path-to\F4TCIE.ahk "%1"
342 |
343 | TC, Configuration, Edit/View, Editor (ini):
344 | drive:\path-to\F4TCIEi.ahk "%1"
345 |
346 | Note: if both AutoHotkey v1.1 and v2 are installed an error message may be shown (from the AutoHotkey launcher).
347 | In that case include the full path of the AutoHotkey v1.1 executable before the drive:\path-to\F4TCIE.ahk like so:
348 |
349 | TC, Configuration, Edit/View, Editor:
350 | c:\program files\autohotkey\autohotkey.exe drive:\path-to\F4TCIE.ahk "%1"
351 |
352 | Tip: To use %PROCESSOR_ARCHITECTURE%
353 |
354 | Rename
355 |
356 | F4TCIE-64i.exe -> F4TCIE-amd64i.exe
357 | F4TCIE-32i.exe -> F4TCIE-x86i.exe
358 |
359 | then use
360 |
361 | drive:\path-to\F4TCIE-%PROCESSOR_ARCHITECTURE%.exe "%1"
362 |
363 | If for some reason the configuration can not be opened, an attempt is made to start the editor
364 | for the file type associated in Windows (so for txt -> notepad, for bmp,jpg -> MS Paint etc).
365 | When there is no editor for the file type found `notepad.exe` is started.
366 |
367 | Reference: see also [#13](https://github.com/hi5/F4MiniMenu/issues/13)
368 |
369 | # DocumentTemplates
370 |
371 | F4TCIE can also make use of DocumentTemplates when creating New files in
372 | Total Commander using the shift+f4 shortcut.
373 |
374 | More information can be found in the [DocumentTemplates README](DocumentTemplates/readme.md)
375 |
376 | # Setup
377 |
378 | ## Requirements
379 |
380 | * AutoHotkey 1.1+ (Ansi or Unicode)
381 | * Total Commander (or some other file managers)
382 |
383 | ## Install
384 |
385 | ### Script
386 |
387 | Download the source as a ZIP from GitHub here
388 | and unpack. To start it simply run `F4MiniMenu.ahk`. Setup F4MiniMenu using the tray menu
389 | options for *Settings* and *Configure editors*.
390 |
391 | Once the shortcuts have been setup access *Settings* and *Configure editors* via the Foreground
392 | menu options by pressing the shortcut (press Esc+F4 by default).
393 | See screenshots below.
394 |
395 | ### Executable
396 |
397 | 1. Compile the script to a standalone executable using [AHK2Exe](https://autohotkey.com/download/).
398 | [Documentation](https://autohotkey.com/docs/Scripts.htm#ahk2exe)
399 | 2. Or see https://github.com/hi5/F4MiniMenu/releases (32 & 64 bit versions of both F4MiniMenu and F4TCIE)
400 |
401 | ## XML or INI - There are two versions:
402 |
403 | 1. F4MiniMenu.ahk (and F4TCIE.ahk) use(s) XML to store its settings (F4MiniMenu.xml)
404 | 2. To store settings in the INI format (F4MiniMenu.ini) simply rename the (compiled) script(s) so it ends with an i (letter i)
405 | so rename or copy F4MiniMenu.ahk to F4MiniMenui.ahk (and F4TCIE.ahk to F4TCIEi.ahk).
406 |
407 | ## Closing F4MiniMenu
408 |
409 | Use tray menu, exit.
410 |
411 | Automatically close F4MiniMenu using the following options (available via Settings):
412 |
413 | 1. Close F4MM when all copies of TC close: this waits until all running copies of Total Commander are closed, then exit F4MiniMenu.
414 | 2. Close F4MM when TC closes started by F4MM: If (a new) Total Commander was started via F4MiniMenu, wait until that specific Total Commander instance closes, then exit F4MiniMenu.
415 |
416 | # Passive (use in button, start menu, user cmd)
417 |
418 | **Important** Do not use passive mode when F4MiniMenu is already running.
419 |
420 | First parameter must be the file list which contains the selected files in Total Commander or Double Commander (refer to file manager documentation for further information).
421 |
422 | Optional parameters are /P1, /P2, /M1, and /M2
423 |
424 | Examples:
425 |
426 | ```
427 | Command: F4MiniMenu.ahk
428 | Parameters: %L
429 |
430 | Command: F4MiniMenui.ahk
431 | Parameters: %L /P1 /M1
432 |
433 | Command: F4MiniMenu.exe
434 | Parameters: %L /P2 /M2
435 | ```
436 |
437 | |Parameter|Meaning|
438 | |---------|-------|
439 | |%L | List file in the TEMP directory with the names of the selected files to be processed by F4MiniMenu (by file manager) |
440 | |/P1 | Menu position at Mouse cursor (useful to have it show at button bar location) |
441 | |/P2 | Menu position Centered in window |
442 | |/M1 | Full menu |
443 | |/M2 | Filtered menu |
444 | |/ED | Open Editors, ignore all other options |
445 | |/SET | Open Settings, ignore all other options |
446 |
447 | ## Other programs
448 |
449 | ### File managers
450 |
451 | The foreground and background menu should work with Explorer, Double Commander, XYPlorer, and Everything.
452 |
453 | Not supported:
454 |
455 | * Starting and Closing of these file managers and/or F4MiniMenu
456 | * DocumentTemplates
457 | * Positioning of the menu - defaults to "Centered in window"
458 |
459 | Each file manager has to be (de)activated in the settings.
460 |
461 | To enable:
462 |
463 | * for Explorer and Everything: tick the checkbox (on)
464 | * for Double Commander and XYPlorer set the hotkey that will copy the full path names to the clipboard, e.g. the equivalent of the `cm_CopyFullNamesToClip` TC command (Double Commander default: Ctrl+Shift+c, XYPlorer default: Ctrl+p)
465 | * save the settings (OK) - F4MiniMenu should reload automatically and now work with the activated file managers.
466 |
467 | To disable:
468 |
469 | * for Explorer and Everything: tick the checkbox (off)
470 | * for Double Commander and XYPlorer delete the hotkey(s) (press DEL)
471 | * save the settings (OK)
472 |
473 | As support for these other file managers is not thoroughly tested, unexpected behaviour may occur.
474 |
475 | ## Screenshots
476 |
477 | __Foreground menu__
478 |
479 | 
480 |
481 | __Confirm maximum__
482 |
483 | 
484 |
485 | __General program settings__
486 |
487 | 
488 |
489 | __Configure editors__
490 |
491 | 
492 |
493 | __Editor configuration__
494 |
495 | 
496 |
497 | ## TODO - Known issues
498 |
499 | 1. TOFIX: If the order of the editors is changed first and then a new one is added, the order is set back to the initial order.
500 |
501 | 2. INFO: Two options for delay:
502 | 2.1 Drag & Drop delay gives program to start up before trying to drop the files - you may need to apply trail and error.
503 | 2.2 Open delay, pauses X ms to open first file.
504 |
505 | ## Credits
506 |
507 | ### Used AHK Functions & Libraries
508 |
509 | * [Class LV_Rows](http://www.autohotkey.com/board/topic/94364-class-lv-rows-copy-cut-paste-and-drag-listviews/) by [Pulover](https://github.com/Pulover/) - as of v0.6
510 | * [XA Save / Load Arrays to/from XML Functions](https://github.com/hi5/XA)
511 | * [DropFilesA - SKAN](http://www.autohotkey.com/board/topic/41467-make-ahk-drop-files-into-other-applications/#entry258810) including Unicode version [nimda](http://www.autohotkey.com/board/topic/79145-help-converting-ahk-ahk-l/#entry502676)
512 | * [OSDTIP_Pop() - SKAN](https://www.autohotkey.com/boards/viewtopic.php?t=76881#p333577)
513 | * [TC_SendData() - dindog and others](https://www.ghisler.ch/board/viewtopic.php?p=363391#p363391) - using WM_CopyData
514 | * [AutoXYWH() - toralf and tmplinshi](https://www.autohotkey.com/boards/viewtopic.php?t=1079)
515 |
516 | ## Changelog
517 |
518 | * See [changelog.md](changelog.md)
519 |
520 | ### Notes
521 |
522 | [1] Based on original idea from F4Menu by Shao Shanny - Backup links for the program can be found on the [Total Commander forum](http://ghisler.ch/board/viewtopic.php?t=17003)
523 |
524 |
--------------------------------------------------------------------------------
/res/f4.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hi5/F4MiniMenu/34d131ef7b47bef92dd4e120032674ac249ce5b3/res/f4.ico
--------------------------------------------------------------------------------