skip to main content
OpenEdge Development: ADM and SmartObjects
SmartLinks : Defining SmartLinks in Progress applications
Defining SmartLinks in Progress applications
You are not restricted to using only the SmartLinks installed with the Progress product in your application. You can define additional SmartLinks for the ADM, either static SmartLinks, which use a standard event support structure and whose run‑time behavior is predefined, or dynamic SmartLinks, whose run‑time behavior varies depending on application‑user choices. The following sections provide information on defining both types.
Defining static SmartLinks
When you define a new, custom, static SmartLink, you must provide the following support structure for standard events:
*The template for a SmartObject that will use the new SmartLink must define a preprocessor value called ADM-SUPPORTED-LINKS. This value is a comma‑separated list of links this object supports. This list becomes the initial value of the SupportedLinks property when the object is initialized; however, you can modify the associated instance property value at run time (before the object is initialized) if an application condition changes the links that the SmartObject must support.
Note: The Container and PageN links are supported implicitly and do not need to be on this list.
*The source object for the link must define a property named linkTarget, where link is the base link name such as Data, and the target object must define a property linkSource, along with getpropname and setpropname functions to get and set the values for those properties. The data type of the property indicates whether the link supports multiple objects on either end:
*A HANDLE data type means only one object is allowed; its procedure handle is stored in its native data type. This is the typical case for the source for the standard ADM links, which generally support only one source SmartObject.
*A CHARACTER data type indicates multiple objects can be at that end of the link; their handles are stored in string format as a comma‑separated list. This is typical for the target for the standard ADM links, which generally support multiple target SmartObjects.
For example, a Data-Source can have multiple Data-Targets, but a Data-Target can have only one Data-Source. The addLink procedure uses these properties to store the handles of related objects and determine whether one object or multiple objects are permitted.
*Any events associated with the link must be defined in a property in the source called linkTargetEvents, where link is the base link name such as Data, and/or in the target in a property called linkSourceEvents. This property is a comma‑separated list of events to subscribe to. For example, a SmartContainer (which can be a Container-Source) has the following:
*A ContainerTarget property of type CHARACTER, where the addLink procedure stores the handles of its Container-Target procedures at run time.
*A ContainerTargetEvents property, which is initialized in the property include file cntnprop.i to exitObject, the one event a Container must subscribe to in its target.
Likewise, all SmartObjects that can be Container-Targets have the following:
*A ContainerSource property of type HANDLE (defined in smrtprop.i, because it applies to all SmartObjects), where addLink stores the handle of its Container-Source at run time.
*A ContainerSourceEvents property, which is initialized in the property include file to a list of all the events to which the Container-Target must subscribe in its Container-Source and for which it must implement event procedures (“initializeObject,destroyObject ”).
These property values also can be modified at run time, before the object is initialized, to change the list of events to which the object will subscribe in that particular instance. The addLink procedure then subscribes to each event in the list using the source and target handles. Normally, the getpropname and setpropname property functions and the event procedures are implemented in the super procedure for the object (containr.p for links defined in cntnprop.i, smart.p for links defined in smrtprop.i, and so on).
Once you account for all these requirements, the ADM takes care of all necessary mechanics of handling events between SmartObjects automatically.
You also can define standard Supported Links programmatically, by writing calls to addLink in an application. Likewise, you can remove them by running the removeLink procedure.
Defining dynamic SmartLinks
Sometimes a SmartObject application requires a link that passes messages between SmartObjects more dynamically; that is, the particular message to be passed (and any resulting processing) is determined by an application user’s run‑time choice. This type of link is a dynamic SmartLink.
When you define a dynamic SmartLink, you do not need to provide the support structure for standard events required for static SmartLinks (see the previous section for details). If, at design time, you define between two SmartObjects a SmartLink not in the SupportedLinks list for either object, the addLink procedure registers the link as a subscription to an event of the same name as the links. (You also can do this programmatically, by running addLink in application code.)
The following example illustrates how to define a dynamic SmartLink. This SmartLink, called ProcessCalc, links a simple SmartObject and a SmartDataObject, passing messages that invoke processing in the SmartDataObject. The particular message sent, and the processing invoked, are determined at run time by the choice of the application user.
To define the ProcessCalc dynamic SmartLink, in the AppBuilder:
1. Create a SmartDataObject that contains an internal procedure named ProcessCalc that has the following code:
CASE pcCalcType:
  WHEN "Totals":U    THEN RUN calcTotals.
  WHEN "Discounts":U THEN RUN calcDiscounts.
2. Create the code for the calcTotals and calcDiscounts procedures.
3. Create a simple SmartObject called sCalcPanel.w that contains two buttons named Calculate Totals and Calculate Discounts, and add the following trigger code to these buttons:
ON CHOOSE OF btnCalcTotals DO:
  PUBLISH "ProcessCalc":U (INPUT "Totals":U).
ON CHOOSE OF btnCalcDiscounts DO:
  PUBLISH "ProcessCalc":U (INPUT "Discounts":U).
4. Create a SmartWindow.
5. Drop the SmartDataObject onto the SmartWindow.
6. Drop the sCalcPanel.w simple SmartObject onto the SmartWindow.
7. Add a SmartLink as follows:
a. Invoke the Link Advisor.
b. Choose Add. The Add a SmartLink dialog box appears.
c. Choose h_sCalcPanel as the source.
d. Choose New... as the Link Type.
e. Enter ProcessCalc as the New Link Type.
f. Choose the SmartDataObject as the target.
g. Click OK.
When you run this application:
*Choosing the Calculate Totals button invokes ProcessCalc in the SmartDataObject with the Totals input parameter, which runs the calcTotals procedure.
*Choosing the Calculate Discounts button invokes ProcessCalc in the SmartDataObject with the Discounts input parameter, which runs the calcDiscounts procedure.
Thus, the ProcessCalc SmartLink is dynamic, in the sense that the link name is not bound to a set of event procedure names that are statically defined in the SmartObjects.