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.
AEUtilities.c
/*------------------------------------------------------------------------------ |
* |
* Apple Developer Technical Support |
* |
* AppleEvent utility routines |
* |
* Program:AEObject-Edition Sample |
* File: AEUtilityRoutines.c - C Source |
* |
* by: C.K. Haun <TR> |
* |
* Copyright © 1991-1992 Apple Computer, Inc. |
* All rights reserved. |
* |
*------------------------------------------------------------------------------ |
* This file contains some generic and specific utility routines I wrote |
* to help with the AppleEvent manager. The prime motivation for this file |
* is to NOT have to type in all the fields needed for many of the |
* AEM parameter accessing routines, since I do them so often. |
* There aren't all that many calls here yet, this will grow as the AEM world grows |
*----------------------------------------------------------------------------*/ |
#define __AEMU__ |
#include "Sampdefines.h" |
#pragma segment AEUtils |
/* A little routine that returns a short from a descriptor */ |
OSErr ShortFromDesc(short *theData, const AppleEvent *theDesc) |
{ |
OSErr myErr = noErr; |
AEDesc tempDesc; |
long temp; |
if (theDesc->descriptorType == typeShortInteger) { |
temp = *((short *)*(theDesc->dataHandle)); |
*theData = temp; |
} else { |
/* if it wasn't a short to begin with, try and coerce it into a short */ |
myErr = AECoerceDesc(theDesc, typeShortInteger, &tempDesc); |
if (!myErr) { |
/* it coerced. grab it */ |
temp = *((short *)*(tempDesc.dataHandle)); |
*theData = temp; |
AEDisposeDesc(&tempDesc); |
} |
} |
return(myErr); |
} |
/* this has been replaced by my coercion handler, see AppleEventCore.c */ |
void PStringFromTextDesc(Str255 theString, const AEDesc *theDesc) |
{ |
theString[0] = GetHandleSize(theDesc->dataHandle); |
BlockMove((Ptr)*theDesc->dataHandle, (Ptr)&theString[1], theString[0]); |
} |
/* Puts up the PPCBrowser, and creates a target address */ |
/* based on the user selection */ |
OSErr BrowseForTarget(AEDesc *theAddress) |
{ |
Str32 prompt1; |
Str32 prompt2; |
LocationNameRec theLoc; |
PortInfoRec theRec; |
OSErr myErr = noErr; |
TargetID theID; |
GetIndString(prompt1,kGeneralStrings,kPPCPrompt1); |
GetIndString(prompt2,kGeneralStrings,kPPCPrompt2); |
myErr = PPCBrowser(prompt1, prompt2, false, &theLoc, &theRec, nil, nil); |
if (!myErr) { |
/* make a target descriptor */ |
BlockMove(theRec.name.name, targetName, theRec.name.name[0] + 1); |
ParamText(&targetName, "", "", ""); |
theID.name = theRec.name; |
theID.location = theLoc; |
myErr = AECreateDesc(typeTargetID, (Ptr)&theID, sizeof(theID), theAddress); |
} |
mAEErrorDisplay("\pBrowser Error", myErr) |
return(myErr); |
} |
/* Makes an AppleEvent address descriptor based on the settings in the Dialog Box */ |
/* in AppleEventCore.c */ |
OSErr MakeAddress(AEDesc *theAddress) |
{ |
OSErr myErr = noErr; |
ProcessSerialNumber myNumber; |
switch (gAddressMode) { |
/* Remember, if you use this case (using the PSN of kCurrentProcess) the */ |
/* AppleEvent Manager will bypass the event loop and directly call (like a normal */ |
/* subroutine call) your handler, the event will _not_ come through */ |
/* WaitNextEvent */ |
case kSelfCur: |
myNumber.highLongOfPSN = 0; |
myNumber.lowLongOfPSN = kCurrentProcess; |
myErr = AECreateDesc(typeProcessSerialNumber, (Ptr)&myNumber, sizeof(ProcessSerialNumber), theAddress); |
break; |
/* If you use your real PSN, then the event will come through WNE */ |
case kSelfPSN: |
myErr = AECreateDesc(typeProcessSerialNumber, (Ptr)&gOurSN, sizeof(ProcessSerialNumber), theAddress); |
break; |
case kOtherApp: |
if (gTargetAddress.dataHandle == nil) { |
myErr = BrowseForTarget(theAddress); |
} else { |
/* If I already have one, duplicate it and pass it back */ |
myErr = AEDuplicateDesc(&gTargetAddress, theAddress); |
} |
break; |
} |
mAEErrorDisplay("\pMakeAddress ", myErr) |
return(myErr); |
} |
/* generic sender, so I don't have to duplicate the various conditional code */ |
/* (for replies, interactions, or whatever) all over */ |
OSErr DoSend(AppleEvent *theEvent, AEDesc *reply) |
{ |
AEDesc *replyPointer = nil; |
short response = 2; |
OSErr myErr; |
long timeOut = kAEDefaultTimeout; |
if (gReplyMode) |
replyPointer = reply; |
if (gReplyMode == 1 && gAddressMode == 1) { |
ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter); |
timeOut = 0; |
response = CautionAlert(kBadMix, upp); |
DisposeRoutineDescriptor(upp); |
} |
if (response == 2) { |
myErr = AESend(theEvent, replyPointer, |
(gSendInteractArray[gAESendInteraction] + gAESwitchLayer) + gReplyLevels[gReplyMode], kAENormalPriority, |
timeOut, gCommonIdleFunctionUPP, nil); |
mAEErrorDisplay("\pAESend in DoSend ", myErr) |
} else { |
myErr = userCanceledErr; |
} |
return(myErr); |
} |
/* lil routine that will print out actual error text for AEM errors, since I */ |
/* got real tired of trying to remeber what -1723 was. */ |
/* revised to reflect the new error codes, and to use my ERST <ckh 1.0.2>*/ |
/* resource <ckh 1.0.2>*/ |
void AEErrorText(OSErr theError) |
{ |
Str63 theWords; |
Ptr theErrors; |
OSErr tempError; |
register qq; |
short errCount; |
Byte stringLen; |
/* get my errors <ckh 1.0.2>*/ |
Handle scratch = GetResource(kErrorStringResourceType,kTheErrorStrings); |
theWords[0] = 0; |
if(scratch){ |
/* if I got it, lock it and deref <ckh 1.0.2>*/ |
HLock(scratch); |
theErrors = *scratch; |
errCount = *((short *)theErrors); |
/* position to the first error code <ckh 1.0.2>*/ |
theErrors = theErrors+sizeof(short); |
errCount--; |
for(qq = 0;qq<errCount;qq++){ |
tempError = *((short *)theErrors); |
theErrors = theErrors + sizeof (OSErr); |
/* get the string count, we'll need this whatever we do <ckh 1.0.2>*/ |
stringLen = *theErrors; |
stringLen ++; |
if(tempError == theError){ |
/* it's this one, theErrors points to the string <ckh 1.0.2>*/ |
BlockMove(theErrors,(Ptr)&theWords,stringLen); |
break; |
} else { |
/* next errror please <ckh 1.0.2>*/ |
theErrors = theErrors + stringLen; |
} |
} |
if(theWords[0] == 0){ |
GetIndString(theWords,kGeneralStrings,kUnknownError); |
} |
AddAEText(theWords); |
HUnlock(scratch); |
ReleaseResource(scratch); |
} |
} |
/* this just pumps out the returned data to the AEWindow */ |
/* just a utility for this sample */ |
void DisplayReturnedData(AEDesc *reply) |
{ |
AEDesc theData; |
OSErr myErr; |
long errorCode = 0; |
DescType returnedType; |
Size returnedSize; |
Str255 returnedText; |
/* I can do most of this by asking for typeChar and getting the desc. */ |
/* this is because the AEM can coerce any numeric data to typeChar */ |
/* (as described in the AEM chapter of IM VI) */ |
/* For things that the AEM _doesn't_ know about, I will install */ |
/* coercion handlers! */ |
/* if the coercion completely fails, because I got something I no nothing about, I bail */ |
mVerboseOutput("\p\n Returned Data was : ") |
myErr = AEGetParamDesc(reply, keyDirectObject, typeChar, &theData); |
if (!myErr) { |
long size = GetHandleSize(theData.dataHandle); |
HLock(theData.dataHandle); |
AddToAEWindow((Ptr)*(theData.dataHandle), size); |
} else { |
/* get it as a wildcard, and just show me the descType */ |
myErr = AEGetParamDesc(reply, keyDirectObject, typeWildCard, &theData); |
AddToAEWindow((Ptr)&theData.descriptorType, kFour); |
} |
/* I got a desc, I need to dispose a desc */ |
if (!myErr) |
AEDisposeDesc(&theData); |
else |
AddAEText("\p not available"); |
/* see if there was an 'errs' or 'errn' added */ |
myErr = AEGetParamPtr(reply, keyErrorNumber, typeLongInteger, &returnedType, (Ptr)&errorCode, sizeof(long), &returnedSize); |
if (myErr && myErr != errAEDescNotFound) { |
mVerboseOutput("\p\n Had an error descriptor, but I can't access it") |
} |
if (!myErr) { |
mVerboseOutput("\p\n Error number (errn) returned, was: ") |
AddAENum(errorCode); |
AEErrorText(errorCode); |
} |
/* try for the error string */ |
myErr = AEGetParamPtr(reply, keyErrorString, typeMyPString, &returnedType, (Ptr)&returnedText, 255, &returnedSize); |
if (!myErr) { |
mVerboseOutput("\p\n Error string (errs) returned, was: ") |
AddAEText(&returnedText); |
} |
} |
/* DoObjectDefinition drives the dialog that sets up the default containers */ |
/* for this sample, boring dialog stuff */ |
void DoObjectDefinition(short which) |
{ |
DialogPtr tdial; |
short hitItem = 0; |
Boolean r5, r6; |
Str32 tempNum; |
register qq; |
long realNum; |
DescType shapeTypes[] = { |
cGraphicLine, cRectangle, cOval |
}; |
tdial = SetUpObjectDialog(which); |
ShowWindow(tdial); |
{ |
ModalFilterUPP upp = NewModalFilterProc(standardDialogFilter); |
while (hitItem != ok && hitItem != cancel) { |
ModalDialog(upp, &hitItem); |
switch (which) { |
case kSetWindowObject: |
switch (hitItem) { |
case kWByIndex: |
case kWByName: |
if (hitItem == kWByIndex) { |
r5 = true; |
r6 = false; |
} else { |
r5 = false; |
r6 = true; |
} |
SetControlValue(SnatchHandle(tdial, kWByIndex), r5); |
SetControlValue(SnatchHandle(tdial, kWByName), r6); |
break; |
} |
break; |
case kSetTextObject: |
switch (hitItem) { |
case kWordIndex: /* checkbox only to worry about */ |
SetControlValue(SnatchHandle(tdial, kWordIndex), (GetControlValue(SnatchHandle(tdial, kWordIndex)) ? 0 : 1)); |
} |
break; |
case kSetShapeObject: |
switch (hitItem) { |
case kLineRadio: |
case kRectangleRadio: |
case kOvalRadio: |
/* find out which one is true */ |
for (qq = kLineRadio; qq < kOvalRadio + 1; qq++) { |
if (GetControlValue(SnatchHandle(tdial, qq))) { |
if (!(qq == hitItem)) { |
SetControlValue(SnatchHandle(tdial, qq), false); |
SetControlValue(SnatchHandle(tdial, hitItem), true); |
} |
} |
} |
break; |
} |
break; |
} |
} |
DisposeRoutineDescriptor(upp); |
} |
/* make the changes permenent */ |
if (hitItem == ok) { |
gPreferences.prefsChanged = true; |
switch (which) { |
case kSetWindowObject: |
HLock((Handle)gWindObjSpecHandle); |
if (GetControlValue(SnatchHandle(tdial, kWByIndex))) { |
/* going by absolute position */ |
(*gWindObjSpecHandle)->form = formAbsolutePosition; |
GetDialogItemText((Handle)SnatchHandle(tdial, kWIndexNum), tempNum); |
StringToNum(tempNum, &realNum); |
(*gWindObjSpecHandle)->u.index = realNum; |
} else { |
/* going by name */ |
(*gWindObjSpecHandle)->form = formName; |
/* put the name where it belongs */ |
GetDialogItemText((Handle)SnatchHandle(tdial, kWIndexName), (*gWindObjSpecHandle)->u.name); |
} |
HUnlock((Handle)gWindObjSpecHandle); |
break; |
case kSetTextObject: |
HLock((Handle)gTextObjSpecHandle); |
/* fewer choices here */ |
GetDialogItemText((Handle)SnatchHandle(tdial, kTextONumber), tempNum); |
StringToNum(tempNum, &realNum); |
(*gTextObjSpecHandle)->u.index = realNum; |
(*gTextObjSpecHandle)->andWord = GetControlValue(SnatchHandle(tdial, kWordIndex)); |
/* see if word is being asked for */ |
if ((*gTextObjSpecHandle)->andWord) { |
GetDialogItemText((Handle)SnatchHandle(tdial, kWordIndexString), tempNum); |
StringToNum(tempNum, &realNum); |
(*gTextObjSpecHandle)->wordNumber = realNum; |
} |
HUnlock((Handle)gTextObjSpecHandle); |
break; |
case kSetShapeObject: |
HLock((Handle)gShapeObjSpecHandle); |
for (qq = kLineRadio; qq < kOvalRadio + 1; qq++) { |
if (GetControlValue(SnatchHandle(tdial, qq))) { |
(*gShapeObjSpecHandle)->type = qq - kLineRadio; |
(*gShapeObjSpecHandle)->form = shapeTypes[qq - kLineRadio]; |
break; |
} |
} |
/* and the index number */ |
GetDialogItemText((Handle)SnatchHandle(tdial, kSIEditLine), tempNum); |
StringToNum(tempNum, &realNum); |
(*gShapeObjSpecHandle)->u.index = realNum; |
HUnlock((Handle)gShapeObjSpecHandle); |
break; |
} |
} |
DisposeDialog(tdial); |
} |
/* Anther case of not wanting to type dialog code all over the sample */ |
DialogPtr SetUpObjectDialog(short which) |
{ |
DialogPtr tdial = CommonDStart(which, nil, nil); |
short tempItem; |
Str63 tempString; |
switch (which) { |
case kSetWindowObject: |
HLock((Handle)gWindObjSpecHandle); |
if ((*gWindObjSpecHandle)->form == 0) { |
tempItem = kWPosRadio; /* default for the first time the app is run */ |
} else { |
if ((*gWindObjSpecHandle)->form == formAbsolutePosition) { |
tempItem = kWPosRadio; |
NumToString((*gWindObjSpecHandle)->u.index, tempString); |
SetDialogItemText((Handle)SnatchHandle(tdial, kWPosNum), tempString); |
} else { |
tempItem = kWTitleRadioSet; |
SetDialogItemText((Handle)SnatchHandle(tdial, kWTitleELine), (*gWindObjSpecHandle)->u.name); |
} |
} |
SetControlValue(SnatchHandle(tdial, tempItem), true); |
HUnlock((Handle)gWindObjSpecHandle); |
break; |
case kSetTextObject: |
HLock((Handle)gTextObjSpecHandle); |
/* fewer choices here */ |
NumToString((*gTextObjSpecHandle)->u.index, tempString); |
SetDialogItemText((Handle)SnatchHandle(tdial, kWPosRadio), tempString); |
/* see if word is being asked for */ |
if ((*gTextObjSpecHandle)->andWord) { |
SetControlValue(SnatchHandle(tdial, kWTitleRadioSet), true); |
NumToString((*gTextObjSpecHandle)->wordNumber, tempString); |
SetDialogItemText((Handle)SnatchHandle(tdial, kWPosNum), tempString); |
} |
HUnlock((Handle)gTextObjSpecHandle); |
break; |
case kSetShapeObject: |
HLock((Handle)gShapeObjSpecHandle); |
if (!(*gShapeObjSpecHandle)->u.index) |
(*gShapeObjSpecHandle)->u.index = 1; |
NumToString((*gShapeObjSpecHandle)->u.index, tempString); |
SetDialogItemText((Handle)SnatchHandle(tdial, kSIEditLine), tempString); |
SetControlValue(SnatchHandle(tdial, ((*gShapeObjSpecHandle)->type) + kLineRadio), true); |
/* byIndex defaults to on for now */ |
SetControlValue(SnatchHandle(tdial, kSByIndexRadio), true); |
break; |
default: |
break; |
} |
return(tdial); |
} |
/* this is a central point to add keyErrorText and keyErrorNumber */ |
/* parameters to a reply */ |
/* just a handy thing to do. */ |
/* It first checks to see if an error is already recorded, if there is one */ |
/* (for an earlier stage in the process) they we exit, since the user will have to */ |
/* deal with the ealier problem before they tackle the one we've just been called */ |
/* to add */ |
/* ¥¥¥¥ BE SURE that you null out the gCurrentReply (or whatever you use) pointer */ |
/* when you exit from your handler, or you could end up writing to a desc that isn't */ |
/* there. And of course, if you send events to yourself from within a handler */ |
/* you're going to have to use a differrent method than this. It's a sample, see? */ |
void AddToReply(ConstStr255Param theWords, long theError) |
{ |
OSErr myErr = noErr; |
long errNo; |
DescType returnedType; |
Size returnedSize; |
/* First, is therre a reply hanging out? */ |
if (gCurrentReply) { |
/* test to see if there is one already*/ |
myErr = AEGetParamPtr(gCurrentReply, keyErrorNumber, typeLongInteger, &returnedType, (Ptr)&errNo, sizeof(long), |
&returnedSize); |
if (myErr == errAEDescNotFound) { |
/* cool, press on. */ |
myErr = AEPutParamPtr(gCurrentReply, keyErrorNumber, typeLongInteger, (Ptr)&theError, sizeof(long)); |
if (!myErr) |
myErr = AEPutParamPtr(gCurrentReply, keyErrorString, typeChar, (Ptr)&theWords[1], theWords[0]); |
} |
} |
} |
OSErr MakeTypeRect(CShapeObjHandle theShape, AEDesc *theValue) |
{ |
OSErr myErr = noErr; |
AEDesc pixDesc; |
AEDescList theList; |
RGBColor black = { |
0, 0, 0 |
}; |
RGBColor white = { |
0xffff, 0xffff, 0xffff |
}; |
short penSize = 1; |
long copyWord = kAEQDCopy; |
ShapesHandle theRealShape = (*theShape)->theShape; |
HLock((Handle)theRealShape); |
/* Now, a typeRectangle is a bunch of stuff, and as the AE Registry so clearly says... */ |
/* "Note that the Apple Event Manager can coerce any Apple event record into any |
other descriptor type. A special coercion handler is not required." |
*/ |
/* If you always wondered what that meant (I know I did) then watch */ |
/* create a list that is a record */ |
myErr = AECreateList(nil, nil, true, &theList); |
/* now start adding all the junk I have lying around, rectangle, color, kitchen sink.... */ |
if (!myErr) |
myErr = MakeSinglePixelMap(&pixDesc, &(*theRealShape)->theColor); |
/* jeeez don't try and write code while the Finder is doing a copy across LocalTalk in the background Like I'm trying to now.... */ |
if (!myErr) |
myErr = AEPutParamDesc(&theList, keyAEPenPattern, &pixDesc); |
if (!myErr) |
myErr = AEPutParamDesc(&theList, keyAEFillPattern, &pixDesc); |
AEDisposeDesc(&pixDesc); |
if (!myErr) |
myErr = MakeSinglePixelMap(&pixDesc, &white); |
if (!myErr) |
myErr = AEPutParamDesc(&theList, keyAEFillColor, &pixDesc); |
AEDisposeDesc(&pixDesc); |
if (!myErr) |
myErr = AEPutParamPtr(&theList, keyAEPenWidth, typeShortInteger, (Ptr)&penSize, sizeof(short)); |
if (!myErr) |
myErr = AEPutParamPtr(&theList, keyAETransferMode, typeEnumeration, (Ptr)©Word, sizeof(long)); |
if (!myErr) |
myErr = AEPutParamPtr(&theList, keyAEBounds, typeQDRectangle, (Ptr)&(*theRealShape)->theRect, sizeof(Rect)); |
if (!myErr) |
myErr = AEPutParamPtr(&theList, keyAEDefinitionRect, typeQDRectangle, (Ptr)&(*theRealShape)->theRect, sizeof(Rect)); |
HUnlock((Handle)theRealShape); |
/* and coerce it into what we want */ |
if (!myErr) |
myErr = AECoerceDesc(&theList, typeRectangle, theValue); |
AEDisposeDesc(&theList); |
mAEErrorDisplay("\p\n Error creating typeRectangle", myErr) |
return(myErr); |
} |
/* MakeGraphicLine is similar to making a typeRectangle */ |
OSErr MakeGraphicLine(CShapeObjHandle theShape, AEDesc *theValue) |
{ |
OSErr myErr = noErr; |
AEDesc emptyList; |
AEDesc pixDesc; |
AEDescList theList; |
RGBColor black = { |
0, 0, 0 |
}; |
RGBColor white = { |
0xffff, 0xffff, 0xffff |
}; |
short penSize = 1; |
long copyWord = kAEQDCopy; |
DescType noArr = kAENoArrow; |
ShapesHandle theRealShape = (*theShape)->theShape; |
HLock((Handle)theRealShape); |
myErr = AECreateList(nil, nil, true, &theList); |
/* now start adding all the junk I have lying around, rectangle, color, kitchen sink.... */ |
if (!myErr) |
myErr = MakeSinglePixelMap(&pixDesc, &(*theRealShape)->theColor); |
/* jeeez don't try and write code while the Finder is doing a copy across LocalTalk in the background Like I'm trying to now.... */ |
if (!myErr) |
myErr = AEPutParamDesc(&theList, keyAEPenPattern, &pixDesc); |
if (!myErr) |
myErr = AEPutParamDesc(&theList, keyAEPenColor, &pixDesc); |
AEDisposeDesc(&pixDesc); |
if (!myErr) |
myErr = AEPutParamPtr(&theList, keyAEPenWidth, typeShortInteger, (Ptr)&penSize, sizeof(short)); |
if (!myErr) |
myErr = AEPutParamPtr(&theList, keyAETransferMode, typeEnumeration, (Ptr)©Word, sizeof(long)); |
if (!myErr) |
myErr = AEPutParamPtr(&theList, keyAEBounds, typeQDRectangle, (Ptr)&(*theRealShape)->theRect, sizeof(Rect)); |
if (!myErr) |
myErr = AEPutParamPtr(&theList, keyAELineArrow, typeEnumeration, (Ptr)&noArr, sizeof(DescType)); |
/* we have no dash styles, so add an empty list */ |
myErr = AECreateList(nil, nil, false, &emptyList); |
if (!myErr) |
myErr = AEPutParamDesc(&theList, keyAEDashStyle, &emptyList); |
AEDisposeDesc(&emptyList); |
if (!myErr) |
myErr = AEPutParamPtr(&theList, keyAEStartPoint, typeQDRectangle, (Ptr)&(*theRealShape)->theRect, sizeof(Point)); |
if (!myErr) |
myErr = AEPutParamPtr(&theList, keyAEStartPoint, typeQDRectangle, (Ptr)&(*theRealShape)->theRect.bottom, sizeof(Point)); |
HUnlock((Handle)theRealShape); |
/* and coerce it into what we want */ |
if (!myErr) |
myErr = AECoerceDesc(&theList, typeGraphicLine, theValue); |
AEDisposeDesc(&theList); |
mAEErrorDisplay("\p\n Error creating typeGraphicLine", myErr) |
return(myErr); |
} |
/* Now some of the definitions in the AE Registry are rather broad, but they */ |
/* really need to be. SO you'll want little routines like this */ |
OSErr MakeSinglePixelMap(AEDesc *thePlace, RGBColor *theColor) |
{ |
OSErr myErr = noErr; |
AEDescList thePixelList, tempList; |
AEDesc scratchDesc; |
long copyWord = kAEQDCopy; |
Rect miniRect = { |
0, 0, 1, 1 |
}; |
myErr = AECreateList(nil, nil, false, &thePixelList); |
if (!myErr) |
myErr = AECreateDesc(typeRGBColor, (Ptr)theColor, sizeof(RGBColor), &scratchDesc); |
if (!myErr) |
myErr = AEPutDesc(&thePixelList, 0, &scratchDesc); |
if (!myErr) |
myErr = AEDisposeDesc(&scratchDesc); |
/* now create the other list */ |
if (!myErr) |
myErr = AECreateList(nil, nil, true, &tempList); |
/* add the pixels */ |
if (!myErr) |
myErr = AEPutParamDesc(&tempList, typePixMapMinus, &thePixelList); |
if (!myErr) |
myErr = AEDisposeDesc(&thePixelList); |
if (!myErr) |
myErr = AECreateDesc(typeQDRectangle, (Ptr)&miniRect, sizeof(Rect), &scratchDesc); |
/* add it */ |
if (!myErr) |
myErr = AEPutParamDesc(&tempList, keyAEBounds, &scratchDesc); |
if (!myErr) |
myErr = AEDisposeDesc(&scratchDesc); |
/* and the transfer mode, I'm using Copy for all of these */ |
if (!myErr) |
myErr = AECreateDesc(typeEnumeration, (Ptr)©Word, sizeof(long), &scratchDesc); |
/* add it */ |
if (!myErr) |
myErr = AEPutParamDesc(&tempList, keyAETransferMode, &scratchDesc); |
if (!myErr) |
myErr = AEDisposeDesc(&scratchDesc); |
/* and coerce thePlace into a typePixelMap */ |
if (!myErr) |
myErr = AECoerceDesc(&tempList, typePixelMap, thePlace); |
/* See? Simplicity itself */ |
mAEErrorDisplay("\p\n Error creating pixMap", myErr) |
return(myErr); |
} |
#undef __AEMU__ |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14