收藏 分享(赏)

delphi基础.doc

上传人:gnk289057 文档编号:7445012 上传时间:2019-05-18 格式:DOC 页数:39 大小:343.50KB
下载 相关 举报
delphi基础.doc_第1页
第1页 / 共39页
delphi基础.doc_第2页
第2页 / 共39页
delphi基础.doc_第3页
第3页 / 共39页
delphi基础.doc_第4页
第4页 / 共39页
delphi基础.doc_第5页
第5页 / 共39页
点击查看更多>>
资源描述

1、Delphi 基础1 数据类型见附表 1特定类型日期和时间 Delphi 也用实型数表示日期和时间数据。但为了更准确起见,Delphi 特别定义了 TDateTime 数据类型,这是一个浮点类型,因为这个类型必须足够宽,使变量能容纳年、月、日、时、分和秒、甚至毫秒。日期值按天计数,从 1899-12-30 开始,放在 TDateTime 类型的整数部分;时间值则位于十进制数的小数部分。TDateTime 不是编译器可直接识别的预定义类型,它在 System 单元定义:typeTDateTime = type Double;使用 TDateTime 类型很简单,因为 Delphi 为该类型定义了

2、一系列操作函数,表 3.3 列出了这些函数。表: TDateTime 类型系统例程 例程 作用 Now 返回当前日期及时间 Date 返回当前日期 Time 返回当前时间 DateTimeToStr 按缺省格式将日期和时间值转换为字符串;特定格式转换可用 FormatDateTime函数 DateTimeToString 按缺省格式将日期和时间值拷贝到字符串缓冲区 DateToStr 将 TDateTime 值的日期部分转为字符串 TimeToStr 将 TDateTime 值的时间部分转为字符串 FormatDateTime 按特定格式将日期和时间值转换为字符串 StrToDateTime

3、将带有日期和时间信息的字符串转换为 TdateTime 类型值,如串有误将引发一个异常 StrToDate 将带有日期信息的字符串转换为 TDateTime 类型格式 StrToTime 将带有时间信息的字符串转换为 TDateTime 类型格式 DayOfWeek 根据传递的日期参数计算该日期是一星期中的第几天 DecodeDate 根据日期值返回年、月、日值 DecodeTime 根据时间值返回时、分、秒、毫秒值 EncodeDate 组合年、月、日值为 TDateTime 类型值 EncodeTime 组合时、分、秒、毫秒值为 TDateTime 类型值 Windows 类型 通常在 w

4、indow.pas 或 sysytem.pas 中定义。可以使用 ctrl鼠标左键查看。Delphi 基础附表 2:有序类型系统例程 例程 作用Dec 将例程中的参数值递减 1 或一个特定的值,其中特定值可在第二个可选参数中定义Inc 将例程中的参数值增加 1 或一个特定的值Odd 如果参数为奇数返回真Pred 根据参数在其数据类型定义中的序列,返回参数值的前驱值Succ 返回参数值的后继值Ord 返回参数值在其数据类型值集合中的序号Low 返回参数对应的有序数据类型的最小取值High 返回参数对应的有序数据类型的最大取值附表 3:类型转换系统例程例程 作用 Chr 将一个有序数据转换为一个

5、ANSI 字符 Ord 将一个有序类型值转换为它的序号 Round 转换一个实型值为四舍五入后的整型值 Trunc 转换一个实型值为小数截断后的整型值 Int 返回浮点数的整数部分 IntToStr 将数值转换为字符串 IntToHex 将数值转换为十六进制数字符串 StrToInt 将字符串转换为一个整型数,如字符串不是一个合法的整型将引发异常 StrToIntDef 将字符串转换为一个整数,如字符串不合法返回一个缺省值 Val 将字符串转换为一个数字(传统 Turbo Pascal 例程用于向后兼容) Str 将数字转换为格式化字符串(传统 Turbo Pascal 例程用于向后兼容) S

6、trPas 将零终止字符串转换为 Pascal 类型字符串,在 32 位 Delphi 中这种类型转换是自动进行的 StrPCopy 拷贝一个 Pascal 类型字符串到一个零终止字符串, 在 32 位 Delphi 中转换是自动进行的 StrPLCopy 拷贝 Pascal 类型字符串的一部分到一个零终止字符串 FloatToDecimal 将一个浮点数转换为包含指数、数字及符号的十进制浮点记录类型 FloatToStr 将浮点值转换为缺省格式的字符串 FloatToStrF 将浮点值转换为特定格式的字符串 FloatToText 使用特定格式,将一个浮点值拷贝到一个字符串缓冲区 Float

