habe ich mich entschlossen, alle Informationen über die Möglichkeiten im TC mit WM_COPYDATA, WM_USER+50 und WM_USER+51 zusammenzusuchen und (hoffentlich) verständlich aufzuschreiben.
Da ich die Infos nicht ungetestet veröffentlichen wollte, und auch um den AHK-Freunden hier mal zu zeigen, wie einfach so etwas in einer richtigen Programmiersprache sein kann, habe ich auch noch eine kleine Delphi-Unit (ohne Infos nur 39 Zeilen) und ein Testprogramm geschrieben:
2022-05-02: Update auf TC10.50b2
Code: Select all
Infos about TC command interface (TC9.00 or higher) ==========================
Commands with WM_COPYDATA: ( [ ] is optional )
CmdType='EM': user commands em_xyz or internal commands cm_xyz
Syntax for CmdStr: 'em_xyz[ <parameters>]'#0 or 'cm_xyz[ <parameters>]'#0
<parameters> with '?' as first char: TC will ask user
Internal commands with parameters: (see also WM_USER+51)
cm_SrcViewModeList=333: [<viewmode>] - view mode menu for source (active) panel
<viewmode>: Name of view mode or 1-based index in view mode list
(use cm_SrcViewMode0=8500 for default view mode)
cm_LeftViewModeList=133: [<viewmode>] - view mode menu for left panel
<viewmode>: Name of view mode or 1-based index in view mode list
cm_RightViewModeList=233: [<viewmode>] - view mode menu for right panel
<viewmode>: Name of view mode or 1-based index in view mode list
cm_List=903: <filename> - View the file with Lister
cm_ListOnly=2934, cm_ListInternalOnly=1006: <filename> - View the file with Lister (from TC10.00b5)
cm_ListMulti, cm_ListInternalMulti:
Does NOT!!! work with <filename>, always shows file under cursor like F3 / Alt+F3
Example: 'em_AppendTabs c:\my.tab'#0
CmdType='CD': change dir(s)
Syntax for CmdStr: ( ['T'] open in new Tab )
[#$EF#$BB#$BF]['<left_path>']#13[#$EF#$BB#$BF]['<right_path>'][#0'T']#0
[#$EF#$BB#$BF]['<source_path>']#13[#$EF#$BB#$BF]['<target_path>']#0'S'['T']#0
(#$EF#$BB#$BF = Unicode UTF-8 BOM, #13 = \r = CR = carriage return)
Examples:
'c:\tc'#13'd:\data'#0 : Left changed to c:\tc , Right changed to c:\data
'c:\tc'#13'#0 : Left changed to c:\tc , Right unchanged
'#13'd:\data'#0 : Left unchanged , Right changed to c:\data
'c:\tc'#13'd:\data'#0'T'#0 : Left new Tab c:\tc , Right new Tab c:\data
'c:\tc'#13'd:\data'#0'S'#0 : Source changed to c:\tc , Target changed to c:\data
'c:\tc'#13'd:\data'#0'ST'#0 : Source new Tab c:\tc , Target new Tab c:\data
Info requests with WM_COPYDATA: since TC8.0b10
CmdType='GA' for ANSI or 'GW' for UTF-16 Unicode answer
Syntax for CmdStr: 'A'#0 : Active panel (returns 'L' or 'R')
'<panel><question>'#0
<panel> : 'L'=left, 'R'=right, 'S'=source, 'T'=target
<question>: 'P'=current path, 'C'=list count, 'I'=caret index,
'N'=name of file under caret
Examples: 'SN'#0 : Name of the focused file in the active panel
'SP'#0 : Current path in the active (source) pane
'TP'#0 : Current path in the target panel
Answer: WM_COPYDATA message with
CmdType='RA' for ANSI or 'RW' for UTF-16 Unicode answer
CmdLen: Length of CmdStr
CmdStr: contains the answer string
Internal commands with WM_USER+51 (1075, $433. 0x433): ( [] is optional )
wparam: numeric value of cm_xyz internal command
lparam: [<parameter>]
Commands with <parameter> : most since TC9.0b
CM_WAIT=-12: <ms> - Wait ms milliseconds
cm_100Percent=910: <width%> - Moves panel separator to width% (percent) of TC window width
<width%>: -1..-100 = left panel to width%
0..100 = active (source) panel to width% (0=100%)
cm_Select=2936: [<itemcount>] - Select <itemcount> file(s) from cursor, go to next
cm_UnSelect=2937: [<itemcount>] - Remove selection of <itemcount> file(s), go to next
cm_Reverse=2938: [<itemcount>] - Reverse selection of <itemcount> file(s), go to next
cm_GoToFirstEntry=2049: [<itemindex>] - Place cursor on <itemindex>+1 folder or file
(zero based, 0 = go to first folder or file)
cm_GoToFirstFile=2050: [<itemindex>] - Place cursor on <itemindex>+1 file
(zero based, 0 = go to first file)
cm_Delete=908: <???> - Delete files (!!!TC9.21a: does always the same as the Del key!!!)
cm_LeftSwitchToThisCustomView=5510: [<colmode>] - Custom columns mode for left panel
<colmode>: 0 = TCdefault, else = what you see in Show / Custom columns mode
cm_RightSwitchToThisCustomView=5511: [<colmode>] - Custom columns mode for right panel
<colmode>: 0 = TCdefault, else = what you see in Show / Custom columns mode
cm_SearchForInCurdir=517: [<drive>] - Opens Search in directory under the cursor
<drive>: numeric value of drive letter (#'A'=65, #'C'=67 ...)
if <drive> is a valid value, search starts in the root of this drive
cm_DirectoryHotlist=526: [<position>] - Directory popup menu
<position>: 1 = mouse pointer pos, 2 = right panel, 3 = left panel
cm_SrcOpenDrives=331: [<drive>] - Opens source (active) drive list
<drive>: numeric value of drive letter (#'A'=65, #'C'=67 ...#'Z') or
#'/'=47:root, #'.'=46:parent dir, #'['=91:nethood
if <drive> is a valid value, the drive will be changed without showing the list
cm_LeftOpenDrives=131: [<drive>] - Opens left drive list
<drive>: numeric value of drive letter (#'A'=65, #'C'=67 ...#'Z') or
#'/'=47:root, #'.'=46:parent dir, #'['=91:nethood
if <drive> is a valid value, the drive will be changed without showing the list
cm_RightOpenDrives=231: [<drive>] - Opens right drive list
<drive>: numeric value of drive letter (#'A'=65, #'C'=67 ...#'Z') or
#'/'=47:root, #'.'=46:parent dir, #'['=91:nethood
if <drive> is a valid value, the drive will be changed without showing the list
cm_VerticalPanels=305: [<state>] - File windows above each other
<state>: 0=toggle, 1=true, 2=false
cm_*Thumbs, cm_*NegOrder: (* stands for Left, Right and Src)
<state>: 0=toggle, 1=true, 2=false
cm_*ByName, cm_*ByExt, cm_*BySize, cm_*ByDateTime: (* stands for Left, Right and Src)
<state>: 0 = toggle direction, 1 = in ascending order, 2 = in descending order,
3 = by THIS column (reverses direction),
4 = additionally sort by THIS column if it is already sorted
by another column (reverses direction),
5 as 4, but sorted in ascending order,
6 as 4, but sorted in descending order
cm_SrcViewModeList=333: [<viewmode>] - view mode menu for source (active) panel
<viewmode>: 1-based index in view mode list (0 = default view mode)
cm_LeftViewModeList=133: [<viewmode>] - view mode menu for left panel
<viewmode>: 1-based index in view mode list (0 = default view mode)
cm_RightViewModeList=233: [<viewmode>] - view mode menu for right panel
<viewmode>: 1-based index in view mode list (0 = default view mode)
cm_rereadsource=540: [<mode>]: (from TC9.50b9)
1: forces refresh even if nothing has changed in that directory, e.g. to re-load icons and overlays
2: re-applies automatic view mode change to current directory
3: 1+2
cm_*Comments, cm_*DirBranch, cm_*DirBranchSel, cm_ToggleAutoViewModeSwitch,
cm_SyncChangeDir, cm_SwitchLongNames, cm_SwitchHidSys, cm_SwitchHid, cm_SwitchSys,
cm_Switch83Names, cm_FtpHiddenFiles, cm_SwitchDirSort, cm_SwitchOverlayIcons,
cm_SwitchWatchDirs, cm_SwitchIgnoreList, cm_SwitchX64Redirection, cm_Vis*: (from TC10.00b1)
[<state>]: 0=toggle, 1=set, 2(or -1)=reset
cm_ZoomIn=2953, cm_ZoomOut=2954: [<percent>]: Zoom thumbnails in 10% steps between 10% and 200% (from TC10.00b1)
cm_*Quickview, cm_*QuickInternalOnly: (* stands for Left, Right and Src) (from TC10.00b2)
[<state>]: 0=toggle, 1=set, 2(or -1)=reset
cm_SeparateQuickview=2941, cm_SeparateQuickInternalOnly=2942: (from TC10.00b2)
[<state>]: 0=toggle, 1=set, 2(or -1)=reset
cm_CloseCurrentTab=3007: [<type>]: 1=close locked tab without confirmation (from TC10.50b1)
cm_CloseAllTabs=3008: [<type>]: 1=close unlocked tabs without confirmation,
2=close also locked tabs with confirmation,
3=close also locked tabs without confirmation
cm_UnloadPlugins=2913: <type>: 0=unload all types, or sum of: 1=packer, 2=file system, 4=lister, 8=content plugins
cm_SwitchColorsByFileType=2957: <state>: 0=toggle, 1=on, 2(or -1)=off
cm_SwitchFileTipWindows=2959: enable/disable showing tooltips (hints) for files (from TC10.50b1):
<state>: 0=toggle, 1=on, 2(or -1)=off
cm_SaveHdrDetailsToFile=2093, cm_SaveHdrDetailsToFileA=2094, cm_SaveHdrDetailsToFileW=2095,
cm_CopyFileDetailsToClip=2036, cm_CopyFpFileDetailsToClip=2037, cm_CopyHdrFileDetailsToClip=2090,
cm_CopyHdrFpFileDetailsToClip=2091, cm_CopyHdrNetFileDetailsToClip=2092,
cm_CopyNetFileDetailsToClip=2038 in normal, comments, and custom columns view (from TC10.50b1):
[<columns>]: 0=all, 1=name+ext, 2=first custom, 4=second custom, 8=third custom etc. (Sum)
### Bugs in TC10.50b2: 1 does same as 0, cm_CopyFileDetailsToClip copies headers too
Examples: SendMessage(TC_hwnd, WM_USER+51, cm_CopySrcPathToClip, 0);
PostMessage(TC_hwnd, WM_USER+51, cm_SrcOpenDrives, #'A');
Info requests with WM_USER+50 (1074, $432): since TC9.0b
wparam: <parameter>
1: returns window handle of control: leftlist,
2: returns window handle of control: rightlist,
3: returns window handle of control: active list,
4: returns window handle of control: inactive list,
5: returns window handle of control: leftheader,
6: returns window handle of control: rightheader,
7: returns window handle of control: leftsize,
8: returns window handle of control: rightsize,
9: returns window handle of control: leftpath,
10: returns window handle of control: rightpath,
11: returns window handle of control: leftinfo,
12: returns window handle of control: rightinfo,
13: returns window handle of control: leftdrives,
14: returns window handle of control: rightdrives,
15: returns window handle of control: leftpanel,
16: returns window handle of control: rightpanel,
17: returns window handle of control: bottompanel,
18: returns window handle of control: lefttree,
19: returns window handle of control: righttree,
20: returns window handle of control: cmdline,
21: returns window handle of control: curdirpanel,
22: returns window handle of control: inplaceedit,
23: returns window handle of control: splitpanel,
24: returns window handle of control: leftdrivepanel,
25: returns window handle of control: rightdrivepanel,
26: returns window handle of control: lefttabs,
27: returns window handle of control: righttabs,
28: returns window handle of control: buttonbar,
29: returns window handle of control: buttonbarvertical,
1000: get active panel, result: 1=left, 2=right,
1001/1002: get number of items in left/right list,
1003/1004: get total number of items (including those hidden by quick filter),
1005/1006: get total number of selected items,
1007/1008: get index of current item (caret),
1009/1010: get index of first item (0 if there is no updir, 1 otherwise),
1011/1012: get index of first file in list (-1 if there are no files)
================================================================================}
unit TCcmd;
interface uses Windows, Messages;
type
TChArr4 = array[1..4] of char;
TTCcmdDATASTRUCT = packed record
CmdType: TChArr4; // dwData: DWORD;
CmdLen : DWORD; // Length of CmdStr, including terminating #0
CmdPtr : Pointer; // Pointer to CmdStr
end;
const CmdGA: TChArr4 = 'GA'#0#0; CmdGW: TChArr4 = 'GW'#0#0;
CmdEM: TChArr4 = 'EM'#0#0; CmdCD: TChArr4 = 'CD'#0#0;
UTF8BOM : array[0..2] of char = #$EF#$BB#$BF;
function TCrequest(CM_Req: Integer): Integer;
function TCcommand(CM_Cmd: Integer; Param: Integer=0): Integer; overload;// if Param < 0 ---> PostMessage
function TCcommand(const aCmdType: TChArr4; const CmdStr: AnsiString): Integer; overload;
var TCwnd, AnswerWnd: THandle; // Wnd handles has to be initialized from main prog
implementation
function TCrequest(CM_Req: Integer): Integer;
begin Result := SendMessage(TCwnd, WM_USER+50, CM_Req, 0) end;
function TCcommand(CM_Cmd: Integer; Param: Integer = 0): Integer;
begin // if Param < 0 ---> PostMessage
if Param >= 0 then Result := SendMessage(TCwnd, WM_USER+51, CM_Cmd, Param)
else Result := Integer(PostMessage(TCwnd, WM_USER+51, CM_Cmd, -Param))
end;
function TCcommand(const aCmdType: TChArr4; const CmdStr: AnsiString): Integer;
var TCcmdDATASTRUCT: TTCcmdDATASTRUCT;
begin
with TCcmdDATASTRUCT do
begin CmdType:= aCmdType; CmdLen:= Length(CmdStr)+1; CmdPtr:= @CmdStr[1] end;
Result := SendMessage(TCwnd, WM_COPYDATA, AnswerWnd, lparam(@TCcmdDATASTRUCT));
end;
end.
Code: Select all
unit TCcmdTestU1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, TCcmd, Hex;
type
TTCcmdForm = class(TForm)
Button1: TButton;
Label1: TLabel;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
public
end;
var TCcmdForm: TTCcmdForm;
implementation
{$R *.dfm}
{$I TotalCmds.inc}
procedure TTCcmdForm.FormShow(Sender: TObject);
begin
AnswerWnd := Self.WindowHandle; TCwnd := FindWindow('TTOTAL_CMD', nil);
if TCwnd = 0 then Label1.Caption := 'Kein TTOTAL_CMD';
Left := 0; Top := 0;
end;
procedure TTCcmdForm.WMCopyData(var Msg: TWMCopyData);
begin
Label1.Caption := PChar(Msg.CopyDataStruct.lpData);
Msg.Result := 1;
end;
procedure TTCcmdForm.Button1Click(Sender: TObject);
begin
// TCcommand(CmdEM, 'em_Test');
// TCcommand(CmdGA, 'SN');
// TCcommand(CmdCD, '\'#13'D:\');
// TCcommand('EM', 'Test');
TCcommand(CmdEM, 'cm_LeftSwitchToThisCustomView Filme');
end;
procedure TTCcmdForm.Button2Click(Sender: TObject);
begin
Label1.Caption := IntToStr(TCcommand(cm_FocusLeft));
TCcommand(cm_GoToFirstEntry, 1)
end;
procedure TTCcmdForm.Button3Click(Sender: TObject);
begin
TCcommand(cm_FocusRight);
Label1.Caption := IntToStr(TCcommand(cm_GoToFirstEntry, 2))
end;
procedure TTCcmdForm.Button4Click(Sender: TObject);
begin
// Label1.Caption := IntToStr(TCrequest(1003)) //get total number of items
// TCcommand(cm_SrcViewModeList, 1);
// TCcommand(cm_LeftSwitchToThisCustomView, 2);
TCcommand(CmdEM, 'em_Test1 "C:\Delphi7\ Neu\Uwe\xx.txt"'); //
end;
procedure TTCcmdForm.Button5Click(Sender: TObject); // Get all selected filenames
var LBwnd: THandle; I, J, L, N: Integer; S: AnsiString;
IntArr: array[1..100] of Integer;
begin
LBwnd := TCrequest(1); // returns window handle of control: leftlist
N := SendMessage(LBwnd, LB_GETSELITEMS, High(IntArr), lparam(@IntArr));
SetLength(S, 2048*10); L := 0;
for I := 1 To N do
begin
if L > Length(S)-2048 then SetLength(S, Length(S) + 2048*10);
J := SendMessage(LBwnd, LB_GETTEXT, IntArr[I], lparam(@S[L+1]));
Inc(L, J); S[L+1] := #10; Inc(L);
end;
SetLength(S, L-1);
Label1.Caption := S;
end;
end.