AutoHotkey: Send a command to Total Commander (Accurate Version)

From TotalcmdWiki
Jump to navigation Jump to search
;;;;
;;;; Function: TC_@( "cm_NAME" )
;;;;
;;;; Returns: the correct numeric code for use with AutoHotKey's SendMessage, or PostMessage.
;;;;
;;;; Author: Balderstrom, August, 2010
;;;;
;;;;
;;
;;
;;  While this doesn't actually "Send" the commands like the other version listed here. 
;;  That is simply accomplished by AutoHotKey's own functions (Send or PostMessage). 
;;  
;;  The purpose of this script is to be complete in actually returning the correct CODE that is contained within
;;  Total Commander's .INC file, or that can be CALCULATED from the values listed in Total Commander's INC. 
;;  Since as is, the INC cannot be used as a complete reference - it skips over numerical sequences that have
;;  more than 10 or so valid cm_ commands. 
;;
;;  As well, this version does not repeatedly parse the INC to look up the code. It reads the file once. And stores
;;  Most of the values that don't need to be calculated. 
;;
;;  Included below is a function to Test the actual TC_@() Code. As well as the onErrorExit() function which is used.
;;
;;
;;  Example Usage: 
;;      TC_@()     ; Don't forget to initialize! (Read the INC File first to get the definitions ...)
;;	WinActivate, ahk_class TTOTAL_CMD
;;	WinWaitActive, ahk_class TTOTAL_CMD
;;	SendMessage, 0x433, TC_@( "cm_SelectAllFiles" ),,, A
;;
;;  Or similiarly:
;;      TC_@()
;;	SendMessage, 0x433, TC_@( "cm_SelectAllFiles" ),,, ahk_class TTOTAL_CMD
;;
;;

TC_@TEST()
{
    TC_@()
    FileRead, TcmdINC, %ProgramFiles%\TotalCMD\TotalCMD.inc
    matches := 0
    Loop, Parse, TcmdINC, `n, `r
    {
        if( !regExMatch( A_LoopField, "^cm_([a-zA-Z]+)([0-9]+)?=([0-9]+);", iCmd ) )
            continue
        cmdTest := TC_@("cm_" . iCmd1 . iCmd2 )
        if( cmdTest <> iCmd3 )
            MsgBox, DAMNIT: `ncm_%iCmd1%%iCmd2%: %iCmd3% <>`ncm_%iCmd1%%iCmd2%: %cmdTest%
    }
     TC_@("novar")
}

TC_@( cm_cmd="" )
{
    static
    static init := 0
    local iCmd, iCmd1, iCmd2, iCmd3, iTmp, retVal, tmpVar
    if( !init && init := 1 )
    {
        FileRead, TcmdINC, %ProgramFiles%\TotalCMD\TotalCMD.inc
        Loop, Parse, TcmdINC, `n, `r
        {
            if( !regExMatch( A_LoopField, "^cm_([a-zA-Z]+)([0-9]+)?=([0-9]+);", iCmd ) )
                continue
             if( iCmd3 > 6000 && iCmd3 <= 20000)
                continue
            if( iCmd3 > 5000 && iCmd3 <= 5500)
                continue
            else
            if( iCmd3 > 2060 && iCmd3 <= 2120 )    ; cm_GotoDriveA ...
                continue
            else
            if( iCmd3 >= 701 && iCmd3 <= 900 )    ; cm_UserMenu1 ... cm_UserMenu200
                continue
            else
            if( iCmd3 >= 271 && iCmd3 <= 299 )    ; cm_SrcCustomView1 - 29
                continue
            else
            if( iCmd3 >= 171 && iCmd3 <= 199 )    ; cm_RightCustomView1 - 29        
                continue
            else
            if( iCmd3 >=  71 && iCmd3 <= 99 )    ; cm_LeftCustomView1 - 29
                continue

            tmpVar = cm_%iCmd1%%iCmd2%
            StringUpper, tmpVar, tmpVar
            %tmpVar% := iCmd3
        }
        return
    }
    if( !cm_cmd )
        return
    if( !inStr( cm_cmd, "cm_") )
        onErrorExit( TRUE, A_ThisFunc, "UnSupported: Input must be a `cm_` string." )
        
    StringUpper, cm_cmd, cm_cmd
    if( retVal := %cm_cmd% )
        return retVal

    if( RegExMatch( cm_cmd, "^CM_(LEFT|RIGHT|SRC)(CUSTOMVIEW)(\d+)$", iCmd ) )
    {
        onErrorExit(( iCmd3 < 1 || iCmd3 > 29 ), A_ThisFunc, "Illegal value for: " cm_cmd )
        local LEFT := 0, RIGHT := 100, SRC := 200
    return % ( %iCmd1% + iCmd3 + 70 )
    }      

    if( RegExMatch( cm_cmd, "^(CM_)(USERMENU)(\d+)$", iCmd ) )
    {
        onErrorExit(( iCmd3 < 1 || iCmd3 > 200 ), A_ThisFunc, "Illegal value for: " cm_cmd )
    return ( iCmd3 + 700 )
    }
    
    if( RegExMatch( cm_cmd, "CM_(LEFT|RIGHT|SRC|TRG)(ACTIVATETAB|SORTBYCOL)(\d+)", iCmd ) )
    {
        onErrorExit(( iCmd3 < 1 || iCmd3 > 99 ), A_ThisFunc, "Illegal value for: " cm_cmd )
        local SRC := 0, TRG := 100, LEFT := 200, RIGHT := 300
        local ACTIVATETAB := 5000, SORTBYCOL := 6000
    return % ( %iCmd1% + %iCmd2% + iCmd3 )
    }
    
    if( RegExMatch( cm_cmd, "(CM_)(GOTODRIVE)([A-Z])", iCmd ) )
    {
    return ( ASC(iCmd3) + 2000    -4 )
    }
    
    onErrorExit(TRUE, A_ThisFunc, "Variable: " cm_cmd " doesn't exist!" )
}


onErrorExit( msgOK, fn, msg, fn_mod="", delay=3)
{
    if( !msgOK || !msg )
        return 0
    if( fn )
        MsgBox, , % A_ScriptName " :: " fn, % fn "(" fn_mod "): " msg, % delay
    else
        MsgBox, , % A_ScriptName, % msg, % delay
    ErrorLevel := 1
Exit
}