Programming Guide: Considerations for the Application Developer

# Programming Guide

## Considerations for the Application Developer

OpenDoc allows you to create program scripts (routines) and attach them to events from within your application. Events change the state of a part. When an event is identified, the script implementing the event routine is called.

The following direct scripting systems are supported by OpenDoc:

- Lotus Script

  If developing a script through Lotus Script, consult the Lotus Scripting guide for information.

- Visual Basic

  If developing a script using Visual Basic, all normal rules pertaining to Visual Basic must be followed.

Through these systems, you can design, attach, and execute code to generate the events that a scriptable part identifies and invokes the methods of those parts.

An example of scripting would be to attach a script to a timer part. When the timer reaches a certain count, a script would run to back up a database.

### Lotus Script Scripting

The Lotus Script Interactive Development Environment (LS IDE) is a tool for managing BASIC scripts associated with various IBM and Lotus products. The LS IDE implements the Scripting Component interface. This interface is delivered as part of the base OpenDoc runtimes. The LS IDE provides a compact and effective user-interface for editing, debugging, and browsing the BASIC code associated with scripted OpenDoc parts. For additional information, see "Script Component".

To participate in OpenDoc Direct Scripting, the LS IDE was extended to include SOM usage bindings. SOM usage bindings provide a language-native mechanism for creating, destroying, sending messages to, and invoking methods on SOM objects.

The following BASIC code fragment creates a SOM Object, sends the message `SayHello`, and deletes the object.

            Dim helloWorld as New ASOMObject
            helloWorld.SayHello
            delete helloWorld

The LS IDE also serves as a debugger for the script code created. A complete set of help for the language and for the LS IDE is available online by running the LS IDE and selecting the Help menu item.

#### Creating OpenDoc References

You can create references to OpenDoc parts in the following ways:

1. In an event, the object reference triggering the events is passed to the event subroutine as the first argument. For example, `SUB MouseDown` (source as ScriptableSimplePart, x as long, y as long). The source argument refers to the object that caused the MouseDown event and can be used to send messages and query properties.

2. When OpenDoc parts are registered with the Lotus Script IDE, they are given a name. These names appear in the object combo-box in the upper left corner of the IDE. OpenDoc objects can be referenced from your script code by using the "bracket syntax," that provides dynamic resolution of the name to the associated OpenDoc part. The script code can contain "named" references to objects that are dynamically created after the script code is compiled. For example, if your application includes a ScriptableBaseContainer, named BCPart, and an embedded ScriptableSimplePart, named Part_SPart, the following code could be used in the BCPart's script to set the color of the ScriptableSimplePart using its Setcolor method:

       [Part_Spart].setcolor 255

3. The set statement can be used to associate a named object with a local object variable to simplify coding. The bind option to this statement specifies the class name of the object that is being named. For example, the following statement allows the script to use the variable `lvar` to reference the ScriptableSimplePart named `Part_`:

       dim lvar as ScriptableSimplePart
       ...
       Set lvar = Bind ScriptableSimplePart ("Part_SPart")
       ...
       lvar.setcolor 128
       [Part_SPart].setcolor 128

   Note:

   > The name of the object as used in this statement is a string expression and could be constructed, if appropriate.

#### Initializing and Terminating Events

The Initialize and Terminate events are generated by the Lotus Script IDE. They are not generated by the OpenDoc parts. The Initialize event provides a mechanism for your script code to establish a default running context, such as initializing globals or opening default files, when the part is initialized. The Terminate event enables your script to cleanup before the object is deleted.

##### Runtime

The Initialize event is called once when the first event arrives to the part. The Terminate event is called when the part is deleted from the scripting component. Generally, the Terminate event occurs when a document is closed.

##### Development Time

The Initialize and Terminate events may be called several times during the development of scripts. Editing a script will reset the object owning the event. Resetting an object send the Terminate event to the object owning the script and triggers the Initialize event when the first new event arrives on the part.

In a given scripting context, the Initialize and Terminate events are only generated for the root object in the scripting context. The contained objects' Initialize and Terminate events should not be scripted because they are not fired. To attach script code to embedded objects' Initialize and Terminate events simply edit the scripts for the embedded object.

#### Programming Considerations

The following sections describe parts of the Lotus Script language that have specific implementations for their use with OpenDoc.

##### CORBA Type-Mapping to Lotus Script

