Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Interapplication Communication /
Chapter 6 - Resolving and Creating Object Specifier Records / Writing Object Accessor Functions


Writing Object Accessor Functions That Find Apple Event Objects

The first three listings in this section demonstrate how to write three object accessor functions that might be called in the following situation: An application receives a Get Data event with a direct parameter that consists of an object specifier record for the first word in the third paragraph of a document. The application's handler for the Get Data event calls the AEResolve function to resolve the object specifier record. The AEResolve function first calls the application's object accessor function for objects of class cDocument in containers identified by a token of descriptor type typeNull.

The AEResolve function passes these values to the MyFindDocumentObjectAccessor function shown in Listing 6-5: in the desiredClass parameter, the constant cDocument; in the containerToken parameter, a descriptor record of descriptor type typeNull with a data handle whose value is NIL; in the containerClass parameter, the constant typeNull; in the keyForm parameter, the constant formName; in the keyData parameter, a descriptor record of descriptor type typeText whose data consists of the string "MyDoc"; and the reference constant specified in the application's object accessor dispatch table.

Listing 6-5 An object accessor function that locates Apple event objects of object class cDocument

FUNCTION MyFindDocumentObjectAccessor 
                              (desiredClass: DescType; 
                               containerToken: AEDesc; 
                               containerClass: DescType;
                               keyForm: DescType; keyData: AEDesc;
                               VAR token: AEDesc; 
                               theRefCon: LongInt): OSErr;
VAR
   docName:          Str255;
   actSize:          Size;
   foundDoc:         Boolean;
   foundDocRecPtr:   MyDocumentRecordPtr;
BEGIN
   IF keyform = formName THEN
   BEGIN
      {get the name of the document from the key data}
      MyGetStringFromDesc(keyData, docName, actSize);
      {look for a document with the given name by }
      { searching all document records}
      MySearchDocRecs(docName, foundDocRecPtr, foundDoc);
      IF NOT foundDoc THEN
         MyFindDocumentObjectAccessor := kObjectNotFound
      ELSE {create token that identifies the document}
         MyFindDocumentObjectAccessor := 
               AECreateDesc(typeMyDocToken, @foundDocRecPtr,
                              SizeOf(foundDocRecPtr), token);
   END
   {handle the other key forms you support}
   ELSE
      MyFindDocumentObjectAccessor := kKeyFormNotSupported;
END;
The MyFindDocumentObjectAccessor function uses the information in the keyForm and keyData parameters to find the specified document. If it finds the Apple event object, MyFindDocumentObjectAccessor returns a token of descriptor type typeMyDocToken to AEResolve. The data handle for this token refers to a pointer to a document record (see Figure 6-5 on page 6-45). The MyFindDocumentObjectAccessor function returns this token and the noErr result code to the AEResolve function.

In the Get Data example, the token returned to AEResolve by the MyFindDocumentObjectAccessor function identifies the document "MyDoc." The AEResolve function then calls the application's object accessor function for objects of class cParagraph in containers identified by a token of descriptor type typeMyDocToken.

In this case, AEResolve passes these values to the MyFindParaObjectAccessor function shown in Listing 6-6: in the desiredClass parameter, the constant cParagraph; in the containerToken parameter, the token returned by the MyFindDocumentObjectAccessor function; in the containerClass parameter, the constant cDocument; in the keyForm parameter, the constant formAbsolutePosition; in the keyData parameter, a descriptor record with the typeLongInteger descriptor type and data that consists of the value 3 (indicating the third paragraph); and the reference constant specified in the application's object accessor dispatch table.

Listing 6-6 An object accessor function that locates Apple event objects of object class cParagraph

FUNCTION MyFindParaObjectAccessor (desiredClass: DescType; 
                                    containerToken: AEDesc; 
                                    containerClass: DescType;
                                    keyForm: DescType; 
                                    keyData: AEDesc; 
                                    VAR token: AEDesc; 
                                    theRefCon: LongInt): OSErr;
VAR
   index:            LongInt;
   {MyFoundTextRecord is an application-defined data type } 
   { consisting of three fields: start, ending, and docPtr} 
   foundParaRec:     MyFoundTextRecord;
   foundParaStart:   LongInt;
   foundParaEnd:     LongInt;
   foundDocRecPtr:   MyDocumentRecordPtr;
   success:          Boolean;
