Code: Select all
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace TCU {
static class TCUtils {
/*
Sends a user command to Total Commander.
Parameters:
userCommand - Name of user command to send.
sourceWindow - Name of the window from which the command is send.
*/
public static int sendUserCommand(string userCommand, IntPtr sourceWindow) {
IntPtr targetWindow = NativeMethod.FindWindow("TTOTAL_CMD", null);
if(targetWindow != IntPtr.Zero) {
byte[] bcUserCommand = ASCIIEncoding.ASCII.GetBytes(userCommand);
byte[] fpUserCommand = new byte[bcUserCommand.Length + 1];
bcUserCommand.CopyTo(fpUserCommand, 0);
fpUserCommand[bcUserCommand.Length] = 0;
IntPtr marshaledUserCommand = Marshal.AllocHGlobal(fpUserCommand.Length);
try {
Marshal.Copy(fpUserCommand, 0, marshaledUserCommand, fpUserCommand.Length);
COPYDATASTRUCT copyStruct = new COPYDATASTRUCT();
copyStruct.dwData = new IntPtr((byte)'E' + 256 * (byte)'M');
copyStruct.cbData = fpUserCommand.Length;
copyStruct.lpData = marshaledUserCommand;
NativeMethod.SendMessage(targetWindow, WM_COPYDATA, sourceWindow, ref copyStruct);
int result = Marshal.GetLastWin32Error();
if(result != 0) {
return result;
}
} finally {
Marshal.FreeHGlobal(marshaledUserCommand);
}
return 0;
}
return -1;
}
/*
Change one or both directories in Total Commander.
Parameters:
firstPath - Name of the first directory to change. Meaning depends on the flags parameter. Can be NULL.
secondPath - Name of the second directory to change. Meaning depends on the flags parameter. Can be NULL.
flags - Can be "S", "T", "ST" or NULL.
S makes firstPath the source panel and secondPath the target panel otherwise firstPath is the left panel and secondPath is the left panel.
T opens the directory in a new tab. Otherwise the directory is changed in the current tab.
sourceWindow - Name of the window from which the command is send.
*/
public static void sendChangeDirectory(string firstPath, string secondPath, string flags, IntPtr sourceWindow) {
IntPtr targetWindow = NativeMethod.FindWindow("TTOTAL_CMD", null);
if(targetWindow == IntPtr.Zero) {
return;
}
StringBuilder commandLine = new StringBuilder();
// One path is mandatory.
if(string.IsNullOrEmpty(firstPath) && string.IsNullOrEmpty(secondPath)) {
return;
}
// First or second path or both can be entered separated by carriage return.
if(!string.IsNullOrEmpty(firstPath)) {
commandLine.Append(firstPath);
}
commandLine.Append("\r");
if(!string.IsNullOrEmpty(secondPath)) {
commandLine.Append(secondPath);
}
byte[] bcCommandLine = ASCIIEncoding.ASCII.GetBytes(commandLine.ToString());
byte[] bcFlags = ASCIIEncoding.ASCII.GetBytes(flags);
byte[] fpCommandLine = new byte[bcCommandLine.Length + 1 + ( string.IsNullOrEmpty(flags) ? 0 : flags.Length + 1 )];
bcCommandLine.CopyTo(fpCommandLine, 0);
fpCommandLine[bcCommandLine.Length] = 0;
if(!string.IsNullOrEmpty(flags)) {
bcFlags.CopyTo(fpCommandLine, bcCommandLine.Length + 1);
fpCommandLine[fpCommandLine.Length - 1] = 0;
}
IntPtr marshaledCommandLine = Marshal.AllocHGlobal(fpCommandLine.Length);
try {
Marshal.Copy(fpCommandLine, 0, marshaledCommandLine, fpCommandLine.Length);
COPYDATASTRUCT copyStruct = new COPYDATASTRUCT(); ;
copyStruct.dwData = new IntPtr((byte)'C' + 0x100 * (byte)'D');
copyStruct.cbData = fpCommandLine.Length;
copyStruct.lpData = marshaledCommandLine;
NativeMethod.SendMessage(targetWindow, WM_COPYDATA, sourceWindow, ref copyStruct);
} finally {
Marshal.FreeHGlobal(marshaledCommandLine);
}
}
#region Native API Signatures and Types
internal const int WM_COPYDATA = 0x004A;
[StructLayout(LayoutKind.Sequential)]
internal struct COPYDATASTRUCT {
public IntPtr dwData; // Specifies data to be passed
public int cbData; // Specifies the data size in bytes
public IntPtr lpData; // Pointer to data to be passed
}
[SuppressUnmanagedCodeSecurity]
internal class NativeMethod {
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg,
IntPtr wParam, ref COPYDATASTRUCT lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
}
#endregion
}
}