Screen description

This chapter discusses:

Screen description and screen recognition are related and intertwined topics. This chapter concentrates primarily on the process of describing screens so that they can then be recognized. It also contains enough information about screen recognition to give you a basic understanding of the relationship between the two functions. In-depth information about the screen recognition process is presented in Screen recognition

Definition of terms

Descriptor
An XML element that occurs in the <description> element of a macro screen and that states an identifying characteristic of the application screen to which the macro screen corresponds.

For example, a macro screen named ScreenB might contain a String descriptor (<string> element) that states that row 3 of the application screen contains the string ISPF Primary Option Menu. During macro playback, when the macro runtime is determining which macro screen to process next, and when ScreenB is a candidate, the macro runtime compares the descriptor in ScreenB with the actual application screen. If the descriptor matches the actual application screen (row 3 of the application screen really does contain the string), then the macro runtime selects ScreenB as the next macro screen to be processed.

Screen description
The process of adding descriptors to the <description> element of a macro screen. You engage in screen description when you use a macro editor to create or edit a descriptor for a macro screen (such as the String descriptor in the previous example). Likewise, the Macro object creates one or more descriptors for each new macro screen that it creates during macro recording (see Recorded descriptions).
Screen recognition
The process that the macro runtime performs when it attempts to match a candidate macro screen to the current application screen.

As detailed in How the macro runtime processes a macro screen, when the macro runtime needs to determine the next macro screen to be processed, the macro runtime places the names of candidate macro screens (usually found in the <nextscreens> element of the current macro screen) onto a list of valid next screens. Then, as the host application updates the host terminal with the new application screen, the macro runtime compares the descriptors of each macro screen on the list with the new application screen. Eventually the application screen is updated to the extent (for example, the string ISPF Primary Option Menu appears in row 3) that the macro runtime can match one of the macro screens on the list to the application screen. The matched macro screen becomes the next macro screen to be processed (see Overview of all 3 stages of the entire process).

For information about screen description using the VME, see Screen Recognition tab, and using the AME, see Description tab.

Recorded descriptions

During macro recording in the HCL ZIETrans host terminal, one or more descriptors is added to the new <description> element of each new macro screen that is created.

You must define the first macro screen of the macro being recorded. HCL ZIETrans automatically adds the OIA descriptor to the description of the first screen.

For every other application screen of the macro after the first application screen, you have the choice of defining the screen or allowing HCL ZIETrans to define it automatically. When HCL ZIETrans defines a screen, it creates three descriptors:

Therefore, when the recorded macro is played back (without having been revised in any way), the macro runtime matches every macro screen after the first one to its corresponding application screen based on whether the input inhibited indicator is cleared, whether the cursor position matches the cursor position of the application screen, and whether the number of input fields in the macro screen's description matches the number of input fields in the application screen.

Why the recorded descriptions work

The recorded descriptions automatically created by HCL ZIETrans work well for at least three reasons.

First, the OIA descriptor, cursor position, and number of input fields can be applied to every possible application screen. That is, every application screen has some number of input fields (perhaps the number is 0), a starting cursor position, and an input inhibited indicator that is either set or cleared.

Second, the combination of the number of input fields and the cursor position provides a pretty reliable description of an application screen, because application screens typically contain many fields, but only a certain number of them are input fields. The cursor position is always in the first input field.

Third, and perhaps most important, during screen recognition the macro runtime compares the new application screen to a short list (usually a very short list) of macro screens called valid next screens (see Stages in processing a macro screen). Therefore a single macro screen need not be differentiated from every other macro screen in the macro, only from the other screens in the list of valid next screens. Frequently the list consists of a single macro screen.

Recorded descriptors provide a framework

For some macro screens, the recorded description might not be sufficient to allow the macro runtime to reliably distinguish one application screen from another similar application screen. Macro recording is still a very useful feature because it quickly provides a framework for your macro. From there you can improve the recorded description.

Often the most straightforward way to improve a recorded description is to add a String descriptor. For example, if the macro screen is for the Utility Selection Panel, then you might add a String descriptor specifying that the application screen contains the string Utility Selection Panel somewhere in row 3. Of course you are not limited to using a String descriptor. Some situations might require that you use one or more of the other descriptors to assure that the application screen is correctly recognized.

Evaluation of descriptors

This section describes in detail how the macro runtime determines whether a macro screen matches an application screen.

