7884 lines
122 KiB
Markdown
7884 lines
122 KiB
Markdown
# 05 对象模型(class/unit)
|
||
|
||
本章整理 Object TSL 的类、对象、属性、方法与相关语法。
|
||
|
||
## 目录
|
||
|
||
- [Object TSL](#object-tsl)
|
||
- [内容](#内容)
|
||
- [类和对象](#类和对象)
|
||
- [内容](#内容-1)
|
||
- [概述](#概述)
|
||
- [类类型声明的语法](#类类型声明的语法)
|
||
- [类类型声明的位置](#类类型声明的位置)
|
||
- [类的实例化](#类的实例化)
|
||
- [对象成员的访问](#对象成员的访问)
|
||
- [类继承和作用域](#类继承和作用域)
|
||
- [内容](#内容-2)
|
||
- [继承](#继承)
|
||
- [作用域](#作用域)
|
||
- [字段](#字段)
|
||
- [内容](#内容-3)
|
||
- [字段简介](#字段简介)
|
||
- [static 静态字段](#static静态字段)
|
||
- [const 常量成员](#const常量成员)
|
||
- [方法](#方法)
|
||
- [内容](#内容-4)
|
||
- [方法简介](#方法简介)
|
||
- [声明和实现](#声明和实现)
|
||
- [覆盖(override)](#覆盖override)
|
||
- [多态](#多态)
|
||
- [隐藏](#隐藏)
|
||
- [重载(overload)](#重载overload)
|
||
- [构造函数](#构造函数)
|
||
- [析构函数](#析构函数)
|
||
- [指定类](#指定类)
|
||
- [Self](#self)
|
||
- [类方法](#类方法)
|
||
- [属性 Property](#属性property)
|
||
- [索引器(index)](#索引器index)
|
||
- [TSL 对象的创建](#tsl对象的创建)
|
||
- [内容](#内容-5)
|
||
- [New](#new)
|
||
- [CreateObject](#createobject)
|
||
- [类信息](#类信息)
|
||
- [内容](#内容-6)
|
||
- [FindClass](#findclass)
|
||
- [ClassInfo](#classinfo)
|
||
- [objectstate](#objectstate)
|
||
- [tslassigning](#tslassigning)
|
||
- [对象的引用计数](#对象的引用计数)
|
||
- [IS 关键字](#is关键字)
|
||
- [函数信息](#函数信息)
|
||
- [内容](#内容-7)
|
||
- [FindOverLoad](#findoverload)
|
||
- [TSLObjects](#tslobjects)
|
||
- [FindFunction](#findfunction)
|
||
- [ThisFunction](#thisfunction)
|
||
- [FunctionInfo](#functioninfo)
|
||
- [算符重载](#算符重载)
|
||
- [内容](#内容-8)
|
||
- [Operator](#operator)
|
||
- [算符重载的案例](#算符重载的案例)
|
||
- [面向对象的 Operator 重载支持[]](#面向对象的operator重载支持)
|
||
- [面向对象的 Operator 算符重载支持++,--,+=,-=](#面向对象的operator算符重载支持)
|
||
- [单元中的类](#单元中的类)
|
||
- [内容](#内容-9)
|
||
- [继承单元中的类](#继承单元中的类)
|
||
- [构造单元中的类实例](#构造单元中的类实例)
|
||
- [预定义:ParentClassInUnit](#预定义parentclassinunit)
|
||
- [单元中的类-应用实例](#单元中的类-应用实例)
|
||
- [TSL 内置对象使用大全](#tsl内置对象使用大全)
|
||
- [内容](#内容-10)
|
||
- [TSL 内置对象使用大全简介](#tsl内置对象使用大全简介)
|
||
- [FTP 对象](#ftp对象)
|
||
- [TRSA](#trsa)
|
||
- [TCipher](#tcipher)
|
||
- [TStringList 对象](#tstringlist对象)
|
||
- [THashedStringList 对象](#thashedstringlist对象)
|
||
- [TStream 对象](#tstream对象)
|
||
- [TMemoryStream 对象](#tmemorystream对象)
|
||
- [THandleStream 对象](#thandlestream对象)
|
||
- [TFileStream 对象](#tfilestream对象)
|
||
- [TIniFile 对象](#tinifile对象)
|
||
- [TMemIniFile 对象](#tmeminifile对象)
|
||
- [TRegistryIniFile 对象](#tregistryinifile对象)
|
||
- [TWebResponse 对象](#twebresponse对象)
|
||
- [TWebRequest 对象](#twebrequest对象)
|
||
- [TCookieCollection 对象](#tcookiecollection对象)
|
||
- [TCookie 对象](#tcookie对象)
|
||
- [TSessionMan 对象](#tsessionman对象)
|
||
- [TSession 对象](#tsession对象)
|
||
- [SMTP 对象](#smtp对象)
|
||
- [Pop3 对象](#pop3对象)
|
||
- [MailMsg 对象](#mailmsg对象)
|
||
- [MessagePart 对象](#messagepart对象)
|
||
|
||
## Object TSL
|
||
|
||
### 内容
|
||
|
||
- 类和对象
|
||
- 类继承和作用域
|
||
- 字段
|
||
- 方法
|
||
- 属性 Property
|
||
- 索引器(index)
|
||
- TSL 对象的创建
|
||
- 类信息
|
||
- IS 关键字
|
||
- 函数信息
|
||
- 算符重载
|
||
- 单元中的类
|
||
- TSL 内置对象使用大全
|
||
|
||
### 类和对象
|
||
|
||
面向对象的概念是相对于面向过程的
|
||
|
||
面向过程的表现形式是函数,数据以参数、系统参数、全局变量的模式传导进函数
|
||
|
||
面向对象的表现形式是类,数据以成员变量的方式存贮在类变量中,而具体的功能以成员函数的方式存在
|
||
|
||
面向对象的最原始的目的在于封装,将数据与多种方法封装在一起
|
||
|
||
此外,继承、多态等也是面向对象的特性
|
||
|
||
#### 内容
|
||
|
||
- 概述
|
||
- 类类型声明的语法
|
||
- 类类型声明的位置
|
||
- 类的实例化
|
||
- 对象成员的访问
|
||
|
||
#### 概述
|
||
|
||
类(或者类类型)定义了一个结构,抽象地,这个结构既可以包括数据,也可以包括行为;
|
||
|
||
具体地,类可以包括字段、方法和属性;
|
||
|
||
类的字段、方法和属性被称为它的成员。
|
||
|
||
类的实例叫做对象;
|
||
|
||
> > 字段在本质上是一个对象的变量。和记录的字段类似,类的字段表示一个类实例的数据项;
|
||
|
||
> > 方法是一个函数,它和类相关联。绝大多数方法作用在对象(也就是类的实例)上,其它一些方法(称为类方法)作用在类上面。
|
||
|
||
> > 属性被看作是访问对象的数据的接口,对象的数据通常用字段来存储。属性可以决定数据如何被读取或修改。属性在被引用的时候就像一个字段,但被实现时候可以是一个方法。
|
||
|
||
声明了类以后,程序员可以创建作为此类的实例对象。尽管有时类和对象叫法可互换,但它们是不同的概念。类定义对象的类型,但它不是对象本身。对象是基于类的具体实体,有时称为类的实例。
|
||
|
||
```text
|
||
Type MyClass = Class
|
||
|
||
End;
|
||
```
|
||
|
||
上面代码声明了一个类类型
|
||
|
||
```text
|
||
Obj:=createObject("MyClass");
|
||
```
|
||
|
||
上面代码创建了类 MyClass 的实例.
|
||
|
||
创建类的实例后,将向程序员传递回对该对象的引用。
|
||
|
||
在前面的示例中,obj 是对基于 MyClass 的对象的引用。此引用指向了新对象,但不包含对象数据本身。
|
||
|
||
#### 类类型声明的语法
|
||
|
||
```text
|
||
type
|
||
className =
|
||
class
|
||
([BaseClass1[,BaseClass2,…]])
|
||
|
||
private //作用域关键字,private表示下面声明的是私有化成员
|
||
|
||
//memberList
|
||
|
||
|
||
Public //作用域关键字,public表示公开成员,不写此类关键字时默认为public
|
||
|
||
//memberList
|
||
|
||
function Create();overload;//初始化--构造函数--可省
|
||
|
||
function Destroy();//析构函数--可省
|
||
|
||
function func1();//成员方法
|
||
|
||
end;
|
||
```
|
||
|
||
说明:
|
||
|
||
Type 是一个关键字,说明要声明一个类型,Class 也是一个关键字,表示要声明一个类类型。
|
||
|
||
className 是要声明的你自己定义的类类型的名字,可以是任何有效标志符.
|
||
|
||
BaseClass1,BaseClass2,… 可选,表示要继承的父类型,可以是 0 个、1 个或多个,如果是多个其中用逗号分割.如果此参数为空,可以省略 class 后面的小括号
|
||
|
||
memberList 声明类的各成员,也就是它的字段、方法和属性。可选.
|
||
|
||
注:
|
||
|
||
一个 Type …End;只能声明一个类类型;
|
||
|
||
即使 memberList 为空也不能省略 end;
|
||
|
||
完整示例:
|
||
|
||
```text
|
||
Type Person = Class
|
||
|
||
//字段
|
||
|
||
name;
|
||
|
||
|
||
//方法
|
||
|
||
function SetName(newName);
|
||
|
||
Begin
|
||
|
||
name:=newName;
|
||
|
||
end;
|
||
|
||
|
||
// 方法
|
||
|
||
Function DisplayName();
|
||
|
||
begin
|
||
|
||
writeln(name);
|
||
|
||
end;
|
||
|
||
|
||
//属性
|
||
|
||
Property theName read name write name;
|
||
|
||
End;
|
||
```
|
||
|
||
以上代码包括了一个完整类类型的声明:
|
||
|
||
声明了一个 Person 的类类型,也为 Person 类型声明了下面的成员:
|
||
|
||
字段:Name
|
||
|
||
方法:SetName 和 DisplayName
|
||
|
||
属性:theName
|
||
|
||
#### 类类型声明的位置
|
||
|
||
与其他类型不同,类类型必须在实例化之前声明并给定一个名称。有三种地方可以声明类类型:
|
||
|
||
1、在程序(program)的最外层声明类,在执行语句块的前面,而不能在过程或函数中声明.
|
||
|
||
示例:
|
||
|
||
```text
|
||
program test;
|
||
|
||
//声明了一个名称为myClass的类类型
|
||
|
||
Type myClass = Class
|
||
|
||
//这里可以定义类的成员:字段、方法、属性
|
||
|
||
End;
|
||
|
||
Begin
|
||
|
||
//这里可以初始化并使用上面声明的类类型
|
||
|
||
C:=CreateObject("myClass");
|
||
|
||
End.
|
||
```
|
||
|
||
2、在主函数的后便声明,示例:
|
||
|
||
```text
|
||
Function abcd();
|
||
|
||
Begin
|
||
|
||
A:=CreateObject("myClass");
|
||
|
||
End;
|
||
|
||
Type myClass = Class
|
||
|
||
End;
|
||
```
|
||
|
||
3、在非 Program 开头的 TSL 语句段后。
|
||
|
||
如:
|
||
|
||
```text
|
||
…………..
|
||
|
||
A:=CreateObject("myClass");
|
||
|
||
…………
|
||
|
||
Type myClass = Class
|
||
|
||
End;
|
||
```
|
||
|
||
4、也可以在 "TSL 解释器安装目录\funcext\" 下面或者在其下的子目录下建立一个同名的.tsf 文件,在文件内部声明一个类类型,文件名和类名必须相同。
|
||
|
||
如:把 myClass 的类类型放在 myClass.tsf 文件中。这样可以被全局引用。
|
||
|
||
#### 类的实例化
|
||
|
||
创建一个类的实例对象,TSL 中提供了两种方式:
|
||
|
||
方式一:调用 CreateObject 函数进行创建;
|
||
|
||
```text
|
||
CreateObject
|
||
(<classname:String|ClassType>[,P1,P2…]):TSLObject
|
||
```
|
||
|
||
用类名字符串或者用一个类类型来创建一个类的对象,返回新建对象的引用。
|
||
|
||
方式二:使用 New 关键字方式进行创建:
|
||
|
||
```text
|
||
New
|
||
ClassName([P1,P2…]):TSLObject
|
||
```
|
||
|
||
和 CreateObject 类似,但 ClassName 不再需要是一个字符串,而是直接写出类名即可,在类名后用(),括号里可以加入构造函数的参数。
|
||
|
||
注意:类名两端的括号不能省略,可使用字符串常量,也可以使用字符串变量。
|
||
|
||
也可以使用类类型作为对象的构造,类类型可以用 class(classname)以及 findclass 等来获得。
|
||
|
||
如果要创建类 Person 的实例,写法可以是以下两种方式:
|
||
|
||
```text
|
||
Obj:=CreateObject('person');
|
||
|
||
obj:=new person();
|
||
```
|
||
|
||
如果类的构造器有参数,则需要把参数列表一起传给 CreateObject 函数,如给类 Person 的实例构造时指定两个属性:
|
||
|
||
```text
|
||
Obj:=CreateObject('person',"zhangfei",25);
|
||
|
||
obj:=new person("zhangfei",25);
|
||
```
|
||
|
||
可以把对象的引用赋值给另外一个变量 Obj2 := Obj1;
|
||
|
||
这时 Obj2 和 Obj1 指向同一个实例,而不是 2 个实例。
|
||
|
||
#### 对象成员的访问
|
||
|
||
成员变量以及方法的访问
|
||
|
||
操作成员变量以及方法均采用.操作符。
|
||
|
||
例如:
|
||
|
||
```text
|
||
Human:=New Person("张三");
|
||
|
||
Human.mSex:="男";
|
||
|
||
Human.mBirthday:=20120101T;
|
||
|
||
Echo Human.GetAge();
|
||
```
|
||
|
||
##### 内容
|
||
|
||
- ?.模式访问 NIL 对象
|
||
|
||
##### ?.模式访问 NIL 对象
|
||
|
||
如果某个内容本身可能是 NIL,也可能是对象,如果我们希望当 NIL 的时候访问方法或者成员不报错返回 NIL。
|
||
|
||
这个时候我们传统需要使用 a?a.b:nil,如果对象访问是嵌套的,例如 a.b.c,那么需要使用 a and a.b?a.b.c:nil,这种情况下使用?.模式会更为表达清晰。
|
||
|
||
TSL 支持使用 a?.b?.c 完成上述需求,该功能和 JAVASCRIPT 的?.相仿。同样的,我们也支持 a?.[index]模式访问,当 a 为 NIL 返回 NIL
|
||
|
||
具体可参考:?.模式
|
||
|
||
### 类继承和作用域
|
||
|
||
#### 内容
|
||
|
||
- 继承
|
||
- 作用域
|
||
|
||
#### 继承
|
||
|
||
面向对象中,继承是基础。我们可以对已有的类复用和扩展。通过继承我们可以让新类拥有了已有类的数据和行为。也可以扩展新类,使它具有更多的数据和行为。
|
||
|
||
我们这里称已有类为新类的基类或父类,有的地方也叫超类。
|
||
|
||
我们称新类为已有类的子类或派生类。
|
||
|
||
由于 TSL 支持多级继承。其中基类,基类的基类(如果有的话)都统一叫做子类的祖先类。
|
||
|
||
子类可以通过继承获得基类的数据和方法,有效复用,提高开发效率,使代码易于维护。
|
||
|
||
TSL 继承的实现方式是:声明类类型时,在 Class 后面的括号内指定父类型的名称。TSL 支持多重继承,基类可以指定多个,其中用逗号分割。格式为:
|
||
|
||
type myClass = class(BaseClass1[,BaseClass2,…]);
|
||
|
||
以上代码定义了一个叫做 myClass 的类,它继承自 BaseClass1、BaseClass2 列表。这样我们称 MyClass 为子类,BaseClass1,BaseClass2…为 MyClass 的基类或父类。也可以叫祖先类.
|
||
|
||
子类 MyClass 将获得基类(BaseClass1、BaseClass2、…)的所有非私有数据和行为,此外新类可以为自己定义新的数据和行为进行扩展,也可以重新定义基类中的行为.
|
||
|
||
示例:
|
||
|
||
```text
|
||
Program test;
|
||
|
||
//声明类A
|
||
|
||
Type A = class
|
||
|
||
Function F1()
|
||
|
||
Begin
|
||
|
||
Writeln("call A.F1");
|
||
|
||
End;
|
||
|
||
End;
|
||
```
|
||
|
||
//声明类 B,继承自 A
|
||
|
||
```text
|
||
Type B =Class(A)
|
||
|
||
End;
|
||
|
||
|
||
Begin
|
||
|
||
//创建B类的实例对象BB
|
||
|
||
BB:=CreateObject("B");
|
||
|
||
BB.F1;
|
||
|
||
End.
|
||
```
|
||
|
||
上面代码类 B 通过继承获得类 A 的方法 F1(),自己确不用定义方法 F1();
|
||
|
||
如果子类的多个基类都有同样的方法,在子类中调用这个方法时需要为这个方法指定具体的父类,方法为在调用的方法前面加上 Class(基类名称).
|
||
|
||
示例
|
||
|
||
```text
|
||
Type Base1 =Class
|
||
|
||
Function F();
|
||
|
||
Begin
|
||
|
||
writeln("Base1.F");
|
||
|
||
End;
|
||
|
||
End;
|
||
|
||
|
||
Type Base2 =Class
|
||
|
||
Function F();
|
||
|
||
Begin
|
||
|
||
writeln("Base2.F");
|
||
|
||
End;
|
||
|
||
End;
|
||
|
||
|
||
Type SubClass =Class(Base1,Base2)
|
||
|
||
Function CallBaseF();
|
||
|
||
Begin
|
||
|
||
class(Base2).F();//指定要调用类Base2的F方法。
|
||
|
||
End;
|
||
|
||
End;
|
||
|
||
|
||
Begin
|
||
|
||
S:=CreateObject("SubClass");
|
||
|
||
S.CallBaseF();
|
||
|
||
End.
|
||
```
|
||
|
||
以上代码演示在类内部调用多个基类相同方法的方法,如果在子类的外部调用这个方法,总是调用基类声明在最前面的类的方法。没有办法调用其他基类的方法,一个技巧是必须在子类中包装这个方法,在外面调用包装的方法。
|
||
|
||
##### 内容
|
||
|
||
- 继承单元类以及成员类
|
||
|
||
##### 继承单元类以及成员类
|
||
|
||
```text
|
||
Type AA=class(UNITB.CC) //支持单元名.类名模式继承
|
||
|
||
....
|
||
|
||
End;
|
||
```
|
||
|
||
同时也支持子类继承:
|
||
|
||
```text
|
||
new AA();
|
||
|
||
Type AA=class(BB.CC) //CC是BB的成员类
|
||
|
||
FAA;
|
||
|
||
End;
|
||
|
||
type BB=class
|
||
|
||
FBB;
|
||
|
||
type cc=class
|
||
|
||
FCC;
|
||
|
||
function create();
|
||
|
||
begin
|
||
|
||
echo "create";
|
||
|
||
end;
|
||
|
||
end;
|
||
|
||
end;
|
||
```
|
||
|
||
#### 作用域
|
||
|
||
类的每个成员都有一个称为可见性的属性,我们称为作用域。
|
||
|
||
作用域决定了一个成员在哪些地方以及如何能被访问。TSL 用下面 3 个关键字之一来表示它:private、protected、public
|
||
|
||
Private:私有域内定义的成员变量以及方法以及其他均属于私有的,仅供在类成员方法中使用
|
||
|
||
即表示最小的访问能力,只能在类内部的方法、属性调用,不能从类的外部调用;也不能被继承。
|
||
|
||
Protected:相比 Private,子类可以引用,但外部不行
|
||
|
||
即表示中等的访问能力,在声明它的类的模块中是随处可用的,并且在它的派生类中也是可用的。
|
||
|
||
Public:公有域内定义的内容均可以被内外部调用
|
||
|
||
即表示最大的访问能力,只要能使用类的地方都是可用的。
|
||
|
||
注:
|
||
|
||
若声明一个成员时没有指定其作用域,则它和前面的成员拥有相同的作用域.
|
||
|
||
若在类声明的开始没有指定作用域, TSL 成员(包括字段、方法、属性)默认的作用域是 public。
|
||
|
||
作用域关键字可以在程序中重复出现多次。
|
||
|
||
为可读性考虑,最好在声明类时用作用域来组织成员:把所有的 private 成员组织在一起,接下来是所有的 protected 成员,最后是 public 成员。用这种方法,每个可见性关键字最多出现一次,并且标明了每个新段的开始。所以,一个典型的类声明应该像下面的形式:
|
||
|
||
```text
|
||
type
|
||
|
||
|
||
MyClass =
|
||
class
|
||
(BaseClass)
|
||
|
||
private
|
||
|
||
|
||
... { private declarations here}
|
||
|
||
protected
|
||
|
||
|
||
... { protected declarations here }
|
||
|
||
public
|
||
|
||
|
||
... { public declarations here }
|
||
|
||
end
|
||
;
|
||
```
|
||
|
||
示例:
|
||
|
||
下面的代码详细说明了继承与作用域的关系
|
||
|
||
```text
|
||
program test;
|
||
|
||
type A =class()
|
||
|
||
private
|
||
|
||
function F1();
|
||
|
||
Begin
|
||
|
||
Writeln("from private F1");
|
||
|
||
End;
|
||
|
||
protected
|
||
|
||
Function F2();
|
||
|
||
Begin
|
||
|
||
Writeln("from protected F2");
|
||
|
||
End;
|
||
|
||
public
|
||
|
||
Function F3();
|
||
|
||
Begin
|
||
|
||
Writeln("from public F3");
|
||
|
||
End;
|
||
|
||
|
||
Function F4();
|
||
|
||
Begin
|
||
|
||
Writeln("from public F4");
|
||
|
||
F1();//正确,可以在类内部的方法调用private 的成员。
|
||
|
||
F2();//正确,可以在类内部的方法调用protected的成员
|
||
|
||
F3();//正确,可以在类内部的方法调用public的成员
|
||
|
||
End;
|
||
|
||
End;
|
||
|
||
|
||
Type B = Class(A)
|
||
|
||
Function F5();
|
||
|
||
Begin
|
||
|
||
Writeln(" Inherit test :call private funciton ");
|
||
|
||
F1();//错误,不能调用基类的私有方法
|
||
|
||
End;
|
||
|
||
Function F6();
|
||
|
||
Begin
|
||
|
||
Writeln("inherit test: call protected function");
|
||
|
||
F2();//正确,调用基类的protected 方法
|
||
|
||
End;
|
||
|
||
Function F7();
|
||
|
||
Begin
|
||
|
||
Writeln("inhert test :call public function ");
|
||
|
||
F3();//正确,调用基类的public 方法
|
||
|
||
End;
|
||
|
||
End;
|
||
|
||
|
||
Begin
|
||
|
||
AA:=createobject("A");
|
||
|
||
AA.F1();//错误,不能调用类型的private方法
|
||
|
||
AA.F2();//错误,不能调用类型的protected方法
|
||
|
||
AA.F3();//正确,可以调用类型的public 方法
|
||
|
||
AA.F4();//正确,可以调用类型的public 方法,方法内部可以调用private成员.
|
||
|
||
End.
|
||
```
|
||
|
||
### 字段
|
||
|
||
#### 内容
|
||
|
||
- 字段简介
|
||
- static 静态字段
|
||
- const 常量成员
|
||
|
||
#### 字段简介
|
||
|
||
字段就像属于对象的一个变量,我们也称之为成员变量,它可以是任何类型。对象用户存放对象的数据。
|
||
|
||
给类定义字段非常简单,只要把字段的名字在类的声明中列出即可。定义方法:
|
||
|
||
```text
|
||
Type myClass =Class
|
||
|
||
Field1;
|
||
|
||
Field2;
|
||
|
||
End;
|
||
```
|
||
|
||
以上的代码声明了一个 myClass 的类,同时定义了 2 个字段,Field1 和 Field2
|
||
|
||
引用:
|
||
|
||
1、在类内部的方法直接调用字段名
|
||
|
||
2、外部调用:实例对象.字段名,例如
|
||
|
||
```text
|
||
myObj:=CreateObject("myClass");
|
||
|
||
myObj.Field1:="This is a Field";
|
||
```
|
||
|
||
注:
|
||
|
||
可以为字段指定作用域
|
||
|
||
#### static 静态字段
|
||
|
||
在字段的前边加入 static 前缀,就表明为静态字段也称静态成员变量,静态字段就是全部类实例共用的字段,亦可以不用实例化来进行调用。
|
||
|
||
与对象实例无关,也就是所有对象实例均共用该变量,类似于一个作用域为该类的全局变量。
|
||
|
||
范例:
|
||
|
||
```text
|
||
Type Thuman=class
|
||
|
||
public
|
||
|
||
|
||
static
|
||
mCount;//人的对象数量,与对象无关
|
||
|
||
function create() begin
|
||
|
||
mCount:=(mCount?:0)+1;//构造的时候+1
|
||
|
||
end;
|
||
|
||
function destroy() begin //析构的时候-1
|
||
|
||
mCount--;
|
||
|
||
end;
|
||
|
||
End;
|
||
```
|
||
|
||
调用方式可如:
|
||
|
||
class(Thuman).mCount;//不用实例化来进行调用
|
||
|
||
或
|
||
|
||
obj:=new Thuman();//用实例化来进行调用
|
||
|
||
obj.mCount;
|
||
|
||
#### const 常量成员
|
||
|
||
常量成员定义的值可以是一个常数也可以是常量参与的计算。具体定义与支持的运算符可参考常量及常量成员的定义与初始化
|
||
|
||
【常量成员定义】
|
||
|
||
```text
|
||
Type C=class
|
||
|
||
|
||
Const
|
||
a="Hello"; //可以在声明中进行定义初始化
|
||
|
||
|
||
Const
|
||
b=a+"Tinysoft";
|
||
|
||
C=a+b+"from TSL";
|
||
|
||
End;
|
||
```
|
||
|
||
【使用范围】
|
||
|
||
1、成员函数使用
|
||
|
||
2、成员函数缺省参数使用
|
||
|
||
3、子类使用
|
||
|
||
4、通过实例访问
|
||
|
||
5、通过类访问静态常量成员
|
||
|
||
示例:
|
||
|
||
```text
|
||
Type C=class
|
||
|
||
public
|
||
|
||
const mA=1; //定义一个常量成员
|
||
|
||
static const mB=mA+10; //允许静态成员常量
|
||
|
||
|
||
function TestConst();
|
||
|
||
begin
|
||
|
||
echo mA+mB,"\r\n"; //允许在成员函数中使用
|
||
|
||
end;
|
||
|
||
function TestConstInParam(b=mB); //允许在缺省参数值中使用
|
||
|
||
begin
|
||
|
||
echo b,"\r\n";
|
||
|
||
end;
|
||
|
||
End;
|
||
```
|
||
|
||
调用:
|
||
|
||
```text
|
||
Cinstance:=New C();
|
||
|
||
Cinstance.TestConst();
|
||
|
||
Cinstance.TestConstInParam();
|
||
|
||
echo Cinstance.mA,"\r\n";
|
||
|
||
echo class(C).mB,"\r\n";
|
||
```
|
||
|
||
打印结果:
|
||
|
||
12
|
||
|
||
11
|
||
|
||
1
|
||
|
||
11
|
||
|
||
### 方法
|
||
|
||
#### 内容
|
||
|
||
- 方法简介
|
||
- 声明和实现
|
||
- 覆盖(override)
|
||
- 多态
|
||
- 隐藏
|
||
- 重载(overload)
|
||
- 构造函数
|
||
- 析构函数
|
||
- 指定类
|
||
- Self
|
||
- 类方法
|
||
|
||
#### 方法简介
|
||
|
||
方法定义一个类的行为,是一个和类相关联的函数,调用一个方法需指定它作用的对象(若是类方法,则指定类),比如,
|
||
|
||
SomeObject.DoSomething
|
||
|
||
调用 SomeObject 的 DoSomething 方法。
|
||
|
||
#### 声明和实现
|
||
|
||
有 2 种方法为类添加方法。
|
||
|
||
在类声明中,可以直接定义方法的声明和实现,
|
||
|
||
或者只在类中定义方法的声明,在类声明后的某个地方(必须属于同一模块)定义它的实现,实现的时候在方法名称前加“类名.”。这种方法称为为外联,上一种方法称为内联.
|
||
|
||
示例:
|
||
|
||
```text
|
||
Type myClass =class
|
||
|
||
|
||
Function F1()
|
||
;
|
||
|
||
Begin
|
||
|
||
writeln("内联");
|
||
|
||
End;
|
||
|
||
|
||
Function F2()
|
||
;
|
||
|
||
End;
|
||
|
||
function
|
||
myClass.F2
|
||
();
|
||
|
||
Begin
|
||
|
||
Writeln("外联");
|
||
|
||
End;
|
||
```
|
||
|
||
外联声明时,方法名总是使用类名进行限定,形式为:类名.方法名。在方法的头部必须重新列出类声明时的参数,名称可以与声明时的不同,但是参数的顺序必须完全相同。
|
||
|
||
##### 内容
|
||
|
||
- 内联与外联
|
||
- 静态方法声明和调用
|
||
- 对象的方法调用
|
||
|
||
##### 内联与外联
|
||
|
||
如果函数的实现在类体内,叫内联方法。
|
||
|
||
如果函数的实现在类体外,叫外联方法。
|
||
|
||
示例:
|
||
|
||
```text
|
||
Type TSamClass=Class
|
||
|
||
Public
|
||
|
||
Function MethodInside(); //内联方法--声名+实现
|
||
|
||
begin
|
||
|
||
return "Inside";
|
||
|
||
end;
|
||
|
||
function MethodOutSide();//仅声名
|
||
|
||
End;
|
||
|
||
Function TSamClass.MethodOutSide(); //外联方法--具体实现
|
||
|
||
Begin
|
||
|
||
return "outside";
|
||
|
||
End;
|
||
```
|
||
|
||
外联声明时,方法名总是使用类名进行限定,形式为:类名.方法名。在方法的头部必须重新列出类声明时的参数,参数名称可以与声明时的不同,但是参数的顺序必须完全相同,
|
||
|
||
##### 静态方法声明和调用
|
||
|
||
静态方法与静态字段(静态成员变量)
|
||
|
||
所有静态方法就是与对象实例无关的方法,其定义为在函数的前边加上 class 前缀,也称类方法。类方法定义了类的行为,与类的实例无关。
|
||
|
||
而静态成员则是在变量的前边加上 static 前缀,表明该成员变量与对象实例无关,也就是所有对象实例均共用该变量,类似于一个作用域为该类的全局变量。
|
||
|
||
在静态方法中禁止使用类的非静态的成员变量。
|
||
|
||
类方法(静态方法)的声明:
|
||
|
||
声明类方法时 function 前面加 class.形式为:Class Function FunctionName([p1,p2,…))
|
||
|
||
如果是外联实现,也在实现前面加 class,形式为:Class Function ClassName.FunctionName([p1,p2,…))
|
||
|
||
类方法(静态方法)的调用:
|
||
|
||
在实例中的调用方法为: class(类名).方法名.形式为:Class(myClass).FunctionName([p1,p2,…])
|
||
|
||
静态方法与静态成员范例
|
||
|
||
```text
|
||
Type Thuman=class
|
||
|
||
public
|
||
|
||
|
||
static mCount;
|
||
//人的对象数量,与对象无关
|
||
|
||
|
||
class function getCount()
|
||
; //得到人对象的数量,与对象无关
|
||
|
||
begin
|
||
|
||
return mCount;
|
||
|
||
end;
|
||
|
||
function create();
|
||
|
||
begin
|
||
|
||
mCount:=(mCount?:0)+1;//构造的时候+1
|
||
|
||
end;
|
||
|
||
function destroy();
|
||
|
||
begin //析构的时候-1
|
||
|
||
mCount--;
|
||
|
||
end;
|
||
|
||
End;
|
||
```
|
||
|
||
静态方法与静态成员的访问
|
||
|
||
```text
|
||
class(Thuman).mCount:=100;//将Thuman类的静态字段mCount的值指定为100
|
||
|
||
echo class(Thuman).mCount;//输出静态字段mCount的值
|
||
|
||
hA:=new Thuman();//创建一个实例
|
||
|
||
echo class(Thuman).getCount();//调用静态方法
|
||
```
|
||
|
||
打印结果:
|
||
|
||
100
|
||
|
||
101
|
||
|
||
##### 对象的方法调用
|
||
|
||
1、如果被类内部其他的方法调用或子类中的方法调用,直接调用方法名就可以了。
|
||
|
||
2、如果在类的外部被调用,需要加上所在类型的对象名:对象名.方法名;
|
||
|
||
如调用 F1()的方法是
|
||
|
||
```text
|
||
myObj:=createObject("myClass");
|
||
|
||
myObj.F1();
|
||
```
|
||
|
||
3、在类内部调用方法,若在父类中存在同名方法,默认是优先调用当前类,
|
||
|
||
若希望调用父类方法,则可使用 Inherited 关键字进行指定。
|
||
|
||
若希望调用指定父类方法,则可使用 class(父类名).方法名的模式调用。
|
||
|
||
###### 内容
|
||
|
||
- Inherited
|
||
|
||
###### Inherited
|
||
|
||
Inherited 是一种调用父类的巧妙的实现,这个实现和 Object pascal 遵循相同的规则。由于 tsl 支持多重继承,因而 Inherited 会优先调用第一个继承的父类,如果没找到则会遍历之后继承的类。
|
||
|
||
Inherited 和 java 的 super 有一定的类似之处,但又不相同, java 的 super 可以表达成父类,也可以调用父类的方法,而 Inherited 都是调用父类的方法,而且单独 Inheritd 的写法,在父类不存在方法的时候不会出错,这样的特性非常便于桌面应用开发里的子类窗口的消息事件响应。
|
||
|
||
用法有两种:
|
||
|
||
方式一:在方法中,增加 inherited;则表示执行父类中存在的与当前方法名同名同参数的方法,若父类中查找不到,不报错,即什么也不做,继续向下执行。
|
||
|
||
方式二:使用如 inherited func(a,b,c);的模式调用方法,表示调用父类中的该方法,若存在多父类,则按顺序查找,若父类中查找不到,则报错。
|
||
|
||
例如:
|
||
|
||
```text
|
||
Type Base1 =Class
|
||
|
||
Function Method1(s,a,b); virtual;
|
||
|
||
Begin
|
||
|
||
s:=s$"-Base1-Method1-"$(a+b);
|
||
|
||
End;
|
||
|
||
Function Method2(a,b);
|
||
|
||
begin
|
||
|
||
return "Base1-Method2-"$(a*b);
|
||
|
||
end;
|
||
|
||
End;
|
||
|
||
|
||
Type SubClass =Class(Base1)
|
||
|
||
Function Method1(s,a,b); override;
|
||
|
||
Begin
|
||
|
||
|
||
Inherited; //优先调用父类中Method1(s,a,b)方法,找不到不报错
|
||
|
||
|
||
s:=s+"->SubClass";
|
||
|
||
s2:=
|
||
Inherited Method2(a,b);//指定调用父类中的Method2(a,b)方法,找不到会报错
|
||
|
||
|
||
s:=s+"->"+s2;
|
||
|
||
return s;
|
||
|
||
End;
|
||
|
||
Function Method2(a,b);
|
||
|
||
begin
|
||
|
||
return "SubClass-Method2-"$(a/b);
|
||
|
||
end;
|
||
|
||
End;
|
||
```
|
||
|
||
调用:
|
||
|
||
```text
|
||
obj:=new SubClass();
|
||
|
||
return obj.Method1("S",2,50);
|
||
```
|
||
|
||
返回结果为:S-Base1-Method1-52->SubClass->Base1-Method2-100
|
||
|
||
即:Inherited;语句执行父类 Base1 中同名同参数方法 Method1(s,a,b)
|
||
|
||
Inherited Method2(a,b);执行父类 Base1 中指定方法 Method2,而非当前类 SubClass 的 Method2 方法
|
||
|
||
#### 覆盖(override)
|
||
|
||
由于继承,子类具有了父类全部非私有的成员(字段、方法、属性),但是子类也可以对基类的方法进行重写。这种方法就叫做覆盖(override),具体的做法如下,
|
||
|
||
首先基类的方法用 virtual 关键字虚函数,告诉编译器允许子类覆盖:
|
||
|
||
```text
|
||
Type BaseClass =class
|
||
|
||
Funciton F();
|
||
virtual;
|
||
//虚方法,允许覆盖
|
||
|
||
Begin
|
||
|
||
//…
|
||
|
||
End;
|
||
|
||
End
|
||
```
|
||
|
||
接下来,在子类中将将要覆盖的方法用 override 关键字标记为覆盖了基类的方法。它的参数的顺序(若有的话)必须和基类相同。
|
||
|
||
```text
|
||
Type SubClass =class(BaseClass)
|
||
|
||
Funciton F();
|
||
override;
|
||
//覆盖虚方法,即重写
|
||
|
||
Begin
|
||
|
||
//…
|
||
|
||
End;
|
||
|
||
End
|
||
```
|
||
|
||
这样子类的方法 F 就覆盖了基类的方法 F,当 SubClass 的实例调用 F 方法时,会执行子类中重新定义的方法。
|
||
|
||
若需要调用父类被覆盖的方法,可以用 Class(父类).方法来调用
|
||
|
||
#### 多态
|
||
|
||
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,就是同一种事物表现出的多种形态。
|
||
|
||
编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。
|
||
|
||
通过继承可以实现多态。父类中调用被覆盖的方法,如果当前对象是子类的实例,那么实际调用的是子类的方法,而非父类的方法。
|
||
|
||
通过继承,一个类可以用作多种类型:可以用作它自己的类型、任何祖先类型,当把子类型当作祖先类型时,调用被覆盖的方法,实际调用的是子类本身的方法,而非基类型的方法。
|
||
|
||
示例:
|
||
|
||
```text
|
||
program test;
|
||
|
||
|
||
type Figure = class
|
||
|
||
Function Draw();
|
||
virtual;
|
||
//虚方法,可以被覆盖
|
||
|
||
Begin
|
||
|
||
Writeln("draw Figure");
|
||
|
||
End;
|
||
|
||
|
||
Function DrawAction();
|
||
|
||
Begin
|
||
|
||
Draw();
|
||
|
||
End;
|
||
|
||
End;
|
||
|
||
Type Ellipse =
|
||
class(Figure)
|
||
|
||
|
||
Function Draw();
|
||
override;
|
||
//重写父类方法
|
||
|
||
Begin
|
||
|
||
Writeln("draw Ellipse");
|
||
|
||
End;
|
||
|
||
end;
|
||
|
||
|
||
Begin
|
||
|
||
F:=CreateObject("Figure");
|
||
|
||
F.DrawAction();//输出 draw Figure
|
||
|
||
E:=CreateObject("Ellipse");
|
||
|
||
E.DrawAction();//输出 draw Ellipse
|
||
|
||
End.
|
||
```
|
||
|
||
上面的示例中:
|
||
|
||
类 Ellipse 的方法 Draw,重写了父类 Draw 这个虚方法,父类的 DrawAction 调用了 Draw 方法,当对象调用 DrawAction 方法时,实际上是间接调用了 Draw 方法。
|
||
|
||
当父类的对象间接 Draw 方法时:执行的是父类的方法。
|
||
|
||
```text
|
||
F:=CreateObject("Figure");
|
||
|
||
F.DrawAction();//输出 draw Figure
|
||
```
|
||
|
||
当子类的对象间接用 Draw 方法时:执行的是子类的方法:
|
||
|
||
```text
|
||
E:=CreateObject("Ellipse");
|
||
|
||
E.DrawAction();//输出 draw Ellipse
|
||
```
|
||
|
||
如果要强制子类调用父类的方法。需要用下面的方式:
|
||
|
||
```text
|
||
Class(BaseClass,SubObject).FunctionName.
|
||
```
|
||
|
||
上面的事例中,
|
||
|
||
```text
|
||
E:=CreateObject("Ellipse");
|
||
|
||
Class(Figure,E).Draw()
|
||
;
|
||
```
|
||
|
||
执行的却是父类的 Draw 方法.输出:输出 draw Figure
|
||
|
||
#### 隐藏
|
||
|
||
如果在子类中重写父类的方法确没有使用 override 标志符,子类的方法隐藏了基类的方法,而非覆盖。
|
||
|
||
父类中调用覆盖的方法时,实际执行的是父类的方法。如果当前对象是子类的实例时,执行的还是父类的方法。因为方法在子类型中给隐藏了,而没有被覆盖。
|
||
|
||
示例:
|
||
|
||
```text
|
||
program test;
|
||
|
||
|
||
type Figure = class
|
||
|
||
Function Draw();
|
||
|
||
Begin
|
||
|
||
Writeln("draw Figure");
|
||
|
||
End;
|
||
|
||
|
||
Function DrawAction();
|
||
|
||
Begin
|
||
|
||
Draw();
|
||
|
||
End;
|
||
|
||
End;
|
||
|
||
Type Ellipse = class(Figure)
|
||
|
||
Function Draw();//
|
||
注意没有override
|
||
|
||
|
||
Begin
|
||
|
||
Writeln("draw Ellipse");
|
||
|
||
End;
|
||
|
||
end;
|
||
|
||
|
||
Begin
|
||
|
||
F:=CreateObject("Figure");
|
||
|
||
F.DrawAction();//输出draw Figure
|
||
|
||
E:=CreateObject("Ellipse");
|
||
|
||
E.DrawAction();//输出draw Figure
|
||
|
||
End.
|
||
```
|
||
|
||
与上节的例子不同,子类中定义 Draw 方法没有使用 override 关键字,说明子类的 Draw 方法隐藏了父类的 Draw 方法.
|
||
|
||
在父类在中调用 Draw 方法时,始终执行的是父类的 Draw 方法.
|
||
|
||
#### 重载(overload)
|
||
|
||
TSL 可以为一个类声明相同的名称不同参数的多个方法,这叫做重载。
|
||
|
||
每个重载方法声明后面加关键字 overload,并且它们必须有不同的参数列表。
|
||
|
||
形式为:
|
||
|
||
```text
|
||
Function F();overload;
|
||
```
|
||
|
||
示例:
|
||
|
||
```text
|
||
Type BaseClass =class
|
||
|
||
public
|
||
|
||
function Display(str,str2) ;overload;
|
||
|
||
Begin
|
||
|
||
writeln(str,' ',str2);
|
||
|
||
End;
|
||
|
||
|
||
function Display(str); overload;
|
||
|
||
begin
|
||
|
||
writeln(str);
|
||
|
||
end;
|
||
|
||
End;
|
||
```
|
||
|
||
上面的代码为 BaseClass 声明了 2 个 Display 方法。可以按照 2 种方式调用,可以在子类中重载也可以重载父类的方法。
|
||
|
||
示例:
|
||
|
||
```text
|
||
program test;
|
||
|
||
Type BaseClass =class
|
||
|
||
public
|
||
|
||
function Display(str);
|
||
|
||
begin
|
||
|
||
writeln(str);
|
||
|
||
end;
|
||
|
||
End;
|
||
|
||
|
||
Type SubClass =class(BaseClass)
|
||
|
||
function Display(str,str2);overload;
|
||
|
||
Begin
|
||
|
||
writeln(str,' ',str2);
|
||
|
||
End;
|
||
|
||
End;
|
||
|
||
Begin
|
||
|
||
SC:=createObject("SubClass");
|
||
|
||
SC.Display("overload");
|
||
|
||
SC.Display("overload","test");
|
||
|
||
End.
|
||
```
|
||
|
||
上面的例子中 SubClass 继承自 BaseClass,而 SubClass 的 Display 方法重载了父类 Display 方法。
|
||
|
||
原理:SubClass 通过继承实际上拥有了方法 Display(str)方法,然后通过 overload 重载了本身的方法,于是 SubClass 具有了 2 个不同参数的 Display 方法。
|
||
|
||
#### 构造函数
|
||
|
||
构造函数是一个特殊的方法,用来创建和初始化一个实例对象。
|
||
|
||
声明一个构造函数就像声明一个函数一样,可以无参数也可以有参数,不同的是方法名必须是 create,在创建实例时会自动查找适合的构造函数。
|
||
|
||
Function Create()
|
||
|
||
TSL 总是为一个类生成默认的公有(public)的 create 方法, 如果显式没有为类声明 public create,对象初始化时就使用默认的 create 方法,如果用户声明了 public create 方法,对象初始化时就执行用户定义的方法。Create 不可以声明为私有(private)的和受保护(protected)的方法,否则对象初始化时不执行自己声明的方法.
|
||
|
||
Create 方法可以被重载(overload)几个不同的定义。
|
||
|
||
由于使用 CreateObject 方法创建对象,Craete 方法的返回值将被忽略。
|
||
|
||
示例:
|
||
|
||
示例是一个简单的日历类,说明了构造函数的重载,初始化时如果调用 Create 方法,设置为当前日期,否则可以指定具体的年月日
|
||
|
||
```text
|
||
program test;
|
||
|
||
Type Calandar =Class
|
||
|
||
year;
|
||
|
||
month;
|
||
|
||
day;
|
||
|
||
|
||
function Create() ;overload;
|
||
|
||
Begin
|
||
|
||
Create(YearOf(Date()),MonthOf(Date()),DayOf(Date()));
|
||
|
||
End;
|
||
|
||
|
||
function Create(y,m,d);overload;
|
||
|
||
Begin
|
||
|
||
year:=y;
|
||
|
||
month:=m;
|
||
|
||
day:=d;
|
||
|
||
End;
|
||
|
||
End;
|
||
|
||
|
||
Begin
|
||
|
||
C:=CreateObject("Calandar");
|
||
|
||
//C:=CreateObject("Calandar",2008,8,8);也可以指定具体的年月日
|
||
|
||
writeln(C.year,C.Month,C.Day);
|
||
|
||
End.
|
||
```
|
||
|
||
构造函数的覆盖:
|
||
|
||
构造函数可以在子类中被覆盖,如果显示声明了构造函数,为了是成员初始化,一般在新的构造函数中都要求实现基类的构造函数
|
||
|
||
调用 Class(BaseClass).Create();
|
||
|
||
#### 析构函数
|
||
|
||
对象销毁时候执行的方法。声明一个析构函数就像声明一个一般的函数,必须以关键字 Destroy 命名的函数,且无参数,当对象释放时会自动调用。
|
||
|
||
Function destroy();
|
||
|
||
#### 指定类
|
||
|
||
如果要指定执行某个类中的方法,需要用 Class 指定类名。
|
||
|
||
如果在类的内部,或者执行类方法,格式为:
|
||
|
||
Class(ClassName).FunctionName;
|
||
|
||
表示执行类 ClassName 中的方法 FunctionName;
|
||
|
||
如果是对实例对象,希望实例对象执行某个祖先类的方法,格式为:
|
||
|
||
Class(ClassName,ObjectName).FunctionName;
|
||
|
||
表示实例对象 ObjectName 执行祖先类 ClassName 的 FunctionName 方法。
|
||
|
||
#### Self
|
||
|
||
在面向对象中,self 有多种用途:
|
||
|
||
第一种:在指定方法时,可以通过 self 指向当前的实例对象。
|
||
|
||
第二种:self(N)方式,可以在类中创建当前类对象或创建实例所属对象。
|
||
|
||
第一种用途:
|
||
|
||
在实现方法时,标志符 Self 引用方法所属的对象,如果是类方法,Self 引用方法所属的类。
|
||
|
||
格式为:
|
||
|
||
Self.functionName();
|
||
|
||
编译器会自动匹配所调用的方法,Self 方法一般可以省略。
|
||
|
||
有一点注意的是:
|
||
|
||
Self 总是指向当前的实例对象。而不是 Self 所在的类的实例对象。与继承混合使用是需要注意。
|
||
|
||
示例:
|
||
|
||
```text
|
||
Program test;
|
||
|
||
type A= class
|
||
|
||
Function F(); virtual;
|
||
|
||
Begin
|
||
|
||
Self.F2();
|
||
|
||
End;
|
||
|
||
Function F2();virtual;
|
||
|
||
Begin
|
||
|
||
Writeln("A.F2");
|
||
|
||
End;
|
||
|
||
End;
|
||
|
||
|
||
Type B = class(A)
|
||
|
||
Function F2();override;
|
||
|
||
Begin
|
||
|
||
Writeln("B.F2");
|
||
|
||
End;
|
||
|
||
end;
|
||
|
||
|
||
Begin
|
||
|
||
AA:=CreateObject("A");
|
||
|
||
AA.F();//输出 A.F2;
|
||
|
||
BB:=CreateObject("B");
|
||
|
||
BB.F();//输出 B.F2()
|
||
|
||
End.
|
||
```
|
||
|
||
说明:
|
||
|
||
AA:=CreateObject("A");
|
||
|
||
AA.F();//输出 A.F2;
|
||
|
||
创建了类型 A 的实例对象,F()中的 Self.F2(),表示调用的是类型 A 的 F2();
|
||
|
||
BB:=CreateObject("B");
|
||
|
||
BB.F();//输出 B.F2()
|
||
|
||
以上代码创建了类型 B 的实例对象,F()中的 Self.F2()表示调用类型 B 的 F2()
|
||
|
||
Self 的这种特性在某些情况下会出现理解上的歧义,如果想固定 Self 的意义,让他只表示当前的类。需要用 Class(ClassName).FunctionName 做替换。
|
||
|
||
以上代码中的 Self.F2()需要换成 Class(A).F2();
|
||
|
||
那么以上代码输出
|
||
|
||
A.F2
|
||
|
||
A.F2
|
||
|
||
第二种用途:
|
||
|
||
在实现方法时,可以通过 self(1)创建一个当前实例所属对象的实例对象。
|
||
|
||
self(0)等同于 self()即创建一个当前方法所在类的实例对象。
|
||
|
||
如:
|
||
|
||
```text
|
||
Function Test_Ooself();
|
||
|
||
Begin
|
||
|
||
obj:=CreateObject('TestSelf');
|
||
|
||
obj.Test1();
|
||
|
||
End;
|
||
|
||
|
||
Type TestSelf=class(TDTestFClass)
|
||
|
||
Function Test1();
|
||
|
||
begin
|
||
|
||
returnV1();
|
||
|
||
returnV0();
|
||
|
||
end
|
||
|
||
end;
|
||
|
||
Type TDTestFClass=class()
|
||
|
||
Public
|
||
|
||
|
||
Function returnV1();
|
||
|
||
Begin
|
||
|
||
ss:=self(1); //创建当前实例所属类的实例对象
|
||
|
||
echo "TDTestFClass-returnV1 ", ss.classinfo()['classname'];
|
||
|
||
End;
|
||
|
||
Function returnV0();
|
||
|
||
Begin
|
||
|
||
ss:=self(0); //创建当前类的对象
|
||
|
||
echo "TDTestFClass-returnV0 ", ss.classinfo()['classname'];
|
||
|
||
End;
|
||
|
||
End;
|
||
```
|
||
|
||
打印结果如下:
|
||
|
||
TDTestFClass-returnV1 testself
|
||
|
||
TDTestFClass-returnV0 tdtestfclass
|
||
|
||
注:示例中 ss.classinfo()['classname'];是获取 ss 所属对象的类名
|
||
|
||
#### 类方法
|
||
|
||
类方法是作用在类而不是对象上面的方法(不同于构造函数)。类方法的定义必须以关键字 class 开始
|
||
|
||
类方法用于创建无需创建类的实例就能够访问的方法。类方法可用于分离独立于任何对象标识的行为:无论对象发生什么更改,这些函数都不会随之变化。
|
||
|
||
形式为:
|
||
|
||
```text
|
||
Type ClassName =Class
|
||
|
||
Class Function FuncName();
|
||
|
||
Begin
|
||
|
||
//方法实现
|
||
|
||
End;
|
||
|
||
End
|
||
```
|
||
|
||
在类方法的定义部分,Self 表示调用方法的类(它或许是定义方法的类的一个派生类)。由于类方法与实例对象无关,所以,你不能使用 Self 访问字段、属性和实例的方法,但能调用构造函数和其它类方法。
|
||
|
||
类方法可以通过类引用来调用
|
||
|
||
Class(类名).类方法
|
||
|
||
示例:
|
||
|
||
上例中,可以
|
||
|
||
Class(ClassName).FuncName();
|
||
|
||
注:
|
||
|
||
一个类方法也可以被当作实例方法使用,使用方法和实例方法完全一样。方法的内部也可以调用实例的字段、属性和方法,如果方法调用了这样的数据或方法,就不能当作类方法使用了,否则的话会出错。
|
||
|
||
在 Tsl 中,字段和属性不支持这种静态的属性方法.
|
||
|
||
静态的字段可以通过全局变量实现。
|
||
|
||
更多可参考:静态方法声明和调用
|
||
|
||
### 属性 Property
|
||
|
||
属性是这样的成员:它们提供灵活的机制来读取、编写或计算私有字段的值。可以像使用公共数据成员一样使用属性,但实际上它们是称作“访问器”的特殊方法。这使得可以轻松访问数据,此外还有助于提高方法的安全性和灵活性。
|
||
|
||
语法:Property PropertyName[(ParamList)] [read fieldOrMethod][write fieldOrMethod][Index IndexValue]
|
||
|
||
其中,
|
||
|
||
1、关键字 Property 关键字表示开始声明了一个属性;
|
||
|
||
2、PropertyName 是自定义合法的属性名,可以带参数,写法如 PropertyName(a,b);
|
||
|
||
3、每个属性至少有一个读限定符或一个写限定符,或两者都有,它们称为访问限定符,具有以下的格式:
|
||
|
||
read fieldOrMethod
|
||
|
||
write fieldOrMethod
|
||
|
||
fieldOrMethod 可以是成员变量,也可以是成员方法。
|
||
|
||
4、在 TSL.INI 支持,一旦设定该选项为 1,则任何域的 property 都可被访问,无论是 public 还是 protected,private。默认情况下这种违反规则是不被允许的。
|
||
|
||
[Compatible]
|
||
|
||
PrivatePropertyAccess=1
|
||
|
||
5、属性可以具有 Private,Protected 或 public 可见性,默认为 public.
|
||
|
||
6、如果单有读限定符,表示属性只读;如果单有写限定符,表示属性只写。
|
||
|
||
7、如果它是在祖先类中声明的,则它对派生类必须是可见的,则 fieldOrMethod 不能是私有的字段或方法;
|
||
|
||
8、在读限定符中,若 fieldOrMethod 是一个方法,它须是一个小于等于定义中参数数量的函数
|
||
|
||
9、在写限定符中,若 fieldOrMethod 是一个方法,属性的设置值会以参数方式送入成员方法,即它须是一个与定义中参数数量多一个的方法。
|
||
|
||
10、属性可以在派生类中给重新定义.
|
||
|
||
示例:
|
||
|
||
```text
|
||
program test;
|
||
|
||
|
||
Type myDate = Class
|
||
|
||
private
|
||
|
||
_year;
|
||
|
||
_month;
|
||
|
||
_day;
|
||
|
||
Function SetMonth(value);
|
||
|
||
Begin
|
||
|
||
if value>0 and value<13 then
|
||
|
||
_month:=value;
|
||
|
||
End;
|
||
|
||
|
||
public
|
||
|
||
//不带参数的定义
|
||
|
||
property Month read _month write setMonth;//读时访问成员变量_month,写时调用成员方法setMonth
|
||
|
||
//带参数的定义
|
||
|
||
property DateV(y,m) read getDateV write setDateV;
|
||
|
||
|
||
Function getDateV();
|
||
|
||
begin
|
||
|
||
return _year*10000+_month*100+_day;
|
||
|
||
end;
|
||
|
||
Function setDateV(y,m,d); //比定义中多一个参数
|
||
|
||
begin
|
||
|
||
_year:=y;
|
||
|
||
SetMonth(m);
|
||
|
||
_day:=d;
|
||
|
||
end;
|
||
|
||
End;
|
||
|
||
|
||
Begin
|
||
|
||
D:=CreateObject("myDate");
|
||
|
||
D.Month:=7; //写
|
||
|
||
echo D.Month;//读
|
||
|
||
D.DateV(2025,8):=10;//写
|
||
|
||
echo D.DateV();//读
|
||
|
||
End.
|
||
```
|
||
|
||
打印结果:
|
||
|
||
7
|
||
|
||
20250810
|
||
|
||
### 索引器(index)
|
||
|
||
简单说来,所谓索引器就是一类特殊的属性,通过它们你就可以像引用数组一样引用自己的对象。索引器通常用于对象容器中为其内的对象提供友好的存取界面.
|
||
|
||
显然,这一功能在创建集合类的场合特别有用,而在其他某些情况下,比如处理大型文件或者抽象某些有限资源等,能让类具有类似数组的行为当然也是非常有用的。
|
||
|
||
索引器的定义方式为:
|
||
|
||
Property PropertyName Index IndexValue read ReadMethod write WriteMethod
|
||
|
||
与属性不同的是,其中读写限定符必须是方法,不能是字段。而且
|
||
|
||
读限定符中的方法声明必须带有一个参数,这个参数指向索引器的索引。
|
||
|
||
写限定符的方法声明必须带有 2 个参数,第一个参数是索引器的索引,第二个是要设置的值。
|
||
|
||
与数组的区别,调用索引器的时候用圆括号,不能用方括号。
|
||
|
||
与 Object pascal 不同的地方:TSL 的索引器的索引值除了支持整数以外,还可以支持字符串。
|
||
|
||
实例:
|
||
|
||
```text
|
||
program test;
|
||
|
||
type A=class()
|
||
|
||
arr;
|
||
|
||
function create()
|
||
|
||
Begin
|
||
|
||
arr:=array();
|
||
|
||
End;
|
||
|
||
|
||
function rIndex(i);
|
||
|
||
Begin
|
||
|
||
return arr[i];
|
||
|
||
End;
|
||
|
||
function wIndex(i,value);
|
||
|
||
Begin
|
||
|
||
arr[i]:=value;
|
||
|
||
End;
|
||
|
||
property idx read rindex write windex;
|
||
|
||
End;
|
||
|
||
|
||
begin
|
||
|
||
AA:=createobject("A");
|
||
|
||
AA.idx(0):="abc";
|
||
|
||
writeln(AA.idx(0));
|
||
|
||
End.
|
||
```
|
||
|
||
上面的示例演示了索引器的使用方法。对类 A 的数据 arr 的操作,不必通过对象 AA.arr 来设置或读取,只要通过索引器即可。索引器为 A 中的数据提供友好的存取界面。
|
||
|
||
我们可以把索引器的一个索引固定为属性,就需要下面的定义方法:
|
||
|
||
Property PropertyName Index IndexValue read ReadMethod write WriteMethod
|
||
|
||
用 index n 指定索引的位置
|
||
|
||
上例中可声明
|
||
|
||
```text
|
||
property idx0 index 0 read rindex write windex;
|
||
```
|
||
|
||
表示 idx0 表示专门对索引器中的位置 0 进行对写,也就是对 arr[0]进行操作。
|
||
|
||
当然,假使有需要,索引也可以使字符串,那样,例如:
|
||
|
||
```text
|
||
property idx0 index "High school" read rindex write windex;
|
||
```
|
||
|
||
### TSL 对象的创建
|
||
|
||
#### 内容
|
||
|
||
- New
|
||
- CreateObject
|
||
|
||
#### New
|
||
|
||
参考 TSL 内置对象使用大全 CreateObject
|
||
|
||
#### CreateObject
|
||
|
||
参考 TSL 内置对象使用大全 New
|
||
|
||
### 类信息
|
||
|
||
判定一个对象是否是某个类的实例,可以用 is 判断符。
|
||
|
||
Class(类名)或者 FindClass(类名字符串)可以获得一个类的类型。
|
||
|
||
CreateObject 支持通过指定类的类型创建实例。
|
||
|
||
如:
|
||
|
||
```text
|
||
obj1:=New T1();
|
||
|
||
Echo obj1
|
||
is class(T1)
|
||
; //判断对象是否是指定类的实例
|
||
|
||
C1:=
|
||
findclass("t1")
|
||
;//获取指定类的类型
|
||
|
||
Echo obj1
|
||
is C1
|
||
;
|
||
|
||
obj2:=
|
||
CreateObject(C1)
|
||
;//通过指定类的类型创建实例
|
||
```
|
||
|
||
#### 内容
|
||
|
||
- FindClass
|
||
- ClassInfo
|
||
- objectstate
|
||
- tslassigning
|
||
- 对象的引用计数
|
||
|
||
#### FindClass
|
||
|
||
范例
|
||
|
||
范例 01:通过查找类运行类方法
|
||
|
||
示例:
|
||
|
||
classA :=FindClass("A");
|
||
|
||
classA 指向了类 A,可以通过 ClassA 调用 A 的共享方法。但是不能调用实例方法,因为 ClassA 没有指向实例对象。
|
||
|
||
```text
|
||
//有类:
|
||
|
||
Type ClassA=class()
|
||
|
||
class function fucA();
|
||
|
||
begin
|
||
|
||
return "ClassA";
|
||
|
||
end;
|
||
|
||
end;
|
||
|
||
//调用:
|
||
|
||
return findclass("ClassA").fucA();
|
||
```
|
||
|
||
返回:ClassA
|
||
|
||
范例 02:将实例对象强制转成指定父类的实例
|
||
|
||
```text
|
||
//有父类:
|
||
|
||
Type ClassA=class()
|
||
|
||
function fuc();virtual;
|
||
|
||
begin
|
||
|
||
return "ClassA";
|
||
|
||
end;
|
||
|
||
end;
|
||
|
||
//有子类:
|
||
|
||
Type ClassB=class(ClassA)
|
||
|
||
|
||
function fuc();virtual;
|
||
|
||
begin
|
||
|
||
return "ClassB";
|
||
|
||
end;
|
||
|
||
end;
|
||
|
||
|
||
//调用:
|
||
|
||
objb:=new ClassB();
|
||
|
||
obj:= findclass("ClassA",objb);//将objb对象强制转换成ClassA的实例对象
|
||
|
||
|
||
return obj.fuc();
|
||
```
|
||
|
||
返回:ClassA
|
||
|
||
#### ClassInfo
|
||
|
||
范例
|
||
|
||
范例 1:返回当前实例对象所属类的定义信息
|
||
|
||
```text
|
||
obj:=createobject("TSBackTesting");
|
||
|
||
return obj.classinfo();
|
||
```
|
||
|
||
范例 2:返回实例对象所属类的对象类型。
|
||
|
||
```text
|
||
obj:=createobject("TSBackTesting");
|
||
|
||
oa2:=obj.classinfo(1); //oa2是一个类的类型
|
||
|
||
obj2:= createobject(oa2); //通过类类型构造一个实例对象
|
||
|
||
return obj2.fbegt;
|
||
```
|
||
|
||
#### objectstate
|
||
|
||
范例
|
||
|
||
```text
|
||
oa := new ca("abc");
|
||
|
||
echo "\r\n构造已经完成",objectstate(oa);
|
||
|
||
type ca = class
|
||
|
||
static sca;
|
||
|
||
function create(n);
|
||
|
||
begin
|
||
|
||
sca := self;
|
||
|
||
echo "\r\n构造中:",
|
||
objectstate(self)
|
||
;
|
||
|
||
end
|
||
|
||
end
|
||
```
|
||
|
||
打印结果:
|
||
|
||
构造中:1
|
||
|
||
构造已经完成 2
|
||
|
||
#### tslassigning
|
||
|
||
如在给属性的赋值方法中打印这个状态值
|
||
|
||
```text
|
||
o := new ca();
|
||
|
||
o.c := 3; //给对象的属性赋值
|
||
|
||
return o.c;
|
||
|
||
type ca = class
|
||
|
||
value;
|
||
|
||
property c read getc write setc;
|
||
|
||
function setc(v); //对象赋值中
|
||
|
||
begin
|
||
|
||
echo "c的写操作>",tslassigning,"<<<<";
|
||
|
||
value:=v;
|
||
|
||
end
|
||
|
||
function getc();
|
||
|
||
begin
|
||
|
||
echo "c的读操作>",tslassigning,"<<<<";
|
||
|
||
return value;
|
||
|
||
end
|
||
|
||
end
|
||
```
|
||
|
||
打印结果:
|
||
|
||
c 的写操作>1<<<<
|
||
|
||
c 的读操作>0<<<<
|
||
|
||
#### 对象的引用计数
|
||
|
||
A:对象的赋值均会将对象的引用计数加 1,当引用计数为 0 的时候才会释放。
|
||
|
||
```text
|
||
O1:=New T1(); //创建对象,引用计数=1
|
||
|
||
O2:=O1; //对象引用计数加1
|
||
|
||
O1:=0; //对象引用计数减1
|
||
|
||
echo "O1 to Zero";
|
||
|
||
O2:=0; //对象引用计算减1,为0,即释放对象
|
||
|
||
echo "O2 to Zero";
|
||
|
||
Type T1=class
|
||
|
||
function destroy();
|
||
|
||
begin
|
||
|
||
echo "destroy";
|
||
|
||
end;
|
||
|
||
End;
|
||
```
|
||
|
||
### IS 关键字
|
||
|
||
关键字 IS 用户判断一个对象是否是某个类的实例。返回值为 Bool 类型。一个子类属于所有它祖先类的类型。
|
||
|
||
示例:
|
||
|
||
```text
|
||
program test;
|
||
|
||
Type A=Class
|
||
|
||
End;
|
||
|
||
|
||
Type B =Class(A)
|
||
|
||
End;
|
||
|
||
|
||
Type C=Class(B)
|
||
|
||
End
|
||
|
||
|
||
Begin
|
||
|
||
CC:=CreateObject("C");
|
||
|
||
Writeln(CC is Class(C)); // 输出 1
|
||
|
||
Writeln(CC is Class(A)); // 输出 1
|
||
|
||
Writeln(CC is Class(B));// 输出 1
|
||
|
||
End.
|
||
```
|
||
|
||
### 函数信息
|
||
|
||
#### 内容
|
||
|
||
- FindOverLoad
|
||
- TSLObjects
|
||
- FindFunction
|
||
- ThisFunction
|
||
- FunctionInfo
|
||
|
||
#### FindOverLoad
|
||
|
||
范例
|
||
|
||
```text
|
||
Type TestClass=class
|
||
|
||
function fun(p1,p2);overload;
|
||
|
||
begin
|
||
|
||
return p1+p2;
|
||
|
||
end
|
||
|
||
function fun(p1);overload;
|
||
|
||
begin
|
||
|
||
return 'a';
|
||
|
||
end
|
||
|
||
class function fun2(p1,p2);
|
||
|
||
begin
|
||
|
||
return p1+p2;
|
||
|
||
end
|
||
|
||
end;
|
||
|
||
//调用有两个参数的重载方法
|
||
|
||
t:=findoverload(2,"fun",CreateObject('TestClass'));
|
||
|
||
return t.do(1,2);//返回3
|
||
```
|
||
|
||
#### TSLObjects
|
||
|
||
范例
|
||
|
||
现有类 TestClass01,其代码如下:
|
||
|
||
```text
|
||
type TestClass01=class()
|
||
|
||
value;
|
||
|
||
function create(_value)
|
||
|
||
begin
|
||
|
||
value:=_value;
|
||
|
||
end
|
||
|
||
class function add(x,y)
|
||
|
||
begin
|
||
|
||
if ifnumber(x) and ifnumber(y) then
|
||
|
||
return x+y;
|
||
|
||
else
|
||
|
||
return 0;
|
||
|
||
end
|
||
|
||
end
|
||
```
|
||
|
||
范例 01:获取当前运行环境下所有对象的引用计数信息
|
||
|
||
```text
|
||
//创建对象,初始引用个数均为1
|
||
|
||
objA:=new TestClass01(100);//objA-直接引用:1,间接引用:1
|
||
|
||
//将对象赋值给其它变量,增加objA的直接引用数
|
||
|
||
objC:=objA;//objA-直接引用:2,间接引用:1
|
||
|
||
objB:=new TestClass01(101);//objB-直接引用:1,间接引用:1
|
||
|
||
//通过对象查找类中的方法,增加objB的间接引用
|
||
|
||
funcA:=findfunction("add",objB);//objB-直接引用:1,间接引用:2
|
||
|
||
funcB:=findfunction("add",objB);//objB-直接引用:1,间接引用:3
|
||
|
||
//通过类名查找类中的方法,没有引用对象,已有对象引用数不变
|
||
|
||
funcC:=findfunction("add",class(TestClass01));
|
||
|
||
return TSLObjects(0);
|
||
```
|
||
|
||
//结果:
|
||
|
||
范例 02:获取当前运行环境下所有对象信息以及原对象,并通过该结果访问其属性、方法
|
||
|
||
```text
|
||
objA:=new TestClass01(100);
|
||
|
||
objB:=new TestClass01(101);
|
||
|
||
objsInfo:=TSLObjects(1);
|
||
|
||
newObjA:=objsInfo["TestClass01"][1,"obj"];
|
||
|
||
newObjB:=objsInfo["TestClass01"][0,"obj"];
|
||
|
||
//获取到的对象,其属性和方法与先前直接创建出的对象一致
|
||
|
||
v1:=newObjA.value;
|
||
|
||
v2:=newObjB.value;
|
||
|
||
t1:=newObjA.add(1,2);
|
||
|
||
t2:=newObjB.add(3,4);
|
||
|
||
return array(v1,v2,t1,t2);
|
||
```
|
||
|
||
//结果:
|
||
|
||
#### FindFunction
|
||
|
||
在对象或类中查找方法:
|
||
|
||
F:=FindFunction(FunctionName, Object or Class)
|
||
|
||
表示在 Object 对象或 Class 中查找名称为 FunctionName 的函数。F 指向找到的函数。
|
||
|
||
第二个参数可以是
|
||
|
||
1)对象,必须预先实例化一个对象,之中方法可以用于查找实例方法或类方法。
|
||
|
||
2)类,格式为:Class(类名)。这种方法只能差找类方法,不能查找实例方法
|
||
|
||
找到的函数可以用 do 方法执行;
|
||
|
||
F.do();表示执行找到的方法,如果函数有参数,把参数传给 do 方法
|
||
|
||
program test;
|
||
|
||
type A=class()
|
||
|
||
function F()
|
||
|
||
Begin
|
||
|
||
writeln("f");
|
||
|
||
End;
|
||
|
||
class function F2();
|
||
|
||
Begin
|
||
|
||
writeln("f2");
|
||
|
||
end;
|
||
|
||
End;
|
||
|
||
begin
|
||
|
||
//从对象中查找实例方法
|
||
|
||
AA:=createobject("A");
|
||
|
||
F:=FindFunction("F",AA);
|
||
|
||
F.do();
|
||
|
||
//从类中查找类方法
|
||
|
||
F2:=FindFunction("F2",class(A));
|
||
|
||
F2.do();
|
||
|
||
End.
|
||
|
||
#### ThisFunction
|
||
|
||
F:=ThisFunction(Object or class.Function);
|
||
|
||
查找方法的又一个方法;参数格式为:
|
||
|
||
1. 对象名.方法名,如果创建了对象,可用这种方法。
|
||
|
||
2. class(类名).方法名,如果是类方法,而且没有穿件对象,可以这样使用。
|
||
|
||
program test;
|
||
|
||
type A=class()
|
||
|
||
function F()
|
||
|
||
Begin
|
||
|
||
writeln("f");
|
||
|
||
End;
|
||
|
||
class function F2();
|
||
|
||
Begin
|
||
|
||
writeln("f2");
|
||
|
||
end;
|
||
|
||
End;
|
||
|
||
begin
|
||
|
||
//从对象中查找实例方法
|
||
|
||
AA:=createobject("A");
|
||
|
||
F:=ThisFunction(AA.F);
|
||
|
||
F.do();
|
||
|
||
//从类中查找类方法
|
||
|
||
F2:=ThisFunction(class(A).F2);
|
||
|
||
F2.do();
|
||
|
||
End.
|
||
|
||
#### FunctionInfo
|
||
|
||
调用方法:
|
||
|
||
方法.FunctionInfo
|
||
|
||
获取函数的信息。返回存放函数信息的字符串下标数组。
|
||
|
||
<table><tbody><tr><td>
|
||
下标</td><td>
|
||
数据类型</td><td>
|
||
描述</td></tr><tr><td>
|
||
functionname</td><td>
|
||
String</td><td>
|
||
方法名</td></tr><tr><td>
|
||
parameter</td><td>
|
||
Array</td><td>
|
||
方法参数</td></tr><tr><td>
|
||
returntype</td><td>
|
||
Stirng</td><td>
|
||
函数返回值</td></tr><tr><td>
|
||
returndim
|
||
</td><td>
|
||
Integer</td><td>
|
||
数组的维度,0表示不是数组</td></tr><tr><td>
|
||
calltype</td><td>
|
||
Integer</td><td>
|
||
调用类型</td></tr><tr><td>
|
||
classname</td><td>
|
||
Stirng</td><td>
|
||
所在的类名</td></tr></tbody></table>
|
||
|
||
其中:parameter 下标所对应的数组也是字符串下标数组。
|
||
|
||
下标
|
||
|
||
<table><tbody><tr><td>
|
||
下标</td><td>
|
||
数据类型</td><td>
|
||
描述</td></tr><tr><td>
|
||
nme</td><td>
|
||
String</td><td>
|
||
参数名称</td></tr><tr><td>
|
||
tpe</td><td>
|
||
String</td><td>
|
||
参数类型</td></tr><tr><td>
|
||
dm</td><td>
|
||
Integer</td><td>
|
||
数组的维度</td></tr><tr><td>
|
||
out</td><td>
|
||
Integer</td><td>
|
||
</td></tr></tbody></table>
|
||
|
||
注意:
|
||
|
||
可以显式为参数或返回值定义类型。当定显式义了类型后以上提到的数据类型将会是自定义定义的值,否则是空字符串,这种用法不会真正做类型检查或转化,只是通知 FunctionInfo 中的数据类型,通常用户 Web service 的构建。
|
||
|
||
### 算符重载
|
||
|
||
TSL 的对象如果要使用算符进行计算,就需要用到算符重载,算符重载可以重载掉 TSL 的算符,在 TSL 的类中要实现算符重载的方法。
|
||
|
||
算符重载支持 TSL 开发的类,也支持用 C++等开发的二进制类。
|
||
|
||
#### 内容
|
||
|
||
- Operator
|
||
- 算符重载的案例
|
||
- 面向对象的 Operator 重载支持[]
|
||
- 面向对象的 Operator 算符重载支持++,--,+=,-=
|
||
|
||
#### Operator
|
||
|
||
#### 算符重载的案例
|
||
|
||
下边是一个复数的例子,范例中重载了+和<运算符:
|
||
|
||
```text
|
||
Type Tcomplex=class
|
||
|
||
vReal;//实部
|
||
|
||
vImaginary;//虚部
|
||
|
||
function Operator +(data); //单参数,即只支持obj+10,不支持10+obj
|
||
|
||
begin
|
||
|
||
r:=new Tcomplex();
|
||
|
||
if ifnumber(data) then
|
||
|
||
r.vReal:=vReal+data
|
||
|
||
else begin
|
||
|
||
r.vReal:=vReal+data.vReal;
|
||
|
||
r.vImaginary:=vImaginary+data. vImaginary;
|
||
|
||
end;
|
||
|
||
return r;
|
||
|
||
end;
|
||
|
||
function Operator<(data,isLeft); //双参数,支持obj<10的判断,也支持10<obj的判断
|
||
|
||
End;
|
||
|
||
Function Operator Tcomplex. <(data,isLeft);
|
||
|
||
Begin
|
||
|
||
//echo "isLeft:",isLeft;//对象是否在左边
|
||
|
||
If ifnumber(data) then
|
||
|
||
V:=vReal<data
|
||
|
||
else
|
||
|
||
V:= (vReal^2+vImaginary^2)<data.vReal^2+data.vImaginary^2;
|
||
|
||
If not isLeft then V:=not V;
|
||
|
||
Return V;
|
||
|
||
End;
|
||
```
|
||
|
||
调用测试:
|
||
|
||
```text
|
||
t1:=new TComplex();
|
||
|
||
t1.vReal:=10;
|
||
|
||
t1.vImaginary:=100;
|
||
|
||
t2:=t1+10; //不支持t2:=10+t1;
|
||
|
||
echo "t2.vReal:",t2.vReal;
|
||
|
||
|
||
echo "t1<5:",t1<5;
|
||
|
||
echo "t1<300:",t1<300;
|
||
|
||
echo "5<t1:",5<t1;//对象在右边
|
||
```
|
||
|
||
打印结果:
|
||
|
||
t2.vReal:20
|
||
|
||
t1<5:0
|
||
|
||
t1<300:1
|
||
|
||
5<t1:1
|
||
|
||
#### 面向对象的 Operator 重载支持[]
|
||
|
||
用[]或者[0]重载读取过程,即实现指定下标时取值的操作,用[1]重载写入过程,即实现指定下标进行赋值的操作。
|
||
|
||
重载读取定义:operator 或 operator0
|
||
|
||
重载写入定义:operator1
|
||
|
||
其中,idx 表示当前下标值,支持整型与字符串
|
||
|
||
重载读取中,s 表示当前层级,中间层从 0 开始,依次为 0,1,2,3,....,最后一层时为-1。
|
||
|
||
重载写入中,v 表示写入的值,但在中间层时它是一个 none 类型,层级由 none 类型的值进行确定,最后一层时为写入的值。
|
||
|
||
[]重载时允许多级,重载中返回对象表示继续下一层
|
||
|
||
在[0]算符重载时,通过第二个参数可判断当前层级,当小于 0 时表示当前处于最后一层,重现实现中返回对象表示继续下一层,否则访问结束。
|
||
|
||
在[1]算符重载时,可通过 ifnone(v)判断第二个参数,若为真,表示为中间级,此时实现中返回对象表示继续下一层,判断为真时当前处于最后一层,此时可对该参数值进行赋值操作。
|
||
|
||
对象算符重载数组 set 算符时级别的获取与当前状态的判定:
|
||
|
||
getnone 函数可以获得 none 类型包含的 int 值。
|
||
|
||
ifnone(v,i)可以判断是否属于 none 并且所含整数位 i。
|
||
|
||
当对象重载下标写入行为时,若当前为中间级,则第二个参数为 none 类型,此时该 none 类型的值为下标的级别,从 0 开始,依次为 0,1,2,3....。如果写入的过程出现错误,则调用写入方法进行重载,此时进入的 none 类型值为-1,这样做方便数据库等事务的实现。
|
||
|
||
例如:单层的实现
|
||
|
||
```text
|
||
type bb=class
|
||
|
||
data;
|
||
|
||
public
|
||
|
||
function create(v);
|
||
|
||
begin
|
||
|
||
data:=v;
|
||
|
||
end;
|
||
|
||
function operator;
|
||
|
||
begin
|
||
|
||
return data[index];
|
||
|
||
end;
|
||
|
||
function operator1;
|
||
|
||
begin
|
||
|
||
echo "set->",index,"->",v;
|
||
|
||
data[index]:=v;
|
||
|
||
end;
|
||
|
||
end;
|
||
```
|
||
|
||
调用测试如:
|
||
|
||
```text
|
||
t:=array(1,2,3,4,5);
|
||
|
||
b:=new bb(t);
|
||
|
||
a:=b[2];//取值
|
||
|
||
echo "b[2]:",a;
|
||
|
||
b[3]:=999; //重新赋值
|
||
|
||
echo "b.data:",tostn(b.data);
|
||
```
|
||
|
||
打印如下:
|
||
|
||
b[2]:3
|
||
|
||
set->3->999
|
||
|
||
b.data:
|
||
|
||
array(1,2,3,999,5)
|
||
|
||
##### 内容
|
||
|
||
- 对象[]重载时允许多级的应用示例
|
||
- 对象算符重载数组 set 算符时 none 类型的应用实例
|
||
|
||
##### 对象[]重载时允许多级的应用示例
|
||
|
||
示例:对象中[]算符重载多级的实现示例
|
||
|
||
```text
|
||
type aa=class
|
||
|
||
data;
|
||
|
||
indList;
|
||
|
||
public
|
||
|
||
function create(v);
|
||
|
||
begin
|
||
|
||
data:=v;
|
||
|
||
indList:=array();
|
||
|
||
end;
|
||
|
||
function operator0; //多级访问
|
||
|
||
begin
|
||
|
||
//s1<0时,最后一层
|
||
|
||
indList[length(indList)]:=index;
|
||
|
||
v:=data;
|
||
|
||
for i,ind in indList do
|
||
|
||
v:=v[ind];
|
||
|
||
if s1<0 then begin
|
||
|
||
indList:=array();
|
||
|
||
return v;
|
||
|
||
end
|
||
|
||
else
|
||
|
||
|
||
return self; //返回对象
|
||
|
||
|
||
end;
|
||
|
||
function operator1;
|
||
|
||
begin
|
||
|
||
indList[length(indList)]:=index;
|
||
|
||
|
||
if ifnone(v) then return self; //返回对象,存在多级
|
||
|
||
|
||
sv:='data';
|
||
|
||
for i,ind in indList do
|
||
|
||
if ifstring(ind) then sv+="['"+ind+"']";
|
||
|
||
else sv+="["$ind$"]";
|
||
|
||
sv+=":=v;";
|
||
|
||
eval(&sv);
|
||
|
||
indList:=array();
|
||
|
||
end;
|
||
|
||
end;
|
||
```
|
||
|
||
调用测试:
|
||
|
||
```text
|
||
t:=array(("A":1,"B":2,"C":3),("A":11,"B":22,"C":33));
|
||
|
||
a:=new aa(t);
|
||
|
||
echo a[0,"B"];
|
||
|
||
a[1,"C"]:=999;
|
||
|
||
echo tostn(a.data);
|
||
```
|
||
|
||
打印结果:
|
||
|
||
2
|
||
|
||
array(
|
||
|
||
("A":1,"B":2,"C":3),
|
||
|
||
("A":11,"B":22,"C":999))
|
||
|
||
##### 对象算符重载数组 set 算符时 none 类型的应用实例
|
||
|
||
例如,实现一个资金流入流出的账单记录,当对历史记录进行篡改时,会引发赋值出错,进行数据回滚处理。如此来展示对象算符重载数组 set 算符时,ifnone(v,i)等功能的作用
|
||
|
||
```text
|
||
//资金出入的联动实现,行标下只能依次递增,否则报错回滚
|
||
|
||
Type DepositMoney = class()
|
||
|
||
FMoneyMX;
|
||
|
||
FlastR; //上行
|
||
|
||
FnewR; //当前行
|
||
|
||
function create(v);
|
||
|
||
begin
|
||
|
||
FMoneyMX:=array();
|
||
|
||
FMoneyMX[0]["时间"] := datetimetostr(now());//初始资产
|
||
|
||
FMoneyMX[0]["当前余额"] := v;//初始资产
|
||
|
||
FMoneyMX[0]["出金"] := 0;//
|
||
|
||
FMoneyMX[0]["入金"] := 0;//
|
||
|
||
FlastR:=-1;
|
||
|
||
FnewR:=0;
|
||
|
||
end
|
||
|
||
function operator1; //设置值
|
||
|
||
begin
|
||
|
||
// echo "Idx->",idx," v->",v;
|
||
|
||
//当赋值出错时,进入该过程,进行回滚
|
||
|
||
|
||
if ifnone(v,-1) then
|
||
//none类型,且none整数位为-1
|
||
|
||
begin
|
||
|
||
//回滚到上一次的状态
|
||
|
||
FMoneyMX:=FMoneyMX[0:FlastR];
|
||
|
||
FnewR:=FlastR;
|
||
|
||
FlastR:=FlastR-1;
|
||
|
||
echo "发生错误-回滚到变更前状态:",tostn(FMoneyMX);
|
||
|
||
return "Erro";
|
||
|
||
end;
|
||
|
||
|
||
if ifnone(v) then //中间层级
|
||
|
||
|
||
begin
|
||
|
||
// echo "getnone(v)->",getnone(v);//当前级别
|
||
|
||
|
||
if getnone(v)=0 then begin //第一层
|
||
|
||
|
||
FlastR:=FnewR;
|
||
|
||
FnewR:=idx;
|
||
|
||
FMoneyMX[idx,"时间"]:=datetimetostr(now());
|
||
|
||
if FnewR<FlastR+1 then raise "不能对历史数据进行修改,当前最新行标:"$FlastR;
|
||
|
||
return self;
|
||
|
||
end
|
||
|
||
else raise "只支持二维数组";
|
||
|
||
end
|
||
|
||
if idx="出金" then
|
||
|
||
begin
|
||
|
||
FMoneyMX[FnewR]["当前余额"]:= FMoneyMX[FlastR]["当前余额"]-v;
|
||
|
||
FMoneyMX[FnewR]["出金"]:= v;
|
||
|
||
FMoneyMX[FnewR]["入金"]:= 0;
|
||
|
||
end
|
||
|
||
else if idx="入金" then
|
||
|
||
begin
|
||
|
||
FMoneyMX[FnewR]["当前余额"]:= FMoneyMX[FlastR]["当前余额"]+v;
|
||
|
||
FMoneyMX[FnewR]["出金"]:= 0;
|
||
|
||
FMoneyMX[FnewR]["入金"]:= v;
|
||
|
||
end
|
||
|
||
end
|
||
|
||
function destroy();
|
||
|
||
begin
|
||
|
||
FMoneyMX := nil;
|
||
|
||
FlastR := nil;
|
||
|
||
FnewR :=nil;
|
||
|
||
end
|
||
|
||
end
|
||
```
|
||
|
||
调用测试:
|
||
|
||
```text
|
||
//--事务示例
|
||
|
||
obj:=new DepositMoney(100);
|
||
|
||
sleep(1*1000);
|
||
|
||
obj[1]["入金"]:=888;
|
||
|
||
echo "入金888->",tostn(obj.FMoneyMX);
|
||
|
||
sleep(1*1000);
|
||
|
||
obj[2]["出金"]:=200;
|
||
|
||
echo "出金200->",tostn(obj.FMoneyMX);
|
||
|
||
sleep(1*1000);
|
||
|
||
obj[2]["出金"]:=100; //此时变动下标应该是3,指定2会引发set出现,数据会进行回滚
|
||
|
||
echo "出金100->",tostn(obj.FMoneyMX);
|
||
|
||
return obj.FMoneyMX;
|
||
```
|
||
|
||
执行报错后,打印结果如下:(在 obj[2]["出金"]:=100;时触发出错逻辑,数据回到赋值之前的状态)
|
||
|
||
入金 888->
|
||
|
||
array(
|
||
|
||
("时间":"2025-08-12 17:55:40","当前余额":100,"出金":0,"入金":0),
|
||
|
||
("时间":"2025-08-12 17:55:41","当前余额":988,"出金":0,"入金":888))
|
||
|
||
出金 200->
|
||
|
||
array(
|
||
|
||
("时间":"2025-08-12 17:55:40","当前余额":100,"出金":0,"入金":0),
|
||
|
||
("时间":"2025-08-12 17:55:41","当前余额":988,"出金":0,"入金":888),
|
||
|
||
("时间":"2025-08-12 17:55:42","当前余额":788,"出金":200,"入金":0))
|
||
|
||
出金 100->
|
||
|
||
发生错误-回滚到变更前状态:
|
||
|
||
array(
|
||
|
||
("时间":"2025-08-12 17:55:40","当前余额":100,"出金":0,"入金":0),
|
||
|
||
("时间":"2025-08-12 17:55:41","当前余额":988,"出金":0,"入金":888),
|
||
|
||
("时间":"2025-08-12 17:55:43","当前余额":788,"出金":200,"入金":0))
|
||
|
||
#### 面向对象的 Operator 算符重载支持++,--,+=,-=
|
||
|
||
实现示例如:
|
||
|
||
```text
|
||
type bb=class
|
||
|
||
data;
|
||
|
||
public
|
||
|
||
function create(v);
|
||
|
||
begin
|
||
|
||
data:=v;
|
||
|
||
end;
|
||
|
||
function operator++(v);
|
||
|
||
begin
|
||
|
||
if v=0 then//d:=obj++;时
|
||
|
||
begin
|
||
|
||
r:= new bb();
|
||
|
||
r.data:=data;
|
||
|
||
r.data++;
|
||
|
||
return r;
|
||
|
||
end //其它情况下,都是++后的状态
|
||
|
||
else data++;
|
||
|
||
end;
|
||
|
||
function operator--(v);
|
||
|
||
begin
|
||
|
||
if v=0 then
|
||
|
||
begin
|
||
|
||
r:= new bb();
|
||
|
||
r.data:=data;
|
||
|
||
r.data--;
|
||
|
||
return r;
|
||
|
||
end
|
||
|
||
else data--;
|
||
|
||
end;
|
||
|
||
function operator+=(v);
|
||
|
||
begin
|
||
|
||
data+=v;
|
||
|
||
end;
|
||
|
||
function operator-=(v);
|
||
|
||
begin
|
||
|
||
data-=v;
|
||
|
||
end;
|
||
|
||
end;
|
||
```
|
||
|
||
调用测试:
|
||
|
||
```text
|
||
t:=array(1,2,3,999,5);
|
||
|
||
b:=new bb(t);
|
||
|
||
++b;//自加
|
||
|
||
echo "++b后:";
|
||
|
||
echo "b.data: ",tostn(b.data);
|
||
|
||
c:=b++;
|
||
|
||
echo "c:=b++;后:";
|
||
|
||
echo "c.data: ",tostn(c.data);
|
||
|
||
echo "b.data:",tostn(b.data);
|
||
```
|
||
|
||
打印结果如下:
|
||
|
||
++b 后:
|
||
|
||
b.data:
|
||
|
||
array(2,3,4,1000,6)
|
||
|
||
c:=b++;后:
|
||
|
||
c.data:
|
||
|
||
array(2,3,4,1000,6)
|
||
|
||
b.data:
|
||
|
||
array(3,4,5,1001,7)
|
||
|
||
### 单元中的类
|
||
|
||
天软中,可以将相同功能封装到单元中,形成专用工具方法库。
|
||
|
||
在单元中的类,可通过 obj:=new Unit1.Class1.Class2()的方式进行构建
|
||
|
||
通过 Type ClassA=Class(Unit1.Class1.Class2...)模式进行继承
|
||
|
||
#### 内容
|
||
|
||
- 继承单元中的类
|
||
- 构造单元中的类实例
|
||
- 预定义:ParentClassInUnit
|
||
- 单元中的类-应用实例
|
||
|
||
#### 继承单元中的类
|
||
|
||
继承单元中的类,和继承常规类不同:
|
||
|
||
继承常规类:直接继承一个已知的类,如 Type ClassA=Class(TStringList)。
|
||
|
||
继承单元中的类:需要通过 Type ClassA=Class(Unit1.Class1.Class2...)模式来定义类,Class 中包含“单元名.外层类名.内层类名”的完整路径形式,精确指定要继承的类位置。
|
||
|
||
具体语法如下:
|
||
|
||
Type ClassA=Class(Unit1.Class1.Class2[,OtherClass...])
|
||
|
||
例如 Type ClassA = Class(Unit1.Class1.Class2),表示 ClassA 将直接继承单元 Unit1 中 Class1 内部定义的嵌套类 Class2。
|
||
|
||
书写时需注意,必须完整、准确的指定从单元名到最终类名的全部路径,否则会执行失败。
|
||
|
||
注:2025-08-27 后的 NG 客户端及使用新一代 TSL 的服务器支持该功能。
|
||
|
||
示例:
|
||
|
||
定义于 Unit1 中的类结构
|
||
|
||
```text
|
||
Unit Unit1;
|
||
|
||
Interface
|
||
|
||
Type Class1=Class
|
||
|
||
Type Class2=Class// 嵌套类
|
||
|
||
function MethodInClass2();//方法
|
||
|
||
class function ClassMethodInClass2();//类方法
|
||
|
||
end;
|
||
|
||
end;
|
||
|
||
Initialization
|
||
|
||
Finalization End.
|
||
```
|
||
|
||
直接继承 Unit1.Class1.Class2
|
||
|
||
```text
|
||
Type MyNewClass = Class(Unit1.Class1.Class2)
|
||
|
||
function MyNewMethod();
|
||
|
||
end;
|
||
```
|
||
|
||
创建实例
|
||
|
||
```text
|
||
//方式一:CreateObject
|
||
|
||
obj1:=CreateObject("MyNewClass");
|
||
|
||
obj1.MethodInClass2();//调用父类方法
|
||
|
||
//方式二:new关键字
|
||
|
||
obj2:=new MyNewClass();
|
||
|
||
obj2.MethodInClass2();//调用父类方法
|
||
```
|
||
|
||
查找类
|
||
|
||
```text
|
||
classRef:=FindClass("MyNewClass");
|
||
|
||
classRef.ClassMethodInClass2();//调用父类中类方法
|
||
```
|
||
|
||
#### 构造单元中的类实例
|
||
|
||
构造单元中的类实例与构造常规类实例方法类似,均可使用 CreateObject 或 new 实现。
|
||
|
||
核心区别在于类标识符的指定方式:
|
||
|
||
常规类实例:只需提供类名,如 CreateObject("TStringList")或 new TStringList()。
|
||
|
||
单元中的类实例:需提供完整的类路径(格式:单元名.类名),如 CreateObject("Unit1.Class1.Class2")或 new Unit1.Class1.Class2()。
|
||
|
||
具体语法如下:
|
||
|
||
obj:=CreateObject("Unit1.Class1.Class2"[,P1,...,PN:any]);//CreateObject 方式
|
||
|
||
obj:=new Unit1.Class1.Class2([,P1,...,PN:any]);//new 方式
|
||
|
||
例如 obj:= new Unit1.Class1.Class2(),表示创建单元 Unit1 中 Class1 内部定义的嵌套类 Class2 的实例,并赋值给 obj。
|
||
|
||
注:2025-08-27 后的 NG 客户端及使用新一代 TSL 的服务器支持该功能。
|
||
|
||
示例:
|
||
|
||
定义于 Unit1 中的类结构
|
||
|
||
```text
|
||
Unit Unit1;
|
||
|
||
Interface
|
||
|
||
Type Class1=Class
|
||
|
||
Type Class2=Class// 嵌套类
|
||
|
||
function MethodInClass2();//方法
|
||
|
||
class function ClassMethodInClass2();//类方法
|
||
|
||
end;
|
||
|
||
end;
|
||
|
||
Initialization
|
||
|
||
Finalization End.
|
||
```
|
||
|
||
创建实例
|
||
|
||
```text
|
||
//方式一:CreateObject
|
||
|
||
obj1:=CreateObject("Unit1.Class1.Class2");
|
||
|
||
obj1.MethodInClass2();//调用方法
|
||
|
||
//方式二:new关键字
|
||
|
||
obj2:=new Unit1.Class1.Class2();
|
||
|
||
obj2.MethodInClass2();//调用方法
|
||
```
|
||
|
||
#### 预定义:ParentClassInUnit
|
||
|
||
判定当前环境是否支持继承和构造单元中的类
|
||
|
||
```text
|
||
{$IFDEF ParentClassInUnit}
|
||
|
||
return 1;
|
||
|
||
{$ELSE} //否则(如果未定义)
|
||
|
||
return "当前环境不支持继承和构造单元中的类";
|
||
|
||
{$ENDIF}
|
||
```
|
||
|
||
#### 单元中的类-应用实例
|
||
|
||
现有日期相关单元 TD_DateUnit,单元中包含类 TD_DateClass、IntDate、StrDate。
|
||
|
||
```text
|
||
Unit TD_DateUnit;
|
||
|
||
Interface
|
||
|
||
Type TD_DateClass=class()//父类
|
||
|
||
value; //天软日期
|
||
|
||
Function create(v);
|
||
|
||
begin
|
||
|
||
value := isDate(v)?v:0;
|
||
|
||
end;
|
||
|
||
function isDate();overload;
|
||
|
||
begin
|
||
|
||
return isDate(value);
|
||
|
||
end
|
||
|
||
class Function isDate(v);overload; //是否是一个日期
|
||
|
||
begin
|
||
|
||
try
|
||
|
||
y := yearof(v);
|
||
|
||
m := monthof(v);
|
||
|
||
d := dayof(v);
|
||
|
||
return isValidDate(y,m,d);
|
||
|
||
except
|
||
|
||
return 0;
|
||
|
||
end;
|
||
|
||
end;
|
||
|
||
//--整型-日期
|
||
|
||
Type IntDate=class(TD_DateClass)//内部类,继承父类
|
||
|
||
iDate;//对应的整数日期
|
||
|
||
Function create(v);
|
||
|
||
begin
|
||
|
||
iDate:=_datetoint(v);
|
||
|
||
value:=inttodate(iDate);
|
||
|
||
end;
|
||
|
||
function _datetoint();overload;
|
||
|
||
begin
|
||
|
||
return iDate;
|
||
|
||
end
|
||
|
||
class Function _datetoint(v);overload;
|
||
|
||
begin
|
||
|
||
if ifstring(v)then
|
||
|
||
begin
|
||
|
||
_iDate := datetoint(strtodate(v));
|
||
|
||
end else
|
||
|
||
if v<99999 then
|
||
|
||
begin
|
||
|
||
isd := isDate(v);
|
||
|
||
_iDate := isd?datetoint(v):v;
|
||
|
||
end
|
||
|
||
else _iDate:=Int(v);
|
||
|
||
return _iDate;
|
||
|
||
end
|
||
|
||
end;
|
||
|
||
//--字符串-日期
|
||
|
||
Type StrDate=class()//内部类,不继承父类
|
||
|
||
value;//天软日期
|
||
|
||
sDate;//对应的字符串日期
|
||
|
||
Function create(v);
|
||
|
||
begin
|
||
|
||
sDate:=_datetostr(v);
|
||
|
||
value:=strtodate(sDate);
|
||
|
||
end;
|
||
|
||
class Function _datetostr(v)
|
||
|
||
begin
|
||
|
||
obj := new IntDate(v);
|
||
|
||
_sDate := datetostr(obj.value);
|
||
|
||
return _sDate;
|
||
|
||
end
|
||
|
||
Function formatS(f); //按指定符号生成字符串日期
|
||
|
||
begin
|
||
|
||
fs := "yyyy"+f+"mm"+f+"dd";
|
||
|
||
return FormatDateTime(fs,value);
|
||
|
||
end;
|
||
|
||
end;
|
||
|
||
End;
|
||
|
||
Implementation
|
||
|
||
Initialization
|
||
|
||
Finalization End.
|
||
```
|
||
|
||
使用示例
|
||
|
||
```text
|
||
dateClass:=findclass("TD_DateUnit.TD_DateClass");
|
||
|
||
echo dateClass.isDate(20250912T);//天软日期,返回值:1
|
||
|
||
echo dateClass.isDate("2025-09-12");//字符串日期,返回值:0
|
||
|
||
//现有如下日期
|
||
|
||
endt:=20250912T;
|
||
|
||
//通过intDate类,转换成整数日期
|
||
|
||
obj:=new TD_DateUnit.TD_DateClass.intDate(endt);
|
||
|
||
echo obj.iDate;//返回值:20250912
|
||
|
||
echo obj._datetoint("2025-09-12");//返回值:20250912
|
||
|
||
//通过strDate类,转换成整数日期
|
||
|
||
obj:=new TD_DateUnit.TD_DateClass.strDate(endt);
|
||
|
||
echo obj.sDate;//返回值:2025-09-12
|
||
|
||
echo obj._datetoStr(20250912);//返回值:2025-09-12
|
||
|
||
echo obj.formatS(".");//返回值:2025.09.12
|
||
|
||
return 1;
|
||
```
|
||
|
||
打印结果如下:
|
||
|
||
### TSL 内置对象使用大全
|
||
|
||
#### 内容
|
||
|
||
- TSL 内置对象使用大全简介
|
||
- FTP 对象
|
||
- TRSA
|
||
- TCipher
|
||
- TStringList 对象
|
||
- THashedStringList 对象
|
||
- TStream 对象
|
||
- TMemoryStream 对象
|
||
- THandleStream 对象
|
||
- TFileStream 对象
|
||
- TIniFile 对象
|
||
- TMemIniFile 对象
|
||
- TRegistryIniFile 对象
|
||
- TWebResponse 对象
|
||
- TWebRequest 对象
|
||
- TCookieCollection 对象
|
||
- TCookie 对象
|
||
- TSessionMan 对象
|
||
- TSession 对象
|
||
- SMTP 对象
|
||
- Pop3 对象
|
||
- MailMsg 对象
|
||
- MessagePart 对象
|
||
|
||
#### TSL 内置对象使用大全简介
|
||
|
||
TSL 支持三种对象:COM 对象,TSL 内置对象,TSL 语言编写的对象。
|
||
|
||
TSL 内置对象是二进制开发的 TSL 对象,独立的 TSL 内置对象可以在 TSL 语言里继承,但是不能重载二进制的内置对象的方法。
|
||
|
||
#### FTP 对象
|
||
|
||
说明:FTP 对象通过文件传输协议(FTP)提供对文件服务器的客户端访问。FTP 对象的方法和属性作用于打开、登陆已经关闭 FTP 连接,同事用于上传、下载、重命名、删除和获得 FTP 服务器上的文件信息。
|
||
|
||
##### 内容
|
||
|
||
- FTP 对象的创建
|
||
- FTP 对象的方法
|
||
- FTP 对象属性
|
||
|
||
##### FTP 对象的创建
|
||
|
||
范例
|
||
|
||
范例 1:创建对象未指定配置名,手动设置 FTP 配置并连接登录服务器
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
obj.connect();//连接服务器
|
||
|
||
obj.login();//登录服务器
|
||
|
||
return obj.RetrieveCurrentDir();
|
||
|
||
//连接并登录成功,返回当前所处目录(默认为"/")
|
||
```
|
||
|
||
范例 2:创建对象时指定配置名,自动读取配置文件中的设置并连接登录服务器
|
||
|
||
配置文件为 Analyse.NET\PLUGIN\FileMgr.INI,配置格式如下:
|
||
|
||
[CLASS:FTP]
|
||
|
||
permit=local
|
||
|
||
[FTP Settings]
|
||
|
||
TSDN.Case.FTP:Port=20
|
||
|
||
TSDN.Case.FTP:UserName=username
|
||
|
||
TSDN.Case.FTP:Password=password
|
||
|
||
TSDN.Case.FTP=ftp.tinysoft.com.cn
|
||
|
||
```text
|
||
obj := CreateObject("FTP","TSDN.Case.FTP");
|
||
|
||
return obj.RetrieveCurrentDir();
|
||
|
||
//连接并登录成功,返回当前所处目录(默认为"/")
|
||
```
|
||
|
||
##### FTP 对象的方法
|
||
|
||
###### 内容
|
||
|
||
- Abort
|
||
- ChangeDir
|
||
- ChangeDirUp
|
||
- Connect
|
||
- Delete
|
||
- DisconnectNotifyPeer
|
||
- FileDate
|
||
- Get
|
||
- Help
|
||
- IsServerMDTZAndListTForm
|
||
- List
|
||
- Login
|
||
- MakeDir
|
||
- Noop
|
||
- Put
|
||
- Quit
|
||
- Quote
|
||
- ReInitialize
|
||
- RemoveDir
|
||
- Rename
|
||
- ResumeSupported
|
||
- RetrieveCurrentDir
|
||
- SetCmdOpt
|
||
- SetLang
|
||
- SetModTime
|
||
- SetModTimeGMT
|
||
- Site
|
||
- Size
|
||
- Status
|
||
- CRC
|
||
|
||
###### Abort
|
||
|
||
范例
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
obj.connect();//连接服务器
|
||
|
||
obj.login();//登录服务器
|
||
|
||
return obj.Abort();
|
||
|
||
//终止连接成功,返回0
|
||
```
|
||
|
||
###### ChangeDir
|
||
|
||
范例
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
obj.connect();//连接
|
||
|
||
obj.login();//登录
|
||
|
||
obj.changedir('/test');//将FTP服务器上的当前目录更改为"/test"
|
||
|
||
return obj.RetrieveCurrentDir();
|
||
|
||
//修改成功,当前目录应为"/test"
|
||
```
|
||
|
||
###### ChangeDirUp
|
||
|
||
范例
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
obj.connect();//连接
|
||
|
||
obj.login();//登录
|
||
|
||
obj.changedir('/test');//将FTP服务器上的当前目录更改为"/test"
|
||
|
||
obj.changeDirUp();//跳转到当前目录的上一级目录"/"
|
||
|
||
return obj.RetrieveCurrentDir();
|
||
|
||
//跳转成功,当前目录应为"/"
|
||
```
|
||
|
||
###### Connect
|
||
|
||
范例
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
return obj.connect();
|
||
|
||
//连接成功,返回0
|
||
```
|
||
|
||
###### Delete
|
||
|
||
范例
|
||
|
||
删除 FTP 服务器指定文件
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
//删除Test.txt文件
|
||
|
||
obj.delete("Test.txt");
|
||
|
||
//验证文件是否被删除
|
||
|
||
return obj.FileDate("Test.txt",0);
|
||
|
||
//获取文件时间,若无该文件,返回0
|
||
```
|
||
|
||
###### DisconnectNotifyPeer
|
||
|
||
###### FileDate
|
||
|
||
范例
|
||
|
||
获取 FTP 服务器指定文件的最后修改时间
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
ret:= obj.FileDate("Test.txt",0);
|
||
|
||
return DateTimeToStr(ret);
|
||
|
||
//"2024-07-31 14:28:00"
|
||
```
|
||
|
||
###### Get
|
||
|
||
范例
|
||
|
||
从服务器下载指定文件至本机
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
obj.TryNATFastTrack := 1;
|
||
|
||
//下载文件
|
||
|
||
st := new TFileStream("","D:\\test\\1.txt",65535);
|
||
|
||
obj.get("FtpTest.txt",st,0);
|
||
|
||
//若下载成功,可在本机对应位置查看文件
|
||
```
|
||
|
||
###### Help
|
||
|
||
###### IsServerMDTZAndListTForm
|
||
|
||
###### List
|
||
|
||
范例
|
||
|
||
查看当前服务器目录下匹配到的文件列表
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
AFiles := new TStringList();
|
||
|
||
//获取当前目录所有.txt文件信息
|
||
|
||
obj.List(AFiles,'*.txt',true);
|
||
|
||
return AFiles.GetText();
|
||
|
||
//字符串:
|
||
|
||
"-rw-r--r-- 1 1001 1001 17 Apr 09 16:07 test01.txt
|
||
|
||
-rw-r--r-- 1 1001 1001 0 Sep 16 2023 test02.txt
|
||
|
||
-rw-r--r-- 1 1001 1001 38 Jul 25 17:26 test03.txt"
|
||
```
|
||
|
||
###### Login
|
||
|
||
范例
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
return obj.RetrieveCurrentDir();
|
||
|
||
//获取当前所在目录,若登录成功,则返回"/"
|
||
```
|
||
|
||
###### MakeDir
|
||
|
||
范例
|
||
|
||
在服务器当前目录中创建新文件夹
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
obj.MakeDir("newDir");
|
||
|
||
//若创建成功,可在服务器中查看或使用FAQ:
|
||
List
|
||
查看
|
||
```
|
||
|
||
###### Noop
|
||
|
||
###### Put
|
||
|
||
范例
|
||
|
||
将本机指定文件上传至服务器
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
//构造TStream对象
|
||
|
||
filepath := "D:\\test\\Test.txt";
|
||
|
||
st := new TMemoryStream();
|
||
|
||
st.LoadFromFile("",filepath);
|
||
|
||
obj.Put(st,"put.txt",false);
|
||
|
||
//若上传成功,可在服务器中查看或使用FAQ:
|
||
Get
|
||
下载后在本机查看
|
||
```
|
||
|
||
###### Quit
|
||
|
||
###### Quote
|
||
|
||
###### ReInitialize
|
||
|
||
###### RemoveDir
|
||
|
||
范例
|
||
|
||
从服务器删除指定文件夹
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
obj.Remove("testDir");
|
||
|
||
//若删除成功,可在服务器中查看或使用FAQ:
|
||
List
|
||
查看
|
||
```
|
||
|
||
###### Rename
|
||
|
||
范例
|
||
|
||
范例一:重命名文件夹
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
obj.rename("testDir","newDir");
|
||
|
||
//若重命名成功,可在服务器中查看或使用FAQ:
|
||
List
|
||
查看
|
||
```
|
||
|
||
范例二:重命名文件
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
obj.rename("test.txt","new.txt");
|
||
|
||
//若重命名成功,可在服务器中查看或使用FAQ:
|
||
List
|
||
查看
|
||
```
|
||
|
||
###### ResumeSupported
|
||
|
||
###### RetrieveCurrentDir
|
||
|
||
范例
|
||
|
||
获取当前所在目录
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
return obj.RetrieveCurrentDir();
|
||
|
||
//字符串:"/"
|
||
```
|
||
|
||
###### SetCmdOpt
|
||
|
||
###### SetLang
|
||
|
||
###### SetModTime
|
||
|
||
###### SetModTimeGMT
|
||
|
||
###### Site
|
||
|
||
###### Size
|
||
|
||
范例
|
||
|
||
查看服务器当前目录指定文件大小
|
||
|
||
```text
|
||
obj := CreateObject("FTP");
|
||
|
||
obj.host := "ftp.tinysoft.com.cn";
|
||
|
||
obj.port := 20;
|
||
|
||
obj.username := username;
|
||
|
||
obj.password := password;
|
||
|
||
//连接FTP服务器
|
||
|
||
obj.connect();
|
||
|
||
//登录
|
||
|
||
obj.Login();
|
||
|
||
return obj.Size("test.txt");
|
||
|
||
//整数,18
|
||
```
|
||
|
||
###### Status
|
||
|
||
###### CRC
|
||
|
||
##### FTP 对象属性
|
||
|
||
###### 内容
|
||
|
||
- Account
|
||
- AUTHCmd
|
||
- AutoLogin
|
||
- AutoIssueFEAT
|
||
- CanResume
|
||
- CurrentTransferMode
|
||
- DataPort
|
||
- DataPortMin
|
||
- DataPortMax
|
||
- DirFormat
|
||
- ExternalIP
|
||
- Host
|
||
- LangsSupported
|
||
- LastCmdResult
|
||
- ListResult
|
||
- Passive
|
||
- Password
|
||
- Port
|
||
- ProxyHost
|
||
- ProxyPort
|
||
- ProxyUsername
|
||
- ProxyPassword
|
||
- ProxyType
|
||
- ReadTimeout
|
||
- SupportsVerification
|
||
- SystemDesc
|
||
- TransferTimeout
|
||
- TransferType
|
||
- TryNATFastTrack
|
||
- UseCCC
|
||
- UseExtensionDataPort
|
||
- UseMLIS
|
||
- Username
|
||
- UseTLS
|
||
- UsingExtDataPort
|
||
- UsingNATFastTrack
|
||
- UsingSFTP
|
||
- PassiveUseControlHost
|
||
- ListenTimeout
|
||
- TransferMode
|
||
|
||
###### Account
|
||
|
||
###### AUTHCmd
|
||
|
||
###### AutoLogin
|
||
|
||
###### AutoIssueFEAT
|
||
|
||
###### CanResume
|
||
|
||
###### CurrentTransferMode
|
||
|
||
###### DataPort
|
||
|
||
###### DataPortMin
|
||
|
||
###### DataPortMax
|
||
|
||
###### DirFormat
|
||
|
||
###### ExternalIP
|
||
|
||
###### Host
|
||
|
||
###### LangsSupported
|
||
|
||
###### LastCmdResult
|
||
|
||
###### ListResult
|
||
|
||
###### Passive
|
||
|
||
###### Password
|
||
|
||
###### Port
|
||
|
||
###### ProxyHost
|
||
|
||
###### ProxyPort
|
||
|
||
###### ProxyUsername
|
||
|
||
###### ProxyPassword
|
||
|
||
###### ProxyType
|
||
|
||
###### ReadTimeout
|
||
|
||
###### SupportsVerification
|
||
|
||
###### SystemDesc
|
||
|
||
###### TransferTimeout
|
||
|
||
###### TransferType
|
||
|
||
###### TryNATFastTrack
|
||
|
||
###### UseCCC
|
||
|
||
###### UseExtensionDataPort
|
||
|
||
###### UseMLIS
|
||
|
||
###### Username
|
||
|
||
###### UseTLS
|
||
|
||
###### UsingExtDataPort
|
||
|
||
###### UsingNATFastTrack
|
||
|
||
###### UsingSFTP
|
||
|
||
###### PassiveUseControlHost
|
||
|
||
###### ListenTimeout
|
||
|
||
###### TransferMode
|
||
|
||
- Account
|
||
- AUTHCmd
|
||
- AutoLogin
|
||
- AutoIssueFEAT
|
||
- CanResume
|
||
- CurrentTransferMode
|
||
- DataPort
|
||
- DataPortMin
|
||
- DataPortMax
|
||
- DirFormat
|
||
- ExternalIP
|
||
- Host
|
||
- LangsSupported
|
||
- LastCmdResult
|
||
- ListResult
|
||
- Passive
|
||
- Password
|
||
- Port
|
||
- ProxyHost
|
||
- ProxyPort
|
||
- ProxyUsername
|
||
- ProxyPassword
|
||
- ProxyType
|
||
- ReadTimeout
|
||
- SupportsVerification
|
||
- SystemDesc
|
||
- TransferTimeout
|
||
- TransferType
|
||
- TryNATFastTrack
|
||
- UseCCC
|
||
- UseExtensionDataPort
|
||
- UseMLIS
|
||
- Username
|
||
- UseTLS
|
||
- UsingExtDataPort
|
||
- UsingNATFastTrack
|
||
- UsingSFTP
|
||
- PassiveUseControlHost
|
||
- ListenTimeout
|
||
- TransferMode
|
||
|
||
#### TRSA
|
||
|
||
TRsa 类用于提供 RSA 算法。RSA 是非对称加密算法,加解密速度慢,被加密明文的长度有限制,通常用于密钥传输、证书签名等场景。TRsa 类提供的成员方法主要包括:密钥生成、密钥读写、加解密。
|
||
|
||
##### 内容
|
||
|
||
- TRSA 的属性
|
||
- TRSA 的方法
|
||
- TRSA 使用说明以及范例
|
||
|
||
##### TRSA 的属性
|
||
|
||
###### 内容
|
||
|
||
- PublicKey
|
||
- PrivateKey
|
||
|
||
###### PublicKey
|
||
|
||
###### PrivateKey
|
||
|
||
##### TRSA 的方法
|
||
|
||
###### 内容
|
||
|
||
- GenerateKey
|
||
- PubEncrypt
|
||
- PriEncrypt
|
||
- PubDecrypt
|
||
- PriDecrypt
|
||
|
||
###### GenerateKey
|
||
|
||
###### PubEncrypt
|
||
|
||
###### PriEncrypt
|
||
|
||
###### PubDecrypt
|
||
|
||
###### PriDecrypt
|
||
|
||
##### TRSA 使用说明以及范例
|
||
|
||
在使用加密和解密方法前必须确保 TRsa 对象中已经正确地设置了密钥。
|
||
|
||
GenerateKey 方法会生成一对新的密钥,而给 PublicKey 和 PrivateKey 赋值可以分别载入一个已经存在的公钥和私钥,要注意的是给 PublicKey 和 PrivateKey 中的任何一个赋值,系统都会先将公钥和私钥同时重置,然后再分别设置公钥和私钥。
|
||
|
||
公钥和私钥都以 PKCS#1 格式编码。
|
||
|
||
被加密的数据长度通常不能超过密钥字节数-11,否则函数将执行失败。例如使用 1024 位密钥,即 128 字节,那么被加密数据不能超过 117 个字节。加密后的密文数据长度和密钥字节数相同。
|
||
|
||
示例:
|
||
|
||
下述代码展示了两种加密解密过程:
|
||
|
||
1.文本内容->公钥加密->私钥对加密内容解密
|
||
|
||
2.文本内容->私钥加密->公钥对加密内容解密
|
||
|
||
<table><tbody><tr><td>
|
||
filename := 'd:\\a.txt';<br/>
|
||
size := filesize("",filename);<br/>
|
||
ReadFile(rwraw(),"",filename,0,size,file_str);//读取文本内容<br/>
|
||
rsa_obj := CreateObject('TRsa');<br/>
|
||
rsa_obj.GenerateKey(1024);<br/>
|
||
rsa_pubkey := rsa_obj.PublicKey;//公钥<br/>
|
||
rsa_prikey := rsa_obj.PrivateKey;//私钥<br/>
|
||
rsa_obj_1 := CreateObject('TRsa');<br/>
|
||
rsa_obj_1.PublicKey := rsa_pubkey;<br/>
|
||
rsa_pub_enc := rsa_obj_1.PubEncrypt(file_str);//使用公钥加密文本内容<br/>
|
||
rsa_obj_1.PrivateKey := rsa_prikey;<br/>
|
||
rsa_pri_dec := rsa_obj_1.PriDecrypt(rsa_pub_enc);//使用私钥解密<br/>
|
||
rsa_pri_enc := rsa_obj_1.PriEncrypt(file_str);//使用私钥加密文本内容<br/>
|
||
rsa_obj_1.PublicKey := rsa_pubkey;<br/>
|
||
rsa_pub_dec := rsa_obj_1.PubDecrypt(rsa_pri_enc);//使用公钥解密<br/>
|
||
return array(<br/>
|
||
'文本内容':file_str,<br/>
|
||
'RSA私钥':rsa_prikey,<br/>
|
||
'RSA公钥':rsa_pubkey,<br/>
|
||
'RSA公钥加密':EncodeRadixStr(rsa_pub_enc,'',16),<br/>
|
||
'RSA私钥解密':rsa_pri_dec,<br/>
|
||
'RSA私钥加密':EncodeRadixStr(rsa_pri_enc,'',16),<br/>
|
||
'RSA公钥解密':rsa_pub_dec<br/>
|
||
);
|
||
</td></tr></tbody></table>
|
||
|
||
#### TCipher
|
||
|
||
TCipher 类用于多重对称加密算法,其支持的算法有:
|
||
|
||
<table><tbody><tr><td>
|
||
mode</td><td>
|
||
算法名</td><td>
|
||
密钥长度(字节)</td><td>
|
||
IV长度(字节)</td></tr><tr><td>
|
||
1</td><td>
|
||
DES_ECB</td><td>
|
||
8</td><td>
|
||
0</td></tr><tr><td>
|
||
2</td><td>
|
||
DEC_CBC</td><td>
|
||
8</td><td>
|
||
8</td></tr><tr><td>
|
||
3</td><td>
|
||
DES_CFB</td><td>
|
||
8</td><td>
|
||
8</td></tr><tr><td>
|
||
4</td><td>
|
||
DES_OFB</td><td>
|
||
8</td><td>
|
||
8</td></tr><tr><td>
|
||
5</td><td>
|
||
IDEA_ECB</td><td>
|
||
16</td><td>
|
||
0</td></tr><tr><td>
|
||
6</td><td>
|
||
IDEA_CBC</td><td>
|
||
16</td><td>
|
||
8</td></tr><tr><td>
|
||
7</td><td>
|
||
IDEA_CFB</td><td>
|
||
16</td><td>
|
||
8</td></tr><tr><td>
|
||
8</td><td>
|
||
IDEA_OFB</td><td>
|
||
16</td><td>
|
||
8</td></tr><tr><td>
|
||
9</td><td>
|
||
AES_128_ECB</td><td>
|
||
16</td><td>
|
||
0</td></tr><tr><td>
|
||
10</td><td>
|
||
AES_128_CBC</td><td>
|
||
16</td><td>
|
||
16</td></tr><tr><td>
|
||
11</td><td>
|
||
AES_128_CFB</td><td>
|
||
16</td><td>
|
||
16</td></tr><tr><td>
|
||
12</td><td>
|
||
AES_128_OFB</td><td>
|
||
16</td><td>
|
||
16</td></tr><tr><td>
|
||
13</td><td>
|
||
AES_192_ECB</td><td>
|
||
24</td><td>
|
||
0</td></tr><tr><td>
|
||
14</td><td>
|
||
AES_192_CBC</td><td>
|
||
24</td><td>
|
||
16</td></tr><tr><td>
|
||
15</td><td>
|
||
AES_192_CFB</td><td>
|
||
24</td><td>
|
||
16</td></tr><tr><td>
|
||
16</td><td>
|
||
AES_192_OFB</td><td>
|
||
24</td><td>
|
||
16</td></tr><tr><td>
|
||
17</td><td>AES_256_ECB</td><td>32</td><td>0</td></tr><tr><td>
|
||
18</td><td>AES_256_CBC</td><td>32</td><td>16</td></tr><tr><td>
|
||
19</td><td>AES_256_CFB</td><td>32</td><td>16</td></tr><tr><td>
|
||
20</td><td>AES_256_OFB</td><td>32</td><td>16</td></tr>
|
||
</tbody></table>
|
||
|
||
##### 内容
|
||
|
||
- TCipher 类的属性
|
||
- TCipher 类的方法
|
||
- TCipher 使用说明以及范例
|
||
|
||
##### TCipher 类的属性
|
||
|
||
###### 内容
|
||
|
||
- Mode
|
||
- Password
|
||
- Key
|
||
- IV
|
||
- KeyLength
|
||
- LVLength
|
||
|
||
###### Mode
|
||
|
||
###### Password
|
||
|
||
###### Key
|
||
|
||
###### IV
|
||
|
||
###### KeyLength
|
||
|
||
###### LVLength
|
||
|
||
##### TCipher 类的方法
|
||
|
||
###### 内容
|
||
|
||
- Encrypt
|
||
- EncryptFile
|
||
- Decrypt
|
||
- DecryptFile
|
||
|
||
###### Encrypt
|
||
|
||
###### EncryptFile
|
||
|
||
范例:
|
||
|
||
```text
|
||
cipher_obj:=CreateObject('TCipher',7); //使用DES_CBC算法
|
||
|
||
cipher_obj.Password:='Tinysoft'; //设定密码
|
||
|
||
//给指定文件进行加密,并将加密后的内容写入指定文件中
|
||
|
||
cipher_obj.EncryptFile('', 'd:\\test\\test.txt', '', 'd:\\test\\test2.txt');
|
||
|
||
//给指定文件进行解密,并将解密后的内容写入指定文件中
|
||
|
||
cipher_obj.DecryptFile('', 'd:\\test\\test2.txt', '', 'd:\\test\\test3.txt');
|
||
|
||
return 1;
|
||
```
|
||
|
||
###### Decrypt
|
||
|
||
###### DecryptFile
|
||
|
||
##### TCipher 使用说明以及范例
|
||
|
||
TCipher 类所支持的加密算法是基于数据块的对称加密算法。在使用类进行处理前,首先应设置 Mode 属性,指定算法种类。
|
||
|
||
对称加密算法加密和解密使用相同的密钥(key)和初始化向量(IV)。初始化向量的作用在于:TCipher 提供的多数加密算法为了提高加密强度,在密文的块与块之间实现了一定的关联,初始化向量为第一块设定初始关联,如果初始化向量不正确,数据会出现错误。不同算法的密钥和初始化向量的长度是不同的,TCipher 提供了 KeyLength 和 IVLength 可以取得密钥和初始化向量的长度。在加密和解密前可以通过 Key 和 IV 属性设置密钥和初始化向量,因为 key 和 IV 都是二进制的,因此应使用 hex 字符串进行设置:
|
||
|
||
```text
|
||
cipher_obj:=CreateObject('TCipher', 2); //使用DES_CBC算法
|
||
|
||
//测试使用key和IV进行加密
|
||
|
||
key8:='0102030405060708';
|
||
|
||
iv8:='FFFFFFFFFFFFFFFF';
|
||
|
||
cipher_obj.key:=key8;
|
||
|
||
cipher_obj.iv:=iv8;
|
||
```
|
||
|
||
因为 key 和 IV 是二进制的,而且在有的算法中较长,在某些应用场景中不便于读取和记忆。TCipher 还提供了 Password 属性。通过 Password 属性可以方便地设置 key 和 IV,TCipher 类会根据设置的 Password 字符串,通过哈希算法计算出一个 key 和 IV,这样加解密的双方就可以用一个 Password 实现加密和解密了。示例:
|
||
|
||
```text
|
||
filename:='d:\\a.txt;
|
||
|
||
size:=filesize("",filename); //获取文件大小
|
||
|
||
ReadFile(rwraw(),"",filename,0,size,file_str);
|
||
|
||
//对称加密算法类
|
||
|
||
cipher_obj:=CreateObject('TCipher', 2); //使用DES_CBC算法
|
||
|
||
cipher_obj.Password:='Tinysoft'; //设定密码
|
||
|
||
des_cbc_str:=cipher_obj.Encrypt(file_str);//加密字符串
|
||
|
||
orig_des_cbc:=cipher_obj.Decrypt(des_cbc_str);//解密字符串
|
||
```
|
||
|
||
文件加解密过程中 src_alias 和 dest_alias 参数用于指定文件的目录别名。下面是文件加解密示例(本地执行):
|
||
|
||
```text
|
||
cipher_obj:=CreateObject('TCipher', 2); //使用DES_CBC算法
|
||
|
||
cipher_obj.Password:='Tinysoft'; //设定密码
|
||
|
||
//加密文件
|
||
|
||
cipher_obj.EncryptFile('', 'd:\\test.bmp', '', 'd:\\test.bmp.enc');
|
||
|
||
//解密文件
|
||
|
||
cipher_obj.DecryptFile('', 'd:\\test.bmp.enc', '', 'd:\\test_dec.bmp');
|
||
```
|
||
|
||
#### TStringList 对象
|
||
|
||
##### 内容
|
||
|
||
- TStringList 对象的创建
|
||
- TStringList 对象的属性
|
||
- TStringList 的方法
|
||
- TStringList 对象重载[]算符
|
||
|
||
##### TStringList 对象的创建
|
||
|
||
调用:CreateObject('TStringList')
|
||
|
||
##### TStringList 对象的属性
|
||
|
||
###### 内容
|
||
|
||
- Values
|
||
- StringsW
|
||
- CommaTextW
|
||
- ValueFromIndex
|
||
- TextW
|
||
- GetText
|
||
- GetTextW
|
||
- Capacity
|
||
- CaseSensitive
|
||
- Count
|
||
- Duplicates
|
||
- Sorted
|
||
- Strings
|
||
- CommaText
|
||
- DelimitedText
|
||
- Delimiter
|
||
- Names
|
||
- NameValueSeparator
|
||
- QuoteChar
|
||
- Text
|
||
|
||
###### Values
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.Delimiter:=";";
|
||
|
||
|
||
obj.DelimitedText:='A=ABC;B=123;C=456.;D=abc';
|
||
|
||
|
||
SN:=obj.count;
|
||
|
||
|
||
r:=array();
|
||
|
||
|
||
for i:=0 to SN-1 do
|
||
|
||
|
||
begin
|
||
|
||
|
||
r[i,'name']:=obj.Names(i);//获取name值
|
||
|
||
|
||
r[i,'value']:=obj.values(obj.Names(i));//获取指定name对应的value值
|
||
|
||
|
||
end
|
||
|
||
|
||
return r;
|
||
```
|
||
|
||
//返回:
|
||
|
||
###### StringsW
|
||
|
||
- Values
|
||
- StringsW
|
||
- CommaTextW
|
||
- ValueFromIndex
|
||
- TextW
|
||
- GetText
|
||
- GetTextW
|
||
- Capacity
|
||
- CaseSensitive
|
||
- Count
|
||
- Duplicates
|
||
- Sorted
|
||
- Strings
|
||
- CommaText
|
||
- DelimitedText
|
||
- Delimiter
|
||
- Names
|
||
- NameValueSeparator
|
||
- QuoteChar
|
||
- Text
|
||
|
||
###### CommaTextW
|
||
|
||
- Values
|
||
- StringsW
|
||
- CommaTextW
|
||
- ValueFromIndex
|
||
- TextW
|
||
- GetText
|
||
- GetTextW
|
||
- Capacity
|
||
- CaseSensitive
|
||
- Count
|
||
- Duplicates
|
||
- Sorted
|
||
- Strings
|
||
- CommaText
|
||
- DelimitedText
|
||
- Delimiter
|
||
- Names
|
||
- NameValueSeparator
|
||
- QuoteChar
|
||
- Text
|
||
|
||
###### ValueFromIndex
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.Delimiter:=";";
|
||
|
||
|
||
obj.DelimitedText:='A=ABC;B=123;C=456.;D=abc';
|
||
|
||
|
||
s0:=obj.ValueFromIndex(1);//读取第1个
|
||
|
||
|
||
obj.ValueFromIndex(1):="888"; //写入,即给指定位置的value重新赋值
|
||
|
||
|
||
return array(s0,obj.DelimitedText);
|
||
```
|
||
|
||
//返回结果如下:
|
||
|
||
###### TextW
|
||
|
||
- Values
|
||
- StringsW
|
||
- CommaTextW
|
||
- ValueFromIndex
|
||
- TextW
|
||
- GetText
|
||
- GetTextW
|
||
- Capacity
|
||
- CaseSensitive
|
||
- Count
|
||
- Duplicates
|
||
- Sorted
|
||
- Strings
|
||
- CommaText
|
||
- DelimitedText
|
||
- Delimiter
|
||
- Names
|
||
- NameValueSeparator
|
||
- QuoteChar
|
||
- Text
|
||
|
||
###### GetText
|
||
|
||
- Values
|
||
- StringsW
|
||
- CommaTextW
|
||
- ValueFromIndex
|
||
- TextW
|
||
- GetText
|
||
- GetTextW
|
||
- Capacity
|
||
- CaseSensitive
|
||
- Count
|
||
- Duplicates
|
||
- Sorted
|
||
- Strings
|
||
- CommaText
|
||
- DelimitedText
|
||
- Delimiter
|
||
- Names
|
||
- NameValueSeparator
|
||
- QuoteChar
|
||
- Text
|
||
|
||
###### GetTextW
|
||
|
||
- Values
|
||
- StringsW
|
||
- CommaTextW
|
||
- ValueFromIndex
|
||
- TextW
|
||
- GetText
|
||
- GetTextW
|
||
- Capacity
|
||
- CaseSensitive
|
||
- Count
|
||
- Duplicates
|
||
- Sorted
|
||
- Strings
|
||
- CommaText
|
||
- DelimitedText
|
||
- Delimiter
|
||
- Names
|
||
- NameValueSeparator
|
||
- QuoteChar
|
||
- Text
|
||
|
||
###### Capacity
|
||
|
||
###### CaseSensitive
|
||
|
||
###### Count
|
||
|
||
###### Duplicates
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.Delimiter:=",";
|
||
|
||
|
||
obj.Sorted:=1;//自动排序
|
||
|
||
|
||
obj.Duplicates:=2; //重复串出错
|
||
|
||
|
||
obj.DelimitedText:='A=abc,B=123,C=abc,F=996,E=abd';
|
||
|
||
|
||
obj.Add("b=123");//插入一个重复串
|
||
|
||
|
||
return obj.DelimitedText;
|
||
```
|
||
|
||
执行报错:
|
||
|
||
###### Sorted
|
||
|
||
范例:
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
obj.CommaText:='C=456.,a=abc,E=666,B=123';
|
||
|
||
echo obj.CommaText,"\r\n";
|
||
|
||
obj.Sorted:=1;//设定排序后
|
||
|
||
echo obj.CommaText,"\r\n";
|
||
|
||
return ;
|
||
```
|
||
|
||
打印结果:
|
||
|
||
C=456.,a=abc,E=666,B=123
|
||
|
||
a=abc,B=123,C=456.,E=666
|
||
|
||
差异说明
|
||
排序与系统有关,Linux 中,默认是以 C 为标准,按 ASCII 大小排序或比较大小的(即区分大小写),而 windows 中,按字母顺序进行(即不区分大小写)。
|
||
|
||
例如运行下列代码:
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
obj.CommaText:='C=456.,c=A123,a=abc,A=ABC,E=666,B=123';
|
||
|
||
echo obj.CommaText,"\r\n";
|
||
|
||
obj.Sorted:=1;//设定排序后
|
||
|
||
echo obj.CommaText,"\r\n";
|
||
|
||
return ;
|
||
```
|
||
|
||
在 Windows 中打印的结果为(排序按字母顺序):
|
||
|
||
C=456.,c=A123,a=abc,A=ABC,E=666,B=123
|
||
|
||
a=abc,A=ABC,B=123,C=456.,c=A123,E=666
|
||
|
||
在 Linux 中打印的结果为(按 ASCII 码):
|
||
|
||
C=456.,c=A123,a=abc,A=ABC,E=666,B=123
|
||
|
||
A=ABC,B=123,C=456.,E=666,a=abc,c=A123
|
||
|
||
排序后的顺序是存在差异的。但在同一系统中,每次表现是一定的。
|
||
|
||
###### Strings
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.Delimiter:=";";
|
||
|
||
|
||
obj.DelimitedText:='A=ABC;B=123;C=456.;D=abc';
|
||
|
||
|
||
return obj.strings(1); //读
|
||
```
|
||
|
||
//结果:B=123
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.Delimiter:=";";
|
||
|
||
|
||
obj.DelimitedText:='A=ABC;B=123;C=456.;D=abc';
|
||
|
||
|
||
obj.strings(1):="EF=aaa";//写
|
||
|
||
|
||
return obj.DelimitedText;
|
||
```
|
||
|
||
//结果:A=ABC;EF=aaa;C=456.;D=abc
|
||
|
||
###### CommaText
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.CommaText:='ABC,12,"3,a""bc"';
|
||
|
||
|
||
return array(obj.strings(0),obj.strings(1),obj.strings(2));
|
||
```
|
||
|
||
//返回:
|
||
|
||
###### DelimitedText
|
||
|
||
范例
|
||
|
||
可参考 QuoteChar
|
||
|
||
###### Delimiter
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.Delimiter:=";"; //这一句必须设置在obj.DelimitedText赋值之前
|
||
|
||
|
||
obj.DelimitedText:='ABC,;123,;456.;abc';
|
||
|
||
|
||
SN:=obj.count;
|
||
|
||
|
||
r:=array();
|
||
|
||
|
||
for i:=0 to SN-1 do
|
||
|
||
|
||
r[i]:=obj.strings(i);
|
||
|
||
|
||
return r;
|
||
```
|
||
|
||
//返回:
|
||
|
||
###### Names
|
||
|
||
范例
|
||
|
||
可参考 values
|
||
|
||
###### NameValueSeparator
|
||
|
||
###### QuoteChar
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.QuoteChar:="&";
|
||
|
||
|
||
obj.Delimiter:=";";
|
||
|
||
|
||
obj.DelimitedText:='&AB;C,&;123,;456.;abc';
|
||
|
||
|
||
SN:=obj.count;
|
||
|
||
|
||
r:=array();
|
||
|
||
|
||
for i:=0 to SN-1 do
|
||
|
||
|
||
r[i]:=obj.strings(i);
|
||
|
||
|
||
return r;
|
||
```
|
||
|
||
返回结果如下:第一个串中,存在分割符;,需要用指定的引用符&将当前完整的串引用起来。
|
||
|
||
###### Text
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.NameValueSeparator:=" ";//空格为间隔符
|
||
|
||
|
||
obj.Text:='A a
|
||
|
||
|
||
B b
|
||
|
||
|
||
C c
|
||
|
||
|
||
D d
|
||
|
||
|
||
';
|
||
|
||
|
||
SN:=obj.count;
|
||
|
||
|
||
r:=array();
|
||
|
||
|
||
for i:=0 to SN-1 do
|
||
|
||
|
||
begin
|
||
|
||
|
||
r[i,'n']:=obj.Names(i);
|
||
|
||
|
||
r[i,'v']:=obj.values(obj.Names(i));
|
||
|
||
|
||
end
|
||
|
||
|
||
return r;
|
||
```
|
||
|
||
返回结果:
|
||
|
||
##### TStringList 的方法
|
||
|
||
###### 内容
|
||
|
||
- ExChange
|
||
- Add
|
||
- Clear
|
||
- Delete
|
||
- Find
|
||
- IndexOf
|
||
- Insert
|
||
- Sort
|
||
- AddStrings
|
||
- Append
|
||
- Assign
|
||
- Equals
|
||
- GetText
|
||
- IndexOfName
|
||
- LoadFromFile
|
||
- LoadFromStream
|
||
- Move
|
||
- SaveToFile
|
||
- SaveToStream
|
||
- SetText
|
||
|
||
###### ExChange
|
||
|
||
范例
|
||
|
||
将位置 0 与位置 2 的内容进行互换
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
obj.CommaText:='A=ABC,B=123,C=abc';
|
||
|
||
obj.ExChange(0,2);
|
||
|
||
return obj.CommaText;
|
||
```
|
||
|
||
//返回结果:C=abc,B=123,A=ABC
|
||
|
||
###### Add
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.CommaText:='A=ABC,B=123,C=abc';
|
||
|
||
|
||
index:=obj.Add("X=DDD");
|
||
|
||
|
||
echo index;
|
||
|
||
|
||
sN:=obj.count;
|
||
|
||
|
||
r:=array();
|
||
|
||
|
||
for i:=0 to SN-1 do
|
||
|
||
|
||
begin
|
||
|
||
|
||
r[i,'n']:=obj.Names(i);
|
||
|
||
|
||
r[i,'v']:=obj.values(obj.Names(i));
|
||
|
||
|
||
end
|
||
|
||
|
||
return r;
|
||
```
|
||
|
||
其中,index 值为 3,添加后结果为:
|
||
|
||
###### Clear
|
||
|
||
###### Delete
|
||
|
||
###### Find
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.Sorted:=1;
|
||
|
||
|
||
obj.CommaText:='C=456.,D=abc,A=ABC,E=666,F=A123,B=123';
|
||
|
||
|
||
f:=obj.Find("E=666",Index);
|
||
|
||
|
||
if f then return Index;
|
||
|
||
|
||
else return '查找失败';
|
||
```
|
||
|
||
//返回 4
|
||
|
||
###### IndexOf
|
||
|
||
###### Insert
|
||
|
||
###### Sort
|
||
|
||
差异说明
|
||
排序结果与系统的默认排序规则有关,具体可参考: FAQ:Sorted
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
obj.CommaText:='C=456.,a=abc,E=666,B=123';
|
||
|
||
echo obj.CommaText,"\r\n";
|
||
|
||
obj.sort();//设定排序后
|
||
|
||
echo obj.CommaText,"\r\n";
|
||
|
||
return ;
|
||
```
|
||
|
||
打印结果:
|
||
|
||
C=456.,a=abc,E=666,B=123
|
||
|
||
a=abc,B=123,C=456.,E=666
|
||
|
||
###### AddStrings
|
||
|
||
范例
|
||
|
||
```text
|
||
bj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.CommaText:='A=ABC,B=123,C=abc';
|
||
|
||
|
||
obj2:=CreateObject('TStringList');
|
||
|
||
|
||
obj2.CommaText:='A=DDD,G=666';
|
||
|
||
|
||
obj.AddStrings(obj2);
|
||
|
||
|
||
return obj.CommaText;
|
||
```
|
||
|
||
返回结果:"A=ABC,B=123,C=abc,A=DDD,G=666"
|
||
|
||
###### Append
|
||
|
||
###### Assign
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.Delimiter:=";";
|
||
|
||
|
||
obj.DelimitedText:='A=DDD;G=666';
|
||
|
||
|
||
obj2:=CreateObject('TStringList');
|
||
|
||
|
||
obj2.Delimiter:=",";
|
||
|
||
|
||
obj2.Assign(obj);//复制
|
||
|
||
|
||
return array(obj2.Delimiter,obj2.DelimitedText);
|
||
```
|
||
|
||
返回结果:array(";","A=DDD;G=666")
|
||
|
||
###### Equals
|
||
|
||
###### GetText
|
||
|
||
###### IndexOfName
|
||
|
||
###### LoadFromFile
|
||
|
||
范例
|
||
|
||
//远端用户需要本地执行这个操作
|
||
|
||
```text
|
||
LJ:="E:\\Test\\Case-save.txt";
|
||
|
||
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.LoadFromFile('',LJ);
|
||
|
||
|
||
return obj.CommaText;
|
||
```
|
||
|
||
返回:
|
||
|
||
A a,B b,C c,D d
|
||
|
||
###### LoadFromStream
|
||
|
||
范例
|
||
|
||
```text
|
||
ws := new TMemoryStream();
|
||
|
||
ws.write("A=aaa",5);
|
||
|
||
ws.position:=0;
|
||
|
||
obj:=CreateObject('TStringList');
|
||
|
||
obj.LoadFromStream(ws);
|
||
|
||
return obj.CommaText;
|
||
```
|
||
|
||
返回结果:A=aaa
|
||
|
||
###### Move
|
||
|
||
###### SaveToFile
|
||
|
||
范例
|
||
|
||
//远端用户需要本地执行这个操作
|
||
|
||
```text
|
||
pathname:= "E:\\Test\\Case-save.txt";
|
||
|
||
obj:=CreateObject('TStringList');
|
||
|
||
obj.Text:=TestStr1();
|
||
|
||
obj.SaveToFile('',pathName);
|
||
```
|
||
|
||
执行后本地生成 txt 文档:
|
||
|
||
###### SaveToStream
|
||
|
||
范例
|
||
|
||
```text
|
||
ws := new TMemoryStream();
|
||
|
||
|
||
obj:=CreateObject('TStringList');
|
||
|
||
|
||
obj.Text:= 'A a
|
||
|
||
|
||
B b
|
||
|
||
|
||
C c
|
||
|
||
|
||
D d
|
||
|
||
|
||
';
|
||
|
||
|
||
obj.SaveToStream(ws);
|
||
|
||
|
||
return ws.size; //返回20
|
||
```
|
||
|
||
###### SetText
|
||
|
||
##### TStringList 对象重载[]算符
|
||
|
||
可通过 TStringList 对象直接[]下标方式访问字符串内容
|
||
|
||
例如:
|
||
|
||
```text
|
||
ts:=new TStringList();
|
||
|
||
ts.CommaText:="aaa,bbb,222,111";
|
||
|
||
echo ts[1]; //数字下标
|
||
|
||
|
||
ts.CommaText:="A=aaa,B=bbb,C=222,D=111";
|
||
|
||
echo ts["B"]; //字符串下标
|
||
```
|
||
|
||
打印结果:
|
||
|
||
bbb
|
||
|
||
bbb
|
||
|
||
#### THashedStringList 对象
|
||
|
||
THashedStringList 对象的使用与 TStringList 完全相同,不同的地方是 THashedStringList 进行了 Hash,所以在检索字符串的时候的效率会比 TStringList 快很多,但是由于要建立 Hash,所以内存占用与插入效率会低于 TStringList。
|
||
|
||
参见:TStringList 对象
|
||
|
||
##### 内容
|
||
|
||
- THashedStringList 对象的创建
|
||
|
||
##### THashedStringList 对象的创建
|
||
|
||
调用:CreateObject('THashedStringList')
|
||
|
||
参见:TStringList 对象
|
||
|
||
#### TStream 对象
|
||
|
||
TStream 类型是 TMemoryStream,THandleStream,TFileStream 对象的父类,本身是一个纯虚对象,不可被直接创建。
|
||
|
||
##### 内容
|
||
|
||
- TStream 的属性
|
||
- TStream 的方法
|
||
|
||
##### TStream 的属性
|
||
|
||
###### 内容
|
||
|
||
- Position
|
||
- Size
|
||
|
||
###### Position
|
||
|
||
指针初始位置从 0 开始,当写入内容后指针会更新,自动指向尾部。
|
||
|
||
如:
|
||
|
||
```text
|
||
obj:=CreateObject("TMemoryStream");
|
||
|
||
echo obj.Position;
|
||
|
||
buffer:="ABC 123";
|
||
|
||
p1:= obj.write(buffer,10);
|
||
|
||
echo obj.Position;
|
||
|
||
p2:= obj.write(buffer,10);
|
||
|
||
echo obj.Position;
|
||
```
|
||
|
||
打印结果为:
|
||
|
||
0
|
||
|
||
10
|
||
|
||
20
|
||
|
||
###### Size
|
||
|
||
##### TStream 的方法
|
||
|
||
###### 内容
|
||
|
||
- CopyFrom
|
||
- Read
|
||
- Seek
|
||
- SetSize
|
||
- Write
|
||
|
||
###### CopyFrom
|
||
|
||
范例:复制一个 TStream 流中的局部内容
|
||
|
||
```text
|
||
obj:=CreateObject("TMemoryStream");
|
||
|
||
buffer:="ABC-123";
|
||
|
||
obj.write(buffer,8);
|
||
|
||
obj.position:=2;//重新指定当前位置
|
||
|
||
obj2:=CreateObject("TMemoryStream");
|
||
|
||
cf:=obj2.CopyFrom(obj,4);//从源流中的位置2起开始复制4个字节的内容
|
||
|
||
buffer:="xxxxxxxxxxxx"; //12个字节
|
||
|
||
obj2.position:=0;
|
||
|
||
obj2.read(buffer,7);//将obj2流的内容读到buffer中
|
||
|
||
return buffer;
|
||
```
|
||
|
||
返回结果为:C-12xxxxxxxx
|
||
|
||
###### Read
|
||
|
||
范例:读流中的内容,注意需要先通过 position 设置起始位置
|
||
|
||
```text
|
||
obj:=CreateObject("TMemoryStream");
|
||
|
||
echo "起始位置:",obj.position;
|
||
|
||
buffer:="ABC-123"; //7个字节
|
||
|
||
obj.Write(buffer,6);//写入6个字节
|
||
|
||
echo "写入后的位置:",obj.position;
|
||
|
||
obj.position:=0;//当前位置重新设置为起始位置
|
||
|
||
buffer:="xxxxxxxxxxxx"; //12个字节
|
||
|
||
obj.read(buffer,7); //将流中的7个字节的内容读到buffer中
|
||
|
||
echo "读取后的位置:",obj.position;
|
||
|
||
return buffer;
|
||
```
|
||
|
||
执行后打印信息:
|
||
|
||
起始位置:0
|
||
|
||
写入后的位置:6
|
||
|
||
读取后的位置:6
|
||
|
||
返回的结果为:ABC-12xxxxxx
|
||
|
||
###### Seek
|
||
|
||
范例 01:从尾部进行移动
|
||
|
||
```text
|
||
obj:=CreateObject("TMemoryStream");
|
||
|
||
buffer:="ABC 123";
|
||
|
||
obj.write(buffer,8);
|
||
|
||
echo "移动前位置:",obj.position;
|
||
|
||
p:= obj.seek(4,2);//从尾部进行移动4个字节
|
||
|
||
echo "移动后位置:",obj.position," 返回的位置:",p;
|
||
|
||
return p;
|
||
```
|
||
|
||
打印的结果如下:
|
||
|
||
移动前位置:8
|
||
|
||
移动后位置:12 返回的位置:12
|
||
|
||
###### SetSize
|
||
|
||
###### Write
|
||
|
||
#### TMemoryStream 对象
|
||
|
||
参见:TStream 对象
|
||
|
||
##### 内容
|
||
|
||
- TMemoryStream 对象的创建
|
||
- TMemoryStream 的方法
|
||
|
||
##### TMemoryStream 对象的创建
|
||
|
||
调用:CreateObject('TMemoryStream')
|
||
|
||
##### TMemoryStream 的方法
|
||
|
||
###### 内容
|
||
|
||
- Clear
|
||
- LoadFromFile
|
||
- LoadFromStream
|
||
- SaveToFile
|
||
- SaveToStream
|
||
|
||
###### Clear
|
||
|
||
###### LoadFromFile
|
||
|
||
范例:加载本地的 txt 的内容,注:该功能是与本地交互,因此,需要在本地执行
|
||
|
||
```text
|
||
LJ:="E:\\test\\TestAAA.txt";
|
||
|
||
obj:=CreateObject("TMemoryStream");
|
||
|
||
obj.position:=0; //设置当前起始位置
|
||
|
||
obj.LoadFromFile("",LJ);//装载指定文件内容
|
||
|
||
buffer:="";
|
||
|
||
SetLength(buffer,10);
|
||
|
||
obj.position:=0;
|
||
|
||
obj.read(buffer,10); //读取前10个节字的内容到buffer中
|
||
|
||
return buffer;
|
||
```
|
||
|
||
返回:Tinysoft h
|
||
|
||
其中,文件 TestAAA.txt 的内容为:
|
||
|
||
###### LoadFromStream
|
||
|
||
范例:
|
||
|
||
```text
|
||
obj:=CreateObject("TMemoryStream");
|
||
|
||
buffer:="ABC-123";
|
||
|
||
obj.write(buffer,8);
|
||
|
||
obj2:=CreateObject("TMemoryStream");
|
||
|
||
cf:= obj2.LoadFromStream(obj);//将obj加载到obj2中
|
||
|
||
buffer:="";
|
||
|
||
SetLength(buffer,8);
|
||
|
||
obj2.position:=0;
|
||
|
||
obj2.read(buffer,8);
|
||
|
||
return buffer;
|
||
```
|
||
|
||
返回:"ABC-123\0"
|
||
|
||
###### SaveToFile
|
||
|
||
范例:将流中的内容存贮到指定的 txt 文件中
|
||
|
||
```text
|
||
LJ:="E:\\test\\TestBBB.txt";
|
||
|
||
obj:=CreateObject("TMemoryStream");
|
||
|
||
obj.position:=0; //设置当前起始位置
|
||
|
||
buffer:="ABC-123";
|
||
|
||
obj.write(buffer,8);
|
||
|
||
obj.savetoFile("",LJ);//保存
|
||
```
|
||
|
||
运行后,本地的 TestBBB.txt 文件如下:
|
||
|
||
###### SaveToStream
|
||
|
||
范例:将实例 obj2 的内容保存到实例 obj 中去
|
||
|
||
```text
|
||
obj:=CreateObject("TMemoryStream");
|
||
|
||
buffer1:="xxxxxxxx";
|
||
|
||
obj.write(buffer1,8);
|
||
|
||
|
||
obj2:=CreateObject("TMemoryStream");
|
||
|
||
buffer:="ABC-123";
|
||
|
||
obj2.write(buffer,7);
|
||
|
||
//obj.position:=0;//改变保存的起始位置
|
||
|
||
cf:= obj2.SaveToStream(obj);//将obj2保存到obj中
|
||
|
||
buffer:="";
|
||
|
||
SetLength(buffer,15);
|
||
|
||
obj.position:=0;
|
||
|
||
obj.read(buffer,15);
|
||
|
||
return buffer;
|
||
```
|
||
|
||
返回:"xxxxxxxxABC-123"
|
||
|
||
#### THandleStream 对象
|
||
|
||
参见:TStream 对象
|
||
|
||
##### 内容
|
||
|
||
- THandleStream 对象的创建
|
||
|
||
##### THandleStream 对象的创建
|
||
|
||
- THandleStream 对象的创建
|
||
|
||
#### TFileStream 对象
|
||
|
||
参见:TStream 对象
|
||
|
||
##### 内容
|
||
|
||
- TFileStream 对象的创建
|
||
|
||
##### TFileStream 对象的创建
|
||
|
||
范例:
|
||
|
||
```text
|
||
FileName:="E:\\Test\\TFileCase01.txt";
|
||
|
||
//-新建一个txt文件并打开
|
||
|
||
obj:= CreateObject("TFileStream","",FileName,65535);
|
||
|
||
buffer:="ABC 123";
|
||
|
||
p:= obj.write(buffer,7); //写入
|
||
|
||
//-读取
|
||
|
||
b:="";
|
||
|
||
SetLength(b,7);
|
||
|
||
obj.Position:=0; //必须设置起始位置,否则失败
|
||
|
||
obj.Read(b,7);
|
||
|
||
return b;
|
||
```
|
||
|
||
返回字符串:ABC 123
|
||
|
||
#### TIniFile 对象
|
||
|
||
##### 内容
|
||
|
||
- TIniFile 的创建
|
||
- TIniFile 的方法
|
||
|
||
##### TIniFile 的创建
|
||
|
||
调用:CreateObject('TIniFile',Alias,FileName:string)
|
||
|
||
参数:
|
||
|
||
Alias:字符串类型,目录别名。
|
||
|
||
FileName:字符串类型,INI 文件名。
|
||
|
||
##### TIniFile 的方法
|
||
|
||
###### 内容
|
||
|
||
- SectionExists
|
||
- ReadString
|
||
- WriteString
|
||
- ReadInteger
|
||
- WriteInteger
|
||
- ReadBoolean
|
||
- WriteBoolean
|
||
- ReadBinaryStream
|
||
- WriteBinaryStream
|
||
- ReadDate
|
||
- WriteDate
|
||
- ReadDateTime
|
||
- WriteDateTime
|
||
- ReadFloat
|
||
- WriteFloat
|
||
- ReadSection
|
||
- ReadSectionValues
|
||
- ReadSections
|
||
- EraseSection
|
||
- DeleteKey
|
||
- ValueExists
|
||
|
||
###### SectionExists
|
||
|
||
###### ReadString
|
||
|
||
###### WriteString
|
||
|
||
###### ReadInteger
|
||
|
||
###### WriteInteger
|
||
|
||
###### ReadBoolean
|
||
|
||
###### WriteBoolean
|
||
|
||
###### ReadBinaryStream
|
||
|
||
###### WriteBinaryStream
|
||
|
||
###### ReadDate
|
||
|
||
###### WriteDate
|
||
|
||
###### ReadDateTime
|
||
|
||
###### WriteDateTime
|
||
|
||
###### ReadFloat
|
||
|
||
###### WriteFloat
|
||
|
||
###### ReadSection
|
||
|
||
###### ReadSectionValues
|
||
|
||
###### ReadSections
|
||
|
||
###### EraseSection
|
||
|
||
###### DeleteKey
|
||
|
||
###### ValueExists
|
||
|
||
#### TMemIniFile 对象
|
||
|
||
参考:TIniFile 对象,TIniFile 的方法对 TmemIniFile 同样适用。
|
||
|
||
##### 内容
|
||
|
||
- TMemIniFile 的创建
|
||
- TMemIniFile 的方法
|
||
- TMemIniFile 的属性
|
||
|
||
##### TMemIniFile 的创建
|
||
|
||
范例
|
||
|
||
```text
|
||
//创建TMemIniFile对象
|
||
|
||
obj:= CreateObject("TMemIniFile");
|
||
|
||
//设置内容
|
||
|
||
sLobj:=new tstringlist();
|
||
|
||
sLobj.LoadFromFile("","D:\\Test\\File.ini");
|
||
|
||
obj.SetStrings(sLobj);
|
||
|
||
//进行其他操作
|
||
|
||
...
|
||
```
|
||
|
||
##### TMemIniFile 的方法
|
||
|
||
###### 内容
|
||
|
||
- Clear
|
||
- GetStrings
|
||
- SetStrings
|
||
|
||
###### Clear
|
||
|
||
范例
|
||
|
||
ini 文件内容如下:
|
||
|
||
[Test]
|
||
|
||
string=TinySoft
|
||
|
||
[ReadStream]
|
||
|
||
array=0a021f35
|
||
|
||
string=4265376941725678666a3871
|
||
|
||
```text
|
||
//创建TMemIniFile对象
|
||
|
||
obj:= CreateObject("TMemIniFile");
|
||
|
||
//设置内容
|
||
|
||
sLobj:=new tstringlist();
|
||
|
||
sLobj.LoadFromFile("","D:\\Test\\File.ini");
|
||
|
||
obj.SetStrings(sLobj);
|
||
|
||
//清空设置的内容
|
||
|
||
obj.clear();
|
||
|
||
//获取设置好的内容
|
||
|
||
getObj:=new TStringList();
|
||
|
||
obj.GetStrings(getObj);
|
||
|
||
return getObj.GetText();
|
||
```
|
||
|
||
结果:""
|
||
|
||
###### GetStrings
|
||
|
||
范例
|
||
|
||
ini 文件内容如下:
|
||
|
||
[Test]
|
||
|
||
string=TinySoft
|
||
|
||
[ReadStream]
|
||
|
||
array=0a021f35
|
||
|
||
string=4265376941725678666a3871
|
||
|
||
```text
|
||
//创建TMemIniFile对象
|
||
|
||
obj:= CreateObject("TMemIniFile");
|
||
|
||
//设置内容
|
||
|
||
sLobj:=new tstringlist();
|
||
|
||
sLobj.LoadFromFile("","D:\\Test\\File.ini");
|
||
|
||
obj.SetStrings(sLobj);
|
||
|
||
//获取设置好的内容
|
||
|
||
getObj:=new TStringList();
|
||
|
||
obj.GetStrings(getObj);
|
||
|
||
return getObj.GetText();
|
||
```
|
||
|
||
结果:
|
||
|
||
###### SetStrings
|
||
|
||
范例
|
||
|
||
ini 文件内容如下:
|
||
|
||
[Test]
|
||
|
||
string=TinySoft
|
||
|
||
[ReadStream]
|
||
|
||
array=0a021f35
|
||
|
||
string=4265376941725678666a3871
|
||
|
||
```text
|
||
//创建TMemIniFile对象
|
||
|
||
obj:= CreateObject("TMemIniFile");
|
||
|
||
//设置内容
|
||
|
||
sLobj:=new tstringlist();
|
||
|
||
sLobj.LoadFromFile("","D:\\Test\\File.ini");
|
||
|
||
obj.SetStrings(sLobj);
|
||
|
||
//获取设置好的内容
|
||
|
||
getObj:=new TStringList();
|
||
|
||
obj.GetStrings(getObj);
|
||
|
||
return getObj.GetText();
|
||
```
|
||
|
||
结果:
|
||
|
||
##### TMemIniFile 的属性
|
||
|
||
###### 内容
|
||
|
||
- CaseSensitive
|
||
|
||
###### CaseSensitive
|
||
|
||
范例
|
||
|
||
ini 文件内容如下:
|
||
|
||
[Test]
|
||
|
||
string=TinySoft
|
||
|
||
[ReadStream]
|
||
|
||
array=0a021f35
|
||
|
||
string=4265376941725678666a3871
|
||
|
||
```text
|
||
//创建TMemIniFile对象
|
||
|
||
obj := CreateObject("TMemIniFile");
|
||
|
||
//设置大小写相关
|
||
|
||
obj.CaseSensitive := 1;
|
||
|
||
//设置内容
|
||
|
||
sLobj := new tstringlist();
|
||
|
||
sLobj.LoadFromFile("","D:\\Test\\File.ini");
|
||
|
||
obj.SetStrings(sLobj);
|
||
|
||
//获取设置好的内容
|
||
|
||
t1 := obj.ReadString("Test","string",""); //大小写一致
|
||
|
||
t2 := obj.ReadString("test","string",""); //大小写不一致
|
||
|
||
return array(t1,t2);
|
||
```
|
||
|
||
结果:
|
||
|
||
#### TRegistryIniFile 对象
|
||
|
||
参考:TIniFile 对象
|
||
|
||
##### 内容
|
||
|
||
- TRegistryIniFile 的创建
|
||
|
||
##### TRegistryIniFile 的创建
|
||
|
||
- TRegistryIniFile 的创建
|
||
|
||
#### TWebResponse 对象
|
||
|
||
TWebResponse 是对 Delphi 的兼容对象,TSL 语言本身提供了函数化的输出以及头设置的方法,但是用 TWebResponse 可以方便熟悉 Delphi 开发的人员。
|
||
|
||
##### 内容
|
||
|
||
- TWebResponse 的创建
|
||
- TWebResponse 的属性
|
||
- TWebResponse 的方法
|
||
|
||
##### TWebResponse 的创建
|
||
|
||
调用:CreateObject('TWebResponse')
|
||
|
||
##### TWebResponse 的属性
|
||
|
||
###### 内容
|
||
|
||
- Allow
|
||
- ContentStream
|
||
- ContentEncoding
|
||
- ContentLength
|
||
- ContentType
|
||
- ContentVersion
|
||
- Cookies
|
||
- CustomHeaders
|
||
- Date
|
||
- DerivedFrom
|
||
- Expires
|
||
- HttpRequest
|
||
- LastModified
|
||
- Location
|
||
- LogMessage
|
||
- Realm
|
||
- ReasonString
|
||
- Server
|
||
- StatusCode
|
||
- Title
|
||
- Version
|
||
- WWWAuthenticate
|
||
|
||
###### Allow
|
||
|
||
###### ContentStream
|
||
|
||
###### ContentEncoding
|
||
|
||
###### ContentLength
|
||
|
||
###### ContentType
|
||
|
||
###### ContentVersion
|
||
|
||
###### Cookies
|
||
|
||
参考 TCookieCollection 对象
|
||
|
||
###### CustomHeaders
|
||
|
||
###### Date
|
||
|
||
###### DerivedFrom
|
||
|
||
###### Expires
|
||
|
||
###### HttpRequest
|
||
|
||
###### LastModified
|
||
|
||
###### Location
|
||
|
||
###### LogMessage
|
||
|
||
###### Realm
|
||
|
||
###### ReasonString
|
||
|
||
###### Server
|
||
|
||
###### StatusCode
|
||
|
||
###### Title
|
||
|
||
###### Version
|
||
|
||
- Allow
|
||
- ContentStream
|
||
- ContentEncoding
|
||
- ContentLength
|
||
- ContentType
|
||
- ContentVersion
|
||
- Cookies
|
||
- CustomHeaders
|
||
- Date
|
||
- DerivedFrom
|
||
- Expires
|
||
- HttpRequest
|
||
- LastModified
|
||
- Location
|
||
- LogMessage
|
||
- Realm
|
||
- ReasonString
|
||
- Server
|
||
- StatusCode
|
||
- Title
|
||
- Version
|
||
- WWWAuthenticate
|
||
|
||
###### WWWAuthenticate
|
||
|
||
##### TWebResponse 的方法
|
||
|
||
###### 内容
|
||
|
||
- GetCustomHeader
|
||
- SendRedirect
|
||
- SendResponse
|
||
- SendStream
|
||
- Sent
|
||
- SetCookieField
|
||
- SetCustomHeader
|
||
|
||
###### GetCustomHeader
|
||
|
||
###### SendRedirect
|
||
|
||
###### SendResponse
|
||
|
||
###### SendStream
|
||
|
||
###### Sent
|
||
|
||
###### SetCookieField
|
||
|
||
###### SetCustomHeader
|
||
|
||
#### TWebRequest 对象
|
||
|
||
TWebRequest 是对 Delphi 的兼容对象,TSL 语言本身提供了函数化的获得请求信息的方法,但是用 TWebRequest 可以方便熟悉 Delphi 开发的人员。
|
||
|
||
##### 内容
|
||
|
||
- TWebRequest 的创建
|
||
- TWebRequest 的属性
|
||
- TWebRequest 的方法
|
||
|
||
##### TWebRequest 的创建
|
||
|
||
调用:CreateObject('TWebRequest')
|
||
|
||
##### TWebRequest 的属性
|
||
|
||
###### 内容
|
||
|
||
- Accept
|
||
- Authorization
|
||
- CacheControl
|
||
- Connection
|
||
- Content
|
||
- ContentEncoding
|
||
- ContentFields
|
||
- ContentLength
|
||
- ContentType
|
||
- ContentVersion
|
||
- Cookie
|
||
- CookieFields
|
||
- Date
|
||
- DerivedFrom
|
||
- Expires
|
||
- From
|
||
- Host
|
||
- IfModifiedSince
|
||
- InternalPathInfo
|
||
- InternalScriptName
|
||
- Method
|
||
- MethodType
|
||
- PathInfo
|
||
- PathTranslated
|
||
- ProtocolVersion
|
||
- Query
|
||
- QueryFields
|
||
- Referer
|
||
- RemoteAddr
|
||
- RemoteHost
|
||
- ScriptName
|
||
- ServerPort
|
||
- Title
|
||
- Url
|
||
- UserAgent
|
||
|
||
###### Accept
|
||
|
||
###### Authorization
|
||
|
||
###### CacheControl
|
||
|
||
###### Connection
|
||
|
||
###### Content
|
||
|
||
###### ContentEncoding
|
||
|
||
###### ContentFields
|
||
|
||
###### ContentLength
|
||
|
||
###### ContentType
|
||
|
||
###### ContentVersion
|
||
|
||
###### Cookie
|
||
|
||
###### CookieFields
|
||
|
||
###### Date
|
||
|
||
###### DerivedFrom
|
||
|
||
###### Expires
|
||
|
||
###### From
|
||
|
||
###### Host
|
||
|
||
###### IfModifiedSince
|
||
|
||
###### InternalPathInfo
|
||
|
||
###### InternalScriptName
|
||
|
||
###### Method
|
||
|
||
###### MethodType
|
||
|
||
###### PathInfo
|
||
|
||
- Accept
|
||
- Authorization
|
||
- CacheControl
|
||
- Connection
|
||
- Content
|
||
- ContentEncoding
|
||
- ContentFields
|
||
- ContentLength
|
||
- ContentType
|
||
- ContentVersion
|
||
- Cookie
|
||
- CookieFields
|
||
- Date
|
||
- DerivedFrom
|
||
- Expires
|
||
- From
|
||
- Host
|
||
- IfModifiedSince
|
||
- InternalPathInfo
|
||
- InternalScriptName
|
||
- Method
|
||
- MethodType
|
||
- PathInfo
|
||
- PathTranslated
|
||
- ProtocolVersion
|
||
- Query
|
||
- QueryFields
|
||
- Referer
|
||
- RemoteAddr
|
||
- RemoteHost
|
||
- ScriptName
|
||
- ServerPort
|
||
- Title
|
||
- Url
|
||
- UserAgent
|
||
|
||
###### PathTranslated
|
||
|
||
###### ProtocolVersion
|
||
|
||
###### Query
|
||
|
||
###### QueryFields
|
||
|
||
###### Referer
|
||
|
||
###### RemoteAddr
|
||
|
||
###### RemoteHost
|
||
|
||
###### ScriptName
|
||
|
||
- Accept
|
||
- Authorization
|
||
- CacheControl
|
||
- Connection
|
||
- Content
|
||
- ContentEncoding
|
||
- ContentFields
|
||
- ContentLength
|
||
- ContentType
|
||
- ContentVersion
|
||
- Cookie
|
||
- CookieFields
|
||
- Date
|
||
- DerivedFrom
|
||
- Expires
|
||
- From
|
||
- Host
|
||
- IfModifiedSince
|
||
- InternalPathInfo
|
||
- InternalScriptName
|
||
- Method
|
||
- MethodType
|
||
- PathInfo
|
||
- PathTranslated
|
||
- ProtocolVersion
|
||
- Query
|
||
- QueryFields
|
||
- Referer
|
||
- RemoteAddr
|
||
- RemoteHost
|
||
- ScriptName
|
||
- ServerPort
|
||
- Title
|
||
- Url
|
||
- UserAgent
|
||
|
||
###### ServerPort
|
||
|
||
###### Title
|
||
|
||
###### Url
|
||
|
||
###### UserAgent
|
||
|
||
##### TWebRequest 的方法
|
||
|
||
###### 内容
|
||
|
||
- ReadClient
|
||
- WriteClient
|
||
- ReadString
|
||
- WriteString
|
||
- WriteHeaders
|
||
- ExtractContentFields
|
||
- ExtractCookieFields
|
||
- ExtractQueryFields
|
||
- GetFieldByName
|
||
- TranslateURI
|
||
|
||
###### ReadClient
|
||
|
||
###### WriteClient
|
||
|
||
###### ReadString
|
||
|
||
###### WriteString
|
||
|
||
###### WriteHeaders
|
||
|
||
###### ExtractContentFields
|
||
|
||
###### ExtractCookieFields
|
||
|
||
###### ExtractQueryFields
|
||
|
||
###### GetFieldByName
|
||
|
||
###### TranslateURI
|
||
|
||
#### TCookieCollection 对象
|
||
|
||
TCookieCollection 不能直接创建,该对象从 TWebResponse 实例中通过 Cookies 属性获得。
|
||
|
||
参见:TWebResponse 对象,TCookie 对象
|
||
|
||
##### 内容
|
||
|
||
- TCookieCollection 的方法
|
||
- TCookieCollection 的属性
|
||
|
||
##### TCookieCollection 的方法
|
||
|
||
###### 内容
|
||
|
||
- Add
|
||
- Clear
|
||
|
||
###### Add
|
||
|
||
参考 TCookie 对象
|
||
|
||
###### Clear
|
||
|
||
##### TCookieCollection 的属性
|
||
|
||
###### 内容
|
||
|
||
- Count
|
||
- Items
|
||
- WebResponse
|
||
|
||
###### Count
|
||
|
||
###### Items
|
||
|
||
参考 TCookie 对象
|
||
|
||
###### WebResponse
|
||
|
||
参考 TWebResponse 对象
|
||
|
||
#### TCookie 对象
|
||
|
||
##### 内容
|
||
|
||
- TCookie 的属性
|
||
- TCookie 的方法
|
||
|
||
##### TCookie 的属性
|
||
|
||
###### 内容
|
||
|
||
- Domain
|
||
- Expires
|
||
- Name
|
||
- Path
|
||
- Secure
|
||
- Value
|
||
|
||
###### Domain
|
||
|
||
###### Expires
|
||
|
||
###### Name
|
||
|
||
###### Path
|
||
|
||
###### Secure
|
||
|
||
###### Value
|
||
|
||
##### TCookie 的方法
|
||
|
||
###### 内容
|
||
|
||
- HeaderValue
|
||
- Assign
|
||
- AssignTo
|
||
|
||
###### HeaderValue
|
||
|
||
###### Assign
|
||
|
||
###### AssignTo
|
||
|
||
#### TSessionMan 对象
|
||
|
||
Session 管理器,可以用来在 WEB 服务器端存贮信息,例如存贮用户的登录状态。
|
||
|
||
参见:TSession 对象
|
||
|
||
##### 内容
|
||
|
||
- TSessionMan 的创建
|
||
- TSessionMan 的方法
|
||
|
||
##### TSessionMan 的创建
|
||
|
||
TSessionMan 对象的创建方法:CreateObject("TSessionMan");
|
||
|
||
##### TSessionMan 的方法
|
||
|
||
###### 内容
|
||
|
||
- NewSession
|
||
- GetSession
|
||
- DeleteSession
|
||
- OnlineUser
|
||
- OnlineSession
|
||
|
||
###### NewSession
|
||
|
||
参考 TSession 对象
|
||
|
||
###### GetSession
|
||
|
||
参考 TSession 对象
|
||
|
||
###### DeleteSession
|
||
|
||
参考 TSession 对象
|
||
|
||
###### OnlineUser
|
||
|
||
###### OnlineSession
|
||
|
||
#### TSession 对象
|
||
|
||
TSession 对象用于管理一个会话的数据存贮,由 TSessionMan 对象来创建,用来在 WEB 端存贮用户的信息。TSession 对象由 TMemIniFile 派生而来,所以 TMemIniFile 的方法和属性 TSession 也都支持。
|
||
|
||
参见:TSessionMan 对象,TMemIniFile 对象
|
||
|
||
##### 内容
|
||
|
||
- TSession 的属性
|
||
|
||
##### TSession 的属性
|
||
|
||
参见:TMemIniFile 对象
|
||
|
||
###### 内容
|
||
|
||
- LastActive
|
||
- Refs
|
||
- LiveSeconds
|
||
- UserId
|
||
- SessionId
|
||
|
||
###### LastActive
|
||
|
||
###### Refs
|
||
|
||
###### LiveSeconds
|
||
|
||
###### UserId
|
||
|
||
###### SessionId
|
||
|
||
#### SMTP 对象
|
||
|
||
说明:邮件发送对象,可派出出子类。
|
||
|
||
##### 内容
|
||
|
||
- SMTP 对象的创建
|
||
- SMTP 对象的方法
|
||
- SMTP 对象属性
|
||
|
||
##### SMTP 对象的创建
|
||
|
||
范例
|
||
|
||
```text
|
||
//范例1:创建smtp对象
|
||
|
||
Obj:= CreateObject("SMTP");
|
||
|
||
//范例2:根据配置创建smtp对象,配置写在\tinysoft\analyse.net\plugin\fileMgr.ini 文件
|
||
|
||
{ [Smtp Settings]
|
||
|
||
test:Port=25
|
||
|
||
test:UserName=name
|
||
|
||
test:Password=password
|
||
|
||
test=smtp.tinysoft.com.cn
|
||
|
||
}
|
||
|
||
obj:= CreateObject("smtp","test") ;
|
||
|
||
echo obj.Authenticate();//验证账号密码是否正确。
|
||
|
||
return 1;
|
||
```
|
||
|
||
##### SMTP 对象的方法
|
||
|
||
###### 内容
|
||
|
||
- Login
|
||
- SendCmd
|
||
- Connect
|
||
- Disconnect
|
||
- DisconnectNotifyPeer
|
||
- Send
|
||
- Authenticate
|
||
- QuickSend
|
||
- Expand
|
||
- Verify
|
||
|
||
###### Login
|
||
|
||
###### SendCmd
|
||
|
||
范例
|
||
|
||
```text
|
||
//发送HELO命令。
|
||
|
||
obj:= CreateObject("smtp") ;
|
||
|
||
obj.Host := 'smtp.tinysoft.com.cn' ;
|
||
|
||
obj.connect();
|
||
|
||
obj.sendcmd("HELO smtp.tinysoft.com.cn\r\n",r,c);
|
||
|
||
return r;
|
||
|
||
//结果:665518 Hello smtp.tinysoft.com.cn [ip], pleased to meet you.
|
||
```
|
||
|
||
###### Connect
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:= CreateObject("smtp") ;
|
||
|
||
|
||
obj.Host := 'smtp.tinysoft.com.cn' ;
|
||
|
||
|
||
obj.connect();
|
||
|
||
|
||
return 1;
|
||
```
|
||
|
||
###### Disconnect
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:= CreateObject("smtp") ;
|
||
|
||
|
||
obj.Host := 'smtp.tinysoft.com.cn' ;
|
||
|
||
|
||
obj.connect();
|
||
|
||
|
||
obj.disconnect();
|
||
|
||
|
||
return 1;
|
||
```
|
||
|
||
###### DisconnectNotifyPeer
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:= CreateObject("smtp") ;
|
||
|
||
|
||
obj.Host := 'smtp.tinysoft.com.cn' ;
|
||
|
||
|
||
obj.connect();
|
||
|
||
|
||
obj.DisconnectNotifyPeer();
|
||
|
||
|
||
return 1;
|
||
```
|
||
|
||
###### Send
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:= CreateObject("smtp") ;
|
||
|
||
|
||
obj.UserName := 'username' ; //邮箱账号
|
||
|
||
|
||
obj.Password := 'password'; //邮箱密码
|
||
|
||
|
||
obj.Host := 'smtp.tinysoft.com.cn' ; //smtp地址
|
||
|
||
|
||
obj.port:=25; //端口
|
||
|
||
|
||
obj.connect();
|
||
|
||
|
||
//设置mailmsg对象
|
||
|
||
|
||
msg := CreateObject("MailMsg");
|
||
|
||
|
||
msg.subject := "SendMailTest"; //邮件标题
|
||
|
||
|
||
msg.body := "test"; //邮件内容
|
||
|
||
|
||
msg.Sender := "username@tinysoft.com.cn"; //邮件发送人邮箱
|
||
|
||
|
||
msg.Recipients :=" Recipients @qq.com";//邮件接收人邮箱
|
||
|
||
|
||
try
|
||
|
||
|
||
obj.send(msg);
|
||
|
||
|
||
except
|
||
|
||
|
||
echo '\r\n邮件错误信息',obj.LastCmdResult();
|
||
|
||
|
||
return echo '\r\n邮件发送失败:',ExceptObject.errinfo;
|
||
|
||
|
||
end;
|
||
|
||
|
||
return 1;
|
||
```
|
||
|
||
参考 MailMsg 对象
|
||
|
||
###### Authenticate
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:= CreateObject("smtp") ;
|
||
|
||
|
||
obj.UserName := 'username' ; //邮箱账号
|
||
|
||
|
||
obj.Password := 'password'; //密码
|
||
|
||
|
||
obj.Host := 'smtp.tinysoft.com.cn' ;
|
||
|
||
|
||
obj.port:=25;
|
||
|
||
|
||
obj.connect();
|
||
|
||
|
||
return obj.Authenticate();//结果:1
|
||
```
|
||
|
||
###### QuickSend
|
||
|
||
范例
|
||
|
||
```text
|
||
obj := CreateObject("smtp");
|
||
|
||
obj.UserName := 'username'; //邮箱账号
|
||
|
||
obj.Password := 'password'; //邮箱密码
|
||
|
||
obj.Host := 'smtp.tinysoft.com.cn'; //smtp地址
|
||
|
||
obj.port := 25; //端口
|
||
|
||
obj.connect();
|
||
|
||
try
|
||
|
||
mailHost:='smtp.tinysoft.com.cn'; //邮件服务器地址
|
||
|
||
mailSubject:="SendMailTest"; //邮件标题
|
||
|
||
mailBody := "test"; //邮件内容
|
||
|
||
mailSender := "username@tinysoft.com.cn"; //邮件发送人邮箱
|
||
|
||
mailRecipients := " Recipients@qq.com"; //邮件接收人邮箱
|
||
|
||
obj.QuickSend(mailHost,mailSubject,mailRecipients,mailSender,mailBody);
|
||
|
||
except
|
||
|
||
echo '\r\n邮件错误信息',obj.LastCmdResult();
|
||
|
||
return echo '\r\n邮件发送失败:',ExceptObject.errinfo;
|
||
|
||
end;
|
||
|
||
return 1;
|
||
```
|
||
|
||
###### Expand
|
||
|
||
###### Verify
|
||
|
||
范例
|
||
|
||
```text
|
||
obj:= CreateObject("smtp","test") ;
|
||
|
||
|
||
obj.Host := 'smtp.tinysoft.com.cn' ;
|
||
|
||
|
||
obj.port:=25;
|
||
|
||
|
||
try
|
||
|
||
|
||
username:="username@tinysoft.com.cn";
|
||
|
||
|
||
return obj.verify(username);
|
||
|
||
|
||
except
|
||
|
||
|
||
return echo ExceptObject.errinfo;
|
||
|
||
|
||
end;
|
||
|
||
|
||
//结果:username < username@tinysoft.com.cn>
|
||
```
|
||
|
||
##### SMTP 对象属性
|
||
|
||
###### 内容
|
||
|
||
- AuthType
|
||
- Host
|
||
- Port
|
||
- Username
|
||
- Password
|
||
- UseTLS
|
||
- LastCmdResult
|
||
- LastCmdResultCode
|
||
- DidAuthenticate
|
||
|
||
###### AuthType
|
||
|
||
###### Host
|
||
|
||
###### Port
|
||
|
||
###### Username
|
||
|
||
###### Password
|
||
|
||
###### UseTLS
|
||
|
||
###### LastCmdResult
|
||
|
||
###### LastCmdResultCode
|
||
|
||
###### DidAuthenticate
|
||
|
||
#### Pop3 对象
|
||
|
||
说明:Pop3 邮件处理对象。可派出出子类
|
||
|
||
##### 内容
|
||
|
||
- Pop3 对象的创建
|
||
- Pop3 对象的方法
|
||
- Pop3 对象属性
|
||
|
||
##### Pop3 对象的创建
|
||
|
||
范例
|
||
|
||
```text
|
||
//范例1:创建pop3对象
|
||
|
||
Obj:= CreateObject('POP3');
|
||
|
||
//范例2:根据配置创建pop3对象并自动连接登录,配置写在\tinysoft\analyse.net\plugin\fileMgr.ini 文件
|
||
|
||
{
|
||
|
||
[CLASS:POP3]
|
||
|
||
permit=local
|
||
|
||
[POP3 Settings]
|
||
|
||
test:Port=110
|
||
|
||
test:UserName=name
|
||
|
||
test:Password=password
|
||
|
||
test=pop3.tinysoft.com.cn
|
||
|
||
}
|
||
|
||
obj:= CreateObject("POP3","test","name","password") ;
|
||
|
||
echo obj.CheckMessages();//若创建成功,则打印邮件数量
|
||
|
||
return 1;
|
||
```
|
||
|
||
##### Pop3 对象的方法
|
||
|
||
使用范例:
|
||
|
||
```text
|
||
ret:=CreateObject('PoP3','POP3.TINYSOFT.COM.CN',uName,passWord);
|
||
|
||
ret.UIDL(ids); //取服务器的邮件唯一标示列表存放在ids中
|
||
|
||
s:= str2array(ids,'\r\n');
|
||
|
||
ss:=array();
|
||
|
||
for i:=0 to length(s)-2 do
|
||
|
||
ss[i]:=str2array(s[i],' ');
|
||
|
||
ss[:,0]:=strtoint(ss[:,0]);
|
||
|
||
MsgID:=ss[3,0];//以第三个邮件为例
|
||
|
||
ret.Top(MsgID,r,10); //指定邮件内容前N行
|
||
|
||
echo '取邮件的前N行内容:',r[length(r)-40:];
|
||
|
||
d:=ret.RetrieveMsgSize(MsgID);//邮件大小
|
||
|
||
echo '邮件大小:',d;
|
||
|
||
d1:=ret.RetrieveMailBoxSize();//邮箱大小
|
||
|
||
echo '邮箱大小:',d1;
|
||
|
||
r1:=ret.Retrieve(MsgID,lr); //返回结果为MailMSg类型
|
||
|
||
echo '取邮件内容:',r1,' ',lr;
|
||
|
||
echo tostn(ReturnMailMsg(lr));
|
||
|
||
r2:=ret.RetrieveHeader(MsgID,hr);//返回结果为MailMSg类型
|
||
|
||
echo '取邮件头部信息:',r2,' ',hr;
|
||
|
||
echo tostn(ReturnMailMsg(hr));
|
||
|
||
r3:=ret.RetrieveHeader(MsgID,yr); //返回结果为MailMSg类型
|
||
|
||
echo '取邮件的原始内容:',r3,' ',yr;
|
||
|
||
echo tostn(ReturnMailMsg(yr));
|
||
|
||
ss:=ret.CAPA();
|
||
|
||
echo '取服务器的支持命令列表:',ss;
|
||
|
||
return ss;
|
||
```
|
||
|
||
打印的信息截图:(只展示部分信息)
|
||
|
||
###### 内容
|
||
|
||
- Login
|
||
- SendCmd
|
||
- Connect
|
||
- Disconnect
|
||
- DisconnectNotifyPeer
|
||
- CheckMessages
|
||
- KeepAlive
|
||
- Reset
|
||
- Delete
|
||
- Top
|
||
- RetrieveMsgSize
|
||
- RetrieveMailBoxSize
|
||
- Retrieve
|
||
- RetrieveHeader
|
||
- RetrieveRaw
|
||
- UIDL
|
||
- CAPA
|
||
|
||
###### Login
|
||
|
||
###### SendCmd
|
||
|
||
范例
|
||
|
||
```text
|
||
ret:=CreateObject('PoP3','POP3.TINYSOFT.COM.CN',uName,password);
|
||
|
||
r:=ret.SendCmd('UIDL 1',cr,rc);//获取指定邮件的唯一标识
|
||
|
||
return array(r,cr,rc);
|
||
```
|
||
|
||
返回:
|
||
|
||
###### Connect
|
||
|
||
范例
|
||
|
||
```text
|
||
ret:=CreateObject('Pop3');
|
||
|
||
|
||
//通过属性设置后再连接
|
||
|
||
|
||
ret.Username:=uName;
|
||
|
||
|
||
ret.Password:=passWord;
|
||
|
||
|
||
ret.Host:='POP3.TINYSOFT.COM.CN';
|
||
|
||
|
||
ret.Port:=110;
|
||
|
||
|
||
ret.UseTLS:=0;
|
||
|
||
|
||
ret.Connect(); //连接邮箱服务器
|
||
|
||
|
||
return ret.CheckMessages();
|
||
```
|
||
|
||
返回:
|
||
|
||
406
|
||
|
||
###### Disconnect
|
||
|
||
###### DisconnectNotifyPeer
|
||
|
||
###### CheckMessages
|
||
|
||
范例
|
||
|
||
```text
|
||
//登陆并返回邮箱中邮件数量
|
||
|
||
ret:=CreateObject('PoP3','POP3.TINYSOFT.COM.CN',uname,password);
|
||
|
||
return ret.CheckMessages();//返回整数
|
||
```
|
||
|
||
###### KeepAlive
|
||
|
||
###### Reset
|
||
|
||
###### Delete
|
||
|
||
###### Top
|
||
|
||
范例
|
||
|
||
获取指定邮件前 3 行内容
|
||
|
||
```text
|
||
//创建pop3对象
|
||
|
||
pop3Obj := new pop3("pop3.tinysoft.com.cn","username","password");
|
||
|
||
ret := pop3Obj.Top(1,msg,3);
|
||
|
||
if ret then return msg;
|
||
|
||
else return "获取指定邮件前3行内容失败!";
|
||
```
|
||
|
||
//结果:
|
||
|
||
###### RetrieveMsgSize
|
||
|
||
范例
|
||
|
||
获取指定邮件大小
|
||
|
||
```text
|
||
//创建pop3对象
|
||
|
||
pop3Obj := new pop3("pop3.tinysoft.com.cn","username","password");
|
||
|
||
return pop3Obj.RetrieveMsgSize(1);
|
||
```
|
||
|
||
//结果:18
|
||
|
||
###### RetrieveMailBoxSize
|
||
|
||
范例
|
||
|
||
获取邮箱大小
|
||
|
||
```text
|
||
//创建pop3对象
|
||
|
||
pop3Obj := new pop3("pop3.tinysoft.com.cn","username","password");
|
||
|
||
return pop3Obj.RetrieveMailBoxSize();
|
||
```
|
||
|
||
###### Retrieve
|
||
|
||
范例 01:获取指定邮件内容
|
||
|
||
```text
|
||
//创建pop3对象
|
||
|
||
pop3Obj := new pop3("pop3.tinysoft.com.cn","username","password");
|
||
|
||
ret := pop3Obj.Retrieve(1,msg);
|
||
|
||
if ret then return msg.asstring;
|
||
|
||
else return "获取指定邮件内容失败!";
|
||
```
|
||
|
||
//结果:
|
||
|
||
###### RetrieveHeader
|
||
|
||
范例 01:获取指定邮件头部信息
|
||
|
||
```text
|
||
//创建pop3对象
|
||
|
||
pop3Obj := new pop3("pop3.tinysoft.com.cn","username","password");
|
||
|
||
ret := pop3Obj.RetrieveHeader(1,msg);
|
||
|
||
if ret then return msg.asstring;
|
||
|
||
else return "获取指定邮件内容失败!";
|
||
```
|
||
|
||
//结果:
|
||
|
||
###### RetrieveRaw
|
||
|
||
范例 01:获取指定邮件的原始内容
|
||
|
||
```text
|
||
//创建pop3对象
|
||
|
||
pop3Obj := new pop3("pop3.tinysoft.com.cn","username","password");
|
||
|
||
ret := pop3Obj.RetrieveRaw(1,msg);
|
||
|
||
if ret then return msg;
|
||
|
||
else return "获取指定邮件内容失败!";
|
||
```
|
||
|
||
//结果:
|
||
|
||
###### UIDL
|
||
|
||
范例
|
||
|
||
```text
|
||
ret:=CreateObject('PoP3','POP3.TINYSOFT.COM.CN',uname,password);
|
||
|
||
|
||
ret.UIDL(ids); //取服务器的邮件唯一标示列表存放在ids中
|
||
|
||
|
||
return ids;
|
||
```
|
||
|
||
返回:
|
||
|
||
(部分结果)
|
||
|
||
1 20220715095212230A
|
||
|
||
2 20220715142439001C
|
||
|
||
3 20220715151305015D
|
||
|
||
4 20220715182243051E
|
||
|
||
5 202207180708290CF7
|
||
|
||
6 20220718094652103B
|
||
|
||
7 20220718100236108E
|
||
|
||
8 2022071810050110AE
|
||
|
||
…
|
||
|
||
###### CAPA
|
||
|
||
范例
|
||
|
||
获取邮件支持的所有命令
|
||
|
||
```text
|
||
//创建pop3对象
|
||
|
||
pop3Obj := new pop3("pop3.tinysoft.com.cn","username","password");
|
||
|
||
return := pop3Obj.CAPA();
|
||
```
|
||
|
||
//结果:
|
||
|
||
##### Pop3 对象属性
|
||
|
||
###### 内容
|
||
|
||
- AuthType
|
||
- Host
|
||
- Port
|
||
- Username
|
||
- Password
|
||
- UseTLS
|
||
- LastCmdResult
|
||
- LastCmdResultCode
|
||
- Capabilities
|
||
- HasCAPA
|
||
- HasAPOP
|
||
- AutoLogin
|
||
|
||
###### AuthType
|
||
|
||
###### Host
|
||
|
||
###### Port
|
||
|
||
###### Username
|
||
|
||
###### Password
|
||
|
||
###### UseTLS
|
||
|
||
###### LastCmdResult
|
||
|
||
###### LastCmdResultCode
|
||
|
||
###### Capabilities
|
||
|
||
###### HasCAPA
|
||
|
||
###### HasAPOP
|
||
|
||
###### AutoLogin
|
||
|
||
#### MailMsg 对象
|
||
|
||
邮件消息对象,用来 POP3 对象接收邮件或者 SMTP 对象发送邮件。辅助类,不能派出子类。
|
||
|
||
##### 内容
|
||
|
||
- MailMsg 对象的创建
|
||
- MailMsg 对象的方法
|
||
- MailMsg 对象属性
|
||
|
||
##### MailMsg 对象的创建
|
||
|
||
调用:CreateObject('MailMsg')
|
||
|
||
##### MailMsg 对象的方法
|
||
|
||
###### 内容
|
||
|
||
- AddText
|
||
- SendCmd
|
||
- SaveToFile
|
||
- LoadFromFile
|
||
- SaveToStream
|
||
- LoadFromStream
|
||
- MessagePart
|
||
- AddAttachment
|
||
|
||
###### AddText
|
||
|
||
参考 MessagePart 对象
|
||
|
||
###### SendCmd
|
||
|
||
###### SaveToFile
|
||
|
||
###### LoadFromFile
|
||
|
||
###### SaveToStream
|
||
|
||
###### LoadFromStream
|
||
|
||
###### MessagePart
|
||
|
||
参考 MessagePart 对象
|
||
|
||
###### AddAttachment
|
||
|
||
参考 MessagePart 对象
|
||
|
||
##### MailMsg 对象属性
|
||
|
||
###### 内容
|
||
|
||
- Flags
|
||
- IsEncoded
|
||
- MsgID
|
||
- Headers
|
||
- UID
|
||
- IsMsgSinglePartMime
|
||
- AttachmentEncoding
|
||
- Body
|
||
- BccList
|
||
- CCList
|
||
- CharSet
|
||
- ContentType
|
||
- ContentTransferEncoding
|
||
- ContentDisposition
|
||
- Date
|
||
- Encoding
|
||
- ExtraHeaders
|
||
- FromList
|
||
- From
|
||
- NewsGroups
|
||
- NoEncode
|
||
- NoDecode
|
||
- Organization
|
||
- Priority
|
||
- ReceiptRecipient
|
||
- Recipients
|
||
- References
|
||
- InReplyTo
|
||
- ReplyTo
|
||
- Subject
|
||
- Sender
|
||
- UseNowForDate
|
||
- LastGeneratedHeaders
|
||
- ConvertPreamble
|
||
- ExceptionOnBlockedAttachments
|
||
- AttachmentTempDirectory
|
||
- MessagePartsCount
|
||
- AsString
|
||
- AsBinary
|
||
|
||
###### Flags
|
||
|
||
###### IsEncoded
|
||
|
||
###### MsgID
|
||
|
||
###### Headers
|
||
|
||
###### UID
|
||
|
||
###### IsMsgSinglePartMime
|
||
|
||
###### AttachmentEncoding
|
||
|
||
###### Body
|
||
|
||
###### BccList
|
||
|
||
###### CCList
|
||
|
||
- Flags
|
||
- IsEncoded
|
||
- MsgID
|
||
- Headers
|
||
- UID
|
||
- IsMsgSinglePartMime
|
||
- AttachmentEncoding
|
||
- Body
|
||
- BccList
|
||
- CCList
|
||
- CharSet
|
||
- ContentType
|
||
- ContentTransferEncoding
|
||
- ContentDisposition
|
||
- Date
|
||
- Encoding
|
||
- ExtraHeaders
|
||
- FromList
|
||
- From
|
||
- NewsGroups
|
||
- NoEncode
|
||
- NoDecode
|
||
- Organization
|
||
- Priority
|
||
- ReceiptRecipient
|
||
- Recipients
|
||
- References
|
||
- InReplyTo
|
||
- ReplyTo
|
||
- Subject
|
||
- Sender
|
||
- UseNowForDate
|
||
- LastGeneratedHeaders
|
||
- ConvertPreamble
|
||
- ExceptionOnBlockedAttachments
|
||
- AttachmentTempDirectory
|
||
- MessagePartsCount
|
||
- AsString
|
||
- AsBinary
|
||
|
||
###### CharSet
|
||
|
||
###### ContentType
|
||
|
||
###### ContentTransferEncoding
|
||
|
||
###### ContentDisposition
|
||
|
||
###### Date
|
||
|
||
###### Encoding
|
||
|
||
- Flags
|
||
- IsEncoded
|
||
- MsgID
|
||
- Headers
|
||
- UID
|
||
- IsMsgSinglePartMime
|
||
- AttachmentEncoding
|
||
- Body
|
||
- BccList
|
||
- CCList
|
||
- CharSet
|
||
- ContentType
|
||
- ContentTransferEncoding
|
||
- ContentDisposition
|
||
- Date
|
||
- Encoding
|
||
- ExtraHeaders
|
||
- FromList
|
||
- From
|
||
- NewsGroups
|
||
- NoEncode
|
||
- NoDecode
|
||
- Organization
|
||
- Priority
|
||
- ReceiptRecipient
|
||
- Recipients
|
||
- References
|
||
- InReplyTo
|
||
- ReplyTo
|
||
- Subject
|
||
- Sender
|
||
- UseNowForDate
|
||
- LastGeneratedHeaders
|
||
- ConvertPreamble
|
||
- ExceptionOnBlockedAttachments
|
||
- AttachmentTempDirectory
|
||
- MessagePartsCount
|
||
- AsString
|
||
- AsBinary
|
||
|
||
###### ExtraHeaders
|
||
|
||
###### FromList
|
||
|
||
###### From
|
||
|
||
- Flags
|
||
- IsEncoded
|
||
- MsgID
|
||
- Headers
|
||
- UID
|
||
- IsMsgSinglePartMime
|
||
- AttachmentEncoding
|
||
- Body
|
||
- BccList
|
||
- CCList
|
||
- CharSet
|
||
- ContentType
|
||
- ContentTransferEncoding
|
||
- ContentDisposition
|
||
- Date
|
||
- Encoding
|
||
- ExtraHeaders
|
||
- FromList
|
||
- From
|
||
- NewsGroups
|
||
- NoEncode
|
||
- NoDecode
|
||
- Organization
|
||
- Priority
|
||
- ReceiptRecipient
|
||
- Recipients
|
||
- References
|
||
- InReplyTo
|
||
- ReplyTo
|
||
- Subject
|
||
- Sender
|
||
- UseNowForDate
|
||
- LastGeneratedHeaders
|
||
- ConvertPreamble
|
||
- ExceptionOnBlockedAttachments
|
||
- AttachmentTempDirectory
|
||
- MessagePartsCount
|
||
- AsString
|
||
- AsBinary
|
||
|
||
###### NewsGroups
|
||
|
||
###### NoEncode
|
||
|
||
###### NoDecode
|
||
|
||
###### Organization
|
||
|
||
###### Priority
|
||
|
||
###### ReceiptRecipient
|
||
|
||
###### Recipients
|
||
|
||
###### References
|
||
|
||
###### InReplyTo
|
||
|
||
###### ReplyTo
|
||
|
||
- Flags
|
||
- IsEncoded
|
||
- MsgID
|
||
- Headers
|
||
- UID
|
||
- IsMsgSinglePartMime
|
||
- AttachmentEncoding
|
||
- Body
|
||
- BccList
|
||
- CCList
|
||
- CharSet
|
||
- ContentType
|
||
- ContentTransferEncoding
|
||
- ContentDisposition
|
||
- Date
|
||
- Encoding
|
||
- ExtraHeaders
|
||
- FromList
|
||
- From
|
||
- NewsGroups
|
||
- NoEncode
|
||
- NoDecode
|
||
- Organization
|
||
- Priority
|
||
- ReceiptRecipient
|
||
- Recipients
|
||
- References
|
||
- InReplyTo
|
||
- ReplyTo
|
||
- Subject
|
||
- Sender
|
||
- UseNowForDate
|
||
- LastGeneratedHeaders
|
||
- ConvertPreamble
|
||
- ExceptionOnBlockedAttachments
|
||
- AttachmentTempDirectory
|
||
- MessagePartsCount
|
||
- AsString
|
||
- AsBinary
|
||
|
||
###### Subject
|
||
|
||
###### Sender
|
||
|
||
###### UseNowForDate
|
||
|
||
###### LastGeneratedHeaders
|
||
|
||
###### ConvertPreamble
|
||
|
||
###### ExceptionOnBlockedAttachments
|
||
|
||
###### AttachmentTempDirectory
|
||
|
||
###### MessagePartsCount
|
||
|
||
###### AsString
|
||
|
||
###### AsBinary
|
||
|
||
#### MessagePart 对象
|
||
|
||
MesssagePart 是从属于 MailMsg 对象的消息部分。辅助类,不能派出子类。
|
||
|
||
##### 内容
|
||
|
||
- MessagePart 对象的创建
|
||
- MessagePart 对象的方法
|
||
- MessagePart 对象属性
|
||
|
||
##### MessagePart 对象的创建
|
||
|
||
调用:CreateObject('MessagePart')。
|
||
|
||
注:一般 MessagePart 无需主动创建,而是由 POP3 或者 NNTP 对象接收的 MailMsg 对象里自动创建,或者在 MailMsg 里调用 AddAttachment、AddText 方法来产生。
|
||
|
||
##### MessagePart 对象的方法
|
||
|
||
###### 内容
|
||
|
||
- SaveToFile
|
||
- LoadFromFile
|
||
- SaveToStream
|
||
- LoadFromStream
|
||
|
||
###### SaveToFile
|
||
|
||
###### LoadFromFile
|
||
|
||
###### SaveToStream
|
||
|
||
###### LoadFromStream
|
||
|
||
##### MessagePart 对象属性
|
||
|
||
###### 内容
|
||
|
||
- ContentType
|
||
- IsEncoded
|
||
- MsgID
|
||
- Headers
|
||
- CharSet
|
||
- ExtraHeaders
|
||
- ContentTransfer
|
||
- ContentID
|
||
- ContentDescription
|
||
- ContentLocation
|
||
- ParentPart
|
||
- PartType
|
||
- FileName
|
||
- Body
|
||
- AsString
|
||
- AsBinary
|
||
|
||
###### ContentType
|
||
|
||
###### IsEncoded
|
||
|
||
###### MsgID
|
||
|
||
###### Headers
|
||
|
||
###### CharSet
|
||
|
||
###### ExtraHeaders
|
||
|
||
###### ContentTransfer
|
||
|
||
###### ContentID
|
||
|
||
###### ContentDescription
|
||
|
||
###### ContentLocation
|
||
|
||
###### ParentPart
|
||
|
||
###### PartType
|
||
|
||
###### FileName
|
||
|
||
###### Body
|
||
|
||
###### AsString
|
||
|
||
###### AsBinary
|