7、ToTextFmt 同上面例程,使用特定格式,将一个浮点值拷贝到一个字符串缓冲区 StrToFloat 将一个 Pascal 字符串转换为浮点数 TextToFloat 将一个零终止字符串转换为浮点数 Delphi 基础2 常量和变量1) 常量Const 常量名=常量值True 和 false 是 boolen 型的标准常量,maxint 是 integer 型的标准常量,表示最大值。三者属于系统定义的常量,可直接使用,不必定义。注:资源字符串的定义方式还可以这样:resourcestringstrName = 文件 ;2) var 变量名:类型名=初始值;3.语句和流程控制1).基本语句 包

8、括赋值语句: 用“:=”;空语句:不执行任何操作;过程语句:如读语句 read 用于从标准输入设备(键盘)中输入数据;写语句 write 用于向标准输出设备(显示器)输出数据。Writeln()输出一个回车换行符。2)流程控制语句If 语句(1)if.then.;(2)if 条件then 语句 1else 语句 2;(3)if 条件 1then 语句 1else if then 语句 2else 语句 3;注意 then 和 else 字句之间不能有分号,只需在最后语句加上分号和其它语句分开就好。Case 语句Case 表达式 of常量 1:语句 1;常量 2:语句 2;常量 n:语句 n;E

9、nd;For 语句递增型 for 语句For 控制变量:=初值 to 终值 do语句;递减型 for 语句For 控制变量:=初值 downto 终值 do语句;Delphi 基础While 语句(先判断后执行)While 布尔表达式 do语句;Repeat 语句(先执行后判断,保证循环体最少执行一次)Repeat(循环体)语句;Until 布尔表达式;Break 跳出循环;continue 结束本次循环,回到循环条件,判断是否执行下一次循环。Break 和 从 continue 语句常和循环语句搭配使用。Exit 退出函数或代码块(复合语句),halt 终值程序运行(非正常),返回操作系统。

10、Goto 标号;使用前需要用关键字 label 定义 标号如:label 标号 1,标号 2;3)With 语句 With 语句是一种用于简化代码的语句。如你要访问一个记录类型变量(或一个对象),用 With语句就不必每次重复变量的名字。例如对于以下的记录类型代码:typeDate = recordYear: Integer;Month: Byte;Day: Byte;end;varBirthDay: Date;beginwith BirthDay dobeginYear := 1995;Month := 2;Day := 14;end;end;在 Delphi 程序中,这种方法能用于访问控件

11、和类变量。4、过程和函数无论过程和函数,都遵循“先说明后使用”的原则。1)过程Procedure 过程名(var 参数:类型);/过程首部过程变量声明; /过程说明begin 语句 /语句体end;Delphi 基础2)函数(Result:函数返回)Funciton 函数名(var 参数:类型); /函数首部函数变量声明;begin 语句 /语句体end;3)参数传递:数值参数,简称值参:不带 var 的,称为数值参数。是缺省的参数传递方式:即将值参的拷贝压入栈中,例程使用、操纵的是栈中的拷贝值,不是原始值。变量参数(传递参数),简称变参:带 var 的,实际传递的是一个实在参数变量的地址。当

12、通过引用传递参数时,没有按正常方式把参数值的拷贝压栈(避免拷贝值压栈一般能加快程序执行速度) ,而是直接引用参数原始值,例程中的代码也同样访问原始值,这样就能在过程或函数中改变参数的值。引用参数用关键字 var 标示。常量参数:带 const 的,常为常量参数。4)函数重载 重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同。实际上,编译器是通过检测参数来确定需要调用的例程。下面是从 VCL 的数学单元(Math Unit)中摘录的一系列函数:function Min (A,B: Integer): Integer; overload;function Min

13、(A,B: Int64): Int64; overload;function Min (A,B: Single): Single; overload;function Min (A,B: Double): Double; overload;function Min (A,B: Extended): Extended; overload;当调用方式为 Min (10, 20)时,编译器很容易就能判定你调用的是上列第一个函数,因此返回值也是个整数。声明重载函数有两条原则: 每个例程声明后面必须添加 overload 关键字。 例程间的参数个数或(和)参数类型必须不同,返回值不能用于区分各例程。 5