Keep the following in mind as you read through the following subsections:

Overview of the process

The following is an overview of the process.

  1. The macro runtime evaluates each descriptor individually and arrives at a boolean result for that descriptor, either true or false.
  2. The macro runtime then combines the boolean results of the individual descriptors to determine whether the description as a whole is true (the macro screen matches the application screen) or false. To combine the results of the individual descriptors the macro runtime uses either the default combining method or the uselogic method.

Evaluation of individual descriptors

For each individual descriptor in the macro description, the macro runtime evaluates the descriptor and arrives at a boolean result of true or false.

For example, if the descriptor is a String descriptor, then the macro runtime looks in the application screen at the row and column that the descriptor specifies, and compares the string at that location with the string that the descriptor specifies. If the two strings match, then the macro runtime assigns a value of true to the String descriptor. If the two strings do not match then the macro assigns a value of false to the String descriptor.

Usually a macro screen contains more than one descriptor. However, if a macro screen contains only one descriptor (and assuming that the descriptor does not have the invertmatch attribute set to true) then if the single descriptor is true the entire description is true, and the macro runtime recognizes the macro screen as a match for the application screen. In contrast, if the single descriptor is false, then the entire description is false, and the macro screen is not recognized.

Default combining method

If you have more than one descriptor in a <description> element, then you must use either the default combining method described in this section or the uselogic attribute described in The uselogic attribute.

When to use the default combining method

The default combining method is appropriate for only two scenarios:

You should not use the default method for any other scenario unless you thoroughly understand how the default combining method works.

The default combining method uses:

Invertmatch attribute

Every descriptor has an invertmatch attribute.

By default this attribute is false, so that it has no effect on the evaluation of the descriptor.

If this setting is true, then the macro runtime inverts the boolean result that it obtains from evaluating the descriptor, changing true to false or false to true.

For example, if the macro runtime determines that a String descriptor is true (the string in the descriptor matches the screen in the application window), but the String descriptor has the invertmatch attribute set to true, then the macro runtime changes the String descriptor's result from true to false.

Optional attribute

Every descriptor has an Optional attribute that is set to either false (the default) or true.

The Optional attribute states how an individual descriptor's result is to be treated when the macro runtime uses the default combining rule to combine the boolean results of the descriptors. By default this attribute is set to false, signifying that the descriptor's result is required rather than optional.

Default combining rule

As stated earlier, the default combining rule is appropriate for only two scenarios:

If you want the description as a whole to be true only if all the descriptors are true, then set the Optional attribute of all the descriptors in the description to false (the default setting).

In contrast, if you want the description as a whole to be true if at least one of the descriptors is true, then set the Optional attribute of all of the descriptors in the description to true.

You should not use the default combining rule in any other scenario where you have multiple descriptors in one macro screen, unless you understand the rule and its implications thoroughly. For more information see Default rule for combining multiple descriptors in one macro screen.

Also, you should not set the Optional attributes of multiple descriptors in one macro screen differently (some true, some false) unless you understand the rule and its implications thoroughly.

The uselogic attribute

The uselogic attribute of the <description> element allows you to define more complex logical relations among multiple descriptors than are available with the default combining method described in the previous section.

HCL ZIETrans adds a default uselogic attribute to the <description> tag when you record the macro. It will be regenerated if you edit the macro in the host terminal or in the macro editors. It will not be regenerated if you edit the macro in the source view.

Note:
If you use the uselogic attribute, then the macro runtime ignores the invertmatch and Optional attributes in the individual descriptors.

The value of the uselogic attribute is a simplified logical expression whose terms are 1-based indexes of the descriptors that follow. Figure 9 shows an example of a <description> element that contains a uselogic attribute (some of the attributes of the <string> element are omitted for clarity):

Figure 9. Example of the uselogic attribute of the <description> element
<description uselogic="(1 and 2) or (!1 and 3)" />
   <oia status="NOTINHIBITED" optional="false" invertmatch="false"/>
   <string value="&apos;Foreground&apos; row="5" col="8"/>
   <cursor row="18" col="19" optional="false" invertmatch="false"/>
</description>

In Figure 9, the value of the uselogic attribute is:

(1 and 2) or (!1 and 3)

This logical expression is not a regular logical expression (as described in Conditional and logical operators and expressions) but rather a simplified style of logical expression used only in the uselogic attribute. The rules for this style of logical expression are:

