1)非RTTI方式适用于所有的DELPHI版本

unit untMain;

interface

uses
Windows, Messages, SysUtils,
Classes, Graphics,
Controls, Forms, Dialogs,
ExtCtrls, Buttons;

type
TFrmMain = class(TForm)
Panel1: TPanel;
SpeedButton1: TSpeedButton;
procedure btnClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
procedure LoadPlugin(const formClass: string);
public
{ Public declarations }
end;

var
FrmMain: TFrmMain;

implementation

{$R *.dfm}

procedure TFrmMain.btnClick(Sender: TObject);
var
h: Integer;
formClass, bplFile: string;
begin
if SameText(TSpeedButton(Sender).Caption, '系统一') then
begin
bplFile := 'bplTest1.bpl';
formClass := 'TfrmTest1';
end;

if TSpeedButton(Sender).Tag = 0 then
begin
if FileExists(bplFile) then
begin
h := LoadPackage(bplFile);
if h = 0 then
ShowMessage(bplFile + ' 包加载失败')
else
begin
TSpeedButton(Sender).Tag := h;
end;
end
else
ShowMessage(bplFile + ' 没有找到');
end;

LoadPlugin(formClass);
end;

procedure TFrmMain.FormDestroy(Sender: TObject);
var
i: integer;
begin
for i := 0 to Panel1.ComponentCount - 1 do
begin
if TSpeedButton(Panel1.Components[i]).Tag <> 0 then
UnloadPackage(TSpeedButton(Panel1.Components[i]).Tag);
end;
end;

procedure TFrmMain.LoadPlugin(const formClass: string);
var
form: TForm;
begin
form := TFormClass(FindClass(formClass)).Create(Self);
form.Position := poScreenCenter;
form.Show;
end;

end.

2)RTTI方式,适用于2009以上版本

unit untMain;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Generics.Collections,
System.Rtti, Vcl.ExtCtrls, Vcl.Buttons;

type
TFrmMain = class(TForm)
Panel1: TPanel;
SpeedButton1: TSpeedButton;
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnClick(Sender: TObject);
private
{ Private declarations }
bplList: TDictionary<string, Integer>;
procedure LoadPlugin(const bplFile, unitClass: string);
public
{ Public declarations }
end;

var
FrmMain: TFrmMain;

implementation

{$R *.dfm}

procedure TFrmMain.btnClick(Sender: TObject);
var
h: Integer;
bplFile: string;
unitClass: string;
begin
if SameText(TSpeedButton(Sender).Caption, '系统一') then
begin
bplFile := 'bplTest1.bpl';
unitClass := 'untTest1.TfrmTest1';
end;

if TSpeedButton(Sender).Tag = 0 then
begin
if FileExists(bplFile) then
begin
h := LoadPackage(bplFile);
if h = 0 then
ShowMessage(bplFile + ' 包加载失败')
else
begin
bplList.Add(bplFile, h);
TSpeedButton(Sender).Tag := h;
end;
end;
end;

LoadPlugin(bplFile, unitClass);
end;

procedure TFrmMain.FormCreate(Sender: TObject);
begin
bplList := TDictionary<string, Integer>.Create;
end;

procedure TFrmMain.FormDestroy(Sender: TObject);
var
i: Integer;
begin
if Assigned(bplList) then
begin
for i in bplList.Values do
UnloadPackage(i);
FreeAndNil(bplList);
end;
end;

procedure TFrmMain.LoadPlugin(const bplFile, unitClass: string);
var
LContext: TRttiContext;
LPackage: TRttiPackage;
LClass: TRttiInstanceType;
aForm: TForm;
begin
if (bplFile = '') or (unitClass = '') then
Exit;

LContext := TRttiContext.Create;
try
try
for LPackage in LContext.GetPackages() do
begin
if SameText(ExtractFileName(LPackage.Name), bplFile) then
begin
LClass := LPackage.FindType(unitClass) as TRttiInstanceType;
aForm := LClass.MetaclassType.Create as TForm;
aForm.Create(nil);
aForm.WindowState := wsNormal;
aForm.Position := poScreenCenter;
aForm.Show;
end;
end;
except
ShowMessage('单元名和类名是大小写敏感的');
end;
finally
LContext.Free;
end;
end;

end.

