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.
GrowToGrid.c
/* |
File: GrowToGrid.c |
Contains: This snippet shows how to grow a window constrained to a grid (i.e. |
only allow a window to grow or shrink by 30 pixels, or whatever). |
Now, you might think that using something like DragHook (see the Window |
Manager documentation) would be the best way to approach this. Well, I |
personally don't think so, and a lot of my pragmatic (i.e. those who |
like to ship products instead of talking about them) friends agree. The |
easiest way to do this is just to write a small MyGrowWIndow function |
and use that. |
Or, even better, just grab this one demonstrated here, and you're even more |
pragmatic than I! |
Written by: C.K. Haun |
Copyright: Copyright © 1994-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
8/6/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include <fonts.h> |
#include <dialogs.h> |
#include <Desk.h> |
#include <diskinit.h> |
#include <resources.h> |
#include <toolutils.h> |
#include <GestaltEqu.h> |
#include <Balloons.h> |
#include <SegLoad.h> |
#include <TextUtils.h> |
#define kExtremeNeg -32768 |
#define kExtremePos (32767 - 1) /* required to address an old region bug, see develop 20 Q&As */ |
/* prototypes */ |
void DrawIndString(short resID,short index); |
void MyGrowWindow(WindowPtr theWindow); |
void InitalizeApp(void); |
void DoDiskEvents(long dinfo); /* hi word is error code, lo word is drive number */ |
void DrawMain(WindowPtr drawIt); |
Boolean DoSelected(long val); |
void SizeMain(WindowPtr theWindow); |
void InitAEStuff(void); |
void DoHighLevel(EventRecord *AERecord); |
void DoDaCall(MenuHandle themenu, long theit); |
void DoDocumentClick(WindowPtr theWindow); |
void DoGridDialog(void); |
ControlHandle SnatchHandle(DialogPtr thebox, short theGetItem); |
pascal OSErr AEOpenHandler(const AppleEvent *messagein, AppleEvent *reply, unsigned long refIn); |
pascal OSErr AEOpenDocHandler(const AppleEvent *messagein, AppleEvent *reply, unsigned long refIn); |
pascal OSErr AEPrintHandler(const AppleEvent *messagein, AppleEvent *reply, unsigned long refIn); |
pascal OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, unsigned long refIn); |
void SampleHelpDialog(void); |
WindowPtr AddNewWindow(short theID); |
WindowPtr FindWindowByKind(short kindToFind); |
void PullRect (Rect *someRect); |
void NilProc(void); |
/* one external */ |
#ifdef applec |
extern void _DataInit(); /* this is the C initialization code */ |
#endif |
/* defines and enums */ |
/* windows */ |
enum { |
kDocumentWindow = 1000, kDocWindow = 128 |
}; |
/* menu enums */ |
enum { |
kMBarID = 128, kAppleMenu = 128, kFileMenu = 129, kEditMenu = 130, kToolsMenu = 131 |
}; |
enum { |
kResumeMask = 1, /* bit of message field for resume vs. suspend */ |
kHelpString = 128 |
}; |
/* file menu enums */ |
enum { |
kNewItem = 1, kOpenItem, kCloseItem, kSaveItem, kSaveAsItem, kFileBlank1, kPageSetupItem, kPrintItem, kFileBlank2, kQuitItem |
}; |
enum { |
kGridDialogItem = 1 |
}; |
/* alerts and dialogs */ |
enum { |
kBadSystem = 130, kSampHelp = 129, kAboutBox = 128, kGridDialog = 131 |
}; |
enum { |
kGridDialogMenuItem = 1, kGridEditLine = 4 |
}; |
enum { |
kMinHeight = 200 |
}; |
enum {kGenStrings = 128,kSayCurrentGrid=1,kSayChangeGrid |
}; |
#define ABS(A) ((A < 0) ? (A*-1):A) |
/* structs */ |
struct AEinstalls { |
AEEventClass theClass; |
AEEventID theEvent; |
AEEventHandlerProcPtr theProc; |
}; |
typedef struct AEinstalls AEinstalls; |
/* windowControl is the structure attached to every window I create (in the refCon */ |
/* field) that contains all the information I need to know about the window. */ |
/* this one is really simple */ |
struct windowControl { |
unsigned long windowID; /* master ID number for section recording */ |
ProcPtr drawMe; /* content drawing procedure pointer */ |
ProcPtr clickMe; /* content click routine */ |
ProcPtr saveMe; /* document save procedure pointer */ |
ProcPtr closeMe; /* document close procedure pointer */ |
ProcPtr sizeMe; |
AliasHandle fileAliasHandle; /* alias for this document */ |
Boolean windowDirty; |
long windowIndex; /* for AppleEvent information */ |
}; |
typedef struct windowControl windowControl, *windowCPtr, **windowCHandle; |
/* globals */ |
Boolean gQuit, gInBackground; |
Boolean dragIn; |
EventRecord gERecord; |
ProcessSerialNumber gOurSN; |
short gHelpItem; |
short gGridIncrement = 30; // start at 30 |
#pragma segment Main |
void main() |
{ |
WindowPtr twindow; |
short fHit; |
windowCHandle tempWCH; |
#ifdef applec |
UnloadSeg((Ptr)_DataInit); /* throw out C setup code */ |
#endif |
InitalizeApp(); |
UnloadSeg((Ptr)InitalizeApp); /* get rid of my initialization code */ |
/* start running */ |
do { |
WaitNextEvent(everyEvent, &gERecord, 30, nil); |
switch (gERecord.what) { |
case nullEvent: |
/* no nul processing in this sample */ |
break; |
case updateEvt: |
/* at update, draw the window */ |
tempWCH = (windowCHandle)GetWRefCon((WindowPtr)gERecord.message); |
(ProcPtr)((*tempWCH)->drawMe)((WindowPtr)gERecord.message); |
break; |
case mouseDown: |
/* first see where the hit was */ |
fHit = FindWindow(gERecord.where, &twindow); |
switch (fHit) { |
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(gERecord.where)); |
break; |
case inSysWindow: |
/* pass to the system */ |
SystemClick(&gERecord, twindow); |
break; |
case inContent: |
/* Handle content and control clicks here */ |
if (FrontWindow()) { /* don't do this unless we have a window open, silly */ |
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 */ |
(ProcPtr)((*clicker)->clickMe)(twindow); |
HUnlock((Handle)clicker); /* all done */ |
} |
break; |
case inDrag: |
if (twindow == FrontWindow()) |
DragWindow(twindow, gERecord.where, &qd.screenBits.bounds); |
break; |
case inGrow: |
/* Call GrowWindow here if you have a grow box */ |
SetPort(twindow); |
MyGrowWindow(twindow); |
break; |
case inGoAway: |
/* Click in Close box */ |
if (TrackGoAway(twindow, gERecord.where)) |
(ProcPtr)((*(windowCHandle)((WindowPeek)twindow)->refCon)->closeMe)(twindow); |
break; |
case inZoomIn: |
case inZoomOut: |
if (TrackBox(twindow, gERecord.where, fHit)) { |
windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow); |
SetPort(twindow); |
ZoomWindow(twindow, fHit, true); |
InvalRect(&twindow->portRect); |
(ProcPtr)((*tempWCH)->sizeMe)(twindow); |
} |
} /* end mouseDown case */ |
case mouseUp: |
/* don't care */ |
break; |
/* same action for key or auto key */ |
case keyDown: |
case autoKey: |
if (gERecord.modifiers & cmdKey) |
DoSelected(MenuKey(gERecord.message & charCodeMask)); |
break; |
case keyUp: |
/* don't care */ |
break; |
case diskEvt: |
/* I don't do anything special for disk events, this just passes them */ |
/* to a function that checks for an error on the mount */ |
DoDiskEvents(gERecord.message); |
break; |
case activateEvt: |
if (gERecord.modifiers & activeFlag) { |
tempWCH = (windowCHandle)GetWRefCon((WindowPtr)gERecord.message); |
(ProcPtr)((*tempWCH)->drawMe)((WindowPtr)gERecord.message); |
} |
break; |
case 10: |
/* don't care */ |
break; |
case 11: |
/* don't care */ |
break; |
case 15: |
switch ((gERecord.message >> 24) & 0x0FF) { /* high byte of message */ |
case suspendResumeMessage: /* suspend/resume is also an activate/deactivate */ |
gInBackground = (gERecord.message & kResumeMask) == 0; |
break; |
} |
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(&gERecord); |
break; |
default: |
break; |
} |
}while (gQuit != true); |
} |
/* DoDaCall opens the requested DA. It's here as a seperate routine if you'd */ |
/* like to perform some action or just know when a DA is opened in your */ |
/* layer. Can be handy to track memory problems when a DA is opened */ |
/* with an Option-open */ |
void DoDaCall(MenuHandle themenu, long theit) |
{ |
long qq; |
Str255 DAname; |
GetMenuItemText(themenu, theit, DAname); |
qq = OpenDeskAcc((ConstStr255Param)&DAname); |
} |
/* end DoDaCall */ |
/* DoDiskEvents just checks the error code from the disk mount, */ |
/* and puts up the 'Format' dialog (through DIBadMount) if need be */ |
/* You can do much more here if you care about what disks are */ |
/* in the drive */ |
void DoDiskEvents(long dinfo) /* hi word is error code, lo word is drive number */ |
{ |
short hival, loval, tommy; |
Point fredpoint = { |
40, 40 |
}; |
hival = HiWord(dinfo); |
loval = LoWord(dinfo); |
if (hival != noErr) /* something happened */ { |
tommy = DIBadMount(fredpoint, dinfo); |
} |
} |
/* draws my window. Pretty simple */ |
void DrawMain(WindowPtr drawIt) |
{ |
RgnHandle tempRgn; |
Rect scratchRect; |
Str31 tempString; |
BeginUpdate(drawIt); |
SetPort(drawIt); |
EraseRect(&drawIt->portRect); |
MoveTo(10, 17); |
DrawIndString(kGenStrings,kSayCurrentGrid); |
NumToString(gGridIncrement, tempString); |
DrawString(tempString); |
MoveTo(10, 37); |
DrawIndString(kGenStrings,kSayChangeGrid); |
scratchRect = drawIt->portRect; |
scratchRect.top = scratchRect.bottom - 15; |
scratchRect.left = scratchRect.right - 15; |
tempRgn = NewRgn(); |
GetClip(tempRgn); |
ClipRect(&scratchRect); |
DrawGrowIcon(drawIt); |
SetClip(tempRgn); |
DisposeRgn(tempRgn); |
EndUpdate(drawIt); |
} |
/* my menu action taker. It returns a Boolean which I usually ignore, but it */ |
/* mught be handy someday */ |
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 */ |
if (loval != 1) { /* if this was not About, it's a DA */ |
DoDaCall(GetMenuHandle(kAppleMenu), loval); |
} else { |
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 */ |
break; |
case kToolsMenu: |
case kGridDialogItem: |
DoGridDialog(); |
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 ) |
} |
/* InitAEStuff installs my appleevent handlers */ |
void InitAEStuff(void) |
{ |
static AEinstalls HandlersToInstall[] = |
{ |
{ kCoreEventClass, kAEOpenApplication, AEOpenHandler }, |
{ kCoreEventClass, kAEQuitApplication, AEQuitHandler }, |
{ kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler }, |
{ kCoreEventClass, kAEPrintDocuments, AEPrintHandler } |
}; |
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) { |
register qq; |
for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) { |
aevtErr = AEInstallEventHandler |
(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent, |
NewAEEventHandlerProc (HandlersToInstall[qq].theProc), 0, false); |
if (aevtErr) { |
ExitToShell(); /* just fail, baby */ |
} |
} |
} else { |
ExitToShell(); |
} |
} |
/* end InitAEStuff */ |
/* 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) |
{ |
AEProcessAppleEvent(AERecord); |
} |
/* end DoHighLevel */ |
/* This is the standard Open Application event. */ |
pascal OSErr AEOpenHandler(const AppleEvent *messagein, AppleEvent *reply, unsigned long refIn) |
{ |
#pragma unused (messagein,reply,refIn) |
/* we of course don't do anything here in this simple app */ |
/* except open our window */ |
AddNewWindow(128); |
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. */ |
pascal OSErr AEOpenDocHandler(const AppleEvent *messagein, AppleEvent *reply, unsigned long refIn) |
{ |
#pragma unused (messagein,refIn,reply) |
/* we of course don't do anything here */ |
return(errAEEventNotHandled); /* we have no docs, so no odoc events should come to us */ |
} |
pascal OSErr AEPrintHandler(const AppleEvent *messagein, AppleEvent *reply, unsigned long 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 (messagein,refIn,reply) |
/* we of course don't do anything here */ |
return(errAEEventNotHandled); /* we have no docs, so no pdoc events should come to us */ |
} |
/* 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. */ |
pascal OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, unsigned long refIn) |
{ |
#pragma unused (messagein,refIn,reply) |
/* prepQuit sets the Stop flag for us. It does _NOT_ quit, you */ |
/* should NEVER quit from an AppleEvent handler. Calling */ |
/* ExitToShell here would blow things up */ |
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(NewModalFilterProc(nil), &itemhit); |
} |
DisposeDialog(tdial); |
} |
#pragma segment Initialize |
void InitalizeApp(void) |
{ |
MenuHandle helpHandle; |
Handle myMenuBar; |
StringHandle helpString; |
short count; |
long vers; |
MaxApplZone(); |
InitGraf((Ptr)&qd.thePort); |
InitFonts(); |
InitWindows(); |
InitMenus(); |
TEInit(); |
InitDialogs(nil); |
InitCursor(); |
/* Check system version */ |
Gestalt(gestaltSystemVersion, &vers); |
vers = (vers >> 8) & 0xf; /* shift result over and mask out major version number */ |
if (vers < 7) { |
StopAlert(kBadSystem, nil); |
ExitToShell(); |
} |
InitAEStuff(); |
/* set up my menu junk */ |
myMenuBar = GetNewMBar(kMBarID); |
SetMenuBar(myMenuBar); |
AppendResMenu(GetMenuHandle(kAppleMenu), 'DRVR'); |
/* now install my Help menu item in the Help Manager's menu */ |
HMGetHelpMenuHandle(&helpHandle); /* Get the Hlpe menu handle */ |
count = CountMItems(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, (ConstStr255Param)helpString, count + 1); /* insert my item in the Help menu */ |
gHelpItem = CountMItems(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; |
short cnt = 0; |
tempWP = GetNewWindow(theID, 0, (WindowPtr)-1); /* get a new window */ |
SetPort(tempWP); |
((WindowPeek)tempWP)->windowKind = kDocumentWindow; /* mark it as a 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)->saveMe = (ProcPtr)NilProc; |
(*setControls)->closeMe = (ProcPtr)NilProc; |
(*setControls)->clickMe = (ProcPtr)DoDocumentClick; |
(*setControls)->sizeMe = (ProcPtr)SizeMain; |
/* now initialize all our required handles */ |
return(tempWP); |
} |
void SizeMain(WindowPtr theWindow) |
{ |
WindowPtr tempWP; |
GetPort(&tempWP); |
InvalRect(&theWindow->portRect); |
SetPort(tempWP); |
} |
void NilProc(void) |
{ |
} |
// This will grid a window grow to a specific increment |
void PullRect(Rect *startRect) |
{ |
Rect *oldRect; |
Point endPoint; |
Boolean hreversed = false; |
Boolean vreversed = false; |
short tempH, tempV; |
short divBy20h, divBy20v; |
/* set up */ |
oldRect = startRect; |
PenMode(srcXor); /* So we can rubberband */ |
PenPat(&qd.gray); |
FrameRect(startRect); |
divBy20h = startRect->right; |
divBy20v = startRect->bottom; |
while (StillDown()) { /* Keep doing this as long as the */ |
/* user keeps the mouse down */ |
GetMouse(&endPoint); /* Current mouse position in local */ |
// see if it's on a grid point |
tempH = ABS(endPoint.h - divBy20h) / gGridIncrement; |
tempV = ABS(endPoint.v - divBy20v) / gGridIncrement; |
// normalize to our grid values. We'll always go outwards as better |
if ((tempH * gGridIncrement) != ABS(endPoint.h - divBy20h)) { |
// shove out based on the remainer |
endPoint.h = (((endPoint.h)/gGridIncrement)*gGridIncrement)+gGridIncrement; |
} |
if ((tempV * gGridIncrement) != ABS(endPoint.v - divBy20v)) { |
endPoint.v = (((endPoint.v)/gGridIncrement)*gGridIncrement)+gGridIncrement; |
} |
// If things reversed, we have to make sure that we don't try |
// and grid the origin point of the drag, cuz that would be weird |
if (hreversed) { |
/* see if the rectangle flipped first */ |
if (endPoint.h > startRect->right) { |
/* they flipped back */ |
hreversed = false; /* and ignore this move */ |
} else { |
/* still reversed */ |
startRect->left = endPoint.h; |
} |
} else { |
if (endPoint.h < startRect->left) { |
hreversed = true; |
} else { |
startRect->right = endPoint.h; |
} |
} |
if (vreversed) { |
/* see if it flipped first */ |
if (endPoint.v > startRect->bottom) { |
/* they flipped back */ |
vreversed = false; /* and ignore this move */ |
} else { |
/* still reversed */ |
startRect->top = endPoint.v; |
} |
} else { |
if (endPoint.v < startRect->top) { |
vreversed = true; |
} else { |
startRect->bottom = endPoint.v; |
} |
} |
if (startRect != oldRect) { /* redraw the rect only if the mouse moved */ |
FrameRect(oldRect); |
FrameRect(startRect); /* draw the new rect */ |
oldRect = startRect; |
} |
} |
FrameRect(startRect); |
PenMode(srcCopy); |
PenPat(&qd.black); |
} |
void MyGrowWindow(WindowPtr theWindow) |
{ |
PenState oldPen; |
WindowPtr tempWP, WMPort; |
Rect draggingRect = theWindow->portRect; |
Rect wideOpen = { |
kExtremeNeg, kExtremeNeg, kExtremePos, kExtremePos |
}; |
RgnHandle oldRgn = NewRgn(); |
GetPort(&tempWP); |
SetPort(theWindow); |
/* normalize my rectangle into the window manager port coordinates */ |
LocalToGlobal((Point *)&draggingRect); |
LocalToGlobal((Point *)&draggingRect.bottom); |
/* go to the WManager port */ |
GetWMgrPort(&WMPort); |
SetPort(WMPort); |
/* save the Window manager pen state since we'll be changing it */ |
GetPenState(&oldPen); |
/* localize back */ |
GlobalToLocal((Point *)&draggingRect); |
GlobalToLocal((Point *)&draggingRect.bottom); |
/* save the current clip region, and set our wide-open clip */ |
GetClip(oldRgn); |
ClipRect(&wideOpen); |
/* go to the routine above and do the actual dragging */ |
PullRect(&draggingRect); |
/* restore the original environment */ |
SetClip(oldRgn); |
SetPenState(&oldPen); |
DisposeRgn(oldRgn); |
/* now size the window for the returned rect */ |
SetPort(theWindow); |
InvalRect(&theWindow->portRect); |
SizeWindow(theWindow, draggingRect.right - draggingRect.left, draggingRect.bottom - draggingRect.top, true); |
SetPort(tempWP); |
} |
void DoGridDialog(void) |
{ |
Str255 tempString; |
WindowPtr tempWP=nil; |
WindowPtr tempPort=nil; |
long aLong; |
DialogPtr theDialog = GetNewDialog(kGridDialog, nil, (WindowPtr)-1); |
short itemHit = 0; |
ModalFilterUPP theStdProc=nil; // inited to nil in case the Get fails |
// get some automatic dialog behaviour |
SetDialogDefaultItem(theDialog,ok); |
SetDialogTracksCursor(theDialog,true); |
GetStdFilterProc(&theStdProc); |
// set the item to be the current grid value |
NumToString(gGridIncrement, tempString); |
SetDialogItemText((Handle)SnatchHandle(theDialog, kGridEditLine), tempString); |
// spin until they hit OK or Cancel |
while (itemHit != ok && itemHit !=cancel) { |
ModalDialog(theStdProc, &itemHit); |
} |
if (itemHit == 1) { |
// they OK'ed their new grid value |
GetDialogItemText((Handle)SnatchHandle(theDialog, kGridEditLine), tempString); |
StringToNum(tempString, &aLong); |
gGridIncrement = aLong; |
// invalidate our document window so the new value will be refelcted |
tempWP = FindWindowByKind(kDocumentWindow); |
if(tempWP != nil){ |
GetPort(&tempPort); |
SetPort(tempWP); |
InvalRect(&tempWP->portRect); |
SetPort(tempPort); |
} |
} |
DisposeDialog(theDialog); |
} |
/* gets a handle from a dialog item */ |
ControlHandle SnatchHandle(DialogPtr thebox, short theGetItem) |
{ |
short itemtype; |
Rect itemrect; |
Handle thandle; |
GetDialogItem(thebox, theGetItem, &itemtype, &thandle, &itemrect); |
return((ControlHandle)thandle); |
} |
/* end SnatchHandle */ |
/* loads an index string and draws it. Just a convinice */ |
void DrawIndString(short resID,short index) |
{ |
Str255 theString; |
GetIndString(theString,resID,index); |
DrawString(theString); |
} |
/* returns the first window of specified kind, or nil if none */ |
WindowPtr FindWindowByKind(short kindToFind) |
{ |
WindowPtr currentWindow = FrontWindow(); |
while(currentWindow){ |
if(((WindowPeek)currentWindow)->windowKind == kindToFind){ |
// found it, break |
break; |
} else { |
// go to the next one |
currentWindow = (WindowPtr) ((WindowPeek)currentWindow)->nextWindow; |
} |
} |
return ( currentWindow ); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-30