DelphiScript Support in Altium NEXUS
Parent page: Scripting Language Support
This section describes the DelphiScript language used by the Altium NEXUS Scripting Engine and provides reference details of the statements, functions, and extensions that are supported. These are special procedures that are used to control and communicate directly with Altium NEXUS.
Also in this reference:
- Differences between DelphiScript and Delphi
- DelphiScript Keywords
- DelphiScript Statements and Operators
- DelphiScript Functions
- DelphiScript Forms and Components
The DelphiScript Language
This DelphiScript reference assumes that you are familiar with basic programming concepts as well as the basic operation of Altium NEXUS. The scripting system supports the DelphiScript language, which is very similar to Embarcadero Delphi™.
The key difference is that DelphiScript is a typeless or untyped scripting language, which means you cannot define records or classes and pass pointers as parameters to functions. Variables can still be declared within scripts for readability.
This page and its accompanying sub-pages contain reference material on interfaces, components, global routines, types, and variables that make up the DelphiScript scripting language.
Key Delphiscript Elements
Objects
In DelphiScript, an Object consists of methods, and in many cases, properties, and events. Properties represent the data contained in the object, Methods are the actions the object can perform, and Events are conditions the Object can react to. All Objects descend (and inherit) from the top-level object of the TObject
type.
Object Interfaces
An Object Interface consists of methods, and in many cases properties, but cannot have data fields. An Interface represents an existing Object, and each Interface has a GUID that marks it unique. Properties represent the data contained in the Object that the Interface is associated with. Methods are the actions the Object (which the interface is associated with) can perform.
Components
Components are visual objects from the Tool Palette panel that can be manipulated at design time. All Components descend from the TComponent
system class in the Embarcadero Delphi Visual Component Library (VCL).
Routines
Global Routines are the Procedures and Functions from the scripting system. These Routines are not part of a class but can be called either directly or from within class methods in a script.
Types
The Variable Types are used as Return types and Parameter types for Interface methods and properties, object methods, properties and events, and global routines. In many cases, Types are documented in the Enumerated Types sections in the API documentation.
Altium NEXUS and the Delphi RTL
The Scripting system supports a subset of Embarcadero Delphi Run Time Library (RTL) and the Altium NEXUS API.
DelphiScript Source Files
In Altium NEXUS, a script project is organized to store script documents (script Units and script Forms). You can execute the script from a menu item, toolbar button, or from the Select Item To Run dialog available from Altium NEXUS's main menu.
PRJSCR, PAS, and DFM Files
Scripts are organized into projects with a *.PRJSCR
extension. Each project consists of files with a *.pas
extension. Files can be either script Units or script Forms — note that each Form has a script file with a *.pas
extension and a corresponding Form file with a *.dfm
extension. A script Form is a graphical window (dialog) that runs on top of Altium NEXUS and hosts different user-accessible controls.
It is possible to attach scripts to different projects, and it's highly recommended to organize scripts into different projects in order to manage the number of scripts, and their procedures/functions.
Example Scripts
The script examples collection illustrates the basic features of DelphiScript programming using simple scripts for use in Altium NEXUS.
The location and purpose of a selection of the example scripts are listed below:
Scripts\DelphiScript Scripts\DXP
folder - Demonstrates the Client and system APIScripts\DelphiScript Scripts\PC
B folder - Demonstrates the PCB APIScripts\DelphiScript Scripts\Processes
folder - Demonstrates server ProcessesScripts\DelphiScript Scripts\General
folder - Demonstrates DelphiScript keywordsScripts\DelphiScript Scripts\Sch
folder - Demonstrates the Schematic APIScripts\DelphiScript Scripts\WSM
folder - Demonstrates the Workspace Manager API
Writing DelphiScript Scripts
DelphiScript Naming Conventions
In general, there are no restrictions to the names that are given to procedures, functions, variables, and constants, as long as they adhere to the following rules:
- The name can contain the letters A to Z, a to z, the underscore character "_" and the digits 0 to 9.
- The name must begin with a letter.
- The name cannot be a DelphiScript Keyword, directive, or reserved word.
- Names are case insensitive when interpreted. Both the upper and lower case can be used when naming a function, subroutine, variable or constant, however, the interpreter will not distinguish between upper and lower case characters. Names that are identical except for the case will be treated as the same name in DelphiScript.
In a DelphiScript file, the functions and procedures are declared using the Procedure-Begin-End
or Function-Begin-End
blocks. Both of these statement blocks require a name to be given to the procedure or function. DelphiScript allows you to create named variables and constants to hold values used in the current script.
Including Comments
In a script, comments are non-executable lines of code that are included for the benefit of the programmer. Comments can be included virtually anywhere in a script.
Any text following //
or enclosed with (* *)
or {}
are ignored by DelphiScript.
//This whole line is a comment
{This whole line is a comment}
{
These lines are comments
These lines are comments
}
(* This whole line is a comment *)
(*
These lines are comments
These lines are comments
*)
Comments can also be included on the same line as executed code. For example, everything after the semicolon in the following code line is treated as a comment.
ShowMessage ('Hello World'); //Display Message
Local and Global Variables
Since all scripts have local and global variables, it is very important to have unique variable names in scripts within a script project. If the variables are defined outside any procedures and functions, they are global and can be accessed by any script unit in the same project.
If variables are defined inside a procedure or function, then these local variables are not accessible outside these procedures/functions.
Example of Local and Global Variables in a Script:
// Note: The Uses keyword is not needed.
{ The global variable from UnitA script (see below) is available to this Script Unit,
as long UnitA is in the same project as this Script Unit. }
Const
GlobalVariableFromThisUnit='Global Variable from this unit';
Procedure TestLocal;
var
Local;
Begin
Local := 'Local Variable';
ShowMessage(Local);
End;
Procedure TestGlobal;
Begin
//ShowMessage(Local); // This line produces an error because the 'Local' variable is not global.
ShowMessage(GlobalVariableFromThisUnit);
// A variable from UnitA can be accessed without the Uses keyword.
ShowMessage(GlobalVariableFromUnitA);
End;
UnitA script:
Const
GlobalVariableFromUnitA = 'Global Variable from Unit A';
Using Named Variables
In a script, named variables or constants are created to store values to be used during program execution. All variables in a script are always of Variant type. Typecasting does not apply, so Types in variables declarations are ignored and can be skipped. These declarations are therefore correct:
Var a : integer;
Var b : integer;
Var c, d;
Splitting a Line
Each code statement is terminated with the semicolon ;
character to indicate the end of the statement. DelphiScript allows you to write a statement on several lines of code, splitting a long instruction into two or more lines. The only restriction in splitting programming statements into different lines is that a string literal may not span several lines.
For example:
X.AddPoint( 25, 100);
X.AddPoint( 0, 75);
// is equivalent to:
X.AddPoint( 25, 100); X.AddPoint( 0, 75);
however...
'Hello World!'
\\is not equivalent to
'Hello
World!'
DelphiScript does not put any practical limit on the length of a single line of code in a script, but for the sake of readability and ease of debugging it is a good practice to limit the length of code lines so that they can easily be read on-screen or in printed form.
If a line of code is very long, you can break this line into multiple lines, and this code will be treated by the DelphiScript interpreter as if it were written on a single line.
Unformatted code example:
If Not (PcbApi_ChooseRectangleByCorners(BoardHandle,'Choose first corner','Choose final corner',x1,y1,x2,y2)) Then Exit;
Formatted code example:
If Not (PcbApi_ChooseRectangleByCorners(BoardHandle,
'Choose first corner',
'Choose final corner',
x1,y1,x2,y2)) Then Exit;
Case Sensitivity
The DelphiScript language used in writing scripts is not case sensitive — that is, all keywords, statements, variable names, function, and procedure names can be written without regard to using capital or lower case letters. Both upper and lower case characters are considered equivalent.
For example, the variable name myVar
is equivalent to myvar
and MYVAR
. DelphiScript treats all of these names as the same variable.
The only exception to this is in literal strings, such as the title string of a dialog definition or the value of a string variable. These strings retain case differences.
The Space Character
A space is used to separate keywords in a script statement. However, DelphiScript ignores any additional white spaces in a statement.
For example:
X = 5
// is equivalent to
X =5
You can use white spaces to make your script more readable.
Functions and Procedures in a Script
The DelphiScript interpreter allows two kinds of methods (procedures): Procedures and Functions. The only difference between a function and a procedure is that a function returns a value.
A script can have at least one procedure that defines the main program code. You can, however, define other procedures and functions that can be called by your code.
As with Embarcadero Delphi, procedures and functions are defined within a Begin-End
statement block. To invoke or call a function or procedure, include the name of the function or procedure in a statement in the same way as when using the built-in DelphiScript functions and procedures. If the function or procedure requires parameters, then these must be included in the calling statement. Both functions and procedures can be defined to accept parameters, but only functions can be defined to return a value to the calling statement.
Any name may be assigned to functions and procedures when they are defined, as long as it conforms to the standard DelphiScript naming conventions.
Typical DelphiScript Procedure:
Procedure CreateSchObjects;
Begin
If SchServer = Nil Then Exit;
SchDoc := SchServer.GetCurrentSchDocument;
If SchDoc = Nil Then Exit;
PlaceSchematicObjects;
SchDoc.GraphicallyInvalidate;
End;
Typical DelphiScript Function:
Function BooleanToString(AValue : Boolean) : String;
Begin
If (AValue) Then Result := 'True'
Else Result := 'False';
End;
The name of a function can not be used to set its return value. The Result
keyword must be used instead.
Var, Begin-End global block:
Var
A, B, C;
Begin
B := 10;
C := 20;
A := B + C;
ShowMessage(IntToStr(A));
End;
Scripting Tips
Referencing Scripts in a Script Project
The code in one script can call a procedure in another script with the same script project. Any global variable in any script can be accessed within the same project.
Local and Global Variables
Since scripts have local and global variables, it is important to have unique variable names in scripts within a script project. If the variables are defined outside any procedures and functions, they are global and can be accessed by any unit in the same project. If variables are defined inside a procedure or function, then these local variables are not accessible outside these procedures/functions.
It is recommended to put scripts of similar nature in a project and to keep the number of scripts in a project at a manageable size — keeping track of global variables in many scripts can become an issue. It is not mandatory to store scripts in a script project, as scripts can be put in other project types.
Unique Identifiers and Variables
When using script forms, make sure that all script forms have unique form names. It's possible to have all script forms named form1
(for example) in the same script project. In this case, the scripting system becomes conflicted when trying to display the correct form, when a script form is executed.
A script form name can be changed using the Object Inspector. The name will be automatically changed in both the script unit and script form files.
Parameter-less Procedures and Functions
Scripts should be written so that the procedures required to be invoked to run the script will only appear in the Select Items to Run dialog. To prevent other procedures/functions from appearing in the Select Items to Run dialog, a (Dummy : Integer)
parameter can be inserted next to the method name. See the example below.
// This function is prevented from appearing in the Select Items to Run dialog.
Function TSineWaveform.CreateShape(Dummy : Integer);
Begin
//Do something
End;
{..................................................}
{..................................................}
Procedure TSineWaveform.bCloseClick(Sender: TObject);
var
I : integer;
Begin
//Doing something
Close;
End;
{..................................................}
{..................................................}
procedure DrawSine;
Begin
SineWaveform.showmodal;
End;
DelphiScript Error Codes
Error |
Description |
---|---|
|
Wrong string used in the script. |
|
Wrong string used in the script. |
|
Multiple instances of functions with the same name in the code are not permitted. Rename the other functions that have the same name. |
|
Unknown identifier. Need to declare this identifier first before using this identifier. |
|
The script has a Variable type that is not valid or unknown. |
|
Multiple instances of the same unit names are not permitted. Ensure script unit names are unique. |
|
The unit declaration is not properly defined. |
|
Missing function in the script. |
|
DelphiScript is unable to link the script to the required internal components. |
|
Multiple instances of the same label exist in the script. Ensure labels are unique in the script. |
|
The declaration block is not defined correctly. |
|
The Goto label is not defined. |
|
Multiple instances of the same variables exist in the script. Ensure variables are unique. |
|
An error exists in the variable declaration block. Wrong declarations or declarations not recognized by the scripting system. |
|
The Variable was not defined, so the scripting system cannot define this variable. |
|
The method signature is illegal. |
|
Wrong parameters used for the method. |
|
Properties of an object not recognized by the scripting system. |
|
Declarations other than classes were attempted to be declared. |
|
Declaration error exists in the script. |
|
A syntax error has occurred on the script |
|
Invalid identifier name such as duplicated identifier name. Redefine the identifier name. |
|
Invalid identifier. Redefine a new identifier |
|
Function not used correctly in the script |
|
The procedure not used correctly in the script |
|
Hex constant value not declared correctly. |
|
The script needs to be compiled first before it can be executed. An internal error. |
|
Real type constant declaration error. |
|
String type constant declaration error. |
|
Unknown parameter type as reported by the scripting system. |
|
The variable value result not found for the specified string in the script. |
|
Missing procedure in the script. |
|
Missing parameter in the script. |
|
An internal error. |
|
The same procedure or function declared and implemented differently. Check the parameters between the two. |
|
One of the parameters of a method, function, or procedure does not have a correct variant type. |
|
An attempt to set a value to the read-only property or a property does not exist. |
|
Arguments used for the procedure or function not valid for the script. |
|
Missing parameter value. |
|
Wrong parameter type used. |
|
This interface is not declared or defined. |
|
Missing parameter required for the method, function, or procedure. |
|
DelphiScript has detected an unknown script error that is not defined in the internal errors table. |
|
DelphiScript has detected an invalid operation code. |