如何使用Runtime Package
By Kingron, 2005-04-21
Answer for bigery
大家都知道使用DLL,非常方便,而Delphi提供了Package的功能,特别是Runtime Package,可以使用类似DLL的功能,然而可以比DLL功能更强大和方便,使用Package可以提高模快重用能力!
下面以如何使用一个函数和一个窗体为例,来说明如何使用Runtime Package。
预计:在Package里面,提供一个Password对话框窗体,提供一个函数,GetRandString(Len: Integer): string。
首先你建立一个Package,设置Package Options为Run Time Package。
然后New一个Form,设置好Password之类的一些界面的东西。并和DLL一样,编写一个函数,注意需要在Interface部分声明。
然后编写代码,Build生成一个DCP和BPL文件。
接下来编写调用Package的工程。
New一个Project,然后设置Project Options,到Pacages页面中,选中 Build with runtime Packages,把其中不需要的删除!不删除那些默认的也可以,不过你需要带VCL的runtime Package,会很大的,如果不带,你的程序在没有安装Delphi的机器上面无法运行,如果使用Pacakge,你的Pacakge文件(bpl)需要同时发布给客户。
修改好Project Options后,在你的需要使用Package中的单元的地方,在use部分添加package中的单元名即可。以后即可和同工程中的文件一样使用,非常方便。
需要注意的是,使用的时候,由于Package 的Form不会被自动创建的,因此需要你手动创建窗体。如果Package需要给别人使用,需要发布DCP文件,DCP默认在Delphi安装目录下的Project\bpl下。
如果要动态加载Package,使用LoadPackage即可,但是必须在Package里面注册你的Class:
RegisterClass(TForm2);
UnRegisterClass(TForm2);
/// 动态加载Package
procedure TForm1.Button1Click(Sender: TObject);
var
PackageModule: HModule;
AClass: TPersistentClass;
begin
PackageModule := LoadPackage('Package1.bpl');
if PackageModule <> 0 then
begin
AClass := GetClass('TForm2');
if AClass <> nil then
with TComponentClass(AClass).Create(Application)
as TCustomForm do
begin
ShowModal;
Free;
end;
UnloadPackage(PackageModule);
end;
end;
在你的Package unload前,注意清除所有Package中的类的应用!下面这个过程可以干这个苦力活!
procedure DoUnloadPackage(Module: HModule);
var
i: Integer;
M: TMemoryBasicInformation;
begin
{ Make sure there aren't any instances of any
of the classes from Module instantiated, if
so then free them. (This assumes that the
classes are owned by the application) }
for i := Application.ComponentCount - 1 downto 0 do
begin
VirtualQuery(
GetClass(Application.Components[i].ClassName),
M, SizeOf(M));
if (Module = 0) or
(HMODULE(M.AllocationBase) = Module) then
Application.Components[i].Free;
end;
UnRegisterModuleClasses(Module);
UnLoadPackage(Module);
end;
即使使用动态Package,也必须设置调用的工程为Build with runtime Package中包含你的Package,否则GetClass会失败!
附件是一个完整的例子。