BEGIN
   IF keyForm = formAbsolutePosition THEN
   BEGIN
      {get the index of the paragraph from the key data}
      MyGetIndexFromDesc(keyData, index);
      {get the desired paragraph by index}
      success := MyGetPara(index, containerToken, foundParaStart, 
                           foundParaEnd, foundDocRecPtr);
      IF NOT success THEN
         MyFindParaObjectAccessor := kObjectNotFound
      ELSE {create token that identifies the paragraph}
      BEGIN
         foundParaRec.start := foundParaStart;
         foundParaRec.ending := foundParaEnd;
         foundParaRec.docPtr := foundDocRecPtr;
         MyFindParaObjectAccessor := 
               AECreateDesc(typeMyTextToken, @foundParaRec,
                              SizeOf(foundParaRec), token);
      END;
   END
      {handle the other key forms you support}
   ELSE 
      MyFindParaObjectAccessor := kKeyFormNotSupported;
END;
The MyFindParaObjectAccessor function uses another application-defined function, MyGetPara, to search the data structures associated with the document and find the desired paragraph. If it finds the paragraph, MyGetPara returns a value that identifies the beginning of the paragraph, a value that identifies the end of the paragraph, and a pointer to the document (which MyGetPara gets from the containerToken parameter). The MyFindParaObjectAccessor function returns an application-defined token that contains this information. This token is of descriptor type typeMyTextToken; it describes a range of characters that can be used to identify any range of text, including a paragraph or a word. The MyFindParaObjectAccessor function returns this token and the noErr result code to the AEResolve function.

In the Get Data example, the token returned to AEResolve by the MyFindParaObjectAccessor function identifies the third paragraph in the document "MyDoc." The AEResolve function then calls the application's object accessor function for objects of class cWord in containers identified by a token of descriptor type typeMyTextToken.

In this case, the AEResolve function passes these values to the MyFindWordObjectAccessor function shown in Listing 6-7: in the desiredClass parameter, the constant cWord; in the containerToken parameter, the token returned by the MyFindParaObjectAccessor function (a token of descriptor type typeMyTextToken that identifies a paragraph); in the containerClass parameter, the constant cParagraph; in the keyForm parameter, the constant formAbsolutePosition; in the keyData parameter, a descriptor record with the typeLongInteger descriptor type and data that consists of the value 1 (indicating the first word); and the reference constant specified in the application's object accessor dispatch table.

The MyFindWordObjectAccessor function uses another application-defined function, MyGetWord, to search the paragraph to find the desired word. If it finds the word, MyGetWord returns a value that identifies the beginning of the word, a value that identifies the end of the word, and a pointer to the document (which MyGetWord gets from the containerToken parameter). The MyFindWordObjectAccessor function returns a token that contains this information. This token is also of descriptor type typeMyTextToken; in this case, the token identifies a specific word. The MyFindWordObjectAccessor function returns this token and the noErr result code to the AEResolve function, which in turn returns the token to the Get Data event handler that originally called AEResolve.

Listing 6-7 An object accessor function that locates Apple event objects of object class cWord

FUNCTION MyFindWordObjectAccessor 
                              (desiredClass: DescType; 
                               containerToken: AEDesc; 
                               containerClass: DescType;
                               keyForm: DescType; keyData: AEDesc;
                               VAR token: AEDesc; 
                               theRefCon: LongInt): OSErr;
VAR
   index:            LongInt;
   foundWordRec:     MyFoundTextRecord;
   foundWordStart:   LongInt;
   foundWordEnd:     LongInt;
   foundDocRecPtr:   MyDocumentRecPtr;
   success:          Boolean;
BEGIN
   IF keyForm = formAbsolutePosition THEN
   BEGIN
      {get the index of the word from the key data}
      MyGetIndexFromDesc(keyData, index);
      {get the desired word by index}
      success := MyGetWord(index, containerToken, foundWordStart, 
                           foundWordEnd, foundDocRecPtr);
      IF NOT success THEN
         MyFindWordObjectAccessor := kObjectNotFound
      ELSE {create token that identifies the paragraph}
      BEGIN
         foundWordRec.start := foundWordStart;
         foundWordRec.ending := foundWordEnd;
         foundWordRec.docPtr := foundDocRecPtr;
         MyFindWordObjectAccessor := 
               AECreateDesc(typeMyTextToken, @foundWordRec,
                              SizeOf(foundWordRec), token);
      END;
   END
   {handle the other key forms you support}
   ELSE 
      MyFindWordObjectAccessor := kKeyFormNotSupported;
