[Autohotkey] Activate the tab if the folder already open in Total Commander

Discuss and announce Total Commander plugins, addons and other useful tools here, both their usage and their development.

Moderators: white, Hacker, petermad, Stefan2

Post Reply
valuex
Junior Member
Junior Member
Posts: 25
Joined: 2014-12-25, 13:53 UTC

[Autohotkey] Activate the tab if the folder already open in Total Commander

Post by *valuex »

Function:
to open file or folder in Total Commander's existed tabs
Feature:
1. if the InputPath is a folder and the folder already open in TC, activate the corresponding tab; else, open a new tab
2. if the InputPath is a file and the folder where the file locates in already open in TC, activate the corresponding tab, close it, and then reopen a tab with the folder open and the file selected.
How to use:
1. in usercmd.ini, set the following user command

Code: Select all

[em_savealltabs]
button=wcmicons.dll,10
cmd=SAVETABS2
param="%|commander_path|\User\SAVETABS2.tab"
[em_focusfile]
button=wcmicons.dll,10
cmd=CD
param="D:\SoftX\TotalCommander11\TCMatch.ini"

2. put the script in the directory of TC, and pass the file or folder path to this script.

As you can see here, the implementation is not beautiful. i,e. a temp file SAVETABS2.tabis needed, a tab needs to be reopen for file selection.
I'd like to see that TC will have a command line switch to do so in the future.

Code: Select all

fpath:=""
loop A_Args.Length
{
    fpath:=fpath . A_Args[A_Index] . " "
}
fpath:=Trim(fpath)  ; remove the last space
SpecialFolder := RegExMatch(fpath, "::\{.*\}")  ; ::{26EE0668-A00A-44D7-9371-BEB064C98683}  control
DiskDrive:=RegExMatch(fpath, '([A-Z]:)\"',&DrivePath) ; drive 
if (SpecialFolder)
    Run "explorer.exe " . fpath   ; for special folders, open it with default explorer
else if (DiskDrive)
{
    fpath:=DrivePath[1] . "\"
    TC_Open(fpath)
}
else
    TC_Open(fpath)
return

