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 theAEResolve
function to resolve the object specifier record. TheAEResolve
function first calls the application's object accessor function for objects of classcDocument
in containers identified by a token of descriptor typetypeNull
.The
AEResolve
function passes these values to theMyFindDocumentObjectAccessor
function shown in Listing 6-5: in thedesiredClass
parameter, the constantcDocument
; in thecontainerToken
parameter, a descriptor record of descriptor typetypeNull
with a data handle whose value isNIL
; in thecontainerClass
parameter, the constanttypeNull
; in thekeyForm
parameter, the constantformName
; in thekeyData
parameter, a descriptor record of descriptor typetypeText
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;TheMyFindDocumentObjectAccessor
function uses the information in thekeyForm
andkeyData
parameters to find the specified document. If it finds the Apple event object,MyFindDocumentObjectAccessor
returns a token of descriptor typetypeMyDocToken
toAEResolve
. The data handle for this token refers to a pointer to a document record (see Figure 6-5 on page 6-45). TheMyFindDocumentObjectAccessor
function returns this token and thenoErr
result code to theAEResolve
function.In the Get Data example, the token returned to
AEResolve
by theMyFindDocumentObjectAccessor
function identifies the document "MyDoc." TheAEResolve
function then calls the application's object accessor function for objects of classcParagraph
in containers identified by a token of descriptor typetypeMyDocToken
.In this case,
AEResolve
passes these values to theMyFindParaObjectAccessor
function shown in Listing 6-6: in thedesiredClass
parameter, the constantcParagraph
; in thecontainerToken
parameter, the token returned by theMyFindDocumentObjectAccessor
function; in thecontainerClass
parameter, the constantcDocument
; in thekeyForm
parameter, the constantformAbsolutePosition
; in thekeyData
parameter, a descriptor record with thetypeLongInteger
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;TheMyFindParaObjectAccessor
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 (whichMyGetPara
gets from thecontainerToken
parameter). TheMyFindParaObjectAccessor
function 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. TheMyFindParaObjectAccessor
function returns this token and thenoErr
result code to theAEResolve
function.In the Get Data example, the token returned to
AEResolve
by theMyFindParaObjectAccessor
function identifies the third paragraph in the document "MyDoc." TheAEResolve
function then calls the application's object accessor function for objects of classcWord
in containers identified by a token of descriptor typetypeMyTextToken
.In this case, the
AEResolve
function passes these values to theMyFindWordObjectAccessor
function shown in Listing 6-7: in thedesiredClass
parameter, the constantcWord
; in thecontainerToken
parameter, the token returned by theMyFindParaObjectAccessor
function (a token of descriptor typetypeMyTextToken
that identifies a paragraph); in thecontainerClass
parameter, the constantcParagraph
; in thekeyForm
parameter, the constantformAbsolutePosition
; in thekeyData
parameter, a descriptor record with thetypeLongInteger
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 (whichMyGetWord
gets from thecontainerToken
parameter). TheMyFindWordObjectAccessor
function returns a token that contains this information. This token is also of descriptor typetypeMyTextToken
; in this case, the token identifies a specific word. TheMyFindWordObjectAccessor
function returns this token and thenoErr
result code to theAEResolve
function, 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 theMyFindWindowObjectAccessor
function shown in Listing 6-8 were installed in an application's object accessor dispatch table, theAEResolve
function would call it as necessary to locate an object of classcWindow
in 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;ThekeyForm
parameter of theMyFindWindowObjectAccessor
function describes how the function should interpret thekeyData
parameter. 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
MyFindWindowObjectAccessor
function supports only theformName
andformAbsolutePosition
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, theMyFindWindowObjectAccessor
function starts with the frontmost window and compares the window's title to the name specified by thekeyData
parameter. It continues this search until it reaches either the end of the window list or finds a match. If theMyFindWindowObjectAccessor
function finds a match, it uses theAECreateDesc
function to create a descriptor record for the token, specifying the application-definedtypeMyWindow
descriptor type and the data for this descriptor type as a window pointer.The
MyFindWindowObjectAccessor
function then sets its function result appropriately, and theAEResolve
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.