The following list describes the mapping from CORBA data types (used by SOM and OpenDoc classes) to their Lotus Script equivalents:

CORBA | Lotus Script Equivalent
tk_any | Not supported
tk_array | Not supported
tk_boolean | Short
tk_char | Short
tk_double | Double
tk_enum | Not supported
tk_float | Single
tk_long | long
tk_null | Not supported
tk_octet | Short
tk_objref | Object Reference
tk_pointer | Not supported
tk_Principal | Not supported
tk_sequence | A collection, see "Sequence CORBA Data Type Mapping".
tk_short | Short
tk_string | String
tk_struct | Not supported
tk_TypeCode | Not supported
tk_ulong | Long, see "Unsigned CORBA Data Type Mapping"
tk_union | String
tk_ushort | Short, see "Unsigned CORBA Data Type Mapping"
tk_void | Void

##### Sequence CORBA Data Type Mapping

CORBA sequences are mapped to the collection data type in Lotus Script. This Lotus Script data type is the forall construct. Lotus Script collections are readonly and therefore cannot be changed. While the collection can not be modified, the items in the collection can be modified or accessed and methods can be invoked. For example:

         forall item in obj.somSequence
                item.HelloWorld
         end forall

##### Unsigned CORBA Data Type Mapping

Lotus Script BASIC does not support unsigned data types. CORBA unsigned data types are mapped into signed Lotus Script types. The Scripting user must take special care when comparing unsigned data type values.

#### Supported Event Return Types

The SOM usage bindings for events supports the following return types for triggered events:

- tk_void
- tk_short
- tk_long

All other return types cause a registration failure on the event. When a non-conforming return type is encountered, the registration process does not add the event to the list of scriptable events.

#### SOM IDL Conversion to Lotus Script

The following sections describe the special considerations for using the LS IDE with OpenDoc and additions made to the LS IDE for OpenDoc. Review these consideration when developing scriptable interfaces for parts you plan to script with the LS IDE.

When designing the scriptable interface for a part you should keep the interface as straight forward as possible for the script writer. For example:

      interface SimpleScriptablePartInterface {
              attribute long Color;
      #ifdef __SOMIDL__
              implementation {
                      Color:ODId=1000
              };
      #endif
      };

The above scriptable interface is presented to the LS IDE as:

            class SimpleScriptablePartInterface
                    Dim Color as Long
            end class

##### Parameter Modifiers

The out and inout parameter specification applied to objects is not supported by the Lotus Script engine.

#### Object Lifecycle

The Lotus Script engine implements a garbage collected environment based on reference counting and language scoping rules. The lifecycles of objects created within the scripts are managed by the script engine using reference counting. Objects created by the Lotus Script engine can be destroyed by the script engine, but objects registered using the script component interface and objects returned to the scripting environment from methods are not destroyed by the script engine. In these cases, the script engine does not take ownership of the object as defined by CORBA. When a CORBA tk_string is returned to the Lotus Script engine ownership passes to the script engine. In all cases, the part developer should follow the CORBA ownership rules for parameters and return values.

#### Inheritance Considerations

Registering a class registers the superclasses of the class. Therefore, the superclasses must be accessible to the registration process. Ensure the superclasses of the class are placed into the SOM Interface Repository along with the class itself. Failure to register a parent class results in a failure to register the child class.

The LS IDE supports single inheritance. Therefore, only the leftmost branch of and object's parent chain will be registered.

The Lotus Script scripting component attempts to load the interface exposed by a scriptable object. When the Lotus Script engine encounters unsupported data types, the particular property, method, or event is not registered. However, the registration process is not terminated. The Lotus Script scripting component will register the total interface exposed by a scriptable object. The total interface encompasses the object's parents and the classes of object used in methods, properties and events. For example, in the following interface:

      interface SimpleScriptableInterface {
              AnotherObject ReturnObject()
      #ifdef __SOMIDL__
              implementation {
                      ReturnObject:ODId=2000;
              };
      #endif
      };

Registering the method `ReturnObject` will cause the LS Scripting Component to also register the class `AnotherObject`. Therefore the meta-data describing `AnotherObject` must be available. If the meta-data for `AnotherObject` is not available the method will not be registered. Meta-data refers to the information maintained in the SOM Interface Repository when a part's IDL is compiled using the -u SOM compiler flags.

#### Runtime Considerations

