怎样才能走上Delphi高手之路?

coffee480 2003-10-15 11:20:52
怎样才能走上Delphi高手之路?
我学Delphi已经有5个月了,那个时候我是从VB转到Delphi学习的。从初学到入门,然后又学会了桌面
数据库应用程序的开发和基于C/S模式的数据库应用开发,最后到现在已经能够架设一个简单的多层分
布式数据库应用程序。在此过程中还了解了有关Delphi创建多线程DLL和组件开发的基本技术。总的看
来自己在这几个月的学习中,多少还是有收获的。但是,在最近的学习过程中,自己已经发觉到自身
的水平已经很难再提高了(几乎感觉不到进步了),写程序时,除了习惯的将几个组件往窗体上拖,然后
编写事件处理过程,最后好像已经没有太多的事情可以做了。本来自己是想在Delphi的数据库应用开发
这一块上有所发展的,但是在写那些数据库应用程序时,也像前面所说的,除了能往窗体上拖组件外,似
乎不能再做别的事情了。我开始郁闷了,难道学习Delpi,就像是在堆积木一样仅此而以吗?于是,我
也开始感到了迷惘,怎样才能提高自己当前的Delphi编程水平,以及如何才能成为一个真正的编程高手?
已经成为了我目前最想解决的最大问题。我现在也有一个想法,也不知道这样一个想法是对还是错。我
想,下一步我会开始学习Win32API,想把Windows运行机制搞个清楚,因为我发觉自己对这方面的了解
还不够,想在这样的一个学习过程中来巩固一下Windows的知识。我不知道这会不会是一个比较好的办法。
我非常希望众Delphi编程高手们能够就我上面所提到的问题给出一点宝贵
的经验和建议。另外我还想请教的是,怎样才能学好Win32API??,,,谢谢!!!!!!
...全文
63 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
FrameSniper 2003-10-17
  • 打赏
  • 举报
回复

当你希望成为高手的时候,你回慢慢感觉到你永远成为不了高手;

当你真正地为自己永远成为不了高手而振作的时候,实际上你已经成为了彻底的高手!
libra01 2003-10-17
  • 打赏
  • 举报
回复
VCL类库很精深,很有意思

楼主有空时研读一下VCL的源码吧,绝对有收获。

对OOP,OOa的概念也深入一些。
scsun 2003-10-17
  • 打赏
  • 举报
回复
OO吗?还是看其他的吧。delphi不足以让你知道OO的优势。
---------------------------------------------------
C++,Java也没少看过,我认为Delphi才是真正的灵活,Java OO的太彻底,有时反而不方便,C++倒还可以点。
reallike 2003-10-16
  • 打赏
  • 举报
回复
delphi能够作任何windows下的32位程序。

请你记住这个。

学海无边。。。。。。
reallike 2003-10-16
  • 打赏
  • 举报
回复
OO吗?还是看其他的吧。delphi不足以让你知道OO的优势。
cnhgj 2003-10-16
  • 打赏
  • 举报
回复
学习
scsun 2003-10-16
  • 打赏
  • 举报
回复
我也是VB转过来的,感觉是对OOP有了较深的认识。
youcheng1 2003-10-16
  • 打赏
  • 举报
回复
规则11:显示组件属性(Expose Components Properties)
当你需要访问其他窗体的状态时,你不应该直接访问它的组件。因为这样会将其他窗体或其它类的代码和用户界面结合在一起,而用户界面往往是一个应用程序中最容易发生改变的部分。最好的方法是,为你需要访问的组件属性定义一个窗体属性。要实现这一点,可以通过读取组件状态的Get方法和设置组件状态的Set方法实现。
假如你现在需要改变用户界面,用另外一个组件替换现有的组件,那么你只需做的是修改与这个组件属性相关的Get方法和Set方法,而不必查找,修改所有引用这个组件的窗体和类的源码。详细实现方法请参见下面的代码:
private
function GetText:String;
procedure SetText(const Value:String);
public
property Text:String;
read GetText write SetText;
function TformDialog.GetText:String;
begin
Result:=Edit1.Text;
end;
procedure TformDialog.SetText(const Value:String);
begin
Edit1.Text;=Value;
end;

