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. oracle 11g SQL Developer instead of isqlplus

    Oracle11g的新工具SQL DEVELOPER,替代了 isqlplus 1.创建连接方式 2.SQL输入窗口 3.表的结构及其他信息查阅 4.SQL语句测试 5.创建表 6.用户授权 7.数据 ...

  2. [51NOD]BSG白山极客挑战赛

    比赛链接:http://www.51nod.com/contest/problemList.html#!contestId=21 /* ━━━━━┒ギリギリ♂ eye! ┓┏┓┏┓┃キリキリ♂ min ...

  3. The dialect was not set. Set the property hibernate.dialect

    The   dialect   was   not   set.   Set   the   property   hibernate.dialect load hibernate.cfg.xml 出 ...

  4. Codeforces Round #271 (Div. 2)

    A. Keyboard 题意:一个人打字,可能会左偏一位,可能会右偏一位,给出一串字符,求它本来的串 和紫书的破损的键盘一样 #include<iostream> #include< ...

  5. UVA 10537 The Toll! Revisited uva1027 Toll(最短路+数学坑)

    前者之所以叫加强版,就是把uva1027改编了,附加上打印路径罢了. 03年的final题哦!!虽然是水题,但不是我这个只会做图论题的跛子能轻易尝试的——因为有个数学坑. 题意:运送x个货物从a-&g ...

  6. I.MX6 开启 1000Mb/s interface

    /*********************************************************************** * I.MX6 开启 1000Mb/s interfa ...

  7. 【流媒體】live555—VS2010 下live555编译、使用及测试

    Ⅰ live555简介 Live555 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如RTP/RTCP.RTSP.SIP等的支持.Live555实现了对多种音视频编 ...

  8. 【Unity3D】枪战游戏—发射子弹、射线检测

    一.子弹的碰撞检测: 因为子弹的移动速度非常的快,那么如果为子弹添加一个collider,就有可能检测不到了. 因为collider是每一帧在执行,第一帧子弹可能在100米处,那么下一帧就在900米处 ...

  9. js中json与数组字符串的相互转化

    <SCRIPT LANGUAGE="JavaScript"> var t="{'firstName': 'cyra', 'lastName': 'richar ...

  10. mysql 基础命令入门学习

    登陆到mysql mysql -u 用户名 -p [数据库]   显示数据库 show databases;   使用一个数据库 use 数据库名;   显示表 show tables;   纠正数据 ...