
Бывают моменты, когда необходимые мысли уже после того приходят, как итоговая программа передана заказчику. С целью решения этой проблемы и придумали плагины. Плагин – представляет собой dll библиотеку, в обязательно порядке в которой, присутствует отмеченный ряд процедур и функций, выполняющих некоторые действия определенные разработчиком...
Спонсор поста: ищете последнюю информацию с мира iPod, iPhone, iMac и MacBook, а также желаете найти технику компании apple по самым низким ценам? Заходите на интернет-блог appleinsider.ru, узнавайте новости Hi-tech и читайте подробные обзоры о продукции Apple!
Вот пример:
function PluginType : PChar;
это функция, которая определяет назначение самого плагина.
function PluginName : PChar;
это функция, возвращающая название плагина. Это название отображается в самом меню.
function PluginExec(AObject: ТТип): boolean;
является главным обработчиком, который выполняет действия определённые и TRUE возвращает;
А также, пример res файла с небольшим битмапом и компилировкой его с плагином вместе, отображался который в самом меню идентичного плагина.
Компилировка res фaйла делается следующим образом:
Создается сам файл с неким расширением *.rc
в нём надо написать: bitmap RCDATA LOADONCALL 1.bmp, где bitmap представляет собой идентификатор ресурса RCDATA LOADONCALL – именно является типом и параметром 1.bmp – это есть имя самого локального файла именно для кампиляций
откомпилируйте данный файл программой под названием brcc32.exe, которая лежит в папке ...Delphi5BIN .
Теперь о загрузке плагина
Теория.
Как мы говорили, плагин представляет собой dll, значит возможно её следующими вариантами подгрузить:
Приклеиванием к самой программе…
function PluginType : PChar; external 'myplg.dll';
// в данном случае dll обязательно должна лежать около exe и не можем мы передать
// имя, не будем же мы все плагины делать только одного имени, такой вариант не подходит нам.
// Программа не загрузится вообще без данного файла! Мы получим сообщение о произошедшей ошибке.
// Данный метод подойти может для поддержки обновления именно программы вашей!
Динамический
значит, что грузим мы правильно ее!
Пример:
var
// здесь объявляем процедурный тип функции из нашего плагина
PluginType: function: PChar;
//тут объявляем переменную типа хендл, мы пишем в которую, хендл плагина
PlugHandle: THandle;
procedure Button1Click(Sender: TObject);
begin
//здесь грузим сам плагин
PlugHandle := LoadLibrary('MYplg.DLL');
//Получилось либо же нет?
if PlugHandle <> 0 then
begin
// здесь ищем функцию в dll
@PluginType := GetProcAddress(plugHandle,'Plugintype');
if @PluginType <> nil then
//здесь вызываем функцию
ShowMessage(PluginType);
end;
//здесь освобождаем библиотеку
FreeLibrary(LibHandle);
end;
Вот данный метод подходит больше для построения самих плагинов!
Функции:
//как правильно вы поняли, загружает саму dll и её хендл возвращает
function LoadLibrary(lpLibFileName : Pchar):THandle;
// далее пытается обработчик найти в ней переданной хендле dll,
// далее при выполнении успешном, указатель обработчика возвращает.
function GetProcAddress(Module: THandle; ProcName: PChar): TFarProc
//здесь освобождает память, которую занимает dll
function FreeLibrary(LibModule: THandle);
Наиболее сложным в построений плагинов, является не сама реализация целого кода, а именно предусмотрение всего, для чего в проге они могут понадобиться, нужно же предусмотреть фактически все возможные типы плагинов! А это вовсе уж не просто.
Вот хороший пример реализации обычной программы для поддержки самих плагинов...
Вот приведен исходный код программного модуля:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, Menus, Grids, DBGrids;
type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
// здесь меню, которое содержать будет ссылки на плагины
N1231: TMenuItem;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
//здесь лист, держать в котором мы будем именно имена файлов плагинов
PlugList : TStringList;
//приведена процедура загрузки самого плагина
procedure LoadPlug(fileName : string);
//приведена процедура инициализации, а также выполнения плагина
procedure PlugClick(sender : TObject);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
Рассмотрим процедуру загрузки плагина.
Тут мы загружаем, имя dll вносим в список и делаем пункт меню специально для него; далее загружаем из dll картинку для нашего пункта меню
procedure TForm1.LoadPlug(fileName: string);
var
//здесь объявление функции, которая возвращать будет само имя плагина
PlugName : function : PChar;
//представлен новый пункт меню
item : TMenuItem;
//это Хендл dll
handle : THandle;
//это объект, с которого мы будем загружать картинку из dll
res :TResourceStream;
begin
item := TMenuItem.create(mainMenu1); //Делаем новый пунктик меню
handle := LoadLibrary(Pchar(FileName)); //далее загружаем dll
if handle <> 0 then //В случае когда все удачно, продолжаем...
begin
@PlugName := GetProcAddress(handle,'PluginName'); //здесь грузим саму процедуру
if @PlugName <> nil then
item.caption := PlugName
//В случае, когда все прошло, продолжаем...
else
begin
ShowMessage('dll not identifi '); //Если нет, выдаёт нам сообщение об какой то ошибке
Exit; //здесь обрываем процедуру
end;
PlugList.Add(FileName); //здесь добавляем название dll
res:= TResourceStream.Create(handle,'bitmap',rt_rcdata); //продолжая, загружаем ресурс из dll
res.saveToFile('temp.bmp'); res.free; //далее сохраняем все файл
item.Bitmap.LoadFromFile('Temp.bmp'); //здесь загружаем в пункт меню
FreeLibrary(handle); //тут уничтожаем dll
item.onClick:=PlugClick; //далее даём ссылку на обработчик
Mainmenu1.items[0].add(item); //продолжая, добавляем пункт меню
end;
end;
Продолжение читайте в статье - Как создавать плагины на Дельфи? Часть 2