14、.面向对象概念初步1.类的定义类的定义分两步:首先在类(单元)的接口(interface)部分说明这个方法.然后在实现部分Delphi 基础(implementation)部分编写方法的实现代码.定义:type类名=class(父类名)数据域说明; /类内部使用变量/常量的声明;方法说明首部;end;实现代码:procedure 类名.方法(参数);实现代码;end;2.创建对象及对象成员的引用创建对象分两步: 首先声明对象,语法格式为 var 类名;/此时对象名还只是个指针,没分配到内存。然后调用 create 分配内存 语法格式为 对象名:=类名.create。对象中数据域(C+中的数据成

15、员)和方法的引用 语法如下:对象.数据域;对象.方法;释放对象 对象.free;3类的封装类的每个成员都有一个称为可见性的属性,我们用下面的关键字之一来表示它:private、protected、 public、published 和 automated类的的数据域(数据成员):1)Fields (字段) 字段就像属于对象的一个变量,它可以是任何类型,包括类类型 (也就是说,字段可以存储对象的引用)。 字段通常具有 private 属性。 2)方法:(1)方法的类型 对象的方法能定义成静态( static )、虚拟( virtual )、动态( dynamic)或消息处理(message )。

16、1. 静态方法 静态方法是方法的缺省类型,对它就像对通常的过程和函数那样调用。编译器知道这些方法的地址,所以调用一个静态方法时它能把运行信息静态地链接进可执行文件。 静态方法执行的速度最快,但它们却不能被覆盖来支持多态性。 2. 虚拟方法(v i r t u a l)虚拟方法和静态方法的调用方式相同。由于虚拟方法能被覆盖,在代码中调用一个指定的虚拟方法时编译器并不知道它的地址。因此,编译器通过建立虚拟方法表 ( V M T )来查找在运行时的函数地址。所有的虚拟方法在运行时通过 V M T 来调度,一个对象的 V M T 表中除了自己定义的虚拟方法外,还有它的祖先的所有的虚拟方法,因此虚拟方法

17、比动态方法用的内存要多,但它执行得比较快。(速度优化) 虚拟方法还有一种特例,即抽象方法:例如procedure One;override;abstract;Delphi 基础在 One 方法后面,不但有 override 关键字,还多了一个 abstract 关键字(意为抽象)。这种方法称为抽象方法(在 C+中称为纯虚拟函数)。含有抽象方法的类称为抽象类。抽象方法的独特之处在于,它只有声明,而根本没有实现部分,如果你企图调用一个对象的抽象方法,你将得到一个异常。只有当这个类的派生类重载并实现了该方法之后,它才能够被调用。(在C+中,甚至根本就不能建立一个抽象类的实例。)既然如此,那么这种抽象

18、方法又有什么用呢?抽象方法本身不能够做任何事情,必须在子类中被重载并实现,才能够完成有意义的工作。但抽象方法的存在,相当于为父类留下了一个接口,当程序将一个子类的对象赋予父类的变量时,父类的变量就可以调用这个方法,当然此时它运行的是相应的子类中重载该方法的代码。如果没有这个抽象方法,父类的变量就不能调用它,因为它不能调用一个只在子类中存在、而在父类中不存在的方法!3. 动态方法 (d y n a m i c)动态方法跟虚拟方法基本相似,只是它们的调度系统不同。编译器为每一个动态方法指定一个独一无二的数字,用这个数字和动态方法的地址构造一个动态方法表 ( D M T )。不像 V M T 表,在

19、 D M T 表中仅有它声明的动态方法,并且这个方法需要祖先的 D M T 表来访问它其余的动态方法。正因为这样,动态方法比虚拟方法用的内存要少,但执行起来较慢,因为有可能要到祖先对象的 D M T 中查找动态方法。(代码大小优化) 4. 消息处理方法 (message)在关键字 m e s s a g e 后面的值指明了这个方法要响应的消息。用消息处理方法来响应 windows 的消息,这样就不用直接来调用它。声明方法时,通过包含 message 指示字创建,并在 message 后面跟一个介于149151 之间的整数常量,体指定消息的号码(ID)。一个message 方法必须具有一个单一

