diff --git a/Articles/Using Classes with RemObjects PascalScript/Images_-1C72A37E-60C1-4D71-91D1-844140034A07-.png b/Articles/Using Classes with RemObjects PascalScript/Images_-1C72A37E-60C1-4D71-91D1-844140034A07-.png new file mode 100644 index 0000000..95c26e0 Binary files /dev/null and b/Articles/Using Classes with RemObjects PascalScript/Images_-1C72A37E-60C1-4D71-91D1-844140034A07-.png differ diff --git a/Articles/Using Classes with RemObjects PascalScript/Images_-46D0599E-8750-448E-ACE1-D71968B4EAF9-.png b/Articles/Using Classes with RemObjects PascalScript/Images_-46D0599E-8750-448E-ACE1-D71968B4EAF9-.png new file mode 100644 index 0000000..69b4177 Binary files /dev/null and b/Articles/Using Classes with RemObjects PascalScript/Images_-46D0599E-8750-448E-ACE1-D71968B4EAF9-.png differ diff --git a/Articles/Using Classes with RemObjects PascalScript/Images_-787B7711-2BF3-41AA-8E56-91D63344D5E0-.png b/Articles/Using Classes with RemObjects PascalScript/Images_-787B7711-2BF3-41AA-8E56-91D63344D5E0-.png new file mode 100644 index 0000000..efa3e7a Binary files /dev/null and b/Articles/Using Classes with RemObjects PascalScript/Images_-787B7711-2BF3-41AA-8E56-91D63344D5E0-.png differ diff --git a/Articles/Using Classes with RemObjects PascalScript/Images_-8821D7ED-4999-4343-A0BB-7822BCD292D5-.png b/Articles/Using Classes with RemObjects PascalScript/Images_-8821D7ED-4999-4343-A0BB-7822BCD292D5-.png new file mode 100644 index 0000000..5ac3070 Binary files /dev/null and b/Articles/Using Classes with RemObjects PascalScript/Images_-8821D7ED-4999-4343-A0BB-7822BCD292D5-.png differ diff --git a/Articles/Using Classes with RemObjects PascalScript/Images_-B70E9BCC-4513-4133-A790-DE8246179CAD-.png b/Articles/Using Classes with RemObjects PascalScript/Images_-B70E9BCC-4513-4133-A790-DE8246179CAD-.png new file mode 100644 index 0000000..12d85ca Binary files /dev/null and b/Articles/Using Classes with RemObjects PascalScript/Images_-B70E9BCC-4513-4133-A790-DE8246179CAD-.png differ diff --git a/Articles/Using Classes with RemObjects PascalScript/Images_-E3CBD245-D791-406D-820D-CC1F9C9CA125-.png b/Articles/Using Classes with RemObjects PascalScript/Images_-E3CBD245-D791-406D-820D-CC1F9C9CA125-.png new file mode 100644 index 0000000..61d603a Binary files /dev/null and b/Articles/Using Classes with RemObjects PascalScript/Images_-E3CBD245-D791-406D-820D-CC1F9C9CA125-.png differ diff --git a/Articles/Using Classes with RemObjects PascalScript/Images_-EA8FCBEF-97D4-47B2-8140-74761B71A83F-.png b/Articles/Using Classes with RemObjects PascalScript/Images_-EA8FCBEF-97D4-47B2-8140-74761B71A83F-.png new file mode 100644 index 0000000..db95697 Binary files /dev/null and b/Articles/Using Classes with RemObjects PascalScript/Images_-EA8FCBEF-97D4-47B2-8140-74761B71A83F-.png differ diff --git a/Articles/Using Classes with RemObjects PascalScript/Images_-F65AD44E-8A42-4A47-A9A4-B329D0DF4CD3-.png b/Articles/Using Classes with RemObjects PascalScript/Images_-F65AD44E-8A42-4A47-A9A4-B329D0DF4CD3-.png new file mode 100644 index 0000000..0c06851 Binary files /dev/null and b/Articles/Using Classes with RemObjects PascalScript/Images_-F65AD44E-8A42-4A47-A9A4-B329D0DF4CD3-.png differ diff --git a/Articles/Using Classes with RemObjects PascalScript/Images_-FEAD5D0B-5E5F-48C4-9D4F-AA44EB5FD131-.png b/Articles/Using Classes with RemObjects PascalScript/Images_-FEAD5D0B-5E5F-48C4-9D4F-AA44EB5FD131-.png new file mode 100644 index 0000000..e7320a5 Binary files /dev/null and b/Articles/Using Classes with RemObjects PascalScript/Images_-FEAD5D0B-5E5F-48C4-9D4F-AA44EB5FD131-.png differ diff --git a/Articles/Using Classes with RemObjects PascalScript/index.html b/Articles/Using Classes with RemObjects PascalScript/index.html new file mode 100644 index 0000000..6f863f9 --- /dev/null +++ b/Articles/Using Classes with RemObjects PascalScript/index.html @@ -0,0 +1,54 @@ + + + +Using Classes with RemObjects PascalScript + + +

