使用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中的导出函数,语法: |
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"
使用RemObjects Pascal Script (转)的更多相关文章
- 使用RemObjects Pascal Script
摘自RemObjects Wiki 本文提供RemObjects Pascal Script的整体概要并演示如何创建一些简单的脚本. Pascal Script包括两个不同部分: 编译器 (uPSCo ...
- 在delphi中嵌入脚本语言--(译)RemObjects Pascal Script使用说明(1)(译)
翻譯這篇文章源於我的一個通用工資計算平台的想法,在工資的計算中,不可避免的需要使用到自定義公式,然而對於自定義公式的實現,我自己想了一些,也在網上搜索了很多,解決辦法大致有以下幾種: 1. 自己寫代碼 ...
- 测试RemObjects Pascal Script
unit Unit1; interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ...
- Inno Setup Pascal Script to search for running process
I am currently trying to do a validation at the uninstall moment. In a Pascal script function, in In ...
- Pascal Script
MsgBox http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_msgbox ExpandConstant http://www.jrs ...
- delphi一些小技巧 从别处看到
开发环境-------- Delphi 7是一个很经典的版本,在Win2000/XP下推荐安装Delphi 7来开发软件,在Vista下推荐使用Delphi 2007开发软件.安装好Delphi ...
- (转载)Delphi开发经验谈
Delphi开发经验谈 开发环境-------- Delphi 7是一个很经典的版本,在Win2000/XP下推荐安装Delphi 7来开发软件,在Vista下推荐使用Delphi 2007开发软件. ...
- Pascal编译器大全(非常难得)
http://www.pascaland.org/pascall.htm Some titles (french) : Compilateurs Pascal avec sources = compi ...
- Delphi 控件大全
delphi 控件大全(确实很全) delphi 控件查询:http://www.torry.net/ http://www.jrsoftware.org Tb97 最有名的工具条(ToolBar ...
随机推荐
- 【leetcode】Find Minimum in Rotated Sorted Array II JAVA实现
一.题目描述 Follow up for "Find Minimum in Rotated Sorted Array":What if duplicates are allowed ...
- npoi z
http://blog.csdn.net/fireghost57/article/details/25623143 http://www.cnblogs.com/jiagoushi/archive/2 ...
- 设置UIImage 圆角
//设置UIImage圆角 @interface UIImage(UIRoundedRectImage) + (id) createRoundedRectImage:(UIImage*)image s ...
- android启动页优化实践
最近观看友盟统计发现App启动页跳出率很高,观看启动页的平均启动时间为2.8s,如下图: 所以一个很现实的问题就出来了,优化启动页面... (一)做了什么? 我们的启动页面主要用于展示启动页面,加载网 ...
- ctype库试运行
from ctypes import * msvcrt=cdll.msvcrt message_string="Hello world!\n" msvcrt.wprintf(&qu ...
- 将数字映射到字母上 .xml
映射成 A1------A20 B1------B20 ... Z1------Z20 这种形式 数字从0开始编 ...
- switch……case不能匹配字符串的方法 .xml
pre{ line-height:1; color:#d1653c; background-color:#000000; font-size:16px;}.sysFunc{color:#566d68; ...
- 从date中获取相应信息
创建测试用表: CREATE OR REPLACE VIEW v AS SELECT TO_DATE('2015-5-5 13:14:15', 'YYYY-MM-DD HH24:MI:SS') AS ...
- Research on Unsupervised Word Alignment Based on Inversion Transduction Grammar
1.提出了一种基于特征函数和反向转录文法(ITG)的无监督词对齐模型,使用对数线性模型对文法规则的概率建模,先验知识可以通过特征函数的形式加入到模型里面,而模型仍然可以进行无监督训练.2. 在模型的参 ...
- 时间日期Date类型
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...