Send User Command to TC from Delphi

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

Moderators: Hacker, petermad, Stefan2, white

Post Reply
olesio
Junior Member
Junior Member
Posts: 54
Joined: 2009-01-22, 15:29 UTC
Location: Poland

Send User Command to TC from Delphi

Post by *olesio »

Hello. I found link on forum to http://ghisler.ch/wiki/index.php/TCUtils.cpp
and I want to translate code to send user commands in TC to Delphi, I did
it like you all see below but it does not work ;/ What I do wrong? I'm only
have Delphi knowledge not C languages. TC is ofcourse running but even
if I change Application.Handle to 0 or CmdArray to PChar(Command) in a
lpData parameter is it still do not work. Nothing happend. Please helpe me
solve this problem. Thanks in advice and sorry for my bad english. My code:

Code: Select all

procedure SendTCUserCommand(Command : string);
var
  I : integer;
  Tc_H : HWND;
  CmdArray : array of Char;
  DataStruct : CopyDataStruct;
begin
  TC_H := FindWindow('TTOTAL_CMD', nil);
  if (TC_H <> 0) and (Command <> '') then
  begin
    SetLength(CmdArray, Length(Command));
    for I := 0 to Length(Command) - 1 do
    begin
      CmdArray[I] := Command[I];
    end;
    DataStruct.dwData := Ord('E') + 256 * Ord('M');
    DataStruct.cbData := Length(Command) + 1;
    DataStruct.lpData := CmdArray; ;
    SendMessage(TC_H, WM_COPYDATA, Application.Handle, Integer(@DataStruct));
  end;
end;
I execute the procedure like this:

Code: Select all

  SendTCUserCommand('cm_FtpNew');
EDIT: and I know comamnds can be send like this (I seen AHK script), but I
wand use OPENTABS command so I need parameters (*.tab path + filename).

Code: Select all

procedure SendTCCommandLikeAhk(CommandID : integer);
var
  Tc_H : HWND;
begin
  TC_H := FindWindow('TTOTAL_CMD', nil);
  if (TC_H <> 0) and (CommandID > 0) then
  begin
    SendMessage(TC_H, 1075, CommandID, 0);
  end;
end;
Best regards: olesio
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

AFAIK you may use WM_COPYDATA only for em_commands and "cd" command for cm_commands, for cm_commands you need to translate them to index (see totalcmd.inc or TC internal command browser) and send this index using SendMessage(TC_H, 1075, index, 0) (e.g. for cm_FtpNew index is 551).

Here was discussed how to send "cd" command, when you want to send em_command, you need just to specify its name and set dwData to Ord('E') + 256 * Ord('M').
olesio
Junior Member
Junior Member
Posts: 54
Joined: 2009-01-22, 15:29 UTC
Location: Poland

Post by *olesio »

Thank you for answer - I thought WM_COPYDATA with 'E' and 'M' is used for
sending all commands like cm_... no only these for user em. Now everything
is ok. Here is my code below. Works compiled as Delphi Console Application.

usercmd.ini entry:

Code: Select all

[em_openirclogstab]
button=
cmd=OPENTABS %COMMANDER_PATH%\irc_logs.tab
Source of tc_cmds.dpr:

Code: Select all

program tc_cmds;

{$APPTYPE GUI}

uses
  Windows, Messages;

procedure SendTCUserCommand(Command : string);
var
  Tc_H : HWND;
  DataStruct : CopyDataStruct;
begin
  TC_H := FindWindow('TTOTAL_CMD', nil);
  if (TC_H <> 0) and (Command <> '') then
  begin
    DataStruct.dwData := Ord('E') + 256 * Ord('M');
    DataStruct.cbData := Length(Command) + 1;
    DataStruct.lpData := PChar(Command);
    SendMessage(TC_H, WM_COPYDATA, 0, Integer(@DataStruct));
  end;
end;

procedure SendTCCommand(CommandID : integer);
var
  Tc_H : HWND;
begin
  TC_H := FindWindow('TTOTAL_CMD', nil);
  if (TC_H <> 0) and (CommandID > 0) then
  begin
    SendMessage(TC_H, 1075, CommandID, 0);
  end;
end;

var
  Tc_H : HWND;
begin
  TC_H := FindWindow('TTOTAL_CMD', nil);
  if TC_H <> 0 then
  begin
    SendTCCommand(4001);
    SendTCUserCommand('em_openirclogstab');
    SetForegroundWindow(TC_H);
  end;
end.
Best regards: olesio
Post Reply