Using Classes with RemObjects PascalScript

+ +

This article explains how to use existing classes in RemObjects Pascal Script by using a copy of the \Samples\Debug project. The following class has been added to that project: + +

+

 

+

The MyClass file is then opened in the Unit Import tool, which generates units for us:

+

+

Press the"Go" button and add the generated uPSI_MyClass.pas to your +project. Now select the main form and create a handler for its +OnCreate:

+

+

In the Create event, we instantiate a TPSImport_MyClass (i.e. the +class generated by the import tool) and add it to the script engine's + plugin list:

+

+

+ When you are going to use this plugin class from multiple projects, +you can also install it in a package so that it gets installed in the + Component Palette.

+

Now it's possible to use the class from the script engine:

+

+

Using an existing TMyClass in the script engine

+

It's also possible to use existing TMyClass variables from the +script engine. To do this, you add a FMyClass: TMyClass to your form +class and create it:

+

+

In the script engine's OnCompile Event you need to let the engine +know that there is a new variable. There are two ways to do this: +AddRegisteredVariable and AddRegisteredPtrVariable. The difference is + that AddRegisteredPtrVariable will make changes directly to the +variable, so if you free the FMyClass and re-create it, the script +engine will use the new variable. AddRegisteredPTRVariable has two +parameters. A name and a type. Add this code to the script engine's +OnCompile event:

+

+

Now the compiler knows about the variable, but the runtime part of +the script engine doesn't know where the variable is yet. To let the +runtime know, you can use the OnExecute event. The SetPointerToData +method can set the value of a script engine variable added with +AddRegisteredPTRVariable. The first parameter is the variable name, +the second is the address of the variable that contains the instance and + the last parameter contains the required type info for the variable +(generally you use ce.FindNamedType('nameoftype') here).

+

+

The final result is:

+

