关于动态加载bpl的问题——如何获得bpl中的窗体类?

wzn0521 2008-07-11 02:28:24
我现在在看以前的一个老程序,除了主界面外,全部都是动态加载包,调用里面的窗体。

主程序中菜单项对应的窗体类,是从数据库表中得到的,当我点击菜单时,首先判断这个窗体类是不是已经存在,如果不存在,则加载这个窗体类对应的包(包和窗体类的对应关系也是存储在数据库表中),然后在获得这个窗体类,在显示这个窗体。

菜单对应窗体类,没办法,只能手工加入到数据库表中。
包和窗体类的对应,是通过一个exe文件执行的,而这个exe文件,则没有源代码。但执行效果可以看得到。当选择了一个bpl文件后,列表框中显示这个包中有哪些窗体类。

我现在就比较困惑,这个功能是怎么实现的。
因为我查找了很多资料,说如果要超找包中的类,必须首先要对类进行注册,执行诸如下面的代码:
initialization
RegisterClass(TForm2);
finalization
UnRegisterClass(TForm2);
才能用FindClass或者GetClass根据类名得到相应的类。

procedure TForm1.Button1Click(Sender: TObject);
var
PackageModule : HModule;
AClass : TPersistentClass;
begin
PackageModule := LoadPackage('Package1.bpl');
if PackageModule <> 0 then
begin
//AClass := GetClass('TForm2');
AClass := FindClass('TForm2');
if AClass <> nil then
with TComponentClass(AClass).Create(Application) as TCustomForm do
begin
ShowModal;
Free;
end;
UnLoadPackage(PackageModule);
end;
end;
以上代码测试过,如果注释掉Form2中的那4行代码,以上代码根本无法找到TForm2。
而以前老程序留下的包中的窗体的源代码,根本就没有关于注册的那部分代码,
那他是如何得到bpl中的窗体类呢?
...全文
332 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
金卯刀 2008-07-14
  • 打赏
  • 举报
回复
嗯,要回答這個問題,先説明一下delphi自帶的RegisterClass和UnRegisterClass。這個有別于windows自帶的窗體類註冊用api-registerclass,UnRegisterClass。以RegisterClass為例,delphi自帶的RegisterClass,目的是記錄類信息,放到delphi的一個全局list裏面,可供調用者查詢。那麽當我們在loadpackage或者loadlibrary時,其實delphi的流機制已經幫我們註冊了窗口類,我們就不需要再顯式地去調用api註冊窗口。之所以在包模式下編程時,需要調用delphi自帶的RegisterClass,是為了能夠正確執行裏面的代碼。

根據你的情況,你的程序必定是用自己list或者類似d方式來記錄類信息。
netfirstman 2008-07-12
  • 打赏
  • 举报
回复
这方面问题我比较清楚,最近在做一个关于这方面的项目。

initialization
RegisterClass(TForm2);
finalization
UnRegisterClass(TForm2);
以上代码是放在你的BPL里的,使用loadpackage('Package1.bpl')函数的时候,会自动执行
Package1这个BPL中的
initialization
RegisterClass(TForm2);

在调用unloadpackage('Package1.bpl')函数时会执行BPL中的
finalization
UnRegisterClass(TForm2);

用兴趣的话你可以看一下RegisterClass()函数和UnregisterClass()的源代码。

另外注意在build的时候要把option里的勾打上,这样才能够动态的加载。


wzn0521 2008-07-12
  • 打赏
  • 举报
回复
谢谢楼上的,这个我知道。
我想知道的是,给你一个bpl文件,如何得到这个文件中包含的窗体类。

而这个bpl中窗体中的pas文件中,没有类似如下的代码:
initialization
RegisterClass(TForm2);
finalization
UnRegisterClass(TForm2);
netfirstman 2008-07-12
  • 打赏
  • 举报
回复
也许你的程序通过数据库做了一些工作,统一注册了或别的
这就只能猜测了,应该还是有相应的代码做了一些工作的
wzn0521 2008-07-12
  • 打赏
  • 举报
回复
to netfirstman
bpl文件是编译后生成的吧,而关于注册代码,是写到pas文件里的吧?
wy7861 2008-07-11
  • 打赏
  • 举报
回复
创建窗体肯定是在bpl中实现的,那也就不需要注册了啊~

把主窗体的Application作为参数传递给bpl,然后在bpl中直接
Application.CreateForm(窗体类, 窗体名);

就可以了

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