规则12:属性数组(Array Properties)
如果你需要处理窗体中的一系列变量,你可以定义一个属性数组。如果这些变量是一些对于窗体很重要的信息,你还可以把他们定义成窗体默认的属性数组,这样你就可以直接使用SpecialForm[3]来访问他们的值了。
下面的代码显示了如何将一个listbox组件的项目定义成窗体默认的属性数组。
type
TformDialog =class(TForm)
private
listItems:TlistBox;
function GetItems(Index:Integer):String;
procedure SetItems(Index:Integer:const Value:String);
public
property Items[Index:Integer]:string;
end;
function TFormDialog.GetItems(Index:Integer):string;
begin
if Index >=ListItems.Items.Count then
raise Exception.Create(‘TformDialog:Out of Range’);
Result:=ListItems.Items[Index];
end;
procedure TformDialog.SetItems(Index:Integer;const alue:string);
begin
if Index >=ListItems.Items.Count then
raise Exception.Create(‘TformDialog:Out of Range’);
ListItems.Items[Index]:=Value;
end;

规则13:使用属性的附加作用(Use Side-Effects In Properties)
请记住:使用属性而不是访问全局变量(参见规则10、11、12)的好处之一就是当你设置或者读取属性的值时,你还可能有意想不到的收获。
例如,你可以直接在窗体界面上拖拉组件,设置多个属性的值,调用特殊方法,立即改变多个组件的状态,或者撤销一个事件(如果需要的话)等等。

规则14:隐藏组件(Hide Components)
我经常听见那些面向对象编程的狂热追求者抱怨Delphi窗体中包含一些在published部分声明的组件,这是和面向对象思想的封装性原理不相符合的。他们确实提出了一个重要的议题,但是他们中的大多数人都没有意识到解决方法其实就在他们手边,完全不用重写Delphi代码,也不用转向其他语言。
Delphi向窗体中添加的组件参照可以被移到private部分,使得其他窗体不能访问他们。如果你这样做,你就有必要设置一些指向组件的窗体属性(请参见规则11),并且使用它们来访问组件的状态。
Delphi将所有的这些组件都放在published部分,这是因为使用这种方式能够保证这些域一定是在.DFM文件中创建的组件。当你改变一个组件的名称时,VCL能够自动地将这个组件对象与它在窗体中的参照关联起来。因为delphi使用RTTI和Tobject方法来实现这种功能,所以如果想要使用这种自动实现功能,就必须把参照放置在published部分(这也正是为什么delphi将所有的组件都放在published部分的缘故)。
如果你想知道的更详细一点,可以参看下面的代码:

procedure Tcomponent.SetReference(Enable:Boolean);
var
Field:^Tcomponent;
begin
If Fowner<> nil then begin
Field:=Fowner.FieldAddress(Fname);
If Field<>nil then
Field^:=Self
else
Field^:=nil;
end;
end;

上面的代码是Tcomponent类的SetReference方法,这个方法可以被InserComponent,RemoveComponent和SetName等方法调用。
当你理解了这一点后,你应该不难想到如果你将组件参照从published部分移到了private段,你将失去VCL的自动关联功能。为了解决这个问题,你可以通过在窗体的OnCreate事件中添加如下代码解决:
Edit1:=FindComponent(‘Edit1’) as Tedit;
你接下来应该做的就是在系统中注册这些组件类,当你为他们注册过后就能使RTTI包含在编译程序中并且能够被系统所使用。当你将这些类型的组件参照移到private部分时,对于每一个组件类,你只需为他们注册一次。即使为他们注册不是一定必要的时候,你也可以这样做,因为对于RegisterClasses的额外调用有益无害。通常你应该在单元中负责生成窗体的初始化部分添加以下的代码:
RegisterClass([TEdit]);

规则15:面向对象编程的窗体向导(The OOP Form Wizard)
为每一个窗体的每一个组件重复上述两个操作不仅十分的烦人,而且相当的浪费时间。为了避免额外的负担,我已经为此写了一个简单的向导程序。这个程序将会生成一些可以完成以上两步工作的代码,你需要做的仅仅是做几次复制和粘贴就行了。
遗憾的是这个向导程序不能自动将代码放置到单元中合适的地方,我目前正在修改这个向导程序,希望能实现这个功能。你可以到我的网站(www.marcocantu.com)查找更加完善的程序。

规则16:可视化窗体继承(Visual Form Inheritance)
如果应用得当,这将是一个强大的工具。根据我的经验,你所开发的项目越大,越能体现它的价值。在一个复杂的程序中,你可以使用窗体的不同等级关系来处理一组相关窗体的多态性(polymorphism)。
可视化窗体继承允许你共享多个窗体的一些公共的动作:你可以使用共享的方法,公用的属性,甚至是事件处理程序,组件,组件属性,组件事件处理方法等等。

