使用RemObjects Pascal Script

來源:互聯網
上載者:User

標籤:byte   ssm   常量   tom   ica   pex   path   進階特性   addm   

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"

使用RemObjects Pascal Script (轉)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.