20、var 参数的过程。例TyptTtextbox=class(Tcustomcontrol)Private WMChar(var Message:TWMChar);message WM_CHAR;Endl;(2)方法的覆盖 在 Object Pascal 覆盖一个方法用来实现 O O P 的多态性概念。通过覆盖使一方法在不同的派生类间表现出不同的行为。Object Pascal 中能被覆盖的方法是在声明时被标识为 v i r t u a l 或 d y n a m i c 的方法。为 了覆盖一个方法,在派生类的声明中用 o v e r r i d e 代替 v i r t u a l 或 d y

21、 n a m i c 。如果不含 override 关键字,如果子类声明和父类相同的方法,则视为新建。T1classProcedure Draw;virtual;End;T2=calss(T1)Procedure Draw;override;End;(3)方法的重载所有方法都支持重载。重载后,子类可以含有和祖先类的方法具有不同参数的方法,它只是重载了该方法,并没覆盖它,调用时编译器依靠参数决定到底调用哪一个。能重载的方法必须用o v e r l o a d 指示符标识出来。若要重载的是 虚方法 则需要使用 reintroduce 指示字。Delphi 基础如 (重载虚方法)typeT1clas

22、s(Tobject)Procedure test(I:integer);virtual;End;T2=calss(T1)Procedure Test(S:string);reintroduce;oveload;;End;(4)方法的继承例如,你如果使用以下代码:typeTMyClass = classprocedure One;virtual;end;typeTNewClass = class(TMyClass)procedure One;override;end;procedure TMyclass.One;virtual;beginShowMessage(调用了 TMyclass 的方法!

23、);end;procedure TNewClass.One; override;beginInherited;ShowMessage(调用了 TNewClass 的方法!);end;可以看到,从 TMyClass 派生了一个新类 TNewClass。这两个类都声明了一个名字相同的方法 One。所不同的是,在 TMyClass 中,One 方法后面多了一个 Virtual 关键 字,表示这个方法是一个虚拟方法(Virtual Method)。而在 TNewClass 中,One 方 法后面多了一个Override 关键字,表示该方法进行了重载(Override)。重载技术能够实现许多特殊的功能。

24、让我们来仔细分析它们的实现部分。在 TMyclass.One 方法的实现部分,调用ShowMessage 过程弹出一个对话框,说明该方法已被调用;这里没有任何特别的地方。在TNewClass.One 方法中,出现了一条以前从未出现过的语句:Inherited;这个词的中文意思是“继承”。我们暂时不要去涉及到太过复杂的 OOP 概念,只要知道这条语句的功能就是了。它的功能是调用基类中相同的虚拟方法中的代码。那么程序将弹出两次对话框,第一次是调用 TMyclass 类中的 One 方法,第二次才是TNewClass.One 方法中的代码。Delphi 基础重载技术使得我们不但可以在派生类中添加基类

25、没有的数据和方法,而且可以非常方便地继承基类中原有方法的代码,只需要简单地加入 Inherited 就可以了。如果你不加入Inherited 语句,那么基类的相应方法将被新的方法覆盖掉。(4)方法的构造函数和析构函数Constructors Create;Destructor Destroy;使用 对象,Create;对象.Destroy;(最好使用 对象.free)3)属性普通属性我们在 delphi 的类中常常能看到这样的代码:propert property 属性名 类型名 read 字符串 1 write 字符串 2例如:property Left: Integer read FLef

26、t write SetLeft;我们在 private 中看到申明:procedure SetLeft(Value: Integer);(方法)和如下代码实现:procedure TControl.SetLeft(Value: Integer);beginSetBounds(Value, FTop, FWidth, FHeight);Include(FScalingFlags, sfLeft);end;如果你写了如下代码改变 left:control1.left:=23,那么程序调用了函数 SetLeft(23),SetBounds 是改变区域的函数,这里你就明白了它封装了的好处,每次你改变

27、left 时它就会根据新的 left 而改变区域的大小,这个函数同时也改变了 Fleft 的大小。这样外部就看起来只是通过赋值运算来改变了该属性的值。Read 和 write 可以是变量,或者是函数,取决于你的设计。你当然可以这样写: propert property 属性名 类型名 read 变量 1(函数) write 变量 2(函数)。变量 1 和变量 2 可以是相同的。你也可以这样propert property 属性名 类型名 read 方法 1 write 方法 2。任你组合。但是有 2 点要注意:1.命名规则最好按习惯来,易于阅读。2. 如果是变量,那么类型要和属性的类型一致,如

