Important: The information in this document is obsolete and should not be used for new development.
Creating a Complex Object Specifier Record
This section describes how to create object specifier records that specify a test or a range. You can specify the object class ID for these object specifier records the same way you would for any other object specifier record. When you create the other three keyword-specified descriptor records, however, you can use additional Apple Event Manager routines and descriptor types to specify any combination of Apple event objects.Specifying a Test
The key formformTest
allows your application to specify key data that identifies one or more elements in the specified container that pass a test. To do so, your application must construct several interconnected descriptor records that specify comparisons and, if necessary, logical expressions.For example, to specify "the first row in which the First Name column equals 'John' and the Last Name column equals 'Chapman' in the table 'MyAddresses' of the database 'SurfDB,'" your application must construct an object specifier record whose key data describes a logical expression that applies the logical operator
AND
to two separate comparisons for each row: a comparison of the First Name column to the word "John" and a comparison of the Last Name column to the word "Chapman."The logical organization of the data for the object specifier record that specifies this test is summarized in Table 6-8 and Table 6-9. (It is also illustrated in Figure 6-3 and Figure 6-4, beginning on page 6-22.) The listings in the remainder of this section demonstrate how to create this object specifier record. For general information about the organization of key data for a test, see "Key Data for a Test," which begins on page 6-16.
Table 6-8 Object specifier record for the first row that meets a test in the table named "MyAddresses" Keyword Descriptor type Data keyAEDesiredClass typeType cRow keyAEContainer typeObjectSpecifier (see indented record) keyAEDesiredClass typeType cRow keyAEContainer typeObjectSpecifier (see indented record) keyAEDesiredClass typeType cTable keyAEContainer typeObjectSpecifier (see indented record) keyAEDesiredClass typeType
cDatabase keyAEContainer typeNull Data handle is NIL
keyAEKeyForm typeEnumerated formName keyAEKeyData typeChar "SurfDB" keyAEKeyForm typeEnumerated formName keyAEKeyData typeChar "MyAddresses" keyAEKeyForm typeEnumerated formTest keyAEKeyData typeLogicalDescriptor (see Table 6-9) keyAEKeyForm typeEnumerated formAbsolutePosition keyAEKeyData typeLongInteger 1 Because both the database and the table shown in Table 6-8 are specified by name, it would be convenient to have an application-defined routine that creates an object specifier record that uses the key form
formName
. TheMyCreateFormNameObjSpecifier
function shown in Listing 6-16 can be used for this purpose.Listing 6-16 Creating an object specifier record with the key form
formName
FUNCTION MyCreateFormNameObjSpecifier (class: DescType; container: AEDesc; keyDataName: str255; VAR resultObjSpecRec: AEDesc): OSErr; VAR keyDataDescRec: AEDesc; myErr: OSErr; BEGIN myErr := AECreateDesc(typeChar, @keyDataName[1], Length(keyDataName), keyDataDescRec); IF myErr = noErr THEN myErr := CreateObjSpecifier(class, container, formName, keyDataDescRec, TRUE, resultObjSpecRec); MyCreateFormNameObjSpecifier := myErr; END;TheMyCreateFormNameObjSpecifier
function shown in Listing 6-16 returns, in theresultObjSpecRec
parameter, an object specifier record that describes an Apple event object of the class specified by theclass
parameter, located in the container specified by thecontainer
parameter, with the key formformName
and key data specified by thekeyDataName
parameter. This function is used in Listing 6-19 on page 6-83 to create object specifier records that use the key formformName
for the database and the table.The nested object specifier records shown in Table 6-9 specify "the rows in which the First Name column equals 'John' and the Last Name column equals 'Chapman.'" To identify the rows that pass this test, the Apple Event Manager needs to evaluate two comparisons: the comparison of each row of the First Name column to the word "John," and the comparison of each row of the Last Name column to the word "Chapman."
The Apple Event Manager uses the information in comparison descriptor records to compare the specified elements in a container, one at a time, either to another Apple event object or to the data associated with a descriptor record. The two comparison descriptor records you need to create for this example are summarized in Table 6-9 on page 6-79.
You can use the
CreateCompDescriptor
function to create a comparison descriptor record, or you can create an AE record and useAECoerceDesc
to coerce it to a comparison descriptor record. Listing 6-17 shows an example of an application-defined routine that creates an object specifier record and a descriptor record oftypeChar
, then uses theCreateCompDescriptor
function to add them to a comparison descriptor record.Listing 6-17 Creating a comparison descriptor record
FUNCTION MyCreateComparisonDescRec (VAR compDesc: AEDesc; colName: str255; name: str255): OSErr; VAR logicalContainer, colNameDesc, nameDesc: AEDesc; myObjectExaminedContainer: AEDesc; myErr: OSErr; BEGIN {create the object specifier record for keyAEObject1; } { first create container} myErr := AECreateDesc(typeObjectBeingExamined, NIL, 0, myObjectExaminedContainer); {create key data} IF myErr = noErr THEN myErr := AECreateDesc(typeChar, @colName[1], Length(colName), colNameDesc); {now create the object specifier record} IF myErr = noErr THEN myErr := CreateObjSpecifier(cColumn, myObjectExaminedContainer, formName, colNameDesc, TRUE, logicalContainer); {create the descriptor record for keyAEObject2} IF myErr = noErr THEN myErr := AECreateDesc(typeChar, @name[1], Length(name), nameDesc); {create the first logical term (comp descriptor record)} IF myErr = noErr THEN myErr := CreateCompDescriptor(kAEEquals, logicalContainer, nameDesc, TRUE, compDesc); MyCreateComparisonDescRec := myErr; END;TheMyCreateComparisonDescRec
function takes two strings and uses them to create a comparison descriptor record. The string passed in the second parameter specifies the name of the column whose contents should be compared to the string passed in the third parameter. First, theMyCreateComparisonDescRec
function usesAECreateDesc
to create a descriptor record oftypeObjectBeingExamined
, which is returned in the variablemyObjectExaminedContainer
. Next,AECreateDesc
creates a descriptor record of descriptor typetypeChar
, whose data consists of the string in the variablecolName
, and which is returned in the variablecolNameDesc
. The code then passes the variablesmyObjectExaminedContainer
andcolNameDesc
to theCreateObjSpecifier
function, which uses them to create an object specifier record, returned in thelogicalContainer
variable, that becomes the keyword-specified descriptor record with the keywordkeyAEObject1
.Next, the
MyCreateComparisonDescRec
function usesAECreateDesc
and thename
parameter to create the descriptor record forkeyAEObject2
, whichAECreateDesc
returns in thenameDesc
variable. Finally, the code passes the constantkAEEquals
, the variablelogicalContainer
, and the variablenameDesc
to theCreateCompDescriptor
function, which creates a comparison descriptor record that allows the Apple Event Manager (with the help of object-comparison functions provided by the server application) to determine whether the specified column in the row currently being checked equals the specified string.You can use the
MyCreateComparisonDescRec
function to create both the descriptor records of typetypeCompDescriptor
shown in Table 6-9 on page 6-79. These descriptor records provide two logical terms for a logical descriptor record. The entire logical descriptor record corresponds to the logical expression "the First Name column equals 'John'AND
the Last Name column equals 'Chapman.'"You can use the
CreateLogicalDescriptor
function to create a logical descriptor record, or you can create an AE record and use theAECoerceDesc
function to coerce it to a comparison descriptor record. Listing 6-18 shows an application-defined function that adds two comparison descriptor records to a descriptor list, then uses theCreateLogicalDescriptor
function to create a logical descriptor record whose logical terms are the two comparison descriptor records.Listing 6-18 Creating a logical descriptor record
FUNCTION MyCreateLogicalDescRec (VAR compDesc1, compDesc2: AEDesc; logicalOperator: DescType; VAR logicalDesc: AEDesc): OSErr; VAR logicalTermsList: AEDescList; myErr: OSErr; BEGIN {create a logical descriptor record that contains two } { comparison descriptor records} {first create a list} myErr := AECreateList(NIL, 0, FALSE, logicalTermsList); IF myErr = noErr THEN myErr := AEPutDesc(logicalTermsList, 1, compDesc1); IF myErr = noErr THEN myErr := AEPutDesc(logicalTermsList, 2, compDesc2); IF myErr = noErr THEN myErr := AEDisposeDesc(compDesc1); IF myErr = noErr THEN myErr := AEDisposeDesc(compDesc2); IF myErr = noErr THEN myErr := CreateLogicalDescriptor(logicalTermsList, logicalOperator, TRUE, logicalDesc); MyCreateLogicalDescRec := myErr; END;Listing 6-19 uses the application-defined functions shown in Listing 6-16, Listing 6-17, and Listing 6-18 to build the object specifier record illustrated in Table 6-8 and Table 6-9.Listing 6-19 Creating a complex object specifier record
FUNCTION MyCreateObjSpecRec (VAR theResultObj: AEDesc): OSErr; VAR nullContainer, databaseContainer, tableContainer: AEDesc; compDesc1, compDesc2: AEDesc; logicalTestDesc, rowTestContainer, rowOffset: AEDesc; myErr: OSErr; BEGIN {create a null container} myErr := AECreateDesc(typeNull, NIL, 0, nullContainer); {create a container for the database} IF myErr = noErr THEN myErr := MyCreateFormNameObjSpecifier(cDatabase, nullContainer, 'SurfDB', databaseContainer); {create a container for the table} IF myErr = noErr THEN myErr := MyCreateFormNameObjSpecifier(cTable, databaseContainer, 'MyAddresses', tableContainer); {create a container for the row--an object specifier record that } { specifies a test (the row whose First Name column = 'John' and } { Last Name column = 'Chapman')} {create the first comparison descriptor record} IF myErr = noErr THEN myErr := MyCreateComparisonDescRec(compDesc1, 'First Name', 'John'); {create the second comparison descriptor record} IF myErr = noErr THEN myErr := MyCreateComparisonDescRec(compDesc2, 'Last Name', 'Chapman'); {create the logical descriptor record} IF myErr = noErr THEN myErr := MyCreateLogicalDescRec(compDesc1, compDesc2, kAEAND, logicalTestDesc); {now create the object specifier record that specifies the test} IF myErr = noErr THEN myErr := CreateObjSpecifier(cRow, tableContainer, formTest, logicalTestDesc, TRUE, rowTestContainer); {create the object specifier record for the Apple event object} {first, create the descriptor record for the key data} IF myErr = noErr THEN myErr := CreateOffsetDescriptor (1, rowOffset); {now create the object specifier record} IF myErr = noErr THEN myErr := CreateObjSpecifier (cRow, rowTestContainer, formAbsolutePosition, rowOffset, TRUE, theResultObj); MyCreateObjSpecRec := myErr; END;TheMyCreateObjSpecRec
function shown in Listing 6-19 begins by usingAECreateDesc
to create a null descriptor record, then uses theMyCreateFormNameObjSpecifier
function (shown in Listing 6-16) to specify the default container for the database named "SurfDB." The code then calls theMyCreateFormNameObjSpecifier
function again, this time passing the object specifier record for SurfDB to specify the container for the table "MyAddresses." The next two calls are both to theMyCreateComparisonDescRec
function (shown in Listing 6-17), which creates the comparison descriptor records that allow the Apple Event Manager to compare the First Name column and Last Name column to the names "John" and "Chapman," respectively. The next call passes these two comparison descriptor records to theMyCreateLogicalDescRec
function (shown in Listing 6-18) in thecompDesc1
andcompDesc2
variables.Now all the components of the logical descriptor record are ready to assemble. The next call, to
CreateObjSpecifier
, specifies the logical descriptor record in thelogicalTestDesc
variable as the key data for the object specifier record that specifies the test. A call to the Apple Event Manager routineCreateOffsetDescriptor
then creates an offset descriptor record that contains the integer 1. Finally, the code passes the offset descriptor record to theCreateObjSpecifier
function in therowOffset
variable to create the final object specifier record, which describes the requested row as the first row that passes the test.The
CreateOffsetDescriptor
function creates a descriptor record of typetypeLongInteger
that can be used as the key data with a key form offormAbsolutePosition
to indicate an element's offset within its container. A positive integer indicates an offset from the beginning of the container (the first element has an offset of 1), and a negative integer indicates an offset from the end of the container (the last element has an offset of -1). UsingCreateOffsetDescriptor
accomplishes the same thing as setting a variable to an integer and passing the variable toAECreateDesc
to create a descriptor record of typetypeLongInteger
.Specifying a Range
The key formformRange
allows your application to specify key data that identifies a range of elements in the specified container. To do so, your application must first create a range descriptor record. The Apple Event Manager uses a range descriptor record to identify the two Apple event objects that specify the beginning and end of a range of elements.For example, an object specifier record for a range of text in a document could specify the table named "Summary of Sales" as the first boundary object and the figure named "Best-Selling Widgets for 1991" as the second boundary object for a range that consists of all the text between the table and the figure. Any word processor that keeps track of the relative positions of text, tables, and figures should be capable of supporting such a request.
Table 6-10 summarizes the logical organization of the data for the object specifier record that specifies this range. For general information about the organization of data within a range descriptor record, see "Key Data for a Range" on page 6-23.
You can use the
CreateRangeDescriptor
function to create a range descriptor record, or you can create an AE record and useAECoerceDesc
to coerce it to a range descriptor record. Listing 6-20 provides an example of an application-defined routine that creates two object specifier records, then uses theCreateRangeDescriptor
function to add them to a range descriptor record.The container for the boundary objects in the range descriptor record created by
Listing 6-20 is the same as the container for the range itself. The object specifier record for the range's container is added to an object specifier record of key formformRange
at the same time that the range descriptor record is added as key data. The container for the two boundary objects can therefore be specified in the range descriptor record by a descriptor record of typetypeCurrentContainer
whose data handle has the valueNIL
. The Apple Event Manager interprets this as a placeholder for the range's container when it is resolving the range descriptor record.Listing 6-20 Creating a range descriptor record
FUNCTION MyCreateRangeDescriptor (VAR rangeDescRec: AEDesc): OSErr; VAR rangeStart: AEDesc; rangeEnd: AEDesc; currentContainer: AEDesc; tableNameDescRec: AEDesc; figureNameDescRec: AEDesc; myErr: OSErr; BEGIN {create the object specifier record for the start of the range } { (the table named 'Summary of Sales' in 'MyDoc' document)} {create a descriptor record of type typeCurrentContainer} myErr := AECreateDesc(typeCurrentContainer, NIL, 0, currentContainer); {create the object specifier record} IF myErr = noErr THEN myErr := MyCreateNameDescRec(tableNameDescRec, 'Summary of Sales'); IF myErr = noErr THEN myErr := CreateObjSpecifier(cTable, currentContainer, formName, tableNameDescRec, FALSE, rangeStart); myErr := AEDisposeDesc(tableNameDescRec); {create the object specifier record for the end of the range } { (the figure named 'Best-Selling Widgets...' in 'MyDoc') } IF myErr = noErr THEN myErr := MyCreateNameDescRec(figureNameDescRec, 'Best-Selling Widgets for 1991'); IF myErr = noErr THEN myErr := CreateObjSpecifier(cFigure, currentContainer, formName, figureNameDescRec, TRUE, rangeEnd); {now create the range descriptor record} IF myErr = noErr THEN myErr := CreateRangeDescriptor(rangeStart, rangeEnd, TRUE, rangeDescRec); MyCreateRangeDescriptor := myErr; END;After creating a descriptor record of typetypeCurrentContainer
and a descriptor record for the first table's name, Listing 6-20 uses theCreateObjSpecifier
function to create an object specifier record that identifies the beginning of the range. The parameters toCreateObjSpecifier
specify that the beginning of the range is an Apple event object of the object classcTable
in the current container, with a key form offormName
and key data that identifies the table by name. A second call toCreateObjSpecifier
creates the object specifier record that identifies the end of the range--an Apple event object of thecFigure
object class in the current container, with a key form offormName
and key data that identifies the figure by name. Finally, the code in Listing 6-20 uses theCreateRangeDescriptor
function to create the range descriptor record, using the two previously created object specifier records to specify the beginning and end of the range.