大侠们,急阿...... package 中对象的调用(在线等) (150分)

  • 主题发起人 主题发起人 飞豹
  • 开始时间 开始时间

飞豹

Unregistered / Unconfirmed
GUEST, unregistred user!
现有一系统,将数据模块和一些公用函数放在一个包内(A.bpl),将查询单元放在另一个包中(B.bpl),主窗口中将A包进行静态引用(因为A包有公用的模块),B包的 requires 中加入A包后进行动态引用,
我的主程序执行A包中的datamodule的方法可以,但调用A包中的datamodule对象如query 就有问题,B包中这个问题同时存在,不知为何?
注:我已经在主程序的 builder with run package 选中并加入了A;
在主程序中uses 了datamodule;
B包中加入了注册;
 
1. A,B 一定要设置 Build with runtime package.
否则主程序中无法取到A,B包中的注册类(getclass('xxx')=nil)
2. A包被静态引用。但不表示A包中的对象已经生成了。
(参考一下: vclx50.bpl,vcmsmp.bpl等包也是静态包,即使你编译选项设置这些包为
build with runtime package,但是使用这些包中的控件一样需要create)

3. 我的方法是: A包中可以放一些公用函数。
datamodule包 动态加载。 并对datamodule进行类注册.这样datamodule中的对象就
可以用了.
 
王大侠,照你说的方法 3 能实现 Tdatamodule 的全局引用吗? B包中 如何引用动态加载的 Tdatamodule 和他的一些方法呢,可不可以所得细一些。
 
飞豹. 可以实现.
主程序动态调用 A,B包.
A包: Datamodule 包
B包: 一般窗体和查询单元
主程序先调用A包。 调用完后, DATAMODULE自动注册
B包的窗体引用和包引用原则同主窗体。 唯一例外的是:
因为主程序在 lOADpAckAge('A包') 后,Datamodule已经被创建了.
所以B包调用A包不能再次Loadpackage, 这时候应该用特殊的方法查找datamodule
窗口 , 你可以使用 Screen对象, Screen.Datamodules 中记载着当前进程已创建
的datamodule窗体列表.
附代码:
主程序调用DataModule
var datamoduleClass : TpersistentClass;
Loop : Integer;
MyDataModule : TDataModule;
begin
dataModuleClass := GetClass('TDataModule1');
If dataModuleClass <> Nil then
begin
MyDataModule :=
TDataModule(TComponentClass(dataModuleClass).Create(Application));
For Loop := 0 To MyDataModule.ComponentCount - 1 do
begin
//查找Mydatamodule中的 tQuery类
If UpperCase(MyDataModule.Components[Loop].ClassName) = 'TQUERY' then
begin
// if TQuery(MyDataModule.Components[Loop]).Name = 'Query1' then
aQuery := TQuery(MyDataModule.Components[Loop]);
//临时query对象
DataSource1.DataSet := aQuery;
//主窗体中的Datasource1,
aQuery.Open;
break;
end;
end;
end;
end;

B包中调用DataModule的方法:
procedure TForm2.FormActivate(Sender: TObject);
begin
LoadDataModule;
end;
Procedure Tform2.LoadDataModule;
Var
iCounter: Integer;
aQuery : TQuery;
MyDataModule : TDataModule;
begin
for icounter := 0 to Screen.DataModuleCount -1 do
begin
If UpperCase(Screen.DataModules[iCounter].ClassName) = 'tDataModule1' then
MyDataModule := Screen.DataModules[iCounter];
end;
If MydataModule <> NIl then
begin
For iCounter := 0 To MyDataModule.ComponentCount - 1 do
begin
If UpperCase(MydataModule.Components[iCounter].ClassName) = 'TQUERY' then
begin
aQuery := TQuery(MyDataModule.Components[iCounter]);
//临时Query对象
DataSource1.DataSet := aQuery;
//form2中的Datasource1
aQuery.Open;
break;
end;
end;
end;
end;

Initialization
RegisterClass(Tform2);
finalization
UnRegisterClass(Tform2);
end.
 
基本明白大意,但仍然不能对创建的 TDataModule 进行全局的调用,可不可以在一段公用的函数(如A.bpl中)写其它包调用数据模块的函数,以便其它包公用一点代码,可以达到这种效果么?
还有没有一种完美的解决方案,使我在主窗口和其它的包中调用 TDataModule 的对象就像调用自己包的对象一样用 MyDataModule.对象名 ?
 
谢谢王大侠!
 
我想,是不是可以这样尝试一下(没有试过)
在公用包里设置一个datamodule变量, 在公用函数包的初始化过程里,调用
find Datamodule 之类的方法给此变量赋值.
其他包的 requires里加上公用函数包, 所有对DATAMODULE 的引用都用 公用函数包里的
datamodule变量.
当然这样就对程序架构有限制. 主程序->加载datamodule包->加载公用函数包
你试试吧。如果能过去, 拜托回帖告诉试验结果
 
我是这么想的,正在实验,今晚打算通宵!
 
后退
顶部