total commander send commands via SendMessage

Just starting out? Need help? Post your questions and find answers here.
User avatar
freepurebasic
Enthusiast
Enthusiast
Posts: 123
Joined: Fri Sep 24, 2010 12:02 pm
Location: world wide web

total commander send commands via SendMessage

Post by freepurebasic »

Code: Select all

Structure FindWindowData 
  hFW.l ; variable to store a handle 
  sFW.s ; variable to store a Window name 
  cFW.s ; variable to store a window class name 
EndStructure 

Global NewList FindWindow.FindWindowData() 
Global NewList FindChild.FindWindowData() 


Procedure.l EnumWindowsProc(hFind, lParam) 
  WindowName.s = Space(255) 
  WindowClass.s = Space(255) 
  If GetWindowText_(hFind, WindowName, 255) 
    Result = GetClassName_(hFind, WindowClass, 255) 
    AddElement(FindWindow()) 
    FindWindow()\hFW = hFind 
    FindWindow()\sFW = WindowName 
    FindWindow()\cFW = WindowClass 
  EndIf 
  ProcedureReturn 1 
EndProcedure 



Procedure.s totalcmdname()
If EnumWindows_(@EnumWindowsProc(), 0) 
    ResetList(FindWindow()) 
    While NextElement(FindWindow()) 
      tmp.s=FindWindow()\sFW
      If((tmp<>"Total Commander")And(FindString(tmp,"Total Commander",1)>0))
        ProcedureReturn tmp
      EndIf
      ClearList(FindChild()) 
    Wend 
EndIf
ProcedureReturn ""  
EndProcedure  


Global totalcmdnameis.s=totalcmdname()


