playbook/docs/tsl/syntax_book/05_object_model.md

122 KiB
Raw Blame History

05 对象模型class/unit

本章整理 Object TSL 的类、对象、属性、方法与相关语法。

目录

Object TSL

内容

  • 类和对象
  • 类继承和作用域
  • 字段
  • 方法
  • 属性 Property
  • 索引器(index)
  • TSL 对象的创建
  • 类信息
  • IS 关键字
  • 函数信息
  • 算符重载
  • 单元中的类
  • TSL 内置对象使用大全

类和对象

面向对象的概念是相对于面向过程的

面向过程的表现形式是函数,数据以参数、系统参数、全局变量的模式传导进函数

面向对象的表现形式是类,数据以成员变量的方式存贮在类变量中,而具体的功能以成员函数的方式存在

面向对象的最原始的目的在于封装,将数据与多种方法封装在一起

此外,继承、多态等也是面向对象的特性

内容

  • 概述
  • 类类型声明的语法
  • 类类型声明的位置
  • 类的实例化
  • 对象成员的访问

概述

类(或者类类型)定义了一个结构,抽象地,这个结构既可以包括数据,也可以包括行为;

具体地,类可以包括字段、方法和属性;

类的字段、方法和属性被称为它的成员。

类的实例叫做对象;

字段在本质上是一个对象的变量。和记录的字段类似,类的字段表示一个类实例的数据项;

方法是一个函数,它和类相关联。绝大多数方法作用在对象(也就是类的实例)上,其它一些方法(称为类方法)作用在类上面。

属性被看作是访问对象的数据的接口,对象的数据通常用字段来存储。属性可以决定数据如何被读取或修改。属性在被引用的时候就像一个字段,但被实现时候可以是一个方法。

声明了类以后,程序员可以创建作为此类的实例对象。尽管有时类和对象叫法可互换,但它们是不同的概念。类定义对象的类型,但它不是对象本身。对象是基于类的具体实体,有时称为类的实例。

Type MyClass = Class

End;

上面代码声明了一个类类型

Obj:=createObject("MyClass");

上面代码创建了类 MyClass 的实例.

创建类的实例后,将向程序员传递回对该对象的引用。

在前面的示例中obj 是对基于 MyClass 的对象的引用。此引用指向了新对象,但不包含对象数据本身。

类类型声明的语法

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;

完整示例:

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的最外层声明类在执行语句块的前面而不能在过程或函数中声明.

示例:

  program test;

  //声明了一个名称为myClass的类类型

  Type myClass = Class

    //这里可以定义类的成员:字段、方法、属性

  End;

  Begin

    //这里可以初始化并使用上面声明的类类型

    C:=CreateObject("myClass");

  End.

2、在主函数的后便声明示例

  Function abcd();

  Begin

    A:=CreateObject("myClass");

  End;

  Type myClass = Class

  End;

3、在非 Program 开头的 TSL 语句段后。

如:

  …………..

  A:=CreateObject("myClass");

  …………

  Type myClass = Class

  End;

4、也可以在 "TSL 解释器安装目录\funcext" 下面或者在其下的子目录下建立一个同名的.tsf 文件,在文件内部声明一个类类型,文件名和类名必须相同。

如:把 myClass 的类类型放在 myClass.tsf 文件中。这样可以被全局引用。

类的实例化

创建一个类的实例对象,TSL 中提供了两种方式:

方式一:调用 CreateObject 函数进行创建;

CreateObject
(<classname:String|ClassType>[,P1,P2…]):TSLObject

用类名字符串或者用一个类类型来创建一个类的对象,返回新建对象的引用。

方式二:使用 New 关键字方式进行创建:

New
ClassName([P1,P2…]):TSLObject

和 CreateObject 类似,但 ClassName 不再需要是一个字符串,而是直接写出类名即可,在类名后用(),括号里可以加入构造函数的参数。

注意:类名两端的括号不能省略,可使用字符串常量,也可以使用字符串变量。

也可以使用类类型作为对象的构造,类类型可以用 class(classname)以及 findclass 等来获得。

如果要创建类 Person 的实例,写法可以是以下两种方式:

Obj:=CreateObject('person');

obj:=new person();

如果类的构造器有参数,则需要把参数列表一起传给 CreateObject 函数,如给类 Person 的实例构造时指定两个属性:

