• Keine Ergebnisse gefunden

Sending a Message

Im Dokument PenPomt GO (Seite 54-57)

another class, and it will inherit all the behavior of that class, or as much behavior as you choose.

You may find it easier to understand class-based programming by viewing code instead of reading abstract explanations. The next few pages give some simple examples of using messages and classes, and even the very simplest program in the tutorial is-has to be!-fully class-based.

Sending a Message

In PenPoint, you usually send a message to an object using the ObjectCall function (if the object is owned by another process you use ObjectSend). The differences between ObjectCall and ObjectSend are detailed in Part 1: Class Manager, of the PenPoint Architectural Reference.

Here's a real-life example of sen~ing a message. PenPoint provides a utility class, clsList, which maintains a list object. The messages that clsList responds to are documented in Part 9: Utility Classes, of the PenPoint Architectural Reference and in the clsList header file (\PENPOINT\SDK\INC\LIST.H). This is the definition of msgListAddItemAt from LIST.H:

/****************************************************************************

msgListAddltemAt takes P_LIST_ENTRY, returns STATUS Adds an item to a list by position.

****************************************************************************/

#define msgListAddltemAt MakeMsg(clsList, 10)

Don't worry about the details of the definition right now; this just tells us that msgListAddItemAt is defined by clsList, that the message uses a P _LIST_ENTRY structure to convey its arguments, and that the message returns a value of type STATUS when it completes.

We want to send msgListAddItemAt to a list object, telling it to add the value 'G'

to itself at position three in the list.

Message Arguments

Now, in order for a list object to respond appropriately to msgListAddItem, it's going to need some additional information. In this case the additional

information is the item to add to the list ('G'), and where to add it (third

postion). Most messages need certain information for objects to respond correctly

to them. The information, called message arguments, you pass to the recipient along with the message.

In this case, the header file informs us that msgListAddItemAt takes a

P_LIST_ENTRY. In Pen Point's C dialect, this means "a pointer to a LIST_ENTRY"

structure. Here's the structure:

typedef struct LIST ENTRY

U16 position;

LIST ITEM item;

LIST_ENTRY, *P_LIST_ENTRY;

typedef P_UNKNOWN LIST_ITEM, *P_LIST_ITEM;

UI6 is an unsigned 16-bit number, P _UNKNOWN means a 32-bit pointer to an unknown. (Chapter 5 of this manual describes the rest of PenPoint's ubiquitous typedefs and #defines.)

When you can deliver the message and its arguments to a list object, you're set.

Here's the C code to do it:

"takes" is deliberate. Although a class usually reqUires a specific message argument structure, there is no mechanism available to detect when you pass it the wrong structure.

",. ObiectCall Parameters

4.4.2

The code fragment above assumes that the list object (list) has already been created; object creation is covered later in this chapter. As you can see, ObjectCall takes three parameters:

• The message (msgListAddItem). Messages are just 32-bit constants defined by a class in its header file. You can send an object a message defined by any of the classes from which it inherits. (Some objects even respond to messages defined by classes that are not their ancestors.)

• The object (list). Objects are referenced by UID's, unique 32-bit ID numbers. UID's are discussed in more detail later.

• The arguments for the message (add). Not all messages take arguments (msgFrameClose, for example, takes none), but others do

(msglconSetPictureSize, for example, takes a width and height). The PenPoint Architectural Reference manual and the header files (in this case,

\PENPOINT\SDK\INC\LIST.H) document each message's arguments.

The term "parameters" is used in function calls; the term

"arguments" is used for data reqUired for a specific message.

We use bold face to indicate items defined by PenPoint and other symbols used in examples.

CHAPTER 4 I PENPOINT CLASS MANAGER 47 Sending a Message

ObjectCall has one 32-bit parameter for all the message's arguments; if a message takes more arguments than can fit in 32 bits, you must assemble the arguments in a structure and pass ObjectCall a pointer to the structure. In this case,

msgListAddltem takes a·P _LIST~ENTRY, a pointer to a LIST_ENTRY structure.

(The PenPoint convention is that a type that begins with P _ is a pointer to a type.) Hence the address of the add structure (&add) is passed to ObjectCall.

"'''' Returned Values

4.4.3

The result of sending a message is returned as a status value (type STATUS). stsOK ("status OK") is zero; All status values that represent error conditions are less than zero. Note that STATUS is a 32-bit quantity, hence the %JX in the Debugf statement to print out a long hexadecimal.

Some messages are designed to return errors that you should test for. For example, the status returned by sending msglsA to an object is stsOK if the object inherits from the specified class, and stsBadAncestor if the object does not.

Some objects respond to messages by returning a positive value (which is not a status value, but an actual number). Others return more complex information by filling in fields of the message argument structure supplied by the caller (or buffers indicated by'pointers in the message argument structure) and passing back the structure.

".. How Obiects Know How to Respond

The list object responds to msgListAddltem because it is an instance of clsList.

But what does that mean?

The list object has several attributes. Among them are the class that created the object and the instance data for that object. As described above, when you define a class, you must also cre~te a table of the messages handled by your class.

The Class Manager finds out which class created the object and looks for the method table for that class. The method table tells the Class Manager that the class has a function entry point for that message, so the Class Manager calls that function entry point, passing in the message and the message argument structure.

Although the object receives the message, its class has the code to handle the message.

If the class decides to give the message to its ancestor, it passes the message and the message arguments to the ancestor (but the instance data is still the instance data for the object that received the message).

4.4.4

The Class Manager gives the object a painter to the object's instance data. This is one aspect of PenPoint's data integrity.

Im Dokument PenPomt GO (Seite 54-57)