28、果是方法,那么入口参数要和属性的类型一致。声明部分:TypeTdog=calssPrivateColor:string;Function Getcolor(x:string);Procedure Setetcolor(x:string)PublicProperty x:string read Getcolor write setcoler;Delphi 基础End;实现部分:Fenction Tdog.Getcolor :string;BeginResult:=color;End;Procedure Tdog.setcoler(value:string)BeginColor:=value;En

29、d;事件属性 Tevent我们常常使用组件的事件属性,比方说 click 事件,可是我们很难从表面看出它是如何调用的呢,如何触发的呢。下面我来给你解答。我们在属性管理器 object inspector 中看到 event 页 onclick 右边对应了一个方法的名字。我们其实可以这样给一个组件的事件对应上一个出来方法。以一个 form 为例子 Form1. OnMouseDown:=你的方法。注意方法的入口参数有讲究,这里是(Sender:TObject)我们还是一 tcontrol 为例子,我们找到这段代码:property OnMouseDown: TMouseEvent read FO

30、nMouseDown write FOnMouseDown;跟上面讲的类似,不过这里有个特殊的类型,TNOtifyEvent,是个事件类型,我们找到它的申明:TMouseEvent = procedure(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer) of object;可以看到,它其实就是个函数,但是蓝色部分把入口参数限定了。那么我们通过赋值Form1. OnMouseDown:=你的方法,就对应了 OnMouseDown 的方法。然后我们只要写了一段拦截鼠标消息的函数,在里面直接或间接调用

31、FonMouseDown,那么就把消息和处理函数对应上去了。这里它间接调用的层数比较多,讲起来比较费时间,涉及到 Message 类型,建议大家去看下李维的书。以下附上间接调用过程,其实还要很多消息发生时也间接调用了,就不一一举出来了:(procedure WMRButtonDblClk(var Message: TWMRButtonDblClk); message WM_RBUTTONDBLCLK;/拦截消息的函数procedure TControl.WMRButtonDblClk(var Message: TWMRButtonDblClk);begininherited;DoMouseDo

32、wn(Message, mbRight, ssDouble);end;procedure DoMouseDown(var Message: TWMMouse; Button: TMouseButton;Shift: TShiftState);procedure TControl.DoMouseDown(var Message: TWMMouse; Button: TMouseButton;Shift: TShiftState);beginif not (csNoStdEvents in ControlStyle) thenwith Message doif (Width 32768) or (

33、Height 32768) thenDelphi 基础with CalcCursorPos doMouseDown(Button, KeysToShiftState(Keys) + Shift, X, Y)elseMouseDown(Button, KeysToShiftState(Keys) + Shift, Message.XPos, Message.YPos);end;procedure MouseDown(Button: TMouseButton; Shift: TShiftState;X, Y: Integer); dynamic;procedure TControl.MouseDo

34、wn(Button: TMouseButton;Shift: TShiftState; X, Y: Integer);beginif Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y);end;好处:如果你多写自己的类,你会发现这样做是多么的方便, delphi 你都只是调用contol1.text 来访问,control1.text:=某字符串来修改它的值。而在处理消息方面,基类把 onclick,onmousedown 这样的属性申明为 protected,如果你要使用,可以申明为 published 就可

35、以出现在 object inspector 里面,然后方便的写处理方法,你也可以不公开,而在 ctreate 函数中给它赋值,而不用像 java 那样,写 listener 那么复杂。5.类的多态虚方法和动态方法通过覆盖和重载技术实现多态。6类的继承 7.类方法类方法是作用在类而不是对象上面的方法(不同于构造函数)。类方法的定义必须以关键字 class 开始, 比如, type TFigure = class public class function Supports(Operation: string): Boolean; virtual; class procedure GetInfo(

36、var Info: TFigureInfo); virtual; . end; 类方法的定义部分也必须以 class 开始,比如, class procedure TFigure.GetInfo(var Info: TFigureInfo); begin . end; Delphi 基础在类方法的定义部分,Self 表示调用方法的类 类方法既可以通过类引用来调用,也可以使用对象,当使用后者时, Self 值等于对象所属的类。 7.Self 参数:Self 是指所编的程序范围是在哪一个类中,Delphi 中大都在窗体范围内编程,因此,Self 即指窗体,假如在编写一个类或是一个组件,则 Self