Obj:=CreateObject('person',"zhangfei",25);

obj:=new person("zhangfei",25);

可以把对象的引用赋值给另外一个变量 Obj2 := Obj1;

这时 Obj2 和 Obj1 指向同一个实例,而不是 2 个实例。

对象成员的访问

成员变量以及方法的访问

操作成员变量以及方法均采用.操作符。

例如:

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 为子类BaseClass1BaseClass2…为 MyClass 的基类或父类。也可以叫祖先类.

子类 MyClass 将获得基类(BaseClass1、BaseClass2、…)的所有非私有数据和行为,此外新类可以为自己定义新的数据和行为进行扩展,也可以重新定义基类中的行为.

示例:

Program test;

//声明类A

Type A = class

  Function F1()

  Begin

    Writeln("call A.F1");

  End;

End;

//声明类 B,继承自 A

Type B =Class(A)

End;


Begin

  //创建B类的实例对象BB

  BB:=CreateObject("B");

BB.F1;

End.

上面代码类 B 通过继承获得类 A 的方法 F1(),自己确不用定义方法 F1();

如果子类的多个基类都有同样的方法,在子类中调用这个方法时需要为这个方法指定具体的父类,方法为在调用的方法前面加上 Class(基类名称).

示例

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.

以上代码演示在类内部调用多个基类相同方法的方法,如果在子类的外部调用这个方法,总是调用基类声明在最前面的类的方法。没有办法调用其他基类的方法,一个技巧是必须在子类中包装这个方法,在外面调用包装的方法。

内容
  • 继承单元类以及成员类
继承单元类以及成员类
Type AA=class(UNITB.CC) //支持单元名.类名模式继承

....

End;

同时也支持子类继承:

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 成员。用这种方法,每个可见性关键字最多出现一次,并且标明了每个新段的开始。所以,一个典型的类声明应该像下面的形式:

type


MyClass =
class
(BaseClass)

private


... { private declarations here}

protected


... { protected declarations here }

public


... { public declarations here }

end
;

示例:

下面的代码详细说明了继承与作用域的关系

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 常量成员

字段简介

字段就像属于对象的一个变量,我们也称之为成员变量,它可以是任何类型。对象用户存放对象的数据。

给类定义字段非常简单,只要把字段的名字在类的声明中列出即可。定义方法:

Type myClass =Class

  Field1;

  Field2;

End;

以上的代码声明了一个 myClass 的类,同时定义了 2 个字段Field1 和 Field2

引用:

1、在类内部的方法直接调用字段名

2、外部调用实例对象.字段名,例如

myObj:=CreateObject("myClass");

myObj.Field1:="This is a Field";

注:

可以为字段指定作用域

static 静态字段

在字段的前边加入 static 前缀,就表明为静态字段也称静态成员变量,静态字段就是全部类实例共用的字段,亦可以不用实例化来进行调用。

与对象实例无关,也就是所有对象实例均共用该变量,类似于一个作用域为该类的全局变量。

范例:

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 常量成员

常量成员定义的值可以是一个常数也可以是常量参与的计算。具体定义与支持的运算符可参考常量及常量成员的定义与初始化

【常量成员定义】

Type C=class


Const
a="Hello"; //可以在声明中进行定义初始化


Const
b=a+"Tinysoft";

 C=a+b+"from TSL";

End;

【使用范围】

1、成员函数使用

2、成员函数缺省参数使用

3、子类使用

4、通过实例访问

5、通过类访问静态常量成员

示例:

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;

调用:

 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 种方法为类添加方法。

在类声明中,可以直接定义方法的声明和实现,

或者只在类中定义方法的声明,在类声明后的某个地方(必须属于同一模块)定义它的实现,实现的时候在方法名称前加“类名.”。这种方法称为为外联,上一种方法称为内联.

示例:

Type myClass =class


Function F1()
;

 Begin

  writeln("内联");

 End;


Function F2()
;

End;

function
myClass.F2
();

Begin

 Writeln("外联");

End;

外联声明时,方法名总是使用类名进行限定,形式为:类名.方法名。在方法的头部必须重新列出类声明时的参数,名称可以与声明时的不同,但是参数的顺序必须完全相同。

内容
  • 内联与外联
  • 静态方法声明和调用
  • 对象的方法调用
内联与外联

如果函数的实现在类体内,叫内联方法。

如果函数的实现在类体外,叫外联方法。

