В Total Commander'е, начиная с версии 7.0 public beta 1, появилась возможность создавать пользовательские команды. Это просто зверски расширяет возможности его автоматизации (да и просто зверски расширяет его возможности) . Расскажу о двух возможных способах это использовать.
Первый способ - самый очевидный (и, как мне кажется, самый удобный). Нужно создать пользовательскую команду (как это сделать рассказывать не стану), и назначить на неё псевдоним (alias). (Назначается там же, где и горячие клавиши). Для примера, назовём этот псевдоним MyAlias. Всё, теперь его можно смело посылать Тоталу в ком. строку, примерно так:
ControlSend, Edit1, MyAlias{Enter}, ahk_class TTOTAL_CMD ; вбиваем свою команду в ком. строку
Тут надо сказать, что и сами пользовательские команды и псевдонимы для них можно писать в соответствующие ini-файлы скриптами. Причём без перезапуска Тотала. Т.е. прямо на ходу вписать нужную команду, да и выполнить её. А затем и удалить, если она больше не понадобится. Правда тут есть некоторые сложности (а куда без них) с определением местоположения этих самых "соответствующих ini-файлов". Дело в том, что одной из новых фич Тотала является возможность дробить ранее цельный wincmd.ini (или как там вы его назвали) на множество разных ini-файлов. И найти нужный не так просто, как может показаться, (это и раньше было тем ещё гемором). Но задача вполне решаемая. Собственно я её уже почти решил, но всё как-то некогда поставить последний штрих. Поставлю - выложу. Ну, это так, к слову. Двигаем далее.
Второй способ посложнее, с использованием функций, но, в каких-то случаях, пригодится и он, т.к. позволяет обращаться к пользовательским командам напрямую, без псевдонимов. Это модифицированный пример из справки к AutoHotkey, который я немного подрихтовал, под наши нужды.
Сами функции:
;-----------------------------------------------------------------------------
Send_WM_COPYDATA( ParameterToSent, TargetTC ) ; функция высылки Тоталу пользовательской команды em_xyz
{
; В качестве параметров функция принимает имя команды em_xyz и целевое окно ТС
VarSetCapacity( CopyDataStruct, 12 ) ; устанавливаем размер высылаемой структуры данных
InsertInteger( Asc( "E" ) + 256 * Asc( "M" ), CopyDataStruct ) ; вставляем в структуру то, что требует ТС для исполнения команд
InsertInteger( StrLen( ParameterToSent ) + 1, CopyDataStruct, 4 ) ; добавляем собственно команду (+ символ конца строки)
InsertInteger( &ParameterToSent, CopyDataStruct, 8 ) ; добавляем указатель на собственно команду
SendMessage, 0x4A,, &CopyDataStruct,, %TargetTC% ; шлём команду Тоталу, обязательно Send, а не Post (0x4A = WM_COPYDATA)
Return, ErrorLevel ; выходим из функции и возвращаем ответ SendMessage'а
}
;-----------------------------------------------------------------------------
InsertInteger( pInteger, ByRef pDest, pOffset = 0, pSize = 4 ) ; функция заполнения структуры данными
{
Loop, 4 ; копируем каждый байт целого числа в структуру как сырые двоичные данные
{
DllCall("RtlFillMemory" ; заполняем структуру нашими данными
, "UInt" , &pDest + pOffset + A_Index-1 ; указатель на адрес, с которого начинается заполнение
, "UInt" , 1 ; размер заполняемой структуры в байтах
, "UChar", pInteger >> 8*( A_Index-1 ) & 0xFF) ; содержимое заполняемого байта
}
}
;-----------------------------------------------------------------------------
Примеры их использования:
Простейший пример:
Send_WM_COPYDATA( "em_usercmd1", "ahk_class TTOTAL_CMD" ) ; шлём пользовательскую команду Тоталу
Пример чуть позаковыристей:
DetectHiddenWindows, On ; искать в скрытых окнах (на случай, если Тотал свёрнут в трей)
WinGet, hw_TTOTAL_CMD, ID, ahk_class TTOTAL_CMD ; получить ID окна TC (не абы какого, а последнего активного :) )
UserParameter = em_usercmd2 ; эту команду будем слать
Send_WM_COPYDATA( UserParameter, "ahk_id" hw_TTOTAL_CMD ) ; вызываем функцию
If ErrorLevel = FAIL ; проверяем, что сказал вызов функции
MsgBox, Команда SendMessage не удалась. Вероятно, Тотал не запущен.
Примечание: Тотал возвращает 0, и если команда им была выполнена успешно, и если такой команды нет. Но во втором случае, он ещё и покажет соответствующее сообщение. На мой взгляд, не самая удачная реализация, но что есть, то есть.
Добавлю, что я пробовал с помощью Winspector Spy отловить, какие сообщения шлёт сам Тотал, когда выполняет пользовательскую команду, и использовать результат для высылки этих сообщений, но способ оказался нерабочий, т.к. wParam плавает от случая к случаю.
Удачи. Будут комменты - прошу высказываться.
Крокодил, крокожу и буду крокодить! (Твёрдое обещание нетрезвого кодера).