以前公司的程序是把所有的程序用EXE编译,我现在想用主程序(EXE)+业务程序(bpl)方式去做,但我把一个业务程序编译成BPL时,主程序居然SHOW不出来,自己用别的测试程序可以把我编译好的BPL能SHOW来这是什么原因呀?例如我主程序調用
FPackageHandle := LoadPackage('aa.bpl');
AClass := GetClass('TfrmFindPublic');
跟蹤時aclass總是NIL
而我建別的工程,去調用時
FPackageHandle := LoadPackage('aa.bpl');
AClass := GetClass('TfrmFindPublic');
ACLASS不爲NIL也就可以SHOW出來
主程序的bulid with runtime package是打勾了
bpl包也註冊了:
initialization
RegisterClass(TfrmFindPublic);
finalization
UnRegisterClass(TfrmFindPublic);
end.請問這是什麽原因呀,百思不得其解,HELP!HELP!
然后判断FPackageHandle是否存在,
然后再看AClass
你把bpl文件放在程序目录下,
你将路径设为绝对路径或者向系统中添加环境变量,应该就没问题了。
AClass: TPersistentClass;
AForm: TForm;
begin
if FPackageHandle=0 then
if dlgOpen1.Execute then
FPackageHandle := LoadPackage(dlgOpen1.FileName);
if FPackageHandle <> 0 thenbeginAClass := GetClass('TfrmFindPublic'); if AClass <> nil then
begin
//FindPublicShow(TRSPDBGrid(ActiveControl), s, i);
// Application.CreateForm(TComponentClass(AClass), AForm);
// AForm.Show;
with TComponentClass(AClass).Create(Application)
as TCustomForm do
begin
ShowModal;
Free;
end;
end;
========上面的是业务程序调用,显示不出来=============
var
AClass: TClass;
AForm: TForm;
beginif FPackageHandle=0 then showmessage(ExtractFilePath(Application.ExeName)+'PUB_find.bpl');
FPackageHandle := LoadPackage(ExtractFilePath(Application.ExeName)+'PUB_find.bpl');
AClass := GetClass('TfrmFindPublic');
if AClass <> nil then
begin
// Application.CreateForm(TComponentClass(AClass), AForm);
//AForm.Show;
with TComponentClass(AClass).Create(Application)
as TCustomForm do
begin
ShowModal;
Free;
end; // UnloadPackage(FPackageHandle); }
end;
===========这个是自己的测试可以SHOW出来========
AClass: TPersistentClass;
AForm: TForm;
begin
if FPackageHandle=0 then
if dlgOpen1.Execute then
FPackageHandle := LoadPackage(dlgOpen1.FileName);showmessage(IntToStr(FPackageHandle))//看看是否调用成功
if FPackageHandle <> 0 thenbegin
AClass := GetClass('TfrmFindPublic'); F5,设置断点,然后运行单步跟踪if AClass <> nil then
begin
//FindPublicShow(TRSPDBGrid(ActiveControl), s, i);
// Application.CreateForm(TComponentClass(AClass), AForm);
// AForm.Show;
with TComponentClass(AClass).Create(Application)
as TCustomForm do
begin
ShowModal;
Free;
end;
end;
这两个都返回什么还是
GetClass('TfrmFindPublic');根本就没执行
AClass := GetClass('TfrmFindPublic'); F5,设置断点,返回的是ACLASS=NIL,但我的包里是有存在TfrmFindPublic的窗体名
if dlgOpen1.Execute then
FPackageHandle := LoadPackage(dlgOpen1.FileName); 这个有执行嘛,你确定 LoadPackage 的bpl是你预期的bpl嘛输出dlgOpen1.FileName 这个看看
要跟踪,应该在这句之后设置断点,断点设在赋值语句上有可能导致未赋值。
比如:
AClass := GetClass('TfrmFindPublic'); F5,设置断点,然后运行单步跟踪
Caption:= 'For break';//<--断点设在这里观察AClass的值。
procedure TMainForm.btnExitClick(Sender: TObject);
var
m_frmClass: TPersistentClass;
m_fc: TMainForm;
m_HModule: HMODULE;
begin
m_HModule:= LoadPackage('Package1.bpl');//bpl在程序目录下,在程序目录下启动程序。
if m_HModule= 0 then
Exit;
RegisterClass(TMainForm);
m_frmClass:= GetClass('TMainForm');
if m_frmClass= nil then
ShowMessage('Error,not found class');
ShowMessage(m_frmClass.ClassName);
end;
你再看看是不是其他什么地方,消息啊什么的干扰了!?
http://edn.embarcadero.com/article/27178
如果要减少对运行时包的依赖,可以尝试,将Build with runtime package下面的编辑框中只保留Vcl一项,这样可以最大程度的减少程序对运行时包的依赖性,这时,就可以动态加载包了,但我觉得这样还不如使用DLL来封装,因为最少也要再包括一个vclxx.bpl(xx对应于你使用的Delphi版本)。
还是尽可能使用DLL封装吧。
我不选中Build with runtime package的话,是找不到动态加载的包中的类的。
如果选中该选项编译,而去掉vclxx.bpl的话,会报运行时异常,程序终止,所以,包依赖于vclxx.bpl。
我的情况是,选中后,仅保留vcl70.bpl,窗体没有加任何控件,如果加了很多扩展控件,恐怕,还要动态加载其他的运行包。