In the example in Figure 9 the macro runtime will determine that the description as a whole is true if one of the following occurs:

Remember that if you use the uselogic attribute, then the macro runtime ignores the invertmatch and the Optional attribute settings in the individual descriptors.

The descriptors

Each type of descriptor is stored as an individual XML element situated within the <description> element of one macro screen.

You do not have to understand all the types of descriptors at first. Instead you should begin by becoming familiar with just the following types:

These types of descriptors are sufficient to reliably describe many and perhaps even most application screens. However, if these types are not sufficient, then you should turn for help to one of the other types of descriptors.

Table 10 lists all the types of descriptors and shows the number of descriptors of each type that are allowed to exist in one macro screen (more specifically, in one <description> element belonging to one <screen> element):

Table 10. Types of descriptors, how many of each type allowed
Type of descriptor: Number of this type of descriptor allowed per macro screen:
OIA 1 (required)
Number of Fields 0 or 1
Number of Input Fields 0 or 1
String descriptor 0 or more
Cursor descriptor 0 or 1
Attribute descriptor 0 or more
Condition descriptor 0 or more
Custom descriptor 0 or more

The following subsections describe each type of descriptor in detail.

OIA descriptor (<oia> element)

In almost all scenarios you can accept the default setting for this descriptor, which is NOTINHIBITED. Then, during screen recognition:

These are the results that you would want and expect. You typically do not want the macro runtime to recognize the macro screen and immediately start processing its actions while the input inhibited indicator is still set. (For more information about timing, see Screen completion). But no matter how you resolve that issue, you should almost always leave this descriptor at the default setting, which is NOTINHIBITED.

However, if you have a scenario in which you want the macro runtime to ignore the input inhibited condition, then set this descriptor to DONTCARE.

Number of Fields descriptor (<numfields> element)

The Number of Fields descriptor specifies a particular number of 3270, or 5250, fields. You can use an integer in the Number of Fields input field, or any entity that evaluates to an integer (such as a variable, an arithmetic expression, or a call to an external Java method).

During screen recognition the macro runtime:

  1. Evaluates this descriptor and obtains an integer result.
  2. Counts the number of fields in the application screen (in its current state).
  3. Compares the two numbers.

If the two numbers are equal then the macro runtime evaluates this descriptor as true. Otherwise the macro runtime evaluates this descriptor as false.

When the macro runtime counts the fields in the host terminal it counts all types of 3270, or 5250, fields, including input fields.

If you do not want to use this descriptor then set the Number of Fields input field to blank.

Number of Input Fields descriptor (<numinputfields> element)

The Number of Input Fields descriptor is very similar to the Number of Fields descriptor described in the previous section. The difference is that the Number of Input Fields descriptor specifies a number of 3270, or 5250, input fields, whereas the Number of Fields descriptor specifies a number of fields of all types, including input fields.

You can use an integer in the Number of Input Fields field, or any entity that evaluates to an integer (such as a variable, an arithmetic expression, or a call to an external Java method).

During screen recognition, the macro runtime:

  1. Evaluates this descriptor and obtains an integer result.
  2. Counts the number of input fields in the application screen (in its current state).
  3. Compares the two numbers.

If the two numbers are equal then the macro runtime evaluates this descriptor as true. Otherwise the macro runtime evaluates this descriptor as false.

If you do not want to use this descriptor then set the Number of Input Fields field to blank.

String descriptor (<string> element)

The String descriptor specifies the following information:

The macro runtime searches inside the entire rectangular area of text for the string you specify. If the macro runtime finds the string inside the rectangular area of text, then it evaluates the string descriptor as true. If not, then it evaluates the string descriptor as false.

Specifying the rectangular area

You define the rectangular area of text by specifying the row and column coordinates of opposite corners. The default values for these coordinates are (1,1) and (-1,-1), indicating the entire text area of the host terminal. For the significance of negative values such as -1,-1, see Significance of a negative value for a row or column. You can use an integer or any entity that evaluates to an integer (such as a variable, an arithmetic expression, or a call to an external Java method).

The rectangular area can be just large enough to contain the string, or much larger than the string. For example, suppose that the application screen that you want to match to the macro screen has the string 'Terminal and user parameters' in the rectangular area (6,20), (6,37). This rectangular area is exactly large enough to contain the string. If the application screen always has this string at this location, then you might specify the exact rectangular area.

