How to Send F5 to TC from my program (see inside)

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

Moderators: Hacker, petermad, Stefan2, white

eitang
Senior Member
Senior Member
Posts: 250
Joined: 2003-05-19, 20:08 UTC
Location: France
Contact:

How to Send F5 to TC from my program (see inside)

Post by *eitang »

I wrote another Delphi (5) program and use the technical advice I received here a couple of days ago,(and it worked!).

I am sending TC from my program

SendMessage(h, TC_Copy_To_Other_Pane, 3101, 1075);

3101 is cm_CopyOtherpanel (Copy to other pane)

What happens is that the F5 detailed windows pops up with the buttons: OK, F2 Queue, Tree, Cancel Etc.

Of course I have to click OK. This is what I want to avoid. Possible ???

Can I send, for example, (3101 OR xyz) for immediate execution ???

TIA,
Best Wishes,

Eitan Gilboa (License #: 17011)
URL: https://eitang.pagesperso-orange.fr/
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

I don't understand what you're sending. AFAIK you should send a message with uMsg=WM_USER+51, wParam=cm_id where cm_id is an internal command number, and lParam value is simply ignored by TC.

However you can wait for copy dialog to be shown and send WM_KEYDOWN with VK_RETURN to it.
eitang
Senior Member
Senior Member
Posts: 250
Joined: 2003-05-19, 20:08 UTC
Location: France
Contact:

Post by *eitang »

MVV,

Thanks for the quick reply !

My sending to TC works fine. What I am using is, as I said, 3101 which copies from source panel to destination panel. This works all right. What I wish to avoid is the TC's F5 (Copy...) window to pop-up and have me click the OK Button. Is there a way to have F5 work without this window ? Just copy no-questions-asked ??? This is my Q. The "OR3 etc. was only and example...

Thanks

>> However you can wait for copy dialog to be shown and send WM_KEYDOWN with VK_RETURN to it

Thanks for the advice, but again I don't know how to send keys to another aplication. I'll have a look around.

Thanks again,
Best Wishes,

Eitan Gilboa (License #: 17011)
URL: https://eitang.pagesperso-orange.fr/
eitang
Senior Member
Senior Member
Posts: 250
Joined: 2003-05-19, 20:08 UTC
Location: France
Contact:

Post by *eitang »

MVV,

Apparently the F5 window (called "Total Commander" isn't found and need also the ClassName which, of course I do not have...

I tried this:

Code: Select all

  const // After the main USES...
  TC_Copy_To_Other_Pane = WM_USER + 51; // for copying marked 
//                                      folders from SOURCE pane to DESTI Pane


VAR
  TC, TC_F5 : HWND; // For Calling TC

TC := FindWindow('TTOTAL_CMD', nil); 
  if IsWindow(TC) then
  begin
    SendMessage(TC, TC_Copy_To_Other_Pane, 3101, 1075); // F5    
    TC_F5 := FindWindowEx(TC_F5, 0, 'Total Commander', nil); // The F5 window needing "Enter"
    if TC_F5 <> 0 then
    begin
      PostMessage(TC_F5, WM_KEYDOWN, VK_RETURN, 0); // Yr Advice
    end;
  end else showmessage('TC not found');
Best Wishes,

Eitan Gilboa (License #: 17011)
URL: https://eitang.pagesperso-orange.fr/
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

Correct way to send cm_CopyOtherpanel:

Code: Select all

SendMessage(0, WM_USER+51, 3101, 0);
This command simply opens copy dialog. And there is no way to pass any parameters to internal commands.
Thanks for the advice, but again I don't know how to send keys to another aplication. I'll have a look around.
You only need to call PostMessage(hdlg, WM_KEYDOWN, VK_RETURN, $01000001), I've checked it just now. Note, you should find dialog handle e.g. by window class (check if it belongs to that process when using FindWindow[Ex]).
eitang
Senior Member
Senior Member
Posts: 250
Joined: 2003-05-19, 20:08 UTC
Location: France
Contact:

Post by *eitang »

MVV,

Thank you very much again.

>> SendMessage(0, WM_USER+51, 3101, 0);
Not working over here. Where is the TC Handle ???

Anyway my SendMessage() works well. Your
>> PostMessage(hdlg, WM_KEYDOWN, VK_RETURN, $01000001);
is doing exactly what "mine" does {PostMessage(TC_F5, WM_KEYDOWN, VK_RETURN, 0);} i.e. nothing.
I believe that the hdlg handle to the F5 window is not working.

How did you calculate your handle ???
how do you find the by window class of a TC window ???


TIA,
Best Wishes,

Eitan Gilboa (License #: 17011)
URL: https://eitang.pagesperso-orange.fr/
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

SendMessage has four parameters: hWnd, uMsg, wParam, lParam where hWnd must be main TC window handle (may be detected as FindWindow('TTOTAL_CMD', nil)), uMsg must be WM_USER+51 (which equals to 1075 and is the same for any internal command -- so your constant name is confusing, I would name such constant e.g. WM_TC_COMMAND), wParam should contain internal command index (3101 in our case -- and I recommend you to define constant with name cm_CopyOtherpanel instead of using direct magic numbers) and lParam should be 0. Why do you pass 1075 as lParam value?

BTW you need PostMessage instead of SendMessage because the latter won't return until dialog is closed.

Next, you should wait for a window with class TInpComboDlg (there are plenty of tools that show information about windows: handles, classes, captions etc) so you need a loop like:

Code: Select all

GetWindowThreadProcessId(hTC, @mainPid);
repeat
    Sleep(100);
    hDlg := 0;
    repeat
        hDlg := FindWindowEx(0, hDlg, 'TInpComboDlg', nil);
        GetWindowThreadProcessId(hDlg, @dlgPid);
    until (hDlg <> 0) and (dlgPid = mainPid);
until hDlg <> 0;
Here I wait until dialog is opened. When I search for its window, I enumerate top-level windows with corresponding class and check that found window belongs to our TC process. Don't forget to debug the code and check that variables receive correct values.

When dialog handle is found, you can post WM_KEYDOWN message to it.
eitang
Senior Member
Senior Member
Posts: 250
Joined: 2003-05-19, 20:08 UTC
Location: France
Contact:

Post by *eitang »

Thank you very much for your time and the lesson. This makes some order in my "trial and eror" learning...

The ( 1075) lParam came from a reply on this forum some time ago. I tried to get the handle of TC with WindowName and failed and then you told me to use ClassName instead. I did and it worked. But you told me the actual TC Classname to use... (TTOTAL_CMD) Now, with the F5 dialog, I don't know how to find this. Maybe TInpComboDlg you mentioned. I'll check.

I am, originally, a DataBase programmer, and system is only a passtime <s>

Anyway, apart from the need to press enter, or click OK, the program now works as I want. I'll read more about this after your very nice explanation. If I get it better good, and if not, not too dramatic...

Thank you very much indeed, MVV.
Best Wishes,

Eitan Gilboa (License #: 17011)
URL: https://eitang.pagesperso-orange.fr/
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

You're welcome. :)

You can try e.g. InqSoft Window Scanner (I'm using it) for checking window classes. Main TC window has class TTOTAL_CMD, copy/move dialog has class TInpComboDlg.

As I said, I tried to post WM_KEYDOWN message with mentioned parameters and it causes dialog to successfully confirm operation.
eitang
Senior Member
Senior Member
Posts: 250
Joined: 2003-05-19, 20:08 UTC
Location: France
Contact:

Post by *eitang »

Thanks.

For the time being I did not make it... Some variables in your sample are obscur to me, like the two pointed to @mainPid and @dlgPid, also GetWindowThreadProcessId is not quite clear... I am not asking you a course on system programming in Delphi, don't worry...

Thanks again
Best Wishes,

Eitan Gilboa (License #: 17011)
URL: https://eitang.pagesperso-orange.fr/
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

Sorry, I thought it would be clear according to Delphi GetWindowThreadProcessId help topic.

Code: Select all

var mainPid, dlgPid: DWORD;
Since multiple TC instances may be run and some of them may have copy dialogs opened, we should check that both windows belong to the same process by comparing process identifiers.

BTW main TC window detection may be a problem too because we don't know which one we need. But FindWindow[Ex] always enumerates windows from top to bottom one so when you start your application from TC, its window will be found first.
eitang
Senior Member
Senior Member
Posts: 250
Joined: 2003-05-19, 20:08 UTC
Location: France
Contact:

Post by *eitang »

MVV,

How nice of you! Thanks. BTW I DL'ed InqSoft - Incredible! Thanks for that as well.

>> Since multiple TC instances may be run ...

Indeed. I gign't think of that. Thanks again.
Best Wishes,

Eitan Gilboa (License #: 17011)
URL: https://eitang.pagesperso-orange.fr/
eitang
Senior Member
Senior Member
Posts: 250
Joined: 2003-05-19, 20:08 UTC
Location: France
Contact:

Post by *eitang »

MVV,

It took some time, but thanks to you the program works as expected, the VK_RETURN acts and all is well !!!

Many many thanks.

One small question: Is there a way to execute the copy (F5) without a warning "Overwrite", "Rename" etc. Regardless of my TC settings ?

Thanks,
Best Wishes,

Eitan Gilboa (License #: 17011)
URL: https://eitang.pagesperso-orange.fr/
User avatar
MVV
Power Member
Power Member
Posts: 8711
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

I doubt that you can copy w/o warnings until you set these options in dialog by window manipulations.

I think you should try shell copy functions if you simply need to copy files...
eitang
Senior Member
Senior Member
Posts: 250
Joined: 2003-05-19, 20:08 UTC
Location: France
Contact:

Post by *eitang »

MVV,

I also doubted it...

I have in my little program two buttons - one to copy through Shell and the other copy with TC.

The reason I added TC is that with TC I can keep the folder's last update date stamp (for newly created ones) whereas the shell systematically assigns NOW to the new folder...

Thanks for clarifying.
Best Wishes,

Eitan Gilboa (License #: 17011)
URL: https://eitang.pagesperso-orange.fr/
Post Reply