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.
ProjectBuilder (OS X)/SuspendEvent.c
/* |
File: SuspendEvent.c |
Contains: A simple example of suspending and resuming an AppleEvent |
Written by: C.K. Haun |
Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Change History (most recent first): |
8/2003 MK Updated for Project Builder |
7/21/1999 KG Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include "SuspendEvent.h" |
/* prototypes */ |
void InitalizeApp(void); |
void DrawMain(WindowPtr drawIt); |
Boolean DoSelected(long val); |
void SizeMain(WindowPtr theWindow); |
void InitAEStuff(void); |
void DoHighLevel(EventRecord *AERecord); |
void DoDocumentClick(WindowPtr theWindow); |
OSErr modfiedProcessOpenPrint(const AppleEvent *messagein, AppleEvent *theReply, Boolean printIt); |
static pascal OSErr AEOpenHandler(const AppleEvent *messagein, AppleEvent *reply, SInt32 refIn); |
static pascal OSErr AEOpenDocHandler(const AppleEvent *messagein, AppleEvent *reply, SInt32 refIn); |
static pascal OSErr AEPrintHandler(const AppleEvent *messagein, AppleEvent *reply, SInt32 refIn); |
static pascal OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, SInt32 refIn); |
void SampleHelpDialog(void); |
void CloseMyWindow(WindowPtr twindow); |
WindowPtr AddNewWindow(short theID); |
void InvalAll(void); |
void NilProc(void); |
/* one external */ |
extern void _DataInit(); /* this is the C initialization code */ |
/* globals */ |
Boolean gQuit, gInBackground; |
unsigned long gMySleep; |
ProcessSerialNumber gOurSN; |
short gHelpItem; |
/* globals for event suspension */ |
Boolean eventIsPending; |
AEDesc theSuspEvent, theSuspReply; |
#pragma segment Main |
int main() |
{ |
EventRecord myEventRecord; |
WindowPtr twindow; |
short fHit; |
windowCHandle tempWCH; |
BitMap* bitMap; |
InitalizeApp(); |
do { |
WaitNextEvent(everyEvent, &myEventRecord, gMySleep, nil); |
switch (myEventRecord.what) { |
case nullEvent: |
/* no nul processing in this sample */ |
break; |
case updateEvt: |
/* always check to see if it's my window */ |
/* this may not seem necessary under 7.0, where it's unlikely or impossible for */ |
/* a DA to be in your layer, but there are others */ |
/* who can stick themselves into your window list, */ |
/* BalloonWriter comes quickly to mind */ |
if (GetWindowKind( (WindowRef) myEventRecord.message ) == kMyDocumentWindow) { |
tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message); |
if (tempWCH){ |
DrawMain( (WindowPtr)myEventRecord.message ); |
} |
} |
break; |
case mouseDown: |
/* first see where the hit was */ |
fHit = FindWindow(myEventRecord.where, &twindow); |
switch (fHit) { |
Rect limitRect; |
Str255 tempString; |
long back; |
case inDesk: /* if they hit in desk, then the process manager */ |
break; /* will switch us out, we don't need to do anything */ |
case inMenuBar: |
DoSelected(MenuSelect(myEventRecord.where)); |
break; |
case inSysWindow: |
/* pass to the system */ |
break; |
case inContent: |
/* Handle content and control clicks here */ |
if (FrontWindow()) { /* don't do this unless we have a window open, silly */ |
if (FrontWindow() == twindow && GetWindowKind( twindow ) == kMyDocumentWindow) { |
windowCHandle clicker; |
clicker = (windowCHandle)GetWRefCon(twindow); |
/* jump to the content function stored for this window */ |
HLock((Handle)clicker); /* lock it down so things don't get stupid */ |
DoDocumentClick( twindow ); |
HUnlock((Handle)clicker); /* all done */ |
} else { |
SelectWindow(twindow); /* select the window */ |
SetPort( GetWindowPort( twindow ) ); |
} |
} |
break; |
case inDrag: |
bitMap = GetQDGlobalsScreenBits( bitMap ); |
DragWindow(twindow, myEventRecord.where, &bitMap->bounds); |
break; |
case inGrow: |
/* Call GrowWindow here if you have a grow box */ |
SetPort( GetWindowPort( twindow ) ); |
limitRect = bitMap->bounds; |
limitRect.top = kMinHeight; |
GetWTitle(twindow, tempString); |
/* I'm not letting the user shrink the window so */ |
/* small that the title is truncated */ |
limitRect.left = StringWidth(tempString) + 120; |
back = GrowWindow(twindow, myEventRecord.where, &limitRect); |
if (back) { |
Rect sizeRect; |
GetWindowPortBounds(twindow, &sizeRect); |
InvalWindowRect(twindow, &sizeRect); |
sizeRect.top = sizeRect.bottom - 16; |
sizeRect.left = sizeRect.right - 16; |
EraseRect(&sizeRect); |
InvalWindowRect(twindow, &sizeRect); |
SizeWindow(twindow, back & 0xffff, back >> 16, true); |
SizeMain( twindow ); |
} |
InvalWindowRect(twindow, GetWindowPortBounds(twindow, NULL) ); |
break; |
case inGoAway: |
/* Click in Close box */ |
if (TrackGoAway(twindow, myEventRecord.where)){ |
CloseMyWindow( twindow ); |
} |
break; |
case inZoomIn: |
case inZoomOut: |
if (TrackBox(twindow, myEventRecord.where, fHit)) { |
SetPort( GetWindowPort( twindow ) ); |
ZoomWindow(twindow, fHit, true); |
InvalWindowRect(twindow, GetWindowPortBounds(twindow, NULL)); |
SizeMain( twindow ); |
} |
} |
case mouseUp: |
/* don't care */ |
break; |
/* same action for key or auto key */ |
case keyDown: |
case autoKey: |
if (myEventRecord.modifiers & cmdKey) |
DoSelected(MenuKey(myEventRecord.message & charCodeMask)); |
break; |
case keyUp: |
/* don't care */ |
break; |
case activateEvt: |
if (myEventRecord.modifiers & activeFlag) { |
tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message); |
DrawMain( (WindowPtr)myEventRecord.message ); |
} |
break; |
case networkEvt: |
/* don't care */ |
break; |
case driverEvt: |
/* don't care */ |
break; |
case app4Evt: |
switch ((myEventRecord.message >> 24) & 0x0FF) { /* high byte of message */ |
case suspendResumeMessage: /* suspend/resume is also an activate/deactivate */ |
gInBackground = (myEventRecord.message & kResumeMask) == 0; |
if (gInBackground) { |
/* nothing for going in the background in this sample */ |
} else { |
/* make sure the cursor is an arrow when we come forward */ |
InitCursor(); |
} |
break; |
} |
break; |
default: |
break; |
/* This dispatches high level events (AppleEvents, for example) */ |
/* to our dispatch routine. This is NEW in the event loop for */ |
/* System 7 */ |
case kHighLevelEvent: |
DoHighLevel(&myEventRecord); |
break; |
} |
} |
while (gQuit != true); |
return 0; |
} |
/* draws my window. Pretty simple */ |
void DrawMain(WindowPtr drawIt) |
{ |
RgnHandle tempRgn; |
short oldSize = GetPortTextSize( GetWindowPort( drawIt ) ); |
Rect scratchRect; |
BeginUpdate(drawIt); |
SetPort( GetWindowPort( drawIt ) ); |
GetWindowPortBounds(drawIt, &scratchRect); |
EraseRect( &scratchRect ); |
/* tell folks if an event has been suspendered */ |
if (eventIsPending) { |
Str255 tempString; |
MoveTo(10, 40); |
TextFace(bold); |
TextSize(24); |
GetIndString(tempString, kGeneralStrings, kPendingWords1); |
DrawString(tempString); |
GetIndString(tempString, kGeneralStrings, kPendingWords2); |
MoveTo(10, 80); |
DrawString(tempString); |
TextSize(oldSize); |
TextFace(normal); |
} |
GetWindowPortBounds(drawIt, &scratchRect); |
scratchRect.top = scratchRect.bottom - 15; |
scratchRect.left = scratchRect.right - 15; |
tempRgn = NewRgn(); |
GetClip(tempRgn); |
ClipRect(&scratchRect); |
DrawGrowIcon(drawIt); |
SetClip(tempRgn); |
DisposeRgn(tempRgn); |
EndUpdate(drawIt); |
} |
void CloseMyWindow(WindowPtr twindow) |
{ |
DisposeWindow(twindow); |
} |
/* my menu action taker. It returns a Boolean which I usually ignore, but it */ |
/* mught be handy someday */ |
/* Actually, I've been returning that Boolean for 7 years, and */ |
/* never used it, but Who Knows? */ |
/* I usually use it in an application to determine if a keystroke was accepted */ |
/* by a menu or whether it should be passed along to any other key acceptors */ |
Boolean DoSelected(long val) |
{ |
short loval, hival; |
Boolean returnVal = false; |
loval = LoWord(val); |
hival = HiWord(val); |
switch (hival) { /* switch off the menu number selected */ |
case kAppleMenu: /* Apple menu */ |
Alert(kAboutBox, nil); /* do about box */ |
returnVal = true; |
break; |
case kFileMenu: /* File menu */ |
switch (loval) { |
case kQuitItem: |
gQuit = true; /* only item */ |
returnVal = true; |
break; |
default: |
break; |
} |
break; |
case kEditMenu: |
/* edit menu junk */ |
/* don't care */ |
switch (loval) { |
default: |
break; |
} |
break; |
case kToolsMenu: |
/* add all your test stuff here */ |
switch (loval) { |
default: |
break; |
} |
break; |
case kHMHelpMenuID: /* Defined in Balloons.h */ |
/* I only care about this item. If anything else is returned here, I don't know what */ |
/* it is, so I leave it alone. Remember, the Help Manager chapter says that */ |
/* Apple reserves the right to add and change things in the Help menu */ |
if (loval == gHelpItem) |
SampleHelpDialog(); |
break; |
} |
HiliteMenu(0); |
return(returnVal); |
} |
void DoDocumentClick(WindowPtr theWindow) |
{ |
#pragma unused (theWindow) |
/* look to see if an event is pending, if so resume the event */ |
if (eventIsPending) { |
/* restart the event */ |
AEResumeTheCurrentEvent(&theSuspEvent, &theSuspReply, (AEEventHandlerUPP)kAEUseStandardDispatch, 0); |
/* kAEUseStandardDispatch means re-enter the handler from the top. */ |
/* You're other option to pass here is kAENoDispatch, which tells the */ |
/* AppleEvent manager that this event is FINISHED, clean up memory */ |
/* and don't re-dspatch. */ |
} |
} |
#pragma segment Initialize |
/* InitAEStuff installs my appleevent handlers */ |
void InitAEStuff(void) |
{ |
OSErr aevtErr = noErr; |
long aLong = 0; |
Boolean gHasAppleEvents = false; |
/* Check this machine for AppleEvents. If they are not here (ie not 7.0) |
* then we exit */ |
gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr); |
/* The following series of calls installs all our AppleEvent Handlers. |
* These handlers are added to the application event handler list that |
* the AppleEvent manager maintains. So, whenever an AppleEvent happens |
* and we call AEProcessEvent, the AppleEvent manager will check our |
* list of handlers and dispatch to it if there is one. |
*/ |
if (gHasAppleEvents) { |
aevtErr = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, |
NewAEEventHandlerUPP(AEOpenHandler),0, false); |
if (aevtErr) ExitToShell(); |
aevtErr = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, |
NewAEEventHandlerUPP(AEOpenDocHandler),0, false); |
if (aevtErr) ExitToShell(); |
aevtErr = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, |
NewAEEventHandlerUPP(AEQuitHandler), 0, false); |
if (aevtErr) ExitToShell(); |
aevtErr = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, |
NewAEEventHandlerUPP(AEPrintHandler),0, false); |
if (aevtErr) ExitToShell(); |
} |
else ExitToShell(); |
} |
/* end InitAEStuff */ |
#pragma segment Main |
/* I'm not doing error handling in this sample for clarities sake, you should. Hah, */ |
/* easy for me to say, huh? */ |
void DoHighLevel(EventRecord *AERecord) |
{ |
OSErr myErr; |
myErr = AEProcessAppleEvent(AERecord); |
} |
/* end DoHighLevel */ |
/* This is the standard Open Application event. */ |
static pascal OSErr AEOpenHandler(const AppleEvent *messagein, AppleEvent *reply, SInt32 refIn) |
{ |
WindowPtr myWindow; |
#pragma unused (messagein,reply,refIn) |
/* we of course don't do anything here in this simple app */ |
/* except open our window */ |
myWindow = AddNewWindow(kDocWindowResID); |
return(noErr); |
} |
/* end AEOpenHandler */ |
/* Open Doc, opens our documents. Remember, this can happen at application start AND */ |
/* anytime else. If your app is up and running and the user goes to the desktop, hilites one */ |
/* of your files, and double-clicks or selects Open from the finder File menu this event */ |
/* handler will get called. Which means you don't do any initialization of globals here, or */ |
/* anything else except open then doc. */ |
/* SO-- Do NOT assume that you are at app start time in this */ |
/* routine, or bad things will surely happen to you. */ |
static pascal OSErr AEOpenDocHandler(const AppleEvent *messagein, AppleEvent *reply, SInt32 refIn) |
{ |
#pragma unused (refIn) |
return(modfiedProcessOpenPrint(messagein, reply, false)); |
} |
static pascal OSErr AEPrintHandler(const AppleEvent *messagein, AppleEvent *reply, SInt32 refIn) |
{ /* no printing handler in yet, so we'll ignore this */ |
/* the operation is functionally identical to the ODOC event, with the additon */ |
/* of calling your print routine. */ |
#pragma unused (refIn) |
return(modfiedProcessOpenPrint(messagein, reply, true)); |
} |
/* Standard Quit event handler, to handle a Quit event from the Finder, for example. */ |
/* ¥¥¥¥¥ DO NOT CALL EXITTOSHELL HERE ¥¥¥¥¥ or you will never have a happy life. */ |
/* OK, it's a few months after I wrote that comment, and I've seen a lot of code */ |
/* come through DTS that calls ExitToShell from quit handlers. Let me explain... */ |
/* When an AppleEvent Handler is called (like this quit handler) you are ALMOST */ |
/* 100% in your application world. A5 is right, you can call any toolbox function, */ |
/* you can call your own routines, everything _seems_ like you are in complete */ |
/* control. Well, almost but not quite. The routine has been dispatch to from the */ |
/* AppleEvent Manager's space, so you _must_ return to that at some point! */ |
/* Which is why you can't call ETS from here. When you call ExitToShell from an */ |
/* AE Handler, the most likely thing that happens is the FInder quits, and your */ |
/* application keeps running. Which ain't what you want, y'know? */ |
/* so, DON'T CALL EXITTOSHELL FROM AN APPLEEVENT HANDLER!!!!!!!!!!!!!! */ |
/* Any of 'em, not just a quit handler. Just don't do it. */ |
/* This comment keeps getting longer because people keep doing it STOP IT! */ |
static pascal OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, SInt32 refIn) |
{ |
#pragma unused (messagein,refIn,reply) |
gQuit = true; |
return(noErr); |
} |
/* This is my sample help dialog. Does not do anything, expand as you need */ |
void SampleHelpDialog(void) |
{ |
DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1); |
short itemhit = 0; |
while (itemhit != 1) { |
ModalDialog(nil, &itemhit); |
} |
DisposeDialog(tdial); |
} |
#pragma segment Initialize |
void InitalizeApp(void) |
{ |
MenuHandle helpHandle; |
StringHandle helpString; |
short count; |
InitCursor(); |
InitAEStuff(); |
/* set up my menu junk */ |
SetMenuBar(GetNewMBar(kMBarID)); |
AppendResMenu(GetMenuHandle(kAppleMenu), 'DRVR'); |
/* now install my Help menu item in the Help Manager's menu */ |
HMGetHelpMenu(&helpHandle, NULL); /* Get the Hlpe menu handle */ |
count = CountMenuItems(helpHandle); /* How many items are there? */ |
helpString = GetString(kHelpString); /* get my help string */ |
DetachResource((Handle)helpString); /* detach it */ |
HNoPurge((Handle)helpString); |
MoveHHi((Handle)helpString); |
HLock((Handle)helpString); |
InsertMenuItem(helpHandle,*helpString, count + 1); /* insert my item in the Help menu */ |
gHelpItem = CountMenuItems(helpHandle); /* The number of the item */ |
DrawMenuBar(); |
GetCurrentProcess(&gOurSN); /* Get our process serial number for later use, if needed */ |
} |
#pragma segment Main |
WindowPtr AddNewWindow(short theID) |
{ |
windowCHandle setControls; |
WindowPtr tempWP; |
tempWP = GetNewWindow(theID, 0, (WindowPtr)-1); /* get a new window */ |
SetWindowKind(tempWP, kMyDocumentWindow); /* mark it as my document window */ |
setControls = (windowCHandle)NewHandleClear(sizeof(windowControl)); /* add our control structure to it */ |
SetWRefCon(tempWP, (long)setControls); /* stop stuffing refCon directly <ckh 1.0.3> */ |
HLock((Handle)setControls); /* lock it down while we fill it*/ |
/* add pointers to our procedures for drawing, saving, and closing */ |
/* This way, all I need is one dispatch point for drawing, closing */ |
/* or whatever, I don't have to case off the window kind to go to the */ |
/* correct routine. Kinda like object-oriented programming, but I won't */ |
/* admit that. */ |
(*setControls)->drawMe = (ProcPtr)DrawMain; |
(*setControls)->clickMe = (ProcPtr)DoDocumentClick; |
(*setControls)->sizeMe = (ProcPtr)SizeMain; |
(*setControls)->closeMe = (ProcPtr)CloseMyWindow; |
(*setControls)->generalData = NewHandle(0); |
return(tempWP); |
} |
void SizeMain(WindowPtr theWindow) |
{ |
WindowPtr tempWP; |
Rect* bounds; |
GetWindowPortBounds(tempWP, bounds); |
InvalWindowRect(theWindow, bounds); |
SetPort( GetWindowPort( tempWP ) ); |
} |
void NilProc(void) |
{ |
} |
/* modfiedProcessOpenPrint handles ODOC and PDOC events. Both events open a document, one prints it */ |
/* This one is modified to suspend any event that opens or prints an kAlDocType document */ |
/* do NOT use this as is in your app! */ |
OSErr modfiedProcessOpenPrint(const AppleEvent *messagein, AppleEvent *theReply, Boolean printIt) |
{ |
#pragma unused(printIt) |
OSErr err = noErr; |
AEDesc theDesc; |
FSSpec theFSS; |
short loopy; |
long numFilesToOpen; |
AEKeyword ignoredKeyWord; |
DescType ignoredType; |
Size ignoredSize; |
FInfo fileInfo; |
Boolean DoSuspend = false; |
err = AEGetParamDesc(messagein, keyDirectObject, typeAEList, &theDesc); |
err |= AECountItems(&theDesc, &numFilesToOpen); |
if (!err) { |
for (loopy = 1; ((loopy <= numFilesToOpen) && (!err)); ++loopy) { |
err = AEGetNthPtr(&theDesc, loopy, typeFSS, &ignoredKeyWord, &ignoredType, (Ptr)&theFSS, sizeof(theFSS), |
&ignoredSize); |
if (err == noErr) { |
FSpGetFInfo(&theFSS, &fileInfo); |
/* make sure it's a data file */ |
/* and if this was called for an eventPend, don't reopen the kFredDocType docs */ |
if (fileInfo.fdCreator == kSuspCreator && fileInfo.fdType == kFredDocType && !eventIsPending) { |
WindowPtr newW = AddNewWindow(kDocWindowResID); |
if (newW) { |
SetWTitle(newW, theFSS.name); |
} |
} else { |
/* here we see if it's an kAlDocType file. If it is, we either ignore it */ |
/* if its not from the resume, or we process it */ |
if (fileInfo.fdCreator == kSuspCreator && fileInfo.fdType == kAlDocType) { |
if (eventIsPending) { |
WindowPtr newW = AddNewWindow(kDocWindowResID); |
if (newW) { |
SetWTitle(newW, theFSS.name); |
} |
} else { |
/* if there is not an event pending, then this is is an Al file */ |
/* from launch, tell ourselves that there is a reason to suspend */ |
DoSuspend = true; |
} |
} |
} |
} |
} /* for loopy = ... */ |
} |
AEDisposeDesc(&theDesc); |
/* determine if this is the first pass, then we should suspend. If not, */ |
/* we press on */ |
if (eventIsPending) { |
/* clear it and life is back to normal */ |
eventIsPending = false; |
} else { |
/* first pass, no kAlDocType files have been opened, suspend the event and set the */ |
/* flag. */ |
/* Only if an kAlDocType file was passed at all, which is the DoSuspend flag. */ |
if (DoSuspend) { |
eventIsPending = true; |
AESuspendTheCurrentEvent(messagein); |
theSuspEvent = *messagein; |
theSuspReply = *theReply; |
} |
} |
InvalAll(); |
return(err); |
} |
void InvalAll(void) |
{ |
WindowRef nowFront; |
WindowRef oldPort; |
Rect bounds; |
nowFront = GetFrontWindowOfClass(kDocumentWindowClass, true); |
oldPort = nowFront; |
while (nowFront) { |
if (IsWindowVisible( nowFront )) { |
SetPort( GetWindowPort( nowFront ) ); |
GetWindowPortBounds(nowFront, &bounds); |
InvalWindowRect(nowFront, &bounds); |
} |
nowFront = GetNextWindowOfClass(nowFront, kDocumentWindowClass, true); |
} |
SetPort( GetWindowPort( oldPort ) ); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-10-14