Object Notation Syntax
Published 29 APR 2016 at 02:13:08PM
Updated on 30 APR 2016 at 02:13:08PM
The OpenInsight event compiler supports an enhanced "shorthand" syntax for working with the Presentation Server object model, much like that provided in standard Basic+ for use with OLE objects. Like the OLE notation, this provides a more natural API to working with properties and methods, rather than the relatively verbose and flat interface provided by the familiar Get/Set_Property and Exec_Method functions. In a nutshell, object notation provides the use of a special "→" operator to allow an object to refer to its properties and methods, along with the "{}" operators to specify object or property indexes. It may be used in place of the following function calls:
- Get_Property
- Set_Property_Only
- Exec_Method
Using Properties
The general format for accessing properties via object notation is illustrated below. In all cases objects that support sub-objects (such as controls that support an IMAGE sub-object) may reference the sub-object by suffixing them to the main object with a "." character as a delimiter.
Get_Property syntax
value = object->property ; // Non-Indexed value = object{index}->property ; // Object-Indexed value = object->property{index} ; // Property-Indexed // With sub-object support value = object.subObject->property ; // Non-Indexed value = object.subObject{index}->property ; // Object-Indexed value = object.subObject->property{index} ; // Property-Indexed
Set_Property_Only syntax
object->property = value ; // Non-Indexed object{index}->property = value ; // Object-Indexed object->property{index} = value ; // Property-Indexed // With sub-object support object.subObject->property = value ; // Non-Indexed object.subObject{index}->property = value ; // Object-Indexed object.subObject->property{index} = value ; // Property-Indexed
Where:
- object is either:
- An equated constant (suffixed with a "$" symbol), or
- The contents of a variable (prefixed with an "@" symbol), or
- An embedded name (prefixed with the "$" symbol), or
- A path prefix (prefixed with the "." symbol to represent the name of the object's parent window (i.e. "@Window")
- property can be an equated constant, the contents of a variable, or an embedded name. It may also be the special token "@@" which means use the DEFPROP property.
- index is either a one or two dimensional index value, delimited by a "," character and surrounded by curly braces.
Get_Property examples
// Get_Property object notation using variable contents CtrlID = @Window : ".MY_LISTBOX" // PropVal = Get_Property( CtrlID, "TEXT" ) PropVal = @CtrlID->Text // PropVal = Get_Property( CtrlID, "LIST", 4 ) PropVal = @CtrlID->List{4} // PropVal = Get_Property( CtrlID, "LIST", ItemIdx ) ItemIdx = Get_Some_Index() PropVal = @CtrlID->List{ItemIdx} // PropVal = Get_Property( CtrlID, "DEFPROP" ) PropVal = @CtrlID->@@ // PropVal = Get_Property( @Window, "TEXT" ) PropVal = @@Window->Text EdtID = @Window : ".MY_EDITTABLE"; Col = 2; Row = 3 // PropVal = Get_Property( EdtID : ".CELLS", "TEXT", Col : @fm : Row ) PropVal = @EdtID.Cells{Col,Row}->Text
// Get_Property object notation using a path-prefix // PropVal = Get_Property( @Window : ".MY_LISTBOX", "TEXT" ) PropVal = .My_ListBox->Text // PropVal = Get_Property( @Window : ".MY_LISTBOX", "LIST", 4 ) PropVal = .My_ListBox->List{4} // PropVal = Get_Property( @Window : ".MY_EDITTABLE.CELLS", "TEXT", 2 : @fm : 3 ) PropVal = .My_EditTable.Cells{2,3}->Text
// Get_Property object notation using equated constants Equ CTRLID$ To "MYWIN.MY_LISTBOX" // PropVal = Get_Property( CTRLID$, "TEXT" ) PropVal = CTRLID$->Text // PropVal = Get_Property( CTRLID$, "LIST", 4 ) PropVal = CTRLID$->List{4} Equ EDTID$ To "MYWIN.MY_EDITTABLE" // PropVal = Get_Property( EDTID$ : ".CELLS", "TEXT", 2 : @fm : 3 ) PropVal = EDTID$.Cells{2,3}->Text
// Get_Property object notation using an embedded name // FocusID = Get_Property( "SYSTEM", "FOCUS" ) FocusID = $System->Focus // PropVal = Get_Property( "MYWIN.MY_CONTROL", "TEXT" ) PropVal = $MyWin.My_Control->Text
Set_Property_Only examples
// Set_Property_Only object notation using variable contents CtrlID = @Window : ".MY_LISTBOX" // Call Set_Property_Only( CtrlID, "TEXT", PropVal ) @CtrlID->Text = PropVal // Call Set_Property_Only( CtrlID, "LIST", PropVal, 4 ) @CtrlID->List{4} = PropVal // Call Set_Property_Only( CtrlID, "DEFPROP", PropVal ) @CtrlID->@@ = PropVal // Call Set_Property_Only( @Window, "TEXT", PropVal ) @@Window->Text = PropVal EdtID = @Window : ".MY_EDITTABLE"; Col = 2; Row = 3 // Call Set_Property_Only( EdtID : ".CELLS", "TEXT", PropVal, Col : @fm : Row ) @EdtID.Cells{Col,Row}->Text = PropVal
// Set_Property_Only object notation using an embedded name // Call Set_Property_Only( "SYSTEM", "FOCUS", focusID ) $System->Focus = FocusID // Call Set_Property_Only( "MYWIN.MY_CONTROL", "TEXT", PropVal ) $MyWin.My_Control->Text = PropVal
// Set_Property_Only object notation using a path-prefix // Call Set_Property_Only( @Window : ".MY_LISTBOX", "TEXT", PropVal ) .My_ListBox->Text = PropVal // Call Set_Property_Only( @Window : ".MY_LISTBOX", "LIST", PropVal, 4 ) .My_ListBox->List{4} = PropVal // Call Set_Property_Only( @Window : ".MY_EDITTABLE.CELLS", "TEXT", PropVal, | // 2 : @fm : 3 ) .My_EditTable.Cells{2,3}->Text = PropVal
// Set_Property_Only object notation using equated constants Equ CTRLID$ To "MYWIN.MY_LISTBOX" // Call Set_Property_Only( CTRLID$, "TEXT", PropVal ) CTRLID$->Text = PropVal // Call Set_Property_Only( CTRLID$, "LIST", PropVal, 4 ) CTRLID$->List{4} = PropVal Equ EDTID$ To "MYWIN.MY_EDITTABLE" // Set_Property_Only( EDTID$ : ".CELLS", "TEXT", PropVal, 2 : @fm : 3 ) EDTID$.Cells{2,3}->Text = PropVal
Using Methods
The general format of the Exec_Method object notation is described below. It may be used to execute the method as a subroutine (i.e. no return value) or as a function.
Exec_Method syntax
object->method( arg1, arg2, … argN ) ; // Call as subroutine result = object->method( arg1, arg2, … argN ) ; // Call as function
Where:
- object is either:
- An equated constant (suffixed with a "$" symbol), or
- The contents of a variable (prefixed with an "@" symbol), or
- An embedded name (prefixed with the "$" symbol), or
- A path prefix (prefixed with the "." symbol to represent the name of the object's parent window (i.e. "@Window")
- method can be an equated constant, the contents of a variable, or an embedded name.
Exec_Method examples
// Exec_Method object notation using variable contents CtrlID = @Window : ".MY_LISTBOX" // Pos = Exec_Method( CtrlID, "INSERT", -1, Item ) Pos = @CtrlID->Insert( -1, Item ) // Call Exec_Method( CtrlID, "DELETE", 4 ) @CtrlID->Delete( 4 )
// Exec_Method object notation using a path-prefix // Pos = Exec_Method( @Window : ".MY_LISTBOX", "INSERT", -1, Item ) Pos = .My_ListBox->Insert( -1, Item ) // Call Exec_Method( @Window : ".MY_LISTBOX", "DELETE", 4 ) .My_ListBox->Delete( 4 ) // Call Exec_Method( @Window : ".MY_EDITTABLE", "APPEND", RowData ) .My_EditTable.Rows->Append( RowData )
// Exec_Method object notation using equated constants Equ CTRLID$ To "MYWIN.MY_LISTBOX" // Pos = Exec_Method( CTRLID$, "INSERT", -1, Item ) Pos = CTRLID$->Insert( -1, Item ) // Call Exec_Method( CTRLID$, "DELETE", 4 ) CTRLID$->Delete( 4 )
// Exec_Method object notation using an embedded name // RetVal = ( "SYSTEM", "CREATE", createStruct ) RetVal = $System->Create( createStruct ) // Call Exec_Method( "SYSTEM", "DESTROY", ctrlID ) $System->Destroy( ctrlID )
Using Object Notation in Stored Procedures
Object Notation was originally designed for use with the event compiler, and therefore prior to version 10 could only be used with event scripts. In the current version however, it may be used in Stored Procedures by including the event pre-compiler in the compilation chain. This is done by adding the following at the top of the program before the other statements:
#Pragma PreComp Event_PreComp
You should also declare the following functions before you use any object notation - the pre-compiler does not insert these into the program itself:
- Get_Property
- Exec_Method
E.g.
Compile Function MyWin_Events( CtrlEntID, Event, Param1, Param2 ) #Pragma PreComp Event_PreComp Declare Function Get_Property, Exec_Method $Insert Logical Locate Event In "CREATE,CLICK,CLOSE" Using "," Setting Pos Then On Pos GoSub OnCreate,OnClick,OnClose End Return RetVal // ... etc ...
Unlike in previous versions this object notation may also be used safely with OLE object notation in the same Stored Procedure.
Object Notation limitations
The current version of Object Notation is currently handled by a pre-compiler, rather than the actual Basic+ compiler itself, thus its parsing accuracy is somewhat limited in comparison. Because of this, the following guidelines should be adhered to:
- The passing of complex expressions to the object notation Set_Property_Only and Exec_Method statements should be avoided; It is better to resolve them to a variable first, and then pass that variable as an argument instead.
- The curly-brace Calculate operators ("{" and "}") are also used to resolve the value of a dictionary column at runtime, and should not be used on the same line as an object notation statement: These operators are interpreted as object or property index tokens instead, and will lead to parsing errors if used incorrectly.
Object Notation troubleshooting
Behind the scenes the pre-compiler converts the object notation syntax to actual Get_Property, Set_Property_Only and Exec_Method calls before passing them to the Basic+ compiler. If you use object notation and run into problems that you cannot resolve easily you can see exactly what gets passed to the compiler by using the Output compiler directive, which will write the pre-compiler output to a specified record. To enable this functionality, place the following statement at the top of your program (before or after the Event_PreComp statement), and replace
and with the table and record names of your choice:
#Pragma Output
E.g. Send the output to the PRECMP_OUT record in SYSLISTS
#Pragma Output SYSLISTS PRECMP_OUT
(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).
Comments
At 29 APR 2016 02:50PM B. Cameron wrote:
Hi Carl, In some of your examples above, you are using "CtrlId","@CtrlId". Will devs need to convert "CtrlEntId","@CtrlEntId" in existing pre-OI10 event code when moving up?? Thanks.
At 29 APR 2016 02:56PM Captain C wrote:
Hi Bruce,
It's just a variable name as an example - if you have a variable called CtrlEntID, then you'd use @CtrlEntID as before. No existing code needs to be changed to use these new additions.
At 29 APR 2016 05:15PM D Purcell wrote:
Nice job Carl :)
Do you have any plans or options to add a more general macro capability?
At 29 APR 2016 10:47PM Captain C wrote:
Thanks - I'd like to see a general macro precompiler - I find it useful in other languages, but it's not something I'll have time to work on for a while ….
Still, nothing to stop you writing one - you can add any number of precompilers … let me know when it's done OK? ;)