TC_Open(InputPath)
{
    TC_Path:=IsScriptInTCDir()
    InPutType:=IsInputFileOrFolder(InputPath)  ; 0- not exist;1 - Folder; 2- File
    IsTC_Active:=AOR("ahk_class TTOTAL_CMD",TC_Path) 

    if(!TC_Path or !InPutType or !IsTC_Active) 
        return

    TC_OpenTabsFile:=A_ScriptDir . "\User\SAVETABS2.tab"
    ReOutput(TC_OpenTabsFile)
    ; get open tabs number in active panel
    AcTabs:=IniRead(TC_OpenTabsFile,"activetabs")
    AcTabNum:=IniRead(TC_OpenTabsFile,"activetabs","activetab")
    AcTabKeyName:=String(AcTabNum) . "_path"
    AcTabPath:=IniRead(TC_OpenTabsFile,"activetabs",AcTabKeyName)
    ; MsgBox AcTabPath
    iTabExist:=false
    if(InPutType=1)  ; input is folder
    {
        iAcTab:=IsFolderInActiveTab(AcTabPath,InputPath,AcTabNum)
        if(iAcTab)
            iTab:=iAcTab
        else
            iTab:=IsFolderOpenInTabs(AcTabs,InputPath)  
   
        if(iTab)
        {
            xsTCCommand:=5000+iTab  ; in TotalCMD.inc, source tab id starts from 5001
            SendMessage( 1075, xsTCCommand, 0, , "ahk_class TTOTAL_CMD")
        }
        else
        {
            ; run tc to open a new tab for input path
            tc_cmd:=TC_Path . " /O /T /S /L= " . DoubleQuote(InputPath)
            run tc_cmd
        }
    }
    else  ; input is file
    {
        SplitPath InputPath, , &dir
        iAcTab:=IsFolderInActiveTab(AcTabPath,dir . "\",AcTabNum)
        if(iAcTab)
            iTab:=iAcTab
        else
            iTab:=IsFolderOpenInTabs(AcTabs,dir . "\")    
        if(iTab)
        {
            xsTCCommand:=5001+iTab  ; in TotalCMD.inc, source tab id starts from 5001
            SendMessage( 1075, xsTCCommand, 0, , "ahk_class TTOTAL_CMD") ; go to tab
            GotoFile(InputPath)
        }
        else
        {
            tc_cmd:=TC_Path . " /O /T /A /S /L= " . DoubleQuote(InputPath)
            run tc_cmd
        }
    }

    GotoFile(path)
    {
        user_cmd_ini:=A_ScriptDir . "\usercmd.ini"
        SecName:="em_focusfile"
        IniWrite(path,user_cmd_ini,SecName,"param")
        SendTCUserCommand("em_focusfile")
    }

    AOR(WinTitle,WinExe)
    {
        if(WinExist(WinTitle))
        {
            WinActivate(WinTitle)
            WinA:=WinWaitClass("TTOTAL_CMD")
            return WinA ? true: false
        }
        else
        {
            Run WinExe
            WinWaitActive(WinTitle,,5)
            WinA:=WinWaitClass("TTOTAL_CMD")
            return WinA ? true: false
        }
    }
    WinWaitClass(WinClass)
    {
        loop(100)
        {
            aClass:=WinGetClass("A")
            if(StrCompare(aClass,WinClass)=0)
                return true
            else
                Sleep(100)
        }
        return false
    }
    IsInputFileOrFolder(FilePattern)
    {
      AttributeString := FileExist(FilePattern)
      if(InStr(AttributeString,"D"))
        return 1 ;"Folder"
      else if(AttributeString) 
        return 2 ;"File"
      else
        return 0 ;AttributeString: empty means no file exsits
    }
    IsScriptInTCDir()
    {
        ; check whether this script in the same directory as Total Commander main program
        TC64:=A_ScriptDir . "\Totalcmd64.exe"
        TC32:=A_ScriptDir . "\Totalcmd.exe"
        if A_Is64bitOS AND FileExist(TC64)
            TC:=DoubleQuote(TC64)
        else if   FileExist(TC32)
            TC:=DoubleQuote(TC32)
        else
        {
            MsgBox "This script shall be put in the directory of Totalcmd.exe!"
            return ""
        }
        return TC
    }
    
    IsFolderOpenInTabs(ActiveTabs,InputPath)
    {
        ; loop to see if there is any tab already exist
        ArrAcTabs:=StrSplit(ActiveTabs,"`n","`r")
        AcTabsNum:=ArrAcTabs.Length-1
        loop AcTabsNum
        {
            i:=Floor((A_Index-1)/2)  ; in SAVETABS2.tab, tab id starts from 0
            iTabIndex:=String(i) . "_path"
            ThisLine:=ArrAcTabs[A_Index]
            ThisLineID:= GetTabID(ThisLine) 
            ThisLinePath:= GetTabPath(ThisLine) 
            if(!InStr(ThisLineID,iTabIndex))
                continue
            if(StrCompare(InputPath,ThisLinePath)=0)
            {
                TabIndex:=StrSplit(ThisLine,"_")[1]
                return TabIndex+1
            }
        }
        return false
    }
    IsFolderInActiveTab(ActiveTabPath,InputPath,AcTabNumber)
    {
        if(StrCompare(InputPath,ActiveTabPath)=0)
            return AcTabNumber
        else
            return false
    }
    GetTabID(iniLine)
    {
        ; to the left of =, like 0_path, 1_path
        EqualPos:=InStr(iniLine,"=")
        TabID:=SubStr(iniLine,1,EqualPos-1)
        return TabID
    }
    GetTabPath(iniLine)
    {
     EqualPos:=InStr(iniLine,"=")
     TabPath:=SubStr(iniLine,EqualPos+1)
     return TabPath
    }
    ReOutput(TC_OpenTabsFile)
    {
        if(FileExist(TC_OpenTabsFile))
            FileDelete TC_OpenTabsFile
    
        ; output open tab list
        SendTCUserCommand("em_savealltabs")
        loop 10
        {
            Sleep(200)
            if(FileExist(TC_OpenTabsFile))
                break
        }
    }
    DoubleQuote(strInput)
    {
        return Chr(34) . strInput . Chr(34)
    }
}

SendTCUserCommand(userCommand) 
{
    ; https://www.autohotkey.com/boards/viewtopic.php?p=538463&sid=4471e03917209854441ac07ebdc70901#p538463
    static EM := 19781, WM_COPYDATA := 0x4A
    ansiBuf := Buffer(StrPut(userCommand, 'CP0'))
    StrPut(userCommand, ansiBuf, 'CP0')
    COPYDATASTRUCT := Buffer(A_PtrSize * 3)
    NumPut('Ptr', EM, 'Ptr', ansiBuf.size, 'Ptr', ansiBuf.ptr, COPYDATASTRUCT)
    MsgResult:=SendMessage( WM_COPYDATA,, COPYDATASTRUCT,, 'ahk_class TTOTAL_CMD')
    return MsgResult
}


Last edited by valuex on 2023-09-24, 02:53 UTC, edited 1 time in total.
User avatar
white
Power Member
Power Member
Posts: 4623
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

Re: [Autohotkey] Activate the tab if the folder already open in Total Commander

Post by *white »

Moderator message from: white » 2023-09-18, 14:47 UTC

Thread moved.
From: Total Commander (English)
To: Plugins and addons: devel.+support (English)
Post Reply