规则17:限制保护域数据的使用(Limit Protected Data)
当创建一些具有不同分级体系的类时,一些程序员趋向于主要使用保护域,因为私有数据不能被子类访问。我不能说这没有其合理性,但是这肯定是和封装性不相容和的。保护数据的实现能够被所有继承的窗体所共享,而且一旦这些数据的原始定义发生改变,你必须更改所有的相关部分。
请注意,如果你遵循隐藏组件这样一条规则(Rule 14),继承窗体就不可能访问基类的私有组件。在一个继承窗体中,类似Edit1.Text:=’’的代码就不会被编译。虽然这是相当的不方便,但是至少在理论上这是值得肯定的事情,而不是否定的。如果你感觉到实现封装性是最主要,最需要的,就请将这些组件参照放在基类的私有段。

规则18:保护域中的访问方法(Protected Access Methods)
在基类中将组件参照放置在私有域中,而为这些组件添加一些访问函数来得到他们的属性,这将是一种更好的方法。如果这些访问函数仅仅在这些类内部使用而且不是类接口的一部分,你应该在保护域声明他们。例如Rule 11中描述过的GetText和SetText方法就可以声明成protected,并且我们可以通过调用SetText(’’)来编辑文本。
事实上,当一个方法被镜像到一个属性时,我们可以简单地采用如下代码就可以达到编辑文本地目的:Text:=’’;

规则19:保护域中的虚拟方法(Protected Virtual Methods)
实现一个灵活的分级制度的另一个关键点是定义一些你可以从外部类调用的虚拟方法来得到多态性。如果这个方法使用得当,将会很少出现其他公共的方法调用保护域中的虚拟方法的情况。这是一个重要的技巧,因为你可以定制派生类的虚拟方法,来修改对象的动作。

规则20:用于属性的虚拟方法(Virtual Methods For Properties)
即使是访问属性的方法也能定义成virtual,这样派生类就能改变属性的动作而不必重定义他们。虽然这种方法在VCL当中很少使用,但是它确实十分灵活、强大。为了实现这一点,仅仅需要将Rule 11当中的Get 和Set 方法定义成Virtual。基类的代码如下所示:
type
TformDialog = class ( TForm)
Procedure FormCreate(Sender:Tobject);
Private
Edit1:Tedit;
Protected
function GetText:String;virtual;
procedure SetText(const Value:String);virtual;
public
constructor Create(Text :String):reintroduce;overload;
property Text:String read GetText write SetText;
end;

在继承窗体中,你可以添加一些额外的动作来重载虚拟方法SetText:
procedure TformInherit.SetText(const Value:String);
begin
inherited SetText(Value);
if Value=’’ then
Button1.Enabled:=False;
end;

如果不符合,学学面向对象的程序设计,试着把你以前写的程序按面向对象的思想重新写一遍,看设计模式,了解封装和多态,写个复杂一点的控件。如果符合,你已经是高手。
youcheng1 2003-10-16
  • 打赏
  • 举报
回复
你写的软件符合这二十条规则吗?
第一部分:窗体是类(A Form is A Class)(rule 1-rule 15)
程序员常常将窗体看作是对象,而事实上窗体是类。两者的差别在于你创建基于相同的窗体类的多个窗体对象。令人感到疑惑的是Delphi为你定义的每一个窗体类创建了一个默认的全局对象。这对于新手来说是相当方便的,但是这同样会使他们形成坏习惯。

第二部分:继承(Inheritance)(rule 15-rule 20)
在讲述了一系列关于类特别是关于窗体类的规则后,第二部分将是一些关于类的继承性以及可视化窗体继承的建议和技巧。

关于代码
本文中所有的代码段都可以在本期杂志(《The Delphi Magazine》 Issue 47)附带的磁盘中的OopDemo工程中找到。你特别应该查看例程中的frm2 单元(unit)和inher单元。如果你想使用这些代码,请注意构造器必要的初始化设置以及私有组件参照,同时有必要设置好窗体的OldCreateOrder属性。否则,带有组件的窗体构造器的初始化代码将在窗体的OnCreate事件之前得到执行。
在这张磁盘上你还可以找到OOP 窗体向导的第一版的编译包,不过我更希望你访问我的网站获得该程序的更完整的版本。
规则一:为每一个类创建一个单元(One Class,One Unit)
请始终牢记这一点:类的私有(private)和保护(protected)的部分只对于其他单元中的类和过程(procedure)才是隐藏的.因此,如果你想得到有效的封装性,你应该为每一个类使用一个不同的单元。对于一些简单的类,比如那些继承其他类的类,你可以使用一个共享的单元。不过共享同一个单元的类的数目是受到限制的:不要在一个简单的单元里放置超过20个复杂的类,虽然Borland公司的VCL代码曾经这样做过。
如果你使用窗体的时候,Delphi会默认的遵循“一个类使用一个单元”的规则,这对于程序员来说也是十分方便的。当你向你的项目中添加一个没有窗体的类时,Delphi也会创建一个新的独立的单元。