At runtime, the SOM Interface Repository is not consulted for the properties, methods, and events registered during design time. The information registered during design time is cached during the saving operation of the scripted OpenDoc document with the compiled scripts. Caching this information improves loading and running compiled scripts.

Note:

> If the scriptable SOM interface for an object changes, ensure that the version number is set to reflect the new changes. Refresh the cache by recompiling the script. If you fail to recompile the script after an object changes, the object will use the previously cached version of the object description.

#### Modifications to the Lotus Script IDE

The following sections describe the modifications made to the Lotus Script IDE to support OpenDoc scripting. The modifications are mainly centered around the dialogs for loading, saving, and preference setting within the environment. For a complete description of the LS IDE's functioning, see the online help.

##### The Menu Bar

The LS IDE panel is shown in Figure 68. This section describes the menu structure for the LS IDE and what action each menu item invokes.

Figure 68. Lotus Script Interactive Development Environment

View figure.

###### File Menu

The File menu has the following items:

- Import loads a previously saved file containing script code associated with a set of scriptable objects into the current script presented in the IDE.
- Export saves the scripts associated with the current object selected in the Object combination box.
- Export Section saves only the script currently displayed in the LS IDE.
- Export All Parts saves all scripts associated with the parts currently registered in the LS IDE.
- Exit closes the LS IDE. The scripts remain associated with their OpenDoc parts.

###### Edit Menu

The Edit menu has the following items:

- Undo Edit reverses the last edit operation
- Redo reverses the last undo edit operation.
- Redo All reverses all undone edit operations on the undo stack.
- Cut removes the selected text and places it on the clipboard.
- Copy copies the selected text to the clipboard.
- Paste pastes the text from the clipboard at the current insertion point.
- Clear removes the entire content of the window removing the event, function, or sub from the list of scripts.
- Select All selects all the text displayed in the LS IDE window.
- Deselect All deselectes all selected text.
- Find/Replace invokes the Find/Replace dialog.

###### Script Menu

The Script menu has the following items:

- Script Properties invokes the Script Properties dialog box (see Figure 69).
- Run This Sub compiles and runs the function or sub currently displayed in the LS IDE editor. Only functions or subs that do not take arguments can be tested using this menu command.
- Check Script Syntax checks the syntax of the currently loaded script.
- New Function invokes the New Function dialog. Another way to create a new function or sub is to enter the declaration and then press Enter. This adds the new function to the LS IDE and moves the selection to the new function.
- New Sub invokes the New Sub dialog.

###### Run Menu

The Run menu has the following items:

- Go runs or continues execution of the script.
- Stop exits debugging mode.
- Test events from the OpenDoc objects will be passed to the scripts associated with those objects, when checked. When not checked, events are not passed to the scripts.
- Step steps into the function or sub at the current execution point. If the current part is a sub or function call, steps into that routine.
- Step Over steps over the function or sub call at the current execution point.
- Step Exit exits the function or sub and continues with the statement following the next call. Stops at the start following the call to this function.
- Set Breakpoint/Clear Breakpoint sets a breakpoint if one does not exist on the current line of the LS IDE. Clears a breakpoint if one is set on the current line.
- Enable Breakpoint/Disable Breakpoint enables a breakpoint at the current line if one exists and is disabled. Disables a break point at the current line if one exists and is enabled.
- Clear Breakpoints clears all break points.
- Disable Breakpoints/Enable Breakpoints disables or enables all breakpoints.
- Breakpoints shows the breakpoints panel in the LS IDE.

###### Help Menu

The Help menu has the following items:

- Contents invokes the help associated with the LS IDE.
- About shows the About box for the LS IDE.

##### Script Properties Dialog

This section describes the Script Properties dialog box (see Figure 69). The script properties affect the behavior of the LS IDE.

Figure 69. Script Properties Dialog

View figure.

###### Formatting

- UndoEnable is a check box that toggles the undo feature of the LS IDE editor on or off. When you check this box, the undo feature is enabled.
  - Undo Levels specifies the number of undo operations to maintain in the undo stack. The range of values for this field is 0 to 15.

    Note:

    > You can only use this field when you select UndoEnable.

- Auto Indenting is a check box that toggles the automatic formatting of the source code in the LS IDE editor. When you check this box, the auto indent feature is enabled.
  - Tab Width specifies the number of spaces to insert into source code when you press the tab key. The range of values for this field is 0 to 20.

    Note:

    > You can only use this field when you select AutoIndenting.

