Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Sources/MSAccessors.c
// MSAEAccessors.c |
// |
// Original version by Jon Lansdell and Nigel Humphreys. |
// 4.0 and 3.1 updates by Greg Sutton. |
// ©Apple Computer Inc 1996, all rights reserved. |
/* |
Changes for 3.1 |
14-Nov-95 : GS : Removed reliance on compiler setting local variable to zero |
in WindowFormAbsolutePosition() and TextFormAbsolutePosition(). |
Changes for 4.0 |
29-Feb-96 : GS : Added differentiation between windows and documents. |
29-Feb-96 : GS : Added resolution of menus and menu items. |
*/ |
#include "MSAccessors.h" |
#include <Menus.h> |
#ifdef THINK_C |
#include "PLStrs.h" |
#else |
#include <PLStringFuncs.h> |
#endif |
#include <Scrap.h> |
#include <TextEdit.h> |
#include <AEObjects.h> |
#include <AEPackObject.h> |
#include <AERegistry.h> |
#include "MSGlobals.h" |
#include "MSUtils.h" |
#include "MSAEUtils.h" |
#include "MSWindow.h" |
#include "MSFile.h" |
#include "MSAppleEvents.h" |
#include "MSToken.h" |
#include "MSAETextUtils.h" |
#include "MSAEWindowUtils.h" |
#include "MSAEMenuUtils.h" |
#pragma segment AppleEvent |
// Install accessors that are used when AEResolve is called to convert |
// object specifiers into internal representations (tokens). |
OSErr InstallAccessors(void) |
{ |
OSErr err; |
err = AEInstallObjectAccessor(cApplication, typeNull, NewOSLAccessorProc(ApplicationFromNullAccessor), 0, false); |
err = AEInstallObjectAccessor(cWindow, typeNull, NewOSLAccessorProc(WindowFromNullAccessor), 0, false); |
err = AEInstallObjectAccessor(cDocument, typeNull, NewOSLAccessorProc(DocumentFromNullAccessor), 0, false); |
err = AEInstallObjectAccessor(cProperty, typeNull, NewOSLAccessorProc(PropertyFromNullAccessor), 0, false); |
err = AEInstallObjectAccessor(cMenu, typeNull, NewOSLAccessorProc(MenuFromNullAccessor), 0, false); |
err = AEInstallObjectAccessor(cWindow, typeMyAppl, NewOSLAccessorProc(WindowFromNullAccessor), 0, false); |
err = AEInstallObjectAccessor(cDocument, typeMyAppl, NewOSLAccessorProc(DocumentFromNullAccessor), 0, false); |
err = AEInstallObjectAccessor(cProperty, typeMyAppl, NewOSLAccessorProc(PropertyFromApplAccessor), 0, false); |
err = AEInstallObjectAccessor(cMenu, typeMyAppl, NewOSLAccessorProc(MenuFromNullAccessor), 0, false); |
err = AEInstallObjectAccessor(cProperty, typeMyWndw, NewOSLAccessorProc(PropertyFromWndwAccessor), 0, false); |
// Handle text from a window |
// e.g. some character of last document |
err = AEInstallObjectAccessor(cInsertionPoint,typeMyDocument, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cChar, typeMyDocument, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cText, typeMyDocument, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cWord, typeMyDocument, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cParagraph, typeMyDocument, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cProperty, typeMyDocument, NewOSLAccessorProc(PropertyFromDocumentAccessor), 0, false); |
// Handle text items within text items |
// e.g. last word of first paragraph of front document |
err = AEInstallObjectAccessor(cInsertionPoint,typeMyText, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cChar, typeMyText, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cText, typeMyText, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cWord, typeMyText, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cParagraph, typeMyText, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cProperty, typeMyText, NewOSLAccessorProc(PropertyFromTextAccessor), 0, false); |
// Menus |
err = AEInstallObjectAccessor(cMenuItem, typeMyMenu, NewOSLAccessorProc(MenuItemFromMenuAccessor), 0, false); |
err = AEInstallObjectAccessor(cProperty, typeMyMenu, NewOSLAccessorProc(PropertyFromMenuAccessor), 0, false); |
// Menu Items |
err = AEInstallObjectAccessor(cProperty, typeMyMenuItem, NewOSLAccessorProc(PropertyFromMenuItemAccessor), 0, false); |
// Handle text items from lists (of hopefully text items) also |
// e.g. every word of every paragraph of front document |
// or even - every word of every character of every paragraph of front document |
err = AEInstallObjectAccessor(cInsertionPoint,typeAEList, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cChar, typeAEList, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cText, typeAEList, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cWord, typeAEList, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cParagraph, typeAEList, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
err = AEInstallObjectAccessor(cProperty, typeAEList, NewOSLAccessorProc(PropertyFromListAccessor), 0, false); |
// This is for 'select insertion point before contents of document 1' |
err = AEInstallObjectAccessor(cInsertionPoint, typeMyWindowProp, NewOSLAccessorProc(TextElemFromTextAccessor), 0, false); |
// This accessor is for getting properties of window properties |
// e.g. font of contents of document 1 |
// Relies on ability to coerce from a window property to text |
// for certain properties. |
err = AEInstallObjectAccessor(cProperty, typeMyDocumentProp, NewOSLAccessorProc(PropertyFromTextAccessor), 0, false); |
return(err); |
} |
// Given selectionData of formAbsolutePosition for a window this routine returns |
// a WindowToken descriptor for specified window. |
// |
// e.g. tell application "MenuScripter" |
// window 1 |
// --first document |
// --some window |
// --every window |
// end tell |
OSErr WindowFormAbsolutePosition(const AEDesc *selectionData, AEDesc* result) |
{ |
AEDesc itemDesc = {typeNull, NULL}; |
short windowCount, |
index; |
OSErr err; |
windowCount = CountWindows(); |
if (! windowCount) |
return(errAEIllegalIndex); |
if (typeAbsoluteOrdinal == selectionData->descriptorType) |
{ |
err = noErr; |
switch (*(DescType *)*selectionData->dataHandle) |
{ |
case kAEFirst: |
index = 1; |
break; |
case kAELast: |
index = windowCount; |
break; |
case kAEMiddle: |
index = (windowCount + 1) / 2; |
break; |
case kAEAny: |
index = (Random() % windowCount) + 1; |
break; |
case kAEAll: |
err = AECreateList(NULL, 0 , false, result); |
if (noErr != err) goto done; |
for (index = 1; index <= windowCount; index++) |
{ |
err = GetDescOfNthWindow(index, &itemDesc); |
if (noErr != err) goto done; |
err = AEPutDesc(result, 0, &itemDesc); |
if (noErr != err) goto done; |
if (itemDesc.dataHandle) |
AEDisposeDesc(&itemDesc); |
} |
goto done; // We have created our list descriptor |
break; // so we can just tidy up and return. |
default: |
err = errAETypeError; |
} |
} |
else |
err = GetIntegerFromDescriptor(selectionData, &index); |
if (noErr != err) goto done; |
if (index < 0) // Handle negative indexes |
index = windowCount + index + 1; |
if (index > windowCount || index <= 0) |
err = errAEIllegalIndex; |
else |
err = GetDescOfNthWindow(index, result); |
done: |
if (itemDesc.dataHandle) |
AEDisposeDesc(&itemDesc); |
return(err); |
} // WindowFormAbsolutePosition |
// Given a formName descriptor in selectionData, this routine returns a |
// WindowToken descriptor for the window with that name. |
// |
// e.g. tell application "MenuScripter" |
// document "Untitled" |
// end tell |
OSErr WindowFormName(const AEDesc *selectionData, AEDesc* result) |
{ |
Str255 name; |
OSErr err; |
// This tries to coerce it first |
err = GetPStringFromDescriptor(selectionData, name); |
if (noErr != err) goto done; |
err = GetDescOfNamedWindow(name, result); |
done: |
return(err); |
} |
// Get a WindowToken descriptor for a window or document object specifier |
// from NULL (or the application). Only handles formAbsolutePosition and formName |
// |
// e.g. tell application "MenuScripter" |
// window 1 |
// --first document |
// --document "Untitled" |
// --every window |
// end tell |
pascal OSErr WindowFromNullAccessor(DescType wantClass, |
const AEDesc *container, |
DescType containerClass, |
DescType form, |
const AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused(container,theRefCon) |
#endif |
OSErr err; |
// Can only handle cWindow and cDocument |
if ( wantClass != cWindow ) |
return errAEWrongDataType; |
// Can only handle typeNull and typeMyAppl |
if ( containerClass != typeNull && containerClass != typeMyAppl ) |
return errAENoSuchObject; |
switch (form) |
{ |
case formAbsolutePosition: |
err = WindowFormAbsolutePosition(selectionData, value); |
break; |
case formName: |
err = WindowFormName(selectionData, value); |
break; |
default: |
err = errAEBadTestKey; |
} |
return err; |
} // WindowFromNullAccessor |
OSErr DocumentFormAbsolutePosition(const AEDesc *selectionData, AEDesc* result) |
{ |
AEDesc itemDesc = {typeNull, NULL}; |
short aCount, |
index; |
OSErr err; |
aCount = CountDocuments(); |
if ( ! aCount ) |
return(errAEIllegalIndex); |
if ( typeAbsoluteOrdinal == selectionData->descriptorType ) |
{ |
err = noErr; |
switch (*(DescType *)*selectionData->dataHandle) |
{ |
case kAEFirst: |
index = 1; |
break; |
case kAELast: |
index = aCount; |
break; |
case kAEMiddle: |
index = ( aCount + 1 ) / 2; |
break; |
case kAEAny: |
index = ( Random() % aCount ) + 1; |
break; |
case kAEAll: |
err = AECreateList( NULL, 0 , false, result ); |
if (noErr != err) goto done; |
for ( index = 1; index <= aCount; index++ ) |
{ |
err = GetDescOfNthDocument( index, &itemDesc ); |
if (noErr != err) goto done; |
err = AEPutDesc( result, 0, &itemDesc ); |
if (noErr != err) goto done; |
(void)AEDisposeDesc( &itemDesc ); |
} |
goto done; // We have created our list descriptor |
break; // so we can just tidy up and return. |
default: |
err = errAETypeError; |
} |
} |
else |
err = GetIntegerFromDescriptor(selectionData, &index); |
if (noErr != err) goto done; |
if (index < 0) // Handle negative indexes |
index = aCount + index + 1; |
if (index > aCount || index <= 0) |
err = errAEIllegalIndex; |
else |
err = GetDescOfNthDocument(index, result); |
done: |
(void)AEDisposeDesc(&itemDesc); |
return(err); |
} // DocumentFormAbsolutePosition |
OSErr DocumentFormName(const AEDesc *selectionData, AEDesc* result) |
{ |
Str255 name; |
OSErr err; |
// This tries to coerce it first |
err = GetPStringFromDescriptor(selectionData, name); |
if (noErr != err) goto done; |
err = GetDescOfNamedDocument(name, result); |
done: |
return(err); |
} |
pascal OSErr DocumentFromNullAccessor(DescType wantClass, |
const AEDesc *container, |
DescType containerClass, |
DescType form, |
const AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused (container,theRefCon) |
#endif |
OSErr err; |
// Can only handle cWindow and cDocument |
if ( wantClass != cDocument ) |
return errAEWrongDataType; |
// Can only handle typeNull and typeMyAppl |
if ( containerClass != typeNull && containerClass != typeMyAppl ) |
return errAENoSuchObject; |
switch (form) |
{ |
case formAbsolutePosition: |
err = DocumentFormAbsolutePosition( selectionData, value ); |
break; |
case formName: |
err = DocumentFormName( selectionData, value ); |
break; |
default: |
err = errAEBadTestKey; |
} |
return err; |
} // DocumentFromNullAccessor |
pascal OSErr ApplicationFromNullAccessor(DescType wantClass, |
const AEDesc *container, |
DescType containerClass, |
DescType form, |
const AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused(container,selectionData,theRefCon) |
#endif |
OSErr myErr; |
AppToken theApp; |
AEDesc resultDesc; |
value->dataHandle = nil; |
resultDesc.dataHandle = nil; |
/* |
should only be called with wantClass = cWindow and |
with containerClass = typeNull. |
Currently accept as either formName or formAbsolutePosition |
*/ |
if ((wantClass != cApplication) || (containerClass != typeNull) || |
!((form == formName) || (form == formAbsolutePosition))) |
return(errAEWrongDataType); |
if ((form == formName) || (form == formAbsolutePosition)) |
{ |
theApp.highLongOfPSN = 0; |
theApp.lowLongOfPSN = kCurrentProcess; |
} |
myErr = AECreateDesc(typeMyAppl, (Ptr)&theApp, sizeof(theApp), value); |
return(myErr); |
} /* ApplicationFromNullAccessor */ |
// Given a formAbsolutePosition selectionData descriptor and a TextToken from |
// which to index from. This routine returns a TextToken descriptor for the |
// text specified. |
// |
// e.g. tell application "MenuScripter" |
// first word of window 1 -- window one will be dealt with in |
// -- WindowFromNullAccessor(). |
// --some character of middle paragraph of last document |
// -- container token will be a paragraph |
// end tell |
OSErr TextFormAbsolutePosition(TextToken* containerToken, AEDesc* selectionData, |
DescType wantClass, AEDesc* result) |
{ |
DPtr docPtr; |
short elementCount; |
AEDesc aDesc = {typeNull, NULL}; |
long index; |
OSErr err; |
docPtr = DPtrFromWindowPtr(containerToken->tokenWindow); |
if (! docPtr) |
{ |
err = errAENoSuchObject; |
goto done; |
} |
err = CountTextElements(docPtr->theText, containerToken->tokenOffset, |
containerToken->tokenLength, wantClass, &elementCount); |
if (noErr != err) goto done; |
if (typeAbsoluteOrdinal == selectionData->descriptorType) |
{ |
err = noErr; |
switch (*(DescType *)*selectionData->dataHandle) |
{ |
case kAEFirst: |
index = 1; |
break; |
case kAELast: |
index = elementCount; |
break; |
case kAEMiddle: |
index = (elementCount + 1) / 2; |
break; |
case kAEAny: |
index = (Random() % elementCount) + 1; |
break; |
case kAEAll: |
err = AECreateList(NULL, 0 , false, result); |
for (index = 1; index <= elementCount; index++) |
{ |
if (noErr == (err = GetDescOfNthTextElement(index, wantClass, |
containerToken, &aDesc))) |
{ |
err = AEPutDesc(result, 0, &aDesc); |
AEDisposeDesc(&aDesc); |
} |
} |
goto done; // Created our result - clean up and return |
break; |
default: |
err = errAETypeError; |
} |
} |
else // Try and get an index out of the descriptor |
err = GetLongIntFromDescriptor(selectionData, &index); |
if (noErr != err) goto done; |
// kAEAll has already created it's list |
err = GetDescOfNthTextElement(index, wantClass, // Checks for negatives and |
containerToken, result); // out of range. |
done: |
if (aDesc.dataHandle) |
AEDisposeDesc(&aDesc); |
return(err); |
} |
// Given a TextToken container and a formRange descriptor. This routine |
// creates a TextToken descriptor starting at the the beginning of the |
// first item in the range and ending at the end of the last item in the range. |
// |
// e.g. tell application "MenuScripter" |
// paragraphs 2 thru 3 of document 1 |
// end tell |
OSErr TextFormRange(TextToken* containerToken, AEDesc* selectionData, |
DescType wantClass, AEDesc* result) |
{ |
#ifdef __MWERKS__ |
#pragma unused(wantClass) |
#endif |
AEDesc selectionRecord = {typeNull, NULL}; |
TextToken startToken, |
stopToken; |
DescType returnedType; |
Size actualSize; |
OSErr err; |
// coerce the selection data into an AERecord |
err = AECoerceDesc(selectionData, typeAERecord, &selectionRecord); |
if (noErr != err) goto done; |
// get the start object as a text token this will reenter |
// TextElemFromTextAccessor() but as formAbsolutePosition via |
// our installed coercion handler CoerceObjToAnything() |
// because the keyAERangeStart parameter is actually an object specifier. |
err = AEGetKeyPtr(&selectionRecord, keyAERangeStart, typeMyText, |
&returnedType, (Ptr)&startToken, sizeof(startToken), &actualSize); |
if (noErr != err) goto done; |
// now do the same for the stop object |
err = AEGetKeyPtr(&selectionRecord, keyAERangeStop, typeMyText, |
&returnedType, (Ptr)&stopToken, sizeof(stopToken), &actualSize); |
if (noErr != err) goto done; |
if (containerToken->tokenWindow != startToken.tokenWindow |
|| containerToken->tokenWindow != stopToken.tokenWindow) |
{ |
err = errAECorruptData; // or whatever |
goto done; |
} |
// Use startToken to create result descriptor |
startToken.tokenLength = stopToken.tokenOffset + stopToken.tokenLength - startToken.tokenOffset; |
err = AECreateDesc(typeMyText, (Ptr)&startToken, sizeof(startToken), result); |
done: |
if (selectionRecord.dataHandle) |
AEDisposeDesc(&selectionRecord); |
return(err); |
} |
// Given a container TextToken and a formRelativePosition selectionData descriptor |
// this routine returns a TextToken descriptor to the reative wantClass object |
// specified. |
// This routine currently only handles relative positions for a wantClass |
// of cInsertionPoint. |
// |
// e.g. tell application "MenuScripter" |
// insertion point after word 5 of document 1 |
// end tell |
OSErr TextFormRelativePosition(TextToken* containerToken, AEDesc* selectionData, |
DescType wantClass, AEDesc* result) |
{ |
TextToken aTextToken; |
DescType aPosition; |
OSErr err; |
aTextToken.tokenWindow = containerToken->tokenWindow; |
switch (wantClass) |
{ |
case cInsertionPoint: |
err = GetEnumeratedFromDescriptor(selectionData, &aPosition); |
switch (aPosition) |
{ |
case kAEPrevious: |
case kAEBefore: |
case kAEBeginning: |
// No change to offset - just 0 length now |
// containerToken.tokenOffset = containerToken.tokenOffset; |
aTextToken.tokenOffset = containerToken->tokenOffset; |
aTextToken.tokenLength = 0; |
break; |
case kAENext: |
case kAEAfter: |
case kAEEnd: |
aTextToken.tokenOffset = containerToken->tokenOffset + containerToken->tokenLength; |
aTextToken.tokenLength = 0; |
break; |
default: |
err = errAEIllegalIndex; |
} |
break; |
default: |
err = errAEWrongDataType; // Could do cChar, cWordÉ but this is only a sample |
} |
if (noErr != err) goto done; |
err = AECreateDesc(typeMyText, (Ptr)&aTextToken, sizeof(aTextToken), result); |
done: |
return(err); |
} |
// Tries to create a TextToken descriptor given a container which may |
// be a TextToken descriptor or a WindowToken descriptor. A |
// selectionData descriptor which can be of formAbsolutePosition, |
// formRange or formRelativePosition, and a wantClass which should |
// be cInsertionPoint, cChar, cText, cWord or cParagraph. |
// |
// e.g. tell application "MenuScripter" |
// first word of document 1 -- document 1 will go through WindowFromNullAccessor() |
// -- which will return a WindowToken descriptor. This |
// -- descriptor will then be coerced to a TextToken |
// -- descriptor and used as the container. |
// end tell |
pascal OSErr TextElemFromTextAccessor(DescType wantClass, |
AEDesc *container, |
DescType containerClass, |
DescType form, |
AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused(containerClass) |
#endif |
TextToken containerToken; |
long index; |
long itemCount; |
AEDesc aDesc = {typeNull, NULL}, |
resultDesc = {typeNull, NULL}; |
DescType returnedType; |
Size actualSize; |
OSErr myErr; |
// If it's a list then we need to call this accessor for every |
// item within the list (which could of course be more lists). |
if (typeAEList == container->descriptorType) |
{ |
myErr = AECreateList(NULL, 0 , false, value); // Result will also be a list of items |
if (noErr != myErr) goto done; |
myErr = AECountItems(container, &itemCount); |
if (noErr != myErr) goto done; |
for (index = 1; index <= itemCount; index++) // Do in forward order |
{ |
myErr = AEGetNthDesc(container, index, typeWildCard, &returnedType, &aDesc); |
if (noErr == myErr) // Call this function recursively if necessary |
myErr = TextElemFromTextAccessor(wantClass, &aDesc, returnedType, |
form, selectionData, &resultDesc, theRefCon); |
if (noErr == myErr) // Add item to the end of our list |
myErr = AEPutDesc(value, 0, &resultDesc); |
if (aDesc.dataHandle) |
AEDisposeDesc(&aDesc); |
if (resultDesc.dataHandle) |
AEDisposeDesc(&resultDesc); |
} |
} |
else |
{ // We have a coercion handler from document to text |
myErr = AECoerceDesc(container, typeMyText, &aDesc); |
if (noErr != myErr) goto done; |
// Get the containing TextToken |
GetRawDataFromDescriptor(&aDesc, (Ptr)&containerToken, sizeof(containerToken), &actualSize); |
switch (form) |
{ |
case formAbsolutePosition: |
myErr = TextFormAbsolutePosition(&containerToken, selectionData, |
wantClass, value); |
break; |
case formRange: |
myErr = TextFormRange(&containerToken, selectionData, |
wantClass, value); |
break; |
case formRelativePosition: |
myErr = TextFormRelativePosition(&containerToken, selectionData, |
wantClass, value); |
break; |
default: |
myErr = errAEBadKeyForm; |
} |
} |
done: |
if (aDesc.dataHandle) |
AEDisposeDesc(&aDesc); |
return(myErr); |
} // TextElemFromTextAccessor |
// Given a TextToken descriptor as a container convert this into |
// a TextPropToken descriptor for the property. |
pascal OSErr PropertyFromTextAccessor(DescType wantClass, |
const AEDesc *container, |
DescType containerClass, |
DescType form, |
const AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused (theRefCon, containerClass) |
#endif |
AEDesc textDesc = {typeNull, NULL}, |
propertyDesc = {typeNull, NULL}; |
Size actualSize; |
TextToken aTextToken; |
TextPropToken aTextPropToken; |
DescType aProperty; |
OSErr err; |
if (cProperty != wantClass || formPropertyID != form) |
return(errAEWrongDataType); |
// Try and coerce to a TextToken descriptor |
err = AECoerceDesc(container, typeMyText, &textDesc); |
if (noErr != err) goto done; |
// Get the TextToken |
GetRawDataFromDescriptor(&textDesc, (Ptr)&aTextToken, |
sizeof(aTextToken), &actualSize); |
// Make sure the selection data is typeType |
err = AECoerceDesc(selectionData, typeType, &propertyDesc); |
if (noErr != err) goto done; |
// Get the property |
GetRawDataFromDescriptor(&propertyDesc, (Ptr)&aProperty, |
sizeof(aProperty), &actualSize); |
// Combine the two into single token |
aTextPropToken.tokenTextToken = aTextToken; |
aTextPropToken.tokenProperty = aProperty; |
err = AECreateDesc(typeMyTextProp, (Ptr)&aTextPropToken, |
sizeof(aTextPropToken), value); |
done: |
(void)AEDisposeDesc(&textDesc); |
(void)AEDisposeDesc(&propertyDesc); |
return(err); |
} // PropertyFromTextAccessor |
// Given a WindowToken descriptor as a container convert this into |
// a WindowPropToken descriptor for the property. |
pascal OSErr PropertyFromWndwAccessor(DescType wantClass, |
AEDesc *container, |
DescType containerClass, |
DescType form, |
AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused(containerClass) |
#endif |
long itemCount, |
index; |
AEDesc resultDesc = {typeNull, NULL}, |
windowDesc = {typeNull, NULL}, |
propDesc = {typeNull, NULL}; |
Size actualSize; |
DescType returnedType; |
WindowToken theWindowToken; |
WindowPropToken myWindowProp; |
OSErr err; |
if (typeAEList == container->descriptorType) |
{ |
err = AECreateList(NULL, 0 , false, value); // Result will also be a list of items |
if (noErr != err) goto done; |
err = AECountItems(container, &itemCount); |
if (noErr != err) goto done; |
for (index = 1; index <= itemCount; index++) // Do in forward order |
{ |
err = AEGetNthDesc(container, index, typeWildCard, &returnedType, &windowDesc); |
if (noErr == err) // Recursively call this routine |
// - could be another list. |
err = PropertyFromWndwAccessor(wantClass, &windowDesc, windowDesc.descriptorType, |
form, selectionData, &resultDesc, theRefCon); |
if (noErr == err) // Add item to the end of our list |
err = AEPutDesc(value, 0, &resultDesc); |
if (windowDesc.dataHandle) |
AEDisposeDesc(&windowDesc); |
if (resultDesc.dataHandle) |
AEDisposeDesc(&resultDesc); |
} |
} |
else |
{ // get the window token - it's the container |
err = AECoerceDesc(container, typeMyWndw, &windowDesc); |
GetRawDataFromDescriptor(&windowDesc, (Ptr)&theWindowToken, |
sizeof(theWindowToken), &actualSize); |
// Check the window exists |
if (theWindowToken.tokenWindow == NULL) |
err = errAEIllegalIndex; |
else |
{ // get the property - it's in the selection data |
err = AECoerceDesc(selectionData, typeType, &propDesc); |
GetRawDataFromDescriptor(&propDesc, (Ptr)&returnedType, |
sizeof(returnedType), &actualSize); |
// Combine the two into single token |
myWindowProp.tokenWindowToken = theWindowToken; |
myWindowProp.tokenProperty = returnedType; |
err = AECreateDesc(typeMyWindowProp, (Ptr)&myWindowProp, |
sizeof(myWindowProp), value); |
} |
} |
done: |
if (windowDesc.dataHandle) |
AEDisposeDesc(&windowDesc); |
if (propDesc.dataHandle) |
AEDisposeDesc(&propDesc); |
if (resultDesc.dataHandle) |
AEDisposeDesc(&resultDesc); |
return(err); |
} // PropertyFromWndwAccessor |
pascal OSErr PropertyFromDocumentAccessor(DescType wantClass, |
AEDesc *container, |
DescType containerClass, |
DescType form, |
AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused(containerClass) |
#endif |
long itemCount, |
index; |
AEDesc resultDesc = {typeNull, NULL}, |
windowDesc = {typeNull, NULL}, |
propDesc = {typeNull, NULL}; |
Size actualSize; |
DescType returnedType; |
WindowToken theWindowToken; |
WindowPropToken myWindowProp; |
OSErr err; |
if (typeAEList == container->descriptorType) |
{ |
err = AECreateList(NULL, 0 , false, value); // Result will also be a list of items |
if (noErr != err) goto done; |
err = AECountItems(container, &itemCount); |
if (noErr != err) goto done; |
for (index = 1; index <= itemCount; index++) // Do in forward order |
{ |
err = AEGetNthDesc(container, index, typeWildCard, &returnedType, &windowDesc); |
if (noErr == err) // Recursively call this routine |
// - could be another list. |
err = PropertyFromDocumentAccessor(wantClass, &windowDesc, windowDesc.descriptorType, |
form, selectionData, &resultDesc, theRefCon); |
if (noErr == err) // Add item to the end of our list |
err = AEPutDesc(value, 0, &resultDesc); |
(void)AEDisposeDesc(&windowDesc); |
(void)AEDisposeDesc(&resultDesc); |
} |
} |
else |
{ // get the window token - it's the container |
err = AECoerceDesc(container, typeMyDocument, &windowDesc); |
GetRawDataFromDescriptor(&windowDesc, (Ptr)&theWindowToken, |
sizeof(theWindowToken), &actualSize); |
// Check the window exists |
if (theWindowToken.tokenWindow == NULL) |
err = errAEIllegalIndex; |
else |
{ // get the property - it's in the selection data |
err = AECoerceDesc(selectionData, typeType, &propDesc); |
GetRawDataFromDescriptor(&propDesc, (Ptr)&returnedType, |
sizeof(returnedType), &actualSize); |
// Combine the two into single token |
myWindowProp.tokenWindowToken = theWindowToken; |
myWindowProp.tokenProperty = returnedType; |
err = AECreateDesc(typeMyDocumentProp, (Ptr)&myWindowProp, |
sizeof(myWindowProp), value); |
} |
} |
done: |
(void)AEDisposeDesc(&windowDesc); |
(void)AEDisposeDesc(&propDesc); |
(void)AEDisposeDesc(&resultDesc); |
return(err); |
} // PropertyFromDocumentAccessor |
pascal OSErr PropertyFromNullAccessor(DescType wantClass, |
AEDesc *container, |
DescType containerClass, |
DescType form, |
AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused (container, containerClass) |
#endif |
AEDesc aDesc = {typeNull, NULL}; |
OSErr err; |
if ((wantClass != cProperty) || (form != formPropertyID)) |
return(errAEWrongDataType); |
switch (*(DescType *)*selectionData->dataHandle) |
{ |
case pSelection: // The selection defaults to the front window |
// selection. |
err = GetDescOfNthDocument( 1, &aDesc ); // Disposed of at end |
if (noErr != err) goto done; |
err = PropertyFromDocumentAccessor(wantClass, &aDesc, typeMyDocument, form, |
selectionData, value, theRefCon); |
break; |
default: // Otherwise try an application property - it is fron NULL |
err = PropertyFromApplAccessor(wantClass, &aDesc, typeMyWndw, form, |
selectionData, value, theRefCon); |
} |
done: |
(void)AEDisposeDesc( &aDesc ); |
return err; |
} |
// Convert a list of Token descriptors to a list of Property Token descriptors. |
// Only TextTokens and WindowTokens are supported in this version. |
OSErr TokenListToPropertyList(AEDesc* tokenList, DescType aProperty, AEDesc* result) |
{ |
AEDesc aDesc = {typeNull, NULL}, |
resultDesc = {typeNull, NULL}; |
DescType returnedType; |
long itemCount, |
index; |
WindowPropToken aWindowPropToken; |
TextPropToken aTextPropToken; |
Size actualSize; |
OSErr err; |
err = AECreateList(NULL, 0 , false, result); // Result will also be a list of items |
if (noErr != err) goto done; |
err = AECountItems(tokenList, &itemCount); // Will return an error if not of type typeAEList |
if (noErr != err) goto done; |
for (index = 1; index <= itemCount; index++) // Do in forward order |
{ |
err = AEGetNthDesc(tokenList, index, typeWildCard, &returnedType, &aDesc); |
if (noErr == err) // Create appropriate property token |
switch (aDesc.descriptorType) |
{ |
case typeMyWndw: |
GetRawDataFromDescriptor(&aDesc, (Ptr)&aWindowPropToken, |
sizeof(WindowToken), &actualSize); |
aWindowPropToken.tokenProperty = aProperty; |
err = AECreateDesc(typeMyWindowProp, (Ptr)&aWindowPropToken, |
sizeof(aWindowPropToken), &resultDesc); |
break; |
case typeMyText: |
GetRawDataFromDescriptor(&aDesc, (Ptr)&aTextPropToken, |
sizeof(TextToken), &actualSize); |
aTextPropToken.tokenProperty = aProperty; |
err = AECreateDesc(typeMyTextProp, (Ptr)&aTextPropToken, |
sizeof(aTextPropToken), &resultDesc); |
break; |
case typeAEList: // Recursive call if a list |
err = TokenListToPropertyList(&aDesc, aProperty, &resultDesc); |
break; |
default: // May already be a property token |
err = errAEBadListItem; |
} |
if (noErr == err) // Add item to the end of our list |
err = AEPutDesc(result, 0, &resultDesc); |
if (aDesc.dataHandle) |
AEDisposeDesc(&aDesc); |
if (resultDesc.dataHandle) |
AEDisposeDesc(&resultDesc); |
err = noErr; // Try and do all the items we can in the list |
} |
done: |
return(err); |
} |
// Given a container that is a list of Token descriptors, this routine |
// returns a list of PropToken descriptors. |
pascal OSErr PropertyFromListAccessor(DescType wantClass, |
AEDesc *container, |
DescType containerClass, |
DescType form, |
AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused(containerClass, theRefCon) |
#endif |
OSErr err; |
if (wantClass != cProperty && form != formPropertyID) |
return(errAEBadKeyForm); |
err = TokenListToPropertyList(container, *(DescType *)*selectionData->dataHandle, value); |
return(err); |
} |
// Given a AppToken descriptor as a container convert this into |
// a WindowPropToken descriptor for the property. |
pascal OSErr PropertyFromApplAccessor(DescType wantClass, |
const AEDesc *container, |
DescType containerClass, |
DescType form, |
const AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused (theRefCon, containerClass) |
#endif |
OSErr myErr; |
OSErr ignoreErr; |
AppToken theApplToken; |
DescType theProperty; |
AEDesc applDesc; |
AEDesc propDesc; |
Size actualSize; |
AppPropToken myApplProp; |
value->dataHandle = nil; |
applDesc.dataHandle = nil; |
propDesc.dataHandle = nil; |
if ((wantClass != cProperty) || |
(form != formPropertyID)) |
{ |
return(errAEWrongDataType); |
} |
// get the application token - it's the container |
myErr = AECoerceDesc(container, typeMyAppl, &applDesc); |
GetRawDataFromDescriptor(&applDesc, (Ptr)&theApplToken, |
sizeof(theApplToken), &actualSize); |
// get the property - it's in the selection data |
myErr = AECoerceDesc(selectionData, typeType, &propDesc); |
GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, |
sizeof(theProperty), &actualSize); |
// Combine the two into single token |
myApplProp.tokenAppToken = theApplToken; |
myApplProp.tokenProperty = theProperty; |
myErr = AECreateDesc(typeMyApplProp, (Ptr)&myApplProp, |
sizeof(myApplProp), value); |
if (applDesc.dataHandle) |
ignoreErr = AEDisposeDesc(&applDesc); |
if (propDesc.dataHandle) |
ignoreErr = AEDisposeDesc(&propDesc); |
return(myErr); |
} // PropertyFromApplAccessor |
pascal OSErr PropertyFromWinPropertyAccessor(DescType wantClass, |
const AEDesc *container, |
DescType containerClass, |
DescType form, |
const AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused(wantClass, containerClass, form, theRefCon) |
#endif |
OSErr myErr; |
OSErr ignoreErr; |
WindowPropToken theWindowPropToken; |
AEDesc newDesc, propDesc; |
Size tokenSize; |
DPtr theDocument; |
TextToken theTextToken; |
DescType theProperty; |
Size actualSize; |
TextPropToken myTextProp; |
// the container is a window property token. Get the token for this |
// and check that it is valid to get a property of this property |
myErr = AECoerceDesc(container, typeMyWindowProp, &newDesc); |
if (myErr) |
return(myErr); |
GetRawDataFromDescriptor(&newDesc, (Ptr)&theWindowPropToken, |
sizeof(theWindowPropToken), &tokenSize); |
// if the property is pSelection, we then want to convert this to a text token |
// and then return a text property token |
if (theWindowPropToken.tokenProperty == pSelection) |
{ |
theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken.tokenWindow); |
// build a text token to represent the selection |
theTextToken.tokenOffset = (**(theDocument->theText)).selStart + 1; |
theTextToken.tokenLength = ((**(theDocument->theText)).selEnd - |
(**(theDocument->theText)).selStart) -1; |
theTextToken.tokenWindow = theWindowPropToken.tokenWindowToken.tokenWindow; |
// now get the property- it's in the selection data |
myErr = AECoerceDesc(selectionData, typeType, &propDesc); |
GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, |
sizeof(theProperty), &actualSize); |
// Combine the two into single token |
myTextProp.tokenTextToken = theTextToken; |
myTextProp.tokenProperty = theProperty; |
myErr = AECreateDesc(typeMyTextProp,(Ptr)&myTextProp, |
sizeof(myTextProp),value); |
if (propDesc.dataHandle) ignoreErr = AEDisposeDesc(&propDesc); |
if (newDesc.dataHandle) ignoreErr = AEDisposeDesc(&newDesc); |
return myErr; |
} |
if (newDesc.dataHandle) |
ignoreErr = AEDisposeDesc(&newDesc); |
return errAEWrongDataType; |
} |
OSErr MenuFormAbsolutePosition( const AEDesc *selectionData, AEDesc* result ) |
{ |
AEDesc itemDesc = {typeNull, NULL}; |
short aCount, |
index; |
OSErr err; |
aCount = CountMenus(); |
if (! aCount) |
return(errAEIllegalIndex); |
if ( typeAbsoluteOrdinal == selectionData->descriptorType ) |
{ |
err = noErr; |
switch (*(DescType *)*selectionData->dataHandle) |
{ |
case kAEFirst: |
index = 1; |
break; |
case kAELast: |
index = aCount; |
break; |
case kAEMiddle: |
index = (aCount + 1) / 2; |
break; |
case kAEAny: |
index = (Random() % aCount) + 1; |
break; |
case kAEAll: |
err = AECreateList(NULL, 0 , false, result); |
if (noErr != err) goto done; |
for (index = 1; index <= aCount; index++) |
{ |
err = GetDescOfNthMenu(index, &itemDesc); |
if (noErr != err) goto done; |
err = AEPutDesc(result, 0, &itemDesc); |
if (noErr != err) goto done; |
if (itemDesc.dataHandle) |
AEDisposeDesc(&itemDesc); |
} |
goto done; // We have created our list descriptor |
break; // so we can just tidy up and return. |
default: |
err = errAETypeError; |
} |
} |
else |
err = GetIntegerFromDescriptor( selectionData, &index ); |
if (noErr != err) goto done; |
if (index < 0) // Handle negative indexes |
index = aCount + index + 1; |
if ( index > aCount || index <= 0 ) |
err = errAEIllegalIndex; |
else |
err = GetDescOfNthMenu( index, result ); |
done: |
(void)AEDisposeDesc( &itemDesc ); |
return err; |
} // MenuFormAbsolutePosition |
OSErr MenuFormName( const AEDesc *selectionData, AEDesc* result ) |
{ |
Str255 name; |
OSErr err; |
// This tries to coerce it first |
err = GetPStringFromDescriptor( selectionData, name ); |
if ( noErr != err ) goto done; |
err = GetDescOfNamedMenu( name, result ); |
done: |
return(err); |
} |
pascal OSErr MenuFromNullAccessor( DescType wantClass, |
const AEDesc *container, |
DescType containerClass, |
DescType form, |
const AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused (container,theRefCon) |
#endif |
OSErr err; |
// Can only handle cWindow and cDocument |
if ( wantClass != cMenu ) |
return errAEWrongDataType; |
// Can only handle typeNull and typeMyAppl |
if ( containerClass != typeNull && containerClass != typeMyAppl ) |
return errAENoSuchObject; |
switch (form) |
{ |
case formAbsolutePosition: |
err = MenuFormAbsolutePosition( selectionData, value ); |
break; |
case formName: |
err = MenuFormName( selectionData, value ); |
break; |
default: |
err = errAEBadTestKey; |
} |
return err; |
} |
pascal OSErr PropertyFromMenuAccessor(DescType wantClass, |
AEDesc *container, |
DescType containerClass, |
DescType form, |
AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused(containerClass) |
#endif |
long itemCount, |
index; |
AEDesc resultDesc = {typeNull, NULL}, |
aDesc = {typeNull, NULL}, |
propDesc = {typeNull, NULL}; |
Size actualSize; |
DescType returnedType; |
MenuToken theToken; |
MenuPropToken thePropertyToken; |
OSErr err; |
if (typeAEList == container->descriptorType) |
{ |
err = AECreateList( NULL, 0 , false, value ); // Result will also be a list of items |
if (noErr != err) goto done; |
err = AECountItems( container, &itemCount ); |
if (noErr != err) goto done; |
for ( index = 1; index <= itemCount; index++ ) // Do in forward order |
{ |
err = AEGetNthDesc( container, index, typeWildCard, &returnedType, &aDesc ); |
if ( noErr != err ) goto done; |
// Recursively call this routine |
// - could be another list. |
err = PropertyFromMenuAccessor( wantClass, &aDesc, aDesc.descriptorType, |
form, selectionData, &resultDesc, theRefCon ); |
err = AEPutDesc( value, 0, &resultDesc ); // Add item to the end of our list |
if ( noErr != err ) goto done; |
(void)AEDisposeDesc( &aDesc ); |
(void)AEDisposeDesc( &resultDesc ); |
} |
} |
else |
{ // get the window token - it's the container |
err = AECoerceDesc( container, typeMyMenu, &aDesc ); |
if ( noErr != err ) goto done; |
GetRawDataFromDescriptor( &aDesc, (Ptr)&theToken, |
sizeof(theToken), &actualSize ); |
// get the property - it's in the selection data |
err = AECoerceDesc( selectionData, typeType, &propDesc ); |
if ( noErr != err ) goto done; |
GetRawDataFromDescriptor( &propDesc, (Ptr)&returnedType, |
sizeof(returnedType), &actualSize ); |
// Combine the two into single token |
thePropertyToken.token = theToken; |
thePropertyToken.tokenProperty = returnedType; |
err = AECreateDesc( typeMyMenuProp, (Ptr)&thePropertyToken, |
sizeof( thePropertyToken ), value ); |
} |
done: |
(void)AEDisposeDesc( &aDesc ); |
(void)AEDisposeDesc( &propDesc ); |
(void)AEDisposeDesc( &resultDesc ); |
return(err); |
} // PropertyFromMenuAccessor |
OSErr MenuItemFormAbsolutePosition( MenuToken* containerToken, const AEDesc *selectionData, AEDesc* result ) |
{ |
AEDesc itemDesc = {typeNull, NULL}; |
short aCount, |
index; |
OSErr err; |
aCount = CountMenuTokenItems( containerToken ); |
if (! aCount) |
return(errAEIllegalIndex); |
if ( typeAbsoluteOrdinal == selectionData->descriptorType ) |
{ |
err = noErr; |
switch (*(DescType *)*selectionData->dataHandle) |
{ |
case kAEFirst: |
index = 1; |
break; |
case kAELast: |
index = aCount; |
break; |
case kAEMiddle: |
index = (aCount + 1) / 2; |
break; |
case kAEAny: |
index = (Random() % aCount) + 1; |
break; |
case kAEAll: |
err = AECreateList(NULL, 0 , false, result); |
if (noErr != err) goto done; |
for (index = 1; index <= aCount; index++) |
{ |
err = GetDescOfNthMenuItem( containerToken, index, &itemDesc ); |
if (noErr != err) goto done; |
err = AEPutDesc(result, 0, &itemDesc); |
if (noErr != err) goto done; |
if (itemDesc.dataHandle) |
AEDisposeDesc(&itemDesc); |
} |
goto done; // We have created our list descriptor |
break; // so we can just tidy up and return. |
default: |
err = errAETypeError; |
} |
} |
else |
err = GetIntegerFromDescriptor( selectionData, &index ); |
if (noErr != err) goto done; |
if (index < 0) // Handle negative indexes |
index = aCount + index + 1; |
if ( index > aCount || index <= 0 ) |
err = errAEIllegalIndex; |
else |
err = GetDescOfNthMenuItem( containerToken, index, result ); |
done: |
(void)AEDisposeDesc( &itemDesc ); |
return err; |
} // MenuFormAbsolutePosition |
OSErr MenuItemFormName( MenuToken* containerToken, const AEDesc* selectionData, AEDesc* result ) |
{ |
Str255 name; |
OSErr err; |
// This tries to coerce it first |
err = GetPStringFromDescriptor( selectionData, name ); |
if ( noErr != err ) goto done; |
err = GetDescOfNamedMenuItem( containerToken, name, result ); |
done: |
return(err); |
} |
pascal OSErr MenuItemFromMenuAccessor( DescType wantClass, |
const AEDesc *container, |
DescType containerClass, |
DescType form, |
const AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused ( containerClass, theRefCon ) |
#endif |
MenuToken containerToken; |
Size actualSize; |
OSErr err; |
// Can only handle cMenu |
if ( wantClass != cMenuItem ) |
return errAEWrongDataType; |
// Can only handle typeMyMenu |
if ( container->descriptorType != typeMyMenu ) |
return errAENoSuchObject; |
// Get the containing MenuToken |
GetRawDataFromDescriptor( container, (Ptr)&containerToken, |
sizeof( containerToken ), &actualSize ); |
switch (form) |
{ |
case formAbsolutePosition: |
err = MenuItemFormAbsolutePosition( &containerToken, selectionData, value ); |
break; |
case formName: |
err = MenuItemFormName( &containerToken, selectionData, value ); |
break; |
default: |
err = errAEBadTestKey; |
} |
return err; |
} |
pascal OSErr PropertyFromMenuItemAccessor(DescType wantClass, |
AEDesc *container, |
DescType containerClass, |
DescType form, |
AEDesc *selectionData, |
AEDesc *value, |
long theRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused(containerClass) |
#endif |
long itemCount, |
index; |
AEDesc resultDesc = {typeNull, NULL}, |
aDesc = {typeNull, NULL}, |
propDesc = {typeNull, NULL}; |
Size actualSize; |
DescType returnedType; |
MenuItemToken theToken; |
MenuItemPropToken thePropertyToken; |
OSErr err; |
if (typeAEList == container->descriptorType) |
{ |
err = AECreateList( NULL, 0 , false, value ); // Result will also be a list of items |
if ( noErr != err ) goto done; |
err = AECountItems( container, &itemCount ); |
if ( noErr != err ) goto done; |
for ( index = 1; index <= itemCount; index++ ) // Do in forward order |
{ |
err = AEGetNthDesc( container, index, typeWildCard, &returnedType, &aDesc ); |
if ( noErr != err ) goto done; |
// Recursively call this routine |
// - could be another list. |
err = PropertyFromMenuItemAccessor( wantClass, &aDesc, aDesc.descriptorType, |
form, selectionData, &resultDesc, theRefCon ); |
if ( noErr != err ) goto done; |
err = AEPutDesc( value, 0, &resultDesc ); // Add item to the end of our list |
if ( noErr != err ) goto done; |
(void)AEDisposeDesc( &aDesc ); |
(void)AEDisposeDesc( &resultDesc ); |
} |
} |
else |
{ |
err = AECoerceDesc(container, typeMyMenuItem, &aDesc); |
if ( noErr != err ) goto done; |
GetRawDataFromDescriptor(&aDesc, (Ptr)&theToken, |
sizeof(theToken), &actualSize); |
// get the property - it's in the selection data |
err = AECoerceDesc( selectionData, typeType, &propDesc ); |
if ( noErr != err ) goto done; |
GetRawDataFromDescriptor( &propDesc, (Ptr)&returnedType, |
sizeof(returnedType), &actualSize ); |
// Combine the two into single token |
thePropertyToken.token = theToken; |
thePropertyToken.tokenProperty = returnedType; |
err = AECreateDesc( typeMyMenuItemProp, (Ptr)&thePropertyToken, |
sizeof( thePropertyToken ), value ); |
} |
done: |
(void)AEDisposeDesc(&aDesc); |
(void)AEDisposeDesc(&propDesc); |
(void)AEDisposeDesc(&resultDesc); |
return(err); |
} // PropertyFromMenuItemAccessor |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14