问一个关于运行期包的问题 (20分)

  • 主题发起人 主题发起人 rockxu
  • 开始时间 开始时间
R

rockxu

Unregistered / Unconfirmed
GUEST, unregistred user!
我如何能把我设计的程序的一部份做成包(.bpl),并在主程序的菜单或按钮中调用?
我的分不多,还请高手不要见笑...
 
一、什么是包?
Delphi中的包是Delphi程序间通讯与模块化的一个方法,其中包可分为设计包(比如控件都有一个设计包)和运行包,包的本质和Win32下的DLL并无本质
区别,可以理解为Borland专有的一个DLL,只不过这个“DLL”只能用Delphi开发的程序中。这有点类似于VC下的可以导出整个类的DLL--这种DLL只
能被使用MFC编程的程序使用。Delphi运行包的好处与VC中的专有DLL有相同之处:使用十分方便,开发的程序可以很容易模块化,便于合作开发。
1。设计包
其实每个VCL控件一般都有一个设计包,可以在 Project| Option...对话框中的Package页中安装、删除。设计包此处从略
2。运行包
可以显式链接也隐式链接(这一点与DLL几乎完全一模一样!)
二、包的开发方法
开发方法十分简单:New|...|package即可,可以在包中添加窗体和各种各样的控件以及相应的代码、数据,与平时开发应用程序无任何不同。
唯一不同的一点是生成 .BPL 文件,生成的BPL文件默认位置是在Delphi的安装目录下的Project|BPL中,不过可以另外设定Output目录。
另外还有一点不同是:在使用包之前必须要知道包中有哪些类,所有先注册。所以要在每个包中的 initialization部分注册类而在 finalization部分注销类
如下使用:

unit1.pas
……

initialization
RegisterClass(TForm2);
finalization
UnRegisterClass(TForm2);


三、使用方法
A)隐式链接
包含相应的Unit单元,同时在 Project | Option... 中的 Packages页选中 Build with RunTime Package复选框,并在相应的Edit框中添加要链接的
包的文件名,如果是放在和Exe文件同一目录中的话,可以不加路径名
B)显式链接
下面例程演示了如何使用:
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;

四、包使用中的应该注意的几点:
1。包不能递归使用。
比如有下面两个程序:A和B两个包而且A中用到了B,那么B就不能使用A包了,否则出错。
解决方法如下:
使用额外的包!即将各个模块共有的部分抽取出来单独做一个包供其它所有的模块使用。


由于水平有限,错误在所难免:-)
同时推荐一个好文章:
http://community.borland.com/article/0,1410,27178,00.html

 
又学到一点点!!!
 
{-----------------------------------------------------------------------------
Procedure: GetPropertyValue
Author: LiYaLei(liyaeli@163.net)
Date: 2001-11-29 16:02:07
Arguments:
Instance: TObject;
PropInfo: PPropInfo // 属性的指针获取方法GetPropInfo(TClass.ClassINfo,PropertyName)
Result: string
Purpose: 得到一个对象的属性值
History:
-----------------------------------------------------------------------------}

function GetPropertyValue(Instance: TObject; PropInfo: PPropInfo): string;
var
ClassName : string;
begin
Result := '';
if PropInfo <> nil then
begin
ClassName := PropInfo^.PropType^.Name;
if ClassName = 'TDateTime' then
begin
if GetFloatProp(Instance, PropInfo) <> 0 then
Result := FormatDateTime('yyyy''年''m''月''d''日''h''时''n''分''',
GetFloatProp(Instance, PropInfo))
end
else
if ClassName = 'TPicture' then
Result := 'TPicture'
else
if ClassName = 'Double' then
Result := FloatToStr(GetFloatProp(Instance, PropInfo))
else
Result := GetStrProp(Instance, PropInfo);
end;
end;

{-----------------------------------------------------------------------------
Procedure: GetPropertyNames
Author: LiYaLei(liyaeli@163.net)
Date: 2001-11-29 16:06:03
Arguments:
pti: PTypeInfo;//类信息的指针,获取方法TCalss.ClassInfo
sList: TStrings
Result: None
Purpose: 得到一个对象的属性列表
History:
-----------------------------------------------------------------------------}

procedure GetPropertyNames(pti: PTypeInfo; sList: TStrings);
var
ppi : PPropInfo;
pProps : PPropList;
nProps, i : Integer;
ptd : PTypeData;
begin
ptd := GetTypeData(pti);
nProps := ptd^.PropCount;
if nProps > 0 then
begin

GetMem(pProps, SizeOf(PPropInfo) * nProps);
try
GetPropInfos(pti, pProps);
// SortPropList(pProps,nProps);

for i := 0 to nProps - 1 do
begin
ppi := pProps;
sList.Add(ppi.Name);

end;
finally
FreeMem(pProps);
end;
end;
end;
 
不好意思发错地方了
 
接受答案了.
 
后退
顶部