BPL插件框架的二种实现的更多相关文章

  1. 终于可以发布Delphi下收点OSGI精髓皮毛而设计的插件框架WisdomPluginFramework

    这是一个Delphi实现的插件框架,我耗费了相当相当相当多的精力来设计她,虽然仅闪着点我微薄智慧的光芒,但我还是决定用Wisdom来命名她,也因它是我绝无仅有的,在完成1年多后回头来看仍能相当满意的作 ...

  2. Delphi 的插件框架 WisdomPluginFramework

    WisdomPluginFramework是融合OSGI微内核理念 + Eclipse的扩展点概念而精心设计的轻量级插件框架, 由Delphi实现,但可以使用于Delphi.BCB.VC++中,提供非 ...

  3. MVC系列——MVC源码学习:打造自己的MVC框架(二:附源码)

    前言:上篇介绍了下 MVC5 的核心原理,整篇文章比较偏理论,所以相对比较枯燥.今天就来根据上篇的理论一步一步进行实践,通过自己写的一个简易MVC框架逐步理解,相信通过这一篇的实践,你会对MVC有一个 ...

  4. JavaScript 框架设计(二)

    JavaScript 高级框架设计 (二) 上一篇,JavaScript高级框架设计(一)我们 实现了对tag标签的选择 下来我们实现对id的选择,即id选择器. 我们将上一篇的get命名为getTa ...

  5. 简单的c#插件框架

    插件式架构,一种全新的.开放性的.高扩展性的架构体系.插件式架构设计近年来非常流行,基于插件的设计好处很多,把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现.扩展功能与框架以一种很松的 ...

  6. (转载)eclipse插件安装的四种方法

    eclipse插件安装的四种方法 Eclipse插件的安装方法 1.在eclipse的主目录(ECLIPSE_HOME, 比如在我的机器上安装的目录是:D:\eclipse)有一个plugins的目录 ...

  7. Dynamic CRM 2013学习笔记(二十)字段改变事件的二种实现方法

    CRM里有二种方式实现字段change事件,一种是在form里,一种完全通过js来实现.本文介绍下二者的用途及区别. 1. Form里用法 这种方式估计其实也是添加一个js的function. 这种方 ...

  8. [原创]Android插件化的一种实现

    Android的插件化已经是老生常谈的话题了,插件化的好处有很多:解除代码耦合,插件支持热插拔,静默升级,从根本上解决65K属性和方法的bug等等. 下面给大家介绍一下我们正在用的插件化框架.本片主要 ...

  9. 如何在Exe和BPL插件中实现公共变量共享及窗口溶入技术Demo源码

    如何在Exe和BPL插件中实现公共变量共享及窗口溶入技术Demo源码 1.Delphi编译方式介绍: 当我们在开发一个常规应用程序时,Delphi可以让我们用两种方式使用VCL,一种是把VCL中的申明 ...

随机推荐

  1. ConcurrentDictionary和Dictionary

    http://stackoverflow.com/questions/6739193/is-the-concurrentdictionary-thread-safe-to-the-point-that ...

  2. 【Todo】【转载】ES6的学习记录

    粗略看了一遍React的内容,然后看了 ES6 的入门文章: http://es6.ruanyifeng.com/#docs/intro 通过这个链接可以查看浏览器对 ES6 的支持程度: http: ...

  3. SQL SERVER 2008筛选时报错 无法为该请求检索数据

    使用SqlServer2008的筛选功能时报错“无法为该请求检索数据. (Microsoft.SqlServer.Management.Sdk.Sfc)” 如下图: 解决方法: 打上SQL SERVE ...

  4. UVa 10561 (SG函数 递推) Treblecross

    如果已经有三个相邻的X,则先手已经输了. 如果有两个相邻的X或者两个X相隔一个.,那么先手一定胜. 除去上面两种情况,每个X周围两个格子不能再放X了,因为放完之后,对手下一轮再放一个就输了. 最后当“ ...

  5. UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design

    题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi  ...

  6. CodeForces 489C (贪心) Given Length and Sum of Digits...

    题意: 找出m位且各个数位数字之和为s的最大和最小整数,不包括前导0(比如说003是非法的),但0是可以的. 分析: 这题是用贪心来做的,同样是m位数,前面的数字越大这个数就越大. 所以写一个can( ...

  7. php linux部署相关

    http://www.itbulu.com/wdcp-php55.html http://www.wdlinux.cn/wdcp/install.html http://www.yiichina.co ...

  8. fzu 1675 The Seventy-seven Problem

    给你长度为 10^5~10^6长度,由数字组成的串 其中有4位不见了 补全该串 使得在该串能整除 77的同时 尽可能大// 先计算出每个 n*10^m 模 77 的循环节 n=0,1,2..,9// ...

  9. JazzyViewPager开源项目的简析及使用

    JazzyViewPager是一个重写的ViewPager,能是ViewPager滑动起来更加的炫酷. 开源地址:https://github.com/jfeinstein10/JazzyViewPa ...

  10. hisi平台mii网络模式和rmii网络模式的uboot制作

    MII网络uboot编译说明 一:编译生成默认的uboot1. 进入到uboot目录a. cd /home/satan/Hi3518_SDK_V1.0.7.0/osdrv/uboot2. 新建临时文件 ...