home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AppleScript - The Beta Release
/
AppleScript - The Beta Release.iso
/
Development Tools
/
Sample Applications
/
CoreSample
/
CoreSample Source
/
CoreSample.c
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
Text File
|
1992-11-24
|
80.8 KB
|
2,203 lines
|
[
TEXT/MPS
]
//----------------------------------------------------------------------------------//
// //
// CoreSample - An application that is Apple Event-aware, Scripting Compatible, //
// and recordable. It supports the Required and Core Suite of //
// Apple Events, the Object Model, and the Open Scripting //
// Architecture. //
// //
// by: Sue Dumont //
// Applications Scripting Group //
// //
// Version 1.01 //
// Copyright © Apple Computer, Inc. 1991,1992 //
// All rights reserved. //
// //
// NOTE: This application conforms to the "Apple Event Registry, Standard Suites //
// Winter 1992, Vers. 1.0". CoreSample replaces the SimpleSample application that //
// was distributed at the Scripting QuickStart Conference on January 15,1992. //
// //
// The main purpose of this sample code is to demonstrate how to develop an //
// application that is Apple event-aware, scripting compatible, uses the Object //
// Support Library, and supports Apple's Open Scripting Architecture. In //
// addition, it has its own 'aete' (Apple Event Terminology Extension) resource //
// (CoreSampleAETE.r). By incorporating these technologies into your application, //
// your application will support Apple's Open Scripting Architecture. //
// //
// The functionality of CoreSample is basic window manipulation. The user may //
// create, drag, size, zoom, and close windows. All these actions may be //
// performed through Apple events. //
// //
// This application is also "factored", which means that user interactions (such //
// as dragging or sizing a window, selecting a menuitem) are converted into Apple //
// events which the application sends off to itself, and then is handled by the //
// corresponding event handler. Factoring makes it possible to access the appli- //
// cation's functionality through Apple events. It also makes it easier to record //
// the user's actions in the form of Apple events. //
// //
// CoreSample supports the Required and Core suites of events, and the application //
// and window object classes. One additional property has been added to the window //
// class, and that is its position, the top left-hand coordinates of the window. //
// Some events only apply to the window class, such as Create, Move, Clone, and //
// Set Data (application properties are not modifiable, except for pClipboard, //
// which I do not support). Currently, CoreSample supports the Simple Grammar, //
// as defined in the "Object Support Library Developer Note". //
// //
// The properties you may access with the Get Data Apple event are as follows: //
// Application - Best Type, Default Type, Class, Name, IsFrontProcess, Version //
// Window - Best Type, Default Type, Bounds, Class, Index, Name, Position, //
// Closeable, Titled, Resizable, Zoomable, Floating, Modal, Zoomed, //
// and Visible. //
// The properties you may set with the Set Data Apple event are as follows: //
// Window - Bounds, Index, Zoomed, Name, Position, and Visible. //
// //
// When you create a new element, you may pass it initial data values. This //
// application will create the new element accordingly if either or both of the //
// initial data parameters exist. In addition, with CoreSample, you may create or //
// move a window without passing it an insertion location record. By default, a //
// window will be created/moved to the frontmost position. //
// //
// (NOTE: Some portions of this code are derived from TESample, a //
// sample application provided by Apple Developer Technical Support.) //
// //
// //
// Modification History: //
// 11/91 <smd> - Initial code implementation. //
// 01/06/92 <kc> - Added code for Count Elements, Do Objects Exist, Move, //
// and Get Data Size. //
// 01/09/92 <kc> - Quick clean up for Scripting QuickStart. //
// 01/10/92 <smd> - Made insertion location parameter optional in the Create //
// and Move events, and provided my own default behavior. //
// 01/21/92 <smd> - Positive and negative offset when referencing by index. //
// 01/30/92 <smd> - Adding complete support for core suite and properties. //
// 02/05/92 <smd> - Handling optional parameters in Create Element event. //
// 02/17/92 <smd> - Added InitializeDescs() and DisposeDescs() routines. //
// 02/21/92 <smd> - Fixed bug where the same AEDesc was being passed as source //
// and dest to AECoerceDesc(). //
// - Send myself a Move event when user clicks in content of a //
// window. //
// 02/24/92 <smd> - Now sends a Move event when just making a window active. //
// This is done in the DoEvent routine, drag region. //
// 02/25/92 <smd> - Modified GetWindowWithTitle, GetWidnowWithIndex, and //
// GetWindowIndexNum routines to use WindowList so ALL windows //
// will be accessed (even invisible ones). //
// - Changed InitializeDescs to MyInitDescs and DisposeDescs to //
// MyDisposeDescs. //
// - Removed the FailIfErr calls from the AE Handlers so that //
// they will return the error code rather than dying. //
// 02/28/92 <smd> - Added coercion routines (thanks Kevin) to clean up code. //
// These convert from descs to boolean, long, and pstrings. //
// 04/20/92 <smd> - Fixed a bug with setting the visibility property of a window.//
// 04/27/92 <smd> - Fixed bug in DoSetData where data was set to a pointer, and //
// then the pointer was diposed of. //
// 04/30/92 <smd> - Check if replacing the same window in HandleMove //
// (i.e., "move window 2 to window 2"). If so, do nothing. //
// 06/25/92 <smd> - Changed FindRelativeWindow to return the windowPtr of the //
// window being replaced rather than closing it. This caused //
// an error when trying to replace the same window, in which //
// case nothing should happen. (Ex. move window 2 to window 2).//
// 07/19/92 <smd> - Fixed bug where the Move event was not recording the //
// correct window being moved when the data was being passed //
// by index rather than by name. //
// 10/01/92 <smd> - Added pVersion to application and now set the port before //
// setting the pPosition property. //
//----------------------------------------------------------------------------------//
#include <SysEqu.h> // To use WindowList.
#include <Types.h>
#include <Quickdraw.h>
#include <Events.h>
#include <AppleEvents.h>
#include <AEObjects.h>
#include <AEPackObject.h>
#include <Resources.h> // for version resource
#include <Windows.h>
#include <Menus.h>
#include <Dialogs.h>
#include <Desk.h>
#include <Scrap.h>
#include <Values.h>
#include <ToolUtils.h>
#include <Memory.h>
#include <SegLoad.h>
#include <OSUtils.h>
#include <OSEvents.h>
#include <DiskInit.h>
#include <Packages.h>
#include <Traps.h>
#include <String.h>
#include <Strings.h>
#include <StdArg.h>
#include "AERegistry.h" // Constants defined in the Registry.
#include "CoreSample.h"
#define HiWrd(aLong) (((aLong) >> 16) & 0xFFFF)
#define LoWrd(aLong) ((aLong) & 0xFFFF)
typedef long* LongPtr;
typedef WindowPeek* PeekPtr;
// Globals.
SysEnvRec gMac; // Contains the system environment
Boolean gHasWaitNextEvent; // True if WaitNextEvent trap is available
Boolean gInBackground; // Determines if currently in the background
long gNumWindowsOpen; // The number of windows open
short gNewWindows; // The number of new windows created
Boolean gQuitApp; // True to quit the application
AEDesc gNullDesc; // A null descriptor record
AEAddressDesc gSelfAddress; // A self-addressed address descriptor record
ProcessSerialNumber gSelfPSN; // This application's psn
short gRefNum; // reference number of rescource file
//----------------------------------------------------------------------------------//
// PROTOTYPES //
//----------------------------------------------------------------------------------//
void AdjustMenuStates(void);
void AlertUser(short error);
void CloseTheWindow(WindowPtr window);
WindowPtr CreateNewWindow(WindowPtr behind);
OSErr CreateWindowObjectSpec(WindowPtr window,short formType,AEDesc *objectSpec);
void DoEvent(EventRecord *event);
void DoGrowWindow(WindowPtr window, EventRecord *event);
void DoMenuCommand(long menuResult);
OSErr DoSetData(AEDesc *token, AEDesc *data);
void DoUpdate(WindowPtr window);
void EventLoop(void);
void FailIfErr(OSErr error);
OSErr FindRelativeWindow(WindowPtr *window,AEDesc *object,DescType pos,WindowPtr *replaceWindow);
OSErr GetAppData(DescType theProperty, AEDesc *result);
OSErr GetMissingParams(AppleEvent *theAppleEvent);
OSErr GetWindowData(DescType property, WindowPtr window, AEDesc *result);
long GetWindowIndexNum(WindowPtr window);
WindowPtr GetWindowAtIndex(long index);
WindowPtr GetWindowWithTitle(ConstStr255Param title);
void InitAEHandlers(void);
void Initialize(void);
Boolean IsAppWindow(WindowPtr window);
Boolean IsDAWindow(WindowPtr window);
Boolean IsTrapAvailable(short tNumber, TrapType tType);
void ReportError(AppleEvent *reply, long err);
WindowPtr ResolveToWindow(AEDesc *objectSpecifier);
void SendClose(WindowPtr window);
void SendCreateElement(void);
void SendMoveEvent(WindowPtr windowToMove, long index);
void SendQuitApp(void);
void SendSetData(AEDesc *pDesc, AEDesc *pData, AEDesc *object);
void SetUpPropertyData(WindowPtr window,DescType propType,DescType dataType,Size dataSize);
void SignalError(short error);
void Terminate(void);
void ZoomIt(WindowPtr window, short part);
extern pascal OSErr CreateObjSpecifier(DescType theClass, AEDesc *theContainer,
DescType keyForm, AEDesc *keyData, Boolean disposeInputs,
AEDesc *objSpecifier);
extern void _DataInit();
//----------------------------------------------------------------------------------//
#pragma segment Main
main()
{
UnloadSeg((Ptr) _DataInit); // Note that _DataInit must not be in Main!
MaxApplZone(); // Expand the heap so code segments load at the top.
Initialize(); // Initialize the program
UnloadSeg((Ptr)Initialize); // Note that Initialize must not be in Main!
EventLoop(); // Call the main event loop
}
//----------------------------------------------------------------------------------//
// Continue retrieving events until the application terminates. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void EventLoop()
{
RgnHandle cursorRgn;
Boolean gotEvent;
EventRecord event;
cursorRgn = NewRgn();
gQuitApp = false; // This is set to true in Terminate().
while (!gQuitApp) // Loop until user quits or error.
{
if (gHasWaitNextEvent)
gotEvent = WaitNextEvent(everyEvent, &event ,MAXLONG, cursorRgn);
else
{
SystemTask();
gotEvent = GetNextEvent(everyEvent, &event);
}
if (gotEvent)
DoEvent(&event);
}
}
//----------------------------------------------------------------------------------//
// Find out which event this is and send it off to its appropriate handler. //
// When the user clicks in the drag region, either one of two events may be //
// triggered. The set position property (set data event) would occur if the widnow //
// is dragged to another location, or the move event would be sent if the window //
// is just made active. In the latter case, the window's index before being //
// moved to the front is passed to SendMoveEvent for recording purposes. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void DoEvent( EventRecord* event )
{
long index=0;
short part, err;
WindowPtr window;
char key;
Rect bounds1, bounds2;
Point aPoint;
switch (event->what)
{
case mouseDown:
part = FindWindow(event->where, &window);
switch (part)
{
case inMenuBar:
AdjustMenuStates();
DoMenuCommand(MenuSelect(event->where));
break;
case inSysWindow:
SystemClick(event, window);
break;
case inContent:
if (window != FrontWindow())
SendMoveEvent(window, index);
break;
case inDrag:
index = GetWindowIndexNum(window);
bounds1 = (*((WindowPeek)window)->contRgn)->rgnBBox;
DragWindow(window, event->where, &qd.screenBits.bounds);
bounds2 = (*((WindowPeek)window)->contRgn)->rgnBBox;
if (bounds1 == bounds2)
SendMoveEvent(GetWindowAtIndex(index), index);
else
SetUpPropertyData(window,pPosition,typeQDPoint,sizeof(Point));
break;
case inGoAway:
if (TrackGoAway(window, event->where))
SendClose(window);
break;
case inGrow:
DoGrowWindow(window, event);
break;
case inZoomIn: // For recording purposes, we send an Apple
case inZoomOut: // event to ourselves to set the bounds property.
if (TrackBox(window, event->where, part))
{
ZoomIt(window, part);
SetUpPropertyData(window, pIsZoomed, typeBoolean, sizeof(Boolean));
}
break;
}
break;
case keyDown:
case autoKey: // Only handle menu key equivalents
key = event->message & charCodeMask;
if (event->modifiers & cmdKey) // Command key down
{
if (event->what == keyDown)
{
AdjustMenuStates(); // Enable/disable/check menu items properly
DoMenuCommand(MenuKey(key));
}
}
break;
case activateEvt:
DrawGrowIcon((WindowPtr)event->message);
break;
case updateEvt:
DoUpdate((WindowPtr) event->message);
break;
case diskEvt:
if (HiWord(event->message) != noErr)
{
SetPt(&aPoint, kDILeft, kDITop);
err = DIBadMount(aPoint, event->message);
}
break;
case kOSEvent:
{
switch ((event->message >> 24) & 0x0FF) // High byte of message.
{
case kMouseMovedMessage:
break; // Do nothing if mouse moved.
case kSuspendResumeMessage: // suspend/resume is also an activate/deactivate
SetCursor(&qd.arrow);
if (IsAppWindow(window = FrontWindow()))
DrawGrowIcon(window);
break;
}
}
break;
case kHighLevelEvent: // Let the Apple Event Manager handle high level event.
AEProcessAppleEvent(event);
break;
default:
break;
}
}
//----------------------------------------------------------------------------------//
// Handle the mouseDown event in the grow box region of the window. If the //
// window has been resized, an Apple Event is sent to set the bounds property. //
// This is done for recording purposes. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void DoGrowWindow( WindowPtr window,
EventRecord* event )
{
long result;
Rect tempRect;
tempRect = qd.screenBits.bounds; // Set up the limiting values.
tempRect.top = kMinWinDim;
tempRect.left = kMinWinDim;
result = GrowWindow(window, event->where, &tempRect);
if (result) // Did window actually change size?
{
SetPort(window);
InvalRect(&window->portRect);
SizeWindow(window, LoWrd(result), HiWrd(result), true);
InvalRect(&window->portRect); // Send event for recording purposes.
SetUpPropertyData(window, pBounds, typeQDRectangle, sizeof(Rect));
}
}
//----------------------------------------------------------------------------------//
// Zoom the window and set the refcon field to reflect its zoomed state. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void ZoomIt( WindowPtr window,
short part )
{
SetPort(window);
EraseRect(&window->portRect); // We just have a blank window.
ZoomWindow(window, part, window == FrontWindow());
SetWRefCon(window, (long)part == inZoomOut); // Set to true if zoomed.
InvalRect(&window->portRect);
}
//----------------------------------------------------------------------------------//
// This is called when an update event is received for a window. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void DoUpdate( WindowPtr window )
{
if (IsAppWindow(window))
{
BeginUpdate(window);
SetPort(window);
EraseRect(&window->portRect); // We just have an empty window.
DrawGrowIcon(window);
EndUpdate(window);
}
}
//----------------------------------------------------------------------------------//
// Set up the menus according to the current state. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void AdjustMenuStates()
{
WindowPtr window;
MenuHandle menu;
window = FrontWindow();
menu = GetMHandle(mFile);
if (gNumWindowsOpen < kMaxOpenWindows)
EnableItem(menu, iNew); // Enable New if we can open more windows.
else
DisableItem(menu, iNew);
if (window)
EnableItem(menu, iClose); // Enable Close if there is a window to close.
else
DisableItem(menu, iClose);
}
//----------------------------------------------------------------------------------//
// This is called when an item is chosen from the menu bar. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void DoMenuCommand(long menuResult)
{
short menuID, menuItem;
short itemHit, daRefNum;
Str255 daName;
WindowPtr window;
window = FrontWindow();
menuID = HiWord(menuResult);
menuItem = LoWord(menuResult);
switch (menuID)
{
case mApple:
switch (menuItem)
{
case iAbout:
itemHit = Alert(rAboutAlert, nil);
break;
default: // all other items in this menu are DA's.
GetItem(GetMHandle(mApple), menuItem, daName);
daRefNum = OpenDeskAcc(daName);
break;
}
break;
case mFile:
switch (menuItem) // All these items send Apple events to
{ // handle the selection.
case iNew:
SendCreateElement();
break;
case iClose:
SendClose(FrontWindow());
break;
case iQuit:
SendQuitApp();
break;
}
break;
case mEdit: // Call SystemEdit for DA editing & MultiFinder.
SystemEdit(menuItem-1);
break;
}
HiliteMenu(0); // Unhighlight what MenuSelect (or MenuKey) hilited.
}
//----------------------------------------------------------------------------------//
// This routine appends the ascii representation of num to the title string. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void MakeNewWindowTitle( short num, // Window number.
Str255 title) // Window title.
{
short i, count, index;
char numStr[5];
i = 0;
do {
numStr[i++] = num % 10 + '0';
} while (num /= 10);
index = title[0] + 1; // Get length of title string.
for (count = i-1; count >= 0; count--)
title[index++] = numStr[count];
title[0] += i;
}
//----------------------------------------------------------------------------------//
// Create a new window behind the given window. Use the window's refCon //
// field to indicate whether the window is zoomed or not. //
//----------------------------------------------------------------------------------//
#pragma segment Main
WindowPtr CreateNewWindow(WindowPtr behindWindow)
{
Ptr storage;
WindowPtr newWindow, firstWindow;
Rect bounds;
Str255 title;
if (gNumWindowsOpen < kMaxOpenWindows)
{
storage = NewPtr(sizeof(WindowRecord));
if (storage != nil)
{
newWindow = GetNewWindow(rDocWindow, storage, behindWindow);
if (newWindow != nil)
{
gNumWindowsOpen++; // Increment the number of windows currently open.
gNewWindows++; // Increment the number of new windows created.
GetWTitle(newWindow, title);
MakeNewWindowTitle(gNewWindows, title);
SetWTitle(newWindow, title);
if (firstWindow = FrontWindow())
{
bounds = (*((WindowPeek)firstWindow)->contRgn)->rgnBBox;
MoveWindow(newWindow, bounds.left+30, bounds.top+30, false);
}
SetWRefCon(newWindow, 0L); // set zoom state to false.
SetPort(newWindow);
return(newWindow);
}
else
DisposPtr(storage); // Dispose of the storage if it is not used.
}
}
return(nil);
}
//----------------------------------------------------------------------------------//
// Close the given window or desk accessory. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void CloseTheWindow(WindowPtr window)
{
if (IsDAWindow(window))
CloseDeskAcc(((WindowPeek)window)->windowKind);
else
if (IsAppWindow(window))
{
CloseWindow(window);
DisposPtr((Ptr)window);
gNumWindowsOpen--;
}
}
//----------------------------------------------------------------------------------//
// Returns true if the window belongs to this application, else false. //
//----------------------------------------------------------------------------------//
#pragma segment Main
Boolean IsAppWindow(WindowPtr window)
{
if (!window)
return(false);
else
return(((WindowPeek)window)->windowKind == userKind);
}
//----------------------------------------------------------------------------------//
// Returns true if the given window belongs to a DA, else false is returned. //
//----------------------------------------------------------------------------------//
#pragma segment Main
Boolean IsDAWindow(WindowPtr window)
{
if (window == nil)
return(false);
else // DA windows have negative windowKinds.
return(((WindowPeek)window)->windowKind < 0);
}
//----------------------------------------------------------------------------------//
// If an error has occurred, I check the user interaction level. If I can //
// interact with the user, I put up a dialog and exit the application; otherwise, //
// I just exit the application. //
// //
// ***NOTE: Real applications would not handle errors in this fashion! If they //
// cannot interact with the user, they should abort the Apple event handler and //
// return the error in the reply parameter. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void FailIfErr(OSErr error)
{
if (error)
{
if (!(AEInteractWithUser(kNoTimeOut, nil, nil))) // Can we interact?
AlertUser(eAEError); // Yes, so put up the dialog.
ExitToShell();
}
}
//----------------------------------------------------------------------------------//
// Display an alert for the user to indicate that an error has occurred. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void AlertUser(short error)
{
short itemHit;
Str255 message;
GetIndString(message, kErrStrings, error);
ParamText(message, "", "", "");
itemHit = Alert(rUserAlert, nil);
}
//----------------------------------------------------------------------------------//
// Quit the application by closing all windows and setting the quit flag to true. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void Terminate()
{
WindowPtr aWindow;
while(aWindow = FrontWindow())
CloseTheWindow(aWindow);
AEDisposeDesc(&gSelfAddress); // Dispose of my self-addressed descriptor.
gQuitApp = true;
}
//----------------------------------------------------------------------------------//
// Perform the initialization necessary at start-up time. Note that we use //
// kCurrentProcess in our psn rather than calling GetCurrentProcess. Using //
// kCurrentProcess will allow us to record those events we send to ourselves, //
// otherwise, the recorder won't recognize the psn and won't record our event! //
//----------------------------------------------------------------------------------//
#pragma segment Initialize
void Initialize()
{
Handle menuBar;
long total, contig;
EventRecord event;
short count;
gInBackground = false;
InitGraf((Ptr)&qd.thePort);
InitWindows();
InitMenus();
InitDialogs(nil);
InitCursor();
InitAEHandlers();
for (count = 1; count <= 3; count++)
EventAvail(everyEvent, &event);
SysEnvirons(kSysEnvironsVersion, &gMac);
if (gMac.machineType < 0)
SignalError(eWrongMachine); // Less than 128K ROM's.
gHasWaitNextEvent = IsTrapAvailable(_WaitNextEvent, ToolTrap);
if ((long)GetApplLimit() - (long)ApplicZone() < kMinHeap)
SignalError(eSmallSize);
PurgeSpace(&total, &contig);
if (total < kMinSpace)
if (UnloadScrap() != noErr)
SignalError(eNoMemory);
else
{
PurgeSpace(&total, &contig);
if (total < kMinSpace)
SignalError(eNoMemory);
}
if (!(menuBar = GetNewMBar(rMenuBar))) // Set up menu bar.
SignalError(eNoMemory);
SetMenuBar(menuBar);
DisposHandle(menuBar);
AddResMenu(GetMHandle(mApple), 'DRVR'); // Add DA's to menu.
DrawMenuBar();
// Set up the self-addressed descriptor record.
gSelfPSN.highLongOfPSN = 0;
gSelfPSN.lowLongOfPSN = kCurrentProcess; //* Use this instead of GetCurrentProcess *//
FailIfErr(AECreateDesc(typeProcessSerialNumber,(Ptr)&gSelfPSN,sizeof(ProcessSerialNumber),&gSelfAddress));
gNullDesc.descriptorType = typeNull; // Initialize the global null descriptor record.
gNullDesc.dataHandle = nil;
gRefNum = CurResFile();
gNumWindowsOpen = 0;
gNewWindows = 0;
}
//----------------------------------------------------------------------------------//
// Returns true if the given trap number is implemented, else returns false. //
//----------------------------------------------------------------------------------//
#pragma segment Initialize
Boolean IsTrapAvailable(short trapNum, TrapType tType)
{
if ((tType == (unsigned char)ToolTrap) && (gMac.machineType > envMachUnknown) &&
(gMac.machineType < envMacII))
{ // it's a 512K, Plus, or SE
trapNum = trapNum & 0x03FF;
if (trapNum > 0x01FF) // which means the tool traps
trapNum = _Unimplemented; // only go to 0x01FF
}
return(NGetTrapAddress(trapNum, tType) != GetTrapAddress(_Unimplemented));
}
//----------------------------------------------------------------------------------//
#pragma segment Initialize
void SignalError(short error)
{
AlertUser(error);
ExitToShell();
}
//**********************************************************************************//
// * Apple Events and Object Model Support * //
//**********************************************************************************//
//----------------------------------------------------------------------------------//
// Initializes all descriptor records passed in to this routine. The variable //
// argument list is null terminated. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void MyInitDescs(AEDesc* desc1, ... ) // Variable, null terminated argument list.
{
va_list argptr; // pointer to each argument in list.
AEDesc* nextDesc; // next descriptor argument in list.
va_start(argptr, desc1);
desc1->descriptorType = typeNull;
desc1->dataHandle = nil;
while(nextDesc = va_arg(argptr, AEDesc *))
{
nextDesc->descriptorType = typeNull;
nextDesc->dataHandle = nil;
}
va_end(argptr);
}
//----------------------------------------------------------------------------------//
// Dispose all descriptor records passed into this routine. (Variable arg. list). //
//----------------------------------------------------------------------------------//
#pragma segment Main
void MyDisposeDescs(AEDesc* desc1, ... ) // Null terminated argument list.
{
va_list argptr; // pointer to each argument in list.
AEDesc* nextDesc; // descriptor argument in list.
va_start(argptr, desc1);
if (desc1->dataHandle)
AEDisposeDesc(desc1);
while(nextDesc = va_arg(argptr, AEDesc *))
{
if (nextDesc->dataHandle)
AEDisposeDesc(nextDesc);
}
va_end(argptr);
}
//----------------------------------------------------------------------------------//
// Converts a descriptor to a boolean. //
//----------------------------------------------------------------------------------//
#pragma segment AppleEvents
OSErr DescToBoolean(const AEDesc* desc, Boolean* boolvalue)
{
AEDesc tempDesc;
Handle dataHandle;
tempDesc.dataHandle = nil;
if (desc->descriptorType == typeBoolean)
dataHandle = desc->dataHandle;
else
if (AECoerceDesc(desc, typeBoolean, &tempDesc) == noErr)
dataHandle = tempDesc.dataHandle;
else
return(errAECoercionFail);
*boolvalue = **dataHandle;
MyDisposeDescs(&tempDesc, kEndOfList);
return(noErr);
}
//----------------------------------------------------------------------------------//
// Converts a descriptor to a long. //
//----------------------------------------------------------------------------------//
#pragma segment AppleEvents
OSErr DescToLong(const AEDesc* desc, long* longvalue)
{
AEDesc tempDesc;
Handle dataHandle;
tempDesc.dataHandle = nil;
if (desc->descriptorType == typeLongInteger)
dataHandle = desc->dataHandle;
else
if (AECoerceDesc(desc, typeLongInteger, &tempDesc) == noErr)
dataHandle = tempDesc.dataHandle;
else
return(errAECoercionFail);
*longvalue = *(LongPtr)*dataHandle;
MyDisposeDescs(&tempDesc, kEndOfList);
return(noErr);
}
//----------------------------------------------------------------------------------//
// Converts a descriptor to a pascal string. //
//----------------------------------------------------------------------------------//
#pragma segment AppleEvents
OSErr DescToPString(const AEDesc* desc, Str255 str, short maxLength)
{
AEDesc tempDesc;
Handle dataHandle;
long charCount;
tempDesc.dataHandle = nil;
if (desc->descriptorType == typeChar)
dataHandle = desc->dataHandle;
else
if (AECoerceDesc(desc, typeChar, &tempDesc) == noErr)
dataHandle = tempDesc.dataHandle;
else
return(errAECoercionFail);
charCount = GetHandleSize(dataHandle);
if (charCount > maxLength)
{
MyDisposeDescs(&tempDesc, kEndOfList);
return(errAECoercionFail);
}
str[0] = charCount;
HLock(dataHandle);
BlockMove(*dataHandle, &str[1], charCount);
HUnlock(dataHandle); // This may be from desc, so must unlock.
MyDisposeDescs(&tempDesc, kEndOfList);
return(noErr);
}
//----------------------------------------------------------------------------------//
// Create the first window in response to the Open Application Apple Event. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr HandleOpenApp(AppleEvent *theAppleEvent, AppleEvent* reply, long refCon)
{
#pragma unused (reply,refCon)
WindowPtr window;
OSErr err;
if (!(err = GetMissingParams(theAppleEvent))) // Error if any parameters.
{
if (window = CreateNewWindow((WindowPtr)-1)) // Create initial window
ShowWindow(window);
else
err = errAEEventNotHandled;
}
return(err);
}
//----------------------------------------------------------------------------------//
// Send a Quit Application Apple Event to myself to terminate this app. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void SendQuitApp()
{
AppleEvent myAppleEvent, reply;
// Create the Apple Event.
FailIfErr(AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &gSelfAddress,
kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent));
// Send the Apple Event.
FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAENeverInteract, kAENormalPriority,
kAEDefaultTimeout, nil, nil));
AEDisposeDesc(&myAppleEvent); // Dispose of the Apple Event.
}
//----------------------------------------------------------------------------------//
// Quit the application. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr HandleQuitApp(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
{
#pragma unused (reply,refCon)
OSErr err;
if (!(err = GetMissingParams(theAppleEvent))) // Error if there are any parameters.
Terminate();
return(err);
}
//----------------------------------------------------------------------------------//
// This routine makes a clone of the given window by copying its bounds, zoom //
// state, and title (with the addition of "copy") properties. //
//----------------------------------------------------------------------------------//
#pragma segment Main
WindowPtr CloneWindow(WindowPtr windowToClone, WindowPtr behindWindow)
{
WindowPtr clonedWindow;
Rect bounds;
Str255 title;
if (clonedWindow = CreateNewWindow(behindWindow))
{
GetWTitle(windowToClone, title);
p2cstr(title);
strcat(title, " copy\0");
c2pstr(title);
bounds = (*((WindowPeek)windowToClone)->contRgn)->rgnBBox;
SetWTitle(clonedWindow, title);
MoveWindow(clonedWindow, bounds.left, bounds.top, false);
SizeWindow(clonedWindow, bounds.right-bounds.left, bounds.bottom-bounds.top, true);
SetWRefCon(clonedWindow, GetWRefCon(windowToClone));
return(clonedWindow);
}
return(nil);
}
//----------------------------------------------------------------------------------//
// Handle the Clone Apple Event and create a clone of the given object. To clone //
// a window, I clone its bounds, zoom state, and visible properties. In addition, //
// I clone the window's title and append " copy" to it for the cloned window's //
// title. If the insertion location parameter is not in the event record, I //
// perform the default behavior, which is to position the clone behind the //
// window being cloned. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr HandleClone(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
{
#pragma unused (refCon)
AEDesc cloneObject, windowObject, replyObject, insertionLoc;
AERecord insertionRec;
DescType theType, position;
WindowPtr windowToClone, window, rplcWindow, behindWindow = nil;
Size paramSize;
OSErr err = noErr;
MyInitDescs(&cloneObject,&windowObject,&replyObject,&insertionLoc,&insertionRec,kEndOfList);
// Let's get the direct object, the object to clone.
if (err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeObjectSpecifier, &cloneObject))
goto myExit;
if (!(windowToClone = ResolveToWindow(&cloneObject)))
{
err = errAENoSuchObject;
goto myExit;
}
else // we have a window to clone.
{
if (!(err = AEGetParamDesc(theAppleEvent,keyAEInsertHere,typeInsertionLoc,&insertionLoc)))
if (!(err = AECoerceDesc(&insertionLoc, typeAERecord, &insertionRec)))
// Get object as typeWildCard because it may be null or an object specifier.
if (!(err = AEGetKeyDesc(&insertionRec, keyAEObject, typeWildCard, &windowObject)))
if (!(err = AEGetKeyPtr(&insertionRec,keyAEPosition,typeEnumeration,&theType,
(Ptr)&position,sizeof(DescType),¶mSize)))
err = FindRelativeWindow(&behindWindow, &windowObject, position, &rplcWindow);
if (err)
if (err == errAEDescNotFound)
behindWindow = windowToClone; // Registry's default behavior.
else
goto myExit;
}
if (window = CloneWindow(windowToClone, behindWindow))
{
if (((WindowPeek)windowToClone)->visible)
ShowWindow(window);
if (position == kAEReplace)
CloseTheWindow(rplcWindow);
if (reply->dataHandle != nil)
{
CreateWindowObjectSpec(window, kIndexKeyForm, &replyObject);
err = AEPutParamDesc(reply, keyAEResult, &replyObject);
}
}
else
err = errAEEventNotHandled;
myExit:
MyDisposeDescs(&cloneObject,&windowObject,&replyObject,&insertionLoc,&insertionRec,kEndOfList);
return(err);
}
//----------------------------------------------------------------------------------//
// Send a Close Apple Event to myself to close the specified window. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void SendClose(WindowPtr window)
{
AppleEvent myAppleEvent, reply;
AEDesc windowObject; // The window object specifier.
// Create the Close Apple Event.
FailIfErr(AECreateAppleEvent(kAECoreSuite, kAEClose, &gSelfAddress, kAutoGenerateReturnID,
kAnyTransactionID, &myAppleEvent));
// Create the window object specifier and add this to myAppleEvent.
CreateWindowObjectSpec(window, kIndexKeyForm, &windowObject);
FailIfErr(AEPutParamDesc(&myAppleEvent, keyDirectObject, &windowObject));
// Send the Apple Event.
FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAECanInteract, kAENormalPriority,
kAEDefaultTimeout, nil, nil));
// Now dispose of the AppleEvent and object specifier.
AEDisposeDesc(&myAppleEvent);
AEDisposeDesc(&windowObject);
}
//----------------------------------------------------------------------------------//
// Respond to the Close Apple Event by closing the specified window object. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr HandleClose(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
{
#pragma unused (reply,refCon)
AEDesc windowObject;
WindowPtr windowToClose;
OSErr myErr;
MyInitDescs(&windowObject,kEndOfList);
// First, get the direct object which is the object to close.
myErr = AEGetParamDesc(theAppleEvent,keyDirectObject,typeObjectSpecifier,&windowObject);
if (!myErr && !(myErr = GetMissingParams(theAppleEvent)))
{
if (windowToClose = ResolveToWindow(&windowObject))
CloseTheWindow(windowToClose);
else
myErr = errAENoSuchObject;
}
MyDisposeDescs(&windowObject,kEndOfList);
return(myErr);
}
//----------------------------------------------------------------------------------//
// Respond to the Count Elements Apple Event. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr HandleCountElements(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
{
#pragma unused (refCon)
AEDesc directObject;
DescType theType, theClass;
Size paramSize;
OSErr err;
MyInitDescs(&directObject, kEndOfList);
// Get the direct object, should be null.
if (!(err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &directObject)))
if (!(err = AEGetParamPtr(theAppleEvent,keyAEObjectClass,typeType,&theType,(Ptr)&theClass,
sizeof(DescType),¶mSize))) // Get class of elements to count.
err = GetMissingParams(theAppleEvent); // Error if more parameters.
if (err)
goto myExit;
// If we had a deeper object hierarchy, we'd probably call AEResolve here, but...
// we only handle the window class contained within the null object.
if (theClass == cWindow && directObject.descriptorType == typeNull)
err = AEPutParamPtr(reply, keyAEResult, typeLongInteger, (Ptr)&gNumWindowsOpen, sizeof(long));
myExit:
MyDisposeDescs(&directObject, kEndOfList);
return(err);
}
//----------------------------------------------------------------------------------//
// Send a Create Element Apple Event to myself to create a new window. By default, //
// I am setting the position to the beginning of the null container (frontmost). //
// In this case, as well as at the end of the container, the object parameter is //
// the null container. If the position is before, after, or replace, the object //
// parameter must be an object specifier to indicate the relative window. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void SendCreateElement()
{
AppleEvent myAppleEvent, reply;
AERecord insertionRec; // Insertion Loc record.
AEDesc insertionLoc; // The coerced insertionRec.
DescType theType;
// Create the Apple Event.
FailIfErr(AECreateAppleEvent(kAECoreSuite, kAECreateElement, &gSelfAddress, kAutoGenerateReturnID,
kAnyTransactionID, &myAppleEvent));
// Attach the class of the new element, which in this case is cWindow.
theType = cWindow;
FailIfErr(AEPutParamPtr(&myAppleEvent, keyAEObjectClass, typeType, (Ptr)&theType, sizeof(DescType)));
// Create insertion loc, object is null container and position is beginning.
FailIfErr(AECreateList(nil, 0, true, &insertionRec)); // Create an AE Record.
theType = kAEBeginning;
FailIfErr(AEPutKeyDesc(&insertionRec, keyAEObject, &gNullDesc));
FailIfErr(AEPutKeyPtr(&insertionRec, keyAEPosition, typeEnumeration, (Ptr)&theType, sizeof(DescType)));
FailIfErr(AECoerceDesc(&insertionRec, typeInsertionLoc, &insertionLoc));
// Now add the insertion location descriptor record to the Apple Event.
FailIfErr(AEPutParamDesc(&myAppleEvent, keyAEInsertHere, &insertionLoc));
// Send the Apple Event.
FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAECanInteract, kAENormalPriority,
kAEDefaultTimeout, nil, nil));
// Now dispose of the AppleEvent and other records.
MyDisposeDescs(&myAppleEvent, &insertionRec, &insertionLoc, kEndOfList);
}
//----------------------------------------------------------------------------------//
// Respond to the Create Element Apple event and create a new window. For this //
// application, the keyAEInsertHere parameter is optional. If this parameter is //
// not present, a new window is created in the frontmost position. //
// This routine also handles the optional initial data parameters (keyAEData and //
// keyAEPropData) if they are present. A window object specifier must be in the //
// keyAEData parameter, which is essentially used to make a clone. If the //
// property data exists, these properties will override those previously set. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr HandleCreateElement(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
{
#pragma unused (refCon)
AEDesc windowObject, dataObject, propData, propObject, replyObject;
AEDesc insLocParam;
AERecord insLocRec;
AERecord dataPropParam; // Initial data parameters.
AEKeyword keyWord; // Property id code for PropData.
DescType theType, theClass, position;
WindowPtr window, relativeWindow, dataWindow, rplcWindow;
Rect bounds;
Size theSize;
Str255 buffer;
long numItems;
short i;
Boolean isVisible;
OSErr err;
if (err = AEGetParamPtr(theAppleEvent, keyAEObjectClass, typeType, &theType, (Ptr)&theClass,
sizeof(DescType), &theSize))
return(err);
if (theClass != cWindow) // We only handle elements of the class cWindow.
return(errAEEventNotHandled);
position = typeNull;
MyInitDescs(&windowObject,&dataObject,&propData,&propObject,&insLocParam,&dataPropParam,&replyObject,&insLocRec,kEndOfList);
// Now get the insertion location record as an AERecord, if it exists.
if (!(err = AEGetParamDesc(theAppleEvent, keyAEInsertHere, typeInsertionLoc, &insLocParam)))
{ // coerce the insertion loc record to an AE record.
err = AECoerceDesc(&insLocParam, typeAERecord, &insLocRec);
// Get the object as typeWildCard because it may be a null descriptor or an object.
if (!(err = AEGetKeyDesc(&insLocRec, keyAEObject, typeWildCard, &windowObject)))
if (!(err = AEGetKeyPtr(&insLocRec, keyAEPosition, typeEnumeration, &theType, (Ptr)&position,
sizeof(DescType), &theSize)))
{
relativeWindow = nil;
err = FindRelativeWindow(&relativeWindow, &windowObject, position, &rplcWindow);
}
}
else
if (err == errAEDescNotFound) // No insertion loc, make it frontmost by default.
{
relativeWindow = (WindowPtr)-1;
position = kAEBeginning;
err = noErr; // Not an error for me because I make this param optional.
}
if (err)
goto myExit;
// Check if optional data parameter is present.
if (!(err = AEGetParamDesc(theAppleEvent,keyAEData,typeObjectSpecifier,&dataObject)))
{
if (dataWindow = ResolveToWindow(&dataObject))
{
window = CloneWindow(dataWindow, relativeWindow);
isVisible = ((WindowPeek)dataWindow)->visible;
}
else
{
err = errAENoSuchObject;
goto myExit;
}
}
else
if (err == errAEDescNotFound) // The optional data parameter is not present.
{
if (window = CreateNewWindow(relativeWindow))
{
err = noErr;
isVisible = true;
if (position == kAEReplace) // Replace the window in the right position.
{
bounds = (*((WindowPeek)rplcWindow)->contRgn)->rgnBBox;
MoveWindow(window, bounds.left, bounds.top, false);
}
}
else
{
err = errAEEventNotHandled; // couldn't create a new window.
goto myExit;
}
}
else
goto myExit;
if (isVisible) // We set the visibility here because it may be changed
ShowWindow(window); // by the following property data.
// Handle PropData parameter if it exists.
if (!(err = AEGetParamDesc(theAppleEvent,keyAEPropData,typeAERecord,&dataPropParam)))
{
AECountItems(&dataPropParam, &numItems);
for (i = 1; i <= numItems; i++)
{
if (!(err = AEGetNthPtr(&dataPropParam,i,typeWildCard,&keyWord,&theType,&buffer,sizeof(Str255),&theSize)))
{
AECreateDesc(keyWord, (Ptr)&window, sizeof(Ptr), &propObject);
AECreateDesc(theType, (Ptr)&buffer, theSize, &propData);
err = DoSetData(&propObject, &propData);
AEDisposeDesc(&propObject);
AEDisposeDesc(&propData);
if (err)
break;
}
}
}
if (!err || err == errAEDescNotFound)
{
if (position == kAEReplace)
CloseTheWindow(rplcWindow);
err = noErr;
if (reply->dataHandle != nil)
{
CreateWindowObjectSpec(window, kIndexKeyForm, &replyObject);
err = AEPutParamDesc(reply, keyAEResult, &replyObject);
}
}
myExit:
MyDisposeDescs(&windowObject,&dataObject,&propData,&propObject,&insLocParam,&dataPropParam,&replyObject,&insLocRec,kEndOfList);
return(err);
}
//----------------------------------------------------------------------------------//
// Respond to the Do Objects Exist AE by attempting to resolve the object specifier//
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr HandleDoObjectsExist(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
{
#pragma unused (reply,refCon)
AEDesc target, token;
Boolean exists;
OSErr err;
MyInitDescs(&target, &token, kEndOfList);
if (!(err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &target)))
if (!(err = GetMissingParams(theAppleEvent))) // Check for missing params.
{
exists = true;
token.descriptorType = typeNull;
if (target.descriptorType != typeNull)
exists = (AEResolve(&target, kAEIDoMinimum, &token) == noErr);
// Add data to the reply Apple event record.
err = AEPutParamPtr(reply, keyDirectObject,typeBoolean,(Ptr)&exists,sizeof(Boolean));
}
myExit:
MyDisposeDescs(&target, &token, kEndOfList);
return(err);
}
//----------------------------------------------------------------------------------//
// Send the Set Data Apple Event with the object, property, and property data. //
// *NOTE*: I am sending myself the Set Data event in response to user interaction. //
// These actions have already occurred by this time, so I am sending the event //
// with the "don't execute" flag set for "smart" recorders. A "smart" recorder //
// would check this flag when it intercepts the Apple event, and if it was set, //
// it wouldn't pass the event to the application. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void SendSetData( AEDesc* propDesc, // the property to set
AEDesc* propData, // the property data
AEDesc* target ) // object to set property of
{
AppleEvent myAppleEvent, reply;
AEDesc objectToSet;
FailIfErr(AECreateAppleEvent(kAECoreSuite, kAESetData, &gSelfAddress, kAutoGenerateReturnID,
kAnyTransactionID, &myAppleEvent));
// Create the object specifier for the property of the object.
FailIfErr(CreateObjSpecifier(cProperty, target, formPropertyID, propDesc,
false, &objectToSet));
// Attach the property object specifier.
FailIfErr(AEPutParamDesc(&myAppleEvent, keyDirectObject, &objectToSet));
// Add the property data.
FailIfErr(AEPutParamDesc(&myAppleEvent, keyAEData, propData));
FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAECanInteract+kAEDontExecute, kAENormalPriority,
kAEDefaultTimeout, nil, nil));
AEDisposeDesc(&objectToSet); // Clean up.
AEDisposeDesc(&myAppleEvent);
}
//----------------------------------------------------------------------------------//
// To set the data of an object, the expected data is passed in its raw form with //
// the property type in the descriptorType field and the data in the dataHandle. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr HandleSetData(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
{
#pragma unused (reply,refCon)
AEDesc target, data, token;
OSErr err;
MyInitDescs(&target, &data,&token, kEndOfList);
// First, get the direct object. This is the object whose data is to be set.
if (!(err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeObjectSpecifier, &target)))
if (!(err = AEResolve(&target, kAEIDoMinimum, &token))) // Resolve it.
if (!(err = AEGetParamDesc(theAppleEvent, keyAEData, typeWildCard, &data)))
err = DoSetData(&token, &data);
MyDisposeDescs(&target, &data, &token, kEndOfList);
return(err);
}
//----------------------------------------------------------------------------------//
// Return a reply to the Get Data or Get Data Size Apple Event for the requested //
// data. The refcon parameter is used to distinguish the two events. If typeBest //
// is the requested return type, the data's descriptor type is the result type. //
// **NOTE: Do not use the same descriptor as source and dest in AECoerceDesc(). //
// This routine creates a copy of the source, and then it is impossible to dispose //
// of the memory originally contained in the source's dataHandle. //
// 2/25/92 - Removed FailIfErr calls. Now the error is returned as a result. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr HandleGetData( AppleEvent* theAppleEvent,
AppleEvent* reply,
long refCon ) // kAEGetData or kAEGetDataSize.
{
AEDesc theObject, token; // direct object and resolved token.
AEDesc objectData, tempDesc; // object data, and coerced data.
DescType reqType;
WindowPtr window;
Size theSize;
OSErr err;
MyInitDescs(&theObject, &objectData, &token, kEndOfList);
// First, get the direct objet.
if (err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeObjectSpecifier, &theObject))
goto myExit;
// Next, get the requested return type, if it exists.
if (err = AEGetParamPtr(theAppleEvent, keyAERequestedType, typeType, &reqType,
(Ptr)&reqType, sizeof(DescType), &theSize))
{
if (err == errAEDescNotFound) // not an error if return type is not found
{
err = noErr;
reqType = typeWildCard;
}
else
goto myExit;
}
if (err = GetMissingParams(theAppleEvent)) // check for missing params
goto myExit;
// Resolve the object specifier and get the token containing the property and container.
if (!(err = AEResolve(&theObject, kAEIDoMinimum, &token)))
if (window = (WindowPtr)*(LongPtr)*token.dataHandle) // Nil for application; WindowPtr for window
err = GetWindowData(token.descriptorType, window, &objectData);
else
err = GetAppData(token.descriptorType, &objectData);
if (err == noErr && reply->dataHandle != nil)
{ // Add data to the reply Apple event record.
if (reqType != typeWildCard && reqType != typeBest &&
reqType != objectData.descriptorType)
{
err = AECoerceDesc(&objectData, reqType, &tempDesc);
MyDisposeDescs(&objectData, kEndOfList);
objectData.descriptorType = tempDesc.descriptorType;
objectData.dataHandle = tempDesc.dataHandle;
}
if (!err)
{
if (refCon == kAEGetData) // return data
err = AEPutParamDesc(reply, keyAEResult, &objectData);
else if (refCon == kAEGetDataSize) // return data size
{
theSize = GetHandleSize(objectData.dataHandle);
err = AEPutParamPtr(reply, keyAEResult, typeLongInteger, (Ptr)&theSize, sizeof(long));
}
}
}
myExit:
MyDisposeDescs(&theObject, &objectData, &token, kEndOfList);
return(err);
}
//----------------------------------------------------------------------------------//
// Send a Move Apple event to myself in response to a user selecting a window //
// and making it frontmost. This event is sent with the insertion location record //
// specifying the beginning of the null container. If the index is non-zero, this //
// indicates that the move event has already been performed by DragWindow(). Thus, //
// this event is passed with the don't execute flag set. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void SendMoveEvent(WindowPtr windowToMove, long index)
{
AppleEvent myAppleEvent, reply, windowObject;
AERecord insertionRec; // Insertion Loc record.
AEDesc insertionLoc; // The coerced insertionRec.
DescType theType;
// Create the Apple Event.
FailIfErr(AECreateAppleEvent(kAECoreSuite, kAEMove, &gSelfAddress, kAutoGenerateReturnID,
kAnyTransactionID, &myAppleEvent));
// Create the object spec for the window to move.
FailIfErr(CreateWindowObjectSpec(windowToMove, kIndexKeyForm, &windowObject));
FailIfErr(AEPutParamDesc(&myAppleEvent, keyDirectObject, &windowObject));
// Create insertion loc record for beginning of null container.
FailIfErr(AECreateList(nil, 0, true, &insertionRec)); // Create an AE Record.
theType = kAEBeginning;
FailIfErr(AEPutKeyDesc(&insertionRec, keyAEObject, &gNullDesc));
FailIfErr(AEPutKeyPtr(&insertionRec,keyAEPosition,typeEnumeration,(Ptr)&theType,sizeof(DescType)));
FailIfErr(AECoerceDesc(&insertionRec, typeInsertionLoc, &insertionLoc));
// Now add the insertion location descriptor record to the Apple Event.
FailIfErr(AEPutParamDesc(&myAppleEvent, keyAEInsertHere, &insertionLoc));
// Send the Apple Event.
if (index)
FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAECanInteract+kAEDontExecute,
kAENormalPriority, kAEDefaultTimeout, nil, nil));
else
FailIfErr(AESend(&myAppleEvent, &reply, kAENoReply+kAECanInteract,
kAENormalPriority, kAEDefaultTimeout, nil, nil));
// Now dispose of the AppleEvent and other records.
MyDisposeDescs(&myAppleEvent,&windowObject,&insertionRec,&insertionLoc,kEndOfList);
}
//----------------------------------------------------------------------------------//
// Respond to the Move Apple Event by reordering the window list. For CoreSample, //
// the keyAEInsertHere parameter is optional. If this parameter does not exist, //
// the specified window will move the to the front. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr HandleMove(AppleEvent* theAppleEvent, AppleEvent* reply, long refCon)
{
#pragma unused (refCon)
AEDesc object, windowObj, replyObj, insertionLoc;
AERecord insertionRec;
DescType theType, position;
WindowPtr windowToMove, relativeWindow, rplcWindow;
Rect bounds;
Size paramSize;
OSErr err;
MyInitDescs(&object,&windowObj,&insertionLoc,&insertionRec,&replyObj,kEndOfList);
// First, get the direct parameter, the object to move.
if (err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeObjectSpecifier, &object))
goto myExit;
if (!(windowToMove = ResolveToWindow(&object))) // Check if valid window object.
{
err = errAENoSuchObject;
goto myExit;
}
// Retrieve the insertion location record, if it exists.
if ((err = AEGetParamDesc(theAppleEvent,keyAEInsertHere,typeInsertionLoc,&insertionLoc)) == errAEDescNotFound)
{ // Execute *MY* default behavior since insertion loc param not present.
SelectWindow(windowToMove);
err = noErr;
goto myExit;
}
else
if (err)
goto myExit;
else // get data from insertion loc and coerce it to typeAERecord.
{
if ((err = GetMissingParams(theAppleEvent)) ||
(err = AECoerceDesc(&insertionLoc, typeAERecord, &insertionRec)) ||
(err = AEGetKeyDesc(&insertionRec,keyAEObject,typeWildCard,&windowObj)) ||
(err = AEGetKeyPtr(&insertionRec,keyAEPosition,typeEnumeration,&theType,
(Ptr)&position,sizeof(DescType),¶mSize)))
goto myExit;
}
if (!(err = FindRelativeWindow(&relativeWindow,&windowObj,position,&rplcWindow)))
{
if (position == kAEReplace)
if (windowToMove == rplcWindow)
goto myExit; // do nothing.
else
{
bounds = (*((WindowPeek)rplcWindow)->contRgn)->rgnBBox;
CloseTheWindow(rplcWindow);
MoveWindow(windowToMove, bounds.left, bounds.top, false);
}
if (relativeWindow == -1)
SelectWindow(windowToMove);
else
if (windowToMove != relativeWindow)
SendBehind(windowToMove, relativeWindow); // NOTE: may have to call PaintOne and
// CalcVis if after; see IM I-286
if (position == kAEReplace && windowToMove != rplcWindow)
{
bounds = (*((WindowPeek)rplcWindow)->contRgn)->rgnBBox;
CloseTheWindow(rplcWindow);
MoveWindow(windowToMove, bounds.left, bounds.top, false);
}
}
myExit:
if (!err)
if (reply->dataHandle != nil)
{
CreateWindowObjectSpec(windowToMove, kIndexKeyForm, &replyObj);
err = AEPutParamDesc(reply, keyAEResult, &replyObj);
}
MyDisposeDescs(&object,&windowObj,&insertionLoc,&insertionRec,&replyObj,kEndOfList);
return(err);
}
//----------------------------------------------------------------------------------//
// Set up the descriptor records needed to set the data for the bounds, position, //
// and zoomed properties. The bounds is set in response to sizing a window; the //
// position is set after dragging a window; and the isZoomed property is set when //
// zooming a window in or out. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void SetUpPropertyData( WindowPtr window, // Window object.
DescType propType, // Property descriptor type.
DescType dataType, // Descriptor type for data.
Size dataSize ) // Size of data.
{
AEDesc windowObject, theData, theProperty;
Rect bounds;
Boolean isZoomed;
MyInitDescs(&windowObject, &theData, &theProperty, kEndOfList);
if (propType == pIsZoomed)
{
isZoomed = (Boolean)GetWRefCon(window);
FailIfErr(AECreateDesc(dataType,(Ptr)&isZoomed,dataSize,&theData));
}
else // it's either pBounds or pPosition.
{
bounds = (*((WindowPeek)window)->contRgn)->rgnBBox; // Use the content region.
FailIfErr(AECreateDesc(dataType, (Ptr)&bounds, dataSize, &theData));
}
CreateWindowObjectSpec(window, kIndexKeyForm, &windowObject);
FailIfErr(AECreateDesc(typeType, (Ptr)&propType, sizeof(DescType), &theProperty));
SendSetData(&theProperty, &theData, &windowObject);
MyDisposeDescs(&windowObject, &theData, &theProperty, kEndOfList);
}
//----------------------------------------------------------------------------------//
// Set the property data for the specified object. For now, we only handle window //
// objects, and you may only set the modifiable properties (defined in Registry). //
// *NOTE*: We do not allow the application's properties to be modified. //
//----------------------------------------------------------------------------------//
#pragma segment Main
OSErr DoSetData( AEDesc* token, // Contains the property and object.
AEDesc* data ) // Contains the data to set.
{
AEDesc propData; // Property data.
Rect bounds;
GrafPtr oldPort;
WindowPtr window, behindWindow;
Str255 name;
long newIndex;
short part;
Boolean value;
Point pt;
OSErr err;
err = noErr;
if (window = (WindowPtr)*(LongPtr)*(token->dataHandle))
{
GetPort(&oldPort);
switch (token->descriptorType)
{
case pBounds:
if (data->descriptorType != typeQDRectangle)
{
propData.dataHandle = nil;
err = AECoerceDesc(data, typeQDRectangle, &propData);
bounds = *(Rect *)*propData.dataHandle; // Get content region.
MyDisposeDescs(&propData, kEndOfList);
}
else
bounds = *(Rect *)*data->dataHandle; // Get content region.
if (!err)
{
SetPort(window);
InvalRect(&window->portRect);
// Real applications may want to make a sanity check on the new bounds.
MoveWindow(window, bounds.left, bounds.top, false);
SizeWindow(window, bounds.right-bounds.left, bounds.bottom-bounds.top, true);
InvalRect(&window->portRect);
}
break;
case pIndex:
if (DescToLong(data,&newIndex) != noErr)
return(errAECoercionFail); // Data cannot be coerced.
if (newIndex > gNumWindowsOpen)
err = errAEIndexTooLarge;
else
{
if (newIndex == 1)
SelectWindow(window);
else
if (behindWindow = GetWindowAtIndex(newIndex))
SendBehind(window, behindWindow);
else
err = errAEEventFailed;
}
break;
case pIsZoomed:
if (DescToBoolean(data,&value) != noErr)
return(errAECoercionFail); // Data cannot be coerced.
part = value ? inZoomOut : inZoomIn;
ZoomIt(window, part);
break;
case pName:
if (DescToPString(data,name,kMaxStrSize) != noErr)
return(errAECoercionFail);
SetWTitle(window, name);
break;
case pPosition:
if (data->descriptorType != typeQDPoint)
{
propData.dataHandle = nil;
err = AECoerceDesc(data, typeQDPoint, &propData);
pt = *(Point *)*propData.dataHandle;
MyDisposeDescs(&propData, kEndOfList);
}
else
pt = *(Point *)*data->dataHandle;
if (!err)
{
// Real applications may want to make a sanity check on the new loc.
SetPort(window);
MoveWindow(window, pt.h, pt.v, false);
InvalRect(&window->portRect);
}
break;
case pVisible:
if (DescToBoolean(data,&value) != noErr)
return(errAECoercionFail); // Data cannot be coerced.
if (value)
ShowWindow(window);
else
HideWindow(window);
break;
default: // No other properties are modifiable.
return(errAENotModifiable);
}
SetPort(oldPort);
}
else
return(errAEEventFailed);
return(err);
}
//----------------------------------------------------------------------------------//
// This is a dummy handler that receives Apple events which I don't handle. It //
// is mainly provided as a stub in order to support all the events in the //
// required suite, as well as the entire core suite. This is the handler for the //
// Open Document and Print Document events (required suite); and the Save, Get //
// Class Info, and Get Event Info events (core suite). The Get Class Info and Get //
// Event Info events "MAY" be supported internally in the future, so applications //
// will not need to handle these events themselves. This support may be provided //
// since it would be consistent across all applications, and the information may //
// be retrieved from the 'aeut'/'aete' resources. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr DummyHandler( AppleEvent *theAppleEvent,
AppleEvent *reply,
long refCon )
{
#pragma unused (theAppleEvent,reply,refCon)
return(errAEEventNotHandled);
}
//----------------------------------------------------------------------------------//
// Locate the window that is relative to the specified window object at the //
// insertion position. If the location is replace, the window to replace is //
// closed, and its bounds are returned to the calling routine. //
// **Note**: if windowObj is used within this routine, the object param will //
// contain the same dataHandle. This will be disposed of by the calling routine. //
//----------------------------------------------------------------------------------//
#pragma segment Main
OSErr FindRelativeWindow( WindowPtr* relativeWindow, // window before insertion loc.
AEDesc* object, // object to be relative to.
DescType position, // insertion position.
WindowPtr* replaceWindow ) // window to replace.
{
AEDesc windowObj; // Coerced descriptor.
WindowPtr windowToReplace;
long index;
OSErr err;
err = noErr;
*replaceWindow = nil;
switch(position)
{
case kAEBeginning: // The object should be the container.
if (object->descriptorType == typeNull)
*relativeWindow = (WindowPtr)-1;
else
err = errAENoSuchObject;
break;
case kAEEnd: // The object should be the container.
if (object->descriptorType == typeNull)
*relativeWindow = nil;
else
err = errAENoSuchObject;
break;
case kAEBefore: // The object should be an object specifier.
case kAEReplace:
if (object->descriptorType != typeObjectSpecifier)
{
err = AECoerceDesc(object, typeObjectSpecifier, &windowObj);
MyDisposeDescs(object, kEndOfList);
object->descriptorType = windowObj.descriptorType;
object->dataHandle = windowObj.dataHandle;
}
if (!err)
if (windowToReplace = ResolveToWindow(object))
{
index = GetWindowIndexNum(windowToReplace);
*relativeWindow = (index==1) ? (WindowPtr)-1 : GetWindowAtIndex(index-1);
if (position == kAEReplace)
*replaceWindow = windowToReplace;
}
else // We weren't able to resolve the object specifier to a window.
err = errAENoSuchObject;
break;
case kAEAfter: // The object should be an object specifier.
if (object->descriptorType != typeObjectSpecifier)
{
err = AECoerceDesc(object,typeObjectSpecifier,&windowObj);
MyDisposeDescs(object, kEndOfList);
object->descriptorType = windowObj.descriptorType;
object->dataHandle = windowObj.dataHandle;
}
if (!err)
if (!(*relativeWindow = ResolveToWindow(object)))
err = errAENoSuchObject;
break;
default:
return(errAEEventNotHandled);
}
return(err);
}
//----------------------------------------------------------------------------------//
// Retrieves the data for the specified property of the window. The result token //
// contains the type of the data in the descriptorType field, and the data itself //
// in the dataHandle field. I know my application's window properties //
// (i.e., has title bar, has close box, is zoomable, etc.), so I set up the //
// result token accordingly. If your application handles various window types, //
// you may need to look at the window defproc to determine which type of window it //
// is. If the property is pBestType or pDefaultType, I return an object specifier//
// for the window which may be used to easily reference it. //
//----------------------------------------------------------------------------------//
#pragma segment Main
OSErr GetWindowData( DescType theProperty, // Window property.
WindowPtr window,
AEDesc *result ) // Contains the result upon return.
{
DescType theType;
Str255 title;
Rect bounds;
long index;
Boolean myAnswer;
switch (theProperty)
{
case pBestType:
case pDefaultType:
return(CreateWindowObjectSpec(window, kIndexKeyForm, result));
case pBounds:
bounds = (*((WindowPeek)window)->contRgn)->rgnBBox; // Use the content region.
return(AECreateDesc(typeQDRectangle, (Ptr)&bounds, sizeof(Rect), result));
case pClass:
theType = cWindow;
return(AECreateDesc(typeType, (Ptr)&theType, sizeof(DescType), result));
case pIndex:
index = GetWindowIndexNum(window);
return(AECreateDesc(typeLongInteger, (Ptr)&index, sizeof(long), result));
case pName:
GetWTitle(window, title);
return(AECreateDesc(typeChar, (Ptr)&title[1], title[0], result));
case pPosition:
bounds = (*((WindowPeek)window)->contRgn)->rgnBBox; // Use the content region.
return(AECreateDesc(typeQDPoint, (Ptr)&bounds, sizeof(Point), result));
case pHasCloseBox:
case pHasTitleBar:
case pIsResizable:
case pIsZoomable:
myAnswer = true;
return(AECreateDesc(typeBoolean, (Ptr)&myAnswer, sizeof(Boolean), result));
case pIsFloating:
case pIsModal:
myAnswer = false;
return(AECreateDesc(typeBoolean, (Ptr)&myAnswer, sizeof(Boolean), result));
case pIsZoomed:
myAnswer = GetWRefCon(window);
return(AECreateDesc(typeBoolean, (Ptr)&myAnswer, sizeof(Boolean), result));
case pVisible: // Must check this because it is modifiable.
myAnswer = ((WindowPeek)window)->visible;
return(AECreateDesc(typeBoolean, (Ptr)&myAnswer, sizeof(Boolean), result));
case pSelection: // No selection in CoreSample.
return(errAENoSuchObject);
default: // We don't handle requested property.
return(errAEEventNotHandled);
}
}
//----------------------------------------------------------------------------------//
// Get the property data for the application and return it in the result parameter.//
// The result token contains the property type in the descriptorType field, and //
// a nil value in the dataHandle field to represent the null application. //
//----------------------------------------------------------------------------------//
#pragma segment Main
OSErr GetAppData( DescType theProperty,
AEDesc* result ) // Descriptor record to hold the property data.
{
DescType theType;
short refNum;
Str255 name;
Handle myHandle;
ProcessSerialNumber thePSN;
Boolean isFront;
OSErr err;
switch (theProperty)
{
case pBestType: // Return the null descriptor representing
case pDefaultType: // the application.
return(AEDuplicateDesc(&gNullDesc, result));
case pClass:
theType = cApplication;
return(AECreateDesc(typeType,(Ptr)&theType,sizeof(DescType),result));
case pName:
GetAppParms(name, &refNum, &myHandle);
return(AECreateDesc(typeChar, (Ptr)&name[1], name[0], result));
case pIsFrontProcess:
GetFrontProcess(&thePSN);
SameProcess(&gSelfPSN, &thePSN, &isFront);
return(AECreateDesc(typeBoolean,(Ptr)&isFront,sizeof(Boolean),result));
case pVersion:
refNum = CurResFile(); // save current resource
UseResFile(gRefNum); // set this resource to be current
myHandle = (Handle)Get1Resource((ResType)'vers', 1);
HLock(myHandle);
err = AECreateDesc(typeVersion, *myHandle, GetHandleSize(myHandle), result);
HUnlock(myHandle);
UseResFile(refNum); // reset back to resource previously set
return(err);
default: // We don't handle the requested property.
return(errAEEventNotHandled);
}
}
//----------------------------------------------------------------------------------//
// Create an object specifier for the window with the indicated key form. //
//----------------------------------------------------------------------------------//
#pragma segment Main
OSErr CreateWindowObjectSpec( WindowPtr window,
short keyForm, // index or name key form.
AEDesc* objectSpec ) // Resulting object specifier.
{
AEDesc data;
Str255 title;
long index;
OSErr err;
MyInitDescs(&data, kEndOfList);
switch(keyForm)
{
case kNameKeyForm: // Object specifier with name.
GetWTitle(window, title);
if (!(err = AECreateDesc(typeChar, (Ptr)&title[1], title[0], &data)))
err = CreateObjSpecifier(cWindow, &gNullDesc, formName, &data,
false, objectSpec);
break;
case kIndexKeyForm: // Object specifier with index.
index = GetWindowIndexNum(window);
if (!(err = CreateOffsetDescriptor(index, &data)))
err = CreateObjSpecifier(cWindow, &gNullDesc, formAbsolutePosition, &data,
false, objectSpec);
break;
}
MyDisposeDescs(&data, kEndOfList);
return(err);
}
//----------------------------------------------------------------------------------//
// Check to see if there exists any additional parameters in the Apple Event. //
// If so, return an error to the calling routine. //
//----------------------------------------------------------------------------------//
#pragma segment Main
OSErr GetMissingParams(AppleEvent* theAppleEvent)
{
DescType theType;
Size actualSize;
OSErr err;
err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
&theType, nil, 0, &actualSize);
if (err == errAEDescNotFound)
return(noErr);
else
return(errAEEventNotHandled);
}
//----------------------------------------------------------------------------------//
// If a reply is expected, the error number is returned in the reply parameter. //
//----------------------------------------------------------------------------------//
#pragma segment Main
void ReportError( AppleEvent* reply,
long err )
{
if (reply->dataHandle != nil && err != noErr)
FailIfErr(AEPutParamPtr(reply,keyErrorNumber,typeLongInteger,(Ptr)&err,sizeof(long)));
}
//----------------------------------------------------------------------------------//
// This routine returns the window object contained in the given object specifier. //
// If the resolution does not return a descriptor record of type cWindow, nil is //
// returned as a result. //
//----------------------------------------------------------------------------------//
#pragma segment Main
WindowPtr ResolveToWindow(AEDesc* objectSpecifier)
{
AEDesc token;
WindowPtr window;
MyInitDescs(&token, kEndOfList);
window = nil;
if (objectSpecifier->descriptorType == typeObjectSpecifier)
if (!(AEResolve(objectSpecifier, kAEIDoMinimum, &token)))
if (token.descriptorType == cWindow)
window = (WindowPtr)*((LongPtr)*(token.dataHandle));
MyDisposeDescs(&token, kEndOfList);
return(window);
}
//----------------------------------------------------------------------------------//
// Retrieve the window from the null container by the key form and return its //
// pointer in the dataHandle field of resultToken. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr WindowAccessor( DescType classWanted, // window class
AEDesc* container, // the application (null container)
DescType containerClass,
DescType keyform,
AEDesc* selectionData,
AEDesc* resultToken, // specified window is returned in result
long theRefCon )
{
#pragma unused (classWanted,container,containerClass,theRefCon)
WindowPtr window;
DescType seldataType;
Str255 title;
long index;
OSErr err;
window = nil;
err = noErr;
if (!gNumWindowsOpen)
return(errAENoSuchObject);
else
{
seldataType = selectionData->descriptorType;
switch(keyform)
{
case formName: // Window title.
if (DescToPString(selectionData,title,kMaxStrSize) != noErr)
return(errAECoercionFail);
if (!(window = GetWindowWithTitle(title)))
return(errAENoSuchObject); // Window was not found.
break;
case formAbsolutePosition:
if (DescToLong(selectionData,&index) != noErr)
return(errAECoercionFail); // Data cannot be coerced.
if (!(window = GetWindowAtIndex(index)))
return(errAENoSuchObject); // Window was not found.
break;
default: // I don't handle any other key forms.
return(errAEEventNotHandled);
}
}
return(AECreateDesc(cWindow, (Ptr)&window, sizeof(Ptr), resultToken));
}
//----------------------------------------------------------------------------------//
// Return a token representing the property for the containing window. The token //
// is returned with the property and window pointer. //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr WindowPropertyAccessor( DescType classWanted, // Property class
AEDesc* container, // Window object
DescType containerClass,
DescType form,
AEDesc* selectionData,
AEDesc* resultToken,
long theRefCon )
{
#pragma unused (containerClass, theRefCon)
Ptr window;
DescType propType;
// Let's make sure we're accessing a valid descriptor type.
if ((classWanted != cProperty) || (form != formPropertyID))
return(errAEWrongDataType);
window = (Ptr)*(LongPtr)*(container->dataHandle); // Get the window pointer.
propType = *(LongPtr)*selectionData->dataHandle; // Get the property type.
return(AECreateDesc(propType, (Ptr)&window, sizeof(Ptr), resultToken));
}
//----------------------------------------------------------------------------------//
// Return a token that contains the property type and nil to represent the null //
// container (the application). //
//----------------------------------------------------------------------------------//
#pragma segment Main
pascal
OSErr AppPropertyAccessor( DescType classWanted, // Property class.
AEDesc* container, // Application.
DescType containerClass,
DescType form,
AEDesc* selectionData,
AEDesc* resultToken,
long theRefCon )
{
#pragma unused (container,containerClass,theRefCon)
DescType propType;
long nilValue;
// Let's make sure we're accessing a valid descriptor type.
if ((classWanted != cProperty) || (form != formPropertyID))
return(errAEWrongDataType);
nilValue = nil;
propType = *(LongPtr)*selectionData->dataHandle; // Get the property type.
return(AECreateDesc(propType, (Ptr)&nilValue, sizeof(long), resultToken));
}
//----------------------------------------------------------------------------------//
// Returns the window with the given title if found. Otherwise, nil is returned. //
// Use WindowList in order to find windows that may be invisible. //
//----------------------------------------------------------------------------------//
#pragma segment Main
WindowPtr GetWindowWithTitle( ConstStr255Param titleToFind )
{
WindowPeek window;
Str255 thisTitle;
window = *(PeekPtr)WindowList; // WindowList finds invisible windows as well.
while (window)
{
GetWTitle((WindowPtr)window, thisTitle);
if (EqualString(thisTitle, titleToFind, false, false))
return((WindowPtr)window);
window = window->nextWindow;
}
return(nil);
}
//----------------------------------------------------------------------------------//
// Search all windows (including invisible), and return the window at the given //
// index if found. Otherwise, nil is returned. This routine also handles negative //
// indices which indicates that the offset is from the end of the container. // //
//----------------------------------------------------------------------------------//
#pragma segment Main
WindowPtr GetWindowAtIndex(long index)
{
WindowPeek window;
short count;
index = index < 0 ? gNumWindowsOpen+index+1 : index;
count = 1;
window = *(PeekPtr)WindowList; // WindowList contains ALL windows.
while (window)
{
if (count == index)
return((WindowPtr)window);
window = window->nextWindow;
count++;
}
return(nil);
}
//----------------------------------------------------------------------------------//
// Returns the index number of the given window, where 1 is the frontmost. //
//----------------------------------------------------------------------------------//
#pragma segment Main
long GetWindowIndexNum(WindowPtr myWindow)
{
WindowPeek thisWindow;
long index;
thisWindow = *(PeekPtr)WindowList;
index = 1;
while (thisWindow)
{
if (thisWindow == myWindow)
return(index);
thisWindow = thisWindow->nextWindow;
index++;
}
return(nil);
}
//----------------------------------------------------------------------------------//
#pragma segment Initialize
void InitAEHandlers()
{
AEInstallEventHandler(kCoreEventClass,kAEOpenApplication,(EventHandlerProcPtr)HandleOpenApp,nil,false);
AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,(EventHandlerProcPtr)DummyHandler,nil,false);
AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments,(EventHandlerProcPtr)DummyHandler,nil,false);
AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, (EventHandlerProcPtr)HandleQuitApp, nil, false);
AEInstallEventHandler(kAECoreSuite, kAEClone, (EventHandlerProcPtr)HandleClone, nil, false);
AEInstallEventHandler(kAECoreSuite, kAEClose, (EventHandlerProcPtr)HandleClose, nil, false);
AEInstallEventHandler(kAECoreSuite, kAECountElements, (EventHandlerProcPtr)HandleCountElements, nil, false);
AEInstallEventHandler(kAECoreSuite, kAECreateElement, (EventHandlerProcPtr)HandleCreateElement, nil, false);
AEInstallEventHandler(kAECoreSuite, kAEDelete, (EventHandlerProcPtr)HandleClose, nil, false);
AEInstallEventHandler(kAECoreSuite, kAEDoObjectsExist, (EventHandlerProcPtr)HandleDoObjectsExist, nil, false);
AEInstallEventHandler(kAECoreSuite, kAEGetData, (EventHandlerProcPtr)HandleGetData, kAEGetData, false);
AEInstallEventHandler(kAECoreSuite, kAEGetDataSize, (EventHandlerProcPtr)HandleGetData, kAEGetDataSize, false);
AEInstallEventHandler(kAECoreSuite, kAEGetClassInfo, (EventHandlerProcPtr)DummyHandler, nil, false);
AEInstallEventHandler(kAECoreSuite, kAEGetEventInfo, (EventHandlerProcPtr)DummyHandler, nil, false);
AEInstallEventHandler(kAECoreSuite, kAEMove, (EventHandlerProcPtr)HandleMove, nil, false);
AEInstallEventHandler(kAECoreSuite, kAESave, (EventHandlerProcPtr)DummyHandler, nil, false);
AEInstallEventHandler(kAECoreSuite, kAESetData, (EventHandlerProcPtr)HandleSetData, nil, false);
AEObjectInit();
AEInstallObjectAccessor(cWindow, typeNull, (accessorProcPtr)WindowAccessor, nil, false);
AEInstallObjectAccessor(cProperty, typeNull, (accessorProcPtr)AppPropertyAccessor, nil, false);
AEInstallObjectAccessor(cProperty, cWindow, (accessorProcPtr)WindowPropertyAccessor, nil, false);
}