37、 指该类或该组件.我们在过程和函数的声明中可以看出Self 是代表哪个组件,即 Self 代表“.“号之前的组件.另外应注重,Self 只能用在类方法中,而不能用在过程或函数中.6.流文件流操作Delphi 操作流文件:什么是流?流,简单来说就是建立在面向对象基础上的一种抽象的处理数据的工具。在流中,定义了一些处理数据的基本操作,如读取数据,写入数据等,程序员是对流进行所有操作的,而不用关心流的另一头数据的真正流向。流不但可以处理文件,还可以处理动态内存、网络数据等多种数据形式。如果你对流的操作非常熟练,在程序中利用流的方便性,写起程序会大大提高效率的。一、Delphi 中流的基本概念及函数声

38、明在 Delphi 中,所有流对象的基类为 TStream 类,其中定义了所有流的共同属性和方法。TStream 类中定义的属性介绍如下:1、Size:此属性以字节返回流中数据大小。2、Position:此属性控制流中存取指针的位置。Tstream 中定义的虚方法有四个:1、Read:此方法实现将数据从流中读出。函数原形为:Function Read(var Buffer;Count:Longint):Longint;virtual;abstract;参数 Buffer 为数据读出时放置的缓冲区,Count 为需要读出的数据的字节数,该方法返回值为实际读出的字节数,它可以小于或等于 Count

39、 中指定的值。2、Write:此方法实现将数据写入流中。函数原形为:Function Write(var Buffer;Count:Longint):Longint;virtual;abstract;参数 Buffer 为将要写入流中的数据的缓冲区,Count 为数据的长度字节数,该方法返回值为实际写入流中的字节数。3、Seek:此方法实现流中读取指针的移动。函数原形为:Function Seek(Offset:Longint;Origint:Word):Longint;virtual;abstract;参数 Offset 为偏移字节数,参数 Origint 指出 Offset 的实际意义,其

40、可能的取值如下:soFromBeginning:Offset 为移动后指针距离数据开始的位置。此时 Offset 必须大于或者等于零。soFromCurrent:Offset 为移动后指针与当前指针的相对位置。soFromEnd:Offset 为移动后指针距离数据结束的位置。此时 Offset 必须小于或者等于零。该方法返回值为移动后指针的位置。4、Setsize:此方法实现改变数据的大小。函数原形为:Function Setsize(NewSize:Longint);virtual;另外,TStream 类中还定义了几个静态方法:1、ReadBuffer:此方法的作用是从流中当前位置读取数据

41、。函数原形为:Procedure ReadBuffer(var Buffer;Count:Longint);Delphi 基础参数的定义跟上面的 Read 相同。注意:当读取的数据字节数与需要读取的字节数不相同时,将产生 EReadError 异常。2、WriteBuffer:此方法的作用是在当前位置向流写入数据。函数原形为:Procedure WriteBuffer(var Buffer;Count:Longint);参数的定义跟上面的 Write 相同。注意:当写入的数据字节数与需要写入的字节数不相同时,将产生 EWriteError 异常。3、CopyFrom:此方法的作用是从其它流中拷

42、贝数据流。函数原形为:Function CopyFrom(Source:TStream;Count:Longint):Longint;参 数 Source 为提供数据的流,Count 为拷贝的数据字节数。当 Count 大于 0 时,CopyFrom从 Source 参数的当前位置拷贝 Count 个字 节的数据;当 Count 等于 0 时,CopyFrom 设置Source 参数的 Position 属性为 0,然后拷贝 Source 的所有数据;TStream 还有其它派生类,其中最常用的是 TFileStream 类。使用 TFileStream 类来存取文件,首先要建立一个实例。声明

43、如下:constructor Create(const Filename:string;Mode:Word);Filename 为文件名(包括路径),参数 Mode 为打开文件的方式,它包括文件的打开模式和共享模式,其可能的取值和意义如下:打开模式:fmCreate :用指定的文件名建立文件,如果文件已经存在则打开它。fmOpenRead :以只读方式打开指定文件fmOpenWrite :以只写方式打开指定文件fmOpenReadWrite:以写写方式打开指定文件共享模式:fmShareCompat :共享模式与 FCBs 兼容fmShareExclusive:不允许别的程序以任何方式打开该文

