home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-06-20 | 67.9 KB | 2,331 lines |
- 18-Jun-88 14:44:01-MDT,71786;000000000000
- Return-Path: <u-lchoqu%sunset@cs.utah.edu>
- Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Sat, 18 Jun 88 14:42:14 MDT
- Received: by cs.utah.edu (5.54/utah-2.0-cs)
- id AA22611; Sat, 18 Jun 88 14:42:05 MDT
- Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
- id AA24770; Sat, 18 Jun 88 14:41:57 MDT
- Date: Sat, 18 Jun 88 14:41:57 MDT
- From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
- Message-Id: <8806182041.AA24770@sunset.utah.edu>
- To: rthum@simtel20.arpa
- Subject: SimpleTools.c.shar
-
- #! /bin/sh
- #
- # This is a shell archive. Save this into a file, edit it
- # and delete all lines above this comment. Then give this
- # file to sh by executing the command "sh file". The files
- # will be extracted into the current directory owned by
- # you with default permissions.
- #
- # The files contained herein are:
- #
- # 3 STools.info
- # 12 SimpleDemo.c
- # 31 SimpleTools.c
- # 19 SimpleTools.doc
- #
- echo 'Extracting STools.info'
- if test -f STools.info; then echo 'shar: will not overwrite STools.info'; else
- sed 's/^X//' << '________This_Is_The_END________' > STools.info
- XFrom: erik@ucbssl.CC.Berkeley.EDU (Erik Kilk)
- X
- X!rSimpleTalk.text
- X
- XHere is an updated version of SimpleTools. Included are the SimpleTools
- Xsources, a MacWrite document, and an example using some of the easy and
- Xadvanced features in the SimpleTools library.
- X
- XSimpleTools is a set of subroutines which greatly ease the use of the
- XMacintosh toolbox. It is mainly intended to be used for your smaller
- Xapplications where you would rather not be too concerned with reading
- XInside Macintosh over again. The subroutines are currently written in C
- Xand were done so using the Megamax compiler. They are designed to be
- Xcompiled into an object file. Your program will then link in this object
- Xfile at the same time it links in the toolbox interface. When you receive
- Xthe SimpleTools source, you should compile it into SimpleTools.o. You can
- Xthen compile the demo, SimpleDemo, and link it to SimpleTools.o.
- X
- XFor example, lets say you want the menu items named "Zoom" and "Widen"
- Xunder the menu "View". You would like the procedure:
- X
- X zoom()
- X {
- X zoomfactor++;
- X }
- X
- Xto be executed when the user selects Zoom and:
- X
- X widen()
- X {
- X zoomfactor--;
- X }
- X
- Xto execute when Widen is selected. You would both create the menus on the
- Xmenu bar AND inform SimpleTools what to do with the calls:
- X
- X menu ("View", "Zoom", zoom);
- X menu ("View", "Widen", widen);
- X
- XThen, your program would run by repeatedly calling SimpleEvents, like:
- X
- X main()
- X {
- X setup();
- X for (;;) SimpleEvents();
- X }
- X
- XSeveral other features are included in SimpleTools:
- X
- X1. Window creation with assignment of procedures to be executed on window
- Xactivation, deactivation, when the mouse is clicked in it, and when an
- Xupdate occurs.
- X
- X2. Assignment of procedures to be "run" each time SimpleEvents() is
- Xcalled. This can easily make it look like multi-subroutines are running
- Xconcurrently.
- X
- X3. Generic prompt() and message() routines which pop up a small dialog box
- Xfor you. For example:
- X
- X prompt("What is your name?", answer)
- X
- Xis all yo have to do to get a dialog box up requesting the user's name.
- XThe answer goes into the string answer.
- X
- X4. Automatic setup of the Apple, File, and Edit menu so even your simplest
- Xof programs will still have Desk Accessories.
- X
- X5. Many, many, hidden options that you will never know about unless you
- Xcare to know about them. (This was a major design goal of SimpleTools--
- Xhide options and use the most common default.)
- X
- XThis has just been a summary of the SimpleTools routines. I'm sure you
- Xcould find them very useful. Many users of SimpleTools have been very
- Xpleased with this idea and have saved many hours of studying and
- Xprogramming. To those people, thanks for your letters, they are very
- Xhighly appreciated.
- X
- X Erik
- X
- XP.S. If you don't have access to the network library, feel free to send a
- Xself-addressed, stamped envelope and a disk (full of any goodies you have)
- Xto Erik Kilk, 1325 Nord Ave #155, Chico, CA 95926, and I'll copy my master
- Xdisk for you.
- ________This_Is_The_END________
- if test `wc -l < STools.info` -ne 84; then
- echo 'shar: STools.info was damaged during transit'
- echo ' (should have been 84 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting SimpleDemo.c'
- if test -f SimpleDemo.c; then echo 'shar: will not overwrite SimpleDemo.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > SimpleDemo.c
- X
- X/*
- X Title : SimpleDemo.c
- X Author : Erik Kilk
- X Date : June 9, 1985
- X Revised : July 17, 1985
- X
- X Synopsis: A demonstration of the use of SimpleTools with
- X other toolbox calls. This demonstrates a very
- X advanced use of SimpleTools. I've always disliked
- X being given simple examples. So, this example
- X uses many, many optional features of SimpleTools.
- X
- X The SimpleTools routines are being freely distributed.
- X You may use them, distribute your applications which use them,
- X and copy them if you send $10 or more to:
- X
- X Erik Kilk
- X 325 San Leandro Way
- X San Francisco, CA 94127
- X
- X Link this demonstration program with SimpleTools.o.
- X
- X*/
- X
- X#define TRUE -1 /* Common boolean constants */
- X#define FALSE 0
- X
- X/*******************************/
- X/* INCLUDE FILES FOR TOOLBOX */
- X/*******************************/
- X
- X#include <qd.h>
- X#include <event.h>
- X#include <mem.h>
- X#include <font.h>
- X#include <qdvars.h>
- X#include <misc.h>
- X#include <win.h>
- X#include <string.h>
- X#include <stdio.h>
- X
- X/***********************************************/
- X/* DEFINITIONS FOR THE SIMPLETOOLS MENU CALL */
- X/***********************************************/
- X
- X#define itemdisable 0L
- X#define itemenable 1L
- X#define itemcheck 2L
- X#define itemuncheck 3L
- X
- X/**************************************/
- X/* GLOBAL VARIABLES AND FUNCTIONS */
- X/**************************************/
- X
- Xint circspeed = 50; /* rate of drawing new circles */
- Xint ourpensize = 1; /* global pen size instead of windows */
- Xrect drag; /* for moving our free mem manually */
- X
- Xextern windowptr windowpoint(); /* defined in SimpleTools */
- Xextern char applestring[]; /* defined in SimpleTools */
- Xextern int windmenu; /* defined in SimpleTools */
- Xextern int dogoaway; /* defined in SimpleTools */
- Xextern int wprocid; /* defined in SimpleTools */
- X
- X/*********************/
- X/* Odds and Ends */
- X/*********************/
- X
- Xleave() /* Attached to the Quit menu */
- X{
- X exit(0);
- X}
- X
- Xnop() /* Attached as a null pointer */
- X{
- X}
- X
- X/******************************/
- X/* Clear the front window */
- X/******************************/
- X
- Xourclear() /* attatched to Clear during sketching */
- X{
- X rect therect; /* rectangle to clear */
- X if ((long)frontwindow() != 0L) { /* if there is a front window */
- X setport (frontwindow()); /* set it for output */
- X setrect ( &therect, 0, 0, 512, 400);/* make a rectangle */
- X fillrect ( &therect, qdvars.qdwhite); /* erase the rectangle in window */
- X }
- X}
- X
- X/***********************/
- X/* Sketch Window */
- X/***********************/
- X
- Xsketactivate() /* Attached to sketch's activate */
- X{ /* Disable the whole sketch menu */
- X menu ("Sketch", "", itemenable);
- X menu ("Edit", "Clear", ourclear); /* put our clear routine into place */
- X}
- X
- Xsketdeactivate() /* Attached to sketch's deactivate */
- X{ /* Enable the whole sketch menu */
- X menu ("Sketch", "", itemdisable);
- X menu ("Edit", "Clear", nop); /* take off our clear routine */
- X}
- X
- Xsketch(x,y) /* follow mouse while it's down */
- Xint x,y; /* we will get passed the mouse point */
- X{
- X point xy, lastxy; /* points of interest */
- X windowptr ourport;
- X
- X getport (&ourport);
- X pensize (ourpensize, ourpensize);
- X moveto (x, y); /* position pen at mouse down point */
- X while ( stilldown() ) { /* while the button is pressed */
- X getmouse (&xy); /* read the mouse position */
- X if ( (xy.a.v != lastxy.a.v) || (xy.a.h != lastxy.a.h) ) {
- X lineto (xy.a.h, xy.a.v); /* if mouse moved, draw a line to it */
- X lastxy.a.v = xy.a.v; /* record position so we can detect */
- X lastxy.a.h = xy.a.h; /* a move. */
- X } /* could runruns here to have circles */
- X runruns(0L);
- X setport (ourport);
- X }
- X}
- X
- Xsetpensize(size) /* Attached to pen size menus */
- Xchar *size; /* menu item name given to us */
- X{
- X static char lastsize[5]={'1','\0'}; /* keep last setting */
- X menu ("Sketch", lastsize, itemuncheck); /* remove old check mark */
- X menu ("Sketch", size, itemcheck); /* install a new check mark */
- X strcpy (lastsize, size); /* save size for the next setpensize */
- X ourpensize = atoi (size); /* convert to a number */
- X}
- X
- X/**************************/
- X/* The Circles Window */
- X/**************************/
- X
- Xint newabs(x) /* an absolute value funtion */
- Xint x;
- X{
- X if (x < 0)
- X x = -x;
- X return (x);
- X}
- X
- Xcircles() /* draw a random sized circle */
- X{
- X static windowptr wind = (windowptr) 0; /* keep "circle" windowptr */
- X static int speed = 1; /* current count between new circles */
- X register int cx, cy; /* center of the circle */
- X int r, b, rd; /* right and bottom edges */
- X register pattern *color; /* color for the circle */
- X rect therect; /* rectangle to draw circle in */
- X if ( --speed == 0) { /* count, and if it reaches zero... */
- X speed = circspeed; /* reset the count */
- X if ((long)wind == 0L) /* get window pointer if we need */
- X wind = windowpoint ("Circles"); /* save window for next time */
- X setport (wind); /* set output to the circle window */
- X r = wind->portrect.a.right; /* get current size of window */
- X b = wind->portrect.a.bottom;
- X cx = newabs(random()) % (r-30) + 1; /* pick a random location */
- X cy = newabs(random()) % (b-30) + 1;
- X rd = newabs(random()) % 25 + 5; /* and size */
- X setrect ( &therect, cx, cy, cx+rd, cy+rd); /* make a rectangle */
- X switch ( newabs(random()) % 4) { /* pick a color */
- X case 0: color = (pattern *)(&dkgray); break;
- X case 1: color = (pattern *)(<gray); break;
- X case 2: color = (pattern *)(&gray); break;
- X case 3: color = (pattern *)(&black); break;
- X }
- X filloval ( &therect, color); /* make the circle */
- X }
- X}
- X
- Xsetspeed(name) /* attached to circle's menu */
- Xchar *name;
- X{
- X menu ("Circles","Slow/S", itemuncheck); /* another way to uncheck last */
- X menu ("Circles","Medium/M", itemuncheck); /* just uncheck everything */
- X menu ("Circles","Fast/F", itemuncheck);
- X menu ("Circles", name, itemcheck); /* then check the current */
- X if (strcmp("Slow/S", name) ==0) circspeed = 100; /* set the reset count */
- X else if (strcmp("Medium/M", name) ==0) circspeed = 50;
- X else if (strcmp("Fast/F", name) ==0) circspeed = 1;
- X}
- X
- X/***********************************************/
- X/* Generate a new sketch window by command */
- X/***********************************************/
- X
- Xnwindow() /* command to attatch to new window menu */
- X{
- X static topplace = 100; /* remember where to put next window */
- X char newname[255]; /* string storage for window's name */
- X strcpy (newname, "New Window"); /* default window name */
- Xretry: /* prompt for the name from user */
- X if (prompt ("Give me a unique name for the new window:", newname)) {
- X if ( (long)windowpoint(newname) != 0L ) {
- X if (message ("Sorry, a window by that name already exists."))
- X goto retry; /* if exists, ask for another name */
- X } else {
- X if ( strlen(newname) > 0) { /* if ok, make the new window */
- X /* then it is new */
- X window (newname, 20,topplace, 200,topplace+60,
- X sketactivate, sketdeactivate, nop, sketch);
- X topplace += 5; /* adjust top for next new window */
- X if (topplace > 300) topplace = 100; /* reset top if too low */
- X }
- X }
- X }
- X}
- X
- X/**********************/
- X/* About SimpleDemo */
- X/**********************/
- X
- Xusageinfo() /* messages for Usage Info menu choice */
- X{
- X char mess[255]; /* string to form a message */
- X strcpy (mess,"You may use, distribute your programs which use, ");
- X strcat (mess,"and copy SimpleTools if you send ");
- X strcat (mess,"$10 or more to ...");
- X if (message (mess)) { /* if OK pressed for first message */
- X strcpy (mess, "Erik Kilk\r325 San Leandro Way\r");
- X strcat (mess, "San Francisco, CA 94127");
- X if (message (mess)) /* if OK pressed for 2nd message */
- X message ("Thank you for your support."); /* show final message */
- X }
- X}
- X
- Xtellabout() /* for the About SimpleDemo menu choice */
- X{
- X char mess[255]; /* string to form a message */
- X strcpy (mess,"SimpleDemo -- Copyright 1985 Erik Kilk\r");
- X strcat (mess,"A demonstration of the use of SimpleTools");
- X strcat (mess," as a Macintosh toolbox aid.");
- X if (message (mess)) /* display the string in a dialog */
- X usageinfo();
- X}
- X
- X/**************************/
- X/* The free memory window */
- X/**************************/
- X
- Xwritemem(forsure) /* write the freemem value */
- Xint forsure; /* true if force write */
- X{ /* false if only on change */
- X static long lastmem;
- X long mem;
- X int foo;
- X char thestring[10], outstr[10];
- X rect erasearea;
- X mem = freemem(); /* get new free memory */
- X foo = mem != lastmem; /* compare it to last reading */
- X if ( forsure | foo ) { /* if forsure or different */
- X withwindow ("FreeMem"); /* set window for output */
- X setrect (&erasearea, 0, 0, 100, 20);
- X eraserect (&erasearea); /* erase old value */
- X moveto (0, 12); /* write new value */
- X numtostring (mem, thestring);
- X strcpy (outstr, " Free ");
- X strcat (outstr, thestring);
- X drawstring (outstr);
- X lastmem = mem; /* record this for next time */
- X }
- X}
- X
- Xshowmem(windp) /* write freemem on an update */
- Xwindowptr windp;
- X{
- X endupdate (windp); /* allow use of entire window */
- X writemem(TRUE); /* clear and write new value */
- X beginupdate (windp);
- X}
- X
- Xnewmemvalue() /* write freemem occasionally */
- X{
- X writemem(FALSE); /* write only if value changed */
- X}
- X
- X/* This is a special, non-standard, method of moving a window. Our
- X free memory window does not have a title bar. So, I have decided
- X to allow it to be moved if the mouse is clicked in its content
- X region. This routine is attached to the free memory in content
- X procedure with SimpleTools. SimpleTools convenienly gives us
- X various parameters, here we need the window pointer and the event
- X record. The event record has the coordinates of the mouse in
- X globals */
- X
- Xmovemem(x,y,windp,event) /* free mem's incontent procedure */
- Xint x,y; /* SimpleTools gives us these for */
- Xwindowptr windp; /* an in-content procedure */
- Xeventrecord *event;
- X{
- X dragwindow (windp, &(event->where), &drag);
- X}
- X
- X/**********************/
- X/* Initialization */
- X/**********************/
- X
- Xsetup() /* to be called with Start Demo menu choice */
- X{
- X int temp;
- X setrect (&drag, 4, 24, 508, 338); /* drag area for free mem window */
- X windmenu = FALSE; /* modify default values, optional */
- X dogoaway = FALSE; /* optional change */
- X window("Circles", 20, 55, 245, 315,nop, nop, nop, nop); /* circles */
- X temp = wprocid; /* save value for an optional change */
- X wprocid = 3; /* optional change to set to altDBoxProc */
- X window ("FreeMem", 407, 322, 497, 337, nop, nop, showmem, movemem);
- X wprocid = temp; /* return to defaults */
- X windmenu = TRUE;
- X dogoaway = TRUE;
- X window ("Sketch", 265, 55, 490, 315,sketactivate,sketdeactivate,
- X nop, sketch); /* display the sketch pad window */
- X menu ( applestring, "About SimpleDemo", tellabout);
- X menu ( applestring, "About SimpleDemo", itemenable);
- X menu ( "File", "New", nwindow); /* setup File menu */
- X menu ( "File", "New", itemenable);
- X menu ( "File", "Quit", leave);
- X menu ("Circles", "Speed", itemdisable); /* install circles menu */
- X menu ("Circles", "Slow/S", setspeed); /* optional key equivs */
- X menu ("Circles", "Medium/M", setspeed);
- X menu ("Circles", "Fast/F", setspeed);
- X menu ("Circles", "Medium/M", itemcheck);
- X menu ("Sketch", "Pen Size", itemdisable); /* install sketches menu */
- X menu ("Sketch", "", itemdisable);
- X menu ("Sketch", "1", setpensize);
- X menu ("Sketch", "1", itemcheck);
- X menu ("Sketch", "2", setpensize);
- X menu ("Sketch", "3", setpensize);
- X menu ("Sketch", "4", setpensize);
- X menu ("Sketch", "5", setpensize);
- X menu ("Sketch", "6", setpensize);
- X run (circles); /* keep drawing circles */
- X run (newmemvalue); /* check if mem changed occasionally */
- X}
- X
- Xmain()
- X{
- X simpletools("About SimpleDemo"); /* setup Apple and Edit menus */
- X setup(); /* setup our program */
- X for (;;) simpleevents(); /* process events */
- X}
- ________This_Is_The_END________
- if test `wc -l < SimpleDemo.c` -ne 351; then
- echo 'shar: SimpleDemo.c was damaged during transit'
- echo ' (should have been 351 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting SimpleTools.c'
- if test -f SimpleTools.c; then echo 'shar: will not overwrite SimpleTools.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > SimpleTools.c
- X
- X/*
- X Title : SimpleTools.c
- X Author : Erik Kilk Copyright 1985
- X Date : June 7, 1985
- X
- X Version : 1.2
- X Revisions:
- X 09/05/85 EK Removed fix needed for a old compiler bug
- X 07/13/85 EK Fixed menu unhilighting with D.A.'s menus.
- X 07/16/85 EK Resettable default for new window type and has goaway.
- X Included menu command key usage.
- X 07/17/85 EK Removed menu changes to avoid flicker.
- X Added return codes to most functions.
- X Fixed in-content call from changing event record.
- X
- X Synopsis: A collection of subroutines to simplify programming
- X the Macintosh in C. These are for those little programs
- X you are tempted not to write because of all the hassles
- X you have to go through writing programs for the Macintosh
- X environment.
- X
- X Copyright: These routines are copyrighted by Erik Kilk. You
- X may use them for your programming, as examples for your
- X own programming, in your programs, in programs you
- X distribute, copy them, and give copies to others who will
- X abide by these rules if you send $10 or more to:
- X Erik Kilk
- X 325 San Leandro Way
- X San Francisco, CA 94127
- X You use this software "as is". The author make no
- X promises and is not responsible nor liable for anything
- X due to your use of these subroutines.
- X
- X Thank you for your support.
- X
- X
- X Summary of User Routines:
- X
- X simpletools ("About SimpleTools"); Initialize
- X simpleevents (); Process next event
- X menu ("Search", "Find", findroutine); Add a menu
- X window ("Sketch", 50,50,200,200,
- X activate,deactivate,update,content); Add a window
- X withwindow ("Sketch"); Set output to window
- X run (routine); Periodically call a routine
- X stop (routine); Stop periodic call
- X message ("Welcome to SimpleTools"); Display dialog message
- X prompt ("What is your name?", answer); Ask a question
- X
- X simpletools("Name");
- X Call this once at the very beginning of your program. Pass
- X it the name of your program if you want an "About Name" menu
- X entry, otherwise pass it just "" as the name. It initializes
- X the data structures used by SimpleTools. It also does all of
- X the toolbox initializing and
- X installs the Apple, File, and Edit menus. Only base pointers
- X to linked structures and a few flags and scratch variables are
- X set. All other data is dynamically allocated with relocatable
- X blocks through the Macintosh memory manager for each new menu
- X and window created with these SimpleTools routines.
- X
- X simpleevents();
- X Repeatedly call this routine as fast as you can. Often this
- X routine is in a for(;;) loop in the main procedure. This routine
- X handles menu selection, desk accessory startups, window moves,
- X window resizes, close-box clicks, all window events, and the
- X periodic calling of routines. It will only handle menus, windows,
- X and periodic routines installed with simpletools(), menu(),
- X window(), and run().
- X This routine does the systemtask() and getnextevent() calls
- X so you don't have to process them yourself.
- X At times simpleevents() will be looking up assigned procedures
- X to be executed. These procedures are passed some of information
- X particular to its situation. With Magamax C (and possibly others)
- X the called procedure need not declare or use this passed data if
- X it has no need for it. The kind of data passed is described below.
- X For key down and autokey events, the procedures set in
- X keydownproc and autokeyproc are passed the address to the event
- X record. By default, keydownproc and autokeyproc are set to
- X a no op procedure.
- X
- X menu ("Settings", "Trace Execution", hideproc );
- X Call this routine for each menu to install or modify. The
- X first argument is the menu bar title, the second is the item name,
- X and the third is either the procedure to be executed when that
- X item is selected or a modifier ( 0L, itemdisable; 1L, itemenable;
- X 2L, itemcheck, 3L, itemuncheck). The first call with a particular
- X menu/item pair will install the menu/item with either a procedure
- X or modifier (in which case it is assigned a no op procedure.)
- X Subseqent calls are used to change either the assigned procedure or
- X the current active modifiers. Calling it with a null item name
- X will disable or enable the entire menu if the menu already exists
- X and the third parameter is either a 0L or 1L as listed above.
- X Assigned procedures will be called with a (char *) pointing to
- X the item name chosen.
- X
- X menuhandle mhand ("Settings");
- X This function returns the handle to a given menu bar selection
- X so that you can call the Menu manager routines yourself.
- X
- X window ("Trace Output", 256, 50, 500, 300, activateproc,
- X deactivateproc, updateproc, incontentproc);
- X Call this routine for each window to install or modify. The
- X first argument is the window's name. Then the (x,y) of the top
- X left corner and the (x,y) of the bottom right corner. These
- X coordinates are only used for installing a window and will be
- X ignored for subsequent calls. Then comes four procedure names.
- X Activateproc is called when the window becomes the active window.
- X Deactivate when another window is activated. Updateproc when
- X windows have moved and the window needs redrawn. And incontentproc
- X when the mouse is clicked inside the window.
- X New windows are given a menu selection of their name under
- X a menu bar title of "Windows." Menu() is used to install these.
- X The procedure called for each window name is a procedure to
- X bring back the window if it was closed by clicking its closebox or
- X activate it (in case it is hidden and can't be clicked on.
- X When the close-box of a window is clicked, the window is just
- X hidden, it isn't really closed.
- X The assigned "in content" procedure will be called with two
- X (int)s. The x and y of the mouse position in that window's
- X local coordinates. Each assigned window procedure is also called
- X with a (windowptr) to the target window and an address to
- X the event record which just occured. Before each is called,
- X the current port is set to the target window.
- X
- X withwindow ("Trace Output");
- X Call this routine to set the current output port to the
- X asked for window. Remember that proper scrolling of text in the
- X window is only taken care of for the active window though output
- X can be to any window.
- X
- X windowptr windowpoint ("Trace Output");
- X This function returns a pointer to the given window name in
- X case you want to use one of the Window manager routines your
- X self.
- X
- X run (flashsquareproc);
- X Call this routine to install a procedure to be periodically
- X executed. Up do 100 procedures may be installed at once. These
- X procedure are called just after each i/o event is read. They are
- X called with the address of the current unprocessed eventrecord.
- X
- X stop (flashsquaresproc);
- X Call this to remove a procedure from the list of procedures
- X running periodically as installed with run().
- X
- X message ("Are you sure you want to quit?");
- X Puts up a dialog with your message and an OK and Cancel
- X button. Returns true if OK is clicked, false if Cancel hit.
- X Memory for the dialog is allocated when it is put up and
- X returned to the heap when a button is clicked.
- X
- X prompt ("What is your name?", answer);
- X Where answer is a string set to a default value. Puts up
- X a dialog with your question, an editable answer field with you
- X default answer, the OK and Cancel buttons. Returns true when
- X OK or RETURN is entered, false if Cancel is clicked.
- X*/
- X
- Xoverlay "simpletools" /* remove or change this if needed */
- X
- X#include <mem.h> /* include type defs and constants */
- X#include <qd.h> /* for the Macintosh tool box */
- X#include <qdvars.h>
- X#include <misc.h>
- X#include <event.h>
- X#include <res.h>
- X#include <win.h>
- X#include <te.h>
- X#include <dialog.h>
- X#include <menu.h>
- X#include <string.h>
- X#include <stdio.h>
- X
- X#define TRUE (-1) /* local definitions */
- X#define FALSE 0
- X#define itemdisable 0 /* constants for menu modifiers */
- X#define itemenable 1
- X#define itemcheck 2
- X#define itemuncheck 3
- X#define maxsruns 50 /* procedure table size */
- X#define MESSN 30 /* array size for message dialog items */
- X#define QUESN 40 /* array size for prompt dialog items */
- X
- Xtypedef struct { /* structure for an item */
- X char itemname[40]; /* to allow reference by name */
- X int itemno; /* item number within menu */
- X int menuid; /* menu id in case menu info is needed */
- X menuhandle menuhand; /* item's menu's handle */
- X procptr menurun; /* procedure to run */
- X ptr next; /* pointer to the next item */
- X} itemdatum;
- X
- Xtypedef struct { /* structure for a menu */
- X char menuname[20]; /* to allow reference by name */
- X int menuid; /* menu id used to create the menu */
- X menuhandle menuhand; /* menu handle used to reference menu */
- X itemdatum **itemlist; /* pointer to the list of items */
- X ptr next; /* pointer to the next menu */
- X} menudatum;
- X
- Xtypedef struct { /* structure for a window */
- X char windname[80]; /* the window's name and reference */
- X windowptr wptr; /* the window's pointer reference */
- X procptr wact; /* the activate procedure */
- X procptr wdeact; /* the deactivate procedure */
- X procptr wupdate; /* the update procedure */
- X procptr wcontent; /* the content procedure */
- X ptr next; /* pointer to the next window */
- X} winddatum;
- X
- Xmenudatum **simplemenus; /* handle to menu data */
- Xchar accname[80]; /* desk accessory name to open */
- Xrect dragrect, sizerect; /* limits for moving windows */
- Xint wprocid = documentprod; /* window procedure id */
- Xint dogoaway = TRUE; /* if window has go away box */
- Xwinddatum **simplewinds; /* handle to window data */
- Xint firstwind; /* true if no windows have been made */
- Xprocptr keydownproc,
- X autokeyproc; /* routines for key down events */
- Xprocptr simpleruns[maxsruns]; /* list of procedures to run */
- Xchar applestring[2]
- X = {'\024', '\0'}; /* name of apple menu */
- Xwindowptr debugw; /* a window pointer for debugging */
- Xint windmenu = TRUE; /* whether or not a window menu is made */
- X
- X/******************************************************************/
- X/* Dialog lists. These were calculated by using the new resource */
- X/* editor to make a template for a dialog and then using fedit to */
- X/* list the hex listing of the item list for the dialog. */
- X/******************************************************************/
- X
- Xint messd[MESSN] = {2,0,0,0x38,0xf1,0x4c,0x12d,0x402,0x4f4b,0,0,5,5,
- X 0x36,0x12d,0x800,0,0,0x38,0xac,0x4c,0xe8,0x406,
- X 0x4361,0x6e63,0x656c};
- Xint quesd[QUESN] = {3,0,0,0x21,0xf0,0x35,0x12c,0x402,0x4f4b,0,0,8,8,
- X 0x28,0xe8,0x800,0,0,0x2b,8,0x4b,0xe8,0x1000,0,0,
- X 8,0xf0,0x1c,0x12c,0x406,0x4361,0x6e63,0x656c};
- X
- Xstnop() /* a no op procedure for defaults */
- X{
- X}
- X
- X/* Given a menu name, find our data structure for it. Return a handle
- X to this structure.
- X*/
- X
- Xmenudatum **getourmenuhandle (name)
- Xchar *name; /* name of menu bar menu */
- X{
- X menudatum **here; /* a handle to our menu structure */
- X here = simplemenus;
- X
- X /* find the menu name or the end of out menu list */
- X while ( (strcmp(name,(**here).menuname) != 0) &
- X ((**here).next != (ptr)0L) )
- X here = (menudatum **)(**here).next;
- X
- X /* see if we found it or just the end of the list */
- X if (strcmp(name,(**here).menuname) == 0)
- X return (here);
- X else
- X return ((menudatum **)0L); /* return 0 if not found */
- X}
- X
- X/* Given a menu name, return the real menu handle as used by most
- X of the Macintosh toolbox menu manager routines.
- X*/
- X
- Xmenuhandle mhand (name) /* find menuhandle */
- Xchar *name; /* given name of menu */
- X{
- X menudatum **menu; /* a handle to our data */
- X menu = getourmenuhandle(name);
- X if ( (long) menu != 0L )
- X return ( (**menu).menuhand); /* return menu handle */
- X else
- X return ( (menuhandle) 0 ); /* return 0 if not found */
- X}
- X
- X/* This takes a handle to our personal item record and either a
- X procedure name or a modifier code. If it got a procedure name,
- X it sets it to the item's procedure to run when the item is chosen.
- X If it got a modifier code, it changes the state of the menu's item
- X to checked, unchecked, enabled, or disabled. It especially keeps
- X track of the standard Edit menu items so we can restore them after
- X a desk accessory is finished.
- X*/
- X
- Xsetitem ( items, routine) /* set a menu item's routine or display */
- Xitemdatum **items; /* if items is neg, then whole menu */
- Xprocptr routine;
- X{
- X int inumber;
- X menuhandle mhand;
- X
- X /* check to see if a procedure pointer was given to us */
- X if ( (((long)items)>0L) && (routine > (procptr)0x1000L)) {
- X /* a good procedure value */
- X (**items).menurun = routine;
- X return;
- X }
- X
- X /* Calculate which item number we are going to modify */
- X if ( (long)items < 0L) { /* the whole menu */
- X mhand = (menuhandle) (0L - (long)items);
- X inumber = 0;
- X }
- X else { /* just one item */
- X mhand = (**items).menuhand;
- X inumber = (**items).itemno;
- X }
- X
- X /* If a NULL procedure pointer, then set to a no_op routine */
- X if ( (inumber > 0) && ((**items).menurun == (procptr)0L) )
- X (**items).menurun = stnop;
- X
- X /* Now change the state of a menu item */
- X switch ((int)routine) {
- X case itemdisable:
- X disableitem(mhand,inumber); break;
- X case itemenable:
- X enableitem(mhand, inumber); break;
- X case itemcheck:
- X checkitem(mhand, inumber, TRUE); break;
- X case itemuncheck:
- X checkitem(mhand, inumber, FALSE); break;
- X }
- X if (inumber == 0) drawmenubar(); /* if main menu was changed */
- X
- X}
- X
- X/* This routine is described above. It takes care of our menu data
- X structure by adding or modifying menu entries.
- X*/
- X
- Xmenu (name, item, routine) /* install or change a menu */
- Xchar *name; /* the menu name */
- Xchar *item; /* the item name */
- Xchar * routine; /* a procedure or modifier */
- X{
- X menudatum **here; /* a roving handle to our data */
- X menudatum **ourmhandle; /* another handle to our data */
- X itemdatum **items; /* a handle to the item */
- X menuhandle mhandle; /* a handle to the real menu */
- X int lastid, lastitem;
- X
- X /* get the handle to menu named 'name' */
- X if ((ourmhandle = getourmenuhandle (name)) == 0L) {
- X
- X /* make a new menu entry by finding the end of the list */
- X here = simplemenus;
- X while ((**here).next != 0L)
- X here = (menudatum **)(**here).next;
- X
- X /* make a structure for our new entry */
- X lastid = (**here).menuid;
- X (**here).next = (ptr)newhandle ( (long)sizeof(menudatum));
- X here = (menudatum **)(**here).next;
- X strcpy ( (**here).menuname, name);
- X (**here).menuid = ++lastid;
- X (**here).next = (ptr) 0L;
- X
- X /* make a new item structure */
- X (**here).itemlist = (itemdatum **)newhandle (
- X (long)sizeof(itemdatum));
- X
- X /* make a new menu entry for the Macintosh */
- X (**here).menuhand = newmenu (lastid, name);
- X mhandle = (**here).menuhand;
- X items = (**here).itemlist;
- X strcpy ((**items).itemname, item);
- X (**items).itemno = 1;
- X (**items).menuid = lastid;
- X (**items).menuhand = (**here).menuhand;
- X (**items).menurun = (procptr) 0L;
- X (**items).next = 0L;
- X
- X /* install and display the menu */
- X appendmenu ((**here).menuhand, item);
- X insertmenu ((**here).menuhand,0);
- X setitem (items, routine);
- X drawmenubar();
- X return(TRUE);
- X }
- X else {
- X if (strlen(item) == 0) {
- X /* then adjust main menu */
- X setitem( 0L - (long) ((**ourmhandle).menuhand), routine);
- X return(FALSE);
- X }
- X /* see if item is in list */
- X items = (**ourmhandle).itemlist;
- X while ( (strcmp(item,(**items).itemname) != 0) &
- X ((**items).next != (ptr)0L)) {
- X items = (itemdatum **)(**items).next;
- X }
- X if (strcmp(item,(**items).itemname) ==0) {
- X setitem( items, routine);
- X return(FALSE);
- X }
- X else {
- X /* make new item entry */
- X lastitem = (**items).itemno;
- X (**items).next =(ptr)newhandle(
- X (long)sizeof(itemdatum));
- X items = (itemdatum **)(**items).next;
- X strcpy ((**items).itemname, item);
- X (**items).itemno = ++lastitem;
- X (**items).menuid = (**ourmhandle).menuid;
- X (**items).menuhand = (**ourmhandle).menuhand;
- X (**items).menurun = (procptr) 0L;
- X (**items).next = 0L;
- X
- X /* and install the item in the menu bar */
- X appendmenu ((**ourmhandle).menuhand,item);
- X setitem (items, routine);
- X return(TRUE);
- X }
- X }
- X}
- X
- X/* This routine is called by the simpletools() initial routine. It gets
- X the pointer list of menus started, loads the desk accessories into
- X the Apple menu, and loads up some standard menu entries. The reason
- X menu File has a New entry, and none others, is because as this code
- X currently stands, a menu must have at least one item. And since we
- X want File before Edit, I had to make an entry. The most commonly used
- X item under File is Quit. But we like quit to be at the end of the list.
- X So, since New is usually always first when it is used, that the one
- X chosen to start File.
- X*/
- X
- Xinitsmenus(about) /* init simpletools' menus */
- Xchar *about;
- X{
- X itemdatum **items;
- X simplemenus = (menudatum **) newhandle ( (long)sizeof(menudatum));
- X strcpy ( (**simplemenus).menuname, applestring);
- X (**simplemenus).menuid = 1;
- X (**simplemenus).next = (ptr) 0L;
- X (**simplemenus).menuhand = newmenu (1, (**simplemenus).menuname);
- X (**simplemenus).itemlist = (itemdatum **)newhandle (
- X (long)sizeof(itemdatum));
- X items = (itemdatum **) (**simplemenus).itemlist;
- X strcpy ((**items).itemname, about);
- X (**items).itemno = 1;
- X (**items).menuid = 1;
- X (**items).menuhand = (**simplemenus).menuhand;
- X (**items).menurun = stnop;
- X (**items).next = 0L;
- X appendmenu ((**simplemenus).menuhand, about);
- X disableitem ((**simplemenus).menuhand, 1);
- X menu (applestring, "-", (procptr) itemdisable);
- X addresmenu ((**simplemenus).menuhand, "DRVR");
- X insertmenu ((**simplemenus).menuhand, 0);
- X menu ("File", "New", (procptr)itemdisable);
- X menu ("Edit", "Undo", stnop);
- X menu ("Edit", "-", (procptr)itemdisable);
- X menu ("Edit", "Cut/X", stnop);
- X menu ("Edit", "Copy/C", stnop);
- X menu ("Edit", "Paste/V", stnop);
- X menu ("Edit", "Clear", stnop);
- X}
- X
- X/* Given a window's name, return its window pointer so that other
- X Macintosh Window Manager routines can be called for that window. */
- X
- Xwindowptr windowpoint(name) /* get window pointer */
- Xchar *name; /* given window's name */
- X{
- X winddatum **wind; /* handle to our window data */
- X if (firstwind) return ((windowptr)0); /* forget if there aren't any */
- X wind = simplewinds; /* look for the named window */
- X while ( (strcmp ((**wind).windname, name) != 0) &
- X ((**wind).next != (ptr) 0)) {
- X wind = (winddatum **) (**wind).next;
- X }
- X if ( strcmp ((**wind).windname, name) ==0)
- X return ( (**wind).wptr); /* return pointer */
- X else
- X return ( (windowptr) 0); /* or zero if it wasn't found */
- X}
- X
- X/* This routine is for the Windows menu item. The Windows menu is
- X set up when new windows are added. It is used to bring forward and
- X bring into view windows that may be under other windows or have been
- X sent hiding by a click on their close box.
- X*/
- X
- Xshowawindow(name) /* show the named window */
- Xchar *name;
- X{
- X windowptr foo;
- X foo = windowpoint(name); /* get its window pointer */
- X if ( (long)foo != 0L ) {
- X showwindow(foo); /* show it on the screen */
- X setport (foo); /* set further output to it */
- X if ( foo != frontwindow()) /* if it isn't active, */
- X selectwindow (foo); /* activate it */
- X }
- X}
- X
- X/* This routine installs a new window onto the screen. It also gives
- X that window an item in the Window menu. This routine is also used
- X to modify a window's associated routines. The x,y positions are the
- X top left and bottom right corners of where the window should originally
- X be placed. The coordinates are never used when this routine is called
- X to update an already existing window. But the spaces must be filled,
- X so you can use zeros if you want. Once the window has been displayed in
- X its original position, the user has complete control of its size and
- X placement with the mouse.
- X*/
- X
- Xwindow(name, xtop, ytop, xbot, ybot, a, d, u, c)
- Xchar *name; /* window's name */
- Xint xtop, ytop, xbot, ybot; /* position if this is a new window */
- Xprocptr a, d, u, c; /* activate, deactivate, update, and */
- X{ /* content procedure names */
- X winddatum **wind; /* handle to our window data */
- X winddatum **newentry; /* another handle */
- X rect newplace; /* a rectable for the window's placement */
- X if (a == (procptr) 0)
- X a = stnop;
- X if (d == (procptr) 0)
- X d = stnop;
- X if (u == (procptr) 0)
- X u = stnop;
- X if (c == (procptr) 0)
- X c = stnop;
- X if ( !firstwind ) {
- X
- X /* see if window is in the list */
- X wind = simplewinds;
- X while ( (strcmp ((**wind).windname, name) != 0) &
- X ((**wind).next != (ptr) 0)) {
- X wind = (winddatum **) (**wind).next;
- X }
- X if ( strcmp ((**wind).windname, name) ==0) {
- X
- X /* reset the found window's parameters */
- X (**wind).wact = (procptr) a;
- X (**wind).wdeact = (procptr) d;
- X (**wind).wupdate = (procptr) u;
- X (**wind).wcontent = (procptr) c;
- X setport ( (**wind).wptr); /* set output to window */
- X return(FALSE);
- X }
- X }
- X
- X /* make a new window entry */
- X newentry = (winddatum **)newhandle ( (long) sizeof (winddatum));
- X if (firstwind)
- X simplewinds = newentry;
- X else
- X (**wind).next = (ptr) newentry;
- X firstwind = 0;
- X strcpy ((**newentry).windname, name);
- X setrect (&newplace, xtop, ytop, xbot, ybot);
- X (**newentry).wptr = newwindow (0L, &newplace, name, -1,
- X wprocid, -1L, dogoaway, newentry);
- X (**newentry).wact = (procptr) a;
- X (**newentry).wdeact = (procptr) d;
- X (**newentry).wupdate = (procptr) u;
- X (**newentry).wcontent = (procptr) c;
- X (**newentry).next = (ptr) 0;
- X if (windmenu)
- X menu ("Windows", name, showawindow);/* make a menu entry for it */
- X setport ( (**newentry).wptr); /* set output to it */
- X return(TRUE);
- X}
- X
- Xwinddatum **wdatum(windpt) /* return handle to window data */
- Xwindowptr windpt;
- X{
- X winddatum **wind;
- X if (firstwind) return ((winddatum **) 0L);
- X wind = simplewinds;
- X while ( ((**wind).wptr != windpt) & /* search for window's name */
- X ((**wind).next != (ptr) 0)) {
- X wind = (winddatum **) (**wind).next;
- X }
- X if ( (**wind).wptr == windpt)
- X return (wind);
- X else
- X return ((winddatum **) 0L); /* zero if not found */
- X}
- X
- Xwithwindow(name) /* set output to a window by name */
- Xchar *name; /* give it the window's name */
- X{ /* returns boolean if window exists */
- X winddatum **wind;
- X wind = simplewinds;
- X if (firstwind) return(FALSE); /* search for the window's name */
- X while ( (strcmp ((**wind).windname, name) != 0) &
- X ((**wind).next != (ptr) 0)) {
- X wind = (winddatum **) (**wind).next;
- X }
- X if ( strcmp ((**wind).windname, name) ==0) {
- X setport ( (**wind).wptr); /* set output to it */
- X return(TRUE);
- X }
- X else
- X return(FALSE);
- X}
- X
- X/* This run procedure is used to install routines to be occasionally
- X run. The routine will be run once for each call to simpleevents()
- X*/
- X
- Xrun(routine) /* install a run procedure */
- Xprocptr routine; /* give it the procedure */
- X{ /* return TRUE if successful */
- X int i;
- X i = 0; /* add it to the end of the list */
- X while ( simpleruns[i] != (procptr) 0L) i++;
- X if (i < maxsruns) {
- X simpleruns[i] = routine;
- X simpleruns[i+1] = (procptr) 0L;
- X return(TRUE);
- X }
- X else
- X return(FALSE);
- X}
- X
- X/* This routine removes a procedure from the list of run procedures */
- Xstop(routine) /* stop a procedure from running */
- Xprocptr routine; /* give the procedure */
- X{ /* return TRUE if successful */
- X int i;
- X i = 0;
- X while ( (simpleruns[i] != routine) & (simpleruns[i] != (procptr) 0L))i++;
- X if (simpleruns[i] == (procptr) 0L)
- X return(FALSE);
- X else {
- X while ( simpleruns[i] != (procptr)0 ) {
- X simpleruns[i] = simpleruns[i+1];
- X i++;
- X }
- X return(TRUE);
- X }
- X}
- X
- Xrunruns(event) /* run all the installed run procedures */
- Xeventrecord *event; /* returns number of routines run */
- X{
- X int i;
- X i = 0;
- X while ( simpleruns[i] != 0 )
- X (*(simpleruns[i++])) (event);
- X return(i);
- X}
- X
- Xstdialog( question, answer, type) /* a general dialog displayer */
- Xchar *question;
- Xchar *answer;
- Xint type; /* type: 1=prompt, 2=message */
- X{
- X dialogptr dialog; /* dialog reference */
- X handle item, items; /* handles for the dialog items */
- X rect screen, box; /* rectangles for dialog/items */
- X int dtype, hit, canc; /* item type and which was hit */
- X char tempanswer[255]; /* address where answer is */
- X
- X items = newhandle (512L); /* get memory for items list */
- X hlock (items); /* lock it down */
- X if (type == 1)
- X blockmove (quesd, *items, (long) QUESN * 2L); /* fill it with list */
- X else
- X blockmove (messd, *items, (long) MESSN * 2L);
- X setrect (&screen, 103, 50, 409, 137); /* position window */
- X dialog = newdialog (0L, &screen, "", 0, dboxproc, -1L, 0, 0L, items);
- X getditem (dialog, 2, &dtype, &item, &box); /* get item#2 handle */
- X setitext (item, question); /* set item#2 text */
- X if (type == 1) { /* set default answer */
- X getditem (dialog, 3, &dtype, &item, &box);
- X setitext (item, answer);
- X canc = 4;
- X }
- X else
- X canc = 3;
- X showwindow (dialog); /* display the dialog */
- X do {
- X modaldialog (0L, &hit); /* process the dialog */
- X } while ( (hit != 1) & (hit != canc) );
- X if (type == 1) {
- X getditem (dialog, 3, &dtype, &item, &box); /* get item#3 handle */
- X hlock (item);
- X getitext (item, tempanswer); /* get item#3 text */
- X strcpy (answer, tempanswer); /* make a copy of it */
- X hunlock (item);
- X }
- X hunlock(items); /* unlock items memory */
- X hpurge(items); /* purge it */
- X disposdialog (dialog); /* get rid of dialog */
- X return ( hit==1 ); /* return true if ok */
- X}
- X
- Xprompt ( question, answer) /* dialog box question/answer */
- Xchar *question;
- Xchar *answer;
- X{
- X return (stdialog (question, answer, 1));
- X}
- X
- Xmessage ( message ) /* dialog box message */
- Xchar *message;
- X{
- X return (stdialog (message, message, 2));
- X}
- X
- Xdocommand (which, thisevent)
- Xlong which;
- Xeventrecord *thisevent;
- X{
- X int themenu, theitem;
- X long size;
- X char *cpoint;
- X grafptr tempport;
- X menudatum **here;
- X itemdatum **items;
- X char **myreshandle;
- X handle myhandle;
- X themenu = hiword (which);
- X theitem = loword (which);
- X if ((themenu == 1) && (theitem != 1)) {
- X /* start up a desk accessory */
- X getitem ((**simplemenus).menuhand,
- X theitem, accname);
- X setresload (FALSE);
- X myreshandle = getnamedresource ("DRVR", accname);
- X setresload (TRUE);
- X size = sizeresource (myreshandle);
- X myhandle = newhandle ( size + 3072L);
- X if (myhandle == 0L)
- X message ("Not enough memory to do that.");
- X else {
- X disposhandle (myhandle);
- X getport (&tempport);
- X opendeskacc(accname);
- X setport (tempport);
- X }
- X return;
- X }
- X if (themenu ==3) {
- X /* do any system edits */
- X if (systemedit(theitem -1) != FALSE)
- X return;
- X }
- X
- X /* now we run an installed menu procedure */
- X here = simplemenus;
- X
- X /* find out menu structure given the menu id */
- X while ( ((**here).menuid != themenu) &
- X ((**here).next != (ptr)0L) )
- X here = (menudatum **)(**here).next;
- X
- X if ((**here).menuid == themenu) {
- X /* now find the item structure */
- X items = (**here).itemlist;
- X while ( ((**items).itemno != theitem) &
- X ((**items).next != (ptr) 0L) )
- X items = (itemdatum **)(**items).next;
- X
- X /* prepare to give the item name to the procedure */
- X cpoint = (**items).itemname;
- X if ((**items).itemno == theitem)
- X /* if we found the item, call its procedure */
- X (*((**items).menurun))(cpoint,thisevent) ;
- X }
- X}
- X
- Xdomousedown(thisevent) /* respond to mouse down events */
- Xeventrecord *thisevent; /* passed the event record */
- X{
- X windowptr whichwindow;
- X int code, x, y;
- X char *cpoint;
- X menudatum **omhand;
- X winddatum **thewdatum;
- X long newplace;
- X point temp;
- X code = findwindow(&(thisevent->where), &whichwindow);
- X switch (code) {
- X case inmenubar:
- X docommand(menuselect(&(thisevent->where)),thisevent);
- X break;
- X case insyswindow:
- X systemclick(thisevent, whichwindow); break;
- X case indrag:
- X dragwindow(whichwindow, &(thisevent->where),
- X &dragrect); break;
- X case ingrow:
- X newplace= growwindow(whichwindow, &(thisevent->where),
- X &sizerect);
- X sizewindow(whichwindow, loword(newplace),
- X hiword(newplace), TRUE);
- X break;
- X case ingoaway:
- X if ( trackgoaway(whichwindow, &(thisevent->where))) {
- X hidewindow (whichwindow);
- X }
- X break;
- X case incontent:
- X
- X /* make the window active if it isn't yet */
- X if (whichwindow != frontwindow()) {
- X selectwindow(whichwindow);
- X }
- X
- X /* find our window data */
- X thewdatum = wdatum (whichwindow);
- X if ((long) thewdatum != 0L) {
- X
- X /* convert the point of click to the window's
- X own coordinates since this will be always
- X more useful than the global coordintates */
- X temp = thisevent->where;
- X setport (whichwindow);
- X globaltolocal (&temp);
- X x = temp.a.h;
- X y = temp.a.v;
- X
- X /* call the window's in content routine */
- X (*((**thewdatum).wcontent))(x, y, whichwindow,
- X thisevent);
- X }
- X break;
- X }
- X}
- X
- Xsimpletools(about) /* to be called at the beginning of program */
- Xchar *about;
- X{
- X maxapplzone(); /* allow maximum heap expansion */
- X flushevents (everyevent,0); /* ignore left over events */
- X initgraf (&theport); /* initialize the screen */
- X initfonts();
- X initwindows();
- X initmenus();
- X initcursor(); /* make the arrow cursor */
- X teinit();
- X initdialogs(0L);
- X setrect ( &sizerect, 20, 50, 250, 330);
- X /*
- X debugw = newwindow(0L,&sizerect,"Debug",-1,documentproc,-1L,-1L,0L);
- X */
- X simpleruns[0] = (procptr) 0; /* empty the run list */
- X /* These are the bounds we are allowed to size a window or
- X move a window to.
- X */
- X setrect ( &sizerect, 20, 20, 511, 341);
- X setrect ( &dragrect, 4, 24, 507, 337);
- X firstwind = 1; /* empty window table */
- X keydownproc = stnop; /* default key hit procedures */
- X autokeyproc = stnop;
- X initsmenus(about); /* install the menus */
- X}
- X
- Xsimpleevents() /* to be called in the main loop */
- X{
- X eventrecord newevent;
- X winddatum **thewdatum;
- X systemtask(); /* Do the system D.A. etc. stuff */
- X hilitemenu(0);
- X getnextevent(everyevent, &newevent);
- X runruns(&newevent); /* Do our run procedures */
- X switch (newevent.what) {
- X case mousedown:
- X domousedown(&newevent); break;
- X case keydown:
- X if ((newevent.modifiers & cmdkey) != 0)
- X docommand(menukey((char)(newevent.message & 0xffL)),
- X &newevent);
- X (*(keydownproc))(&newevent);
- X break;
- X case autokey:
- X if ((newevent.modifiers & cmdkey) != 0)
- X docommand(menukey((char)(newevent.message & 0xffL)),
- X &newevent);
- X (*(autokeyproc))(&newevent);
- X break;
- X case activateevt:
- X thewdatum = wdatum(newevent.message);
- X if ((long)thewdatum != 0L) {
- X setport(newevent.message);
- X if ((newevent.modifiers & 1) == 1) {
- X (*((**thewdatum).wact))(newevent.message,
- X &newevent);
- X }
- X else {
- X (*((**thewdatum).wdeact))(newevent.message,
- X &newevent);
- X }
- X }
- X break;
- X case updateevt:
- X thewdatum = wdatum(newevent.message);
- X if ((long)thewdatum != 0L) {
- X setport (newevent.message);
- X beginupdate (newevent.message);
- X (*((**thewdatum).wupdate))(newevent.message,
- X &newevent);
- X endupdate (newevent.message);
- X }
- X break;
- X }
- X}
- X
- ________This_Is_The_END________
- if test `wc -l < SimpleTools.c` -ne 911; then
- echo 'shar: SimpleTools.c was damaged during transit'
- echo ' (should have been 911 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'Extracting SimpleTools.doc'
- if test -f SimpleTools.doc; then echo 'shar: will not overwrite SimpleTools.doc'; else
- sed 's/^X//' << '________This_Is_The_END________' > SimpleTools.doc
- X
- X
- XSimpleTools
- X
- XCopyright (c) 1985 Erik Kilk
- X
- X
- X
- X
- X
- XWhat is SimpleTools?
- X
- XSimpleTools is a collection of subroutines (presently written for the C
- Xlanguage) to aid the programmer in using the most common of the
- XMacintosh user interfaces: menus, windows, mouse control, and dialogs.
- XIts purpose is to allow the programmer to get on with programming
- Xhis/her application without spending much effort on how to incorporate
- Xthe standard Macintosh user interfaces into the application. It was
- Xdesigned mainly to allow you to program those simple little programs
- Xwhich you are tempted not to write due to all the work needed to make a
- Xprogram look like a Macintosh program. It is not intended for use in large,
- Xcomplicated programs which may need a larger variety of display
- Xinterfaces.
- X
- X
- X
- XDue to the slowness of a human user in selecting menus and manipulating
- Xwindows, SimpleTools is not noticably slow. It was not intended to be
- Xefficient for the user, but rather easy for the programmer to use. Aren't
- Xyou tired of constantly looking up how to use so-and-so routine in Inside
- XMacintosh? Menus and windows are referenced by name, not by a number
- Xor complex data structure. One routine, simpleevents(), processes the next
- XMacintosh event, including calling the appropriate routine when a menu or
- Xwindow is selected. Most of the other routines are used to "install" menus
- Xand windows so that simpleevents() knows what to do.
- X
- X
- X
- XCopyright and Usage Info
- X
- XSimpleTools is supplied AS IS with absolutely no warrenties, promises, or
- X
- Xliability from or to the author. You may use, copy, give others copies of,
- Xand sell applications developed with SimpleTools after submitting a $10
- Xor more fee to:
- X
- X Erik Kilk
- X
- X 325 San Leandro Way
- X
- X San Francisco, CA 94127
- X
- X
- X
- XSummary of SimpleTools
- X
- XThe purpose of SimpleTools is to aid the use of the Macintosh user
- Xinterface. The routines take care of most of the work needed to maintain
- Xwindows and menus. It is intended to be most effectively used in tandom
- Xwith the Macintosh toolbox routines.
- X
- X
- X
- XSimpleTools works by maintaining several "lists of things to do" when
- Xcertain events occure. The programmer must supply the procedure to do
- Xfor certain events. To document this procedure, a step-by-step tutorial
- Xtype discussion will be given. Please note that NOT EVERYTHING useful to
- Xknow about SimpleTools is contained here. This is meant to get you
- Xstarted. Please take a look at the source code, SimpleTools.c, for more
- Xadvanced usages.
- X
- X
- X
- XPlease report SimpleTools bugs to Erik Kilk, 325 San Leandro Way, San
- XFrancisco, CA 94127.
- X
- X
- X
- XThe Main SimpleTools' Routines
- X
- X simpletools() -- install the apple, file, and edit menus
- X
- X menu() -- install your own menu
- X
- X window() -- install your own window
- X
- X withwindow() -- send output to your window
- X
- X run() -- install a routine to run periodically
- X
- X stop() -- remove a routine from the "run" list
- X
- X message() -- display a message in a dialog box
- X
- X prompt() -- ask a question, get an answer in dialog
- X
- X simpleevents() -- handle all events
- X
- X
- X
- XReferences to all menus and windows are by a string containing the name
- X
- Xof the menu, item, or window. There is no need to remember such things
- X
- Xas menu ids, item ids, menu handles, and window pointers.
- X
- X
- X
- XHow to Use SimpleTools
- X
- XFor the following discussion, assume the following main() routine is
- Xcoded:
- X
- X main()
- X
- X {
- X
- X simpletools("Documentation Tutorial");
- X
- X mysetup();
- X
- X for (;;) simpleevents();
- X
- X }
- X
- XThis is a typical main() routine while using SimpleTools. We will now
- X
- Xdiscuss what is happening.
- X
- X
- X
- XAfter you have compiled your program, you must use your linker to link
- XSimpleTools.o to your object file.
- X
- X
- X
- Xsimpletools("Documentation Tutorial");
- X
- XThis routine initializes the other SimpleTools routines. It must be called
- X
- Xbefore any other SimpleTools routines are called. It is called with the
- X
- Xname of the menu item to appear just under the apple menu (usually this
- X
- Xwill be something like "About MyProgram").
- X
- X
- X
- XThe apple, file, and edit menus will be installed and displayed on the
- X
- Xmenu bar. Under the apple menu will be the name you supplied (disabled),
- X
- Xa dashed line (disabled), and the available desk accessories. Under the
- X
- Xfile menu will be the item "New" disabled. Under the edit menu will be
- X
- Xundo, a dashed line (disabled), cut, copy, paste, and clear.
- X
- X
- X
- X
- X
- XWhat Can Go In or Replace MySetup()
- X
- XBefore you start repeatedly calling simpleevents(), you'll probably want
- X
- Xto set up some windows and more menues than those installed by
- X
- Xsimpletools(). BUT, YOU DON'T HAVE TO! Your program will run with
- X
- Xjust the lines:
- X
- X main()
- X
- X {
- X
- X simpletools("My Program Name");
- X
- X for (;;) simpleevents();
- X
- X }
- X
- XThis little program will just give you a skeleton application and about
- X
- Xall you will be able to do is run desk accessories.
- X
- X
- X
- XThe following routines can be used to setup your application before you
- X
- Xrun the simpleevents() loop.
- X
- X
- X
- Xmenu ("File", "Quit", leave);
- X
- XLet us say you have previously defined the procedure:
- X
- X leave()
- X
- X {
- X
- X exit(0);
- X
- X }
- X
- XThen the statement:
- X
- X menu ("File", "Quit", leave);
- X
- Xwill install under the File menu an item named Quit. It will also store
- X
- Xthe procedure 'leave' as the routine to execute if the user picks Quit
- X
- Xfrom the File menu.
- X
- X
- X
- XUsing this menu() statement, you can install or modify menu entries. Each
- X
- Xcall to menu() must have three arguments. The first is the menu name you
- X
- Xwish to reference, the second is the item name within the menu, and the
- X
- Xthird is either a procedure pointer or either 0L, 1L, 2L, or 3L (this will be
- Xexplained).
- X
- X
- X
- XIf you want to install a new menu/item pair, first define the procedure you
- X
- Xwould like to run when that item is selected. It can be a no op, like:
- X
- X nop()
- X
- X {
- X
- X }
- X
- XSo you can say:
- X
- X menu ("Commands", "Start Demo", nop);
- X
- X
- X
- X
- X
- XIf you want to change the procedure to run when an menu/item pair is
- Xselected, just call menu() again with the new procedure. For example, if
- Xyou had:
- X
- X beep()
- X
- X {
- X
- X sysbeep(10);
- X
- X }
- X
- Xyou can say (at any time, not just during your setup):
- X
- X menu ("Commands", "Start Demo", beep);
- X
- X
- X
- XYou may use a name such as "Medium/M" or "Slow/S" and then
- X
- Xyou may use the keys Command-M or Command-S to invoke the menu item
- Xinstead of using the mouse. Any reference to the item name must
- Xinclude the /K addition to the name.
- X
- X
- X
- XDisabling, Enabling, Checking, or Unchecking Menu Items
- X
- XIf you want to disable, enable, check, or uncheck an item, you would pass
- X
- Xeither 0L, 1L, 2L, or 3L. It is best if you define constants like:
- X
- X #define itemdisable 0L
- X
- X #define itemenable 1L
- X
- X #define itemcheck 2L
- X
- X #define itemuncheck 3L
- X
- Xthen you can say:
- X
- X menu ("Commands", "Start Demo", itemdisable);
- X
- Xor:
- X
- X menu ("Commands", "Start Demo", itemcheck);
- X
- X
- X
- XWhat you would probably do is have the procedure assigned to the
- Xmenu/item handle the checking and unchecking. And you would have the
- Xprocedures which deactivate and activate windows do the job of disabling
- Xand enabling menus. For example, take a look at this complete program:
- X
- X #define itemcheck 2L
- X
- X #define itemuncheck 3L
- X
- X #define normal 0
- X
- X #define wide 1
- X
- X int pensize = normal;
- X
- X
- X
- X setwidepen()
- X
- X {
- X
- X if (pensize == normal) {
- X
- X menu ("Commands", "Wide Pen", itemcheck);
- X
- X pensize = wide;
- X
- X } else {
- X
- X menu ("Commands", "Wide Pen", itemuncheck);
- X
- X pensize = normal;
- X
- X }
- X
- X }
- X
- X
- X
- X main()
- X
- X {
- X
- X simpletools("Check-Uncheck Test");
- X
- X menu ("Commands", "Wide Pen", setwidepen);
- X
- X for (;;) simpleevents();
- X
- X }
- X
- X
- X
- XIf you call menu() to disable/enable/check/uncheck an item with a
- Xmenu/item not already installed, that menu/item will be installed with a
- Xno_op procedure before disabling/enabling/checking/unchecking.
- X
- X
- X
- XThe "About" Entry Under the Apple Menu
- X
- XTo assign a procedure or enable the first item under the apple menu, you
- X
- Xwould use exactly the same menu() routine. The difficult part is what
- X
- Xto call the Apple menu. I thought about making a special case for the
- X
- XApple menu so you might just say, menu ("Apple", "About MyProgram",
- Xroutine), but that would put a "special case" into menu()'s use which I
- Xdidn't want to have to remember. Instead, you must pass a regular C string
- Xwith the Apple character as its contents (since that is the name of the
- Xmenu.) To simplify making such a string, I have one already defined which
- Xyou can link into your program by using extern. If you add the line:
- X
- X extern char applestring[];
- X
- Xyou will then have a string containing the apple character. You can then
- X
- Xsay:
- X
- X #define itemenable 1L
- X
- X extern char applestring[];
- X
- X
- X
- X tellaboutme() /* displays a dialog box */
- X
- X {
- X
- X message ("Hi. I'm a practice program");
- X
- X }
- X
- X
- X
- X main()
- X
- X {
- X
- X simpletools("About Practice");
- X
- X menu (applestring,"About Practice",tellaboutme);
- X
- X menu (applestring,"About Practice",itemenable);
- X
- X for (;;) simpleevents();
- X
- X }
- X
- X
- X
- XInstalling a Window
- X
- XAs a tutorial example, let's say we want to put up a single window on the
- X
- Xscreen. Let's say that nothing "extra" will happen with the window is
- X
- Xactivated, deactivated, updated or when the mouse button is pressed inside
- X
- Xof it. This window will be movable, sizable, and hadeable by the user
- X
- Xwhile simpleevents() is being repeatedly run. Take a look at this program:
- X
- X nop()
- X
- X {
- X
- X }
- X
- X
- X
- X main()
- X
- X {
- X
- X simpletools("Window Demo");
- X
- X window ("My Window", 50, 50, 500, 300, nop, nop,
- X nop, nop);
- X
- X for (;;) simpleevents();
- X
- X }
- X
- XThis program will first install the standard apple, file, and edit menus.
- X
- XIt will then place a document window on the screen with its top left
- Xcorner at 50, 50 and its bottom right corner at 500, 300. Nop is used for
- Xthe "thing to do" when the window is activated, deactivated, updated, or
- Xwhen the mouse is clicked in the window.
- X
- X
- X
- XAn additional menu item is added under a menu title of Windows with the
- Xname of the window. This item is enabled and when selected will bring
- Xthe named window to the front and visable. The installation of this menu
- Xitem may be turned off and on as windows are created in case there are
- Xsome windows you don't want in this Windows menu. To turn this feature
- Xoff, you must set the external variable "windmenu" to false while you
- Xmake the window() call. You get access to this variable with the line:
- X
- X extern int windmenu;
- X
- X
- X
- X
- X
- X
- X
- XMore Detail On Window()
- X
- XThe window() procedure installs or modifies the "things to do" lists for
- X
- Xa window. Its first argument is the name of the window. The next four
- X
- Xarguments are integers describing where the window is to be placed and
- X
- Xhow big it is. These positioning arguments are only used to orginally
- X
- Xinstall the window. They will be ignored if the window has already been
- X
- Xmade! This is so that the user has complete control of the placement of
- X
- Xthe window once the programmer has put one onto the screen. The next
- X
- Xfour arguments are procedures to run when the system receives an event
- Xto activate, deactivate, update, or that a mouse has clicked inside the
- X
- Xwindow.
- X
- X
- X
- XHere is an example of a program which uses windows with the window's
- X
- X"things to do" list not just no_ops:
- X
- X #define itemenable 1L
- X
- X #define itemdisable 0L
- X
- X
- X
- X nop()
- X
- X {
- X
- X }
- X
- X
- X
- X myactivate() /* to be done when window is activated */
- X
- X {
- X
- X menu ("Edit", "Clear", itemenable);
- X
- X }
- X
- X
- X
- X mydeactivate() /* when window is deactivate */
- X
- X {
- X
- X menu ("Edit", "Clear", itemdisable);
- X
- X }
- X
- X
- X
- X myupdate() /* when window needs redrawn */
- X
- X {
- X
- X moveto (10,10);
- X
- X puts("Hi There");
- X
- X }
- X
- X
- X
- X mycontent() /* when mouse is clicked in window */
- X
- X {
- X
- X sysbeep(10);
- X
- X }
- X
- X
- X
- X myclear()
- X
- X {
- X
- X /* something to erase the contents of the window */
- X
- X }
- X
- X
- X
- X main()
- X
- X {
- X
- X simpletools("More Window Demo");
- X
- X menu ("Edit", "Clear", myclear);
- X
- X window ("My Demo Window", 50, 50, 300, 300,
- X myactivate,mydeactivate, myupdate, mycontent);
- X
- X for (;;) simpleevents();
- X
- X }
- X
- X
- X
- XThe Run and Stop Routines
- X
- XEach time simpleevents() is run, it calls (in addition to handling all
- X
- Xsystem events) any procedures you have asked it to call with the run()
- X
- Xcommand. By using run(), you can make procedures look as if they are
- X
- Xrunning in the "background". For example, a run procedure might display
- X
- Xrandom sized circles in a particular window. Then, while anything else
- X
- Xis happening in your program, as long as it keeps calling simpleevents()
- X
- Xyou will get random sized circles appearing in a window.
- X
- X
- X
- XYou may install up to 50 procedures to execute each time
- X
- Xsimpleevents is called. For example, if you would like to count how
- X
- Xmany times simpleevents() is running, you could have:
- X
- X long count = 0L;
- X
- X countcalls()
- X
- X {
- X
- X count++;
- X
- X }
- X
- Xand then say:
- X
- X run (countcalls)
- X
- Xsomewhere in your program whenever you want to start executing
- Xcountcalls. The run() procedure DOES NOT RUN the routine you give it. It
- Xonly adds it to the list of things to run.
- X
- X
- X
- XPROCEDURE ASSIGNED TO BE RUN SHOULD END QUICKLY. If they don't, other
- X
- Xevents will be hung up. Also, if a procedure to be run calls simpleevents(),
- Xyou'll get into an infinate loop with no way out.
- X
- X
- X
- XThe stop() procedure is used to remove an item from the run list. For
- X
- Xexample, in the above example we could have said:
- X
- X long count = 0L;
- X
- X countcalls()
- X
- X {
- X
- X if (count++ > 100000) {
- X
- X sysbeep (10);
- X
- X count = 0L;
- X
- X stop (countcalls);
- X
- X }
- X
- X }
- X
- Xand then said:
- X
- X run (countcalls)
- X
- Xafter a while, you'll hear a beep and countcalls() will be removed from
- X
- Xthe list of procedures to run.
- X
- X
- X
- XDirecting Output to a Window of Your Choice
- X
- XLet us say you have installed a window named "My First Window". If you
- X
- Xwant to direct output to this window, use:
- X
- X withwindow ("My First Window");
- X
- Xand all output (graphics and text) will go to that window. This is
- X
- Xthe same as using the toolbox's setport() routine except you don't
- X
- Xhave to know the window's grafport pointer.
- X
- X
- X
- XA Message Dialog
- X
- XYou may display a dialog box with a message by using a line like:
- X
- X message ("Sorry, a window by that name already exists.");
- X
- X
- X
- X
- X
- XMessage() returns either TRUE or FALSE depending on whether OK or Cancel
- Xwas clicked by the user. There is enough room for a three line message.
- XYou may place Carriage Return characters to force using the next line.
- XThis is done in C with:
- X
- X message ("First line\rSecond line");
- X
- X
- X
- XA Prompt Dialog
- X
- XYou may ask the user a question by using a dialog box with a question, an
- Xeditable window for the answer, and the OK and Cancel buttons. An
- Xexample:
- X
- X char answer[255];
- X
- X strcpy (answer, "New Window");
- X
- X prompt("Give me a unique name for the new window:",
- X
- X answer);
- X
- X
- X
- X
- X
- XPrompt() returns TRUE if either the OK button is pressed or RETURN is
- Xtyped. FALSE is returned if Cancel was clicked by the user. Make sure you
- Xset the answer string to at least a null string. Random data in the answer
- Xstring will generate a random default answer.
- X
- X
- X
- X+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- X
- X
- X
- XAdvanced Notes:
- X
- X
- X
- X1) Each procedure called when a menu item is selected is passed the
- X
- Xaddress of a string containing the name of the item which was
- X
- Xselected. This is convenient if you want several menu/items to call
- X
- Xthe same procedure. For example, if you had a list of baud rate
- X
- Xsettings in a menu. Each item can be assigned the same routine
- X
- Xto run. The routine might look like:
- X
- X int brate;
- X
- X
- X
- X setbaudrate( itemselected )
- X
- X char *itemselected;
- X
- X {
- X
- X brate = atoi ( itemselected);
- X
- X }
- X
- X
- X
- X2) Simpleevents() will set the output port to the proper window before
- X
- Xit calls the procedures assigned to that window. This means that those
- X
- Xprocedures do not have to set output to any window. Output will
- X
- Xautomatically go to the window which is being activated, deactivated,
- Xupdated, or for which the mouse has been pressed.
- X
- X
- X
- X3) Each window content procedure assigned to one of your windows is
- X
- Xpassed the x and y position of the mouse in that window's local
- X
- Xcoordinates. You could declare one of these procedures like:
- X
- X dotinmywindow(x,y)
- X
- X int x,y;
- X
- X {
- X
- X moveto (x,y);
- X
- X lineto (x,y);
- X
- X }
- X
- Xand used dotinmywindow() as a window's procedure to run when the mouse
- X
- Xis clicked in that window.
- X
- X
- X
- X4) Each window procedure is passed the relavant window pointer and
- X
- Xthe address of the event record which caused that window to have some
- X
- Xaction taken on it.
- X
- X
- X
- X5) Each run procedure is passed the address of the next event record
- X
- Xto be processed by simpleevents(). Maybe your run procedure would
- X
- Xlike to monitor this or even change it?
- X
- X
- X
- X6) A very useful function is:
- X
- X windowptr windowpoint ("My Window")
- X
- XThis returns the window pointer to your window named "My Window". This
- Xallows you to call nearly all of the toolbox routines which manipulate
- Xwindows. You could say things like:
- X
- X setport ( windowpoint ("My Window"));
- X
- X hidewindow ( windowpoint ("My Window"));
- X
- X showwindow ( windowpoint ("My Window"));
- X
- X selectwindow ( windowpoint ("My Window"));
- X
- X if (frontwindow() !=windowpoint("My Window")) {};
- X
- X
- X
- XYou can have access to this fuction after the definition:
- X
- X extern windowptr windowpoint();
- X
- X
- X
- X7) Another useful fuction is:
- X
- X menuhandle mhand ("Edit")
- X
- XThis returns a menuhandle to the named menu. This allows you to call
- Xnearly all of the toolbox routines which manipulate menus.
- X
- X
- X
- XYou can have access to this function after the definition:
- X
- X extern menuhandle mhand();
- X
- X
- X
- X8) Several of the SimpleTools routines return result codes. You may
- Xchoose to ignore these. In case you want to use them, here is what they
- Xare:
- X
- X menu () TRUE if a new item was added
- X
- X FALSE if it already existed
- X
- X
- X
- X window () TRUE if a new window was added
- X
- X FALSE if it already existed
- X
- X
- X
- X withwindow ()
- X
- X TRUE if window exists
- X
- X FALSE if not
- X
- X
- X
- X run () TRUE if installation worked
- X
- X FALSE if not (too many installs)
- X
- X
- X
- X stop () TRUE if procedure was found
- X
- X FALSE if not
- X
- X
- X
- X runruns() # of routines runned
- X
- X
- X
- X9) Three external integers may be modified to affect how the window()
- Xcommand works. They are originally set to default values. You can ignore
- Xthese variables. If you want to change them, they stay changed until you
- Xchange them back to their original value.
- X
- X
- X
- X wprocid The window procedure id.
- X
- X 0 standard document window (default)
- X
- X 1 alert box
- X
- X 2 plain box
- X
- X 3 plain box with shadow
- X
- X 4 document window without size
- X
- X 16 rounded corner box (DA type)
- X
- X
- X
- X dogoaway TRUE if go away box is used (default)
- X
- X
- X
- X windmenu TRUE if entry is made into Window menu
- X
- X
- X
- ________This_Is_The_END________
- if test `wc -l < SimpleTools.doc` -ne 919; then
- echo 'shar: SimpleTools.doc was damaged during transit'
- echo ' (should have been 919 bytes)'
- fi
- fi ; : end of overwriting check
- exit 0
-