However, suppose that the application screen that you want to match to the macro screen has the same string, 'Terminal and user parameters', located within it, but you cannot predict which row of the application screen will contain the string. In this case you could specify the rectangular area (1,1), (-1,-1), indicating that the macro runtime should search every row of the application screen for the identifying string.

For the string value you can use a string or any entity that evaluates to a string (such as a variable, an expression, or a call to an external Java method). The string must be in the form required by the macro format that you have chosen, either basic or advanced.

During screen recognition the macro runtime:

  1. Evaluates the row and column values and obtains an integer result for each value.
  2. Evaluates the string value and obtains a string result.
  3. Looks for the string anywhere within the rectangular block of text in the application screen (in its current state) specified by the row and column values.

If the macro runtime finds the string within the rectangular block of text then the macro runtime evaluates this descriptor as true. Otherwise the macro runtime evaluates this descriptor as false.

How the macro runtime searches the rectangular area (Wrap attribute)

If the Wrap attribute is set to false (the default setting), then the macro runtime searches each row of the rectangular area separately. This method works well when the entire string is contained within one row. For example, if the string is Utility Selection Panel and the rectangular area is (1,1), (24,80), then the macro runtime searches for the string as follows:

  1. Get the first row of the rectangular area. Determine whether the string occurs in the this row. If it does not, then search the next row.
  2. Get the second row of the rectangular area. Determine whether the string occurs in this row. If it does not, then search the next row.
  3. And so on.

In contrast, if the Wrap attribute is set to true then the macro runtime searches for the string as follows:

  1. Get all the lines of the rectangular area and concatenate them in order.
  2. Determine whether the string occurs in the concatenated string.

If the string you are searching for can wrap from one line to the next of the host terminal, then you should set the Wrap attribute to true. Do not confuse this attribute with the Unwrap attribute of the Extract action, which is based on fields rather than blocks of text (see Unwrap attribute).

The following description provides an example in which the Wrap attribute is set to true.

Figure 10 shows rows 14 through 18 of an application screen:

Figure 10. Rows 14-18 of an application screen
 6  Hardcopy    Initiate hardcopy output
 7  Transfer    Download ISPF Client/Server or Transfer data set
 8  Outlist     Display, delete, or print held job output
 9  Commands    Create/change an application command table
 *  Reserved    This option reserved for future expansion

In Figure 10, the first character of each row is a blank space. For example, in row 14, the first two characters are ' 6', that is, a blank space followed by the numeral 6. Suppose that you want to set up a String descriptor that checks for the following rectangular block of text on this application screen:

Hardcopy
Transfer
Outlist
Commands
Reserved

The steps in setting up the String descriptor for this multi-row block are as follows:

  1. Create a new String descriptor.
  2. Set the row and column location of the upper left corner of the text rectangle above to (14, 5) and the row and column location of the lower right corner to (18, 12).
  3. Set the string value. The string value is:
    'HardcopyTransferOutlist CommandsReserved'
  4. Set the Wrap attribute to true.
  5. Leave all the other attributes set to the default.

Notice that in step 3 above the five rows are concatenated as a single string, without any filler characters added (such as a newline or space at the end). However, the string does contain a blank space after 'Outlist' because that blank space does fall within the boundaries of the rectangle.

Using an extracted string in a String descriptor

If you use an Extract action to read text from the screen into a string variable (see Extract action (<extract> element)) then in a subsequent screen you can use the string variable in the String input field of a String descriptor.

For example, in ScreenA you might read a company name from the host terminal into a string variable named $strTmp$, using an Extract action. Then in ScreenB you could use $strTmp$ as the string to be searched for in a String descriptor.

You can do this when extracting multiple lines of text if you have the Wrap attribute set to true.

Multiple String descriptors in the same <description> element

You can create more than one String descriptor in the same <description> element. You should use as many String descriptors as you need in order to create a reliable description.

You can even define two different strings for the same rectangular block of text in the same <description> element. You might do this if the application screen corresponding to your macro screen displays different strings in the same location at different times. However, if you do define two different strings for the same rectangular block of text, you should be careful to indicate that both of the strings are not required (both are optional).

Cursor descriptor (<cursor> element)

The Cursor descriptor specifies a row and column location on the application screen, such as row 10 and column 50. For either the row value or the column value you can use an integer or any entity that evaluates to an integer (such as a variable, an arithmetic expression, or a call to an external Java method).

