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.
Relevant replacement documents include:
MoreAppleEvents/MoreAppleEvents.cp
/* |
File: MoreAppleEvents.cp |
Contains: |
Written by: Andy Bachorski |
Copyright: Copyright (c) 2000 Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
<11> 27/3/00 Quinn Remove MoreAEDeleteItemFromRecord. It's functionality is |
covered by AEDeleteKeyDesc. |
<10> 20/3/00 Quinn Added routines to deal with "missing value". Added |
MoreAECopyDescriptorDataToHandle. Added |
MoreAEDeleteItemFromRecord. |
<9> 3/9/00 gaw Y2K! |
<8> 3/9/00 gaw API changes for MoreAppleEvents |
<7> 3/9/00 GW Intergrating AppleEvent Helper code. First Check In |
<6> 6/3/00 Quinn Added a bunch of trivial wrapper routines. George may come |
along and change all these soon, but I needed them for MoreOSL. |
<5> 1/3/00 Quinn Change the signature for AEGetDescData to match the version we |
actually shipped. |
<4> 2/15/99 PCG add AEGetDescDataSize for non-Carbon clients |
<3> 1/29/99 PCG add AEGetDescData |
<2> 11/11/98 PCG fix header |
<1> 11/10/98 PCG first big re-org at behest of Quinn |
Old Change History (most recent first): |
<2> 10/11/98 Quinn Convert "MorePrefix.h" to "MoreSetup.h". |
<2> 6/16/98 PCG CreateProcessTarget works with nil PSN |
<1> 6/16/98 PCG initial checkin |
*/ |
// Conditionals to setup the build environment the way we like it. |
#include "MoreSetup.h" |
//********** Universal Headers **************************************** |
#include <AERegistry.h> |
#include <AEObjects.h> |
#include <AEPackObject.h> |
#include <ASRegistry.h> |
//#include <FinderRegistry.h> |
#include <Gestalt.h> |
//********** Project Headers **************************************** |
#include "MoreAppleEvents.h" |
#include "MoreAEObjects.h" |
#include "MoreProcesses.h" |
#include "MoreMemory.h" |
//********** Private Definitions **************************************** |
enum { |
kFinderFileType = 'FNDR', |
kFinderCreatorType = 'MACS', |
kFinderProcessType = 'FNDR', |
kFinderProcessSignature = 'MACS' |
}; |
static AEIdleUPP gAEIdleUPP = nil; |
//******************************************************************************* |
#pragma mark ==> Create Target Descriptors for AEvents ¥ |
/******************************************************************************** |
Create and return an AEDesc for the process target with the specified PSN. |
If no PSN is supplied the use the current process |
pAEEventClass input: The class of the event to be created. |
pAEEventID input: The ID of the event to be created. |
pAppleEvent input: Pointer to an AppleEvent where the |
event record will be returned. |
output: The Apple event. |
RESULT CODES |
____________ |
noErr 0 No error |
memFullErr -108 Not enough room in heap zone |
____________ |
*/ |
pascal OSErr MoreAECreateProcessTarget (ProcessSerialNumber *pPSN, AEDesc *target) |
{ |
ProcessSerialNumber self; |
if (!pPSN) |
{ |
pPSN = &self; |
self.lowLongOfPSN = kNoProcess; |
self.highLongOfPSN = kCurrentProcess; |
} |
return AECreateDesc (typeProcessSerialNumber,pPSN,sizeof(*pPSN),target); |
} |
//******************************************************************************* |
#pragma mark ==> Create AEvents ¥ |
/******************************************************************************** |
Create and return an AppleEvent of the given class and ID. The event will be |
targeted at the current process, with an AEAddressDesc of type |
typeProcessSerialNumber. |
pAEEventClass input: The class of the event to be created. |
pAEEventID input: The ID of the event to be created. |
pAppleEvent input: Pointer to an AppleEvent where the |
event record will be returned. |
output: The Apple event. |
RESULT CODES |
____________ |
noErr 0 No error |
memFullErr -108 Not enough room in heap zone |
____________ |
*/ |
pascal OSErr MoreAECreateAppleEventSelfTarget( const AEEventClass pAEEventClass, |
const AEEventID pAEEventID, |
AppleEvent *pAppleEvent ) |
{ |
OSErr anErr = noErr; |
ProcessSerialNumber selfPSN = {0, kCurrentProcess}; |
anErr = MoreAECreateAppleEventProcessTarget( &selfPSN, pAEEventClass, pAEEventID, pAppleEvent ); |
return ( anErr ); |
}//end MoreAECreateAppleEventSelfTarget |
/******************************************************************************** |
Create and return an AppleEvent of the given class and ID. The event will be |
targeted at the process specified by the target type and creator codes, |
with an AEAddressDesc of type typeProcessSerialNumber. |
pType input: The file type of the process to be found. |
pCreator input: The creator type of the process to be found. |
pAEEventClass input: The class of the event to be created. |
pAEEventID input: The ID of the event to be created. |
pAppleEvent input: Pointer to an AppleEvent where the |
event record will be returned. |
output: The Apple event. |
RESULT CODES |
____________ |
noErr 0 No error |
memFullErr -108 Not enough room in heap zone |
procNotFound Ð600 No eligible process with specified descriptor |
____________ |
*/ |
pascal OSErr MoreAECreateAppleEventSignatureTarget(const OSType pType, |
const OSType pCreator, |
const AEEventClass pAEEventClass, |
const AEEventID pAEEventID, |
AppleEvent *pAppleEvent ) |
{ |
OSErr anErr = noErr; |
ProcessSerialNumber psn = {kNoProcess, kNoProcess}; |
anErr = MoreProcFindProcessBySignature( pType, pCreator, &psn ); |
if ( anErr == noErr ) |
{ |
anErr = MoreAECreateAppleEventProcessTarget( &psn, pAEEventClass, pAEEventID, pAppleEvent ); |
} |
return anErr; |
}//end MoreAECreateAppleEventSignatureTarget |
/******************************************************************************** |
Create and return an AppleEvent of the given class and ID. The event will be |
targeted at the application with the specific creator. |
psnPtr input: Pointer to the PSN to target the event with. |
pAEEventClass input: The class of the event to be created. |
pAEEventID input: The ID of the event to be created. |
pAppleEvent input: Pointer to an AppleEvent where the |
event record will be returned. |
output: The Apple event. |
RESULT CODES |
____________ |
noErr 0 No error |
memFullErr -108 Not enough room in heap zone |
procNotFound Ð600 No eligible process with specified descriptor |
____________ |
*/ |
pascal OSStatus MoreAECreateAppleEventCreatorTarget( |
const AEEventClass pAEEventClass, |
const AEEventID pAEEventID, |
const OSType pCreator, |
AppleEvent *pAppleEvent) |
{ |
OSStatus err; |
AEDesc targetDesc; |
MoreAssertQ(pAppleEvent != nil); |
MoreAENullDesc(&targetDesc); |
err = AECreateDesc(typeApplSignature, &pCreator, sizeof(pCreator), &targetDesc); |
if (err == noErr) |
err = AECreateAppleEvent(pAEEventClass, pAEEventID, &targetDesc, |
kAutoGenerateReturnID, kAnyTransactionID, pAppleEvent); |
MoreAEDisposeDesc(&targetDesc); |
return err; |
} |
/******************************************************************************** |
Create and return an AppleEvent of the given class and ID. The event will be |
targeted with the provided PSN. |
psnPtr input: Pointer to the PSN to target the event with. |
pAEEventClass input: The class of the event to be created. |
pAEEventID input: The ID of the event to be created. |
pAppleEvent input: Pointer to an AppleEvent where the |
event record will be returned. |
output: The Apple event. |
RESULT CODES |
____________ |
noErr 0 No error |
memFullErr -108 Not enough room in heap zone |
procNotFound Ð600 No eligible process with specified descriptor |
____________ |
*/ |
pascal OSErr MoreAECreateAppleEventProcessTarget( const ProcessSerialNumberPtr psnPtr, |
const AEEventClass pAEEventClass, |
const AEEventID pAEEventID, |
AppleEvent *pAppleEvent ) |
{ |
OSErr anErr = noErr; |
AEDesc targetAppDesc = {typeNull, nil}; |
anErr = AECreateDesc (typeProcessSerialNumber, psnPtr, sizeof( ProcessSerialNumber ), &targetAppDesc); |
if ( anErr == noErr ) |
{ |
anErr = AECreateAppleEvent( pAEEventClass, pAEEventID, &targetAppDesc, |
kAutoGenerateReturnID, kAnyTransactionID, pAppleEvent); |
} |
AEDisposeDesc( &targetAppDesc ); |
return anErr; |
}//end MoreAECreateAppleEventProcessTarget |
/******************************************************************************** |
Create and return an AppleEvent of the given class and ID. The event will be |
targeted with the provided TargetID. |
pTargetID input: Pointer to the TargetID to target the event with. |
pAEEventClass input: The class of the event to be created. |
pAEEventID input: The ID of the event to be created. |
pAppleEvent input: Pointer to an AppleEvent where the |
event record will be returned. |
output: The Apple event. |
RESULT CODES |
____________ |
noErr 0 No error |
memFullErr -108 Not enough room in heap zone |
procNotFound Ð600 No eligible process with specified descriptor |
____________ |
*/ |
pascal OSErr MoreAECreateAppleEventTargetID( const TargetID *pTargetID, |
const AEEventClass pAEEventClass, |
const AEEventID pAEEventID, |
AppleEvent *pAppleEvent ) |
{ |
OSErr anErr = noErr; |
AEDesc targetAppDesc = {typeNull, nil}; |
anErr = AECreateDesc (typeTargetID, pTargetID, sizeof( TargetID ), &targetAppDesc); |
if ( anErr == noErr ) |
{ |
anErr = AECreateAppleEvent( pAEEventClass, pAEEventID, &targetAppDesc, |
kAutoGenerateReturnID, kAnyTransactionID, pAppleEvent); |
} |
AEDisposeDesc( &targetAppDesc ); |
return anErr; |
}//end MoreAECreateAppleEventTargetID |
#pragma mark ==> Send AppleEvents ¥ |
#if 0 |
//¥ De-appreciated! Don't use! Use one of the more specific routines (w/idle proc) below. |
pascal OSErr MoreAESendAppleEvent (const AppleEvent *pAppleEvent, AppleEvent *pAEReply) |
{ |
OSErr err = noErr; |
AESendMode aeSendMode = kAEAlwaysInteract | kAECanSwitchLayer; |
if (pAEReply) |
{ |
aeSendMode |= kAEWaitReply; |
pAEReply->descriptorType = typeNull; |
pAEReply->dataHandle = nil; |
} |
err = AESend (pAppleEvent, pAEReply, aeSendMode, kAENormalPriority, kAEDefaultTimeout, nil, nil); |
return err; |
} |
#endif 0 |
/******************************************************************************** |
Send the provided AppleEvent using the provided idle function. |
Will wait for a reply if an idle function is provided, but no result will be returned. |
pIdleProcUPP input: The idle function to use when sending the event. |
pAppleEvent input: The event to be sent. |
RESULT CODES |
____________ |
noErr 0 No error |
and any other error that can be returned by AESend or the handler |
in the application that gets the event. |
____________ |
*/ |
pascal OSErr MoreAESendEventNoReturnValue( |
const AEIdleUPP pIdleProcUPP, |
const AppleEvent *pAppleEvent ) |
{ |
OSErr anErr = noErr; |
AppleEvent theReply = {typeNull, nil}; |
AESendMode sendMode; |
if (nil == pIdleProcUPP) |
sendMode = kAENoReply; |
else |
sendMode = kAEWaitReply; |
anErr = AESend( pAppleEvent, &theReply, sendMode, kAENormalPriority, kNoTimeOut, pIdleProcUPP, nil ); |
if ((noErr == anErr) && (kAEWaitReply == sendMode)) |
anErr = MoreAEGetHandlerError(&theReply); |
(void) AEDisposeDesc( &theReply ); |
return anErr; |
}//end MoreAESendEventNoReturnValue |
/******************************************************************************** |
Send the provided AppleEvent using the provided idle function. |
Return data (at pDataPtr) of type pDesiredType |
pIdleProcUPP input: The idle function to use when sending the event. |
pAppleEvent input: The event to be sent. |
theValue output: The value returned by the event. |
RESULT CODES |
____________ |
noErr 0 No error |
paramErr -50 No idle function provided |
and any other error that can be returned by AESend or the handler |
in the application that gets the event. |
____________ |
*/ |
pascal OSErr MoreAESendEventReturnData( |
const AEIdleUPP pIdleProcUPP, |
const AppleEvent *pAppleEvent, |
DescType pDesiredType, |
DescType* pActualType, |
void* pDataPtr, |
Size pMaximumSize, |
Size *pActualSize) |
{ |
OSErr anErr = noErr; |
// No idle function is an error, since we are expected to return a value |
if (pIdleProcUPP == nil) |
anErr = paramErr; |
else |
{ |
AppleEvent theReply = {typeNull, nil}; |
AESendMode sendMode = kAEWaitReply; |
anErr = AESend(pAppleEvent, &theReply, sendMode, kAENormalPriority, kNoTimeOut, pIdleProcUPP, nil); |
// [ Don't dispose of the event, it's not ours ] |
if (anErr == noErr) |
{ |
anErr = MoreAEGetHandlerError(&theReply); |
if (!anErr && theReply.descriptorType != typeNull) |
{ |
anErr = AEGetParamPtr(&theReply, keyDirectObject, pDesiredType, |
pActualType, pDataPtr, pMaximumSize, pActualSize); |
} |
AEDisposeDesc(&theReply); |
} |
} |
return anErr; |
} // MoreAESendEventReturnData |
/******************************************************************************** |
Send the provided AppleEvent using the provided idle function. |
Return a SInt16 (typeSmallInteger). |
pIdleProcUPP input: The idle function to use when sending the event. |
pAppleEvent input: The event to be sent. |
theValue output: The value returned by the event. |
RESULT CODES |
____________ |
noErr 0 No error |
paramErr -50 No idle function provided |
and any other error that can be returned by AESend or the handler |
in the application that gets the event. |
____________ |
*/ |
pascal OSErr MoreAESendEventReturnSInt16( |
const AEIdleUPP pIdleProcUPP, |
const AppleEvent* pAppleEvent, |
SInt16* pValue) |
{ |
DescType actualType; |
Size actualSize; |
return MoreAESendEventReturnData(pIdleProcUPP,pAppleEvent,typeShortInteger, |
&actualType,pValue,sizeof(SInt16),&actualSize); |
} // MoreAESendEventReturnSInt16 |
/******************************************************************************** |
Send the provided AppleEvent using the provided idle function. |
Returns a PString. |
pIdleProcUPP input: The idle function to use when sending the event. |
pAppleEvent input: The event to be sent. |
pStr255 output: The value returned by the event. |
RESULT CODES |
____________ |
noErr 0 No error |
paramErr -50 No idle function provided |
and any other error that can be returned by AESend or the handler |
in the application that gets the event. |
____________ |
*/ |
pascal OSErr MoreAESendEventReturnPString( |
const AEIdleUPP pIdleProcUPP, |
const AppleEvent* pAppleEvent, |
Str255 pStr255) |
{ |
DescType actualType; |
Size actualSize; |
return MoreAESendEventReturnData(pIdleProcUPP,pAppleEvent,typePString, |
&actualType,pStr255,sizeof(Str255),&actualSize); |
} // MoreAESendEventReturnSInt16 |
#pragma mark ==> Functions for talking to ourselfs |
/******************************************************************************** |
Send an AppleEvent of the specified Class & ID to myself using the |
default idle function. |
pEventID input: The event to be sent. |
RESULT CODES |
____________ |
noErr 0 No error |
and any other error that can be returned by AESend or the handler |
in the application that gets the event. |
____________ |
*/ |
pascal OSErr MoreAESendToSelfNoReturnValue( |
const AEEventClass pEventClass, |
const AEEventID pEventID) |
{ |
AppleEvent theEvent = {typeNull, nil}; // If you always init AEDescs, it's always save to dispose of them. |
OSErr anErr = noErr; |
if (nil == gAEIdleUPP) |
gAEIdleUPP = NewAEIdleUPP(MoreAESimpleIdleFunction); |
anErr = MoreAECreateAppleEventSelfTarget(pEventClass,pEventID,&theEvent); |
if (anErr == noErr) |
{ |
AEDesc containerObj = {typeNull, nil}; // start with the null (application) container |
AEDesc propertyObject = {typeNull, nil}; |
anErr = MoreAEOCreatePropertyObject(pSelection, &containerObj, &propertyObject); |
if (anErr == noErr) |
{ |
anErr = AEPutParamDesc(&theEvent, keyDirectObject, &propertyObject); |
if (anErr == noErr) |
anErr = MoreAESendEventNoReturnValue(gAEIdleUPP, &theEvent); |
AEDisposeDesc(&propertyObject); // Always dispose of objects as soon as you are done (helps avoid leaks) |
} |
AEDisposeDesc(&theEvent); // always dispose of AEDescs when you are finished with them |
} |
return anErr; |
} |
/******************************************************************************** |
Send an AppleEvent of the specified Class & ID to myself using the |
default idle function. Wait for a reply and extract a SInt16 result. |
pEventID input: The event class to be sent. |
pEventID input: The event ID to be sent. |
pValue Output: Where the return SInt16 will be stored. |
RESULT CODES |
____________ |
noErr 0 No error |
and any other error that can be returned by AESend or the handler |
in the application that gets the event. |
____________ |
*/ |
pascal OSErr MoreAESendToSelfReturnSInt16( |
const AEEventClass pEventClass, |
const AEEventID pEventID, |
SInt16* pValue) |
{ |
AppleEvent theEvent = {typeNull, nil}; // If you always init AEDescs, it's always save to dispose of them. |
OSErr anErr = noErr; |
if (nil == gAEIdleUPP) |
gAEIdleUPP = NewAEIdleUPP(MoreAESimpleIdleFunction); |
anErr = MoreAECreateAppleEventSelfTarget(pEventClass,pEventID,&theEvent); |
if (anErr == noErr) |
{ |
AEDesc containerObj = {typeNull, nil}; // start with the null (application) container |
AEDesc propertyObject = {typeNull, nil}; |
anErr = MoreAEOCreatePropertyObject(pSelection, &containerObj, &propertyObject); |
if (anErr == noErr) |
{ |
anErr = AEPutParamDesc(&theEvent, keyDirectObject, &propertyObject); |
if (anErr == noErr) |
anErr = MoreAESendEventReturnSInt16(gAEIdleUPP, &theEvent, pValue); |
AEDisposeDesc(&propertyObject); // Always dispose of objects as soon as you are done (helps avoid leaks) |
} |
AEDisposeDesc(&theEvent); // always dispose of AEDescs when you are finished with them |
} |
return anErr; |
} |
/******************************************************************************** |
Send a get data (kAEGetData) AppleEvent to myself using the |
default idle function. Wait for a reply and extract a SInt16 result. |
pIdleProcUPP input: The idle function to use when sending the event. |
pEventID input: The event to be sent. |
pValue Output: Where the resulting SInt16 will be stored. |
RESULT CODES |
____________ |
noErr 0 No error |
and any other error that can be returned by AESend or the handler |
in the application that gets the event. |
____________ |
*/ |
pascal OSErr MoreAETellSelfToGetSInt16Property( |
const DescType pPropType, |
SInt16* pValue) |
{ |
AppleEvent theEvent = {typeNull, nil}; // If you always init AEDescs, it's always save to dispose of them. |
OSErr anErr = noErr; |
if (nil == gAEIdleUPP) |
gAEIdleUPP = NewAEIdleUPP(MoreAESimpleIdleFunction); |
anErr = MoreAECreateAppleEventSelfTarget(kAECoreSuite,kAEGetData,&theEvent); |
if (anErr == noErr) |
{ |
AEDesc containerObj = {typeNull, nil}; // start with the null (application) container |
AEDesc propertyObject = {typeNull, nil}; |
anErr = MoreAEOCreatePropertyObject(pPropType, &containerObj, &propertyObject); |
if (anErr == noErr) |
{ |
anErr = AEPutParamDesc(&theEvent, keyDirectObject, &propertyObject); |
if (anErr == noErr) |
anErr = MoreAESendEventReturnSInt16(gAEIdleUPP, &theEvent, pValue); |
AEDisposeDesc(&propertyObject); // Always dispose of objects as soon as you are done (helps avoid leaks) |
} |
AEDisposeDesc(&theEvent); // always dispose of AEDescs when you are finished with them |
} |
return anErr; |
} |
/******************************************************************************** |
Send a get data (kAEGetData) AppleEvent to myself using the |
default idle function. Wait for a reply and extract a Str255 result. |
pIdleProcUPP input: The idle function to use when sending the event. |
pEventID input: The event to be sent. |
pValue Output: Where the resulting Str255 will be stored. |
RESULT CODES |
____________ |
noErr 0 No error |
and any other error that can be returned by AESend or the handler |
in the application that gets the event. |
____________ |
*/ |
pascal OSErr MoreAETellSelfToGetStr255Property( |
const DescType pPropType, |
Str255 pValue) |
{ |
AppleEvent theEvent = {typeNull, nil}; // If you always init AEDescs, it's always save to dispose of them. |
OSErr anErr = noErr; |
if (nil == gAEIdleUPP) |
gAEIdleUPP = NewAEIdleUPP(MoreAESimpleIdleFunction); |
anErr = MoreAECreateAppleEventSelfTarget(kAECoreSuite,kAEGetData,&theEvent); |
if (anErr == noErr) |
{ |
AEDesc containerObj = {typeNull, nil}; // start with the null (application) container |
AEDesc propertyObject = {typeNull, nil}; |
anErr = MoreAEOCreatePropertyObject(pPropType, &containerObj, &propertyObject); |
if (anErr == noErr) |
{ |
anErr = AEPutParamDesc(&theEvent, keyDirectObject, &propertyObject); |
if (anErr == noErr) |
anErr = MoreAESendEventReturnPString(gAEIdleUPP, &theEvent, pValue); |
AEDisposeDesc(&propertyObject); // Always dispose of objects as soon as you are done (helps avoid leaks) |
} |
AEDisposeDesc(&theEvent); // always dispose of AEDescs when you are finished with them |
} |
return anErr; |
} |
/******************************************************************************** |
Send a set data (kAESetData) AppleEvent to myself with a SInt16 parameter |
and using the default idle function. |
pIdleProcUPP input: The idle function to use when sending the event. |
pEventID input: The event to be sent. |
pValue Output: Where the resulting SInt16 will be stored. |
RESULT CODES |
____________ |
noErr 0 No error |
and any other error that can be returned by AESend or the handler |
in the application that gets the event. |
____________ |
*/ |
pascal OSErr MoreAETellSelfToSetSInt16Property( |
const DescType pPropType, |
SInt16 pValue) |
{ |
AppleEvent theEvent = {typeNull, nil}; // If you always init AEDescs, it's always save to dispose of them. |
OSErr anErr = noErr; |
if (nil == gAEIdleUPP) |
gAEIdleUPP = NewAEIdleUPP(MoreAESimpleIdleFunction); |
anErr = MoreAECreateAppleEventSelfTarget(kAECoreSuite,kAESetData,&theEvent); |
if (anErr == noErr) |
{ |
AEDesc containerObj = {typeNull, nil}; // start with the null (application) container |
AEDesc propertyObject = {typeNull, nil}; |
anErr = MoreAEOCreatePropertyObject(pPropType, &containerObj, &propertyObject); |
if (anErr == noErr) |
{ |
anErr = AEPutParamDesc(&theEvent, keyDirectObject, &propertyObject); |
AEDisposeDesc(&propertyObject); |
if (anErr == noErr) |
{ |
anErr = AEPutParamPtr(&theEvent, keyAEData, typeSInt16, &pValue, sizeof(SInt16)); |
if (anErr == noErr) |
anErr = MoreAESendEventNoReturnValue(gAEIdleUPP, &theEvent); |
} |
} |
AEDisposeDesc(&theEvent); // always dispose of AEDescs when you are finished with them |
} |
return anErr; |
} |
/******************************************************************************** |
Send a set data (kAESetData) AppleEvent to myself with a SInt16 parameter |
and using the default idle function. |
pIdleProcUPP input: The idle function to use when sending the event. |
pEventID input: The event to be sent. |
pValue Output: Where the resulting Str255 will be stored. |
RESULT CODES |
____________ |
noErr 0 No error |
and any other error that can be returned by AESend or the handler |
in the application that gets the event. |
____________ |
*/ |
pascal OSErr MoreAETellSelfToSetStr255Property( |
const DescType pPropType, |
Str255 pValue) |
{ |
AppleEvent theEvent = {typeNull, nil}; // If you always init AEDescs, it's always save to dispose of them. |
OSErr anErr = noErr; |
if (nil == gAEIdleUPP) |
gAEIdleUPP = NewAEIdleUPP(MoreAESimpleIdleFunction); |
anErr = MoreAECreateAppleEventSelfTarget(kAECoreSuite,kAESetData,&theEvent); |
if (anErr == noErr) |
{ |
AEDesc containerObj = {typeNull, nil}; // start with the null (application) container |
AEDesc propertyObject = {typeNull, nil}; |
anErr = MoreAEOCreatePropertyObject(pPropType, &containerObj, &propertyObject); |
if (anErr == noErr) |
{ |
anErr = AEPutParamDesc(&theEvent, keyDirectObject, &propertyObject); |
AEDisposeDesc(&propertyObject); |
if (anErr == noErr) |
{ |
anErr = AEPutParamPtr(&theEvent, keyAEData, typePString, pValue, pValue[0] + 1); |
if (anErr == noErr) |
anErr = MoreAESendEventNoReturnValue(gAEIdleUPP, &theEvent); |
} |
} |
AEDisposeDesc(&theEvent); // always dispose of AEDescs when you are finished with them |
} |
return anErr; |
} |
//******************************************************************************* |
#pragma mark ==> Misc. AE utility functions ¥ |
//******************************************************************************* |
// Appends each of the items in pSourceList to the pDestList. |
extern pascal OSStatus MoreAEAppendListToList(const AEDescList *pSourceList, AEDescList *pDestList) |
{ |
OSStatus err; |
AEKeyword junkKeyword; |
SInt32 listCount; |
SInt32 listIndex; |
AEDesc thisValue; |
MoreAssertQ(pSourceList != nil); |
MoreAssertQ(pDestList != nil); |
err = AECountItems(pSourceList, &listCount); |
if (err == noErr) { |
for (listIndex = 1; listIndex <= listCount; listIndex++) { |
MoreAENullDesc(&thisValue); |
err = AEGetNthDesc(pSourceList, listIndex, typeWildCard, &junkKeyword, &thisValue); |
if (err == noErr) { |
err = AEPutDesc(pDestList, 0, &thisValue); |
} |
MoreAEDisposeDesc(&thisValue); |
if (err != noErr) { |
break; |
} |
} |
} |
return err; |
} |
//******************************************************************************* |
// This routine takes a result descriptor and an error. |
// If there is a result to add to the reply it makes sure the reply isn't |
// NULL itself then adds the error to the reply depending on the error |
// and the type of result. |
pascal OSErr MoreAEMoreAESetReplyErrorNumber (OSErr pOSErr, AppleEvent *pAEReply) |
{ |
OSErr err = noErr; |
if (pAEReply->dataHandle) |
{ |
if (!MoreAssert (pAEReply->descriptorType == typeAppleEvent)) |
err = paramErr; |
else |
err = AEPutParamPtr (pAEReply,keyErrorNumber,typeShortInteger,&pOSErr,sizeof(pOSErr)); |
} |
return err; |
} |
//******************************************************************************* |
// This routine takes a result descriptor, a reply descriptor and an error. |
// If there is a result to add to the reply it makes sure the reply isn't |
// NULL itself then adds the result to the reply depending on the error |
// and the type of result. |
pascal OSErr MoreAEAddResultToReply(AEDesc* pResult, AEDesc* pAEReply, OSErr error) |
{ |
OSErr anErr; |
// Check that the pAEReply is not NULL and there is a result to put in it |
if (typeNull == pAEReply->descriptorType || typeNull == pResult->descriptorType) |
return (error); |
if (noErr == error) |
anErr = AEPutParamDesc(pAEReply, keyDirectObject, pResult); |
else |
{ |
switch (pResult->descriptorType) |
{ |
case typeInteger: |
anErr = AEPutParamDesc(pAEReply, keyErrorNumber, pResult); |
break; |
case typeChar: |
anErr = AEPutParamDesc(pAEReply, keyErrorString, pResult); |
break; |
default: |
anErr = errAETypeError; |
} |
if (noErr == anErr) |
anErr = error; // Don't loose that error |
} |
return (anErr); |
} |
// ---------------------------------------------------------------------- |
// Name: MoreAEGotRequiredParams |
// Function: Checks that all parameters defined as 'required' have been read |
// ---------------------------------------------------------------------- |
pascal OSErr MoreAEGotRequiredParams(const AppleEvent *theAppleEvent) |
{ |
DescType returnedType; |
Size actualSize; |
OSErr anErr; |
// look for the keyMissedKeywordAttr, just to see if it's there |
anErr = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard, |
&returnedType, NULL, 0, &actualSize); |
switch (anErr) |
{ |
case errAEDescNotFound: // attribute not there means we |
anErr = noErr; // got all required parameters. |
break; |
case noErr: // attribute there means missed |
anErr = errAEParamMissed; // at least one parameter. |
break; |
// default: pass on unexpected error in looking for the attribute |
} |
return (anErr); |
} // GotReqiredParams |
/******************************************************************************** |
Takes a reply event checks it for any errors that may have been returned |
by the event handler. A simple function, in that it only returns the error |
number. You can often also extract an error string and three other error |
parameters from a reply event. |
Also see: |
IM:IAC for details about returned error strings. |
AppleScript developer release notes for info on the other error parameters. |
pAEReply input: The reply event to be checked. |
RESULT CODES |
____________ |
noErr 0 No error |
???? ?? Pretty much any error, depending on what the |
event handler returns for it's errors. |
*/ |
pascal OSErr MoreAEGetHandlerError( const AppleEvent *pAEReply ) |
{ |
OSErr anErr = noErr; |
OSErr handlerErr; |
DescType actualType; |
long actualSize; |
if ( pAEReply->descriptorType != typeNull ) // there's a reply, so there may be an error |
{ |
OSErr getErrErr = noErr; |
getErrErr = AEGetParamPtr( pAEReply, keyErrorNumber, typeShortInteger, &actualType, |
&handlerErr, sizeof( OSErr ), &actualSize ); |
if ( getErrErr != errAEDescNotFound ) // found an errorNumber parameter |
{ |
anErr = handlerErr; // so return it's value |
} |
} |
return anErr; |
}//end MoreAEGetHandlerError |
/******************************************************************************** |
Get the class and ID from an AppleEvent. |
pAppleEvent input: The event to get the class and ID from. |
pAEEventClass output: The event's class. |
pAEEventID output: The event's ID. |
RESULT CODES |
____________ |
noErr 0 No error |
memFullErr -108 Not enough room in heap zone |
errAEDescNotFound -1701 Descriptor record was not found |
errAENotAEDesc -1704 Not a valid descriptor record |
errAEReplyNotArrived -1718 Reply has not yet arrived |
*/ |
pascal OSErr MoreAEExtractClassAndID ( const AppleEvent *pAppleEvent, AEEventClass *pAEEventClass, AEEventID *pAEEventID ) |
{ |
DescType actualType; |
Size actualSize; |
OSErr anErr; |
anErr = AEGetAttributePtr( pAppleEvent, keyEventClassAttr, typeType, &actualType, |
pAEEventClass, sizeof( pAEEventClass ), &actualSize ); |
if ( anErr == noErr ) |
{ |
anErr = AEGetAttributePtr( pAppleEvent, keyEventIDAttr, typeType, &actualType, |
pAEEventID, sizeof( pAEEventID ), &actualSize ); |
} |
return ( anErr ); |
}//end ExtractClassAndID |
/******************************************************************************** |
A very simple idle function. It simply ignors any event it receives, |
returns 30 for the sleep time and nil for the mouse region. |
Your application should supply an idle function that handles any events it |
might receive. This is especially important if your application has any windows. |
Also see: |
IM:IAC for details about idle functions. |
Pending Update Perils technote for more about handling low-level events. |
*/ |
pascal Boolean MoreAESimpleIdleFunction( EventRecord *event, |
long *sleepTime, |
RgnHandle *mouseRgn ) |
{ |
#pragma unused( event ) |
*sleepTime = 30; |
*mouseRgn = nil; |
return ( false ); |
}//end MoreAESimpleIdleFunction |
/******************************************************************************** |
Is the Apple Event Manager present. |
RESULT CODES |
____________ |
true The Apple Event Manager is present |
false It isn't |
*/ |
pascal Boolean MoreAEHasAppleEvents(void) |
{ |
OSErr anErr = noErr; |
static long gHasAppleEvents = kFlagNotSet; |
if ( gHasAppleEvents == kFlagNotSet ) |
{ |
long response; |
if ( Gestalt( gestaltAppleEventsAttr, &response ) == noErr ) |
gHasAppleEvents = ( response & (1L << gestaltAppleEventsPresent) ) != 0; |
} |
return gHasAppleEvents; |
}//end MoreAEHasAppleEvents |
//******************************************************************************* |
// Did this AppleEvent come from the Finder? |
pascal OSErr MoreAEIsSenderFinder (const AppleEvent *pAppleEvent, Boolean *pIsFinder) |
{ |
OSErr err = noErr; |
DescType actualType; |
ProcessSerialNumber senderPSN; |
Size actualSize; |
if (!MoreAssert (pAppleEvent && pIsFinder)) return paramErr; |
if (!MoreAssert (pAppleEvent->descriptorType == typeAppleEvent)) return paramErr; |
if (!MoreAssert (pAppleEvent->dataHandle)) return paramErr; |
err = AEGetAttributePtr (pAppleEvent, keyAddressAttr, typeProcessSerialNumber, &actualType, |
(Ptr) &senderPSN, sizeof (senderPSN), &actualSize); |
if (MoreAssert (err == noErr)) |
{ |
if (!MoreAssert (actualType == typeProcessSerialNumber)) |
err = paramErr; |
else if (!MoreAssert (actualSize == sizeof (senderPSN))) |
err = paramErr; |
else |
{ |
ProcessInfoRec processInfo; |
if (!(err = MoreProcGetProcessInformation (&senderPSN,&processInfo))) |
{ |
*pIsFinder = ( processInfo.processSignature == kFinderProcessSignature && |
processInfo.processType == kFinderProcessType); |
} |
} |
} |
return err; |
} |
#pragma mark ==> AEDesc Constructor & Destructor ¥ |
//******************************************************************************* |
// Initialises desc to the null descriptor (typeNull, nil). |
pascal void MoreAENullDesc(AEDesc *desc) |
{ |
MoreAssertQ(desc != nil); |
desc->descriptorType = typeNull; |
desc->dataHandle = nil; |
} |
//******************************************************************************* |
// Disposes of desc and initialises it to the null descriptor. |
pascal void MoreAEDisposeDesc(AEDesc *desc) |
{ |
OSStatus junk; |
MoreAssertQ(desc != nil); |
junk = AEDisposeDesc(desc); |
MoreAssertQ(junk == noErr); |
desc->descriptorType = typeNull; |
desc->dataHandle = nil; |
} |
//******************************************************************************* |
#pragma mark ==> AEDesc Data Accessors for 68K ¥ |
//******************************************************************************* |
// These routines are only implemented in PreCarbon.o for PowerPC |
// So for 68K we had to write our own versions |
#if TARGET_CPU_68K || !ACCESSOR_CALLS_ARE_FUNCTIONS |
pascal Size AEGetDescDataSize( const AEDesc* pAEDesc) |
{ |
return GetHandleSize(pAEDesc->dataHandle); |
} |
pascal OSErr AEGetDescData( const AEDesc* pAEDesc, |
void* pDataPtr, |
Size pMaxSize) |
{ |
Size copySize = AEGetDescDataSize(pAEDesc); |
if ((nil == pAEDesc) || (nil == pDataPtr)) |
return paramErr; |
if (pMaxSize < copySize) |
copySize = pMaxSize; |
BlockMoveData(*pAEDesc->dataHandle,pDataPtr,copySize); |
return noErr; |
} |
#endif TARGET_CPU_68K || !ACCESSOR_CALLS_ARE_FUNCTIONS |
//******************************************************************************* |
#pragma mark ==> Get Data From Descriptors ¥ |
/******************************************************************************** |
This is the generic routine that all the other's use instead of |
duplicating all this code unnecessarily. |
pAEDesc input: The descriptor we want the data from |
pDestPtr output: Where we want to store the data from this desc. |
pMaxSize input: The maxium amount of data we can store. |
pActualSize output: The actual amount of data stored. |
RESULT CODES |
____________ |
noErr 0 No error |
____________ |
*/ |
pascal void MoreAEGetRawDataFromDescriptor(const AEDesc* pAEDesc, |
Ptr pDestPtr, |
Size pMaxSize, |
Size *pActualSize) |
{ |
Size copySize; |
if (pAEDesc->dataHandle) |
{ |
*pActualSize = AEGetDescDataSize(pAEDesc); |
if (*pActualSize < pMaxSize) |
copySize = *pActualSize; |
else |
copySize = pMaxSize; |
AEGetDescData(pAEDesc,pDestPtr,copySize); |
} |
else |
*pActualSize = 0; |
} |
/******************************************************************************** |
Extract a pascal string a descriptor. |
pAEDesc input: The descriptor we want the data from |
pStringPtr output: Where we want to store the pascal string |
RESULT CODES |
____________ |
noErr 0 No error |
____________ |
*/ |
pascal OSErr MoreAEGetPStringFromDescriptor(const AEDesc* pAEDesc, StringPtr pStringPtr) |
{ |
Size stringSize; |
AEDesc resultDesc = {typeNull, NULL}; |
OSErr anErr; |
anErr = AECoerceDesc(pAEDesc, typeChar, &resultDesc); |
if (noErr != anErr) goto done; |
pStringPtr[0] = 0; |
MoreAEGetRawDataFromDescriptor(&resultDesc, (Ptr) &pStringPtr[1], 255, &stringSize); |
if (stringSize <= 255) |
pStringPtr[0] = stringSize; |
else |
anErr = errAECoercionFail; |
done: |
if (resultDesc.dataHandle) |
AEDisposeDesc(&resultDesc); |
return(anErr); |
} |
/******************************************************************************** |
Extract a C string from the descriptor. |
pAEDesc input: The descriptor we want the data from |
pStringPtr output: Where we want to store the C string |
RESULT CODES |
____________ |
noErr 0 No error |
____________ |
*/ |
pascal OSErr MoreAEGetCStringFromDescriptor(const AEDesc* pAEDesc, char* pCharPtr) |
{ |
Size stringSize; |
AEDesc resultDesc = {typeNull, NULL}; |
OSErr anErr; |
anErr = AECoerceDesc(pAEDesc, typeChar, &resultDesc); |
if (noErr == anErr) |
{ |
MoreAEGetRawDataFromDescriptor(&resultDesc, pCharPtr, 256, &stringSize); |
pCharPtr[stringSize] = 0; |
} |
if (resultDesc.dataHandle) |
AEDisposeDesc(&resultDesc); |
return (anErr); |
} |
/******************************************************************************** |
Extract a short from a descriptor. |
pAEDesc input: The descriptor we want the data from |
pStringPtr output: Where we want to store the short. |
RESULT CODES |
____________ |
noErr 0 No error |
____________ |
*/ |
pascal OSErr MoreAEGetShortFromDescriptor(const AEDesc* pAEDesc, SInt16 *pResult) |
{ |
OSErr myErr; |
OSErr ignoreErr; |
Size intSize; |
AEDesc resultDesc; |
*pResult = 0; |
myErr = AECoerceDesc(pAEDesc,typeShortInteger,&resultDesc); |
if (myErr==noErr) |
{ |
MoreAEGetRawDataFromDescriptor(&resultDesc,(Ptr) pResult,2,&intSize); |
if (intSize>2) |
myErr = errAECoercionFail; |
} |
if (resultDesc.dataHandle) |
ignoreErr = AEDisposeDesc(&resultDesc); |
return(myErr); |
} |
/******************************************************************************** |
Extract a Boolean from a descriptor. |
pAEDesc input: The descriptor we want the data from |
pStringPtr output: Where we want to store the boolean. |
RESULT CODES |
____________ |
noErr 0 No error |
____________ |
*/ |
pascal OSErr MoreAEGetBooleanFromDescriptor(const AEDesc* pAEDesc,Boolean *pResult) |
{ |
OSErr myErr; |
OSErr ignoreErr; |
Size boolSize; |
AEDesc resultDesc; |
*pResult = false; |
myErr = AECoerceDesc(pAEDesc,typeBoolean,&resultDesc); |
if (myErr==noErr) |
{ |
MoreAEGetRawDataFromDescriptor(&resultDesc,(Ptr)pResult, |
sizeof(Boolean),&boolSize); |
if (boolSize > sizeof(Boolean)) |
myErr = errAECoercionFail; |
} |
if (resultDesc.dataHandle) |
ignoreErr = AEDisposeDesc(&resultDesc); |
return(myErr); |
} |
/******************************************************************************** |
Extract a long from a descriptor. |
pAEDesc input: The descriptor we want the data from |
pStringPtr output: Where we want to store the long. |
RESULT CODES |
____________ |
noErr 0 No error |
____________ |
*/ |
pascal OSErr MoreAEGetLongFromDescriptor(const AEDesc* pAEDesc, long *pResult) |
{ |
OSErr myErr; |
OSErr ignoreErr; |
Size intSize; |
AEDesc resultDesc; |
*pResult = 0; |
myErr = AECoerceDesc(pAEDesc,typeLongInteger,&resultDesc); |
if (myErr==noErr) |
{ |
MoreAEGetRawDataFromDescriptor(&resultDesc,(Ptr)pResult,4,&intSize); |
if (intSize>4) |
myErr = errAECoercionFail; |
} |
if (resultDesc.dataHandle) |
ignoreErr = AEDisposeDesc(&resultDesc); |
return(myErr); |
} /*MoreAEGetLongIntFromDescriptor*/ |
/******************************************************************************** |
Extract a OSType from a descriptor. |
pAEDesc input: The descriptor we want the data from |
pResult output: Where we want to store the OSType. |
RESULT CODES |
____________ |
noErr 0 No error |
____________ |
*/ |
pascal OSErr MoreAEGetOSTypeFromDescriptor(const AEDesc* pAEDesc, OSType *pResult) |
{ |
return (MoreAEGetLongFromDescriptor(pAEDesc,(long *)pResult)); |
} /*MoreAEGetOSTypeFromDescriptor*/ |
extern pascal OSStatus MoreAECopyDescriptorDataToHandle(const AEDesc *desc, Handle *descData) |
// see comment in header. |
{ |
OSStatus err; |
OSStatus junk; |
MoreAssertQ(desc != nil); |
MoreAssertQ(descData != nil); |
MoreAssertQ(*descData == nil); |
*descData = NewHandle(AEGetDescDataSize(desc)); |
err = MoreMemError(*descData); |
if (err == noErr) { |
HLock(*descData); |
junk = AEGetDescData(desc, **descData, AEGetDescDataSize(desc)); |
MoreAssertQ(junk == noErr); |
HUnlock(*descData); |
} |
return err; |
} |
extern pascal Boolean MoreAEIsMissingValue(const AEDesc *desc) |
// See comment in header. |
{ |
DescType missing; |
return (desc->descriptorType == typeType) |
&& (AEGetDescDataSize(desc) == sizeof(missing)) |
&& (AEGetDescData(desc, &missing, sizeof(missing)) == noErr) |
&& (missing == cMissingValue); |
} |
extern pascal OSStatus MoreAECreateMissingValue(AEDesc *desc) |
// See comment in header. |
{ |
const static DescType missingValue = cMissingValue; |
return AECreateDesc(typeType, &missingValue, sizeof(missingValue), desc); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14