📄 jvpluginmanager.pas
字号:
end;
{function TJvPluginManager.GetVersion: string;
begin
result := C_VersionString;
end;}
{procedure TJvPluginManager.SetVersion(newValue: string);
begin
end;}
function TJvPluginManager.GetPluginCount: Integer;
begin
Result := FPluginInfos.Count;
end;
function TJvPluginManager.GetPlugin(Index: Integer): TJvPlugIn;
var
PlgI: TPluginInfo;
begin
PlgI := FPluginInfos.Items[Index];
Result := PlgI.PlugIn;
end;
procedure TJvPluginManager.GetLoadedPlugins(PlugInList: TStrings);
var
I: Integer;
begin
PlugInList.BeginUpdate;
try
PlugInList.Clear;
for I := 0 to FPluginInfos.Count - 1 do
PlugInList.Add(Plugins[I].Name);
finally
PlugInList.EndUpdate;
end;
end;
// Create and add plugin - if error occurs, the Plugin is not added to list
function TJvPluginManager.AddCustomPlugin(PlugIn: TJvPlugIn): Boolean;
var
PlgInfo: TPluginInfo;
Counter: Integer;
begin
Result := False;
try
Result := PlugIn.Initialize(Self, Application, 'CustomPlugin');
if not Result then
Exit;
PlgInfo := TPluginInfo.Create;
PlgInfo.PluginKind := plgCustom;
PlgInfo.PlugIn := PlugIn;
FPluginInfos.Add(PlgInfo);
try
if Assigned(FOnBeforeNewCommand) then
FOnBeforeNewCommand(Self, PlugIn);
// Events for all new commands
if Assigned(FOnNewCommand) then
for Counter := 0 to PlugIn.Commands.Count - 1 do
with TJvPluginCommand(PlugIn.Commands.Items[Counter]) do
FOnNewCommand(Self, Caption, Hint, Data, ShortCut, Bitmap, OnExecute);
finally
if Assigned(FOnAfterNewCommand) then
FOnAfterNewCommand(Self, PlugIn);
end;
except
on E: Exception do
begin
if not (csDesigning in ComponentState) and Assigned(FOnPlugInError) then
FOnPlugInError(Self, E)
else
raise;
end;
end;
end;
// Load a Plugin - either DLL or package
procedure TJvPluginManager.LoadPlugin(FileName: string; PlgKind: TPluginKind);
type
TSxRegisterPlugin = function: TJvPlugIn; stdcall;
var
Counter: Integer;
LibHandle: Integer;
RegisterProc: TSxRegisterPlugin;
PlugIn: TJvPlugIn;
NumCopies: Integer;
PlgInfo: TPluginInfo;
AllowLoad: Boolean;
begin
LibHandle := 0;
AllowLoad := True;
if Assigned(FOnBeforeLoad) then
FOnBeforeLoad(Self, FileName, AllowLoad);
if AllowLoad then
begin
try
LibHandle := 0;
PlugIn := nil;
case PlgKind of
plgDLL:
LibHandle := LoadLibrary(PChar(FileName));
plgPackage:
LibHandle := LoadPackage(FileName);
end;
if LibHandle = 0 then
raise EJvLoadPluginError.CreateResFmt(@RsEPluginPackageNotFound, [FileName]);
AllowLoad := True;
if Assigned(FOnAfterLoad) then
FOnAfterLoad(Self, FileName, LibHandle, AllowLoad);
if not AllowLoad then
begin
UnloadLibrary(PluginKind, LibHandle);
Exit;
end;
// Load the registration procedure
RegisterProc := GetProcAddress(LibHandle, C_REGISTER_PLUGIN);
if not Assigned(RegisterProc) then
raise EJvLoadPluginError.CreateResFmt(@RsERegisterPluginNotFound, [C_REGISTER_PLUGIN, FileName]);
// register the plugin
PlugIn := RegisterProc;
if PlugIn = nil then
raise EJvCantRegisterPlugInError.CreateResFmt(@RsERegisterPluginFailed, [C_REGISTER_PLUGIN, FileName]);
// make sure we don't load more copies of the plugin than allowed
if PlugIn.InstanceCount > 0 then // 0 = unlimited
begin
NumCopies := 0;
for Counter := 0 to FPluginInfos.Count - 1 do
if Plugins[Counter].PluginID = PlugIn.PluginID then
Inc(NumCopies);
if NumCopies >= PlugIn.InstanceCount then
begin
PlugIn.Free;
Exit; // Todo : Don't know what Skipload does here
end;
end; // if Plugin.InstanceCount > 0
// initialize the plugin and add to list
if AddCustomPlugin(PlugIn) then
begin
PlgInfo := FPluginInfos.Last;
PlgInfo.PluginKind := PlgKind;
PlgInfo.Handle := LibHandle;
end;
except
//!11 if - for whatever reason - an exception has occurred
// free Plugin and library
// (rom) statements used twice could be wrapped in method
on E: Exception do
begin
FreeAndNil(PlugIn);
if LibHandle <> 0 then
UnloadLibrary(PlgKind, LibHandle);
if not (csDesigning in ComponentState) and Assigned(FOnPlugInError) then
FOnPlugInError(Self, E)
else
raise;
end;
end;
end;
end;
// Load all plugins in the plugin-folder
// exceptions can only be seen through the OnErrorLoading-Event
procedure TJvPluginManager.LoadPlugins;
var
FileName: string;
Found: Integer;
Path: string;
Sr: TSearchRec;
begin
// if the PluginPath is blank, we load from the app's folder.
if FPluginFolder = '' then
Path := ExtractFilePath(Application.ExeName)
else
Path := FPluginFolder;
Path := IncludeTrailingPathDelimiter(Path);
try
try
Found := FindFirst(Path + '*.' + FExtension, 0, Sr);
while Found = 0 do
begin
FileName := Sr.Name;
//! If one plugin made problems -> no other plugins where loaded
//! To avoid that the try-except block was wrapped around here...
try
LoadPlugin(Path + FileName, PluginKind);
except
end;
Found := FindNext(Sr);
end;
except
on E: Exception do
begin
if not (csDesigning in ComponentState) and Assigned(FOnPlugInError) then
FOnPlugInError(Self, E)
else
raise;
end;
end;
finally
FindClose(Sr);
end;
end;
procedure TJvPluginManager.UnloadPlugin(Index: Integer);
var
PlgI: TPluginInfo;
begin
PlgI := FPluginInfos.Items[Index];
PlgI.PlugIn.Free;
UnloadLibrary(PlgI.PluginKind, PlgI.Handle);
PlgI.Free;
FPluginInfos.Delete(Index);
end;
procedure TJvPluginManager.SendMessage(PluginMessage: Longint; PluginParams: string);
var
I: Integer;
begin
for I := 0 to FPluginInfos.Count - 1 do
Plugins[I].SendPluginMessage(PluginMessage, PluginParams);
end;
procedure TJvPluginManager.UnloadLibrary(Kind: TPluginKind;
LibHandle: Integer);
begin
case Kind of
plgDLL:
FreeLibrary(LibHandle);
plgPackage:
UnloadPackage(LibHandle);
end;
end;
{$IFDEF UNITVERSIONING}
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -