使用RemObjects Pascal Script

使用RemObjects Pascal Script摘自 RemObjectsWi 本文提供 RemObjectsPa 的整体概要并演示如何创建一些简单的脚本 PascalScript 包括两个不同部分 编译器 uPSCompiler pas 运行时 uPSRuntime pas

 

摘自RemObjects Wiki

本文提供RemObjects Pascal Script的整体概要并演示如何创建一些简单的脚本.

Pascal Script包括两个不同部分:

  • 编译器 (uPSCompiler.pas)
  • 运行时 (uPSRuntime.pas)

两部分彼此独立.可以分开使用,或通过TPSScript 控件使用他们,这个控件定义在uPSComponent.pas单元,对这两个部分进行简易封装.

要使用控件版本的Pascal Script,首先要将控件放在窗体或data module上,并设置script属性,调用Compile和Execute方法.编译的错误,警告,提示可在CompilerMessages数组属性中获取,同样运行时错误存储在ExecErrorToString属性中.

下面的范例将编译并执行一个空脚本(“begin end.”):

var

  Messages: string;

  compiled: boolean;

begin

  ce.Script.Text := ‘begin end.’;

  Compiled := Ce.Compile;

  for i := 0 to ce.CompilerMessageCount -1 do

    Messages := Messages +

                ce.CompilerMessages[i].MessageToString +

                #13#10;

  if Compiled then

    Messages := Messages + ‘Succesfully compiled’#13#10;

  ShowMessage(‘Compiled Script: ‘#13#10+Messages);

  if Compiled then begin

    if Ce.Execute then

      ShowMessage(‘Succesfully Executed’)

    else

      ShowMessage(‘Error while executing script: ‘+

                  Ce.ExecErrorToString);

  end;

end;

默认情况下,控件只向脚本引擎添加少数几个标准函数(具体函数可从uPSComponents.pas单元顶部获取).

除了标准函数,Pascal Script还包含几个函数库:

使用RemObjects Pascal ScriptTPSDllPlugin

使用RemObjects Pascal ScriptTPSImport_Classes

导入Tobject和Classes单元.

使用RemObjects Pascal ScriptTPSImport_DateUtils

导入date/time相关函数.

使用RemObjects Pascal ScriptTPSImport_ComObj

在脚本中可使用COM对象.

使用RemObjects Pascal ScriptTPSImport_DB

导入db.pas.

使用RemObjects Pascal ScriptTPSImport_Forms

导入Forms及Menus单元.

使用RemObjects Pascal ScriptTPSImport_Controls

导入Controls.pas和Graphics.pas单元.

使用RemObjects Pascal ScriptTPSImport_StdCtrls

导入ExtCtrls和Buttons.

要使用这些库,将相应控件添加到窗体或Data Module中,选择TPSCompiler控件点击plugins属性后的[…]按钮,增加一个新项并设置其Plugin属性为特定的插件控件.除了这些标准库函数,还可以轻松的向脚本引擎添加新函数.为了实现这个目的,首先创建要导出给脚本引擎的函数,例如:

procedure TForm1.ShowNewMessage(const Message: string);

begin

  ShowMessage(‘ShowNewMessage invoked:’#13#10+Message);

end;

然后,实现TPSCompile控件的OnCompile事件,使用AddMethod方法注册实际方法:

procedure TForm1.CECompile(Sender: TPSScript);

begin

  Sender.AddMethod(Self, @TForm1.ShowNewMessage,

                   ‘procedure ShowNewMessage

                   (const Message: string);’);

end;

在脚本中调用方式:

begin

  ShowNewMessage(‘Show This !’);

end.

高级特性

Pascal脚本支持预编译,可以使用{$IFDEF}, {$ELSE}, {$ENDIF}指令,而且可以使用{$I filename.inc}指令将其他文件内容引入脚本中.为了使用这个特性,必须设置UsePreprocessor属性为True,而且MainFileName属性必须与Script属性中的脚本名称相匹配.Defines属性指定预定义指令,在OnNeedFile事件中处理引入其他文件.

function TForm1.ceNeedFile(Sender: TObject;

  const OrginFileName: String;

  var FileName, Output: String): Boolean;

var

  path: string;

  f: TFileStream;

begin

  Path := ExtractFilePath(ParamStr(0)) + FileName;

  try

    F := TFileStream.Create(Path, fmOpenRead or fmShareDenyWrite);

  except

    Result := false;

    exit;

  end;

  try

    SetLength(Output, f.Size);

    f.Read(Output[1], Length(Output));

  finally

  f.Free;

  end;

  Result := True;

end;

当设置了这些属性,CompilerMessages数组属性将输出包含文件的名称.

另外,你可以在Delphi中调用脚本中的函数.下面的代码定义在脚本中:

function TestFunction(Param1: Double; Data: String): Longint;

begin

  ShowNewMessage(‘Param1: ‘+FloatToString(param1)

                 +#13#10+’Data: ‘+Data);

  Result := ;

end;

 

begin

end.

在使用脚本中的函数之前,必须检查函数参数与返回值类型,可在OnVerifyProc事件中进行.

procedure TForm1.CEVerifyProc(Sender: TPSScript;

                              Proc: TPSInternalProcedure;

                              const Decl: String;

                              var Error: Boolean);

begin

  if Proc.Name = ‘TESTFUNCTION’ then begin

    if not ExportCheck(Sender.Comp, Proc,

               [btS32, btDouble, btString], [pmIn, pmIn]) then begin

      Sender.Comp.MakeError(”, ecCustomError, ‘Function header for

      TestFunction does not match.’);

      Error := True;

    end

    else begin

      Error := False;

    end;

  end

  else

    Error := False;

end;

ExportCheck函数检查参数是否匹配.本例中,btu8是boolean (返回值类型), btdouble是第一个参数, btString是第二个参数.[pmIn, pmIn]指示两个参数都是IN参数.要调用这个脚本函数还需要为这个函数创建一个事件声明.

type

  TTestFunction = function (Param1: Double;

                            Data: String): Longint of object;

//…

var

  Meth: TTestFunction;

  Meth := TTestFunction(ce.GetProcMethod(‘TESTFUNCTION’));

  if @Meth = nil then

    raise Exception.Create(‘Unable to call TestFunction’);

  ShowMessage(‘Result: ‘+IntToStr(Meth(pi, DateTimeToStr(Now))));

也可以向脚本引擎中添加变量,使之可在脚本中使用.可在OnExecute事件中调用AddRegisteredVariable函数实现:

procedure TForm1.ceExecute(Sender: TPSScript);

begin

  CE.SetVarToInstance(‘SELF’, Self);

  // ^^^ For class variables

  VSetInt(CE.GetVariable(‘MYVAR’), );

end;

在脚本执行完毕后,读取变量的新值,可在OnAfterExecute事件中调用: VGetInt(CE.GetVariable(‘MYVAR’)).

向脚本引擎注册外部变量,有两个步骤,首先在OnCompile事件中,使用AddRegisteredPTRVariable函数向脚本中添加变量声明.

procedure TMyForm.PSScriptCompile(Sender: TPSScript);

begin

  Sender.AddRegisteredPTRVariable(‘MyClass’, ‘TButton’);

  Sender.AddRegisteredPTRVariable(‘MyVar’, ‘Longint’);

end;

这就将外部变量MyClass和MyVar导入了.其次,在OnExecute事件中将变量与具体指针关联:

procedure TMyForm.PSScriptExecute(Sender: TPSScript);

begin

  PSScript.SetPointerToData(‘MyVar’, @MyVar, PSScript.FindBaseType(bts32));

  PSScript.SetPointerToData(‘Memo1’, @Memo1, PSScript.FindNamedType(‘TMemo’));

end;

这里在脚本中有两种类型变量,基础类型(如下表的简单类型),及类类型.基础类型定义在uPSUtils.pas单元,可使用FindBaseType函数获取.类类型使用FindNamedType按名称获取.在脚本中修改变量将直接影响关联的变量.

基础类型:

btU8

Byte

btS8

Shortint

btU16

Word

btS16

Smallint

btU32

Longword

btS32

Longint

btS64

Int64

btSingle

Single

btDouble

Double

btExtended

Extended

btVariant

Variant

btString

String

btWideString

WideString

btChar

Char

btWideChar

WideChar

基于控件的Pascal脚本也可执行脚本函数.需要使用ExecuteFunction方法.

ShowMessage(CompExec.ExecuteFunction([1234.5678, 4321,

                                      ‘test’],

                                     ‘TestFunction’));

这将执行叫做’TestFunction’的函数,有三个参数,一个float类型,一个integer类型和一个string类型.返回值直接传给ShowMessage.

注意:

  • 为使用一些函数和常量,有必要将uPSCompiler.pas, uPSRuntime.pas和uPSUtils.pas引入到uses中.
  • 脚本引擎不会主动调用Application.ProcessMessages,导致脚本运行时应用程序挂起.为了避免这个问题,可在TPSScript.OnLine事件中调用Application.ProcessMessages.
  • 如果要向脚本引擎导入自定义的类,可以使用/Unit-Importing/目录下的工具生成导入类库.
  • 如果要向脚本脚本引擎导入自定义类,可使用Bin目录下的工具生成导入类库.
  • 如果分开使用compiler和runtime,请见Import和Kylix范例.
  • Debug范例需要控件SynEdit http://synedit.sourceforge.net.

Retrieved from “http://wiki.remobjects.com/wiki/Using_RemObjects_Pascal_Script”

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/212830.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午7:10
下一篇 2026年3月18日 下午7:10


相关推荐

  • IDEA优化设置

    IDEA优化设置IDEA优化设置设置Ctrl+鼠标滑轮动态放大缩小页面文字

    2022年5月21日
    43
  • c语言 switch案例,c语言switch case语句使用例子

    c语言 switch案例,c语言switch case语句使用例子c 语言 switchcase 语句使用例子发布时间 2020 04 2311 48 53 来源 亿速云阅读 421 作者 小新这篇文章主要为大家详细介绍了 c 语言 switchcase 语句使用例子 文中示例代码介绍的非常详细 具有一定的参考价值 感兴趣的小伙伴们可以参考一下 c 语言 switchcase 语句怎么用 C 语言提供了一种用于多分支选择的 switch 语句 其一般形式为 switch 表达式 c

    2026年3月26日
    2
  • input file读取文件

    input file读取文件js读取inputfile文件的两种方式:<divid="localImag"><imgid="preview"src=""width="150"height="180"style="display:block;width:150px;height:180px;"><

    2022年7月17日
    15
  • Java学习代码合集

    Java学习代码合集其实我学习java最根本的原因是:我是一个挺关注外在的人,虽然是个程序员,所以我很喜欢写出那些带有漂亮的界面的程序,因为C总是控制台,我不是很喜欢,在这份java代码合集中,我会记录自己学习Java界面化编程的点点滴滴。更新:因为C/C++是我主要使用语言,所有后来写界面主要用Qt写了,但我java也会继续学的。我只是给想学界面gui的同志一个思路。可以参考这篇文章Qt5计算器的实现可能…

    2022年5月8日
    44
  • 覆盖,交换技术和虚拟存储技术的区别在于_虚拟存储技术的目的

    覆盖,交换技术和虚拟存储技术的区别在于_虚拟存储技术的目的操作系统—覆盖,交换技术和虚拟存储技术的区别

    2026年4月13日
    3
  • Java类加载过程图解

    Java类加载过程图解朋友给我发了一道有意思的题目 如下为什么用 class 的方式加载类和以 Class forName 的方式加载的结果不同呢 原因很简单 就是类加载过程的不同 这就扯到基础理解上了 就是 Java 是如何加载一个类的呢 上图是我绘制的整个 Java 类加载过程 首先是编译期 将 Java 源文件也就是敲好的代码通过编译 转换成 class 文件 也就是字节码文件 byte 然后经过传输传

    2026年3月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号