Difference between revisions of "AutoHotkey: From FileSync open another TC instance with selected files"
m (date) |
(cleaned up path for missing files in root dir; boUseFix_ArchiveFocusNoOpen: optional fix for TC bug unintentionally opening archives instead of focussing them (up to TC 9.50b13)) |
||
Line 5: | Line 5: | ||
*/ ; --> <code><pre> | */ ; --> <code><pre> | ||
; //////////////////////////////////////////////////////////////////////////// | ; //////////////////////////////////////////////////////////////////////////// | ||
− | ; // TC_Sync_OpenFolderInSecondTC.ahk V0. | + | ; // TC_Sync_OpenFolderInSecondTC.ahk V0.30 (W) StatusQuo 2008 - 2020 |
; // http://ghisler.ch/board/viewtopic.php?t=19713 | ; // http://ghisler.ch/board/viewtopic.php?t=19713 | ||
; // | ; // | ||
; // open another TC instance | ; // open another TC instance | ||
− | ; // with the folders of the currently selected file in cm_FileSync | + | ; // with the folders of the currently selected file in cm_FileSync (Synchronize directories) |
; // via hotkey: Ctrl+Win+T | ; // via hotkey: Ctrl+Win+T | ||
; //////////////////////////////////////////////////////////////////////////// | ; //////////////////////////////////////////////////////////////////////////// | ||
Line 18: | Line 18: | ||
#IfWinActive, ahk_class TCmpForm | #IfWinActive, ahk_class TCmpForm | ||
; F4:: | ; F4:: | ||
− | ^#t:: ; hotkey = Ctrl+Win+T | + | ^#t:: ; hotkey = Ctrl+Win+T: Open selected files from SyncFiles in second TC instance (reused by recurring calls) |
; please adjust path here; %COMMANDER_PATH% is not available outside of TC | ; please adjust path here; %COMMANDER_PATH% is not available outside of TC | ||
sTCExe := "C:\totalcmd\TOTALCMD.EXE" | sTCExe := "C:\totalcmd\TOTALCMD.EXE" | ||
− | boAlwaysOpenNewTask := 0 ; set to 1 to not re-use TC target window (always open a new one) | + | boAlwaysOpenNewTask := 0 ; set to 1 to not re-use TC target window (always open a new one) |
− | boCdToFolderOnly | + | boCdToFolderOnly := 0 ; set to 0 to have cursor placed on selected files; uses Lister (experimental?) |
− | iListerTimeOutSecs | + | iListerTimeOutSecs := 1 ; if using Lister: timeout after n seconds of not appearing Lister |
− | + | boTCSync2nd_RunAsAdmin := 1 ; set to 1 to start 2nd TC as other user, e.g. administrator | |
+ | boUseFix_ArchiveFocusNoOpen := 0 ; fixes a TC bug when using /A /O (present up to TC 9.50b13) | ||
+ | ; - slower, calls target TC twice (for left/right panel separately) | ||
+ | ; - set to 1 to use it | ||
+ | ; - set to 0 if one of the panels is not always refreshing | ||
; static pidTC2 | ; static pidTC2 | ||
; | ; | ||
Line 31: | Line 35: | ||
ControlGetFocus, Panel_id | ControlGetFocus, Panel_id | ||
SendMessage, %LB_GETCARETINDEX%, 0, 0, %Panel_id% | SendMessage, %LB_GETCARETINDEX%, 0, 0, %Panel_id% | ||
− | LB_CursorPosition := ErrorLevel | + | LB_CursorPosition := ErrorLevel ; *** 0 = line #1 (zero-based) |
+ | LB_CursorPosition_Save := LB_CursorPosition ; *** for debugging only | ||
VarSetCapacity(LB_String, 1024, 0) | VarSetCapacity(LB_String, 1024, 0) | ||
SendMessage, %LB_GETTEXT%, %LB_CursorPosition%, &LB_String, %Panel_id% | SendMessage, %LB_GETTEXT%, %LB_CursorPosition%, &LB_String, %Panel_id% | ||
LB_CursorLine := LB_String | LB_CursorLine := LB_String | ||
+ | ; | ||
Loop ; *** find subdirectory *** only working for VISIBLE lines - after scrolling dir line out of view, LB_GETTEXT fails! (Win2k, TC8.51a) | Loop ; *** find subdirectory *** only working for VISIBLE lines - after scrolling dir line out of view, LB_GETTEXT fails! (Win2k, TC8.51a) | ||
{ | { | ||
Line 43: | Line 49: | ||
LB_CursorPosition -= 1 | LB_CursorPosition -= 1 | ||
} | } | ||
− | + | ControlGetText, sLPath, TEdit2, ahk_class TCmpForm ; *** TC <= 7.04a | |
− | ControlGetText, sLPath, TEdit2, ahk_class TCmpForm ; TC <= 7.04a | + | ControlGetText, sRPath, TEdit1, ahk_class TCmpForm ; *** TC <= 7.04a |
− | ControlGetText, sRPath, TEdit1, ahk_class TCmpForm | ||
boTC75 := 0 ; TC <= 7.04a | boTC75 := 0 ; TC <= 7.04a | ||
if (sLPath . sRPath = "") | if (sLPath . sRPath = "") | ||
{ | { | ||
− | ControlGetText, sLPath, TAltEdit2, ahk_class TCmpForm ; TC >= 7.50 rc1 | + | ControlGetText, sLPath, TAltEdit2, ahk_class TCmpForm ; *** TC >= 7.50 rc1 |
− | ControlGetText, sRPath, TAltEdit1, ahk_class TCmpForm | + | ControlGetText, sRPath, TAltEdit1, ahk_class TCmpForm ; *** TC >= 7.50 rc1 |
if (sLPath . sRPath != "") | if (sLPath . sRPath != "") | ||
− | boTC75 := 1 ; TC >= | + | boTC75 := 1 ; *** TC >= 7.50 rc1 |
} | } | ||
− | if (boTC75) ; TC >= | + | if (boTC75) ; *** TC >= 7.50 rc1 |
{ | { | ||
if (SubStr(LB_String, 1, 7) = "DIR EQ ") | if (SubStr(LB_String, 1, 7) = "DIR EQ ") | ||
Line 67: | Line 72: | ||
; | ; | ||
LB_SubDir := LB_String | LB_SubDir := LB_String | ||
+ | if (InStr(LB_SubDir, "|") > 0) and (StrLen(LB_SubDir) >= 32) ; *** minimum string lenth: "L L to R F 1 01.02.12 11:22:33 |" | ||
+ | LB_SubDir := "" ; *** fix: if no subdir exists: LB_SubDir = LB_CursorLine of FIRST file line (also with cursor on a line below the first) | ||
; | ; | ||
− | ; *** TC 8.51a: | + | ; *** TC 8.51a / 9.22a: |
− | ; *** LB_CursorLine = | + | ; *** LB_CursorLine = 2 EQ both.zip 1.118 17.01.20 10:30:32 | 17.01.20 10:30:32 1.118 both.zip |
− | ; *** LB_CursorLine = | + | ; *** LB_CursorLine = L L to R left.zip 1.118 17.01.20 10:30:32 | |
− | ; *** LB_CursorLine = | + | ; *** LB_CursorLine = R R to L | 17.01.20 10:30:32 1.118 right.zip |
+ | ; *** LB_CursorLine = R DEL | 17.01.20 10:30:32 1.118 right.zip | ||
sLDirName := "" ; *** get left path name | sLDirName := "" ; *** get left path name | ||
if (not boCdToFolderOnly) | if (not boCdToFolderOnly) | ||
Line 81: | Line 89: | ||
If (sLDirName = "") | If (sLDirName = "") | ||
sLDirName := sLPath . LB_SubDir | sLDirName := sLPath . LB_SubDir | ||
− | + | ; --- | |
sRDirName := "" ; *** get right path name | sRDirName := "" ; *** get right path name | ||
− | if (not boCdToFolderOnly) | + | if (not boCdToFolderOnly) ; *** do not focus file |
and (SubStr(LB_CursorLine, 1, 1) != "L") ; and (SubStr(LB_CursorLine, StrLen(LB_CursorLine), 1) != "\") | and (SubStr(LB_CursorLine, 1, 1) != "L") ; and (SubStr(LB_CursorLine, StrLen(LB_CursorLine), 1) != "\") | ||
{ | { | ||
Line 91: | Line 99: | ||
If (sRDirName = "") | If (sRDirName = "") | ||
sRDirName := sRPath . LB_SubDir | sRDirName := sRPath . LB_SubDir | ||
− | + | ; --- | |
− | If boAlwaysOpenNewTask | + | If (boAlwaysOpenNewTask) |
or (not WinExist("ahk_pid " . pidTC2)) | or (not WinExist("ahk_pid " . pidTC2)) | ||
pidTC2 := "" | pidTC2 := "" | ||
Line 101: | Line 109: | ||
} | } | ||
; | ; | ||
− | sRunStr := sTCExe | + | sRunStr := sTCExe |
+ | sRunStrL := "" | ||
+ | sRunStrR := "" | ||
if (sLDirName != "") | if (sLDirName != "") | ||
− | sRunStr = %sRunStr% /A /L="%sLDirName%" | + | { |
+ | sRunStr = %sRunStr% /A /L="%sLDirName%" | ||
+ | sRunStrL = /A /L="%sLDirName%" | ||
+ | } | ||
if (sRDirName != "") | if (sRDirName != "") | ||
− | sRunStr = %sRunStr% /A /R="%sRDirName%" | + | { |
+ | sRunStr = %sRunStr% /A /R="%sRDirName%" | ||
+ | sRunStrR = /A /R="%sRDirName%" | ||
+ | } | ||
if (sRunStr = sTCExe) | if (sRunStr = sTCExe) | ||
Return | Return | ||
if (pidTC2 = "") | if (pidTC2 = "") | ||
{ | { | ||
− | if ( | + | if (boTCSync2nd_RunAsAdmin) |
{ | { | ||
− | ; | + | ; *** run as admin: also workaround for TC "As Administrator" bug up to TC 7.50 pubbeta 2 |
sRunUser := "" | sRunUser := "" | ||
sRunPw := "" | sRunPw := "" | ||
Line 126: | Line 142: | ||
if ErrorLevel | if ErrorLevel | ||
sRunUser := "" | sRunUser := "" | ||
+ | sRunPw := "" | ||
} | } | ||
; | ; | ||
− | Run, %sRunStr%,,, pidTC2 | + | Run, %sRunStr%,,, pidTC2 ; *** single call OK here, no TC bug when opening new instance; also: 2 calls would open 2 new instances! |
RunAs | RunAs | ||
} | } | ||
else | else | ||
{ | { | ||
− | Run, %sRunStr% | + | if (boUseFix_ArchiveFocusNoOpen) and not (boCdToFolderOnly) ; *** separate calls for each TC panel (left/right), workaround for TC bug ("/A") |
+ | { | ||
+ | Run, %sTCExe% %sRunStrR% ; *** right side first - on this side "/A" fails using a single command line + existing TC instance (TC 7.22a x86 @ Win7 x64) | ||
+ | ; *** second run on existing instance may fail, if TC is called twice in a row too fast! | ||
+ | Sleep, 200 ; *** >= 120 needed for TC 9.50b13 (may vary) | ||
+ | Run, %sTCExe% %sRunStrL% | ||
+ | } else { | ||
+ | Run, %sRunStr% | ||
+ | } | ||
} | } | ||
; | ; | ||
Line 146: | Line 171: | ||
global boCdToFolderOnly, iListerTimeOutSecs | global boCdToFolderOnly, iListerTimeOutSecs | ||
WinWaitNotActive, ahk_class TCmpForm,, %iListerTimeOutSecs% ; wait for starting lister, timeout in seconds, set in hotkey (^#t) | WinWaitNotActive, ahk_class TCmpForm,, %iListerTimeOutSecs% ; wait for starting lister, timeout in seconds, set in hotkey (^#t) | ||
− | |||
− | |||
SetTitleMatchMode, 1 | SetTitleMatchMode, 1 | ||
− | + | IfWinNotActive, ahk_class TLister ; *** Lister hasn't started - no file on this panel side? | |
{ | { | ||
+ | Return, % "" | ||
+ | } else { | ||
WinGetActiveTitle, sWinTitle | WinGetActiveTitle, sWinTitle | ||
WinClose, %sWinTitle% | WinClose, %sWinTitle% | ||
Line 160: | Line 185: | ||
} | } | ||
} | } | ||
− | |||
iNamePos := (InStr(sWinTitle, "[", false, 1) + 1) | iNamePos := (InStr(sWinTitle, "[", false, 1) + 1) | ||
iNameEnd := (InStr(sWinTitle, "]", false, 0) - 1) ; *** InStr start=0: search in reverse | iNameEnd := (InStr(sWinTitle, "]", false, 0) - 1) ; *** InStr start=0: search in reverse | ||
Line 167: | Line 191: | ||
sReturn := SubStr(sWinTitle, iNamePos, (InStr(sWinTitle, "\", false, 0) + 1) - iNamePos) ; *** InStr start=0: search in reverse | sReturn := SubStr(sWinTitle, iNamePos, (InStr(sWinTitle, "\", false, 0) + 1) - iNamePos) ; *** InStr start=0: search in reverse | ||
} else { ; folder + file name | } else { ; folder + file name | ||
− | |||
sReturn := SubStr(sWinTitle, iNamePos, iNameEnd - iNamePos + 1) ; *** _[123abc] 8 - 3 ; ; *** fixed multimedia viewer mode (universal: terminate at last "]") | sReturn := SubStr(sWinTitle, iNamePos, iNameEnd - iNamePos + 1) ; *** _[123abc] 8 - 3 ; ; *** fixed multimedia viewer mode (universal: terminate at last "]") | ||
} | } |
Latest revision as of 19:11, 18 January 2020
; ////////////////////////////////////////////////////////////////////////////
; // TC_Sync_OpenFolderInSecondTC.ahk V0.30 (W) StatusQuo 2008 - 2020
; // http://ghisler.ch/board/viewtopic.php?t=19713
; //
; // open another TC instance
; // with the folders of the currently selected file in cm_FileSync (Synchronize directories)
; // via hotkey: Ctrl+Win+T
; ////////////////////////////////////////////////////////////////////////////
#SingleInstance, Force
Return
#IfWinActive, ahk_class TCmpForm
; F4::
^#t:: ; hotkey = Ctrl+Win+T: Open selected files from SyncFiles in second TC instance (reused by recurring calls)
; please adjust path here; %COMMANDER_PATH% is not available outside of TC
sTCExe := "C:\totalcmd\TOTALCMD.EXE"
boAlwaysOpenNewTask := 0 ; set to 1 to not re-use TC target window (always open a new one)
boCdToFolderOnly := 0 ; set to 0 to have cursor placed on selected files; uses Lister (experimental?)
iListerTimeOutSecs := 1 ; if using Lister: timeout after n seconds of not appearing Lister
boTCSync2nd_RunAsAdmin := 1 ; set to 1 to start 2nd TC as other user, e.g. administrator
boUseFix_ArchiveFocusNoOpen := 0 ; fixes a TC bug when using /A /O (present up to TC 9.50b13)
; - slower, calls target TC twice (for left/right panel separately)
; - set to 1 to use it
; - set to 0 if one of the panels is not always refreshing
; static pidTC2
;
LB_GETCARETINDEX := 0x019F
LB_GETTEXT := 0x0189
ControlGetFocus, Panel_id
SendMessage, %LB_GETCARETINDEX%, 0, 0, %Panel_id%
LB_CursorPosition := ErrorLevel ; *** 0 = line #1 (zero-based)
LB_CursorPosition_Save := LB_CursorPosition ; *** for debugging only
VarSetCapacity(LB_String, 1024, 0)
SendMessage, %LB_GETTEXT%, %LB_CursorPosition%, &LB_String, %Panel_id%
LB_CursorLine := LB_String
;
Loop ; *** find subdirectory *** only working for VISIBLE lines - after scrolling dir line out of view, LB_GETTEXT fails! (Win2k, TC8.51a)
{
If (SubStr(LB_String, StrLen(LB_String)) = "\")
or (LB_CursorPosition < 0)
Break
SendMessage, %LB_GETTEXT%, %LB_CursorPosition%, &LB_String, %Panel_id%
LB_CursorPosition -= 1
}
ControlGetText, sLPath, TEdit2, ahk_class TCmpForm ; *** TC <= 7.04a
ControlGetText, sRPath, TEdit1, ahk_class TCmpForm ; *** TC <= 7.04a
boTC75 := 0 ; TC <= 7.04a
if (sLPath . sRPath = "")
{
ControlGetText, sLPath, TAltEdit2, ahk_class TCmpForm ; *** TC >= 7.50 rc1
ControlGetText, sRPath, TAltEdit1, ahk_class TCmpForm ; *** TC >= 7.50 rc1
if (sLPath . sRPath != "")
boTC75 := 1 ; *** TC >= 7.50 rc1
}
if (boTC75) ; *** TC >= 7.50 rc1
{
if (SubStr(LB_String, 1, 7) = "DIR EQ ")
LB_String := SubStr(LB_String, 8)
if (SubStr(LB_String, 1, 8) = "DIR DEL ")
LB_String := SubStr(LB_String, 9)
if (SubStr(LB_String, 1, 11) = "DIR L to R ")
LB_String := SubStr(LB_String, 12)
if (SubStr(LB_String, 1, 11) = "DIR R to L ")
LB_String := SubStr(LB_String, 12)
}
;
LB_SubDir := LB_String
if (InStr(LB_SubDir, "|") > 0) and (StrLen(LB_SubDir) >= 32) ; *** minimum string lenth: "L L to R F 1 01.02.12 11:22:33 |"
LB_SubDir := "" ; *** fix: if no subdir exists: LB_SubDir = LB_CursorLine of FIRST file line (also with cursor on a line below the first)
;
; *** TC 8.51a / 9.22a:
; *** LB_CursorLine = 2 EQ both.zip 1.118 17.01.20 10:30:32 | 17.01.20 10:30:32 1.118 both.zip
; *** LB_CursorLine = L L to R left.zip 1.118 17.01.20 10:30:32 |
; *** LB_CursorLine = R R to L | 17.01.20 10:30:32 1.118 right.zip
; *** LB_CursorLine = R DEL | 17.01.20 10:30:32 1.118 right.zip
sLDirName := "" ; *** get left path name
if (not boCdToFolderOnly)
and (SubStr(LB_CursorLine, 1, 1) != "R") ; and (SubStr(LB_CursorLine, StrLen(LB_CursorLine), 1) != "\")
{
Send, {F3}
sLDirName := GetActiveTCListerPath()
}
If (sLDirName = "")
sLDirName := sLPath . LB_SubDir
; ---
sRDirName := "" ; *** get right path name
if (not boCdToFolderOnly) ; *** do not focus file
and (SubStr(LB_CursorLine, 1, 1) != "L") ; and (SubStr(LB_CursorLine, StrLen(LB_CursorLine), 1) != "\")
{
Send, +{F3}
sRDirName := GetActiveTCListerPath()
}
If (sRDirName = "")
sRDirName := sRPath . LB_SubDir
; ---
If (boAlwaysOpenNewTask)
or (not WinExist("ahk_pid " . pidTC2))
pidTC2 := ""
if not (pidTC2 = "")
{
WinActivate, ahk_pid %pidTC2%
sTCExe = %sTCExe% /O
}
;
sRunStr := sTCExe
sRunStrL := ""
sRunStrR := ""
if (sLDirName != "")
{
sRunStr = %sRunStr% /A /L="%sLDirName%"
sRunStrL = /A /L="%sLDirName%"
}
if (sRDirName != "")
{
sRunStr = %sRunStr% /A /R="%sRDirName%"
sRunStrR = /A /R="%sRDirName%"
}
if (sRunStr = sTCExe)
Return
if (pidTC2 = "")
{
if (boTCSync2nd_RunAsAdmin)
{
; *** run as admin: also workaround for TC "As Administrator" bug up to TC 7.50 pubbeta 2
sRunUser := ""
sRunPw := ""
InputBox, sRunUser, TC RunAs: Enter Administrator user name, Logon user name (Administrator):,,, 120,,,,, Administrator
if ErrorLevel
sRunUser := ""
if (sRunUser != "")
InputBox, sRunPw , TC RunAs: Enter Administrator password, Logon password for "%sRunUser%":,,, 120
if ErrorLevel
sRunUser := ""
if (sRunUser != "")
RunAs, %sRunUser%, %sRunPw%
if ErrorLevel
sRunUser := ""
sRunPw := ""
}
;
Run, %sRunStr%,,, pidTC2 ; *** single call OK here, no TC bug when opening new instance; also: 2 calls would open 2 new instances!
RunAs
}
else
{
if (boUseFix_ArchiveFocusNoOpen) and not (boCdToFolderOnly) ; *** separate calls for each TC panel (left/right), workaround for TC bug ("/A")
{
Run, %sTCExe% %sRunStrR% ; *** right side first - on this side "/A" fails using a single command line + existing TC instance (TC 7.22a x86 @ Win7 x64)
; *** second run on existing instance may fail, if TC is called twice in a row too fast!
Sleep, 200 ; *** >= 120 needed for TC 9.50b13 (may vary)
Run, %sTCExe% %sRunStrL%
} else {
Run, %sRunStr%
}
}
;
Return
#IfWinActive
; =============
; === TC Lister: grab path/file names of file in active lister window
GetActiveTCListerPath()
{
global boCdToFolderOnly, iListerTimeOutSecs
WinWaitNotActive, ahk_class TCmpForm,, %iListerTimeOutSecs% ; wait for starting lister, timeout in seconds, set in hotkey (^#t)
SetTitleMatchMode, 1
IfWinNotActive, ahk_class TLister ; *** Lister hasn't started - no file on this panel side?
{
Return, % ""
} else {
WinGetActiveTitle, sWinTitle
WinClose, %sWinTitle%
Loop, 10 ; *** for big files: wait until load+close is done
{
If !WinExist( sWinTitle )
Break
Sleep, 300
}
}
iNamePos := (InStr(sWinTitle, "[", false, 1) + 1)
iNameEnd := (InStr(sWinTitle, "]", false, 0) - 1) ; *** InStr start=0: search in reverse
If (boCdToFolderOnly) ; folder only
{
sReturn := SubStr(sWinTitle, iNamePos, (InStr(sWinTitle, "\", false, 0) + 1) - iNamePos) ; *** InStr start=0: search in reverse
} else { ; folder + file name
sReturn := SubStr(sWinTitle, iNamePos, iNameEnd - iNamePos + 1) ; *** _[123abc] 8 - 3 ; ; *** fixed multimedia viewer mode (universal: terminate at last "]")
}
Return, %sReturn%
}
/*
;
Back to AutoHotkey