示例:

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,…])

静态方法与静态成员范例

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;

静态方法与静态成员的访问

 class(Thuman).mCount:=100;//将Thuman类的静态字段mCount的值指定为100

 echo class(Thuman).mCount;//输出静态字段mCount的值

 hA:=new Thuman();//创建一个实例

 echo class(Thuman).getCount();//调用静态方法

打印结果:

100

101

对象的方法调用

1、如果被类内部其他的方法调用或子类中的方法调用直接调用方法名就可以了。

2、如果在类的外部被调用需要加上所在类型的对象名对象名.方法名;

如调用 F1()的方法是

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);的模式调用方法,表示调用父类中的该方法,若存在多父类,则按顺序查找,若父类中查找不到,则报错。

例如:

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;

调用:

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 关键字虚函数,告诉编译器允许子类覆盖:

Type BaseClass =class

  Funciton F();
virtual;
//虚方法,允许覆盖

  Begin

  //…

  End;

End

接下来,在子类中将将要覆盖的方法用 override 关键字标记为覆盖了基类的方法。它的参数的顺序(若有的话)必须和基类相同。

Type SubClass =class(BaseClass)

  Funciton F();
override;
//覆盖虚方法,即重写

  Begin

  //…

  End;

End

这样子类的方法 F 就覆盖了基类的方法 F当 SubClass 的实例调用 F 方法时,会执行子类中重新定义的方法。

若需要调用父类被覆盖的方法,可以用 Class(父类).方法来调用

多态

多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,就是同一种事物表现出的多种形态。

编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。

通过继承可以实现多态。父类中调用被覆盖的方法,如果当前对象是子类的实例,那么实际调用的是子类的方法,而非父类的方法。

通过继承,一个类可以用作多种类型:可以用作它自己的类型、任何祖先类型,当把子类型当作祖先类型时,调用被覆盖的方法,实际调用的是子类本身的方法,而非基类型的方法。

示例:

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 方法时:执行的是父类的方法。

  F:=CreateObject("Figure");

  F.DrawAction();//输出 draw Figure

当子类的对象间接用 Draw 方法时:执行的是子类的方法:

  E:=CreateObject("Ellipse");

  E.DrawAction();//输出 draw Ellipse

如果要强制子类调用父类的方法。需要用下面的方式:

Class(BaseClass,SubObject).FunctionName.

上面的事例中,

E:=CreateObject("Ellipse");

Class(Figure,E).Draw()
;

执行的却是父类的 Draw 方法.输出:输出 draw Figure

隐藏

如果在子类中重写父类的方法确没有使用 override 标志符,子类的方法隐藏了基类的方法,而非覆盖。

父类中调用覆盖的方法时,实际执行的是父类的方法。如果当前对象是子类的实例时,执行的还是父类的方法。因为方法在子类型中给隐藏了,而没有被覆盖。

示例:

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并且它们必须有不同的参数列表。

形式为:

Function F();overload;

示例:

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 种方式调用,可以在子类中重载也可以重载父类的方法。

示例:

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 方法,设置为当前日期,否则可以指定具体的年月日

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 所在的类的实例对象。与继承混合使用是需要注意。

示例:

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()即创建一个当前方法所在类的实例对象。

如:

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 开始

类方法用于创建无需创建类的实例就能够访问的方法。类方法可用于分离独立于任何对象标识的行为:无论对象发生什么更改,这些函数都不会随之变化。

形式为:

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、属性可以在派生类中给重新定义.

示例:

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 的索引器的索引值除了支持整数以外,还可以支持字符串。

实例:

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 指定索引的位置

上例中可声明

property idx0 index 0 read rindex  write windex;

表示 idx0 表示专门对索引器中的位置 0 进行对写,也就是对 arr[0]进行操作。

当然,假使有需要,索引也可以使字符串,那样,例如:

property idx0 index "High school" read rindex  write windex;

TSL 对象的创建

内容

  • New
  • CreateObject

New

参考 TSL 内置对象使用大全 CreateObject

CreateObject

参考 TSL 内置对象使用大全 New

类信息

判定一个对象是否是某个类的实例,可以用 is 判断符。

Class(类名)或者 FindClass(类名字符串)可以获得一个类的类型。

CreateObject 支持通过指定类的类型创建实例。

如:

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 没有指向实例对象。

//有类:

