Chapter 3 The Application Description Language

3.23 Wrapped Classes

Wrapped classes are C++ classes that are "wrapped" with the necessary information to make them usable in the ADL. Wrapped classes are also called system-defined classes. They cannot be modified although they can be adapted through subclassing. AM2 comes with a set of wrapped classes, which are described in Chapter 6, "Wrapped Class Reference" page 111.

By convention, the names of wrapped classes begin with two capital letters that define the module the class belongs to, followed by a lower case word specifying the class within the module. If more than one word is necessary, the names are concatenated with second and later words starting with a capital letter. The following samples are typical wrapped class names:

XFtop        // a top level frame or shell window
XFbutton
XFcheckBox   // note the capitalization
MMimage
The exceptions to this convention are the set of wrapped notification classes (see Section 4.2, "Using Notification Request Objects" page 62) and certain abstract wrapped classes, e.g., ActivityManager, that never appear in ADL programs. Most programmers try to distinguish their ADL from wrapped classes by starting the names of ADL classes with only a single capital letter, e.g., ExitButton. Note that XFtop and XFbutton will frequently be used as example wrapped classes in this document.

System developers can also create wrapped classes using the wrap script (see "Creating Wrapped Classes" on page 271). We use wrapped classes and user-defined classes (those written in the ADL by an application developer) in almost exactly the same way, with some restrictions on member access for wrapped classes. This section discusses how wrapped classes differ from user-defined classes.

There are five things that you can do with any class: refer to it by name, create a subclass of it, create an instance of it, access members of its instances, and invoke methods of its instances. Let's look at each activity in turn.

3.23.1 Scope of a Class Name

An ADL programmer specifies a class by its name when creating a subclass or an instance of the class, and when getting a handle to the class (using theClass operator). The scope of a class name represents the part of the program in which the name refers to that class (see Section 3.26, "Scope" page 52). A wrapped class' name has the same scope as that of a non-nested, user-defined class. This means that a wrapped class can be used anywhere in an ADL application.

One difference between wrapped classes and user-defined classes is that the latter, when defined with the same name as a wrapped class silently hides the corresponding wrapped class. For instance, suppose there is a wrapped class named XFselectList. A user-defined class named
XFselectList would hide the wrapped class of the same name so that any objects of type
XFselectList would be instances of the user-defined class, not instances of the wrapped class. Two user-defined classes with the same name generate a semantic error.

3.23.2 Creating an Instance of a Class

You can instantiate, that is represent by a concrete instance, all wrapped classes with the exception of an abstract wrapped class. An abstract wrapped class is one that exists only to provide organization in the hierarchy of classes. It is not a complete class in itself and therefore instances of it are not allowed.

3.23.3 Creating a Subclass

You can create a subclass, which is a class that inherits from a superclass, of most wrapped classes. For example, an ADL program might create a subclass of the wrapped class XFtop to add XFbutton member instances as part of creating separate user interfaces.

Some wrapped classes, however, do not allow for the creation of subclasses. For example, the wrapped class XFwidget is an incomplete class that exists to provide organization in the hierarchy of classes. Most abstract wrapped classes are in this category. One notable exception is the ActivityManager class, an abstract class that you can use to create subclasses (see Section 4.5, "Creating ADL Classes That Manage Activities" page 70). It is abstract because without the information stored in its subclasses an instance of it has little use. It is the subclass that provides the information that makes it useful.

3.23.4 Member Access

Wrapped classes can have simple and compound members, namely booleans, integers, reals, strings, lists, intervals, times, and handles. They cannot have arrays or instances of other objects as members. There are three operations that you can attempt on a simple or compound member of an object: taking a handle to the member, getting the member's value, and setting the member's value. The following sections describes the operations available for using those members and the restrictions on the way they are referred to by name.

Operating on Members

We call instances of wrapped classes wrapper objects. Taking a handle to a member of a wrapper object is not allowed because the member does not necessarily exist. Some members of a wrapper object are actually implemented by making method calls on the C++ object that implements the wrapper instance. Other members, known as attributes, are actually contained and managed by the underlying windowing or operating system. For instance, think of all the possible attributes of a button, width, height, borderWidth, foreground, background,etc. The XFbutton passes management of these attributes down to the underlying windowing system on each platform.

You cannot assign unset values to members of wrapped classes. For the most part, however, you can get and set the members of a wrapper object just like the members of an instance of a user-defined class. Just as a user-defined class can prevent the setting of one of its members by providing a Set_memberName method, and either not setting the member or calling the die built-in function, a wrapped class can prevent the getting or setting of its members in a similar way. For example, the width member of the MMimage wrapped class is read-only and attempting to set it is a fatal error. See the documentation for wrapped classes in Chapter 6, "Wrapped Class Reference" page 111 to determine which members are accessible.

Naming of Members

As with members of user-defined objects, you can refer to each member of a wrapper object by its name. For example, the class XFlabel has a member called width. In subclasses of XFlabel, you simply refer to width if the subclass does not have another member with the same name that hides it. From outside the label class, you can refer to width as a member of XFlabel by a construct similar to myLabel.width or handleToMyLabel->width.

Unlike the members of a user-defined object, in a wrapper object you cannot qualify the members of a wrapped class by the name of the base that provides it. For instance, XFfontable is a superclass that provides the font member for other classes, such as XFtext. You cannot refer to this font member as XFfontable::font. You can, however, refer to XFtext::font.

Qualifying self

Unlike the base objects of a user-defined object, you cannot access the base of a wrapped object from the ADL. For instance, suppose that MySelectList is a user-defined subclass of XFselectList. It is an error to access the XFwidget base of XFselectList from within
MySelectList using the conventional XFwidget::self because there is not necessarily an object that properly represents this base.

3.23.5 Method Invocation

The invocation of methods works just as it does for user-defined objects, except that a method cannot be sent to a base class of a wrapped class. In the ADL, a message goes to the appropriate base object to invoke an overridden method of that class. Since it is not possible to access any base object of a wrapped object, as discussed in the previous section, it is not possible to access overridden methods.

3.23.1 - Scope of a Class Name
3.23.2 - Creating an Instance of a Class
3.23.3 - Creating a Subclass
3.23.4 - Member Access
3.23.5 - Method Invocation

AM2 Documentation - 19 NOV 1996

Generated with Harlequin WebMaker