программирование


Плагинимся к FAR

Думаю, что такое FAR, знают все. Знаменитый файловый менеджер, продолжатель дела Norton Commander'а, обладает кучей достоинств, одно из которых — подключаемые модули, или плагины. FAR предоставляет удобные API-функции, которые помогают существенно расширить стандартную функциональность. Для FAR'а уже написано много плагинов, но мы, естественно, не ищем легких путей и попытаемся разобраться в написании плагинов сами. Дабы не уснуть над клавиатурой, мы не будем писать банальное «Hello, World!», а сразу соорудим что-нибудь полезное. Например, плагин, который при вызове будет копировать путь файла, на котором в данный момент стоит курсор, в буфер обмена. Для Windows я писал (не реклама :)) расширение стандартного меню Explorer'а, которое добавляло соответствующий пункт, но в FAR'е это меню недоступно. Ну да ничего.
Итак, нам понадобится сам FAR (иначе нафига нам вообще плагин?), Delphi (версия роли не играет), а также заголовочный файл, содержащий объявления всех необходимых функций, записей, констант. Этот файл можно взять из архива PluginDoc.doc, который находится в папке с FAR'ом (в архиве – папка Headers .pas), однако в моей версии FAR'а (FAR PowerPack) такого архива не оказалось. Поэтому я вытащил его из демонстрационного плагина, который скачал отсюда: сайт

У меня он называется FARIntf.pas. Также рядом с ним присутствует файлик FARLang.pas, в котором предполагается объявлять константы для загрузки строк из языковых файлов, но в нашем плагине строка будет одна (и та – название плагина в меню), поэтому мы обойдемся без языковой поддержки. Все плагины FAR'а – динамические библиотеки, поэтому в Делфи мы создаем новый проект библиотеки через DLL Wizard. После создания сразу подключим заголовочный файл:

uses
FARIntf in 'D:\CodeGear\RAD Studio\5.0\lib\FarPlugins\FARIntf.pas',
windows, clipbrd, sysutils;

Путь к заголовочному файлу плагинов, естественно, может отличаться. Модуль clipbrd пригодится, т.к. мы будем работать с буфером обмена. Теперь рассмотрим структуру плагина. Плагин всегда состоит как минимум из трех функций: SetStartupInfo, GetPluginInfo и OpenPlugin. Функция SetStartupInfo передает нашему плагину указатели на все функции, которыми разрешает нам пользоваться FAR. В параметре передается запись типа TpluginStartupInfo, в которой описаны все функции (см. заголовочный файл). Плагин должен сохранить эту запись у себя, чтобы в дальнейшем пользоваться функциями. Так и пишем:

var
FARAPI: TpluginStartupInfo; //глобальная переменная для хранения записи

procedure SetStartupInfo(var psi: TPluginStartupInfo); stdcall;
begin
Move(psi, FARAPI, SizeOf(FARAPI)); //переписываем запись себе
end;

Следующий пункт нашей программы – передача FAR'у информации о нашем плагине. Для этого и существует функция GetPluginInfo. Ее параметр – указатель на запись типа TpluginInfo.
Мы должны заполнить эту запись, дабы FAR знал, кто мы и зачем пришли:

procedure GetPluginInfo(
var Info: TPluginInfo);
stdcall;
begin
with Info do
begin
StructSize := SizeOf(Info); //размер записи
Flags := PF_EDITOR;//флаги – так мы говорим FAR'у, что наш плагин будет доступен в меню, вызываемому по F11, во встроенном редакторе //в меню режима панелей плагин доступен всегда, однако его можно убрать, если передать флаг PF_DISABLEPANELS

DiskMenuStringsNumber := 0; //так мы говорим,что не будет добавлять строки в список дисков (ALT-F1, ALT-F2);
PluginStrings[0]:='Copy Path'; //название нашего плагина в меню

PluginMenuStrings:=@PluginStrings;
PluginMenuStringsNumber:=1; //количество пунктов в меню

PluginConfigStringsNumber:=0; //количество пунктов, которые будут добавлены в меню «Настройка внешних модулей».

CommandPrefix:=nil; //префиксы команд, т.е. например сайт
//мы команды не используем
end;
end;

Рис.1. Процесс кодинга в самом разгаре.

Заключительная остановка – функция OpenPlugin, которая вызывается при любом запуске нашего плагина. В ней-то мы и будем копировать путь. Функция принимает два параметра. Первый — это идентификатор, показывающий, откуда был вызван плагина (меню дисков, меню F11 и т.д. - нам это не интересно); второй параметр зависит от первого. Подробнее смотрим тут: сайт Итак, пишем:

function OpenPlugin(
OpenFrom: OPEN;
Item: Integer): THandle
stdcall;
var
s, FileName: string;
P:TPanelInfo; //понадобится, чтобы получить информацию о текущей панели
begin
try
FARAPI.Control(INVALID_HANDLE_VALUE,FCTL_GETPANELINFO,@P); //то, ради чего мы сохраняли запись с функциями – получаем информацию о текущей панели.
finally
if @P<>nil then
if (P.PanelType=PTYPE_FILEPANEL) and (P.ItemsNumber>0) then //если это панель просмотра файлов и выбран хотя бы один файл...
begin
if (P.PanelType=PTYPE_FILEPANEL) and (P.ItemsNumber>0) then
begin
if P.PanelItems^[P.CurrentItem].FindData.cFileName = '..' then
FileName := '' //если курсор стоит на переходе в родительский каталог, то копируем только путь к папке
else //иначе копируем и имя файла
FileName := P.PanelItems^[P.CurrentItem].FindData.cFileName;
S:=Format('"%s\%s"', [P.CurDir, //текущая директория
FileName]); //имя выбранного файла
Clipboard.AsText := s; //сохраняем добытое в буфер обмена
end;
end;
Result := INVALID_HANDLE_VALUE; //небольшой финт ушами – говорим, что функция провалилась, чтобы FAR сам освободил все ресурсы, иначе придется еще писать ClosePlugin.
End;

Плагин готов. Теперь компилируем его, создаем для него папку в каталоге %FAR%\Plugins и копируем туда получившуюся DLL. Запускаем FAR, нажимаем F11 (при этом курсор должен стоять на файле), ищем наш Copy Path и нажимаем на нем Enter. Затем открываем любой файл и нажимаем Ctrl+V. Для пущего удобства для вызова плагина можно назначить горячую клавишу (F11 -> F4 -> клавиша; обращение: F11->клавиша).


Рис.2. Вот он, наш плагин.

Конечно, еще есть что добавить к плагину: обработку нескольких файлов, работу с другими плагинами (например, если попробовать скопировать путь к одному из пунктов “Панели управления”, то мы получим абракадабру), но моей целью было не написать идеальный плагин, а подтолкнуть читателя заняться этим полезным и интересным делом: чем больше читателей клюнут на мою пропаганду, тем больше хороших плагинов получат все пользователи этого замечательного файл-менеджера. Напоследок – пара ссылок по теме:

сайт – сообщество плагинописателей;
сайт – энциклопедия разработчиков плагинов;
сайт – «Copy Path» для Windows.



PainKiller, q@sa-sec.org

© компьютерная газета