Type ClassA=class()

  class function fucA();

  begin

    return "ClassA";

  end;

end;

//调用:

return findclass("ClassA").fucA();

返回ClassA

范例 02将实例对象强制转成指定父类的实例

//有父类:

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返回当前实例对象所属类的定义信息

obj:=createobject("TSBackTesting");

return obj.classinfo();

范例 2返回实例对象所属类的对象类型。

obj:=createobject("TSBackTesting");

oa2:=obj.classinfo(1); //oa2是一个类的类型

obj2:= createobject(oa2); //通过类类型构造一个实例对象

return obj2.fbegt;

objectstate

范例

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

如在给属性的赋值方法中打印这个状态值

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 的时候才会释放。

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 类型。一个子类属于所有它祖先类的类型。

示例:

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

范例

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其代码如下

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获取当前运行环境下所有对象的引用计数信息

//创建对象初始引用个数均为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获取当前运行环境下所有对象信息以及原对象并通过该结果访问其属性、方法

  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

获取函数的信息。返回存放函数信息的字符串下标数组。

下标 数据类型 描述
functionname String 方法名
parameter Array 方法参数
returntype Stirng 函数返回值
returndim Integer 数组的维度,0表示不是数组
calltype Integer 调用类型
classname Stirng 所在的类名

其中parameter 下标所对应的数组也是字符串下标数组。

下标

下标 数据类型 描述
nme String 参数名称
tpe String 参数类型
dm Integer 数组的维度
out Integer

注意:

可以显式为参数或返回值定义类型。当定显式义了类型后以上提到的数据类型将会是自定义定义的值,否则是空字符串,这种用法不会真正做类型检查或转化,只是通知 FunctionInfo 中的数据类型,通常用户 Web service 的构建。

算符重载

TSL 的对象如果要使用算符进行计算,就需要用到算符重载,算符重载可以重载掉 TSL 的算符,在 TSL 的类中要实现算符重载的方法。

算符重载支持 TSL 开发的类,也支持用 C++等开发的二进制类。

内容

  • Operator
  • 算符重载的案例
  • 面向对象的 Operator 重载支持[]
  • 面向对象的 Operator 算符重载支持++,--,+=,-=

Operator

算符重载的案例

下边是一个复数的例子,范例中重载了+和<运算符:

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;

调用测试:

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 开始,依次为 0123....,最后一层时为-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,这样做方便数据库等事务的实现。

例如:单层的实现

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;

调用测试如:

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 类型的应用实例
对象[]重载时允许多级的应用示例

示例:对象中[]算符重载多级的实现示例

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;

调用测试:

  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)等功能的作用

//资金出入的联动实现,行标下只能依次递增,否则报错回滚

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

调用测试:

//--事务示例

  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 算符重载支持++,--,+=,-=

实现示例如:

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;

调用测试:

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 中的类结构

Unit Unit1;

Interface

Type Class1=Class

  Type Class2=Class// 嵌套类

    function MethodInClass2();//方法

    class function ClassMethodInClass2();//类方法

  end;

end;

Initialization

Finalization End.

直接继承 Unit1.Class1.Class2

Type MyNewClass = Class(Unit1.Class1.Class2)

  function MyNewMethod();

end;

创建实例

//方式一CreateObject

obj1:=CreateObject("MyNewClass");

obj1.MethodInClass2();//调用父类方法

//方式二new关键字

obj2:=new MyNewClass();

obj2.MethodInClass2();//调用父类方法

查找类

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 中的类结构

Unit Unit1;

Interface

Type Class1=Class

  Type Class2=Class// 嵌套类

    function MethodInClass2();//方法

    class function ClassMethodInClass2();//类方法

  end;

end;

Initialization

Finalization End.

创建实例

//方式一CreateObject

obj1:=CreateObject("Unit1.Class1.Class2");

obj1.MethodInClass2();//调用方法

//方式二new关键字

obj2:=new Unit1.Class1.Class2();

obj2.MethodInClass2();//调用方法

预定义ParentClassInUnit

判定当前环境是否支持继承和构造单元中的类

{$IFDEF ParentClassInUnit}

return 1;

{$ELSE} //否则(如果未定义)

return "当前环境不支持继承和构造单元中的类";

{$ENDIF}

单元中的类-应用实例

现有日期相关单元 TD_DateUnit单元中包含类 TD_DateClass、IntDate、StrDate。

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.