During screen recognition the macro runtime:

  1. Evaluates the row value and obtains an integer result.
  2. Evaluates the column value and obtains an integer result.
  3. Looks at the row and column location of the text cursor in the application screen (in its current state).
  4. Compares the row and column location in the descriptor with the row and column location of the text cursor in the application screen.

If the two locations are the same then the macro runtime evaluates this descriptor as true. Otherwise the macro runtime evaluates this descriptor as false.

Attribute descriptor (<attrib> element)

The attribute descriptor specifies a 3270, or 5250, attribute and a row and column location on the application window.

During screen recognition the macro runtime compares the specified attribute (such as 0x3) to the actual attribute at the row and column specified. If the attributes are the same, then the macro runtime evaluates the descriptor as true. Otherwise the macro runtime evaluates the descriptor as false.

This descriptor can be useful when you are trying to differentiate between two application screens that are very similar except for their attributes.

Condition descriptor (<condition> element)

The Condition descriptor specifies a conditional expression that the macro runtime evaluates during screen recognition, such as $intNumVisits$ == 0. For more information on conditional expressions see Conditional and logical operators and expressions.

During screen recognition the macro runtime evaluates the conditional expression and obtains a boolean result.

If the conditional expression evaluates to true then the macro runtime evaluates this descriptor as true. Otherwise the macro runtime evaluates this descriptor as false.

The Condition descriptor increases the flexibility and power of screen recognition by allowing the macro runtime to determine the next macro screen to be processed based on the value of one or more variables or on the result of a call to a Java method.

Custom descriptor (<customreco> element)

The Custom descriptor allows you to call custom description code.

To create a Custom descriptor you must use the source view to add a <customreco> element to the <description> element of the macro screen. For more information on this element, see <customreco> element.

Note:
If you are using custom screen recognition in the screen descriptors of an HCL ZIETrans macro, and the macro is invoked through the <playmacro> action from within a separate macro, the custom screen recognition logic does not work.

HCL ZIETrans can only register as a listener for custom recognition events in the first macro of a chain. HCL ZIETrans cannot register as a listener for any of the subsequent macros in the chain.

To resolve this problem, use non-chained macros when using HCL ZIETrans custom screen recognition.

Variable update action (<varupdate> element)

The Variable update entry is not a descriptor at all. Instead, it is an action that the macro language allows to occur inside a <description> element.

The Variable update action in a <description> element performs the very same type of operation that it performs in an <actions> element, which is to store a specified value into a specified variable.

For information about creating a Variable update action see Variable update action (<varupdate> element).

Processing a Variable update action in a description

You should be aware of how the macro runtime processes one or more Variable update actions when they occur in a <description> element:

  1. The macro runtime performs all the Variable update actions immediately, as if they were first in sequence.
  2. The macro runtime then evaluates the remaining items (descriptors) in the description as usual and arrives at an overall boolean result. The Variable update actions have no effect on the boolean result.

As you might remember, the macro runtime can go through the screen recognition process a number of times before matching a macro screen to an application screen (see Repeated screen evaluations). Therefore, if a <description> element contains one or more Variable update actions, then the macro runtime will perform the Variable update actions each time that it evaluates the <description> element.

For example, suppose that a macro is being played back, that the screen name ScreenB is on the list of valid next screens, and that ScreenB contains a <description> element like the one shown in Figure 11:

Figure 11. The <description> element of ScreenB
<description>
   <oia status="NOTINHIBITED" optional="false" invertmatch="false" />
   <varupdate name="$intUpdate$" value="$intUpdate$+1" />
   <attrib value="0x4" row="1" col="1" plane="COLOR_PLANE" optional="false"
               invertmatch="false" />
</description>

Each time that the macro runtime tries to match ScreenB to the current application screen:

  1. The macro runtime sees the <varupdate> action and performs it, incrementing the value of $intUpdate$ by 1.
  2. The macro runtime evaluates the <oia> descriptor and the <attrib> descriptor and arrives at a boolean result for the entire <description> element.

Variable update with the uselogic attribute

If you want the macro runtime to perform a Variable update action in a <description> element in some other sequence than first, you can change the order of execution by using the <description> element's uselogic attribute instead of the default combining rule (see The uselogic attribute).

When a Variable update action is used in a uselogic attribute: