Delphi中Package是一件非常强大的工具,用的好可以起到非常清晰的
划分程序结构的作用。因为他内建描述信息,可以和当前代码无缝集成起来,
可以保护包括类在内的任何元素,相当于VC中的MFC Extension DLL的作用。
但是一直以来的文章都只介绍静态连接的方法,这其实限制了Package的使用
因为静态连接的Package失去了其灵活性,可配置性等等。至于通过函数入口
方式访问,实在是大材小用,那不如直接用DLL还方便一些。
如何动态载入Package,使用其中的类、函数、变量等等?起始说穿了很
简单,就是做一个代理包。因为在一个Delphi程序中,每个unit只能存在
一份,否则发生冲突。要动态载入包,又得取得其中信息,又不能直接uses
包含信息的unit(否则引起冲突),解决办法是另外建一个代理包来作为桥梁
传递信息。下面是一个简单的例子,主程序使用到两个包,DemoPak包中有
一个简单的Form;RegPak是所谓的代理包,起到注册信息的作用。
主程序对RegPak静态使用(在Project Options里面设置了),对DemoPak
动态载入(通过LoadPackage),而DemoPak依赖于RegPak(requires),
并在初始化时向代理包RegPak注册自己的可用类,这里举例注册类信息,
你可以方便的改成注册其他信息
unit FormReg;
interface
uses
Classes, SysUtils, Forms, Contnrs;
type
TFormClass = class of TForm;
procedure RegisterFormClass(const AName: string
const AFormClass: TFormClass);
procedure UnregisterFormClass(const AName: string);
function FindFormClass(const AName: string): TFormClass;
implementation
var
g_lstNames: TStringList;
g_lstForms: TClassList;
procedure RegisterFormClass(const AName: string
const AFormClass: TFormClass);
begin
g_lstNames.Add(AName);
g_lstForms.Add(AFormClass);
end;
procedure UnregisterFormClass(const AName: string);
var
Index: Integer;
begin
Index := g_lstNames.IndexOf(AName);
if Index <> -1 then
begin
g_lstNames.Delete(Index);
g_lstForms.Delete(Index);
end;
end;
function FindFormClass(const AName: string): TFormClass;
var
I: Integer;
begin
for I := 0 to g_lstNames.Count - 1 do
begin
if g_lstNames
= AName then
begin
Result := TFormClass(g_lstForms.Items);
Exit;
end;
end;
Result := nil;
end;
initialization
g_lstNames := TStringList.Create;
g_lstForms := TClassList.Create;
finalization
FreeAndNil(g_lstForms);
FreeAndNil(g_lstNames);
end.
以上是RegPak的主要代码,因为举例,代码很简陋。主要思想就是保存注册信息,
提供查询方法。让我们看看在DemoPak中的使用
unit AboutForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfrmAbout = class(TForm)
lblAbout: TLabel;
private
public
end;
var
frmAbout: TfrmAbout;
implementation
uses FormReg;
{$R *.dfm}
initialization
RegisterFormClass(TfrmAbout.ClassName, TfrmAbout);
finalization
UnregisterFormClass(TfrmAbout.ClassName);
end.
在初始化时向RegPak的FormReg单元提交自己的类信息,因为每个Package在载入时
无论动态静态都会自动初始化,而RegPak被主程序静态引用,肯定已经初始化,所以直接
注册即可,非常简单。最后看看主程序中的使用
uses
FormReg;
procedure TfrmMain.btnAboutClick(Sender: TObject);
var
hModule: THandle;
begin
hModule := LoadPackage('DemoPak.bpl');
try
with FindFormClass('TfrmAbout').Create(nil) do
try
ShowModal;
finally
Free;
end;
finally
UnloadPackage(hModule);
end;
end;
动态载入需要的包,查询需要的类的信息,使用之,最后卸载包。
很简单吧 起始很多东西都没有什么技术难度的,关键看你想不想得到