Previous Book Contents Book Index Next

Inside Macintosh: Interapplication Communication /
Chapter 4 - Responding to Apple Events / Handling Apple Events


Replying to an Apple Event

Your handler routine for a particular Apple event is responsible for performing the action requested by the Apple event, and can optionally return data in a reply Apple event. The Apple Event Manager passes a default reply Apple event to your handler. The default reply Apple event has no parameters when it is passed to your handler. Your handler can add parameters to the reply Apple event. If the client application requested a reply, the Apple Event Manager returns the reply Apple event to the client.

The reply Apple event is identified by the kCoreEventClass event class and by the kAEAnswer event ID. If the client application specified the kAENoReply flag in the reply parameter of the AESend function, the Apple Event Manager passes a null descriptor record (a descriptor record of type typeNull whose data handle has the value NIL) to your handler instead of a default reply Apple event. Your handler should check the descriptor type of the reply Apple event before attempting to add any attributes or parameters to it. An attempt to add an Apple event attribute or parameter to a null descriptor record generates an error.

If the client application requests a reply, the Apple Event Manager prepares a reply Apple event for the client by passing a default reply Apple event to your handler. The default reply Apple event has no parameters when it is passed to your handler. Your handler can add any parameters to the reply Apple event. If your application is a spelling checker, for example, you can return a list of misspelled words in a parameter.

When your handler finishes processing an Apple event, it returns a result code to AEProcessAppleEvent, which returns this result code as its function result. If your handler returns a nonzero result code, and if you have not added your own keyErrorNumber parameter, the Apple Event Manager also returns this result code to the client application by putting the result code into a keyErrorNumber parameter for the reply Apple event. The client can check for the existence of this parameter to determine whether the handler performed the requested action.

The client application specifies whether it wants a reply Apple event or not by specifying flags (represented by constants) in the sendMode parameter of the AESend function.

If the client specifies the kAEWaitReply flag in the sendMode parameter, the AESend function does not return until the timeout specified by the timeoutInTicks parameter expires or the server application returns a reply. When the server application returns a reply, the reply parameter to AESend contains the reply Apple event that your handler returned to the AEProcessAppleEvent function. When the client application no longer needs the original Apple event and the reply event, it must dispose of them, but the Apple Event Manager disposes of both the Apple event and the reply event for the server application when the server's handler returns to AEProcessAppleEvent.

If the client specified the kAEQueueReply flag, the client receives the reply event at a later time during its normal processing of other events.

Your handler should always set its function result to noErr if it successfully
handles the Apple event. If an error occurs, your handler should return either errAEEventNotHandled or some other nonzero result code. If the error
occurs because your application cannot understand the event, return errAEEventNotHandled. This allows the Apple Event Manager to look for a handler in the system special handler or system Apple event dispatch tables that might be able to handle the event. If the error occurs because the event is impossible to handle as specified, return the result code returned by whatever function caused the failure, or whatever other result code is appropriate.

For example, suppose your application receives a Get Data event requesting the name of the current printer, and your application cannot handle such an event. In this situation, you should return errAEEventNotHandled in case another handler available to the Apple Event Manager can handle the Get Data event. This strategy allows users to take advantage of system capabilities from within your application via system handlers.

However, if your application cannot handle a Get Data event that requests the fifth paragraph in a document because the document contains only four paragraphs, you should return some other nonzero error, because further attempts to handle the event are pointless.

If your Apple event handler calls the AEResolve function and AEResolve calls an object accessor function in the system object accessor dispatch table, your Apple event handler may not recognize the descriptor type of the token returned by the function. In this case, your handler should return the result code errAEUnknownObjectType. When your handler returns this result code, the Apple Event Manager attempts to locate a system Apple event handler that can recognize the token. For more information, see "Installing Entries in the Object Accessor Dispatch Tables," which begins on page 6-21.

The Apple Event Manager automatically adds any nonzero result code that your handler returns to a keyErrorNumber parameter in the reply Apple event. In addition to returning a result code, your handler can also return an error string in the keyErrorString parameter of the reply Apple event. Your handler should provide meaningful text in the keyErrorString parameter, so that the client can display this string to the user if desired.

Listing 4-12 shows how to add the keyErrorString parameter to the reply Apple event. See "Adding Parameters to an Apple Event" on page 5-5 for a description of the AEPutParamPtr function.

Listing 4-12 Adding the keyErrorString parameter to the reply Apple event

FUNCTION MyHandler (theAppleEvent: AppleEvent; reply: AppleEvent;
                    handlerRefcon: LongInt): OSErr; 
VAR
   myErr:      OSErr;
   errStr:     Str255;
BEGIN
   {handle your Apple event here}

   {if an error occurs when handling an Apple event, set the }
   { function result and error string accordingly}
   IF myErr <> noErr THEN
   BEGIN
      MyHandler := myErr; {result code to be returned--the }
                           { Apple Event Manager adds this }
                           { result code to the reply Apple }
                           { event as the keyErrorNumber }
                           { parameter}
      IF (reply.dataHandle <> NIL) THEN
      {add error string parameter to the default reply}
      BEGIN
         {strings should normally be stored in resources}
         errStr := 'Why error occurred';
         myErr := AEPutParamPtr(reply, keyErrorString, 
                                 typeIntlText, @errStr[1], 
                                 length(errStr));
      END;
   END
   ELSE
      MyHandler := noErr;
END;
If your handler needs to return data to the client, it can add parameters to the reply Apple event. Listing 4-13 shows how a handler for the Multiply event (an imaginary Apple event that asks the server to multiply two numbers) might return the results of the multiplication to the client.

Listing 4-13 Adding parameters to the reply Apple event

FUNCTION MyMultHandler (theAppleEvent: AppleEvent; 
                        reply: AppleEvent; 
                        handlerRefcon: LongInt): OSErr; 
VAR
   myErr:            OSErr;
   number1,number2:  LongInt;
   replyResult:      LongInt;
   actualSize:       Size;
   returnedType:     DescType;
BEGIN
   {get the numbers to multiply from the parameters of the }
   { Apple event; put the numbers in the number1 and number2 }
   { variables and then perform the requested multiplication}
   myErr := MyDoMultiply(theAppleEvent, number1, 
                           number2, replyResult);
   IF myErr = noErr THEN 
      IF (reply.dataHandle <> NIL) THEN
         {return result of the multiplication in the reply Apple }
         { event}
         myErr := AEPutParamPtr(reply, keyDirectObject, 
                                 typeLongInteger, @replyResult, 
                                 SizeOf(replyResult));
   MyMultHandler := myErr;
   {if an error occurs, set the error string }
   { accordingly, as shown in Listing 4-12}
END;

Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996