home *** CD-ROM | disk | FTP | other *** search
- /* MyAddResMenu */
- /* There is a minor bug in system 7.1 (oh no!) */
- /* AddResMenu will only alphabatize 'FONT' resources, all others */
- /* will just be displayed in the order they appear in the resource map */
- /* of the resource fork. */
- /* This isn't harmful, it's just a little ugly. */
- /* Fixing it is pretty simple, just use the function in this sample */
- /* called MyAddResMenu */
- /* C.K. Haun */
- /* Apple DTS */
- /* Of course, Copyright 1991-1992, Apple Computer Inc. */
-
- #include "AddResMenu7.1.h"
-
- /* prototypes */
-
- 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);
-
- pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
-
- void SampleHelpDialog(void);
-
- WindowPtr AddNewWindow(short theID);
- short HasSelectionRange(DialogPeek inputDialog);
- Boolean IsEditKey(char theKey, short modifiers);
- void AddAResourceType(void);
- void MyAddResMenu(ResType theType, MenuHandle theMenu, short afterItem);
- pascal Boolean filterIt(DialogPtr inputDialog, EventRecord *myDialogEvent, short *theDialogItem);
- ControlHandle SnatchHandle(DialogPtr thebox, short theGetItem);
- void CleanUpMetaChars(Str255 theString);
- 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;
-
-
- #pragma segment Main
- main()
- {
- EventRecord myEventRecord;
- WindowPtr twindow;
- short fHit;
- windowCHandle tempWCH;
-
- UnloadSeg((Ptr)_DataInit); /* throw out setup code */
- InitalizeApp();
- UnloadSeg((Ptr)InitalizeApp); /* get rid of my initialization code */
- 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 (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
- tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
- (ProcPtr)((*tempWCH)->drawMe)((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 */
- SystemClick(&myEventRecord, 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;
- if (((WindowPeek)twindow)->windowKind == kMyDocumentWindow) {
-
- 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:
- DragWindow(twindow, myEventRecord.where, &qd.screenBits.bounds);
- break;
- case inGrow:
- /* Call GrowWindow here if you have a grow box */
- SetPort(twindow);
- limitRect = qd.screenBits.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) {
- windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
- Rect sizeRect = ((WindowPtr)twindow)->portRect;
- InvalRect(&sizeRect);
- sizeRect.top = sizeRect.bottom - 16;
- sizeRect.left = sizeRect.right - 16;
- EraseRect(&sizeRect);
- InvalRect(&sizeRect);
- SizeWindow(twindow, back & 0xffff, back >> 16, true);
- (ProcPtr)((*tempWCH)->sizeMe)(twindow);
- }
- InvalRect(&twindow->portRect);
-
- break;
- case inGoAway:
- /* Click in Close box */
- if (TrackGoAway(twindow, myEventRecord.where)) {
- if (((WindowPeek)twindow)->windowKind == kMyDocumentWindow)
- (ProcPtr)((*(windowCHandle)((WindowPeek)twindow)->refCon)->closeMe)(twindow);
- }
- break;
- case inZoomIn:
- case inZoomOut:
- if (TrackBox(twindow, myEventRecord.where, fHit)) {
- windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
- SetPort(twindow);
-
- ZoomWindow(twindow, fHit, true);
- InvalRect(&twindow->portRect);
- if (((WindowPeek)twindow)->windowKind == kMyDocumentWindow)
- (ProcPtr)((*tempWCH)->sizeMe)(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 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(myEventRecord.message);
- break;
- case activateEvt:
-
- if (myEventRecord.modifiers & activeFlag) {
- if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
-
- tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
- (ProcPtr)((*tempWCH)->drawMe)((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;
- 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);
-
- }
-
- /* 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;
- char DAname[255];
- GetItem(themenu, theit, &DAname);
- qq = OpenDeskAcc(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;
- BeginUpdate(drawIt);
- SetPort(drawIt);
- 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 */
- /* 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 */
- if (loval != 1) { /* if this was not About, it's a DA */
- DoDaCall(GetMHandle(kAppleMenu), loval);
- } else {
- Alert(kAboutBox, nil); /* do about box */
- }
- returnVal = true;
- break;
-
- case kFileMenu: /* File menu */
- switch (loval) {
-
- case kQuitItem:
- gQuit = true; /* onlyitem */
- 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) {
- case kTestMenuChooseType:
- AddAResourceType();
- break;
- 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)
- {
-
- }
-
- /* InitAEStuff installs my appleevent handlers */
- void InitAEStuff(void)
- {
- AEinstalls HandlersToInstall[] = {
- {
- kCoreEventClass, kAEOpenApplication, AEOpenHandler
- }, {
- kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
- }, {
- kCoreEventClass, kAEQuitApplication, AEQuitHandler
- }, {
- kCoreEventClass, kAEPrintDocuments, AEPrintHandler
- },
- /* The above are the four required AppleEvents. */
-
- };
-
- 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,
- 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)
- {
- OSErr myErr;
- myErr = AEProcessAppleEvent(AERecord);
-
- }
-
- /* end DoHighLevel */
-
- /* This is the standard Open Application event.*/
- pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long 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. */
-
- pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, 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(AppleEvent *messagein, AppleEvent *reply, 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.*/
- /* 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!!!!!!!!!!!!!! */
- pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long 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((ModalFilterProcPtr)nil, &itemhit);
- }
- DisposDialog(tdial);
- }
-
- WindowPtr AddNewWindow(short theID)
- {
- windowCHandle setControls;
- WindowPtr tempWP;
- short cnt = 0;
- Str31 wtitle;
- tempWP = GetNewWindow(theID, 0, (WindowPtr)-1); /* get a new window */
- ((WindowPeek)tempWP)->windowKind = 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)->generalData = NewHandle(0);
- return(tempWP);
- }
-
- void SizeMain(WindowPtr theWindow)
- {
- WindowPtr tempWP;
- GetPort(&tempWP);
- InvalRect(&theWindow->portRect);
- SetPort(tempWP);
- }
-
- void NilProc(void)
- {
-
- }
-
- /* AddAResourceType asks for the resource type to add to the menu */
- /* it preflights to see if at least one exists, then passes of to MyAddResMenu */
- void AddAResourceType(void)
- {
- Rect tempRect;
- short tempItem;
- Handle tempHandle;
- Str15 myStr;
- ResType theType;
- short hitItem;
- DialogPtr myDialog = GetNewDialog(kResTypeDialog, nil, (WindowPtr)-1);
-
- /* New System 7 dialog manager calls, see tech note #304 */
- /* interface to these calls is in AddResMenu7.1.h */
- SetDialogDefaultItem(myDialog, ok);
- SetDialogCancelItem(myDialog, cancel);
- SetDialogTracksCursor(myDialog, true);
-
- do {
- ModalDialog((ModalFilterProcPtr)filterIt, &hitItem);
- }
- while (hitItem != ok && hitItem != cancel);
-
- if (hitItem == ok) {
-
- /* get the type and hammer it */
- GetDItem(myDialog, kResTypeEditLine, &tempItem, &tempHandle, &tempRect);
- GetIText(tempHandle, myStr);
-
- /* make sure there are 4 characters here, please */
- if (myStr[0] == 4) {
- BlockMove((Ptr)&myStr[1], (Ptr)&theType, sizeof(theType));
- /* reality check to see if there are any of these at this time */
- tempItem = Count1Resources(theType);
- if (tempItem) {
- /* clear the menu out before I add new things*/
- tempItem = CountMItems(GetMHandle(kToolsMenu));
-
- /* I want to add below the dividing line */
- tempItem -= kTestMenuDivider;
- while (tempItem) {
- DelMenuItem(GetMHandle(kToolsMenu), kTestMenuDivider + 1);
-
- tempItem--;
- }
-
- /* call my routine */
- MyAddResMenu(theType, GetMHandle(kToolsMenu), kTestMenuDivider);
- } else {
- /* yell because there are none of that type around */
- ParamText(myStr, "", "", "");
- CautionAlert(kNoneOfThatType, nil);
- }
- }
- }
- DisposDialog(myDialog);
-
- }
-
- /* MyAddResMenu does, basically, what AddResmenu does, it does an */
- /* "insert sort" (one of the Comp. Sci. types around here told me to call it that) */
- /* of the names of the resources.It uses IUCompString for */
- /* International Reasons (KFJC 89.7, 12-3 Sundays) */
- /* The only thing it really does differently is includes items that don't have */
- /* names by including the 'unnamedX' string. */
- /* Also notice that, since I'm using InsMenuItem I have to parse the*/
- /* name string and take out any menu manager meta-characters before I insert things */
- /* so I don't get strange command keys from a name like "Alert/Warning 1" */
-
- void MyAddResMenu(ResType theType, MenuHandle theMenu, short afterItem)
- {
- short originalCount = afterItem;
- short resourceCount = Count1Resources(theType);
- short index = 1;
- short unnamedCount = 0;
- short qq;
- ResType theIndexType;
- short theID;
- Str255 theName;
- Str32 unusedWord;
- Str255 tempString;
- Handle tempHandle;
- Boolean oldResLoad = *((Boolean *)0xA5E);
- Boolean addedIt = false;
-
- GetIndString(unusedWord, kGenStrings, kUnnamedString);
- SetResLoad(false); /* don't want to load the resources */
- do {
- tempHandle = Get1IndResource(theType, index);
- theName[0] = 0;
- GetResInfo(tempHandle, &theID, &theIndexType, &theName);
- /* Check the name, if no name tell it so... */
- if (theName[0] == 0) {
- BlockMove((Ptr)&unusedWord, (Ptr)&theName, unusedWord[0] + 1);
- NumToString((long)unnamedCount, tempString);
- if ((theName[0] + tempString[0]) < 254) {
- BlockMove((Ptr)&tempString[1], (Ptr)(&theName[1] + theName[0]), tempString[0]);
- theName[0] += tempString[0];
- }
- unnamedCount++;
- }
- CleanUpMetaChars(theName);
- /* here's where you sort in the menu items */
- /* it goes roughly like.... */
- for (qq = afterItem + 1; qq < CountMItems(theMenu) + 1; qq++) {
- GetItem(theMenu, qq, &tempString);
- if (IUCompString(theName, tempString) == -1) {
- /* new string is less than an existing name */
- /* so insert it before it */
- InsMenuItem(theMenu, theName, qq - 1);
- addedIt = true;
- break; /* leave the 'for' loop */
- }
- }
- /* If it didn't sort in, just add it to the end of the menu */
- if (!addedIt)
- InsMenuItem(theMenu, theName, CountMItems(theMenu) + 1);
- addedIt = false;
- index++;
- }
- while (index <= resourceCount);
- SetResLoad(oldResLoad);
- }
-
- /* Some dialog filtering things */
- /* TabRetEsc toggles the cancel or OK button for keystrokes, and */
- /* treats a Tab press as selecting the whole edit line contents */
-
- Boolean TabRetEsc(DialogPtr inputDialog, EventRecord *myDialogEvent, short *theDialogItem)
- {
- Boolean returnValue = false;
- long tilticks;
- WindowPtr tempWindowPtr;
- char theKey = myDialogEvent->message &charCodeMask;
- GetPort(&tempWindowPtr);
- SetPort(inputDialog);
- switch (theKey) {
- case kReturnKey:
- case kEnterKey: /* enter key */
- /* This filters for Return or Enter as item 1, and Esc as item 2 */
- *theDialogItem = ok; /* change whatever the current item is to the OK item */
- /* now we need to invert the button */
- HiliteControl(SnatchHandle(inputDialog, ok), inButton);
- Delay(8, &tilticks); /* wait about 8 ticks so they can see it */
- HiliteControl(SnatchHandle(inputDialog, ok), false);
- returnValue = true;
- break;
- /* This filters the escape key as the same as item 2 (the canx button, usually ) */
- case kEscKey:
- *theDialogItem = cancel;
- HiliteControl(SnatchHandle(inputDialog, cancel), inButton);
- Delay(8, &tilticks); /* wait about 8 ticks so they can see it */
- HiliteControl(SnatchHandle(inputDialog, cancel), false);
- returnValue = true;
- break;
- case kTabKey:
- /* I'm filtering the tab key here so a tab selects all the */
- /* text in the edit line, as a convinience */
- SelIText(inputDialog, kResTypeEditLine, 0, 5);
- returnValue = true; /* don't allow edit line swaps */
- break;
- }
- SetPort(tempWindowPtr);
-
- return(returnValue);
-
- }
-
- /* Main dialog filter */
- pascal Boolean filterIt(DialogPtr inputDialog, EventRecord *myDialogEvent, short *theDialogItem)
- {
-
- Boolean returnVal = false;
- ModalFilterProcPtr theModalProc;
- char theKey;
- Rect tempRect;
- short tempItem;
- Handle tempHandle;
- char tempKey;
- Str255 myStr;
- long offset;
- short selection;
- long scrapLen;
- short resultLen;
- Boolean wasAKey = false;
- if (myDialogEvent->what == updateEvt && myDialogEvent->message != inputDialog) {
- /* May be a pending update event for another window, handle it so */
- /* other layers get time */
- windowCHandle tempWCH;
- WindowPtr theWindow = (WindowPtr)myDialogEvent->message;
- /* draw my window if it's really mine */
- if (((WindowPeek)theWindow)->windowKind == kMyDocumentWindow) {
- tempWCH = (windowCHandle)GetWRefCon(theWindow);
- (ProcPtr)((*tempWCH)->drawMe)((WindowPtr)theWindow);
-
- *theDialogItem = 0;
- returnVal = true;
- }
- } else {
- wasAKey = (myDialogEvent->what == keyDown) || (myDialogEvent->what == autoKey);
-
- if ((wasAKey)) {
- /* first check on the Big Three, tab, return, and escape */
- if (!(returnVal = TabRetEsc(inputDialog, myDialogEvent, theDialogItem))) {
-
- /* not one of those, see if this keystroke will fit */
- /* in the edit line (restricted to 4 characters for a ResType) */
-
- /* Here I'm seeing if anything is selected, and getting the length */
- /* of the desk scrap in case the user presses */
- /* Copy or Paste keys */
-
- selection = HasSelectionRange((DialogPeek)inputDialog);
- scrapLen = GetScrap(nil, 'TEXT', &offset);
-
- GetDItem(inputDialog, kResTypeEditLine, &tempItem, &tempHandle, &tempRect);
- GetIText(tempHandle, myStr);
-
- /* calculate the result of adding the scrap to the current record.We use */
- /* this in a few places here */
- resultLen = myStr[0] + (scrapLen - selection);
-
- theKey = myDialogEvent->message & charCodeMask;
- tempKey = theKey;
- if (tempKey >= 0x61 && tempKey <= 0x7a)
- tempKey -= 0x20;
-
- if (myStr[0] > 3) { /* over 4, see what it is */
-
- if (IsEditKey(theKey, myDialogEvent->modifiers)) {
- /* it was an editing key, but it MAY be a command-V. */
- /* If it's a command-V then we won't allow it UNLESS */
- /* there is a slection range AND the new data won't overrun things */
- if ((tempKey == 'V') && (myDialogEvent->modifiers & cmdKey)) {
-
- /* this was a paste.check selection range and scrap len*/
- if (resultLen < 4) {
- returnVal = false; /* net result is4 or less */
- } else {
- SysBeep(1);
- returnVal = true;
- }
- } else {
- returnVal = false; /* don't filter out editing keys */
- }
- } else {
- /* One more check (this can get complicated, huh?) */
- /* We now look to see if there is a selection range.If there */
- /* is a range of 1 or more characters, then the one character they are entering */
- /* now will replace that, and we'll end up with _less_ than 4 (or equal) */
- /* to do this, we have to get the TERecord out of the dialog.*/
- /* I'm going to do this in a seperate function */
- if (selection == nil) {
- SysBeep(1); /* complain a little */
- returnVal = true; /* tell the dialog manager that we handled this already and */
- /* it doesn't have to, so the keystroke will _not_ get */
- /* added to the edit line */
- }
- }
- } else {
- /* even if we're less than 4 currently, a Command-V (paste) could put us over */
- /* so check it out */
-
- if ((tempKey == 'V') && (myDialogEvent->modifiers & cmdKey)) {
-
- /* Gettting the scrap with a nil handle, which does not give us data, just */
- /* returns the size */
- if (resultLen > 3) {
- SysBeep(1); /* complain a little */
- returnVal = true; /* tell the dialog manager that we handled this already and */
-
- }
- }
- }
- }
- }
- }
- if (!returnVal) {
-
- OSErr myErr = GetStdFilterProc(&theModalProc);
- if (myErr == noErr)
- returnVal = theModalProc(inputDialog, myDialogEvent, theDialogItem);
- }
- return(returnVal);
- }
-
- short HasSelectionRange(DialogPeek inputDialog)
- {
- TEHandle theTERecord = inputDialog->textH;
- short returnVal = (*theTERecord)->selEnd -(*theTERecord)->selStart;
-
- return(returnVal);
- }
-
- /* end HasSelectionRange */
-
- /* a little utility to see if the current key is an edit-type key */
- Boolean IsEditKey(char theKey, short modifiers)
- {
- register qq;
- Boolean returnVal = false;
- char editChars[] = {
- kLeftArrow, kUpArrow, kRightArrow, kDownArrow, kBackSpace, kEscKey
- };
- char commandEdits[] = {
- 'C', 'V', 'P'
- };
- for (qq = 0; qq < sizeof(editChars) / sizeof(char); qq++) {
- if (theKey == editChars[qq])
- returnVal = true;
- }
- if (returnVal != true && (modifiers & cmdKey)) {
- /* check for XCP */
- /* Do you want me to use 'toupper()'?What! And link in all of StdLib! aggggg */
- if (theKey >= 0x61 && theKey <= 0x7a)
- theKey -= 0x20;
- for (qq = 0; qq < sizeof(commandEdits) / sizeof(char); qq++) {
- if (theKey == commandEdits[qq])
- returnVal = true;
- }
- }
- return(returnVal);
- }
-
- /* end IsEditKey */
-
- /* Gets the ControlHandle for the item you want in the dialog box thebox.*/
- /* Handy for setting checkboxes and radio buttons */
- /* This is the _most_ copied routine from this file */
- ControlHandle SnatchHandle(DialogPtr thebox, short theGetItem)
- {
- short itemtype;
- Rect itemrect;
- Handle thandle;
-
- GetDItem(thebox, theGetItem, &itemtype, &thandle, &itemrect);
- return((ControlHandle)thandle);
- }
-
- /* end SnatchHandle */
-
- void CleanUpMetaChars(Str255 theString)
- {
- char metaKeys[] = {
- ';', '^', '!', '<', '/', '('
- };
- register qq, ii;
-
- qq = theString[0];
- while (qq) {
- for (ii = 0; ii < sizeof(metaKeys) / sizeof(char); ii++) {
- if (theString[qq] == metaKeys[ii])
- theString[qq] = '•'; /* replace with a Spot */
- }
- qq--;
- }
- }
-
-
- #pragma segment Initialize
- void InitalizeApp(void)
- {
- Handle myMenu;
- MenuHandle helpHandle, appleMenuHandle;
- 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 */
- myMenu = GetNewMBar(kMBarID);
- SetMenuBar(myMenu);
- appleMenuHandle = GetMHandle(kAppleMenu);
- AddResMenu(appleMenuHandle, '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(helpString); /* detach it */
- HNoPurge(helpString);
- MoveHHi((Handle)helpString);
- HLock((Handle)helpString);
- InsMenuItem(helpHandle, (Ptr)*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
-