In this kind of code, where you are walking through a frame that might contain many different kinds of objects, you might need to verify not only whether the current object handle is valid, but also whether it is valid to set or query a particular attribute. If you do not, you might get an error at run time. The code you looked at checks that an object is a fill-in before it checks the DATA-TYPE, but suppose for a moment that the original TYPE check was not there:

IF hObject:DATA-TYPE = "INTEGER" THEN
  ASSIGN hObject:SENSITIVE = NO
    hObject:BGCOLOR = 8.
ELSE hObject:BGCOLOR = 10.

When the AVM tries to retrieve the DATA-TYPE of an object that does not have this attribute, such as the browse, you get the error shown:

Figure 1. DATA-TYPE error message

To avoid this error, in cases where you cannot be sure whether the attribute matches the object type, you can use the CAN-QUERY function to check whether something is a readable attribute before your code does so. CAN-QUERY takes two arguments, a valid object handle and a character expression that evaluates to an attribute name. This code example eliminates the error:

IF CAN-QUERY(hObject, "DATA-TYPE") AND
  hObject:DATA-TYPE = "INTEGER" THEN
  .
  .
  .

Likewise, you can check in advance whether something is a writable attribute using the CAN-SET function, which also takes an object handle and attribute name as arguments:

IF CAN-SET (hObject, "SENSITIVE") AND
    CAN-SET(hObject, "BGCOLOR") THEN
  ASSIGN hObject:SENSITIVE = NO
    hObject:BGCOLOR = 8.

These functions are useful especially in cases where the attribute name itself is a variable, so that you cannot be sure when you write the code whether all possible values will be valid.

To see a list of all the valid attributes you can set or query for an object, use the LIST-QUERY-ATTRS and LIST-SET-ATTRS functions. Each function takes a valid object handle as an argument:

IF hObject:TYPE = "FILL-IN" THEN
  MESSAGE LIST-QUERY-ATTRS(hObject).

As you can see in the following figure, the list of attributes for most objects is quite large. You can find out about all of them in the ABL Reference.

Figure 2. Result of LIST-QUERY-ATTRS function example
Note: After running the code, remove the MESSAGE statement you just added to list the query attributes..