44、件fmShareDenyWrite:不允许别的程序以写方式打开该文件fmShareDenyRead :不允许别的程序以读方式打开该文件fmShareDenyNone :别的程序可以以任何方式打开该文件TStream 还有一个派生类 TMemoryStream,实际应用中用的次数也非常频繁。它叫内存流,就是说在内存中建立一个流对象。它的基本方法和函数跟上面是一样的。delphi 编写和调用 dll 文件Delphi 基础Windows 的执行文件可以划分为两种形式程序和动态连接库 (DLLs) 。一般程序运行是用.EXE 文件,但应用程序有时也可以调用存储在 DLL 的函数。 在如下几种情况下,

45、调用 DLL 是合理的: 1) 不同的程序使用相同的 DLL ,这样只需要将 DLL 在内存中装载一次,节省了内存的开销。 2) 当某些内容需要升级的时候,如果使用 DLL 只需要改变 DLL 就可以了,而不需要把整个程序都进行变动。 3) 由于 DLL 是独立于语言的,所以,当不同语言习惯的人共同开发一个大型项目的时候,使用DLL 便于程序系统的交流,当然,Delphi 开发的 DLL 也可以在诸如 Visual BASIC,C+ 等系统中使用。 下面通过几个例子,说明 Delphi 开发动态连接库的方法和规范。 第一节 动态连接库的构建和调用方法 一、动态连接库构建1.创建了一个动态连接库

46、的基本模块File-New-Other-DLL Wizard library Project1; 如果DLL输出的过程或函数带有长字符类型的参数,或者函数返回类型是长字符串或带有长字符串元素的构造类型,Object Pascal规定无论是DLL还是调用它的程序必须把ShareMem单元加到Uses部分。而ShareMem单元是从DelphiMM.DLL这个DLL中引入的接口单元,因此这种程序分发时必须带有DelphiMM.DLL。Delphi建议为了避免使用DELPHIMM.DLL,传递字符串信息时使用PChar或ShortString类型参数。(原文为英文) uses SysUtils, C

47、lasses; ( 代码部分)$R *.res begin end. 把工程名改为 Math(Save Project as ),并写入必要的函数 library Math;usesSysUtils,Classes;function Mround (d:Double ):Double ;stdcall; /四舍五入函数:数学上的四舍五入函数不 begin /同于 Delphi 的银行家四舍五入法Result:=Int(d*100+0.5)/100;end;exportsMround ;$R *.RESDelphi 基础beginend.从这个例子中可以看出 DLL 程序的几个规则: 1) 在D

48、LL 程序中,输出函数必须被声明为stdcall ,以使用标准的 Win32 参数传递技术来代替优化的Register。参数的调用约定。调用约定如下:指令 传递顺序 参数删除stdcall 从左到右 函数方面cdecl 从右到左 调用方面Pascal 从左到右 函数方面register 从左到右 函数方面 (说明:register,默认,即是 唯一使用 CPU寄存器的参数传递方式,也是传递速度最快的方式; pascal: 调用协议仅用于向后兼容,即向旧的版本兼容;cdecl: 多用于 C和 C+语言编写的例程,也用于需要由调用者清除参数的例程; stdcall: 和safecall主要用于调用

49、Windows API 函数;其中safecall还用于双重接口。2)所有的输出函数都必须列在 exports 子句下面,这使的子例程在 DLL 外部就可以看到。exportsMroundname 别名 ;列出了用户使用这个函数的接口名字。虽然别名不是必须的,但最好给个别名,以便用户程序更容易找到这个函数,同时还要指出 Delphi 6.0 取消了 Delphi 5.0 中允许使用的 index ,如果还用Index 指明接口名字,Delphi 6.0 中将提示错误。 实例中给出了 messagebox 提示方法,主要想说明一个问题:而 messagebox(0,mb_ok) 是 Windows 提供的 API 函数,做出的程序会比较小。 Showmessage(),是 VCL 提供的函数,由于多次编译 VCL,做出的程序会比较大。 这就是说,编写 DLL 程序的时候,要尽量避免多次编译 VCL 。作为一个实例,这里把两种方法都列出来了。 2.保存 3.编

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报