Tag Archives: Properties


As most of you will probably know, “commuter module” is the term given to a stored procedure whose main purpose is to handle event processing for a specific form.  Rather than have each individual event processed in a separate event script, quick-events are used instead to call the commuter module directly, passing it various parameters such as the name of the object firing the event, the name of the event itself, and any relevant arguments.  The commuter module then branches off to different internal subroutines to handle the event.

Following this methodology offers several important advantages:

  • Simplified code management
  • Simplified deployment
  • Improved code sharing via internal subroutines
  • Lower memory overhead (single procedure vs. multiple event scripts)

While using a commuter module like this is the recommended way of developing applications in OpenInsight, there has never been any sort of formal link between the commuter module and the form itself, which means that it is usually necessary to adopt a naming convention for this approach to work.

For example, it is common to have a commuter module with the same name as the form, or with the same name as the form and suffixed with the string “_EVENTS”.  By doing this it was easy to define quick-events to call the commuter module in the old v9 Form Designer like so:

v9 Commuter Module Quick Event

v9 Commuter Module Quick Event

The OBJ_CALL_EVENT program looks for a stored procedure with the same name as the form, or one with the same name as the form and suffixed with “_EVENTS”.  It was also possible to avoid the overhead of a lookup and call the commuter module directly by using the “@WINDOW” placeholder like this:

v9 Commuter Module Quick Event (using @WINDOW)

v9 Commuter Module Quick Event (using @WINDOW)

Or the “@WINDOW_EVENTS” placeholder like this:

v9 Commuter Module Quick Event (using @WINDOW_EVENTS)

Of course, even with this approach the form still wasn’t actually linked to it’s commuter module, rather it was only linked to “OBJ_CALL_EVENTS” or a fictitious entity called “@WINDOW”.

In version 10 we’ve added a new WINDOW property called COMMUTERMODULE, which simply contains the name of the stored procedure to use (this can be any valid name – you are no longer limited to one based on the name of the form, though we do suggest you keep this convention to help organize your application):

CommuterModule Property

CommuterModule Property

When the form is saved and compiled this stored procedure is linked to the form with a “used-by” relationship, thereby making deployment easier as you will see the link when you create your RDK definition records.

Another benefit of this is that you can quickly open your commuter module from the form by using the “View Commuter Module” button on the Form Designer toolbar:

View Commuter Module button

View Commuter Module button

Finally you can easily set your quick events to call your commuter module in the Event Designer like so:

Commuter Module QuickEvent

Commuter Module QuickEvent

Note that it uses an “@COMMUTER” placeholder – this is replaced with the contents of the COMMUTERMODULE property at runtime.

(You can still use the previous @WINDOW/_EVENTS or Obj_Call_Events methods if you wish – those options still exist.)

So, this is the first step in tightening the relationship between a form and it’s commuter module.  There is certainly scope for more integration between the two and this is something that we hope to pursue during subsequent releases.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10)

Context Menus in OpenInsight 10 – Part I

Using context menus in previous versions of OpenInsight has always been something of a chore: they were not well documented and they were subject to several limitations:

  • They could only be attached to a control programmatically, rather than via the Form Designer.
  • The context menu designer tool would name a menu based on the control it was supposed to be attached to – there was no real concept of sharing a menu between controls.
  • They were limited to a single level – no sub-menu nesting was allowed.
  • They were difficult to modify at runtime.

These issues made them quite onerous to use, which is unfortunate as context menus are an important part of modern UI design, having been in widespread use across the OS since Windows 95.

With version 10 we went back to the drawing board and completely redesigned them to make them first class UI citizens and solve the problems outlined above.

The Context Menu Designer

One of the new tools in the IDE is the Context Menu Designer, which allows you to define the structure of the menu along with any quick events (Event scripts are not supported for context menus).

Context Menu Designer (WIP)

Context Menu Designer (WIP)

Menus saved by the designer are given simple names in the same format as any other repository entity – they are no longer based on the name of a specific control.  They can then be attached in the Form Designer by using an object’s CONTEXTMENU property.

(Note that like normal WINDOW menus they also support nested structures as they share the same code-base.)

The CONTEXTMENU property

Forms and controls now support an explicit CONTEXTMENU property which is the repository ID of a saved context menu.

ContextMenu Property

ContextMenu Property

At runtime, when a user right-clicks on a control, the Presentation Server looks at the CONTEXTMENU property to find the name of an attached menu, and, if found, displays it.

When the user selects an item from context menu a MENU event is raised and sent to the quick event target defined in the designer.

This is a much simpler and streamlined process.

Of course, that’s not the end of the story as there are times when the context menu will need to be adjusted before it is displayed at runtime, depending on factors like the state of it’s parent control and so on.  We’ll take a look at how to do that in the next post.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).


