Delphi程序设计之--惯用法(3)
2008-04-10 02:57:10来源:互联网 阅读 ()
设计:
1、设计一个图形对象抽象类,在此类中,定义一个抽象函数 CadPerform,函数的参数参照function TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
2、在图形管理类中,实现一个图形对象列表的管理,列表中保存的是抽象对象的指针。
3、对于要对具体类对象进行操纵控制时,只需通过条用CanPerform函数,然后根据当前操作的类别传入 Msg, 并传入相应的参数信息。
实现: TCad 为由抽象类继承下来的第一层控件类
function TCad.CadPerform(Msg: Cardinal; WParam, LParam: Longint): Longint;
begin
Case Msg of
My_Message1: Result := MyMessage1(WParam, LParam);
My_Message2: Result := MyMessage2(WParam, LParam);
end;
end;
对于,TPoint继承自 TCad, CadPerform函数实现如下。
function TPoint.CadPerform(Msg: Cardinal; WParam, LParam: Longint): Longint;
begin
Case Msg of
My_Message1: Result := MyMessage1(WParam, LParam); //屏蔽了TCad中此操作类型的处理
My_Message3: Result := MyMessage3(WParam, LParam);
else Result := inherited CadPerform(Msg, WParam, LParam);
end;
end;
*说明:
因为,我们对图形对象的操作会非常频繁,所以我们通过定义一个公共开放的接口函数来实现,类的高封装性和程序的易维护性、好扩展等性能。
*//
{ No. 12 }
以下是我编程时的要求:(部分信息没有语言限制)
//以下的解决方案,几乎都可以在上面的方法中,找到
1、减少程序的复杂度。a、减少函数个数,使用Case、Tag方式,学习实现Perform定义方式;b、减少单元嵌套关系,使用消息传递方式,减少窗体单元的互相包含。
2、减少
{ No. 13 }使用广播,实现管理类对管理列表对象的通知
//对于{ No. 12 } 项目描述中,当画图的窗体控件属性或状态改变时,经常会需要通知所有的图形对象,进行相应的改变。
//则如果只定义一个广播函数,就可以实现父子通知的话,也会提高程序的可重用性、扩展性、易维护性等,使类结构清晰。
//比如:1、在Visio和MapInfo中,如果当前窗体的比例尺(缩放比例)改变时,需要用新的比例尺重画当前所有的显示图形对象。2、当当前窗体默认窗体字体改变后,对于默认使用窗体字体显示文字信息的图形对象,他们的文字字体也应该相应的改变。
//解决方案,参考TWinControl中,属性或状态改变时,通知所有子Controls的处理机制:
procedure TWinControl.NotifyControls(Msg: Word);
var
Message: TMessage;
begin
Message.Msg := Msg;
Message.WParam := 0;
Message.LParam := 0;
Message.Result := 0;
Broadcast(Message);//广播当前的变更消息
end;
其中:
procedure TWinControl.Broadcast(var Message);
var
I: Integer;
begin
for I := 0 to ControlCount - 1 do
begin
Controls[I].WindowProc(TMessage(Message));
//改为:with TMessage(Message) do Cads[I].CadPerform(msg, WParam, LParam);
if TMessage(Message).Result <> 0 then Exit;
end;
end;
但是,我们处理图形对象时,可能会直接调用 Cads 的CanPerform公共函数即可
{ No. 14 }需要时,动态创建你的对象
比如:http://www.delphibbs.com/keylife/iblog_show.asp?xid=824 中的
//*******方案二 当需要的时候在创建属性窗体
uses
...
fProperty;
type
TfrmMyMap = class
...
procedure OnfrmMyMapDestroy(Sender: TObject);
procedure OnMapGeoSelected(AGeo: TGeometry);
private
FfrmProperty: TfrmProperty;
procedure ShowPropertyForm(aVisible: Boolean);
public
end;
procedure TfrmMyMap.ShowPropertyForm(aVisible: Boolean);
begin
if Not Assigned(FfrmProperty) then FfrmProperty := TfrmProperty.Create(Application);
FfrmProperty.Visible := aVisible;
end;
procedure TfrmMyMap.OnfrmMyMapDestroy(Sender: TObject);
begin
if Assigned(FfrmProperty) then FfrmProperty.Free;
end;
procedure TfrmMyMap.OnMapGeoSelected(AGeo: TGeometry);
begin
if Assigned(FfrmProperty) then FfrmProperty.MyRefresh(AGeo);
end;
这里说明了:
1、需要时,动态创建你的对象 FfrmProperty
2、当前对象释放时,判断你的对象的合法性,然后释放动态创建的对象。
{ No. 15 }创建接口还是创建结构
//项目描述:我开发一个表格控件时,如果我将单元格设置为一个Com,则如果表格现实的信息过多的话,则装载速度无法保证,甚至于有死机的可能。我之所以用Com是为了将来每个单元格的处理和信息都可以在控件外扩展。
我的解决办法是:对于每个从Cell派生来的控件创建一个实例,通过动态创建若干个结构对象Record来记录个单元格的信息,如果需要对单元格进行操作,则将结构对象指针赋值给Cell组件,测试结果很令人满意。
所以,如果需要使用某个Com大量实例的话,尽量管理和维护一个实例,而对于其中的数据可以实行动态创建管理,速度上会有很好的效果。
另外,尽量声明一个 pMyInterface = ^IMyInterface 借口指针,参数传递或使用时,直接使用接口指针,这样可以减少调用计数函数_AddInft等,如果操作平凡也可以提高速度的。
注:此文作者笔名:JoyYuan97。(自己很菜,写不出来什么,找到好的东西希望大家一起分享,也感谢作者给我带来的经验和技巧)
希望看过的人留下意见,下面为作者的话:
“另外,最好请将您转贴位置的连接给我一份。我向定期看看别人的建议。谢谢!
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:华为CMPP源码delphi6版
下一篇:程序设计和调试中的几点总结
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash
