动态载入BPL包的完整过程及其他

1.出现'A CLASS NAMED Already exists' 错误

如果你是动态载入BPL包,那有一原因是在呼叫BPL的程序已经USES了那个包中的类或模块;删除USES中的名字

2.出现'无法注册窗体'
在呼叫程式的component/install packages的build with runtime packages里面,把基类包含进去,在动态载入BPL中表单的时候,常常会出现这个问题;

3.整个动态载入bpl包的过程:
预备动作:
1).在呼叫程式的component/install packages的build with runtime packages里面,把基类包含进去
2)在呼叫程式的uses中把当前程式中的类或模块包含进去,并且决不能包含动态载入的BPL包中的任何东西;
3)编写bpl包时,要把基类的.dcp文件包含到requires中,并且注意:在呼叫程式和BPL中都应当包含VCL.dcp,否则呼叫程式无法识别BPL包的注册.
4).在bpl包中的form初始化阶段,要将它对应的DATAMODULE建立,方法如下:

uses datamodulename;

procedure tform1.create(sender:tobject);
begin
if  fmdatamodulename=nil then application.createform(tdatamodulename,fmdatamodulename);
inherited;
end;
datamodulename是指数据模块中.pas的名字,fmdatamodulename是指表单的名字,tdatamodulename是它的类名;
5)只要是被外部呼叫的东西,在它pas中都应当注册,如下:

initialization
RegisterClass(Tfmname);
finalization
RegisterClass(Tfmname);

tfmname是指这个表单的类名;
这两个标识放在implementation之后,end.之前任意的非过程内即可;
6)注意编译BPL包存放的位置,编译后有三个档案是有用的:.bpl是打包给别人用的,.dcu是记录性质的文档,.dcp是包含在呼叫程式的运行时程式中的.

载入bpl包:
1)载入bpl包
  var
   moduleinstance:HMODULE;
begin
    ModuleInstance := LoadPackage(FileName);
end;
2)载入数据模块:
function CreateDataModuleByClassName(const ClassName: string): TDataModule;
var dmTemp: TDataModule;
    AClass: TPersistentClass;
begin
  Result := nil;
  AClass := GetClass(ClassName);
  if (AClass <> nil) then
  begin
    dmTemp := TComponentClass(AClass).Create(Application) as TDataModule;
    Result := dmTemp;
  end;
end;

3)载入表单
function CreateFormByClassName(const ClassName: string): TCustomForm;
var
  AClass: TPersistentClass;
begin
  { Note that TApplication "owns" this form and thus it must be freed prior
    to unloading the package }
  AClass := GetClass(ClassName);
  if AClass <> nil then
    Result := TComponentClass(AClass).Create(Application) as TCustomForm
  else
    raise Exception.CreateFmt(sErrorCreateForm, [ClassName]);
end;
4)显示表单
function ShowModalFormByClassName(const ClassName: string;const IsShowModal: shortstring): integer;
var
  frm: TCustomForm;
begin
  Result:=0;
  frm := CreateFormByClassName(ClassName);
  try
    if IsShowModal='Y' then
    Result := frm.ShowModal
    else
    frm.Show;
  finally
    if IsShowModal='Y' then frm.Release;
  end;
end;

卸载包:
  UnRegisterModuleClasses(ModuleInstance);
  UnloadPackage(ModuleInstance);
如果用完了就卸,无所谓,否则就要把它ModuleInstance全局定义一下.

你可能感兴趣的:(动态载入BPL包的完整过程及其他)