1、Delphi 基础知识,Delphi 培训(一),你能学到什么,能够使用Delphi进行简单的开发和程序调试掌握一种新的计算机“外语”:OOP语法了解VCL及其框架,学习一些系统架构设计的知识掌握一些新的编程思想、观念,开拓一下视野学习一些编程技巧和程序调试技巧,主要内容,Delphi的故事Delphi IDE介绍Delphi程序的基本概念和框架OOPObject Pascal语言介绍VCL框架更多,更多(待定),组件开发Windows APIDLL文件处理网络编程(Socket、TCP/IP)消息和线程及多CPU下的编程RPC和进程通信内核对象等,Long long ago,很久很久以前,有
2、两个绝顶高手叫做Borland和Micro-Soft天才安德尔森的故事(盖茨不是最优秀的程序员)市场最大的不一定是最优秀的物以稀为贵,跟风不一定对,Delphi的身世,常见的对Delphi误解,编写的程序很大运行效率很低不能跨平台不能编写底层的东西第三方包、组件缺乏C/C+写的程序质量高Delphi的文档差:其实是因为Delphi不需要提供OS的SDK,API SDK文档Delphi只能编写小的软件,不能编写大型软件,Pascal是最优美的编程语言,简洁而又高效请参考文章:Delphi vs vc+,请Google之,用Delphi开发的软件,OS:MAC OS(麦金托什)早期版本办公:WPS
3、 Office开发:Delphi、Protel游戏:传奇网络:Foxmail、FlashFXP财务:管家婆,用友9工具:Total Commander、金山毒霸、Windows优化大师欧洲航天局的罗赛塔慧星探测器的控制软件也是用Delphi写 ,为什么要用Delphi?,开发效率极高开发简单,容易上手,很容易学会丰富的第三方控件库集成开发和调试非常方便开发的是原生32位程序,可执行机器码史上最强编译器:DCC32,Delphi的最大缺点,太容易上手,门槛太低只会摆弄控件,浮在上层,沉不下去是个人就号称精通Delphi,主要内容,Delphi的故事Delphi IDE介绍Delphi程序的基本概
4、念和框架OOPObject Pascal语言介绍VCL框架更多,大杀器Delphi的IDE,请问:对一个开发工具最关注的两点是什么?最好用的界面设计工具:所见即所得的窗体,拖拉式,属性编辑最优秀的Code编辑器:代码切换、跳转、自动代码完成最好用的集成调试环境:所见即所得,现场查看,现有控件列表,选定控件的属性,控件面板相当于画板工具,相当于VS的解决方案资源管理器,现有类及其方法属性列表Code Explorer,现有工程中的文件列表File ExplorerProject Explorer,效率之源代码编辑器,代码浏览:Ctrl+点击,书签(Ctrl+09),Alt+,Code Insig
5、ht:代码补全,自动完成,参数提示:Ctrl + Space,Inside Tips语法高亮Keymapping:兼容其他IDE的快捷键设定,如VS、Eclipse等,允许自定义多显示器支持扩展工具:CnPack、MMX、DelFor,强烈推荐国产CnPack,杀虫能手Debugger,秒杀臭虫,单步调试:F7/F8F4:运行到当前光标所在代码行然后断点F5、F9,Ctrl+F2Ctrl+F7,打开临时修改变量值AssertInt 3,条件断点,地址断点,数据断点等,主要内容,Delphi的故事Delphi IDE介绍Delphi程序的基本概念和框架OOPObject Pascal语言介绍VC
6、L框架更多,Delphi的主要文件组成,源代码级:工程文件、源代码文件、窗体文件、资源及其脚本等输出文件:Dcu、bpl、备份、dof、Exe等,Delphi的程序框架,1,2,3,工程文件dpr入口,窗体文件dfm/pas,单元头,单元名/文件名,Delphi单元文件框架,编译指令,Interface到Implementation中的部分相当于.h中的内容,Project Options,我该从那里开始下手?,New一个Application查看文件结构、代码结构编写Hello World并理解程序运行机制使用简单的调试功能New一个Console学会编写简单的示例程序看书看Delphi的源
7、代码,我怎样才能学好Delphi?,请给自己一年时间,看完以下书籍:Delphi x从入门到精通,Marco Cantu,电子工业出版社Delphi x开发人员指南,Steve Teixeira和Xavier Pacheco,机械工业出版社泡论坛:大富翁,CSDN其他资料PASCAL精要、Insided VCL、Delphi源代码分析、Windows核心编程、Windows网络编程,主要内容,Delphi的故事Delphi IDE介绍Delphi程序的基本概念和框架OOPObject Pascal语言介绍VCL框架更多,OO的故事,软件开发技术的演变和发展面向对象(Object-Oriente
8、d)的由来请问OO有什么特点?,面向对象的误解,滥用:OP是有代价的,建议:中小型项目可以采用传统方式来做,大型项目用OO来做理解不够面向对象编程不是把你的代码用OO编译器进行编译就可以了C+的害人之处;JAVA的贡献,JAVA是一个纯面向对象的语言语言不重要,重要的是思想,面向对象不是一种编程技术,而是一种编程思想不是使用组件,使用类就表明你掌握了面向对象对于面向对象编程的程序员,我们可以分成两大类:类的设计创建者和类的使用者Delphi开发DOS程序不是面向对象的,开发的Windows程序就是OO的关于编程语言判断一个语言是不是支持面向对象的语言,可以从面向对象的三大特点来判断VC和Del
9、phi是支持OO的语言,VB不是Delphi的伟大之处在于让一个不懂OO的人也能进行OO方式的编程,OOP对OO的支持,通过属性(Property)和方法(Method)实现封装通过Override实现继承,Delphi只能支持单根继承,不支持多重继承多层继承可以通过接口实现Delphi通过虚方法(Virtual,VMT)和动态方法(Dynamic, DMT)实现多态通过动态联编(多态)和滞后联编(虚函数)实现编译支持,VMT和DMT,VMT:虚拟方法表体积庞大,占用内存大,效率高DMT:动态方法表体积小,内存消耗低,但效率差一般情况下,几乎每个子类都要覆盖的函数方法,就将它声明为 virtu
10、al;如果类层次很深,或子类很多,但某个函数方法只被很少的子类覆盖,就将它声明为 dynamic Delphi大部分采用Virtual,极少Dynamic。,OOP的基本概念,类(Class) 类是对对象的抽象描述,把一个对象用语言描述出来就是一个类类的实例(Instance)类的实例也称为对象(Object)。类是一个数据类型,那么类的实例就是这个数据类型的变量,一个类可以有多个对象类的实例化:类声明之后,必须创建才能使用,创建类的实例就是类的实例化,每一个类都应该有构造函数和析够函数Delphi不会自动调用构造函数和析构函数在Delphi中创建一个对象需要传递一个Owner参数,如果这个参
11、数不为Nil,那么你可以不关心资源的释放,否则需要调用析够函关系Object - Class - Instance(对象)-抽象- (类) -变量-(实例)传统的面向过程和面向对象编程的区别,OOP的“敏感”字,and array as asm begin case class const constructor destructor dispinterface div do downto else end except exports file finalization finally for function goto if implementation in inherited init
12、ialization inline interface is label library mod nil not object of or out packed procedure program property raise record repeat resourcestring set shl shr string then thread var to try type unit until uses var while with private,protected,public,published,OOP的常量和变量,标识符以字母、下划线开头,后面跟字母、下划线、数字不能使用保留字和关
13、键字作为标识符变量的声明,Pascal,C/C+,Var Value,: integer;,int Value,;,常量的声明,Pascal,C/C+,const Pi=3.1415926; Msg=Pascal Program.;,#define Pi 3.1415926 #define Msg “Pascal Program.”,标识符的命名约定,命名约定的意义良好的团队合作与开发相似的名字可以使你更容易并且更自信地猜测陌生变量的功用可以使你更快地熟悉新项目的代码防止一变量多名匈牙利命名法:主要包括三个部分:基本类型、一个或更多的前缀、一个限定词常用约定前缀:Txxx,Fxxx,SetXx
14、x,GetXxx,OnXxx,Pxxx,Ixxx变量名字应该有意义,驼峰命名法,firstname就比FirstName差控件名称缩写为前缀,例如:BtnOK,预定义数据类型-数值型,序数类型integer:4Byte,整数,范围-2147483648-2147483647word:2Byte,无符号整数,范围:065535Dword,Cardinal:4Byte,无符号整数,范围:04294967295byte:1Byte,无符号整数,范围:0255shortint:1Byte,-128127smallint:2Byte,-3276832767Int64:8Byte,-263263-1boo
15、lean:布尔类型,True=非0,False=0浮点类型Real,Double:8Byte,5.0 x 10-324 . 1.7 x 10308Single:4Byte,1.5 x 10-45 . 3.4 x 1038Real48:6Byte,2.9 x 10-39 . 1.7 x 1038Extend:10Byte,3.6 x 10-4951 . 1.1 x 104932,预定义数据类型(续),字符型String:长字符串类型,默认字符串,长度限制:2G,注意:Delphi的字符串类型是内存自管理类型的,并且采取了引用计数技术来保证效率,字符串用单引号括起来,如:My Program ,从
16、1开始StringW:短字符型,0W=255,从1开始Pchar:等价于C/C+中的字符串指针类型,Pchar的使用非常麻烦,主要是为了兼容Windows的标准,一般用在API中,Pchar用#0字符表示结束Char:单个字符,单个字符也用单括号表示,如:A特殊类型Variant:变体类型,可以支持不同数据类型的数据类型,严格来说,变体类型违反了编程规则,另外Variant效率很低TDateTime:日期和时间,实际上是一个Double类型,12/30/1899 12:00=0,整数表示天数,小数部分表示时间/24的值,只能表示到秒例:t := 32978.5;t := StrToDateTi
17、me(“2010-06-28 12:00:00”),OP基础知识-运算符,类型强制和变换,Delphi支持类型强制和变换,但是不推荐这样做Var N:integer; C:char; H:boolean; N:=integer(X);/charinteger C:=Char(N);/integerchar B:=Boolean(0);/B:=False;,相关函数:chr,ord,round,trunc,int,inttostr,strtoint,str,strpas,inttohex,floattostr 类的强制变换用as来完成:(AButton as TControl).Tag:=0赋值
18、强制这种类型强制,要求两种数据类型的长度要一致! var n:char; . byte(n)=65;,赋值、注释,赋值符号:=,相当于C/C+中的=注释,同类型注释不可以嵌套语句块,基本语句-If,注意多个条件的时候,要注意书写格式:例如书本上面if Edit1.Text=Saturday or Edit1.Text=Sunday then 应该写成if (Edit1.Text=Saturday) or (Edit1.Text=Sunday) then,基本语句-Case,Delphi,Case 序数类型 of 序数值1,.:语句1; 序数值2,.:语句2;else 其它处理;end;,C/C
19、+,switch(表达式) case 值1:语句1;break; case 值2:语句2;break; default: 其它处理;break;,Case和If都可以嵌套,基本语句-循环,For循环中,不能改变循环控制变量的值,这一点和C/C+不同,基本语句-With,异常处理,Delphi全面支持异常处理,异常主要是提供程序的健壮性,保证资源不会流失,异常处理可以嵌套Tryexcept,异常捕获格式try /保护代码except /异常处理代码end;TryFinally,异常保护格式try /保护代码finaly /代码end;Except和finally的区别:Except后面的代码在发
20、生异常的时候才会执行,不管是否发生异常,Finaly后面的代码总是会执行,程序书写风格,必须有注释,哪怕只有一行简短的,甚至一个单词!但是注释要求合理缩进Delphi不区分大小写,但是写代码的时候应该注意大小写的风格匹配,例如编写程序的时候,有块语句,必须先写好beginend;然后再到中间添加代码,又例如,写括号,应该把()写好之后,然后到中间添加代码,Delphi6能够自动匹配()保留字应该小写推荐一个代码格式化工具:DelForExp,自定义数据类型-枚举,自定义数据类型都是用type定义枚举类型,枚举类型的元素就是标识符,枚举的好处在于可以构造自己独有的数据类型并进行数据类型检查定义变
21、量声明 var ADay:Tdays;也可以直接这样声明 var MyCard: (Club, Diamond, Heart, Spade);枚举类型属于序数类型,例如前面的Monday的序号为0,Tuesday为1. Delphi提供一些函数,可以操作枚举类型:ord(),prec(),succ(),low(),high(),自定义数据类型-记录,记录,Delphi,TypeTStudentRec=record/记录 No:ingeger; Name:string; Class:byte;End;/TypeTstudentRec=packed record No:integer; Name:
22、string; Class:byte;End; /紧缩记录,C/C+,Struct TStudentRec int No; char* Name; char Class;,Packed record和reocord的区别:Windows的内存分配机制 ,变量分配的内存都进行“边界对齐”,一次分配4Byte的内存,packed的作用,可以使用SizeOf(变量)来测试一个变量占用内存的大小Packed速度要慢,但是占用内存少,普通记录占用内存多,但是速度要快一些,自定义数据类型-子界,子界的好处在于可以利用编译器自动进行范围检查能定义子界数据类型的数据类型:整型,字符,逻辑,枚举,Type TS
23、core=0.100;/子界Var Score:Tscore; / Score:0.100; / Score:=120; /Error!,自定义数据类型-静态数组,静态数组,Delphi,TypeTmyArray=array1.100 of integer;/定义数组数据类型var Ar:TMyArray; / or Ar:array1.100 of integer; Ar:array0.4,1.20 of char; / Ar:array0.4 of array1.20 of char;.Ar13:=C; / Ar1,3:=C;,C/C+,int Ar100;char Ar520;Ar12=
24、C;,字符串可以当作字符数组进行处理,例如要访问s:string中的第二个字符,可以用下面的代码:s2:=C;,自定义数据类型-动态数组,动态数组:动态分配内存,var ar:array of integer;.SetLength(ar,5); /内存分配请求,并没有实际分配内存for i:=Low(ar) to High(ar) do ari:=0;Ar0:=3;/动态数组下标从0开始,自定义数据类型-集合,集合类型最多只能有255个元素,type TMyChars:set of A.D;var s:TMyChars; s:set of A.Z; s:set of 1.100; s:set
25、of 1.300; /Error!/集合函数和运算Include();/把一个元素包含到一个集合里面,相当于+Exclude();/把一个元素从一个集合里面删除,相当于-/Include和Exclude效率要高!,指针,参数传递,值传递引用传递(变参)例子(包含返回值):function ProcName(var I:integer;const Name:string):integer;begin / Result:=0; / OR ProcName:=0;end;,类的定义,声明格式(头、实现两个部分)数据的封装程度有三种:私有、保护、公有,定义类的时候,也要按上面的顺序友元?,typeTd
26、emoClass=class(FatherClass)/如不指定FC,默认TObjectPrivate /私有部分protected /保护部分public /公共部分 procedure StaticMethod;/静态方法 procedure VirtualMethod;Virtual;/虚拟方法,多态 procedure DynamicMethod;Dynamic;/动态方法,多态published /发布部分,用于设计状态(Object Inspecter)end;,继承,TA称之为TB的父类,TB称之为TA的子类,或者说TB从TA继承而来,TA也称为TB的基类,TB是TA的派生类va
27、r B:TB; B.Proc1; /合法B.Proc2; /不合法B.Proc3; /合法B.Proc4; /不合法,多态,多态需要在定义父类的方法的时候,用Virtual或者Dynamic关键字进行定义,在定义子类的方法的时候,用override进行修饰,否则多态功能无法正常使用,并且有一个编译警告(程序可以正常运行):Method XXXhides the virtual method of base type XXX,typeTAnimal=class procedure Voice;virtual;end;TDog=class(TAnimal) procedure Voice;over
28、ride;end;,vara : TAnimal;begin a := TAnimal.Create; a.Voice; a.Free; a := TDog.Create; a.Voice; a.Free;end;,构造函数和析构函数、覆盖和重载,构造函数用于创建对象时调用,分配内存,初始化析构函数用于销毁对象覆盖和重载是用同名的方法遮盖父类的方法,type TA=class public constructor Create; destructor Destroy;override; end; TB=Class(TA) public constructor Create; destructo
29、r Destroy;override; end;,constructor TA.Create;Begin inherited; /推荐,inherited放在最前面 ShowMessage(Create A);end;,destructor TA.Destroy;begin ShowMessage(Destroy A); inherited; /推荐:inhertied的顺序问题end;,Unit interfaceType TAClass=class private protect public end;Var ImplimetiationProcedure TAClass.MethodVa
30、rBegin End;End;,变量的作用范围,2,1,3,6,定义变量的一个重要的原则是:尽量减少变量的作用范围,少用全局变量变量可以尽量定义成Class的Private,4,5,高手是怎样练成的?,架构第一,算法至上采用正统的方法手段来解决问题,而不是旁门左道良好的代码风格,编写无Warn、Hint代码差劲的代码,应当重新编写存储和业务分离,业务和界面分离,降低耦合性完美主义者,追求完美,不断改进大道至简:不要涉及面面俱到、非常灵活的数据结构注意代码细节:内存、资源的管理;异常处理一个优秀的程序,不在于正常的功能处理的如何,而是在于不正常的时候处理的如何,主要内容,Delphi的故事Del
31、phi IDE介绍Delphi程序的基本概念和框架OOPObject Pascal语言介绍VCL框架更多,主要的VCL架构,VCL封装了什么东东?,Windows 标准控件:Edit,Combobox,Memo,RichEdit,ListView等内核对象:文件、线程、临界区、Event等等资源管理:TIcon, TImage,TIamgeList等GDI和绘图对象:TPicture,TPaintBox, TGraphControl等工具类:TList,TStringList等,VCL是如何封装的?,通过Object、TWriter/TReader、TPersistent, TFiler等实现
32、最基础的封装,完成控件属性等数据存储和持久化通过Windows标准API完成控件本身的创建关联通过Message完成消息处理过程通过CM_xxx消息完成附加功能通过在对应消息默认处理过程中增加对事件的支持,控件的使用,Owner和Parent,容器组件控件面板的组件页面Object Inspector和常用控件的属性、事件在窗体中使用组件向窗体中添加组件删除窗体中的组件调整组件的大小和位置(键盘、鼠标操作)设置可视组件的TabOrder组件的锁定与解锁设置窗体中组件的属性创建组件的事件处理过程,可以多个控件使用同一个处理过程多窗口的使用和Splash窗体常用文本控件和常用按钮控件控件的动态创建和使用多窗体的使用、模态(Modal)窗体、非模态(Modaless)窗体,