- Show Error Count Dialog is a check box that toggles the display of the error count dialogs. When you check this box, the error count feature is enabled.

###### Colors

To change the color of a category, select the color sample with the selection mouse button. You can change the color for the following members.

- Identifiers is the color used to display language identifiers.
- Keywords is the color used to display language keywords.
- Errors is the color used to display language errors.
- Directive is the color used to display language directives.
- Comments is the color used to display language comments.

After selecting the sample color, the Platform Color dialog is displayed. Select the color you want to use with the mouse. This new color is the color in which this member will be displayed.

###### Font

When you select the Font button from the Script Properties dialog box, it invokes the Platform Font Selection dialog for the font in which to display the source code. select the font you want to use. This font selected the new text font for the source code.

##### Find/Replace Dialog Box

The Find/Replace dialog is available from the Edit submenu of the LS IDE menu. Use the dialog to search for a specified text string and optionally replace it with another. This dialog box contains the following input and selection fields:

- Find is the entry field for the search text.
- Replace with is the entry field for the replacement text.

The Options section specifies search parameters on the search string. These parameters are as follows:

- Wrap Around is a check box to select if you want the search to wrap to the top of the search selection.
- Case Sensitive is a check box to select if you want the search to be case sensitive.
- Accent Sensitive is a check box to select if you want the search to be accent sensitive.
- Backward is a check box to select if you want to search to the top of the source.
- Whole Word is a check box to select if you want the search to only match to the exact text specified.

The Part Scope and Section Scope sections specify which objects and scripts to search for the text string. A part equates to an object and a section equates to a script. The specifiers for these section are as follows:

- Current Part is a check box to select if you only want to search the specified script or scripts for the current object type.
- All Parts is a check box to select if you want to search the specified script or scripts for all objects in the Part Scope section of the LS IDE.
- Current Section is a check box to select if you only want to search the current script for the object or objects in the Part Scope section of the LS IDE.
- All Sections is a check box to select if you want to search all scripts for the object or objects in the Part Scope section of the LS IDE.

### Visual Basic Scripting

This section contains instructions for doing OpenDoc scripting with Visual Basic. These instructions cover how to call your OpenDoc Part and how to access the OpenDoc Part properties inside a Visual Basic program.

Before reading this section, you should know how to program in Visual Basic, how to develop an OpenDoc Part, and the principles of OpenDoc Scripting.

#### Embedding an OpenDoc Part into a Visual Basic Form

To embed your part into a Visual Basic form, perform the following:

1. Start Visual Basic (32-bit). Do not start Visual Basic with the double-click method unless you are positive that all environment variables are set correctly. If you are unsure of the environment variables start from the command line.
2. Open the project.
3. Select the OLE icon from the toolbox.
4. Draw the rectangle in the form.
5. Select the part from the dialog box, then select the OK push button. If your part is not in the dialog box, there is a problem. See "Troubleshooting Hints" in the OpenDoc Problem Determination Guide for additional information.

   If there are no problems, the OLE object is created as `ole`n, where n is a numeric value.

#### Writing a Visual Basic Program to Access the Part.

The Visual Program should contain the following sections.

- Create and set the object.
- Call the method and access the property.

##### Creating and Setting the Object

You must declare and set an object to be the embedded OpenDoc Part. For example:

       DIM obj as object
       Set obj = ole1.object

##### Calling Method for Accessing the Property

After the object has been set, you can use it as any other object. You could use it to get a property value, to set a property value, or to call a method. For example:

       obj.method1 parameter1
       obj.property1 = "abc"
       i = obj.property2

#### Perform Event Handling

If your part supports event callback, you should not directly embed it as an OLE object. You should make your part as a custom control and add the control to the form. The procedure is as follows:

1. Create the TYPELIB for the part and run the scriptrg command.
2. Click the Tools menu and select the Custom Control menu item. In the dialog box, select your part.

   Note:

   > If your part is not in the list, run the scriptrg command.

   Click the OK button. A new control icon should show up in your toolbox.
3. Select the new control icon. Draw a sized rectangle in the form. All the event handling function prototypes should be added to your code. You must write functions to handle all the events.

[ Top | Previous | Next | Contents | Index | Documentation Homepage ]