END;
Listing 6-5 on page 6-36 shows an object accessor function that locates a document in the default container. Every application must provide one or more object accessor functions that can find Apple event objects in the default container, which is always identified by a descriptor record of descriptor type typeNull. Listing 6-8 provides another example of an object accessor function that locates an Apple event object in the default container. If the MyFindWindowObjectAccessor function shown in Listing 6-8 were installed in an application's object accessor dispatch table, the AEResolve function would call it as necessary to locate an object of class cWindow in a container identified by a token of descriptor type typeNull.

Listing 6-8 An object accessor function that locates Apple event objects of object class cWindow

FUNCTION MyFindWindowObjectAccessor (desiredClass: DescType; 
                                     containerToken: AEDesc; 
                                     containerClass: DescType;
                                     keyForm: DescType; 
                                     keyData: AEDesc;
                                     VAR token: AEDesc; 
                                     theRefCon: LongInt): OSErr;
VAR
   windowName:    Str255;
   actSize:       Size;
   windTitle:     Str255;
   window:        WindowPtr;
   index, iLoop:  Integer;
   found:         Boolean;
BEGIN
   IF keyForm = formName THEN
   BEGIN
      {get the name of the window to find from the keyData }
      { parameter. MyGetStringFromDesc gets data out of an }
      { AEDesc and returns a string and the string's size}
      MyGetStringFromDesc(keyData, windowName, actSize);
      {look for a window with the given name}
      window := FrontWindow;
      found := FALSE;
      WHILE ((window <> NIL) AND (found = FALSE)) DO 
      BEGIN
         GetWTitle(window, windTitle);
         found := EqualString(windTitle, windowName, FALSE, TRUE); 
         IF NOT found THEN
            window := WindowPtr(WindowPeek(window)^.nextWindow);
      END;     {of while}
   END {of formName}
   ELSE
   IF keyForm = formAbsolutePosition THEN
      {find the window given an index in key data}
      BEGIN    {get the index from the key data}
         MyGetIndexFromDesc(keyData, index);
         found := FALSE;
         iLoop := 0;
         window := FrontWindow;
         WHILE (window <> NIL) AND (found <> TRUE) DO
         BEGIN
            iLoop := iLoop +1;
            IF iLoop = index THEN
               found := TRUE
            ELSE
            window := WindowPtr(WindowPeek(window)^.nextWindow);
         END; {of while}
      END {of formAbsolutePosition}
   {handle the other key forms you support}
   ELSE
   BEGIN
      MyFindWindowObjectAccessor := kKeyFormNotSupported;
      Exit(MyFindWindowObjectAccessor);
   END;
   IF window = NIL THEN
      MyFindWindowObjectAccessor := kObjectNotFound
   ELSE {create token that identifies the window}
      MyFindWindowObjectAccessor := 
               AECreateDesc(typeMyWindow, @window, 
                              SizeOf(window), token);
END;
The keyForm parameter of the MyFindWindowObjectAccessor function describes how the function should interpret the keyData parameter. If the key form is formName, then the key data contains the name of the window to locate. If the key form is formAbsolutePosition, the key data contains the position of the window to locate in the window list; for example, a value of 1 identifies the frontmost window.

The MyFindWindowObjectAccessor function supports only the formName and formAbsolutePosition key forms. Your object accessor functions should support all key forms that make sense for the kinds of objects the functions can locate.

For the formName keyword, the MyFindWindowObjectAccessor function starts with the frontmost window and compares the window's title to the name specified by the keyData parameter. It continues this search until it reaches either the end of the window list or finds a match. If the MyFindWindowObjectAccessor function finds a match, it uses the AECreateDesc function to create a descriptor record for the token, specifying the application-defined typeMyWindow descriptor type and the data for this descriptor type as a window pointer.

The MyFindWindowObjectAccessor function then sets its function result appropriately, and the AEResolve function either returns this function result and token, or uses the returned token to request the next Apple event object in the container hierarchy, such as a document in the window.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996