规则二:为组件命名(Name Components)
为每一个窗体和单元给出一个有意义的名字是十分重要的。窗体和单元的名字必须是不同的,不过我趋向于为他们两者使用相似的名字,如对于关于窗体和单元可以为他们使用AboutForm 和About.pas.
为组件使用带有描述性的名字同样十分重要。最常见的命名方式是使用类的小写字母开头,再加上组件的功能,如BtnAdd 或者editName。采用这样的命名方式为组件命名可能会有很多相似的名字,而且也没有一个最好的名字,到底应该选择那一个应该依据你的个人爱好而定。

规则三:为事件命名(Name Events)
对于事件处理方法给出合适的名字更加重要。如果你对于组件给出了一个合适的名字,那么系统默认的名字ButtonClick将变成BtnAddClick。虽然从这个名字中我们可以猜到这个事件处理程序的功能,但是我认为使用一个能够描述该方法的作用的名字,而不是采用Delphi附加的名字是一种更好的方式。例如,BtnAdd按钮的OnClick事件可以命名成AddToList。这会使得你的程序可读性更强,特别是当你在这个类的其他方法中调用这个事件处理程序时,而且这会帮助程序员为类似的事件或是不同的组件选用相同的方法。不过我必须声明,使用动作(Actions)是目前开发重要的程序时我最喜欢的方法。

规则四:使用窗体方法(Use Form Methods)
窗体都是一些类,因此窗体的代码是以方法组织的。你可以向窗体中添加事件处理程序,这些处理程序完成一些特别的功能,而且他们能被其他方法调用。除了事件处理方法外,你还可以向窗体添加完成动作的特别定义的方法以及访问窗体状态的方法。在窗体中添加一些公共的(Public)方法供其他窗体调用要比其他窗体直接操作他的组件要好。

规则5:添加窗体构造器(Add Form Constructors)
在运行时创建的第二个窗体除了一个默认的构造器(从Tcomponent 类继承而来)外还会提供其他特殊的构造器。如果你不需要考虑和Delphi4以前的版本的兼容性问题,我建议你重载(Overload)Create方法,添加必要的初始化参数。具体代码可参见下面的代码:
Public
Constructor Create(Text:string); reintroduce ; overload;
Constructor TformDialog.Create(Text:string);
Begin
Inherited Create(Application);
Edit1.Text:=Text;
End;
规则6:避免全局变量(Avoid Global Variables)
应该避免使用全局变量(就是那些在单元的interface 部分定义的变量)。下面将会有一些建议帮助你如何去做。
如果你需要为窗体存储额外的数据,你可以向窗体类中添加一些私有数据。这种情况下,每一个窗体实例都会有自己的数据副本。你可以使用单元变量(在单元的implementation部分定义的变量)声明那些供窗体类的多个实例共享的数据。
如果你需要在不同类型的窗体之间共享数据,你可以把他们定义在主窗体里来实现共享,或者使用一个全局变量,使用方法或者是属性来获得数据。

规则7:永远不要在Tform1类中使用Form1(Never Use Form1 in Tform1)
你应该避免在类的方法中使用一个特定的对象名称,换句话说,你不应该在TForm1类的方法中直接使用Form1.如果你确实需要使用当前的对象,你可以使用Self关键字。请牢记:大多数时候你都没有必要直接使用当前对象的方法和数据。
如果你不遵循这条规则,当你为一个窗体类创建多个实例的时候,你会陷入麻烦当中。

规则8:尽量避免在其他的窗体中使用Form1(Seldom Use Form1 In Other Forms )
即使在其他窗体的代码中,你也应该尽量避免直接使用全局变量,如Form1.定义一些局部变量或者私有域供其他窗体使用会比直接调用全局变量要好。
例如,程序的主窗体能够为对话框定义一个私有域。很显然,如果你计划为一个派生窗体创建多个实例,这条规则将是十分有用。你可以在主窗体的代码范围内保持一份清单,也可以更简单地使用全局Sreen对象的窗体数组。

规则9:移除Form1(Remove Form1)
事实上,我的建议是在你的程序中移除Delphi自动创建的全局窗体对象。即使你禁止了窗体的自动添加功能,这也有可能是必要的,因为在Delphi随后仍然可能添加这样的窗体。我给你的建议是应该尽量避免使用全局窗体对象。
我认为对于Delphi新手而言,移除全局窗体对象是十分有用的,这样他们不至于对类和全局对象两者的关系感到疑惑。事实上,在全局窗体对象被移除后,所有与它有关的代码都会产生错误。

