home *** CD-ROM | disk | FTP | other *** search
- /*
- * menu.c - MenuDemo: a demo of a custom Menu Definition.
- *
- * How to build this program:
- * 1) In the "crushproj" project, create the CODE resource, "crush.mdef".
- * 2) Run RMaker on the file "menu.r".
- * 3) Use ResEdit to edit "crushproj.rsrc", changing the proc-id of each
- * menu from 0 (the stock MDEF) to 400 (our custom MDEF's resource ID).
- * 4) In the "menuproj" project, Build the Application, MenuDemo.
- */
-
- #include <MacTypes.h>
- #include <Quickdraw.h>
- #include <MemoryMgr.h>
- #include <WindowMgr.h>
- #include <DialogMgr.h>
- #include <MenuMgr.h>
- #include <EventMgr.h>
- #include <DeskMgr.h>
- #include <ControlMgr.h>
- #include <TextEdit.h>
- #include <PackageMgr.h>
- #include <ToolboxUtil.h>
- #include <pascal.h>
-
- /*
- * LINKED_MDEF - Set to '1' if the MDEF is really a subroutine that we're
- * testing; Set to '0' otherwise.
- *
- * This definition makes it easy to debug a new MDEF by having this program
- * call our menu definition subroutine directly
- * (rather than calling MenuSelect()).
- *
- * To use this feature, add the menu definition code to this program's project
- * (so it gets linked in) and change the MDEF's entry point name from "main"
- * to "mymenu".
- *
- * When you're done debugging, change LINKED_MDEF to '0', change the MDEF's
- * entry name back to "main", and remove the MDEF's code from this project.
- */
-
- #define LINKED_MDEF 0
-
- /**********
- * Garden-variety declarations for this program follow.
- * they're not really part of the demo.
- **********/
-
- #define APPLEMENU 1 /* Menu ID for Apple menu */
- #define FILEMENU 2 /* ...File menu */
- #define DEMOMENU 3 /* ...Demo menu */
- #define LASTMENU 3 /* Number of menus */
-
- #define DLG_ABOUT 256 /* ResID of the About... dialog */
-
- MenuHandle mymenus[LASTMENU + 1]; /* menus[1..LASTMENU] */
-
- #define maxStackSize 8192 /* max size of our stack */
-
- /*
- * screenport - used to keep the current port from ever dangling.
- * This is a port for the whole screen.
- */
-
- GrafPtr screenport;
-
- /***************
- * The following routines are just boilerplate.
- * They aren't part of the virus detection code.
- ***************/
-
- /*
- * main() - run the program.
- */
-
- main()
- {
- long *stackbaseptr; /* points to current stack base */
- int i;
-
- /*
- * Initialize our memory,
- * then init the Toolbox managers (order is important).
- */
-
- stackbaseptr = (long *) 0x908;
- SetApplLimit((Ptr) (*stackbaseptr - maxStackSize));
- MaxApplZone();
- MoreMasters();
- MoreMasters();
-
- InitGraf(&thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs((ProcPtr) 0);
- DILoad();
- SetEventMask(everyEvent - keyUpMask);
- InitCursor();
- GetWMgrPort(&screenport);
- SetPort(screenport);
-
- /*
- * Setup our menus, then do nothing until we quit.
- */
-
- for (i = 1; i <= LASTMENU; i++) {
- mymenus[i] = GetMenu(i);
- InsertMenu(mymenus[i], 0);
- }
- DrawMenuBar();
-
- while (doevent())
- ;
- InitCursor();
- SetEventMask(everyEvent - keyUpMask);
- }
-
- /*
- * doevent() - one loop through the main event handler
- */
-
- int /* "do another event" */
- doevent()
- {
- EventRecord myevent; /* the event to handle */
- WindowPtr whichwindow; /* Points to window of MouseDown */
- char whichchar; /* the character typed */
- long menucommand; /* a menu command to do (menu + item) */
- int windowcode; /* What mouse was in when event posted */
- int userdone; /* True when user wants to exit program */
-
- userdone = FALSE;
- SystemTask(); /* give the system a moment of time */
-
- if (!GetNextEvent(everyEvent, &myevent)) {
- /* We're idle. */
- } else if ((myevent.modifiers & cmdKey) &&
- (myevent.what == keyDown || myevent.what == autoKey)) {
-
- /*
- * It's a command-key keystroke.
- * (command keystrokes are handled here since dialogs can't)
- */
-
- whichchar = (char) (myevent.message & charCodeMask);
- menucommand = MenuKey(whichchar);
- userdone = docommand(menucommand);
- } else if (IsDialogEvent(&myevent)) {
- /* here's where we'd handle modeless dialog events */
- } else {
- switch (myevent.what) {
- case mouseDown: /* a mouse click someplace */
- windowcode = FindWindow(myevent.where, &whichwindow);
- if (windowcode == inMenuBar) {
- menucommand = MenuSelect(myevent.where);
- userdone = docommand(menucommand);
- break;
- } else {
- #if LINKED_MDEF
- int theitem;
-
- theitem = dumbmenu(myevent.where);
- #endif
- }
- break;
- }
- }
- return(!userdone);
- }
-
- /*
- * docommand() - handle a command given through a menu selection.
- */
-
- int /* "the command was 'quit' */
- docommand(mresult)
- long mresult; /* the command to execute (a menu item) */
- {
- int themenu; /* menu the mouse chose */
- int theitem; /* item in that menu */
- int returns; /* value to be returned */
- short itemhit;
- DialogPtr reportptr;
-
- returns = FALSE;
- themenu = HiWord(mresult);
- theitem = LoWord(mresult);
-
- switch (themenu) {
- case APPLEMENU: /* Tell about the program */
- reportptr = GetNewDialog(DLG_ABOUT, (char *) 0, (long) -1);
- ModalDialog((ProcPtr) 0, &itemhit);
- DisposDialog(reportptr);
- break;
-
- case FILEMENU: /* quit */
- returns = TRUE;
- break;
- }
- HiliteMenu(0);
- return(returns);
- }
-
- #if LINKED_MDEF
-
- /*
- * dumbmenu() - pretend to be MenuSelect(),
- * calling the appropriate operations in the MDEF we're testing.
- *
- * This arrangement lets us quickly debug a new MDEF under Lightspeed C
- * without going to the hassle of generating a real MDEF each time we
- * make a change.
- */
-
- int /* the item # */
- dumbmenu(pt)
- Point pt; /* mouse-down (global coords) */
- {
- MenuHandle menuh; /* the menu we're working with */
- Rect menurect; /* the rect bounding the menu */
- int theitem; /* the selected item number */
- Rect tmprect;
- pascal void mymenu(); /* the name of our MDEF subroutine */
-
- menuh = mymenus[DEMOMENU];
- menurect.top = 0;
- menurect.left = 0;
- menurect.bottom = 0;
- menurect.right = 0;
- theitem = 0;
-
- mymenu((int) mSizeMsg, menuh, &menurect, pt, &theitem);
-
- menurect.top = 50;
- menurect.left = 30;
- menurect.bottom = menurect.top + (*menuh)->menuHeight;
- menurect.right = menurect.left + (*menuh)->menuWidth;
-
- EraseRect(&menurect);
- tmprect = menurect;
- InsetRect(&tmprect, -1, -1);
- FrameRect(&tmprect);
- MoveTo(tmprect.left + 2, tmprect.bottom);
- LineTo(tmprect.right, tmprect.bottom);
- LineTo(tmprect.right, tmprect.top + 2);
-
- mymenu((int) mDrawMsg, menuh, &menurect, pt, &theitem);
- while (StillDown()) {
- GetMouse(&pt);
- LocalToGlobal(&pt);
- mymenu((int) mChooseMsg, menuh, &menurect, pt, &theitem);
- }
- EraseRect(&menurect);
- }
- #endif
-