Procedure SendKeys(handle,window$,keys$)
  If window$<>"" : handle=FindWindow_(0,window$) : EndIf ; Use window$ instead of handle.
  If IsWindow_(handle)=0 ; Does the target window actually exist?
    ProcedureReturn 0 ; Nope, so report 0 for failure to type.
  Else
    ; This block gives the target window the focus before typing.
    thread1=GetWindowThreadProcessId_(GetForegroundWindow_(),0)
    thread2=GetWindowThreadProcessId_(handle,0)
    If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#True) : EndIf
    SetForegroundWindow_(handle) ; Target window now has the focus for typing.
    Sleep_(125) ; 1/8 second pause before typing to prevent fast CPU problems.
    ; Now the actual typing starts.
    keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT key before typing.
    keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL key before typing.
    keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT key before typing.
    keybd_event_(#VK_LWIN,0,#KEYEVENTF_KEYUP,0) ; Release WINDOWS key before typing.
    For r=1 To Len(keys$)
      vk=0 : vk$=Mid(keys$,r,1)
      If vk$="{" ; Special key found.
        s=FindString(keys$,"}",r+1)-(r+1) ; Get length of special key.
        s$=Mid(keys$,r+1,s) ; Get special key name.
        Select s$ ; Get virtual key code of special key.
          Case "ALTDOWN" : keybd_event_(#VK_MENU,0,0,0) ; Hold ALT down.
          Case "ALTUP" : keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT.
          Case "BACKSPACE" : vk=#VK_BACK
          Case "CONTROLDOWN" : keybd_event_(#VK_CONTROL,0,0,0) ; Hold CONTROL down.
          Case "CONTROLUP" : keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL.
          Case "DELAY" : vk=0 : Sleep_(1000) ; Delay typing for one second.
          Case "DELETE" : vk=#VK_DELETE
          Case "DOWN" : vk=#VK_DOWN
          Case "END" : vk=#VK_END
          Case "ENTER" : vk=#VK_RETURN
          Case "ESCAPE" : vk=#VK_ESCAPE
          Case "F1" : vk=#VK_F1
          Case "F2" : vk=#VK_F2
          Case "F3" : vk=#VK_F3
          Case "F4" : vk=#VK_F4
          Case "F5" : vk=#VK_F5
          Case "F6" : vk=#VK_F6
          Case "F7" : vk=#VK_F7
          Case "F8" : vk=#VK_F8
          Case "F9" : vk=#VK_F9
          Case "F10" : vk=#VK_F10
          Case "F11" : vk=#VK_F11
          Case "F12" : vk=#VK_F12
          Case "HOME" : vk=#VK_HOME
          Case "INSERT" : vk=#VK_INSERT
          Case "LEFT" : vk=#VK_LEFT
          Case "PAGEDOWN" : vk=#VK_NEXT
          Case "PAGEUP" : vk=#VK_PRIOR
          Case "PRINTSCREEN" : vk=#VK_SNAPSHOT
          Case "RIGHT" : vk=#VK_RIGHT
          Case "SCROLL" : vk=#VK_SCROLL
          Case "SPACE" : vk=#VK_SPACE
          Case "SHIFTDOWN" : shifted=1 : keybd_event_(#VK_SHIFT,0,0,0) ; Hold SHIFT down.
          Case "SHIFTUP" : shifted=0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT.
          Case "TAB" : vk=#VK_TAB
          Case "UP" : vk=#VK_UP
          Case "WINDOWS" : vk=#VK_LWIN
        EndSelect
        If Left(s$,3)<>"ALT" And Left(s$,7)<>"CONTROL" And Left(s$,5)<>"SHIFT"
          If vk<>0
            keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the special key.
          EndIf
        EndIf
        r+s+1 ; Continue getting the keystrokes that follow the special key.
      Else
        vk=VkKeyScanEx_(Asc(vk$),GetKeyboardLayout_(0)) ; Normal key found.
        If vk>303 And shifted=0 : keybd_event_(#VK_SHIFT,0,0,0) : EndIf ; Due to shifted character.
        keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the normal key.
        If vk>303 And shifted=0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) : EndIf ; Due to shifted character.
      EndIf
    Next
    If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#False) : EndIf ; Finished typing to target window!
    keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT key in case user forgot.
    keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL key in case user forgot.
    keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT key in case user forgot.
    keybd_event_(#VK_LWIN,0,#KEYEVENTF_KEYUP,0) ; Release WINDOWS key in case user forgot.
    ProcedureReturn 1 ; Report successful typing!  :)
  EndIf
EndProcedure

Global hInput
Procedure SendConsole(command.l)
   PostMessage_(hInput,#WM_USER+51,command,0)
EndProcedure





hInput = FindWindow_(0,totalcmdnameis)
If hInput = 0
  Debug "Error, command prompt not open or string mismatch!"
Else
  SendConsole(907)
 Delay(10)
keybd_event_(18,#VK_A,#KEYEVENTF_KEYUP,0) 
  SendKeys(0,totalcmdnameis,"it_think_is_works_but_i_am_not_sure")
EndIf






i modified this :

Code: Select all

/* 8/16/2004
 *
 * FileForum.ru :
 *     http://www.fforum.ru/index.php?s=390d85f944c93d3690cf437b3c3d0b8a&act=ST&f=26&t=4817&unread=&st=0&
 *
 * You can send TC the following command:  
 *
 *     wm_InvokeMenuCommand=WM_USER+51
 *
 * with WPARAM set to the command you want to pass to TC.
 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <windows.h>

//#define DEBUG

#define TCCP_VER    "0.1b"
#define TCCP_DATE   "18.08.2004"

#define WM_USER_TC  WM_USER+51


#define PROG_LOGO \
"Total Commander Command Poster version " TCCP_VER ", " TCCP_DATE ".\n" \
"Written by Oleg Bondar, mailto:hobo@hobo.yaransk.ru. \n" \
"Posts command(s) to TC window by number or name defined in Totalcmd.inc\n" \
"using function PostMessage() Win32 API with WM_USER+51 and wParam=cmd.\n\n"

#define PROG_USAGE \
"Usage:\n" \
"    tccp <cmd> [<cmd>...] [-i<tc_inc>] [-s] [-t<class_name>]\n" \
"\n" \
"<cmd> - numeric code (dec) or name of command,\n" \
"        e.g. 690 or cm_About for \"About\" box\n" \
"   -i - parse command code from file <tc_inc>, e.g. -ic:\\wincmd\\Totalcmd.inc\n" \
"        default: Totalcmd.inc in working directory\n" \
"   -s - use SendMessage() function instead of PostMessage()\n" \
"   -t - TC main window class; in version 6.03 and default is TTOTAL_CMD\n" \
"   -? - help\n" \
"\n" \
"ERRORLEVEL: 0 - success or TC not started, non zero - some (m.b. unknown) error.\n" \
"\n" \
"Switches and command names are NOT case sensitive. It\'s order - arbitrary.\n" \
"Program NOT tested with file names contains non-ASCII chars.\n" \
"Message(s) will be sent to FIRST found copy of Total Commander ONLY.\n"


static int  *TC_commands = NULL;                    /* Help/About Total Commander */
static int  use_Send     = 0;                       /* !0 - use SendMessage(), 0 - PostMessage() */
static char inc_path[MAX_PATH]  = "Totalcmd.inc";   /* File with command codes names */
static char TC_class[MAX_PATH]  = "TTOTAL_CMD";     /* Tatal Commander main window class */


extern int main(int argc, char *argv[])
{
    HWND    tcwnd;
    int     i, j, cmdc = 0, rc = 0;
    char    *s, tcwn[256];

    /* parse switches and count commands */
    for(i = 1, cmdc = 0; i < argc; ++i) {
        s = argv[i];
        if(*s != '-') {
            ++cmdc;
            continue;
        }
        ++s;
        switch(*s) {
            case 'i': case 'I': strcpy(inc_path, s+1); break;

            case 's': case 'S': use_Send = 1; break;

            case 't': case 'T': strcpy(TC_class, s+1); break;

            case '?':
            printf(PROG_LOGO PROG_USAGE);
            rc = 0;
            goto stop;
            break;

            default:
            printf("Invalid switch -%s. Use tccp -? for help.\n", s);
            rc = 1;
            goto stop;
        }
    }
    if(!cmdc) {
        printf(PROG_LOGO PROG_USAGE);
        rc = 1;
        goto stop;
    }
    if(!(TC_commands = malloc(cmdc * sizeof(int *)))) {
        printf("Can not alloc memory.\n");
        rc = 1;
        goto stop;
    }

    /* parse command */
    for(i = 1, j = 0; i < argc; ++i) {
        s = argv[i];
        if(*s == '-') continue;     /* skip switch */
        if(isdigit(*s)) {           /* numeric */
            TC_commands[j] = atoi(s);
        }
        else {                      /* symbolic */
            FILE    *fp;
            char    buf[1024], *s1, *ch;
            int     found = 0;

            if(!(fp = fopen(inc_path, "r"))) {
                printf("Can not open %s.\n", inc_path);
                rc = 1;
                goto stop;
            }
            while(fgets(buf, sizeof(buf), fp) && !found) {
                if(ch = strchr(buf, '=')) {
                    for(s1 = buf; *s && *s <= ' '; ++s) ;
                    *ch++ = 0;
                    if(!_stricmp(s, s1)) {
                        found = 1;
                        TC_commands[j] = atoi(ch);
                    }
                }
            }
            fclose(fp);
            if(!found) {
                printf("Command code not found for \"%s\".\n", s);
                rc = 2;
                goto stop;
            }
        }
        ++j;
    }
#ifdef DEBUG
    printf("Commands: ");
    for(i = 0; i < cmdc; ++i) printf(" %d", TC_commands[i]);
    printf("\nuse_Send: %d, inc_path: %s, TC_class: %s.\n", use_Send, inc_path, TC_class);
#endif

    if(!(tcwnd = FindWindow(TC_class, NULL))) {
        printf("TC main window not found.\n");
        rc = 0;
        goto stop;
    }
    GetWindowText(tcwnd, tcwn, sizeof(tcwn));

    for(i = 0; i < cmdc; ++i) {
        if(use_Send) {
            printf("S: %u --> \"%s\"... ", TC_commands[i], tcwn);
            fflush(stdout);
            printf("RC=%u.\n", SendMessage(tcwnd, WM_USER_TC, TC_commands[i], 0));
        }
        else {
            printf("P: %u --> \"%s\"... ", TC_commands[i], tcwn);
            fflush(stdout);
            if(!PostMessage(tcwnd, WM_USER_TC, TC_commands[i], 0)) {
                printf("Failed.\n");
                rc = 1;
                goto stop;
            }
            else printf("Ok.\n");
        }
    }

stop:
    if(TC_commands) {
        free(TC_commands);
        TC_commands = NULL;
    }
    return rc;
}




so my question is : this is work ? sould be work in Total Commander 7.56

1.instructions to use: try to compile an .exe ,
2.open total commander
3.run .exe

effect : will popup the mkdir window


i not garantee is work so let me know if working , post an confirmation here (maybe a screen copy too).
thanks a lot!
User avatar
charvista
Addict
Addict
Posts: 949
Joined: Tue Sep 23, 2008 11:38 pm
Location: Belgium

Re: total commander send commands via SendMessage

Post by charvista »

I tested this with Total Commander 8.51a and it works! :)
Finally you get an answer after more than 3 years!!! :lol:
- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: total commander send commands via SendMessage

Post by djes »

Nice, thank you ! :)
Post Reply