Gesammelte Infos über WM_COPYDATA, WM_USER+50 und WM_USER+51 im TC

German support forum

Moderators: white, Hacker, Stefan2

Post Reply
diopter
Junior Member
Junior Member
Posts: 31
Joined: 2017-02-02, 06:42 UTC
Location: Germany

Gesammelte Infos über WM_COPYDATA, WM_USER+50 und WM_USER+51 im TC

Post by *diopter »

Da es bisher noch niemand getan (oder jedenfalls nicht veröffentlicht) hat,
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.
Testprogramm:

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.
Wenn jemand Fehler findet oder über weitere Informationen verfügt, würde ich mich über eine Rückmeldung freuen.
Last edited by diopter on 2022-05-03, 23:17 UTC, edited 5 times in total.
phantom
Power Member
Power Member
Posts: 671
Joined: 2003-11-21, 15:34 UTC

Re: Gesammelte Infos über WM_COPYDATA, WM_USER+50 und WM_USER+51 im TC

Post by *phantom »

Sorry, ich weiß nicht mal was WM_COPYDATA bedeutet.
User avatar
Frizz
Member
Member
Posts: 161
Joined: 2011-06-18, 12:20 UTC

Re: Gesammelte Infos über WM_COPYDATA, WM_USER+50 und WM_USER+51 im TC

Post by *Frizz »

Ja, es wäre schön, frei nach Paul Hindemid, wohin damit?

Ich fand diesen Text: https://www.qsl.net/dl4yhf/yhf_comm/yhf_comm_info.htm
leider nur englisch!
Bei Microsoft: https://docs.microsoft.com/en-us/windows/desktop/dataxchg/wm-copydata

Hier im TC-Forum: viewtopic.php?p=310263#p310263
Gruß Frizz
User avatar
Hacker
Moderator
Moderator
Posts: 13052
Joined: 2003-02-06, 14:56 UTC
Location: Bratislava, Slovakia

Re: Gesammelte Infos über WM_COPYDATA, WM_USER+50 und WM_USER+51 im TC

Post by *Hacker »

diopter,
Sehr schön, dass das mal jemand gesammelt hat, danke! Obwohl, vielleicht wäre das eher was für die Wiki?

Roman
Mal angenommen, du drückst Strg+F, wählst die FTP-Verbindung (mit gespeichertem Passwort), klickst aber nicht auf Verbinden, sondern fällst tot um.
diopter
Junior Member
Junior Member
Posts: 31
Joined: 2017-02-02, 06:42 UTC
Location: Germany

Re: Gesammelte Infos über WM_COPYDATA, WM_USER+50 und WM_USER+51 im TC

Post by *diopter »

Erklärung (für phantom und Frizz) siehe:
TC von außen steuern / SendMessage / WM_USER / WM_COPYDATA
User avatar
Frizz
Member
Member
Posts: 161
Joined: 2011-06-18, 12:20 UTC

Re: Gesammelte Infos über WM_COPYDATA, WM_USER+50 und WM_USER+51 im TC

Post by *Frizz »

Danke, stärkt die Übersicht, hatte ich mit der Aktualisierung von Stefan2 zum 10.09.18 auch gefunden.
Bei nicht so intensiver TC-Nutzung und längeren Threads, ist die Leitung manchmal länger.
Gruß Frizz
diopter
Junior Member
Junior Member
Posts: 31
Joined: 2017-02-02, 06:42 UTC
Location: Germany

Re: Gesammelte Infos über WM_COPYDATA, WM_USER+50 und WM_USER+51 im TC

Post by *diopter »

Update Post #1 auf TC10.50b2
Post Reply