TCC plugins are user-written DLL's that allow you to write your own internal variables, variable functions, and internal commands, and have TCC load them at startup. Plugin names will override existing names, so you can extend and/or replace internal variables and commands. When TCC starts, it will automatically load any plugins in the default directory (the subdirectory PLUGINS\ in the TCC installation directory). The plugins will be loaded before the startup file (TCSTART) are executed.
You can specify a particular plugin to execute by prefixing the function / variable / command name with the plugin name and a $. For example:
echo %_myplugin$variable
echo %@myplugin$func[abc]
myplugin$mycommand
Plugins can be written in any language that can create a Windows DLL. The TCC plugin SDK has samples for Visual C++ and Delphi. The SDK is available on our web site at https://jpsoft.com/downloads/sdk/sdk.zip.
Keystroke Plugins:
You can also write keystroke plugins that will be called for every keystroke entered at the command line. A keystroke plugin can perform actions when a specific key is entered, or even change the key before passing it back to the command processor. Keystroke plugins are called after key aliases, and before TCC looks for the default action for that key.
V24+ only: If the value passed in "nKey" is 0, the key is not a valid Unicode character, and the plugin needs to parse the pszKey string to get the name. The name will be passed in the format:
[Ctrl-][Alt-][Shift-]key
For example:
F12
Ctrl-F1
Ctrl-Alt-Left
Ctrl-Shift-F5
The keystroke plugin can modify the nKey or pszKey value and pass it back to TCC to evaluate the default action for the (new) value. If nKey is != 0, TCC will treat it as a normal Unicode character. If nKey = 0, TCC will evaluate pszKey for a valid keyname.
If the plugin handled the key and doesn't want TCC to do anything more, set nKey to 0 and pszKey to an empty string (write a null to the first byte).
Plugin Syntax:
// PluginInfo structure - returned by plugin in response to GetPluginInfo() call from command processor
// Note that the strings should all be Unicode; if your PlugIn is compiled for ASCII you'll need to use
// the MultiByteToWideChar API to convert the strings before passing them back to TCC
typedef struct {
TCHAR *pszDll; // name of the DLL
TCHAR *pszAuthor; // author's name
TCHAR *pszEmail; // author's email
TCHAR *pszWWW; // author's web page
TCHAR *pszDescription; // (brief) description of plugin
TCHAR *pszFunctions; // comma-delimited list of functions in the
// plugin (leading _ for internal vars, @ for
// var funcs, * for keystroke function,
// otherwise it's a command)
int nMajor; // plugin's major version #
int nMinor; // plugin's minor version #
int nBuild; // plugin's build #
HMODULE hModule; // module handle
TCHAR *pszModule; // module name
} PLUGININFO, *LPPLUGININFO;
// structure passed to plugin functions to monitor keystrokes. A
// keystroke function can be named anything, but must prefix a
// * to its name in the function list (pszFunctions, above).
// If the keystroke plugin handled the keystroke and doesn't want
// to pass it back to TCC, it should set nKey = 0 and pszKey to an empty string.
// The command processor will call the keystroke function with all
// parameters set to 0 just before accepting input for each new
// command line.
// The string pointers are Unicode
typedef struct {
int nKey; // key entered
int nHomeRow; // start row
int nHomeColumn; // start column
int nRow; // current row in window
int nColumn; // current column in window
LPTSTR pszLine; // command line
LPTSTR pszCurrent; // pointer to position in line
int fRedraw; // if != 0, redraw the line
LPTSTR pszKey; // (v24+ only) ASCII name of key (for example, "Ctrl-Alt-Home")
} KEYINFO, *LPKEYINFO;
__declspec(dllexport) BOOL WINAPI InitializePlugin( void ); // called by command processor after loading all plugins
__declspec(dllexport) LPPLUGININFO WINAPI GetPluginInfo( HMODULE hModule ); // called by command processor to get information from plugin, primarily for the names of functions & commands
__declspec(dllexport) BOOL WINAPI ShutdownPlugin( BOOL bEndProcess ); // called by command processor when shutting down
// if bEndProcess = 0, only the plugin is being closed
// if bEndProcess = 1, the command processor is shutting down
The functions listed in "pszFunctions" and called by TCC need to be in the format:
DLLExports INT WINAPI MyFunctionName( LPTSTR pszArguments );
Internal variable names in pszFunctions (and their corresponding functions) must begin with an underscore ('_').
Variable function names in pszFunctions must begin with an @; the corresponding function must be prefixed by "f_". (This allows variable functions to have the same name as internal commands.)
For example:
pszFunctions = "reverse,@reverse"
Entering the name "reverse" on the command line will invoke the command reverse()
Entering the name "@reverse[]" on the command line will invoke the variable function f_reverse()
Variable function names are limited to a maximum of 31 characters.
Internal command names are any combination of alphanumeric characters (maximum 12 characters).
Calling the PlugIn:
For internal variables, pszArguments is empty (for output only)
For variable functions, pszArguments passes the argument(s) to the plugin function
For internal commands, pszArguments is the command line minus the name of the internal command
Returning from the PlugIn:
For internal variables and variable functions, copy the result string over pszArguments. The maximum string length for internal variables and variable functions is 32K (32767 characters + terminating null character).
Internal variables have no meaningful integer return value. For variable functions, the integer return can be:
0 = success
< 0 = failure; error message already displayed by the PlugIn function
> 0 = failure; error value should be interpreted as a system error and
displayed by 4NT / TC
There is a special return value (0xFEDCBA98) that tells the parser to assume that the plugin decided not to handle the variable/function/command. The parser then continues looking for a matching internal, then external. Note that you can use this return value to have your plugin modify the command line and then pass it on to an existing internal variable/function/command!
For internal commands, return the integer result (anything left in pszArgument will be ignored)
Exception Handling:
TCC will trap any exceptions occurring in the plugin, to prevent the plugin from crashing the command processor. An error message will be displayed and the plugin will return an exit code = 2.
Take Command Interface:
Added some new API functions for manipulating the directory history and command history:
DirHistoryStart(void) - returns a pointer to the beginning of the directory history
HistoryStart(void) - returns a pointer to the beginning of the command history
DeleteFromHistory( LPTSTR lpszLine ) - deletes the line from the command history (this is a pointer to the line to be deleted, not a line to be matched!)
If the user tries to display online help with HELP, F1 or Ctrl-F1, TCC will check for a plugin variable, variable function, or command, and if the name matches search for, load and execute a "Help" function in the plugin. The plugin is responsible for displaying its own help. The "Help" function should NOT appear in the plugin's comma-delimited function list in pszFunctions. Help should return 1 if it displayed help (or if it doesn't want TCC to try to display help for this topic). The syntax of the Help function in the plugin should be:
Help( LPTSTR pszName );
If Take Command wants to display usage text, TCC will check for a plugin command, and if the name matches search for, load and execute a "Usage" function in the plugin. The plugin is responsible for displaying its own help. The "Usage" function should NOT appear in the plugin's comma-delimited function list in pszFunctions. The plugin should return a multi-line string containing the command syntax. The first line (terminated by a \r) is displayed in the Take Command status bar. The entire string is displayed as a tooltip popup when the mouse hovers over the status bar message. Usage should return 1 if it wrote something to pszUsage (or if it doesn't want TCC to try to display a usage string). The syntax of the Usage function in the plugin should be:
Usage( LPTSTR pszName, LPTSTR pszUsage );
The TakeCommandIPC function allows plugins to communicate with the controlling Take Command instance. The syntax is:
__declspec(dllexport) int TakeCommandIPC( LPTSTR pszCommand, LPTSTR pszArguments );
The supported commands are:
ACTIVATE
Activate the window whose handle (as a decimal string) is in pszArguments.
CDD
Change the current folder in File Explorer to the directory name in pszArguments.
HELP
Displays the Take Command help for the topic in pszArguments.
HWND
Returns the Take Command window handle in pszArguments.
HVIEW
Returns the handle of the active tab window in pszArguments.
SHORTCUT
Return the name of the shortcut that started Take Command in pszArguments.
SELECTED
Return the currently selected text in pszArguments.
START
Attach a hidden console window whose hex PID (as a string) is in pszArguments.
STARTNA
Attach a hidden console window whose hex PID (as a string) is in pszArguments but don't make it active.
STATUSBAR
Display the message in pszArguments in the status bar.
TCTOOLBAR
Update the Take Command tab toolbar with the TCTOOLBAR command line in pszArguments.
TCFILTER
Return the selected filter in the File Explorer window in pszArguments.
TCFILTER_CMD
Set the selected filter in the File Explorer window to the value in pszArguments.
TCFOLDER
Return the selected folder in the Folders tree control in pszArguments.
TCTAB
Returns 1 if the process ID in pszArguments is running in a TC window
TCTABS
Returns the number of Take Command tab windows.
USAGE
Display the usage message in pszArguments in the status bar. The first line (up to the first CR) is displayed in the
status bar; the rest is displayed in the tooltip if you hover the mouse over the status bar.
WINDOW
Has a number of arguments (specified as a string in pszArguments) to control the Take Command window:
MAX
MIN
HIDE
RES
TRAY
TRANS=n
FLASH=n
DETACH n (where n is the PID of the process to detach)
TOPMOST
NOTOPMOST
TOP
BOTTOM
Filename Completion
When TCC is performing filename ("tab") completion, it will look for a plugin function named TABCOMPLETION. Like TABCOMPLETE scripts, TABCOMPLETION allows you to create plugin functions to customize TCC's filename completion. The syntax is:
INT WINAPI TABCOMPLETION(LPCTSTR Command, LPCTSTR Argument, int Index, LPCTSTR CommandLine);
Command - the name of the command at the beginning of the command line
Argument - the current argument being evaluated
Index - the offset in the command line of the beginning of Argument
CommandLine - the entire command line (double quoted)
When the plugin function finishes, it should return 0 if it processed the completion, and save the result(s) in the TABCOMPLETIONRESULT environment variable. If the function has multiple completion results, they should be added to TABCOMPLETIONRESULT, separated by a space (and double quoted if they contain any whitespace).
TCC will examine the contents of TABCOMPLETIONRESULT; if it contains a single value TCC will insert it at the completion point on the command line. If there are multiple return values, TCC will display a popup window for selection (like the F7 completion window).
TCC will try to find a filename completion script first; if none of them perform the requested completion, TCC will look for the plugin function.
You can specify a particular plugin to execute by prefixing the function / variable / command name with the plugin name and a $. For example:
echo %_myplugin$variable
echo %@myplugin$func[abc]
myplugin$mycommand