+ \ No newline at end of file diff --git a/Articles/Using RemObjects Pascal Script/Images_-2BDBA214-FEF1-4A54-AA23-93F70EE217C9-.png b/Articles/Using RemObjects Pascal Script/Images_-2BDBA214-FEF1-4A54-AA23-93F70EE217C9-.png new file mode 100644 index 0000000..3804e85 Binary files /dev/null and b/Articles/Using RemObjects Pascal Script/Images_-2BDBA214-FEF1-4A54-AA23-93F70EE217C9-.png differ diff --git a/Articles/Using RemObjects Pascal Script/Images_-437262DA-CA48-473A-8890-2161A932852F-.png b/Articles/Using RemObjects Pascal Script/Images_-437262DA-CA48-473A-8890-2161A932852F-.png new file mode 100644 index 0000000..f253935 Binary files /dev/null and b/Articles/Using RemObjects Pascal Script/Images_-437262DA-CA48-473A-8890-2161A932852F-.png differ diff --git a/Articles/Using RemObjects Pascal Script/Images_-7331DD6C-58D8-40D3-8BCC-D65E975EC424-.png b/Articles/Using RemObjects Pascal Script/Images_-7331DD6C-58D8-40D3-8BCC-D65E975EC424-.png new file mode 100644 index 0000000..ae11a5c Binary files /dev/null and b/Articles/Using RemObjects Pascal Script/Images_-7331DD6C-58D8-40D3-8BCC-D65E975EC424-.png differ diff --git a/Articles/Using RemObjects Pascal Script/Images_-7AEF4D36-18ED-4465-B887-4C9665DDBE0C-.png b/Articles/Using RemObjects Pascal Script/Images_-7AEF4D36-18ED-4465-B887-4C9665DDBE0C-.png new file mode 100644 index 0000000..d06a7ca Binary files /dev/null and b/Articles/Using RemObjects Pascal Script/Images_-7AEF4D36-18ED-4465-B887-4C9665DDBE0C-.png differ diff --git a/Articles/Using RemObjects Pascal Script/Images_-A8439C86-1330-42FE-944F-31BD046504D1-.png b/Articles/Using RemObjects Pascal Script/Images_-A8439C86-1330-42FE-944F-31BD046504D1-.png new file mode 100644 index 0000000..99a237c Binary files /dev/null and b/Articles/Using RemObjects Pascal Script/Images_-A8439C86-1330-42FE-944F-31BD046504D1-.png differ diff --git a/Articles/Using RemObjects Pascal Script/Images_-C3B60367-A372-4053-942E-A9220AE2F7DA-.png b/Articles/Using RemObjects Pascal Script/Images_-C3B60367-A372-4053-942E-A9220AE2F7DA-.png new file mode 100644 index 0000000..b178747 Binary files /dev/null and b/Articles/Using RemObjects Pascal Script/Images_-C3B60367-A372-4053-942E-A9220AE2F7DA-.png differ diff --git a/Articles/Using RemObjects Pascal Script/Images_-C914388E-AAF5-4E0C-90B0-6568433352F2-.png b/Articles/Using RemObjects Pascal Script/Images_-C914388E-AAF5-4E0C-90B0-6568433352F2-.png new file mode 100644 index 0000000..1182d28 Binary files /dev/null and b/Articles/Using RemObjects Pascal Script/Images_-C914388E-AAF5-4E0C-90B0-6568433352F2-.png differ diff --git a/Articles/Using RemObjects Pascal Script/Images_-CCEE9133-9036-4715-87A1-FC47B9AADC00-.png b/Articles/Using RemObjects Pascal Script/Images_-CCEE9133-9036-4715-87A1-FC47B9AADC00-.png new file mode 100644 index 0000000..eba5bfa Binary files /dev/null and b/Articles/Using RemObjects Pascal Script/Images_-CCEE9133-9036-4715-87A1-FC47B9AADC00-.png differ diff --git a/Articles/Using RemObjects Pascal Script/index.html b/Articles/Using RemObjects Pascal Script/index.html new file mode 100644 index 0000000..e588b5e --- /dev/null +++ b/Articles/Using RemObjects Pascal Script/index.html @@ -0,0 +1,276 @@ + + + +Using RemObjects Pascal Script + + + +

Using RemObjects Pascal Script

+ +

This article provides an overview of the new RemObjects Pascal Script and explains how to create some simple scripts.

+

Pascal Script comprises two different parts:

+ +

The two parts have no interdependencies. You can use them directly, or you can use them in theTPSScriptcomponent, which can be found in the uPSComponent.pas unit, and wraps them both in one easy to use class.

+

To use the component version of Pascal Script, you must first place it on your form or data module, set or assign the script property and call the Compile method and the Execute method. Compile errors, warnings or hints can be found in the CompilerMessages array property, while runtime errors can be found by reading the ExecErrorToString property.

+

