AutoHotkey: From FileSync open another TC instance with selected files

From TotalcmdWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
		; ////////////////////////////////////////////////////////////////////////////
		; // 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