转载自:http://blog.youkuaiyun.com/henreash/article/details/7029844
1. 新建一个exe执行文件作为主框架,并建立一个存放插件类的单元,建立插件类TTestClass.接着新添加一个单元TestClasses1,在其中添加一个继承于TTestClass的类TTestClass1,并在单元的initialization节中调用基类TTestClasses1的RegistClass方法注册类型.
其中RegistClass方法为类方法;
class procedure RegistClass;
class function GetRegistClasses: TStrings;
步骤:
1.1、 创建一个Application , 如下图
保存单元UMain.pas ,项目文件为 Main.dpr, 即编译出来的exe为 Main.exe
窗体如下图:
UMain.pas代码为:
unit UMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btn1: TButton;
btn2: TButton;
cbClassName: TComboBox;
procedure btn1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
HModel: Cardinal;
HDll: Cardinal;
implementation
uses
TestClasses;
{$R *.dfm}
//按钮1的单击事件
procedure TForm1.btn1Click(Sender: TObject);
var
oList: TStrings;
i: Integer;
oClass: TTestClassClass;
oObj: TTestClass;
begin
oList := TTestClass.GetRegistClasses;
for i := 0 to oList.Count - 1 do
begin
oClass := TTestClassClass(oList.Objects[i]);
oObj := oClass.Create;
ShowMessage(oClass.ClassName);
oObj.ShowSomeMessage;
oObj.Free;
end;
end;
//窗口的关闭事件
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
UnloadPackage(HModel);//卸载运行时包
end;
//窗口的创建事件
procedure TForm1.FormCreate(Sender: TObject);
var
oList: TStrings;
I: Integer;
begin
HModel := LoadPackage('Package1.bpl');
HDll := LoadLibrary('PjtDll.dll');
oList := TTestClass.GetRegistClasses;
cbClassName.Items.BeginUpdate;
cbClassName.Items.Clear;
for I := 0 to oList.Count - 1 do
begin
cbClassName.Items.Add(oList.ValueFromIndex[I]);
end;
if (oList.Count > 0) then
cbClassName.ItemIndex := 0;
cbClassName.Items.EndUpdate;
end;
//按钮2的单击事件
procedure TForm1.btn2Click(Sender: TObject);
var
oList: TStrings;
i: Integer;
oClass: TTestClassClass;
oObj: TTestClass;
pClass: TClass;
strClass: string;
begin
oList := TTestClass.GetRegistClasses;
oClass := TTestClassClass(oList.Objects[oList.IndexOf(cbClassName.Text)]);
oObj := oClass.Create;
pClass := oObj.ClassType;
while (pClass <> nil) do
begin
strClass := strClass + #10#13 + '-- ' + pClass.ClassName;
pClass := pClass.ClassParent;
end;
ShowMessage(strClass) ;//oClass.ClassName);
oObj.ShowSomeMessage;
oObj.Free;
end;
end.
1.2、 创建TestClasses.pas
File-->New-->Unit, 命名为TestClasses.pas,代码如下:
unit TestClasses;
interface
uses Windows, Classes, SysUtils;
type
TTestClassClass = class of TTestClass;
TTestClass = class(TObject) //
class procedure RegistClass;//类过程
class function GetRegistClasses: TStrings;//类函数
procedure ShowSomeMessage; virtual; //定义虚方法,子类实现
end;
implementation
var
FClassList: TStringList;
{ TTestClass }
class function TTestClass.GetRegistClasses: TStrings;
begin
Result := FClassList;
end;
class procedure TTestClass.RegistClass;
begin
FClassList.AddObject(Self.ClassName, TObject(Self));
end;
procedure TTestClass.ShowSomeMessage;
begin
raise Exception.Create('not implementation');
end;
initialization
if (not Assigned(FClassList)) then
FClassList := TStringList.Create;
finalization
if (Assigned(FClassList)) then
FreeAndNil(FClassList);
end.
1.3、 类似1.2, 添加TestClasses1.pas,代码如下:
unit TestClasses1;
interface
uses Windows, Classes, TestClasses, Dialogs;
type
TTestClasses1 = class(TTestClass)
procedure ShowSomeMessage; override;
end;
implementation
{ TTestClasses1 }
procedure TTestClasses1.ShowSomeMessage;
begin
ShowMessage('TestClasses1');
end;
initialization
TTestClasses1.RegistClass;
end.
2. 创建运行时包,将TestClasses单元添加到Contains中,并新建一个TestClasses2单元(同TestClasses1).
2.1、创建运行时包
a、File-->New-->Other , 如下图:
b、在Contains,添加TestClasses.pas, 新建TestClasses2.pas(和1.2一样) ,并添加到Contains中
TestClasses2.pas代码如下:
unit TestClasses2;
interface
uses Windows, Classes, TestClasses, Dialogs;
type
TTestClasses2 = class(TTestClass)
procedure ShowSomeMessage; override;
end;
implementation
{ TTestClasses2 }
procedure TTestClasses2.ShowSomeMessage;
begin
ShowMessage('TestClasses2');
end;
initialization
TTestClasses2.RegistClass ;
end.
c、编译 Package1,然后安装,到 Delphi7的安装目录中的Borland\Delphi7\Projects\Bpl中取出Package1.bpl,放到和Main.exe的同意目录下。
3. 创建DLL工程,将TestClasses单元添加到工程中,并创建一个TestClasses4单元(同TestClasses1)
3.1、创建dll
a、创建Dll,命名为PjtDll.dpr, 即编译出来为PjtDll.dll
File-->New-->Other , 如下图:
b、添加TestClasses.pas到 Dll中,同时创建TestClasses3.pas(步骤如:1.2 创建TestClasses) ,
TestClasses3.pas代码如下:
unit TestClasses3;
interface
uses Windows, Classes, TestClasses, Dialogs;
type
TTestClasses3 = class(TTestClass)
procedure ShowSomeMessage; override;
end;
implementation
{ TTestClasses3 }
procedure TTestClasses3.ShowSomeMessage;
begin
ShowMessage('TestClasses3');
end;
initialization
TTestClasses3.RegistClass ;
end.
4. 将第1,3两步创建的工程改为带包编译(需包括步骤2所创建的包)
步骤:菜单栏-->Project-->Options的Packages页面中;
4.1、Main.exe带包编译设置如下图
4.2、PjtDll.dpr带包编译设置如下图:
5. 在exe项目中调用LoadLibrary导入dll及LoadPackage 导入bpl ;
实现效果:
带包编译的情况下,点击按钮可以分别调用bpl,dll,exe中创建的TestClasses子类方法.具体开发中在主程序中动态查找bpl或dll并将其装载即可使用其中的类及方法.
转载自:http://blog.youkuaiyun.com/henreash/article/details/7029844