Consultor Eletrônico



Kbase 21118: ADM2-How To Add Static Properties In The ADMProps Temp-table
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   10/16/2008
Status: Unverified

GOAL:

What are ADM2 static properties and how to add them in the ADMProps temp-table

FACT(s) (Environment):

Progress 9.x

SYMPTOM(s):

ADM2

FIX:

Static properties -- Static properties are instantiated with their initial values when the SmartObject is executed.  These properties are stored in the ADMProps temp-table and it is possible to add properties to it.  The property name is defined by the field name of the ADMProps temp-table.

ADMProps temp-table -- ADMProps is a temp-table that is created in the smrtprop.i file.  The next include files for each class in the ADM2 hierarchy add new fields to the ADMProps temp-table.  Therefore, the children class in the ADM2 hierarchy inherits the static properties from their parents, like procedures or functions.

Shown here is the ADMProps definition in the smrtprop.i include file:

&IF "{&ADMSuper}":U = "":U &THEN
 CREATE TEMP-TABLE ghADMProps.
 ghADMProps:UNDO = FALSE.
 ghADMProps:ADD-NEW-FIELD('ObjectName':U, 'CHAR':U, 0, ?, '':U).
 ghADMProps:ADD-NEW-FIELD('ObjectVersion':U, 'CHAR':U, 0, ?,
   '{&ADM-VERSION}':U).
 ghADMProps:ADD-NEW-FIELD('ObjectType':U, 'CHAR':U, 0, ?,
   '{&PROCEDURE-TYPE}':U).
 ghADMProps:ADD-NEW-FIELD('ContainerType':U, 'CHAR':U, 0, ?,
   '{&ADM-CONTAINER}':U).
 ghADMProps:ADD-NEW-FIELD('PropertyDialog':U, 'CHAR':U, 0, ?,
   '{&ADM-PROPERTY-DLG}':U).
 ghADMProps:ADD-NEW-FIELD('QueryObject':U, 'LOGICAL':U, 0, ?, no).
 ghADMProps:ADD-NEW-FIELD('ContainerHandle':U, 'HANDLE':U).
 ghADMProps:ADD-NEW-FIELD('InstanceProperties':U, 'CHAR':U, 0, ?,
   '{&xcInstanceProperties}':U ).
 /* NOTE: Any need to support &User-Supported-Links?? */
 ghADMProps:ADD-NEW-FIELD('SupportedLinks':U, 'CHAR':U, 0, ?,
   '{&ADM-SUPPORTED-LINKS}':U).
 ghADMProps:ADD-NEW-FIELD('ContainerHidden':U, 'LOGICAL':U, 0, ?, NO).
 ghADMProps:ADD-NEW-FIELD('ObjectInitialized':U, 'LOGICAL':U, 0, ?, no).
 ghADMProps:ADD-NEW-FIELD('ObjectHidden':U, 'LOGICAL':U, 0, ?, yes).
 ghADMProps:ADD-NEW-FIELD('UIBMode':U, 'CHAR':U, 0, ?, '':U).
 ghADMProps:ADD-NEW-FIELD('ContainerSource':U, 'HANDLE':U).
 ghADMProps:ADD-NEW-FIELD('ContainerSourceEvents':U, 'CHAR':U, 0, ?,
   'initializeObject,hideObject,viewObject,destroyObject,enableObject,confirmExit':U).
 ghADMProps:ADD-NEW-FIELD('DataSource':U, 'HANDLE':U).
 ghADMProps:ADD-NEW-FIELD('DataSourceEvents':U, 'CHAR':U, 0, ?,
   'dataAvailable,queryPosition,deleteComplete,fetchDataSet,confirmContinue,assignMaxGuess':U).
 ghADMProps:ADD-NEW-FIELD('TranslatableProperties':U, 'CHAR':U, 0, ?,
   '{&xcTranslatableProperties}':U).
 ghADMProps:ADD-NEW-FIELD('ObjectPage':U, 'INT':U, 0, ?, 0).
 ghADMProps:ADD-NEW-FIELD('DBAware':U, 'LOGICAL':U, 0, ?,
 &IF DEFINED (DB-AWARE) NE 0 &THEN
   {&DB-AWARE}).
 &ELSE
   no).
 &ENDIF
 ghADMProps:ADD-NEW-FIELD('DesignDataObject':U, 'CHAR':U, 0, ?,'':U).