The following example will compile and execute an empty script ("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;
+

+

By default, the component only adds a few standard functions to the scripting engine (the exact list can be found at the top of uPSComponents.pas).

+

Besides the standard functions, there are a few libraries included with Pascal Script:

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TPSDllPluginAllow scripts to use dll functions, the syntax is like:
function FindWindow(C1, C2: PChar): Longint; external 'FindWindowA@user32.dll stdcall';
TPSImport_ClassesImport library for TObject and the Classes unit.
TPSImport_DateUtilsImport library for date/time related functions.
TPSImport_ComObjAccess COM Objects from your scripts.
TPSImport_DBImport library for db.pas.
TPSImport_FormsImport library for the Forms & Menus units.
TPSImport_ControlsImport library to Controls.pas and Graphics.pas.
TPSImport_StdCtrlsImport library for ExtCtrls and Buttons.
+

+

To use these libraries, add them to your form or data module, select the [...] button next to the plugins property of the TPSCompiler component, add a new item and set the Plugin property to the plugin component. Besides the standard libraries, you can easily add new functions to the scripting engine. In order to do that, create a new method you would like to expose to the scripting engine, for example:

+

+procedure TForm1.ShowNewMessage(const Message: string);
+begin
+  ShowMessage('ShowNewMessage invoked:'#13#10+Message);
+end;
+

+

Then assign an event handler to the OnCompile event and use the AddMethod method of TPSCompiler to add the actual method:

+

+procedure TForm1.CECompile(Sender: TPSScript);
+begin
+  Sender.AddMethod(Self, @TForm1.ShowNewMessage,
+                   'procedure ShowNewMessage
+                   (const Message: string);');
+end;
+

+

A sample script that uses this function could look like this:

begin
+  ShowNewMessage('Show This !');
+end.

Advanced Features

+

Pascal Script includes a preprocessor that allows you to use defines ({$IFDEF}, {$ELSE}, {$ENDIF}) and include other files in your script ({$I filename.inc}). To enable these features, you must set the UsePreprocessor property to true and the MainFileName property to match the name of the script in the Script property. The Defines property specifies which defines are set by default, and the OnNeedFile event is called when an include file is needed.

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;

+

When these properties are set, the CompilerMessages array property will include the file name these messages occur in.

+

Additionally, you can call scripted functions from Delphi. The following sample will be used as a script:

function TestFunction(Param1: Double; Data: String): Longint;
+begin
+  ShowNewMessage('Param1: '+FloatToString(param1)
+                 +#13#10+'Data: '+Data);
+  Result := 1234567;
+end;
+
+begin
+end.

+

Before this scripted function can be used, it has to be checked to match its parameter and result types, which can be done in the OnVerifyProc event.

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;

+

The ExportCheck function checks if the parameters match. In this case, btu8 is a boolean (the result type), btdouble is the first parameter, and btString the second parameter. [pmIn, pmIn] specifies that both parameters are IN parameters. To call this scripted function, you have to create an event declaration for this function and call that.

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))));

+

It's also possible to add variables to the script engine, which can be used from within the script. To do this, you have to use the AddRegisteredVariable function. You can set this in the OnExecute event :

procedure TForm1.ceExecute(Sender: TPSScript);
+begin
+  CE.SetVarToInstance('SELF', Self);
+  // ^^^ For class variables
+  VSetInt(CE.GetVariable('MYVAR'), 1234567);
+end;

+

To read this variable back, after the script has finished executing, you can use the OnAfterExecute event: VGetInt(CE.GetVariable('MYVAR')).

+

Registering external variables to the script engine is also possible. It's a two step process, first, in the OnCompile event, add the types to the script using the AddRegisteredPTRVariable function.

procedure TMyForm.PSScriptCompile(Sender: TPSScript);
+begin
+  Sender.AddRegisteredPTRVariable('MyClass', 'TButton');
+  Sender.AddRegisteredPTRVariable('MyVar', 'Longint');
+end;

+

This will register the external MyClass and MyVar variables. Second, attach a pointer to these variables in the OnExecute event:

procedure TMyForm.PSScriptExecute(Sender: TPSScript);
+begin
+  PSScript.SetPointerToData('MyVar', @MyVar, PSScript.FindBaseType(bts32));
+  PSScript.SetPointerToData('Memo1', @Memo1, PSScript.FindNamedType('TMemo'));
+end;

+

There are two types of variables in Pascal Script, base types, which are simple types (see the table below), and class types. Base types are registered in the uPSUtils.pas unit and can be located using the FindBaseType function. Class types have to be located by name, using the FindNamedType. Changes to these variables have a direct effect on the actual variable.

+

Base types:

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
btU8Byte
btS8Shortint
btU16Word
btS16Smallint
btU32Longword
btS32Longint
btS64Int64
btSingleSingle
btDoubleDouble
btExtendedExtended
btVariantVariant
btStringString
btWideStringWideString
btCharChar
btWideCharWideChar

+

The component version of Pascal Script also supports execution of scripted functions. This works by using the ExecuteFunction method.

ShowMessage(CompExec.ExecuteFunction([1234.5678, 4321,
+                                      'test'],
+                                     'TestFunction'));

+

This will execute the function called 'TestFunction' with 3 parameters, a float, an integer and a string. The result will be passed back to ShowMessage.

Notes:

+ + + +