Important: The information in this document is obsolete and should not be used for new development.
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 theAEResolvefunction to resolve the object specifier record. TheAEResolvefunction first calls the application's object accessor function for objects of classcDocumentin containers identified by a token of descriptor typetypeNull.The
AEResolvefunction passes these values to theMyFindDocumentObjectAccessorfunction shown in Listing 6-5: in thedesiredClassparameter, the constantcDocument; in thecontainerTokenparameter, a descriptor record of descriptor typetypeNullwith a data handle whose value isNIL; in thecontainerClassparameter, the constanttypeNull; in thekeyFormparameter, the constantformName; in thekeyDataparameter, a descriptor record of descriptor typetypeTextwhose 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;TheMyFindDocumentObjectAccessorfunction uses the information in thekeyFormandkeyDataparameters to find the specified document. If it finds the Apple event object,MyFindDocumentObjectAccessorreturns a token of descriptor typetypeMyDocTokentoAEResolve. The data handle for this token refers to a pointer to a document record (see Figure 6-5 on page 6-45). TheMyFindDocumentObjectAccessorfunction returns this token and thenoErrresult code to theAEResolvefunction.In the Get Data example, the token returned to
AEResolveby theMyFindDocumentObjectAccessorfunction identifies the document "MyDoc." TheAEResolvefunction then calls the application's object accessor function for objects of classcParagraphin containers identified by a token of descriptor typetypeMyDocToken.In this case,
AEResolvepasses these values to theMyFindParaObjectAccessorfunction shown in Listing 6-6: in thedesiredClassparameter, the constantcParagraph; in thecontainerTokenparameter, the token returned by theMyFindDocumentObjectAccessorfunction; in thecontainerClassparameter, the constantcDocument; in thekeyFormparameter, the constantformAbsolutePosition; in thekeyDataparameter, a descriptor record with thetypeLongIntegerdescriptor 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;TheMyFindParaObjectAccessorfunction 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,MyGetParareturns a value that identifies the beginning of the paragraph, a value that identifies the end of the paragraph, and a pointer to the document (whichMyGetParagets from thecontainerTokenparameter). TheMyFindParaObjectAccessorfunction returns an application-defined token that contains this information. This token is of descriptor typetypeMyTextToken; it describes a range of characters that can be used to identify any range of text, including a paragraph or a word. TheMyFindParaObjectAccessorfunction returns this token and thenoErrresult code to theAEResolvefunction.In the Get Data example, the token returned to
AEResolveby theMyFindParaObjectAccessorfunction identifies the third paragraph in the document "MyDoc." TheAEResolvefunction then calls the application's object accessor function for objects of classcWordin containers identified by a token of descriptor typetypeMyTextToken.In this case, the
AEResolvefunction passes these values to theMyFindWordObjectAccessorfunction shown in Listing 6-7: in thedesiredClassparameter, the constantcWord; in thecontainerTokenparameter, the token returned by theMyFindParaObjectAccessorfunction (a token of descriptor typetypeMyTextTokenthat identifies a paragraph); in thecontainerClassparameter, the constantcParagraph; in thekeyFormparameter, the constantformAbsolutePosition; in thekeyDataparameter, a descriptor record with thetypeLongIntegerdescriptor 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
MyFindWordObjectAccessorfunction uses another application-defined function,MyGetWord, to search the paragraph to find the desired word. If it finds the word,MyGetWordreturns a value that identifies the beginning of the word, a value that identifies the end of the word, and a pointer to the document (whichMyGetWordgets from thecontainerTokenparameter). TheMyFindWordObjectAccessorfunction returns a token that contains this information. This token is also of descriptor typetypeMyTextToken; in this case, the token identifies a specific word. TheMyFindWordObjectAccessorfunction returns this token and thenoErrresult code to theAEResolvefunction, which in turn returns the token to the Get Data event handler that originally calledAEResolve.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 typetypeNull. Listing 6-8 provides another example of an object accessor function that locates an Apple event object in the default container. If theMyFindWindowObjectAccessorfunction shown in Listing 6-8 were installed in an application's object accessor dispatch table, theAEResolvefunction would call it as necessary to locate an object of classcWindowin a container identified by a token of descriptor typetypeNull.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;ThekeyFormparameter of theMyFindWindowObjectAccessorfunction describes how the function should interpret thekeyDataparameter. If the key form isformName, then the key data contains the name of the window to locate. If the key form isformAbsolutePosition, 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
MyFindWindowObjectAccessorfunction supports only theformNameandformAbsolutePositionkey forms. Your object accessor functions should support all key forms that make sense for the kinds of objects the functions can locate.For the
formNamekeyword, theMyFindWindowObjectAccessorfunction starts with the frontmost window and compares the window's title to the name specified by thekeyDataparameter. It continues this search until it reaches either the end of the window list or finds a match. If theMyFindWindowObjectAccessorfunction finds a match, it uses theAECreateDescfunction to create a descriptor record for the token, specifying the application-definedtypeMyWindowdescriptor type and the data for this descriptor type as a window pointer.The
MyFindWindowObjectAccessorfunction then sets its function result appropriately, and theAEResolvefunction 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.