One of the new controls added to version 10 is the FILEPREVIEW control, which taps into the Windows Shell interface to expose the same  functionality provided by the Windows Explorer when previewing the contents of files, as per the example below:


Windows Explorer PowerPoint preview

Using the FILEPREVIEW control is quite easy – simply set the FILENAME property with the name and path of the file you want to preview, and if the OS has handlers installed for that file type then the control will render them.

Here’s an example of previewing a PowerPoint file:

  fileName = get_Property( @window : ".EDL_FILENAME", "TEXT" )
  if bLen( fileName ) then
     call set_Property_Only( @window : ".FPV_VIEWER", "FILENAME", |
                             fileName )

FILEPREVIEW control example

The devil of course is in the details – your OS must have the correct handler DLLs installed for you to view the preview of the file, and this may rely on third party software being installed as well.  For example, to preview Word and Excel documents you must have Office installed, to preview PDF files you must have something like Adobe Reader installed and so on.  You can test for this at runtime by using the PREVIEWHANDLER method, which returns a GUID identifying the preview handler DLL if it is installed.  You simply pass the extension you wish to look up and check for a returned GUID like so:

  handlerGUID = exec_Method( previewCtrl, "PREVIEWHANDLER", "pdf" )
  if bLen( handlerGUID ) then
    // We have a PDF preview viewer on the workstation ...
    call set_Property_Only( previewCtrl, "FILENAME", "c:\temp\test.pdf" )

The control also supports an ACTIVE property which returns TRUE$ if the control currently has a file loaded for previewing.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).




One of the areas in which dropdown comboboxes have always been lacking is the ability to fully control when the list is populated in a visually pleasing manner.  Under most circumstances the contents are loaded well before the dropdown button is clicked, and this is fine, but in situations where the items are context -sensitive it is necessary to load them just before the list is shown, and in previous versions this can look a little messy.

You can see an example of this in the OI9 System Editor++: there is a very handy pair of dropdowns at the top if the form that allow you to navigate your source code using inserts and labels, but when you use them you see the list contents loaded just after it has been dropped; this looks somewhat jarring and usually causes issues with the vertical scrollbar too.

Of course, the reason for this is that OpenInsight events are normally fired in an asynchronous manner, and the DROPDOWN event won’t run until after the list has been shown.  While you do have the ability to fire events in a synchronous fashion, this can introduce other complications and is something that should be avoided whenever possible.

So, in order to fix this, OpenInsight 10 provides a new property called AUTODROPDOWN that allows the list to be loaded during the DROPDOWN event and then displayed precisely when needed.

AUTODROPDOWN is a boolean property and is set to TRUE$ by default.

  • When set to TRUE$ the combobox behaves in exactly the same way as previous versions.
  • When set to FALSE$, the list is not shown until you explicitly set the DROPDOWN property to TRUE$. This gives you ability to load the list contents and then show them when ready.

Here’s an example of loading a list of STPROC repository items in a DROPDOWN event when AUTODROPDOWN is FALSE$

  // Get a list of items
  reposIDs = get_Repos_Entities( "", "STPROC", "", FALSE$, |
                                 TRUE$, FALSE$, "" )
  // Load them into the combobox LIST property
  call set_Property_Only( ctrlEntID, "LIST", reposIDs )

  // Now show the list
  call set_Property_Only( ctrlEntID, "DROPDOWN", TRUE$ )

Comboboxes as options buttons?

Another area where AUTODROPDOWN may help is for systems that use comboboxes as a combined edit and options control, where clicking the dropdown button loads a dialog box or popup instead of dropping a list.  Again, in previous versions this tends to look a little crude because the combobox shows a very shallow list even though it is empty, but with AUTODROPDOWN set to FALSE$ the list is never shown, and consequently looks much better.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

Listboxes and ToolTips

Following on from our previous post on the new TOOLTIP property, this time we’re going to look at the new tooltip functionality added to Listbox controls, namely tracking and in-place item tooltips.

Tracking tooltips are small popup windows that appear when a user hovers over a partially obscured item in the control: they display the full item text string instead, and thereby avoid the need for horizontal scrolling, which is always a preferable user experience.


Offset tracking tooltip

In-place tooltips operate in a similar manner, but rather than appearing at an offset to the cursor position they actually appear over the item itself, hence the term “in-place”:


In-place tracking tooltip

This behaviour is controlled by the new SHOWITEMTOOLTIPS property which can be set to one of the following values:

  "0" - Disabled : Item tooltips are not displayed
  "1" - Offset   : Item tooltips are displayed at an offset to the cursor
  "2" - In-place : Item tooltips are displayed over the item itself.

When set to “1” (Offset) or “2” (In-place) the SHOWITEMTOOLTIPS property overrides the normal TOOLTIP property, so a “normal” tooltip will not be displayed.

Displaying alternative item text

Sometimes it is desirable to display a different text string in the tooltip rather than the item text itself.  In this case you can set the new SHOWVALUESASTOOLTIPS property to specify that the tooltip should display the contents of the item’s VALUE property instead.