使用示例

  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 配置并连接登录服务器

  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

  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

范例

  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

范例

  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

范例

  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

范例

  obj := CreateObject("FTP");

  obj.host := "ftp.tinysoft.com.cn";

  obj.port := 20;

  obj.username := username;

  obj.password := password;

  return obj.connect();

  //连接成功返回0
Delete

范例

删除 FTP 服务器指定文件

  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 服务器指定文件的最后修改时间

  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

范例

从服务器下载指定文件至本机

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

范例

查看当前服务器目录下匹配到的文件列表

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

范例

  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

范例

在服务器当前目录中创建新文件夹

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

范例

将本机指定文件上传至服务器

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

范例

从服务器删除指定文件夹

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

范例

范例一:重命名文件夹

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
查看

范例二:重命名文件

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

范例

获取当前所在目录

  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

范例

查看服务器当前目录指定文件大小

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.文本内容->私钥加密->公钥对加密内容解密

filename := 'd:\\a.txt';
size := filesize("",filename);
ReadFile(rwraw(),"",filename,0,size,file_str);//读取文本内容
rsa_obj := CreateObject('TRsa');
rsa_obj.GenerateKey(1024);
rsa_pubkey := rsa_obj.PublicKey;//公钥
rsa_prikey := rsa_obj.PrivateKey;//私钥
rsa_obj_1 := CreateObject('TRsa');
rsa_obj_1.PublicKey := rsa_pubkey;
rsa_pub_enc := rsa_obj_1.PubEncrypt(file_str);//使用公钥加密文本内容
rsa_obj_1.PrivateKey := rsa_prikey;
rsa_pri_dec := rsa_obj_1.PriDecrypt(rsa_pub_enc);//使用私钥解密
rsa_pri_enc := rsa_obj_1.PriEncrypt(file_str);//使用私钥加密文本内容
rsa_obj_1.PublicKey := rsa_pubkey;
rsa_pub_dec := rsa_obj_1.PubDecrypt(rsa_pri_enc);//使用公钥解密
return array(
'文本内容':file_str,
'RSA私钥':rsa_prikey,
'RSA公钥':rsa_pubkey,
'RSA公钥加密':EncodeRadixStr(rsa_pub_enc,'',16),
'RSA私钥解密':rsa_pri_dec,
'RSA私钥加密':EncodeRadixStr(rsa_pri_enc,'',16),
'RSA公钥解密':rsa_pub_dec
);

TCipher

TCipher 类用于多重对称加密算法,其支持的算法有:

mode 算法名 密钥长度(字节) IV长度字节
1 DES_ECB 8 0
2 DEC_CBC 8 8
3 DES_CFB 8 8
4 DES_OFB 8 8
5 IDEA_ECB 16 0
6 IDEA_CBC 16 8
7 IDEA_CFB 16 8
8 IDEA_OFB 16 8
9 AES_128_ECB 16 0
10 AES_128_CBC 16 16
11 AES_128_CFB 16 16
12 AES_128_OFB 16 16
13 AES_192_ECB 24 0
14 AES_192_CBC 24 16
15 AES_192_CFB 24 16
16 AES_192_OFB 24 16
17AES_256_ECB320
18AES_256_CBC3216
19AES_256_CFB3216
20AES_256_OFB3216
内容
  • TCipher 类的属性
  • TCipher 类的方法
  • TCipher 使用说明以及范例
TCipher 类的属性
内容
  • Mode
  • Password
  • Key
  • IV
  • KeyLength
  • LVLength
Mode
Password
Key
IV
KeyLength
LVLength
TCipher 类的方法
内容
  • Encrypt
  • EncryptFile
  • Decrypt
  • DecryptFile
Encrypt
EncryptFile

范例:

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 字符串进行设置:

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 和 IVTCipher 类会根据设置的 Password 字符串,通过哈希算法计算出一个 key 和 IV这样加解密的双方就可以用一个 Password 实现加密和解密了。示例:

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 参数用于指定文件的目录别名。下面是文件加解密示例(本地执行):

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

范例

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

范例

  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

范例

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

范例:

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 中,按字母顺序进行(即不区分大小写)。

例如运行下列代码:

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

范例

obj:=CreateObject('TStringList');


  obj.Delimiter:=";";


  obj.DelimitedText:='A=ABC;B=123;C=456.;D=abc';


  return obj.strings(1); //读

