使用RemObjects Pascal Script (转)

http://www.cnblogs.com/MaxWoods/p/3304954.html

摘自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还包含几个函数库:


TPSDllPlugin


允许脚本使用DLL中的导出函数,语法:
function FindWindow(C1, C2: PChar): Longint; external‘[email protected] stdcall‘;


TPSImport_Classes


导入Tobject和Classes单元.


TPSImport_DateUtils


导入date/time相关函数.


TPSImport_ComObj


在脚本中可使用COM对象.


TPSImport_DB


导入db.pas.


TPSImport_Forms


导入Forms及Menus单元.


TPSImport_Controls


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


TPSImport_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 := 1234567;

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‘), 1234567);

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"

时间: 2024-10-17 21:02:15

使用RemObjects Pascal Script (转)的相关文章

Pascal Script

MsgBox http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_msgbox ExpandConstant http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_expandconstant DelTree http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_deltree Event Functions The

data abstraction下载地址及简单介绍

原文来自龙博方案网http://www.fanganwang.com/product/1321转载请注明出处 Data Abstract是最好的多层次框架,它提供端到端的解决方案,同时也可以很轻松地建立起可扩展的数据库方案以满足如今的分布式系统要求. 概况特性 ·         为.NET,Mono,32/64位的Windows以及Linux建立可扩展的.跨平台的多层次数据库解决方案. ·         使用一个通用的代码库处理不同的数据库设计或数据库系统. ·         使用RAD

.net数据访问层组件Data Abstract 免费下载及使用方法大全

原文来自龙博方案网http://www.fanganwang.com/product/1321.com/转载请注明出处 Data Abstract是最好的多层次框架,它提供端到端的解决方案,同时也可以很轻松地建立起可扩展的数据库方案以满足如今的分布式系统要求. 概况特性 ·         为.NET,Mono,32/64位的Windows以及Linux建立可扩展的.跨平台的多层次数据库解决方案. ·         使用一个通用的代码库处理不同的数据库设计或数据库系统. ·         使

Pascal编译器大全(非常难得)

http://www.pascaland.org/pascall.htm Some titles (french) : Compilateurs Pascal avec sources = compiler with sourcesComposants pour Delphi = Components for DelphiCompilateurs pour autres langages avec sources en pascal = Compilers for other languages

Delphi资源大全

A curated list of awesome Delphi frameworks, libraries, resources, and shiny things. Inspired by awesome-... stuff. Note that only open-source projects are considered. Dead projects are mainly ignored except for those which do not have alive analogs.

atitit.元编程总结 o99

atitit.元编程总结 o99.doc 1. 元编程(Metaprogramming) 1 2. 元编程的历史and发展 1 3. 元类型and元数据 1 4. 元编程实现方式 2 4.1. 代码生成 2 4.2. lex和yacc分析器 2 4.3. 泛型编程 2 4.4. 注解 2 4.5. 解释型框架 2 4.6. 对象工厂概念,一个会写程序的程序! 3 4.7. Aop 3 4.8. 数据对象触发器和 可配置的插入式服务 3 5. 应用场景 4 6. 参考 4 1. 元编程(Meta 

Add GUI to connect to SQL

(*********************************************************************************) (* *) (* Below is the list of support classes that can be used from within the Pascal *) (* script. There are also three support objects available: MainForm of type *

20 Inno Setup制作安装包的几个问题

系统开发好之后,通常需要制作成安装包,才能卖给用户.利用Inno Setup的向导可以制作简单的安装包,但是如果要做个好的安装包的话可能会遇到一些麻烦,今日终于抽空解决了,Inno Setup打包的一些问题.具体如下: 1. 卸载时,如何判断应用程序是否运行    InnoSetup 提供变量AppMutex,用来保存应用程序的Mutex名称.现在很多应用程序都是唯一实例运行.这样避免配置文件被错误修改以及其他很多衍生问题.通常都会用WindowsAPI CreateMuex来创建一个Mutex

atitit.提升软件开发的效率and 质量的那些强大概念and方法总结

atitit.提升软件开发的效率and 质量的那些强大概念and方法总结 1. 主流编程中三个最糟糕的问题 1 1.1. 从理解问题后到实现的时间很长 1 1.2. 理解和维护代码  2 1.3. 学习曲线高  2 1.4. 扩展性烂 2 1. Coc 2 2. Dsl 2 3. DSM 3 4. 4gl 3 5. 产生式编程(Generative Programming,GP) 3 5.1. 为重用而开发以及使用重用的开发 3 6. 在模型驱动开发(MDD)介绍MDA 4 7. ·  元编程