{*******************************************************}
{ }
{ 插件管理 }
{ }
{ 版权所有 (C) 2008 咏南工作室(陈新光) }
{ }
{*******************************************************}
unit untMPlg;
interface
uses
Classes,Windows, Messages, SysUtils, Variants,
Graphics, Controls, Inifiles,Forms,menus,dialogs;
Type
PDescPlg = ^TDescPlg;
TDescPlg = record
MName:pchar; //菜单名
PMItemName:pchar; //父菜单名
MForm:integer; //模式窗体?
end;
TPlgDesc = function :Pointer;stdcall;
TShowPlgForm = function(AHandle:THandle;mForm:integer;AOwner:TWinControl):Pointer;stdcall;
TClosePlgForm = procedure(AForm:Pointer);stdcall;
{ 插件状态保存 }
TPlgHolder = class(TObject)
private
FDllHandle:integer; //插件DLL地址
FPForm:Pointer; //Form的地址
FMForm:integer; //模式窗体
FPlgName:string; //插件名(即在菜单上显示的名字)
FHostHandle:THandle;
FOwner:TWinControl; // 非模式窗体的父控件
public
procedure ClickHandler(Sender: TObject);
published
property DLLHandle:integer read FDllHandle write FDllHandle;
property MForm:integer read FMForm write FMForm;
property PlgName:string read FPlgName write FPlgName;
property HostHandle:THandle read FHostHandle write FHostHandle;
property FormOwner:TWinControl read FOwner write FOwner;
end;
{ 插件管理 }
TMplg = class(TObject)
private
FPlgForms:TStrings;
FMenu: TMenu;
FMPlgHostHandle:THandle;
FMplgFormOwner:TWinControl;
public
Constructor Create;
destructor Destory;
procedure GetPlgLists;
procedure LoadPlugin(sr: TSearchRec);
published
property menu: TMenu read FMenu write FMenu;
property MplgHostHandle:THandle read FMPlgHostHandle write FMPlgHostHandle;
property MplgFormOwner:TWinControl read FMplgFormOwner write FMplgFormOwner;
end;
var
Mplg :TMplg;
implementation
uses untMain;
{ TMplg }
procedure TMplg.GetPlgLists;
var
sr: TSearchRec;
path: string;
Found: Integer;
begin
path := ExtractFilePath(Application.Exename);
try
Found := FindFirst(path + 'Plugins/*.dll', 0, sr);
while Found = 0 do begin
LoadPlugin(sr);
Found := FindNext(sr);
end;
finally
FindClose(sr);
end;
end;
procedure TMplg.LoadPlugin(sr: TSearchRec);
var
DescribeProc: TPlgDesc;
DLLhandle :integer;
i:integer;
APlgHolder:TPlgHolder;
MItem : TMenuItem;
{ 包自描述内容 }
MName:pchar; //菜单名
PMItemName:pchar; //父菜单名
MForm:integer; //模式窗体?
begin
DLLHandle := LoadLibrary(PChar('Plugins/'+(sr.Name)));
if DLLHandle <> 0 then
begin
// 查找 DescribePlugin.
DescribeProc := GetProcAddress(DLLHandle, 'PlgDesc');
if Assigned(DescribeProc) then
begin
PMItemName := PDescplg(DescribeProc)^.PMItemName;
MForm := PDescplg(DescribeProc)^.MForm;
MName := PDescplg(DescribeProc)^.MName;
APlgHolder := TPlgHolder.Create;
APlgHolder.DLLHandle := DLLhandle;
APlgHolder.MForm := MForm ;
APlgHolder.PlgName := MName;
AplgHolder.HostHandle := FMPlgHostHandle;
APlgHolder.FormOwner := FMplgFormOwner;
{ 动态创建菜单 }
MItem := TMenuItem.Create(nil);
MItem.OnClick := APlgHolder.ClickHandler;
MItem.Caption := APlgHolder.PlgName;
for i:=0 to FMenu.Items.Count-1 do
begin
if FMenu.Items[i].name = PMItemName then
begin
FMenu.items[i].Add(MItem);
break;
end;
end;
FPlgForms.AddObject(APlgHolder.PlgName,APlgHolder);
end;
end;
end;
constructor TMplg.Create;
begin
FPlgForms := TStringList.Create;
end;
destructor TMplg.Destory;
var
i:integer;
APlgHolder:TPlgHolder;
ClosePlgForm:TClosePlgForm;
begin
for i := 0 to FPlgForms.Count-1 do
begin
APlgHolder := TPlgHolder(FPlgForms.Objects[i]);
if APlgHolder.MForm = 0 then // 非模式窗体释放
begin
ClosePlgForm := GetProcAddress(APlgHolder.DLLHandle,'ClosePlgForm');
if assigned(ClosePlgForm) then
begin
if assigned(APlgHolder.FPForm) then
begin
ClosePlgForm(APlgHolder.FPForm);
ClosePlgForm := nil;
end;
end;
end;
FreeLibrary(APlgHolder.DLLHandle);
end;
end;
{ THolder }
procedure TPlgHolder.ClickHandler(Sender: TObject);
var
ShowPlgForm :TShowPlgForm;
begin
ShowPlgForm := GetProcAddress(FDllHandle, 'ShowPlgForm');
if assigned(FPForm) then
showmessage('ss');
FPForm := ShowPlgForm(HostHandle,FMForm,FOwner);
if assigned(FPForm) then
showmessage(IntToStr(Integer(FPForm)));
end;
end.
//主窗口获取插件
procedure TfrmMain.Button2Click(Sender: TObject);
begin
Mplg.GetPlgLists;
end;
procedure TfrmMain.FormShow(Sender: TObject);
begin
Mplg := TMplg.Create;
MPlg.menu := mmMain;
MPlg.MplgHostHandle := Application.MainForm.Handle;
MPlg.MplgFormOwner := tabsheet4;
end;
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
MPlg.Destory;
end;
library plgAdd;
uses
SysUtils,
Classes,forms,Controls,
untPlgView in 'untPlgView.pas' {frmPlgView};
{$R *.res}
type
PDescPlg = ^TDescPlg;
TDescPlg = record
MName:pchar; //菜单名
PMItemName:pchar; //父菜单名
MForm:integer; //模式窗体?
end;
var
Desc:TDescPlg;
function ShowPlgForm(AHandle:THandle;mForm:integer;AOwner:TWinControl):Pointer;stdcall;
var
clientForm:TfrmPlgView;
begin
Application.Handle := AHandle;
clientForm := TfrmPlgView.create(Application);
case mForm of
1:begin //模式窗体
try
clientForm.ShowModal;
finally
freeandnil(clientForm);
end;
end;
0:begin //非模式窗体
clientForm.Parent := AOwner;
clientForm.Align := alClient;
clientForm.BorderStyle := bsNone;
clientForm.show;
end;
end;
Result := Pointer(clientForm);
end;
procedure ClosePlgForm(AForm:Pointer);stdcall;
begin
if assigned(AForm) then TfrmPlgView(AForm).close;
end;
function PlgDesc:Pointer;stdcall;
begin
desc.MName := '增加结点';
desc.PMItemName := PChar('Plugin');
desc.MForm := 1;
Result := @desc;
end;
exports
ShowPlgForm,ClosePlgForm,PlgDesc;
begin
end.
library plgView;
uses
SysUtils,
Classes,forms,Controls,
untPlgView in 'untPlgView.pas' {frmPlgView};
{$R *.res}
type
PDescPlg = ^TDescPlg;
TDescPlg = record
MName:pchar; //菜单名
PMItemName:pchar; //父菜单名
MForm:integer; //模式窗体?
end;
var
Desc:TDescPlg;
function ShowPlgForm(AHandle:THandle;mForm:integer;AOwner:TWinControl):Pointer;stdcall;
var
clientForm:TfrmPlgView;
begin
Application.Handle := AHandle;
clientForm := TfrmPlgView.create(Application);
case mForm of
1:begin
try
clientForm.ShowModal;
finally
freeandnil(clientForm);
end;
end;
0:begin
clientForm.Parent := AOwner;
clientForm.Align := alClient;
clientForm.BorderStyle := bsNone;
clientForm.show;
end;
end;
Result := Pointer(clientForm);
end;
procedure ClosePlgForm(AForm:Pointer);stdcall;
begin
//Desc := nil;
if assigned(AForm) then TfrmPlgView(AForm).close;
end;
function PlgDesc:Pointer;stdcall;
begin
desc.MName := '查看结点';
desc.PMItemName := PChar('Plugin');
desc.MForm := 0;
Result := @desc;
end;
exports
ShowPlgForm,ClosePlgForm,PlgDesc;
begin
end.