//结果B=123

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

范例

obj:=CreateObject('TStringList');


  obj.CommaText:='ABC,12,"3,a""bc"';


  return array(obj.strings(0),obj.strings(1),obj.strings(2));

//返回:

DelimitedText

范例

可参考 QuoteChar

Delimiter

范例

  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

范例

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

范例

  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 的内容进行互换

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

范例

  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

范例

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

差异说明 排序结果与系统的默认排序规则有关,具体可参考: FAQSorted

范例

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

范例

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

范例

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

范例

//远端用户需要本地执行这个操作

LJ:="E:\\Test\\Case-save.txt";


  obj:=CreateObject('TStringList');


  obj.LoadFromFile('',LJ);


  return obj.CommaText;

返回:

A a,B b,C c,D d

LoadFromStream

范例

  ws := new TMemoryStream();

  ws.write("A=aaa",5);

  ws.position:=0;

  obj:=CreateObject('TStringList');

  obj.LoadFromStream(ws);

  return obj.CommaText;

返回结果A=aaa

Move
SaveToFile

范例

//远端用户需要本地执行这个操作

pathname:= "E:\\Test\\Case-save.txt";

obj:=CreateObject('TStringList');

  obj.Text:=TestStr1();

  obj.SaveToFile('',pathName);

执行后本地生成 txt 文档:

SaveToStream

范例

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 对象直接[]下标方式访问字符串内容

例如:

  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 类型是 TMemoryStreamTHandleStreamTFileStream 对象的父类,本身是一个纯虚对象,不可被直接创建。

内容
  • TStream 的属性
  • TStream 的方法
TStream 的属性
内容
  • Position
  • Size
Position

指针初始位置从 0 开始,当写入内容后指针会更新,自动指向尾部。

如:

  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 流中的局部内容

  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 设置起始位置

  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从尾部进行移动

  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 的内容,注:该功能是与本地交互,因此,需要在本地执行

 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

范例:

 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 文件中

  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 中去

 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 对象的创建

范例:

  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 的创建

范例

//创建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

//创建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

//创建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

//创建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

//创建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
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 对象的创建

范例

//范例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

范例

//发送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

范例

obj:= CreateObject("smtp") ;


obj.Host := 'smtp.tinysoft.com.cn' ;


obj.connect();


return 1;
Disconnect

范例

obj:= CreateObject("smtp") ;


obj.Host := 'smtp.tinysoft.com.cn' ;


obj.connect();


obj.disconnect();


return 1;
DisconnectNotifyPeer

范例

obj:= CreateObject("smtp") ;


obj.Host := 'smtp.tinysoft.com.cn' ;


obj.connect();


obj.DisconnectNotifyPeer();


return 1;
Send

范例

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

范例

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

范例

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

范例

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 对象的创建

范例

//范例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 对象的方法

使用范例:

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

范例

ret:=CreateObject('PoP3','POP3.TINYSOFT.COM.CN',uName,password);

r:=ret.SendCmd('UIDL 1',cr,rc);//获取指定邮件的唯一标识

return array(r,cr,rc);

返回:

Connect

范例

  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

范例

//登陆并返回邮箱中邮件数量

ret:=CreateObject('PoP3','POP3.TINYSOFT.COM.CN',uname,password);

return ret.CheckMessages();//返回整数
KeepAlive
Reset
Delete
Top

范例

获取指定邮件前 3 行内容

//创建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

范例

获取指定邮件大小

//创建pop3对象

pop3Obj := new pop3("pop3.tinysoft.com.cn","username","password");

return pop3Obj.RetrieveMsgSize(1);

//结果18

RetrieveMailBoxSize

范例

获取邮箱大小

//创建pop3对象

pop3Obj := new pop3("pop3.tinysoft.com.cn","username","password");

return pop3Obj.RetrieveMailBoxSize();
Retrieve

范例 01获取指定邮件内容

//创建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获取指定邮件头部信息

//创建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获取指定邮件的原始内容

//创建pop3对象

pop3Obj := new pop3("pop3.tinysoft.com.cn","username","password");

ret := pop3Obj.RetrieveRaw(1,msg);

if ret then return msg;

else return "获取指定邮件内容失败!";

//结果:

UIDL

范例

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

范例

获取邮件支持的所有命令

//创建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