<<

Using Component (COM) components in Plex applications

Summary:

This document explains the various ways COM components can be included and controlled in Plex applications and how to choose the approach and best practices which best fit your requirements. Some recommendations are provided which supplement the Plex 6.1 product documentation in the areas of:

 efficient component instance management  reducing package build size and compile times  COM versioning and upgrade procedures

Description:

1. Introduction

There are two ways in which COM components can be placed into the design of a Plex application. Firstly, components with a visual element, known as ActiveXs, can be inserted directly into a panel design. Alternatively, entire COM packages can be imported into a Plex model via the COM Import facility and Plex field objects then set up to reference the desired components. Those Plex field objects can be added to panel designs and functions to provide functional entry points for ActiveXs and non-visual components alike.

There is no restriction on the number of ActiveXs that can be placed on a panel, even multiple instances of the same ActiveX. Thus, a panel that requires the input of several dates could achieve this by using multiple instances of the same calendar ActiveX. It is possible to mix and match, by using ActiveX controls directly added to panels with those included by fields that reference the same or different ActiveXs. 2. Panel Designer and COM Import

2.1. Including a COM object using ActiveX Hosting

An example of how to include an ActiveX directly into a panel design is given below. Positioning in an empty area of the design canvas and pressing the right mouse creates a pop-up menu with an option to create an ActiveX control. This option shows a list of registered controls and selecting one and pressing the Create button adds an instance to the design canvas:

1

2

3 2.2 Including a COM object using COM Import

COM Import requires an infrastructure of the shipped group model called COMPONENTS as a model and the mappings in the configuration file PlexComImport.cfg in the Plex product directory. The pairing gives the mappings between Plex and COM native data types. The next example brings in the same ActiveX as part of a COM Import process and creates model objects. The main Tools menu Import option has a sub-menu Component Import option. This invokes a Component Import Wizard, which allows a selection of COM components to be imported and creates Plex objects for the components imported:

1

2

3 4

5

Having imported a package, the visual component it supports can be added to a panel design by dragging and dropping it from the Object Browser. Unlike a freestanding ActiveX, one added by drag- and-drop must belong to a region, because it will be associated a field that will reference the component. When dropped in an area not occupied by a region, a region will be prompted for and then a control name, which will also serve as the name of the referencing field, visible in the Panel Palette and whose properties can be inspected in the Model Editor:

2 1

3

4

If a referencing field already exists, the same effect can be achieved by dragging-and-dropping that field from the Object Browser to a panel design region.

3. Interaction and control

ActiveXs in panel designs, regardless of how they arrived, can have their properties set in the Panel Designer. Additionally, they can have any physical events mapped to panel logical events, which can then be processed by the parent function’s Action Diagram. The disadvantage of handling events in this way is that any parameters associated with the event are not available for interrogation in the Action Diagram.

Both types of ActiveX can be controlled by Action Diagram statements that make API calls using Plex source code objects that contain scripts. These will be executed by the Plex Windows ++ runtime in an ActiveX scripting environment that gives access to Action Diagram variables. However, the scripts need knowledge of the names that have been assigned to the ActiveX controls.

Alternatively, ActiveXs derived from referencing fields can be controlled without resorting to scripts, as long as their events that have not been mapped to logical events in the Panel Designer. In the controlling function’s Action Diagram, Event statements can be used to detect particular events for each ActiveX and any event parameters will be available via Action Diagram variables and data:

Additionally, any data, including references to COM objects, can be passed within and between functions and calls can be made to any COM methods directly. This gives greater integration within Plex and removes the need for separate maintenance of scripts. 4. Implementation

COM objects that are placed on panel designs are created and initialised when that panel is first shown. Any other COM objects that are needed should be created by using an Action Diagram assignment statement using New.

COM objects that are based on the COM Import facility are implemented using a wrapper layer, created by generating and building the corresponding package object in Plex. The advantage of this approach is that it employs defensive code to detect and prevent potential GPFs and it automatically handles the transformation between Plex and Com native data types. As long as COM implementers have complied with COM standards, a Plex application using COM will work with any version of the COM objects at or later than the version imported into Plex.

Plex COM Import and wrapper generation is now mature and even problematic COM objects can be coerced with use of compilation import attribute overrides, which are specified via a triple. Whereas earlier releases of COM wrapper runtime support relied upon users to maintain correct object reference counts by use of the Action Diagram DeleteObject statement, Plex 6.1 (PTF build 043.017 onwards) now handles this aspect automatically. Plex will automatically clear up references when objects go out of scope or when applications close. DeleteObject is now only required where object deletion is specifically wanted and checks are made that double deletions do not occur.

5. Tips and best practices

If only a basic level of interaction is required, the obvious choice is to insert ActiveX controls directly onto panel designs and control interactions in Action Diagrams with scripts placed in source code objects. If extensive interaction is required and/or more complete integration with Action Diagrams and the pattern capabilities of Plex, then COM Import will be the preferred route.

Direct COM Import Pros Cons Pros Cons Need VB script Quick Extensible Slow (multi-step) expertise Easy integration with Simple way of Separate maintenance Plex Action Diagram improving GUI overhead patterns Hard to extend No scripting

functionality knowledge required Hard to integrate with Plex Action Diagram patterns

If you have imported a COM component and the final, application is deployed in an environment that uses a later version of that component; there should be no problem, as long as the component implementers have adhered to the rules of COM versioning. If you need to re-import a component to take advantage of new functionality in a later version, then Plex will allow more than one version to exist in the model (Plex normally appends version information to the name to aid distinction). This is usually better than deleting the old version, because links from fields and Action Diagrams to the old components will be broken. It is better to start the process by making a later Plex configuration level for the task and then import a later COM version. Not only are links maintained, but the entire old application can be built or maintained without preventing any enhancement from progressing. After re-import, reference fields can be changed to point to the new version and links can be modified to call the later version by changing Action Diagram calls or using ‘replaces’ triples. Again, by making the changes at a later configuration level, the earlier level details will be preserved.

COM Import can bring in large packages, with many components, interfaces, methods and properties. This will result in a large code size for generated wrappers and compiled programs. In these circumstances, any components or interfaces that are not used or referenced can be deleted from the model because the wrapper needs only to address the parts of the package actually used and the final code for the application can be significantly reduced.

Creating component instances may represent a significant overhead and can lead to performance degradation if the component is large or complex and instances are created often. It is not possible to stop Plex creating ActiveXs that appear on panels, or to update their references. However, it is possible to improve performance for components subject to frequent New or DeleteObject operations. Firstly, DeleteObject operations are no longer necessary because the Plex runtime will look after and so these statements can be removed. Secondly, unnecessary New operations can be avoided either by passing existing references as function parameters or by cast or assignment statements.

One way to share a frequently used component within an application is to create the component when the application is started and to store a reference to it in an application’s global properties. The original reference can be allowed to lapse, as the Plex Windows C++ runtime looks after any reference counting for global properties that refer to COM objects (Plex 6.1 Windows C++ Runtime PTF build 043.017 onwards). When the component is required again, the reference can be read from global properties again. The Plex Windows C++ runtime provides two for this purpose: SetValue and GetValue. The calling code can be placed in source code objects and adding parameters to allow customized use. Within Action Diagrams API Call statements can be added that call these source code objects. An example is given of how to create and use a global for an imported Scripting File component:

Objects and triples

Source code details

Action Diagram statements and parameter mappings