规则10:添加窗体属性(Add Form Properties)
正如我已经提到过的,当你需要为你的窗体添加数据时,请添加一个私有域。如果你需要访问其他类的数据,可以为你的窗体添加属性。使用这种方法你就能够改变当前窗体的代码和数据(包含在它的用户界面中)而不必改变其他窗体或类的代码。
你还应该使用属性或是方法来初始化派生窗体或是对话框,或是访问他们的最终状态。正如我前文所说的,你应该使用构造器来完成初始化工作

无名2018 2003-10-16
  • 打赏
  • 举报
回复
至于WIN32 API的学习
看你是专门学习还是
如果是前者,我建议看《progrmming windows》
其实看《delphi深度历险》也相当不错的
这本书主要讲述了SDK方面的东西
比较高深,适合楼主这样的高手;)
无名2018 2003-10-16
  • 打赏
  • 举报
回复
看 李维的书:)

还有陈宽达的《delphi深度历险》
steve0531 2003-10-16
  • 打赏
  • 举报
回复
深夜闲来无事..看到你的这个问题..谈了下自己的体会..请勿见笑..
steve0531 2003-10-16
  • 打赏
  • 举报
回复
等你到了高手阶段.回头想一下我的学习方法.."的确如此.的确是效率最高的学习方法"!

答案:带着问题去学习..

比如.现在我准备作一个同学录..那么好吧.我打开delphi.建一个窗体.添加几个合适的控件.这个控件是做什么的呢?嗯.是这样的.然后在这些控件上写代码.好了.我写了一行代码.F9运行.哇哇!我写的代码运行了.等等.好像有什么不对.consider.为什么呢?.去查查吧.看看书.到网上讨论讨论."朋友真多".我的问题解决了.这个功能终于实现了.哇哇.庆祝一下吧.开灌啤酒.打个电话给朋友让他同你分享喜悦(不管他如何的不理解你)..
嗯.现在我着手下个功能了.写了些代码.没有错误.又写了些代码.有问题了.好吧.我的朋友很多.到网上找找steve0531吧.这是个热心的家伙.哈哈.我的这个功能又实现了..嗯.我很幸运.也很伟大.第一个作品终于做完了..
没高兴多久..女朋友又要给我算开支了.她告诉我.上个月我化了多少多少gold..天哪.我化了那么多吗?.(男人总不承认这点).我自己都不清楚怎么化的了..只记得我是从她手里申请了这么多..那么我到底是怎么化的呢?干脆.程序员.天不怕.地不怕.自己写个理财软件.管他什么帐套.什么会计专业名词.自己看的懂.在软件上知道自己什么时间化了钱.用了多少.到底是干什么用的..我什么时间又在终端机上取了钱.女朋友什么时间放了贷款给我.什么时间我发了薪水.又是什么时间面对全额上交女朋友的残酷现实..
好吧.说干就干.不然.被人冤枉了都不知道..男人说话要有理由的.她什么时间冤枉了我.我在我自己的软件上点一下鼠标.精确到几分几厘..哈哈.这下.让女朋友赔赏精神损失.掏500大洋来~.哇哈.那叫一个爽...
设计了窗体.嗯嗯.这次窗体我要做的漂亮一些..添加控件..我要操作方便一些..写代码.哇哇.我写了那么多.没有错误.???.碰到问题了.看书去吧.在书上看一下怎样解决.或者找我网上的那些朋友们..哇哈..成功万岁..
一个个问题被我解决了..我的软件出来了..运行了一个月..^&**#$@#..我下个月的费用.老婆无奈的多给了500..没有比这更让人兴奋的了..
consider..consider..老婆太相信电脑了..但我可以随意的控制它..我让他干什么它就干什么..consider..consider..也就是说..如果我让它显示什么结果.它就显示什么结果..consider..consider..那么..天..下个月.我要再多要500.!!!!!!!
打开delphi..打开我的理财软件代码..修改..修改..遇到问题就提问..解决..再解决..哇.完成了...
一个月又过去了..女朋友如期检查我的花费情况.当看到软件的显示数据时..$%^&%$$%$##$##@%$#..你猜怎么样?...我我我..这个月的花费少了500...原因?..还用说????...这叫一个惨!
佣工7001 2003-10-16
  • 打赏
  • 举报
回复
找有兴趣的源码,学习,实践
不二法门

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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