<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK. Открыть в Total Commander'е (пункт контекстного меню и не только)]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=364&amp;type=atom" />
	<updated>2007-03-16T08:50:16Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=364</id>
		<entry>
			<title type="html"><![CDATA[AHK. Открыть в Total Commander'е (пункт контекстного меню и не только)]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=2192#p2192" />
			<content type="html"><![CDATA[<p>Гислер следит за мной! <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /> К такому параноидальному и маниявеличному выводу я пришел после того, как он внедрил в Тотал уже пятую фишку, которую я реализовал скриптами. Вот и сейчас: не успел я как следует погонять предлагаемый ниже скрипт, как он р-раз, и вроде как добавил его функционал в ТС. Правда, работает этот функционал в Тотале из рук вон плохо. Надеюсь, этот добрый мужчина доведёт фишку до ума. Но поскольку ждать этого можно долго, то скрипт я решил всё же выложить.<br />Короче, идея скрипта такая: во многих прогах, работающих с файлами/папками, есть такой пункт &quot;Открыть в Проводнике&quot; (как бы он там ни назывался). Это здорово, но я Проводник недолюбливаю (мягко говоря), а Тотал - наоборот (и тоже, говоря мягко). Вот чтобы такая очень нужная (мне) возможность открытия была бы и для Тотала, я и накатал скриптец. <br />Его можно зарегистрировать в реестре (это необязательно, см. комменты в теле скрипта) и в контекстном меню всяких файлов/папок, появится пункт &quot;<strong>Открыть в Total Commander&#039;е</strong>&quot; (название можно изменить). И при работе в каком нибудь приложении, (скажем, в ACDSee) можно этот пункт выбрать и откроется Тотал, а в нём курсор встанет на выбранный файл. Это очень удобно.<br />Другой вариант применения: скрипт можно поставить как внешний инструмент в те проги, которые позволяют это делать (ну, например, в Foobar) и опять таки открывать файлы в Тотале.<br />Третий вариант такой: можно повесить скрипт на кнопку в самом Тотале и (допустим, после результатов поиска) нажатием на кнопку открывать файл в противоположной панели. Или скопировать в буфер какой-нибудь путь откуда-нибудь, нажать кнопку в ТС и открыть его там, где хочется и как хочется. Под &quot;открыть, где хочется&quot; я имею в виду не запуск файла, а переход к нему в указанной панели. А под &quot;как хочется&quot; то, что дополнительно можно передавать команды, которые понимает Тотал. Например, переключиться на пользовательские колонки. Или даже выполнить какую-нибудь пользовательскую команду (ну те, что em_abc).<br />В общем, я нахожу скрипт рульным. Если его таким найдёте и вы - буду рад. А найдёте не рульным, а ошибку - дайте знать. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /> Будут вопросы, комментарии - не стесняйтесь. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p><p>Скрипт нужно поместить рядом с Totalcmd.exe или в какую нибудь из подпапок (у меня, скажем, в папке с Тоталом есть папка AutoTotal, где я держу всякие скрипты для понятно чего). Чтобы добавить скрипт в контекстное меню файлов/папок, его нужно запустить с параметром <strong>/reg</strong>. Для удаления из контекстного меню, с параметром <strong>/unreg</strong>.</p><p><strong>Примерчик </strong>добавления скрипта в качестве внешнего инструмента в FastStone Image Viewer (гляделка такая).<br />1. Кликаем правой кнопкой по рисунку и в конт. меню выбираем пункт &quot;Правка во внешней программе&quot; - &quot;Добавить/удалить программу&quot;.<br />2. Жмём кнопку &quot;добавить&quot; и в появившееся поле вписываем путь к скрипту (путь нужно именно вписать, т.к. выбрать неоткомпилированный скрипт FastStone не позволит, но если его сюда вписать, или вставить, то всё будет ОК)<br />3. Даём название инструменту (то, какое хотите)<br />4. В &quot;параметры&quot; вписываем (filename) /O /T<br />5. Подтверждаем<br />Всё. Теперь можно нажать на рисунке E (английскую) и рисунок откроется в Тотале.</p><div class="codebox"><pre><code>;*************************************************************************************************************
; AutoHotkey Version:        1.0.45.04+
; Автор:                     Androgen Belkin
; Имя скрипта:               OpenInTC.ahk (v.1.0)
; Total Commander Version:   7.0+
;*************************************************************************************************************
; Скрипт переходит в ТС по переданному пути. Может переходить по адресу, содержащемуся в буфере обмена.
; Путь передаётся в ком. строке, или берётся из буфера обмена (см. возможные параметры ниже).
; Если передана папка - она открывается в панели ТС (ТС и сам так может).
; Если передан файл - открывается родительская папка и курсор позиционируется на этот файл (а так не может).
; Переданный путь открывается в активной вкладке (если не указано иначе).

; Если командная строка передаётся в уже запущенный ТС и в нём открыто какое-либо модальное окно,
; то скрипт прервёт свою работу. Это сделано для того, чтобы не помешать работе ТС.

; Список возможных параметров (параметры нечувствительны к регистру):
;--------------- стандартные для ТС параметры ----------------------------------------------------------------
; /O  - используем запущенный ТС
; /N  - запускаем новый экземпляр TC (независимо от запрещающей это настройки ТС)
; /T  - открыть в новой вкладке,
; /L= - открыть в левой панели
; /R= - открыть в правой панели
; /i= - путь к wincmd.ini (если используется отличный от по умолчанию, например, i=.\MyProfile\MyWincmd.ini)
; /F= - путь к wcx_ftp.ini (если используется отличный от по умолчанию, например, f=.\MyProfile\Mywcx_ftp.ini)
;-------------------------------------------------------------------------------------------------------------
;--------------- дополнительные параметры скрипта ------------------------------------------------------------
; /CB или /ClipBoard - открыть путь, содержащийся в буфере
; /trg               - открыть в неактивной панели
; /reg               - добавить соответствующий пункт в конт. меню всех файлов и папок
; /unreg             - удалить соответствующий пункт из конт. меню всех файлов и папок
;*************************************************************************************************************

; ========== НАСТРОЙКИ ПОЛЬЗОВАТЕЛЯ ===============
TCParam = /O                 ; вписать сюда параметры, которые скрипт будет использовать по умолчанию
TotalCmd_Name = Totalcmd.exe ; на случай, если Totalcmd.exe зачем-то переименован
DebugIn = 0  ; вписать сюда число 1 для того, чтобы вместо открытия пути посмотреть ПОЛУЧЕННУЮ ком.строку
DebugOut = 0 ; вписать сюда число 1 для того, чтобы вместо открытия пути посмотреть ОБРАБОТАННУЮ ком.строку
NameInShell = Открыть в Total Commander&#039;е ; имя для пункта контекстного меню
; ========== КОНЕЦ НАСТРОЕК ПОЛЬЗОВАТЕЛЯ ==========


#NoTrayIcon       ; не отображать значок скрипта в трее
#NoEnv            ; запрещаем имена переменных как у переменных окружения
SendMode Input    ; новый режим высылки без задержки и повышенной надежности
SetBatchLines, -1 ; указываем максимальную скорость для скрипта


; ПРОВЕРКА ПРАВИЛЬНОСТИ ПУТИ ЗАПУСКА СКРИПТА
SetWorkingDir, %A_ScriptDir% ; для начала ищем Totalcmd.exe в папке, где запущен этот скрипт
IfNotExist, %TotalCmd_Name% ; если в текущей папке НЕ найден Totalcmd.exe, то...
{
    SetWorkingDir, .. ; теперь ищем Totalcmd.exe в папке на уровень выше
    IfNotExist, %TotalCmd_Name% ; если и здесь НЕ найден Totalcmd.exe, то...
    {
        MsgBox, 64, Total Commander не найден!, ; показываем сообщение
        ( LTrim
        Скрипт следует поместить в папку, содержащую файл &quot;%TotalCmd_Name%&quot;.
        Или в любую из её подпапок.
        )
        ExitApp ; конец скрипта
    }
}
TotalCmd_Path = %A_WorkingDir%\%TotalCmd_Name% ; запоминаем путь к Totalcmd.exe
; ПРОВЕРКА ВЕРСИИ ТС
FileGetVersion, TCVersion, %TotalCmd_Path% ; проверяем версию ТС
If TCVersion &lt; 7.0
{
    MsgBox, 64, Внимание!, ; показываем сообщение
    ( LTrim
    Total Commander должен быть версии 7.0 или выше.
    Текущая версия %TCVersion%
    )
    ExitApp ; конец скрипта
}
; ПРОВЕРКА НАЛИЧИЯ ПЕРЕДАННЫХ ПАРАМЕТРОВ
If 0 = 0 ; если скрипт запущен без параметров
{
    SplashImage,, B1 CT000080,, Запускай меня с параметрами ; показать сообщение (чтоб не думалось)
    Sleep, 800
    ExitApp ; закончить скрипт
}
; ОТЛАДОЧНЫЙ БЛОК 1
If DebugIn ; если указано, что нужно показать полученную ком.строку
{
    Loop, %0% ; лопатим полученную ком. строку
        Param := Param A_Space %A_Index% ; соединяем все параметры через пробел
    MsgBox, Param=%Param% ; показываем полученную строку
    If NOT DebugOut ; если не нужно показывать ком. строку после обработки
        ExitApp ; закончить скрипт
}

; СОРТИРОВКА ПОЛУЧЕННЫХ ПАРАМЕТРОВ
IfInString, TCParam, /T ; если этот параметр задан в настройках скрипта как параметр по умолчанию
    NewTab := True ; будем открывать новую вкладку
Loop, %0% ; лопатим полученную ком. строку
{
    Param := %A_Index% ; берем каждый параметр (чтобы далее не париться с синтаксисом)
    If ( Param = &quot;/reg&quot; )
        Goto, RegInShell
    If ( Param = &quot;/unreg&quot; )
        Goto, UnRegInShell
    If ( Param = &quot;/O&quot; )
    {
        TCParam = %TCParam% %Param% ; добавляем полученный параметр
        Continue ; идём к следующему параметру
    }
    If ( Param = &quot;/N&quot; )
    {
        TCParam = %TCParam% %Param% ; добавляем полученный параметр
        Continue ; идём к следующему параметру
    }
    If ( InStr( Param, &quot;i=&quot; ) = 1 ) OR ( InStr( Param, &quot;i=&quot; ) = 2 ) ; если стоит в начале (или после &quot;/&quot;)
    {
        TCParam = %TCParam% %Param% ; добавляем полученный параметр
        Continue ; идём к следующему параметру
    }
    If ( InStr( Param, &quot;f=&quot; ) = 1 ) OR ( InStr( Param, &quot;f=&quot; ) = 2 ) ; если стоит в начале (или после &quot;/&quot;)
    {
        TCParam = %TCParam% %Param% ; добавляем полученный параметр
        Continue ; идём к следующему параметру
    }
    If ( Param = &quot;/T&quot; )
    {
        NewTab := True ; будем открывать новую вкладку
        Continue ; идём к следующему параметру
    }
    If ( Param = &quot;/L&quot; )
    {
        Left := True ; путь будем открывать слева
        Continue ; идём к следующему параметру
    }
    If ( Param = &quot;/R&quot; )
    {
        Right := True ; путь будем открывать справа
        Continue ; идём к следующему параметру
    }
    If ( Param = &quot;/trg&quot; )
    {
        Target := True ; путь будем открывать в неактивной панели
        Continue ; идём к следующему параметру
    }

    If ( InStr( Param, &quot;L=&quot; ) = 1 ) OR ( InStr( Param, &quot;L=&quot; ) = 2 ) ; если стоит в начале (или после &quot;/&quot;)
    {
        StringTrimLeft, Received_Path, Param, InStr( Param, &quot;L=&quot; ) + 1 ; отрезаем идентификатор
        Left := True ; путь будем открывать слева
        Continue ; идём к следующему параметру
    }
    If ( InStr( Param, &quot;R=&quot; ) = 1 ) OR ( InStr( Param, &quot;R=&quot; ) = 2 ) ; если стоит в начале (или после &quot;/&quot;)
    {
        StringTrimLeft, Received_Path, Param, InStr( Param, &quot;R=&quot; ) + 1 ; отрезаем идентификатор
        Right := True ; путь будем открывать справа
        Continue ; идём к следующему параметру
    }
    If ( InStr( Param, &quot;cm_&quot; ) = 1 ) ; если строка так начинается
    {
        TCExtCom = %TCExtCom% %Param% ; добавляем полученный параметр
        Continue ; идём к следующему параметру
    }
    If ( InStr( Param, &quot;em_&quot; ) = 1 ) ; если строка так начинается
    {
        TCExtCom = %TCExtCom% %Param% ; добавляем полученный параметр
        Continue ; идём к следующему параметру
    }
    If ( InStr( Param, &quot;/ClipBoard&quot; ) = 1 ) OR ( InStr( Param, &quot;/cb&quot; ) = 1 )  ; если строка так начинается
    {
        Received_Path := Clipboard ; берём путь из буфера
        Continue ; идём к следующему параметру
    }
    Else If NOT Received_Path ; если в параметре нет ни одного из вышеобработанных и путь не взят из буфера
        Received_Path := Param ; считаем полученную строку - путем
}
; ОТЛАДОЧНЫЙ БЛОК 2
If DebugOut ; если указано, что нужно показать полученную ком.строку
{
    MsgBox, 64, Ком. строка после обработки, ; показываем сообщение
    ( LTrim
    Received_Path=%Received_Path%
    TCParam=%TCParam%
    NewTab=%NewTab%
    TCExtCom=%TCExtCom%
    Left=%Left%
    Right=%Right%
    Clipboard=%Clipboard%
    )
    ExitApp
}

; ПРОВЕРКА СУЩЕСТВОВАНИЯ ПОЛУЧЕННОГО ПУТИ
StringRight, RightSymbol, Received_Path, 1 ; берем последний символ
If RightSymbol = \ ; если последний символ в строке бэкслэш &quot;\&quot;, то...
    StringTrimRight Received_Path, Received_Path, 1 ; удалить последний символ (&quot;\&quot;)
SplitPath, Received_Path, Received_FileName, Received_Dir ; берём родительскую папку
IfExist, %Received_Path% ; если полученный путь существует, то...
{
    If InStr( FileExist( Received_Path ), &quot;D&quot; ) ; если это - папка, то...
        Received_FileName = ; сбрасываем имя &quot;файла&quot;
    Else ; если это - файл
        Received_Path := Received_Dir ; сначала будем открывать родительскую папку
    Goto, OpenInTC ; перейти к открытию папки в ТС
}
IfNotExist, %Received_Dir% ; если и родительской папки не существует, то...
{
    SplashImage,, B1 CT000080,, Полученный путь не существует ; показать сообщение (чтоб не думалось)
    Sleep, 800
    ExitApp ; закончить скрипт
}

; ОТКРЫВАЕМ ПОЛУЧЕННЫЙ ПУТЬ В ТС
OpenInTC:
Process, Exist, %TotalCmd_Name% ; проверяем запущен ли ТС
If ErrorLevel AND InStr( TCParam, &quot;/O&quot; ) ; если уже запущен, и указано открывать в имеющемся
    WaitingTime = 2 ; ждать будем недолго
Else ; если ещё не запущен, или нужно запускать новый экземпляр
    WaitingTime = 5 ; ждать будем подольше
Run, &quot;%TotalCmd_Path%&quot; %TCParam% ; передаём TC параметры (запускаем, если нужно)
; Особенность открытия пути через ком. строку (не Тоталовскую) в том,
; что если не указано иначе, путь открывается в панели по умолчанию.
; Чтобы он открывался в активной панели, используется ControlSetText (см. ниже).
WinWaitActive, ahk_class TTOTAL_CMD,, %WaitingTime% ; ждем активации окна ТС указанное время
If ErrorLevel ; если не дождались окна
{
    MsgBox, Не дождались окна
    ExitApp ; закончить скрипт
}
WinGet, hw_TTOTAL_CMD, ID, ahk_class TTOTAL_CMD ; получить ID окна TC (последнего активного)
If Left ; если открывать нужно слева
    SendMessage, 1075, 4001,,, ahk_id %hw_TTOTAL_CMD% ; 4001=cm_FocusLeft (перейти на левую панель)
If Right ; если открывать нужно справа
    SendMessage, 1075, 4002,,, ahk_id %hw_TTOTAL_CMD% ; 4002=cm_FocusRight (перейти на правую панель)
; если не указано открывать слева или справа, открывать будем в активной панели
WinActivate, ahk_id %hw_TTOTAL_CMD%
ControlGetFocus, Active_Panel, ahk_id %hw_TTOTAL_CMD% ; определяем какая панель активна
If (Active_Panel != &quot;TMyListBox1&quot; AND Active_Panel != &quot;TMyListBox2&quot;)
{
    MsgBox, Не активны панели Тотала
    ExitApp ; закончить скрипт
}
If Target ; если было указано открывать в противоположной панели
{
    If Active_Panel = TMyListBox1 ; если активна правая панель
    {
        SendMessage, 1075, 4001,,, ahk_id %hw_TTOTAL_CMD% ; 4001=cm_FocusLeft переходим на левую панель
        Active_Panel = TMyListBox2 ; будем читать другую панель

    }
    Else
    {
        SendMessage, 1075, 4002,,, ahk_id %hw_TTOTAL_CMD% ; 4002=cm_FocusRight переходим на правую панель
        Active_Panel = TMyListBox1 ; будем читать другую панель
    }
}
If NewTab ; если было указано открывать новую вкладку
    SendMessage, 1075, 3001,,, ahk_id %hw_TTOTAL_CMD% ; 3001=cm_OpenNewTab (открываем новую вкладку)
ControlSetText, Edit1, cd %Received_Path%, ahk_id %hw_TTOTAL_CMD% ; вбиваем путь в ком. строку
ControlSend, Edit1, {Enter}, ahk_id %hw_TTOTAL_CMD% ; открываем папку
; 4 действия ниже нужны для того, чтобы привести открытую панель к виду
; из которого можно правильно получить список файлов
SendMessage, 1075, 302,,, ahk_id %hw_TTOTAL_CMD% ; 302=cm_SrcLong (вид - подробный)
SendMessage, 1075, 312,,, ahk_id %hw_TTOTAL_CMD% ; 312=cm_SrcAllFiles (вид - все файлы)
SendMessage, 1075, 325,,, ahk_id %hw_TTOTAL_CMD% ; 325=cm_SrcUnsorted (без сортировки)
SendMessage, 1075, 321,,, ahk_id %hw_TTOTAL_CMD% ; 321=cm_Sort by name (сортировать по имени)

If Received_FileName ; если был получен файл (а не папка)
{
    ControlGet, RawList, List,, %Active_Panel%, ahk_id %hw_TTOTAL_CMD% ; получаем список из активной панели
    Loop, Parse, RawList, `n ; обработать полученный список
    {
        IfInString, A_LoopField, %A_Space%&lt; ; если текущий пункт - папка, то...
            Continue ; ищем дальше
        Else ; если текущий пункт - файл, то...
        {
            CurName := A_LoopField ; запоминаем обрабатываемую строку
            Loop, 5 ; будем отсчитывать 5-й справа пробел
            {
                ; отбрасываем последнее поле
                StringLeft, CurName, CurName, InStr( CurName, A_Space, False, 0 ) - 1
                If A_Index = 3 ; готовы проверять 4-е поле
                {
                    Check_nbsp := SubStr(CurName, InStr( CurName, A_Space, False, 0 ) +1 ) ; берём 4-е поле
                    If InStr( Check_nbsp, Chr(160) ) ; если в нём есть неразрывный пробел
                    ; (он может здесь быть, если ТС показывает размер в байтах)
                    {
                        ; отбрасываем последнее поле
                        StringLeft, CurName, CurName, InStr( CurName, A_Space, False, 0 ) - 1
                        Break ; больше лопатить не будем
                    }
                }
            }
        }
        If CurName = %Received_FileName% ; если дошли до искомого файла
        {
            SendMessage, 0x19e, A_Index-1, 0, %Active_Panel%, ahk_id %hw_TTOTAL_CMD% ; ставим курсор на файл
            ; 0x19e=LB_SETCARETINDEX, -1=отсчет идет с нуля
            Break ; выходим из цикла
        }
    }
}
; ОБРАБОТКА ДОПОЛНИТЕЛЬНЫХ (ВОЗМОЖНО ПЕРЕДАННЫХ) ПАРАМЕТРОВ
If TCExtCom ; если была передана дополнительная команда
{
    ControlSetText, Edit1, %TCExtCom%, ahk_id %hw_TTOTAL_CMD% ; вбиваем команду в ком. строку
    ControlSend, Edit1, {Enter}, ahk_id %hw_TTOTAL_CMD% ; выполняем команду
}
ExitApp ; конец скрипта

; РЕГИСРАЦИЯ И ДЕРЕГИСТРАЦИЯ В РЕЕСТРЕ
RegInShell: ; регистрация в реестре
If NOT A_IsCompiled ; если скрипт не откомпилирован
{
    ; пишем себя в контекстное меню всех файлов
    RegWrite, REG_SZ, HKCR, *\shell\OpenInTC,, %NameInShell%
    RegWrite, REG_SZ, HKCR, *\shell\OpenInTC\command,, &quot;%A_AhkPath%&quot; &quot;%A_ScriptFullPath%&quot; &quot;`%1&quot;
    ; пишем себя в контекстное меню папок
    RegWrite, REG_SZ, HKCR, Directory\shell\OpenInTC,, %NameInShell%
    RegWrite, REG_SZ, HKCR, Directory\shell\OpenInTC\command,, &quot;%A_AhkPath%&quot; &quot;%A_ScriptFullPath%&quot; &quot;`%1&quot;
}
Else
{
    ; пишем себя в контекстное меню всех файлов
    RegWrite, REG_SZ, HKCR, *\shell\OpenInTC,, %NameInShell%
    RegWrite, REG_SZ, HKCR, *\shell\OpenInTC\command,, &quot;%A_ScriptFullPath%&quot; &quot;`%1&quot;
    ; пишем себя в контекстное меню папок
    RegWrite, REG_SZ, HKCR, Directory\shell\OpenInTC,, %NameInShell%
    RegWrite, REG_SZ, HKCR, Directory\shell\OpenInTC\command,, &quot;%A_ScriptFullPath%&quot; &quot;`%1&quot;
}
If NOT ErrorLevel
    MsgBox, Теперь в контекстном меню файлов и папок есть пункт`n&quot;%NameInShell%&quot;
ExitApp ; конец скрипта

UnRegInShell: ; удаления из реестра
RegDelete, HKCR, *\shell\OpenInTC ; удаляем себя из контекстного меню всех файлов
RegDelete, HKCR, Directory\shell\OpenInTC ; удаляем себя из контекстного меню дисков
If NOT ErrorLevel
    MsgBox, Из контекстного меню файлов и папок удалён пункт`n&quot;%NameInShell%&quot;
ExitApp ; конец скрипта</code></pre></div><p>Можете не копировать код, а забрать скриптец архивчиком.</p>]]></content>
			<author>
				<name><![CDATA[Androgen]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=4</uri>
			</author>
			<updated>2007-03-16T08:50:16Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=2192#p2192</id>
		</entry>
</feed>