&ENDIF

Since smrtprop.i is an include file of the smart.i file, the static properties for every object in the ADM2 hierarchy are defined in this procedure.  The next classes in the hierarchy add their own properties; for example, visprop.i adds the static properties for visual objects (SmartDataViewers and SmartDataBrowsers).  This shows the fields defined in visprop.i:

&IF "{&ADMSuper}":U = "":U &THEN
 ghADMProps:ADD-NEW-FIELD('ObjectLayout':U, 'CHAR':U, 0, ?, '':U).
 ghADMProps:ADD-NEW-FIELD('LayoutOptions':U, 'CHAR':U, 0, ?, '':U).
 ghADMProps:ADD-NEW-FIELD('ObjectEnabled':U, 'LOGICAL':U, 0, ?, no).
 ghADMProps:ADD-NEW-FIELD('LayoutVariable':U, 'CHAR':U, 0, ?, '{&LAYOUT-VARIABLE}':U).
 ghADMProps:ADD-NEW-FIELD('DefaultLayout':U, 'CHAR':U, 0, ?, '':U).
 ghADMProps:ADD-NEW-FIELD('HideOnInit':U, 'LOGICAL':U, 0, ?, no).
 ghADMProps:ADD-NEW-FIELD('DisableOnInit':U, 'LOGICAL':U, 0, ?, no).
 ghADMProps:ADD-NEW-FIELD('EnabledObjFlds':U, 'CHAR':U, 0, ?, '':U).
 ghADMProps:ADD-NEW-FIELD('EnabledObjHdls':U, 'CHAR':U, 0, ?, '':U).
&ENDIF

ADMProps temp-table has one record -- this record is initialized by the initial field values.

Before adding a new field in the ADMProps temp-table, the preprocessor definition for this field must be added.  The preprocessor varia.ble name must have the field name plus the prefix 'xp'.  The following shows the preprocessor definitions for the fields in visprop.i:

  &GLOB xpObjectLayout
  &GLOB xpLayoutOptions
  &GLOB xpObjectEnabled
  &GLOB xpLayoutVariable
  &GLOB xpDefaultLayout
  &GLOB xpHideOnInit
  &GLOB xpDisableOnInit
  &GLOB xpEnabledObjFlds
  &GLOB xpEnabledObjHdls


These preprocessor definitions are important in order to improve performance using {get} and {set}.  The {get} and {set} include file should be used to get and set static properties.  The following example uses {get} and {set}:


/*-----------------------------------------
 Get the DataSource handle and store it in
 The hHandle variable.
-----------------------------------------*/
DEFINE VARIABLE hHandle AS HANDLE NO-UNDO.

{get DataSource hHandle [target-handle]}


/*-------------------------
 Set h_dCust as DataSource
-------------------------*/
{get DataSource h_dCust [target-handle]}

These include files check first if the preprocessor variable is defined.  If true, the value will be set directly in or gotten directly from (get) the ADMProps temp-table, otherwise the dynamic-function for the specified property will be executed.

After defining the preprocessor variable and creating the new field in the ADMProps temp-table, the get and set dynamic functions for this property should be created.  The name of these functions must be the property name, plus the prefix get or set.  The following code for the HideOnInit property in the visual.p super procedure provides a good example:


FUNCTION getHideOnInit RETURNS LOGICAL
 (  ) :
/*--------------------------------------------------------------
 Purpose:  Returns a flag indicating whether the current object should be
           left hidden when it is first initialized.
  Params:  <none>
--------------------------------------------------------------*/

 DEFINE VARIABLE lHide AS LOGICAL NO-UNDO.
 {get HideOnInit lHide}.
 RETURN lHide.

END FUNCTION.

As shown in the example, the dynamic function uses the {get} or {set}
include file, therefore using this include directly in the application
results in better performance.

It's very important to define this dynamic function because the
developer could choose between using the {get}/{set} include files or
dynamic-function statement.  

Another reason to create the dynamic functions is for the use of Open
Client.  When using Open Client it is not possible to use {get}/{set}
include files; these include files are Progress 4GL programs and can
not be used with Java or Visual Basic.  When creating the prototype
file, these functions will be included in it, therefore the proxy file
will have them and they can be accessed by the Open Client code..