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/MSAEGetData.c
// MSAEGetData.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 4.0 |
29-Feb-96 : GS : Added abiltiy to get properties from menus and menu items. |
29-Feb-96 : GS : Added script properties to application and document objects. |
*/ |
#include "MSAEGetData.h" |
#include "MSWindow.h" |
#include "MSGlobals.h" |
#include "MSAEUtils.h" |
#include "MSAppleEvents.h" |
#include "MSAETextUtils.h" |
#include "MSAEWindowUtils.h" |
#include "MSAEMenuUtils.h" |
#include "MSAccessors.h" |
#include "MSAERecording.h" |
#include "MSToken.h" |
#include "MSScript.h" |
#include "MSResultWind.h" |
#include <AEPackObject.h> |
#include <Resources.h> |
#ifdef THINK_C |
#include "PLStrs.h" |
#else |
#include <PLStringFuncs.h> |
#endif |
// Globals |
extern short gRefNum; |
// ----------------------------------------------------------------------- |
// Name: DoGetData |
// Purpose: Handles the GetData AppleEvent. |
// ----------------------------------------------------------------------- |
pascal OSErr DoGetData(const AppleEvent *theAppleEvent, |
AppleEvent *reply, |
long handlerRefCon) |
{ |
#ifdef __MWERKS__ |
#pragma unused (handlerRefCon) |
#endif |
AEDesc directObj = {typeNull, NULL}, |
result = {typeNull, NULL}; |
Size actualSize; |
DescType returnedType; |
DescType aWantType; |
OSErr err; |
// extract the direct object, which is the object |
// whose data is to be returned |
err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &directObj); |
if (noErr != err) goto done; |
// now the get the type of data wanted - optional |
err = AEGetParamPtr( theAppleEvent, keyAERequestedType, typeType, |
&returnedType, (Ptr)&aWantType, sizeof( aWantType ), &actualSize ); |
if ( noErr != err ) |
aWantType = typeWildCard; |
err = GotRequiredParams(theAppleEvent); |
if (noErr != err) goto done; |
// get the data |
err = HandleGetData( &directObj, aWantType, &result ); |
err = AddResultToReply(&result, reply, err); |
done: |
(void)AEDisposeDesc( &directObj ); |
(void)AEDisposeDesc( &result ); |
return(err); |
} // DoGetData |
// ----------------------------------------------------------------------- |
// Name: HandleGetData |
// Purpose: Coerces theObj into a token which we understand and |
// extracts the data requested in the token and puts it |
// into dataDesc. |
// ----------------------------------------------------------------------- |
OSErr HandleGetData( AEDesc *theObj, DescType theWantType, AEDesc *result ) |
{ |
TextToken theTextToken; |
Size tokenSize; |
AEDesc objTokenDesc = {typeNull, NULL}, |
itemDesc = {typeNull, NULL}, |
resultDesc = {typeNull, NULL}; |
long index; |
DescType returnedType; |
OSErr err; |
// Coerce theObj into a token which we can use - |
// this may involve converting a list of tokens to a list of property tokens |
if ( typeObjectSpecifier == theObj->descriptorType ) |
err = AEResolve( theObj, kAEIDoMinimum, &objTokenDesc ); |
else if ( typeNull != theObj->descriptorType ) // Otherwise, just copy it |
err = AEDuplicateDesc( theObj, &objTokenDesc ); |
if ( noErr != err ) goto done; |
switch ( objTokenDesc.descriptorType ) |
{ |
case typeMyApplProp: |
err = GetApplicationProperty( &objTokenDesc, theWantType, result ); |
break; |
case typeMyTextProp: |
err = GetTextProperty(&objTokenDesc, result); |
break; |
case typeMyWindowProp: |
err = GetWindowProperty(&objTokenDesc, result); |
break; |
case typeMyDocumentProp: |
err = GetDocumentProperty( &objTokenDesc, theWantType, result ); |
break; |
case typeMyMenuProp: |
err = GetMenuProperty( &objTokenDesc, theWantType, result ); |
break; |
case typeMyMenuItemProp: |
err = GetMenuItemProperty( &objTokenDesc, theWantType, result ); |
break; |
case typeMyText: |
GetRawDataFromDescriptor( &objTokenDesc, (Ptr)&theTextToken, |
sizeof(theTextToken), &tokenSize ); |
if ( theWantType == typeChar || theWantType == typeIntlText ) |
err = GetTextTextProperty( &theTextToken, result ); |
else // For OSADoEvent() |
err = GetTextTokenObjectSpecifier( &theTextToken, result ); |
break; |
case typeAEList: |
err = AECountItems(&objTokenDesc, &index); |
if (noErr != err) goto done; |
for (; index > 0; index--) |
{ |
err = AEGetNthDesc(&objTokenDesc, index, typeWildCard, &returnedType, &itemDesc); |
if (noErr == err) // Call this function recursively if necessary |
err = HandleGetData(&itemDesc, theWantType, &resultDesc); |
if (noErr == err) // Overwrite item in list with descriptor item |
err = AEPutDesc(&objTokenDesc, index, &resultDesc); |
// objTokenDesc is just a copy anyway. |
(void)AEDisposeDesc(&itemDesc); |
(void)AEDisposeDesc(&resultDesc); |
} |
err = AEDuplicateDesc( &objTokenDesc, result ); // Copy list into result |
break; |
default: |
err = AEDuplicateDesc( theObj, result ); // For OSADoEvent() |
break; |
} |
done: |
(void)AEDisposeDesc( &objTokenDesc ); |
return err; |
} // HandleGetData |
// Get the actual data for a text token - rather than just offset and length |
// used internally. |
OSErr GetTextTextProperty(TextToken* theToken, AEDesc *result) |
{ |
TEHandle aTEH; |
short anOffset, |
aLength; |
OSErr err; |
aTEH = TEHandleFromTextToken(theToken); |
anOffset = theToken->tokenOffset; |
aLength = theToken->tokenLength; |
err = BuildStyledTextDesc(aTEH, anOffset, aLength, result); |
return(err); |
} |
// ----------------------------------------------------------------------- |
// Name: GetTextProperty |
// Purpose: Fills result with the requested text property. |
// ----------------------------------------------------------------------- |
OSErr GetTextProperty(const AEDesc *theTokenDesc, AEDesc *result) |
{ |
DPtr theDocument; |
TEHandle theHTE; |
Str255 fontName; |
TextStyle theTextStyle; |
short lineHeight; |
short fontAscent; |
TextPropToken theTextPropToken; |
Size tokenSize; |
AEDesc tempDesc; |
OSErr err; |
err = AECoerceDesc(theTokenDesc, typeMyTextProp, &tempDesc); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor(&tempDesc, (Ptr)&theTextPropToken, |
sizeof(theTextPropToken), &tokenSize); |
// For each property we build a descriptor to be returned as the reply. |
theDocument = DPtrFromWindowPtr(theTextPropToken.tokenTextToken.tokenWindow); |
theHTE = theDocument->theText; |
TEGetStyle(theTextPropToken.tokenTextToken.tokenOffset - 1, &theTextStyle, |
&lineHeight, &fontAscent, theHTE); |
switch (theTextPropToken.tokenProperty) |
{ |
case pText: |
case pContents: |
err = GetTextTextProperty(&(theTextPropToken.tokenTextToken), result); |
break; |
case pFont: |
GetFontName(theTextStyle.tsFont, fontName); |
err = AECreateDesc(typeChar, (Ptr)&fontName[1], fontName[0], result); |
break; |
case pTextStyles: |
err = BuildTextStylesDesc(theTextStyle.tsFace, result); |
break; |
case pPointSize: |
err = CreateOffsetDescriptor(theTextStyle.tsSize, result); |
break; |
case pScriptTag: |
err = CreateOffsetDescriptor(smSystemScript, result); |
break; |
case pColor: |
err = AECreateDesc(typeRGBColor, (Ptr)&theTextStyle.tsColor, |
sizeof(theTextStyle.tsColor), result); |
break; |
case pLength: |
tokenSize = theTextPropToken.tokenTextToken.tokenLength; |
err = AECreateDesc(typeInteger, (Ptr)&tokenSize, |
sizeof(tokenSize), result); |
break; |
case pOffset: |
tokenSize = theTextPropToken.tokenTextToken.tokenOffset; |
err = AECreateDesc(typeInteger, (Ptr)&tokenSize, |
sizeof(tokenSize), result); |
break; |
default: |
err = errAEEventNotHandled; |
} |
done: |
if (tempDesc.dataHandle) |
AEDisposeDesc(&tempDesc); |
return(err); |
} // GetTextProperty |
// ----------------------------------------------------------------------- |
// Name: GetWindowProperty |
// Purpose: Fills result with the requested window property. |
// ----------------------------------------------------------------------- |
OSErr GetWindowProperty(const AEDesc *theTokenDesc, AEDesc *result) |
{ |
WindowPropToken theWindowPropToken; |
AEDesc tempDesc = {typeNull, NULL}; |
Size tokenSize; |
OSErr err; |
err = AECoerceDesc( theTokenDesc, typeMyWindowProp, &tempDesc ); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor(&tempDesc, (Ptr)&theWindowPropToken, |
sizeof(theWindowPropToken), &tokenSize); |
err = GetWindowTokenProperty( &theWindowPropToken, result ); |
done: |
(void)AEDisposeDesc( &tempDesc ); |
return(err); |
} // GetWindowProperty |
OSErr GetWindowTokenProperty( WindowPropToken* theToken, AEDesc *result ) |
{ |
DescType aType; |
Rect aRect; |
Boolean aBoolean; |
Str255 aString; |
long aLong; |
WStateDataHandle stateHandle; |
OSErr err; |
switch( theToken->tokenProperty ) |
{ |
case pClass: |
case pDefaultType: // ? |
aType = cWindow; |
err = AECreateDesc(typeType, (Ptr)&aType, sizeof(aType), result); |
break; |
case pBestType: |
if ( IsDocumentWindow( theToken->tokenWindowToken.tokenWindow ) ) |
aType = cDocument; |
else |
aType = cWindow; |
err = AECreateDesc(typeType, (Ptr)&aType, sizeof(aType), result); |
break; |
case pBounds: |
aRect = (*((WindowPeek)theToken->tokenWindowToken.tokenWindow)->strucRgn)->rgnBBox; |
err = AECreateDesc(typeQDRectangle, (Ptr)&aRect, sizeof(aRect), result); |
break; |
case pVisible: |
aBoolean = IsVisible( theToken->tokenWindowToken.tokenWindow ); |
err = AECreateDesc(typeBoolean, (Ptr)&aBoolean, sizeof(aBoolean), result); |
break; |
case pHasCloseBox: |
aBoolean = ((WindowPeek)theToken->tokenWindowToken.tokenWindow)->goAwayFlag; |
err = AECreateDesc(typeBoolean, (Ptr)&aBoolean, sizeof(aBoolean), result); |
break; |
case pIsZoomable: |
aBoolean = ((WindowPeek)theToken->tokenWindowToken.tokenWindow)->spareFlag; |
err = AECreateDesc(typeBoolean, (Ptr)&aBoolean, sizeof(aBoolean), result); |
break; |
case pIsZoomed: |
if (((WindowPeek)theToken->tokenWindowToken.tokenWindow)->spareFlag) |
{ |
stateHandle = (WStateDataHandle)((WindowPeek)theToken->tokenWindowToken.tokenWindow)->dataHandle; |
HLock((Handle)stateHandle); |
aBoolean = ! EqualRect(&(*stateHandle)->userState, &(*stateHandle)->stdState); |
HUnlock((Handle)stateHandle); |
} |
else |
aBoolean = false; |
err = AECreateDesc(typeBoolean, (Ptr)&aBoolean, sizeof(aBoolean), result); |
break; |
case pName: |
GetWTitle(theToken->tokenWindowToken.tokenWindow, aString); |
err = AECreateDesc(typeChar, (Ptr)&aString[1], aString[0], result); |
break; |
case pIndex: |
aLong = GetWindowIndex( theToken->tokenWindowToken.tokenWindow ); |
err = AECreateDesc(typeLongInteger, (Ptr)&aLong, sizeof(aLong), result); |
break; |
default: |
err = errAEEventNotHandled; |
} |
return(err); |
} |
OSErr GetDocumentProperty( const AEDesc *theTokenDesc, DescType theWantType, AEDesc *result ) |
{ |
WindowPropToken theWindowPropToken; |
AEDesc tempDesc = {typeNull, NULL}; |
Size tokenSize; |
OSErr err; |
err = AECoerceDesc( theTokenDesc, typeMyDocumentProp, &tempDesc ); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor( &tempDesc, (Ptr)&theWindowPropToken, |
sizeof( theWindowPropToken ), &tokenSize ); |
err = GetDocumentTokenProperty( &theWindowPropToken, theWantType, result ); |
done: |
(void)AEDisposeDesc( &tempDesc ); |
return(err); |
} |
OSErr GetDocumentTokenProperty( WindowPropToken* theToken, DescType theWantType, AEDesc *result ) |
{ |
AEDesc aDesc = { typeNull, NULL }; |
DescType aType; |
DescType aLong; |
Boolean aBoolean; |
DPtr aDoc; |
TEHandle theHTE; |
Handle thePGXHandle; |
// Str255 aPStr; |
OSErr err; |
aDoc = DPtrFromWindowPtr( theToken->tokenWindowToken.tokenWindow ); |
switch ( theToken->tokenProperty ) |
{ |
case pBestType: |
case pClass: |
case pDefaultType: |
aType = cDocument; |
err = AECreateDesc( typeType, (Ptr)&aType, sizeof(aType), result ); |
break; |
case pText: |
case pContents: |
theHTE = aDoc->theText; |
err = BuildStyledTextDesc(theHTE, 1, (**theHTE).teLength, result); |
break; |
case pIsModified: |
aBoolean = aDoc->dirty; |
err = AECreateDesc(typeBoolean, (Ptr)&aBoolean, sizeof( aBoolean ), result); |
break; |
case pIndex: |
aLong = GetDocumentIndex( theToken->tokenWindowToken.tokenWindow ); |
err = AECreateDesc(typeLongInteger, (Ptr)&aLong, sizeof(aLong), result); |
break; |
case pPageSetup: |
if (! gGXIsPresent) |
{ |
HLock((Handle)aDoc->thePrintSetup); |
err = AECreateDesc(typeTPrint, (Ptr)*(aDoc->thePrintSetup), |
sizeof(TPrint), result); |
HUnlock((Handle)aDoc->thePrintSetup); |
} |
else |
err = errAEEventNotHandled; |
break; |
case pGXPageSetup: |
if ( gGXIsPresent ) |
{ |
thePGXHandle = NewHandle( 0 ); |
GXFlattenJobToHdl( aDoc->documentJob, thePGXHandle ); |
HLock( thePGXHandle ); |
err = AECreateDesc( typeTPrint, *thePGXHandle, |
GetHandleSize(thePGXHandle), result ); |
HUnlock( thePGXHandle ); |
DisposeHandle( thePGXHandle ); |
} |
else |
err = errAEEventNotHandled; |
break; |
case pSelection: |
err = MakeSelectedTextObj( theToken->tokenWindowToken.tokenWindow, |
aDoc->theText, result ); |
break; |
case pScript: |
if ( kOSANullScript == aDoc->theScriptID ) |
{ |
err = errAENoSuchObject; |
goto done; |
} |
err = GetScriptDesc( aDoc->theScriptID, theWantType, result ); |
break; |
default: |
err = GetWindowTokenProperty( theToken, result ); |
} |
done: |
(void)AEDisposeDesc( &aDesc ); |
return err; |
} |
// ----------------------------------------------------------------------- |
// Name: GetApplicationProperty |
// Purpose: Fills result with the requested application property. |
// ----------------------------------------------------------------------- |
OSErr GetApplicationProperty( const AEDesc *theTokenDesc, DescType theWantType, AEDesc *result ) |
{ |
Boolean isFront; |
AppPropToken theAppPropToken; |
AEDesc aDesc = {typeNull, NULL}, |
nullDesc = {typeNull, NULL}; |
Size tokenSize; |
DescType theType; |
short refNum; |
Handle aHandle; |
OSErr err; |
err = AECoerceDesc(theTokenDesc, typeMyApplProp, &aDesc); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor(&aDesc, (Ptr)&theAppPropToken, |
sizeof(theAppPropToken), &tokenSize); |
switch ( theAppPropToken.tokenProperty ) |
{ |
case pBestType: // Return the null descriptor representing |
case pDefaultType: // the application. |
err = AEDuplicateDesc(&nullDesc, result); |
break; |
case pClass: |
theType = cApplication; |
err = AECreateDesc(typeType, (Ptr)&theType, sizeof(DescType), result); |
break; |
case pName: |
// We got the name and FSSpec for our application |
// in InitApplicationRec(). |
err = AECreateDesc( typeChar, (Ptr)&gAppRec.theName[1], gAppRec.theName[0], result ); |
break; |
case pIsFrontProcess: |
isFront = ! gInBackground; |
err = AECreateDesc(typeBoolean, (Ptr)&isFront, sizeof(isFront), result); |
break; |
case pVersion: |
refNum = CurResFile(); // save current resource |
UseResFile(gRefNum); // set this resource to be current |
aHandle = (Handle)Get1Resource((ResType)'vers', 1); |
HLock(aHandle); |
err = AECreateDesc(typeVersion, *aHandle, GetHandleSize(aHandle), result); |
HUnlock(aHandle); |
UseResFile(refNum); // reset back to resource previously set |
break; |
case pResults: |
err = MakeDocumentObj( GetResultsWindPtr( ), result ); |
break; |
case pScript: |
if ( kOSANullScript == gAppRec.theScriptID ) |
{ |
err = errAENoSuchObject; |
goto done; |
} |
err = GetScriptDesc( gAppRec.theScriptID, theWantType, result ); |
break; |
default: // We don't handle the requested property. |
err = errAEEventNotHandled; |
} |
done: |
(void)AEDisposeDesc( &aDesc ); |
return err; |
} // GetApplicationProperty |
OSErr GetMenuProperty( const AEDesc *theTokenDesc, DescType theWantType, AEDesc *result ) |
{ |
Str255 aPStr; |
MenuPropToken thePropToken; |
MenuItemToken aMenuItemToken; |
AEDesc aDesc = {typeNull, NULL}; |
Size tokenSize; |
DescType aType; |
MenuScriptRecPtr aMenuRecPtr; |
OSErr err; |
err = AECoerceDesc( theTokenDesc, typeMyMenuProp, &aDesc ); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor( &aDesc, (Ptr)&thePropToken, |
sizeof( thePropToken ), &tokenSize ); |
switch ( thePropToken.tokenProperty ) |
{ |
case pBestType: |
case pDefaultType: |
case pClass: |
aType = cMenu; |
err = AECreateDesc( typeType, (Ptr)&aType, sizeof( DescType ), result ); |
break; |
case pName: |
GetMenuName( &thePropToken.token, aPStr ); |
err = AECreateDesc( typeChar, (Ptr)&aPStr[1], aPStr[0], result ); |
break; |
case pMenuID: |
err = AECreateDesc( typeShortInteger, (Ptr)&thePropToken.token.tokenID, |
sizeof( thePropToken.token.tokenID ), result ); |
break; |
case pScript: |
// Get a Ptr to the script for the whole menu |
aMenuRecPtr = GetMenuScriptRecPtr( thePropToken.token.tokenID * 32 ); |
if ( ! aMenuRecPtr || kOSANullScript == aMenuRecPtr->theScriptID ) |
{ |
err = errAENoSuchObject; |
goto done; |
} |
err = GetScriptDesc( aMenuRecPtr->theScriptID, theWantType, result ); |
break; |
case pSelection: |
aMenuItemToken.tokenItem = GetScriptActiveItem( ); |
if ( 0 == aMenuItemToken.tokenItem ) |
aMenuItemToken.tokenItem = 1; |
if ( 0 != aMenuItemToken.tokenItem ) |
{ // A selection is only current while executing a command |
// that has an associated script. |
aMenuItemToken.tokenMenuToken = thePropToken.token; |
err = MakeMenuItemSpecifier( &aMenuItemToken, result ); |
} |
else |
err = errAENoSuchObject; |
break; |
default: // We don't handle the requested property. |
err = errAEEventNotHandled; |
} |
done: |
(void)AEDisposeDesc( &aDesc ); |
return(err); |
} |
OSErr GetMenuItemProperty( const AEDesc *theTokenDesc, DescType theWantType, AEDesc *result ) |
{ |
Str255 aPStr; |
MenuItemPropToken thePropToken; |
AEDesc aDesc = {typeNull, NULL}; |
Size tokenSize; |
DescType aType; |
MenuScriptRecPtr aMenuRecPtr; |
OSErr err; |
err = AECoerceDesc( theTokenDesc, typeMyMenuItemProp, &aDesc ); |
if (noErr != err) goto done; |
GetRawDataFromDescriptor( &aDesc, (Ptr)&thePropToken, |
sizeof( thePropToken ), &tokenSize ); |
switch ( thePropToken.tokenProperty ) |
{ |
case pBestType: // Return the null descriptor representing |
case pDefaultType: // the application. |
case pClass: |
aType = cMenuItem; |
err = AECreateDesc( typeType, (Ptr)&aType, sizeof( DescType ), result ); |
break; |
case pName: |
GetMenuItemName( &thePropToken.token, aPStr ); |
err = AECreateDesc( typeChar, (Ptr)&aPStr[1], aPStr[0], result ); |
break; |
case pItemNumber: |
err = AECreateDesc( typeShortInteger, (Ptr)&thePropToken.token.tokenItem, |
sizeof( thePropToken.token.tokenItem ), result ); |
break; |
case pEnabled: |
err = errAEEventNotHandled; |
break; |
case pScript: |
// Get a Ptr to the script for the menu item |
aMenuRecPtr = GetMenuScriptRecPtr( thePropToken.token.tokenMenuToken.tokenID * 32 |
+ thePropToken.token.tokenItem ); |
if ( ! aMenuRecPtr || kOSANullScript == aMenuRecPtr->theScriptID ) |
{ |
err = errAENoSuchObject; |
goto done; |
} |
err = GetScriptDesc( aMenuRecPtr->theScriptID, theWantType, result ); |
break; |
default: // We don't handle the requested property. |
err = errAEEventNotHandled; |
} |
done: |
(void)AEDisposeDesc( &aDesc ); |
return(err); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14