SHOWVALUESASTOOLTIPS is a simple boolean property of TRUE$ or FALSE$.


Displaying the Value property as a tooltip

Note in this case the tooltip is always displayed at an offset, and is triggered regardess of whether or not the item is clipped.


Combobox and TreeListbox controls

Both new properties described here also apply to simple Combobox and TreeListbox controls.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).



A tooltip is a small pop-up window that describes a control being pointed to, usually referred to as a “tool”, and they are commonly used to provide labelling for controls that only display an image, such as toolbar buttons.

Simple tooltip

Simple tooltip

Earlier versions of OpenInsight supported some basic tooltip functionality for a very limited set of controls via the HELPTEXT property, but for version 10 the name HELPTEXT has been deprecated for all standard controls (i.e. for objects other than menu items) and renamed to TOOLTIP instead, thereby bringing it in line with standard Windows terminology.  The name HELPTEXT can still be used however, to preserve backwards compatibility with your existing code.

Unlike in previous versions the new TOOLTIP property is not a single string, because there are more attributes that can be set – It is now an @fm-delimited dynamic array structured as follows:

   <1> Text
   <2> Title
   <3> Icon
   <4> Large Icon
   <5> Balloon Style
   <6> Centered


This is the text to display.  Multiple lines are delimited by @tm.  This attribute is required for the tooltip to be displayed.

Tooltip with multiple lines

Tooltip with multiple lines


This is the title to display in the tooltip. This is an optional attribute.

Tooltip with title

Tooltip with title


This attribute is only valid if the Title attribute is set.  It should contain the name of an icon file or resource to display in the tooltip (as per the usual ICON property).  Alternatively you can pass one of the following special characters to use a standard Windows icon instead (in a similar manner to the Msg() function):

  • “*” – Use the standard Information icon
  • “!” – Use the standard Warning icon
  • “H” – Use the standard Error icon
Tooltip with icon

Tooltip with icon

Large Icon

Normally the tooltip uses a 16×16 pixel size icon.  When this attribute is set to TRUE$ the tooltip will use a 32×32 pixel size one instead.  The default value is FALSE$.

Tooltip with large icon

Tooltip with large icon

Balloon Style

Standard tooltips use a rectangle shape when they are displayed. When this attribute is set to TRUE$ a “balloon” shape is used instead, with a stem pointing to the owning tool.  The default value is FALSE$.

Balloon style tooltip

Balloon style tooltip


Tooltips normally display themselves at an offset to their tool – when this attribute is set to TRUE$ the tooltip is centered underneath the tool instead.  The default value is FALSE$.

Tooltip with center-style

Tooltip with center-style

Basic+ example:

   // Example: display a multiline balloon tooltip containing a warning icon 
   // and title for a static control called TXT_ALERT

   declare function rti_ErrorText
   $insert ps_Tooltip_Equates
   $insert logical

   tooltip = ""
   tooltip<PS_TOOLTIP_POS_TEXT$>    = rti_ErrorText( "SP", errorCodes )
   tooltip<PS_TOOLTIP_POS_TITLE$>   = "Woeful tidings"
   tooltip<PS_TOOLTIP_POS_ICON$>    = PS_TOOLTIP_ICON_WARNING$  ; // "!"

   call set_Property_Only( @window : ".TXT_ALERT", "TOOLTIP", tooltip )

The TOOLTIP property applies to all controls except OLE controls, as these usually provide their own tooltips.  Some controls, such as List Box and Toolbar controls, also support different types of tooltips such as in-place and tracking, and these will be described in a future post.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

Object Notation Syntax

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


  • object is either:
    1. An equated constant (suffixed with a “$” symbol), or
    2. The contents of a variable (prefixed with an “@” symbol), or
    3. An embedded name (prefixed with the “$” symbol), or
    4. 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  
 // PropVal = Get_Property( CTRLID$, "TEXT" )
 PropVal = CTRLID$->Text
 // PropVal = Get_Property( CTRLID$, "LIST", 4 ) 
 PropVal = CTRLID$->List{4}
 // 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
 // Call Set_Property_Only( CTRLID$, "TEXT", PropVal )
 CTRLID$->Text  = PropVal
 // Call Set_Property_Only( CTRLID$, "LIST", PropVal, 4 ) 
 CTRLID$->List{4} = PropVal
 // 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


  • object is either:
    1. An equated constant (suffixed with a “$” symbol), or
    2. The contents of a variable (prefixed with an “@” symbol), or
    3. An embedded name (prefixed with the “$” symbol), or
    4. 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
 // 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


 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
 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:

  1. 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.
  2. 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 <table> and <record> with the table and record names of your choice:

   #Pragma Output <table> <record>

E.g. Send the output to the PRECMP_OUT record in SYSLISTS


(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).