动态添加控件和代码(300分)

  • 主题发起人 主题发起人 chcw
  • 开始时间 开始时间
C

chcw

Unregistered / Unconfirmed
GUEST, unregistred user!
我要开发20个软件, 这20个软件都有以下相同的地方:
1. 有一个主Form
2. 主Form中包含一个TPageControl, TPageControl中有5个TTabSheet, 这5个TTabsheet中, 前4个包含的控件以及对应的事件处理代码都是一样的.
不同的地方是:
最后一个TTabSheet包含的控件和事件处理代码是不同的.
为了避免重复编码, 我打算写一个程序, 包含上述20个软件中相同的部分, 最后一个TTabSheet中的部分, 则单独放在一个外部的数据文件(比如DLL, DCU, XML或者其它格式的数据文件)中. 这个文件应该包含最后一个TTabSheet中控件的信息, 以及控件对应的事件处理程序. 程序运行时, 读取外部数据文件中的控件信息, 并动态创建最后一个TTabSheet, 在其中添加控件, 并设置事件处理代码指针. 这样, 对于不同的软件, 只要使用相同的程序和不同的外部数据文件即可.
请问这样的想法是否能够实现, 应该用什么样的技术实现?
 
给你段代码,改改应该能解决你的问题
procedure TfrmBaseForm.SetModualRight(UserNO,ADept: string;ARow,ACol: Integer;
AParent: TWincontrol;suiFileTheme1:TsuiFileTheme;adoBtn,temp: TADOQuery);
var
//sUserNo, sXY,
sSQL,sqlStr,Value: string;
//X,Y,
I,J: Integer;
btn: array of array of TsuiButton;
Pnl:TPanel;
begin
sSQL := ' select * from xtDeptBtn where dept='''+ADept+''' order by xy ';
QueryWithSql(adoBtn,sSQL);
with adoBtndo
begin
First;
SetLength(btn,ARow+1);
for I := (Low(Btn)+1) to (High(btn))do
begin
SetLength(btn,ACol+1);
for J := (Low(btn)+1) to High(btn)do
begin
//btn[i,j]:= TsuiButton.Create(TPanel(AParent));
btn[i,j]:= TsuiButton.Create(TsuiPanel(AParent));
btn[i,j].FileTheme:=suiFileTheme1;
btn[i,j].UIStyle:=MacOS;//FromThemeFile;
btn[i,j].Height:=26;
btn[i,j].Width:=80;
if i=1 then
btn[i,j].top:=26
else
btn[i,j].top:=i*26;
btn[i,j].left:=3;//(j-1)*10;
btn[i,j].Font.Height:=-12;
btn[i,j].Font.Size:=9;
btn[i,j].Font.Name:='宋体';
btn[i,j].parent:= AParent;
value:=inttostr(i)+inttostr(j);
btn[i,j].Name:='btn'+ADept+value;
btn[i,j].caption:=' ';
btn[i,j].Enabled :=true;
if Locate('xy',value,[loCaseInsensitive]) then
//寻找xy
begin
btn[i,j].caption:=trim(Fieldbyname('caption').asstring);
//按钮标题
btn[i,j].OnClick:=BtnClick;
//按钮单击事件
sqlStr:=' select * from xtUserPurview where UserNO='''+trim(UserNO)+''' '+
' and Active=1 and BtnId='''+trim(Fieldbyname('BtnId').asstring)+'''';
QueryWithSql(temp,sqlStr);
// if temp.RecordCount>0 then
// btn[i,j].Enabled := true;
end;
end;
// end of for J ...
end;
// end of for I ...
end;
// end of with ...
end;

procedure TfrmBaseForm.BtnClick(Sender:TObject);
begin
if fmain.DeptFlag='销售管理' then
fSell_Base.SellBtnClick(Sender)
else
if fmain.DeptFlag='客户管理' then
showmessage('客户');
end;
 
前面一样的,做成一个基类.
最后个自己写,看你怎么做了,DLL也可.
 
看来楼主还没有用可视化继承!
搜搜前面的贴子你就能搞定了!

????不对啊,看了你的信息,是2001年注册的,不可能这么....
是JAVA转DELPHI了????
 
to fanboynet,
放在DLL中应该怎么做, 能具体一点吗? 谢谢.
to fas2000,
什么是可视化继承? 能具体一点吗? 谢谢.
 
这个是面向对象的基本理论问题了.自己看书学吧.理解了就能明白是怎么回事,不理解别人怎么说都没用.
相同的部分做成一个基类,你程序里面用这个基类派生,再在不同的地方写自己的代码.
 
可视化继承,即是继承窗口,
在基类窗口中,做好通用性的东西
在新建窗口时,有一个标签页,即是项止的名称,里面就有基类窗口,
你会发现新建的窗口跟基类窗口一样,接下来你就知道怎么做了吧!
 
把最后一个Tabsheet中的东西放到一个bpl包中,其他东西做成exe,让exe动态加载bpl包就可以实现你要的功能,以后不同的软件只需要做不同的bpl包。
 
面向对象编程

模块化系统(dll,bpl)
 
呵呵, 我只知道面向对象和派生, 对可视化继承没有什么概念, 以前也只做过从TEdit派生的简单控件.
请问各位:
1. 能否推荐经典的介绍可视化继承的书(或者Delphi文档也可以), 特别是介绍派生Form的.
2. 我把所有程序相同的控件都放在一个基类TBaseForm, 然后从该基类Form中继承子Form, TMyForm, 但是在Delphi的编辑器中, 打开TMyForm, 却看不到TBaseForm中的控件, 如何解决这一问题?
3. 如果使用派生的方法, 能不能把基类Form放在一个DLL中, 然后主程序中从这个基类Form中派生子Form?
非常感谢
 
你到以下地址去找找,可能找得到你需要的答案。
http://iinsnian.cnblogs.com/
http://del.cnblogs.com/
这两个地址里介绍了很多DELPHI的技巧,不知道你的运气好不好。
 
貌似可以这样,
将那20个相关信息都扔到一个INI或XML中,只写类名。
然后,在你的程序中,写20个类,以实现不同的功能,再根据条件传入的类名来生成类的实例,设置类的Parent,进行相关操作。。。
public
class function CreateInstance(Name: String): TIntfClass;
overload;

implementation
{$R *.dfm}
class function TIntfClass.CreateInstance(Name: String): TIntfClass;
var
AClass: TPersistentClass;
begin
Result := nil;
AClass := GetClass(Name);
if Assigned(AClass) then
begin
Result := AClass.NewInstance as TIntfClass;
Result.Create;
end;
end;
.......
initialization
RegisterClass(类名);
finalization
UnRegisterClass(类名);
end.

.......
 
后退
顶部