Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
wm_copydata example for filemanager Total Commander
#1
I am trying to use the WM_COPYDATA command from a macro to the filemanager Total Commander.
The file manager supports it, but I can't get the syntax right. I have been helped on this with Xyplorer and it works!, I hope that there can be solution for this filemanager too?

I have copied some examples from the totalcommander forum and wiki here in the hopes that it provides you with the right information.

An example from a user who used these commands, which is similair to the structure used in QM:
http://ghisler.ch/board/viewtopic.php?t=36885
Code:
Copy      Help
char data[]="\rC:\\Windows\0";
COPYDATASTRUCT cds;
cds.dwData='DC';
cds.lpData=data;
cds.cbData=sizeof(data);
SendMessage(hTcWnd, WM_COPYDATA, 0, (LPARAM)&cds);

The above example opens 'c:\windows' in the right panel


C++ example:
http://ghisler.ch/board/viewtopic.php?t=32658
Code:
Copy      Help
LRESULT __stdcall WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
   static byte cds_ret_data[520];
   static COPYDATASTRUCT cds_ret;

   switch (uMsg) {
      case WM_CREATE: {
         HWND htcwnd=FindWindow(L"TTOTAL_CMD", 0);
         COPYDATASTRUCT cds;

         cds.dwData='AG';
         cds.lpData="SC";
         cds.cbData=3;
         cds_ret.dwData=0; // reset dwData to check if answer was received
         SendMessage(htcwnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
         int cnt=cds_ret.dwData=='AR' ? atoi((char*)cds_ret_data) : -1; // number of items in active panel

         cds.dwData='WG';
         cds.lpData="SN";
         cds.cbData=3;
         cds_ret.dwData=0;
         SendMessage(htcwnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
         wchar_t* filename=cds_ret.dwData=='WR' ? (wchar_t*)cds_ret_data : 0; // name of focused file in active panel

         PostQuitMessage(0);
         break;
      }
      case WM_COPYDATA: {
         COPYDATASTRUCT& cds=*(COPYDATASTRUCT*)lParam;
         if (cds.dwData=='AR' || cds.dwData=='WR') {
            size_t n=min(cds.cbData, sizeof(cds_ret_data)-2);
            memcpy(cds_ret_data, cds.lpData, n);
            *(wchar_t*)(cds_ret_data+sizeof(cds_ret_data)-2)=0;
            cds_ret.dwData=cds.dwData;
            cds_ret.lpData=cds_ret_data;
            cds_ret.cbData=n;
         }
         return 1;
      }
   }

   return DefWindowProc(hWnd, uMsg, wParam, lParam);
}



int main() {
   const WNDCLASS wc={CS_HREDRAW|CS_VREDRAW, WindowProc, 0, 0, GetModuleHandle(0), 0, 0, (HBRUSH)COLOR_WINDOW, 0, L"TestWnd"};
   HWND hWnd=CreateWindow((LPWSTR)RegisterClass(&wc), wc.lpszClassName, 0, 0, 0, 0, 0, 0, 0, wc.hInstance, 0);

   if (!hWnd) return 1;

   while (1) {
      MSG msg;
      if (!~GetMessage(&msg, hWnd, 0, 0) || msg.message==WM_QUIT) break;

      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   return 0;
}

Another example:
http://www.ghisler.ch/wiki/index.php/TCUtils.cpp
Code:
Copy      Help
#include "TCUtils.h"
#include <strsafe.h>

void TCUtils::sendUserCommand (const char* userCommand, HWND sourceWindow)
{
    HWND targetWindow = FindWindow ("TTOTAL_CMD", NULL);
    if (targetWindow)
    {
        COPYDATASTRUCT copyStruct;
        ZeroMemory (&copyStruct, sizeof (COPYDATASTRUCT));
        copyStruct.dwData = 'E' + 256 * 'M';
        copyStruct.cbData = strlen (userCommand) +1;
        copyStruct.lpData = (PVOID)userCommand;
        SendMessage (targetWindow, WM_COPYDATA, (WPARAM)sourceWindow, (LPARAM)&copyStruct);
    }
}

void TCUtils::sendChangeDirectory (const char* firstPath, const char* secondPath, const char* flags, HWND sourceWindow)
{    
    HWND targetWindow = FindWindow ("TTOTAL_CMD", NULL);
       if (!targetWindow)
    {
        return;
    }
    COPYDATASTRUCT copyStruct;
    ZeroMemory (&copyStruct, sizeof (COPYDATASTRUCT));        
    copyStruct.dwData = 'C' + 256 * 'D';
    char commandLine [MAX_PATH] = {0};        
    // One path is mandatory.
    if (!firstPath && !secondPath)
    {
        return;
    }
    // First or second path or both can be entered separated by carriage return.
    if (firstPath)
    {
        StringCchCopy (commandLine, MAX_PATH, firstPath);
    }
    StringCchCat (commandLine, MAX_PATH, "\r");
    if (secondPath)
    {
        StringCchCat (commandLine, MAX_PATH, secondPath);
    }        
    if (flags)
    {
        StringCchCat (commandLine + strlen(commandLine) +1, MAX_PATH, flags);
    }
    // Calculate command line length.
    copyStruct.cbData = strlen (commandLine) +1;
    if (flags)
    {
        copyStruct.cbData += strlen(flags) +1;
    }        
    copyStruct.lpData = (PVOID)commandLine;
    SendMessage (targetWindow, WM_COPYDATA, (WPARAM)sourceWindow, (LPARAM)&copyStruct);
}
#2
not tested
Macro Macro2202
Code:
Copy      Help
;char data[]="\rC:\\Windows\0";
;COPYDATASTRUCT cds;
;cds.dwData='DC';
;cds.lpData=data;
;cds.cbData=sizeof(data);

str data="[13]C:\Windows"
COPYDATASTRUCT cds;
cds.dwData='D'<<8|'C';
cds.lpData=data;
cds.cbData=data.len+2;
#3
Yes this works!!!

THANK YOU!!!


EDIT, update for others who want to experiment with Total Commander, use like this:

Macro Macro25
Code:
Copy      Help
int w=win("Total Commander" "TTOTAL_CMD")

if(!w)    
,ret
,
str data="d:\test[13]C:\Windows"
COPYDATASTRUCT cds;
cds.dwData='D'<<8|'C';
cds.lpData=data;
cds.cbData=data.len+2;
SendMessage(w WM_COPYDATA 0 &cds)

Left panel opens "d:\test" and right panel "c:\windows", use [13] as shown above, do not use \r


Forum Jump:


Users browsing this thread: 1 Guest(s)