Текущий архив: 2002.11.18;
Скачать: CL | DM;
Вниз
Создание плагинов для Delphi Найти похожие ветки
← →
Сатир © (2002-10-28 16:56) [0]у кого есть опыт/примеры/идеи?
делитесь, буду очень признателен всем откликнувшимся
← →
Игорь Шевченко © (2002-10-28 17:10) [1]www.gexperts.org
← →
han_malign © (2002-10-28 17:10) [2]
unit Plugins;
interface
uses Windows, Utils, NetDefs, NetTraf, PluginDefs;
type
TPlugInInfo = packed record
piiHandle : THandle;
piiPlugIn : TStatusPlugin;
end;
var
PlugIn : array[0..cMaxNapp-1] of TPlugInInfo;
function CreatePlugins : Integer;
procedure DestroyPlugins;
function PluginByName(AName : String) : Integer;
implementation
uses SysUtils,SysConst;
function GetModuleName(Module: HMODULE): string;
var
ModName: array[0..MAX_PATH] of Char;
begin
SetString(Result, ModName, Windows.GetModuleFileName(Module, ModName, SizeOf(ModName)));
end;
function ForceLoadPackage(const Name: string): HMODULE;
type
TPackageLoad = procedure;
var
PackageLoad: TPackageLoad;
begin
Result := SafeLoadLibrary(Name);
if Result = 0 then
raise EPackageError.CreateResFmt(@sErrorLoadingPackage,
[Name, SysErrorMessage(GetLastError)]);
try
// CheckForDuplicateUnits(Module);
@PackageLoad := GetProcAddress(Result, "Initialize"); //Do not localize
if Assigned(PackageLoad) then
PackageLoad else
raise Exception.CreateFmt(sInvalidPackageFile, [GetModuleName(Result)]);
except
FreeLibrary(Result);
raise;
end;
end;
function CreatePlugins : Integer;
var SR : TWin32FindData; SH : THandle; S : String; hLib : THandle; Usable : Boolean; Spi : TStatusPlugin; Idx : Integer;
GetNappProc : TStatusPluginGetNappProc;
CreateProc : TStatusPluginCreateProc;
begin
result := 0;
SH := FindFirstFile(PChar(ProgPath+cPluginDir+"*.bpl"), SR);
while SH <> INVALID_HANDLE_VALUE do if SR.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then begin
S := ProgPath+cPluginDir+SR.cFileName;
hLib := ForceLoadPackage(S);
if hLib <> 0 then begin
Usable := False;
@GetNappProc := GetProcAddress(hLib, PChar({c}{_s}cGetNappProcName));//changed by Malign 18.07.01
@CreateProc := GetProcAddress(hLib, PChar({c}{_s}cCreateProcName ));//changed by Malign 18.07.01
if (@GetNappProc <> nil) and (@CreateProc <> nil) and
(GetProcAddress(hLib, PChar(cDestroyProcName)) <> nil)
then begin
Idx := GetNappProc;
if (Idx >= Low(PlugIn)) and (Idx <= High(PlugIn)) {and PlugInAllowed(Idx)} and (PlugIn[Idx].piiHandle = 0) then begin
Spi := CreateProc;
if Spi <> nil then with PlugIn[Idx] do begin
piiHandle := hLib;
piiPlugIn := Spi;
Usable := True;
inc(result);
end;
end;
end;
if not Usable then UnloadPackage(hLib);
end;
if not FindNextFile(SH, SR) then begin
if SH <> INVALID_HANDLE_VALUE then Windows.FindClose(SH); SH := INVALID_HANDLE_VALUE;
end;
end;
end;
procedure DestroyPlugins;
var I : Integer; DestroyProc : TStatusPluginDestroyProc; //remed by Malign 18.07.01
begin
for I := Low(PlugIn) to High(PlugIn) do with PlugIn[I] do if piiHandle <> 0 then begin
@DestroyProc := GetProcAddress(piiHandle, PChar(cDestroyProcName)); //remed by Malign 18.07.01
if (@DestroyProc <> nil) then DestroyProc;
piiPlugIn := nil;
UnloadPackage(piiHandle);
piiHandle := 0;
end;
end;
function PluginByName(AName : String) : Integer;
var X : Integer;
begin
result := -1;
for X := Low(PlugIn) to High(PlugIn) do with PlugIn[X] do if piiPlugin <> nil then begin
if Trim(piiPlugin.Caption) = Trim(AName) then begin
result := X; Break;
end;
end;
end;
end.
← →
han_malign © (2002-10-28 17:10) [3]
unit Plugins;
interface
uses Windows, Utils, NetDefs, NetTraf, PluginDefs;
type
TPlugInInfo = packed record
piiHandle : THandle;
piiPlugIn : TStatusPlugin;
end;
var
PlugIn : array[0..cMaxNapp-1] of TPlugInInfo;
function CreatePlugins : Integer;
procedure DestroyPlugins;
function PluginByName(AName : String) : Integer;
implementation
uses SysUtils,SysConst;
function GetModuleName(Module: HMODULE): string;
var
ModName: array[0..MAX_PATH] of Char;
begin
SetString(Result, ModName, Windows.GetModuleFileName(Module, ModName, SizeOf(ModName)));
end;
function ForceLoadPackage(const Name: string): HMODULE;
type
TPackageLoad = procedure;
var
PackageLoad: TPackageLoad;
begin
Result := SafeLoadLibrary(Name);
if Result = 0 then
raise EPackageError.CreateResFmt(@sErrorLoadingPackage,
[Name, SysErrorMessage(GetLastError)]);
try
// CheckForDuplicateUnits(Module);
@PackageLoad := GetProcAddress(Result, "Initialize"); //Do not localize
if Assigned(PackageLoad) then
PackageLoad else
raise Exception.CreateFmt(sInvalidPackageFile, [GetModuleName(Result)]);
except
FreeLibrary(Result);
raise;
end;
end;
function CreatePlugins : Integer;
var SR : TWin32FindData; SH : THandle; S : String; hLib : THandle; Usable : Boolean; Spi : TStatusPlugin; Idx : Integer;
GetNappProc : TStatusPluginGetNappProc;
CreateProc : TStatusPluginCreateProc;
begin
result := 0;
SH := FindFirstFile(PChar(ProgPath+cPluginDir+"*.bpl"), SR);
while SH <> INVALID_HANDLE_VALUE do if SR.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then begin
S := ProgPath+cPluginDir+SR.cFileName;
hLib := ForceLoadPackage(S);
if hLib <> 0 then begin
Usable := False;
@GetNappProc := GetProcAddress(hLib, PChar({c}{_s}cGetNappProcName));//changed by Malign 18.07.01
@CreateProc := GetProcAddress(hLib, PChar({c}{_s}cCreateProcName ));//changed by Malign 18.07.01
if (@GetNappProc <> nil) and (@CreateProc <> nil) and
(GetProcAddress(hLib, PChar(cDestroyProcName)) <> nil)
then begin
Idx := GetNappProc;
if (Idx >= Low(PlugIn)) and (Idx <= High(PlugIn)) {and PlugInAllowed(Idx)} and (PlugIn[Idx].piiHandle = 0) then begin
Spi := CreateProc;
if Spi <> nil then with PlugIn[Idx] do begin
piiHandle := hLib;
piiPlugIn := Spi;
Usable := True;
inc(result);
end;
end;
end;
if not Usable then UnloadPackage(hLib);
end;
if not FindNextFile(SH, SR) then begin
if SH <> INVALID_HANDLE_VALUE then Windows.FindClose(SH); SH := INVALID_HANDLE_VALUE;
end;
end;
end;
procedure DestroyPlugins;
var I : Integer; DestroyProc : TStatusPluginDestroyProc; //remed by Malign 18.07.01
begin
for I := Low(PlugIn) to High(PlugIn) do with PlugIn[I] do if piiHandle <> 0 then begin
@DestroyProc := GetProcAddress(piiHandle, PChar(cDestroyProcName)); //remed by Malign 18.07.01
if (@DestroyProc <> nil) then DestroyProc;
piiPlugIn := nil;
UnloadPackage(piiHandle);
piiHandle := 0;
end;
end;
function PluginByName(AName : String) : Integer;
var X : Integer;
begin
result := -1;
for X := Low(PlugIn) to High(PlugIn) do with PlugIn[X] do if piiPlugin <> nil then begin
if Trim(piiPlugin.Caption) = Trim(AName) then begin
result := X; Break;
end;
end;
end;
end.
← →
AL2002 © (2002-10-28 17:43) [4]Так это плуги для Дельфи или вообще для программ?
← →
han_malign © (2002-10-28 17:56) [5]Упс - не понял вопроса наверное (это вообще для программ - bpl используется для того чтобы к основному приложениею правильно форму из DLL прилинковать (чтобы оди экземпляр Application был), и здесь обходится проверка уникльности имен подгружаемых модулей)
← →
Сатир © (2002-10-28 18:14) [6]2han_malign © (28.10.02 17:56)
Спасибо-спасибо, немного не по теме, но тоже очень интересно
а примерчики есть или линк, откуда взял?
← →
han_malign © (2002-10-28 18:22) [7]Сам ваял (вернее доделывал), из BPL-ки просто выдергивается функциональная форма, котороя прилепляется на основную (более полные исходники выслать не могу - комерческий проект - уволят к чертям)
← →
Сатир © (2002-10-28 21:34) [8]2Игорь Шевченко © (28.10.02 17:10)
спасибо за линк, уже себе поставил
бо я уже собирался писать что-то подобное (облегчённый вариант;), а шеф грит, что такое уже написано, но где лежит, сказать - не сказал/не помнил...
теперь осталось поковыряться в исходниках...
← →
Dimedrol © (2002-10-28 21:48) [9]Нуууу.... вот я юзаю свою технологию, типа.... ;-)
Посмотрел я, и вижу - у всех нормальных (не BPL!) реализациях плугинов
есть 1 существенный минус -
они "не видят" нормально данные основной программы.
Все реализации это были, так или иначе,
"советы" как в меню добавлять новые пунктики,
ка которыми стоят почти что вполне самостоятельные
программы, практически никак не связанные с главной прогой.
А я хочу вот как в Фотошопе ! ;-)
Чтобы туда-сюда общаться можно было, а ?!
Так вот я и придумал такую фичу :
все необходимые данные\переменные
оформил в виде рекорда,
и населяя этот рекорд данными
создаю системные евент(если нужно),
а так перебрасываю указатель на эту
сгенерированную структуру
из основной программы в плугин
и обратно.
Все построено на базе Messages.
В общем - уже почти год юзаю...
Тьфу,тьфу! 8-)
Все нормально.
Знай пописываю новые плугины и
основную прогу не трогаю...
Короче. если заинтересовало -
пиши на мыло !
Поговорим.
Удачи!
PS
А на счет там "коммерческий проееееект..."
я так вам скажу -
Human knowledge belongs to the world!
(C) Antitrust movie.
← →
vuk © (2002-10-28 21:52) [10]to Dimedrol:
>Чтобы туда-сюда общаться можно было, а ?!
Кстати, IDE Delphi со своим ToolsAPI представляет хороший пример того, как можно общаться "туда-сюда". Вся технология основана на интерфейсах.
← →
Сатир © (2002-10-29 13:12) [11]2Dimedrol © (28.10.02 21:48)
please, send me sources right here -> mailto:joe@ivl.kiev.ua
Страницы: 1 вся ветка
Текущий архив: 2002.11.18;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.022 c