␡
- Introduction—Types of Menus
- Pull-Down Menus
- Hierarchical Menus
- Pop-Up Menus
- Menu Objects, Menu IDs and Item Numbers, Command IDs, and Menu Lists
- Creating Your Application's Menus
- Providing Help Balloons (Mac OS 8/9)
- Changing Menu Item Appearance
- Adding Items to a Menu
- Associating Data with Menu Items
- Handling Menu Choices
- Hiding and Showing the Menu Bar
- Accessing Menus from Alerts and Dialogs
- Main Menu Manager Constants, Data Types, and Functions
- Demonstration Program Menus1 Listing
- Demonstration Program Menus1 Comments
- Demonstration Program Menus2 Listing
- Demonstration Program Menus2 Comments
This chapter is from the book
Demonstration Program Menus1 Listing
// ******************************************************************************************* // Menus1.c CLASSIC EVENT MODEL // ******************************************************************************************* // // This program: // // Opens a window. // // Creates these pull-down menus: Apple, File, Edit, Font, Size, Special, and Window. // // Displays text in the window indicating the menu selection made by the user. // // The Apple menu includes an "About..." menu item for the program. // // The second menu item in the Special menu contains a submenu. // // The Font and Window menus are created programmatically using the functions // CreateStandardFontMenu and CreateStandardWindowMenu. // // The implementation of the Size menu is nominal only. The current size is indicated with a // checkmark; however, the number of sizes shown is not font-dependent and there is no "Other" // item. // // Because the primary purpose of the program is to demonstrate menu creation and handling, no // code is included to update and activate/deactivate the window or to respond to events which // are not relevant to the demonstration. // // The program is terminated by selecting Quit from the File menu, by pressing the keyboard // equivalent for that item (Command-Q), or by clicking in the window's go-away box/close // button. // // The program utilises the following resources: // // A 'plst' resource. // // A 'WIND' resource (purgeable) (initially not visible). // // An 'MBAR' resource (preload, non-purgeable). // // 'MENU' resources for the Apple, File, Edit, Font, Size, and Special drop-down menus // and the submenu (all preload, all non-purgeable). // // A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground, // doesActivateOnFGSwitch, and isHighLevelEventAware flags set. // // ******************************************************************************************* // ...................................................................................includes #include <Carbon.h> // ...................................................................................defines #define rMenubar 128 #define mAppleApplication 128 #define iAbout 1 #define mFile 129 #define iQuit 12 #define mEdit 130 #define iUndo 1 #define iCut 3 #define iCopy 4 #define iPaste 5 #define iClear 6 #define mFont 131 #define mSize 132 #define iTen 1 #define iTwelve 2 #define iEighteen 3 #define iTwentyFour 4 #define mSpecial 133 #define iFirstItem 1 #define iSecondItem 2 #define mWindow 134 #define mSubmenu 135 #define mFirstFontSubMenu 136 #define iFirstSubItem 1 #define iSecondSubItem 2 #define rWindowResource 128 // ..............................................................................global variables Boolean gDone; ItemCount gFontMenuHierMenuCount; MenuItemIndex gCurrentFontSizeItem = 2; MenuItemIndex gCurrentFontMenuItem; MenuItemIndex gCurrentFontSubMenuItem; MenuRef gCurrentFontSubMenuRef = NULL; // ..............................................................................function prototypes void main (void); void doPreliminaries (void); OSErr quitAppEventHandler (AppleEvent *,AppleEvent *,SInt32); void doGetMenus (void); void doEvents (EventRecord *); void doMouseDown (EventRecord *); void doAdjustMenus (void); void doMenuChoice (SInt32); void doAppleApplicationMenu (MenuItemIndex); void doFileMenu (MenuItemIndex); void doEditMenu (MenuItemIndex); void doFontMenu (MenuID,MenuItemIndex); void doSizeMenu (MenuItemIndex); void doSpecialMenu (MenuItemIndex); void doSubMenus (MenuItemIndex); void drawItemString (Str255); // ************************************************************************************** main void main(void) { EventRecord eventStructure; WindowRef windowRef; // ...............................................................................do preliminaries doPreliminaries(); // ...............................................................................open a window if(!(windowRef = GetNewCWindow(rWindowResource,NULL,(WindowRef) -1))) { SysBeep(10); ExitToShell(); } SetPortWindowPort(windowRef); // ....................................................set up menu bar and menus, then show window doGetMenus(); ShowWindow(windowRef); // ..................................................................................event loop gDone = false; while(!gDone) { if(WaitNextEvent(everyEvent,&eventStructure,180,NULL)) doEvents(&eventStructure); } } // *************************************************************************** doPreliminaries void doPreliminaries(void) { OSErr osError; MoreMasterPointers(640); InitCursor(); FlushEvents(everyEvent,0); osError = AEInstallEventHandler(kCoreEventClass,kAEQuitApplication, NewAEEventHandlerUPP((AEEventHandlerProcPtr) quitAppEventHandler), 0L,false); if(osError != noErr) ExitToShell(); } // **************************************************************************** doQuitAppEvent OSErr quitAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon) { OSErr osError; DescType returnedType; Size actualSize; osError = AEGetAttributePtr(appEvent,keyMissedKeywordAttr,typeWildCard,&returnedType,NULL,0, &actualSize); if(osError == errAEDescNotFound) { gDone = true; osError = noErr; } else if(osError == noErr) osError = errAEParamMissed; return osError; } // ******************************************************************************** doGetMenus void doGetMenus(void) { MenuBarHandle menubarHdl; SInt32 response; MenuRef menuRef; OSStatus osError; Str255 smallSystemFontName, itemString; SInt16 numberOfItems,a; // ...................................................................get and set, and menu bar menubarHdl = GetNewMBar(rMenubar); if(menubarHdl == NULL) ExitToShell(); SetMenuBar(menubarHdl); // ..................if running on Mac OS X, delete Quit item and preceding divider from File menu Gestalt(gestaltMenuMgrAttr,&response); if(response & gestaltMenuMgrAquaLayoutMask) { menuRef = GetMenuRef(mFile); if(menuRef != NULL) { DeleteMenuItem(menuRef,iQuit); DeleteMenuItem(menuRef,iQuit - 1); DisableMenuItem(menuRef,0); } } // ................................ create hirearchical Font menu, checkmark small system font menuRef = GetMenuRef(mFont); if(menuRef != NULL) { osError = CreateStandardFontMenu(menuRef,0,mFirstFontSubMenu,kHierarchicalFontMenuOption, &gFontMenuHierMenuCount); if(osError != noErr) ExitToShell(); } else ExitToShell(); GetFontName(kThemeSmallSystemFont,smallSystemFontName); numberOfItems = CountMenuItems(menuRef); for(a=1;a<numberOfItems + 1;a++) { GetMenuItemText(menuRef,a,itemString); if(EqualString(itemString,smallSystemFontName,false,false)) { CheckMenuItem(menuRef,a,true); gCurrentFontMenuItem = a; break; } } // .................................................create Window menu and insert into menu list CreateStandardWindowMenu(0,&menuRef); SetMenuID(menuRef,mWindow); InsertMenu(menuRef,0); // ......................................................get submenus and insert into window list menuRef = GetMenu(mSubmenu); if(menuRef != NULL) InsertMenu(menuRef,hierMenu); else ExitToShell(); // ............................. set initial font size and checkmark associated item in Size menu doSizeMenu(gCurrentFontSizeItem); // ...............................................................................draw menu bar DrawMenuBar(); } // ********************************************************************************** doEvents void doEvents(EventRecord *eventStrucPtr) { switch(eventStrucPtr->what) { case kHighLevelEvent: AEProcessAppleEvent(eventStrucPtr); break; case mouseDown: doMouseDown(eventStrucPtr); break; case keyDown: if((eventStrucPtr->modifiers & cmdKey) != 0) { doAdjustMenus(); doMenuChoice(MenuEvent(eventStrucPtr)); } break; case updateEvt: BeginUpdate((WindowRef) eventStrucPtr->message); EndUpdate((WindowRef) eventStrucPtr->message); break; } } // ******************************************************************************* doMouseDown void doMouseDown(EventRecord *eventStrucPtr) { WindowRef windowRef; WindowPartCode partCode; SInt32 menuChoice; partCode = FindWindow(eventStrucPtr->where,&windowRef); switch(partCode) { case inMenuBar: doAdjustMenus(); menuChoice = MenuSelect(eventStrucPtr->where); doMenuChoice(menuChoice); break; case inContent: if(windowRef != FrontWindow()) SelectWindow(windowRef); break; case inDrag: DragWindow(windowRef,eventStrucPtr->where,NULL); break; case inGoAway: if(TrackGoAway(windowRef,eventStrucPtr->where)) gDone = true; break; } } // ***************************************************************************** doAdjustMenus void doAdjustMenus(void) { // Adjust menus here. } // ****************************************************************************** doMenuChoice void doMenuChoice(SInt32 menuChoice) { MenuID menuID; MenuItemIndex menuItem; menuID = HiWord(menuChoice); menuItem = LoWord(menuChoice); if(menuID == 0) return; if(menuID == mFont || ((menuID >= mFirstFontSubMenu) && (menuID <= mFirstFontSubMenu + gFontMenuHierMenuCount))) doFontMenu(menuID,menuItem); else { switch(menuID) { case mAppleApplication: doAppleApplicationMenu(menuItem); break; case mFile: doFileMenu(menuItem); break; case mEdit: doEditMenu(menuItem); break; case mSize: doSizeMenu(menuItem); break; case mSpecial: doSpecialMenu(menuItem); break; case mSubmenu: doSubMenus(menuItem); break; } } HiliteMenu(0); } // ******************************************************************** doAppleApplicationMenu void doAppleApplicationMenu(MenuItemIndex menuItem) { if(menuItem == iAbout) drawItemString("\pAbout Menus1"); } // ******************************************************************************** doFileMenu void doFileMenu(MenuItemIndex menuItem) { if(menuItem == iQuit) gDone = true; } // ******************************************************************************** doEditMenu void doEditMenu(MenuItemIndex menuItem) { switch(menuItem) { case iUndo: drawItemString("\pUndo"); break; case iCut: drawItemString("\pCut"); break; case iCopy: drawItemString("\pCopy"); break; case iPaste: drawItemString("\pPaste"); break; case iClear: drawItemString("\pClear"); break; } } // ******************************************************************************** doFontMenu void doFontMenu(MenuID menuID,MenuItemIndex menuItem) { MenuRef menuRef, fontMenuRef; OSStatus osError; FMFontFamily currentFontFamilyReference; FMFontStyle currentFontStyle; Str255 fontName, styleName, itemName; SInt16 a, numberOfFontMenuItems; menuRef = GetMenuRef(menuID); osError = GetFontFamilyFromMenuSelection(menuRef,menuItem,¤tFontFamilyReference, ¤tFontStyle); if(osError == noErr) { TextFont(currentFontFamilyReference); TextFace(currentFontStyle); GetFontName(currentFontFamilyReference,fontName); drawItemString(fontName); if(menuID == mFont) { CheckMenuItem(menuRef,gCurrentFontMenuItem,false); gCurrentFontMenuItem = menuItem; CheckMenuItem(menuRef,gCurrentFontMenuItem,true); if(gCurrentFontSubMenuRef != NULL) CheckMenuItem(gCurrentFontSubMenuRef,gCurrentFontSubMenuItem,false); } else { if(gCurrentFontSubMenuRef != NULL) CheckMenuItem(gCurrentFontSubMenuRef,gCurrentFontSubMenuItem,false); gCurrentFontSubMenuRef = menuRef; gCurrentFontSubMenuItem = menuItem; CheckMenuItem(gCurrentFontSubMenuRef,gCurrentFontSubMenuItem,true); fontMenuRef = GetMenuRef(mFont); CheckMenuItem(fontMenuRef,gCurrentFontMenuItem,false); numberOfFontMenuItems = CountMenuItems(fontMenuRef); for(a=1;a<=numberOfFontMenuItems;a++) { GetMenuItemText(fontMenuRef,a,itemName); if(EqualString(fontName,itemName,true,true)) { gCurrentFontMenuItem = a; break; } } SetItemMark(fontMenuRef,gCurrentFontMenuItem,'-'); GetMenuItemText(menuRef,menuItem,styleName); DrawString("\p "); DrawString(styleName); } } else ExitToShell(); } // ******************************************************************************** doSizeMenu void doSizeMenu(MenuItemIndex menuItem) { MenuRef sizeMenuRef; switch(menuItem) { case iTen: TextSize(10); break; case iTwelve: TextSize(12); break; case iEighteen: TextSize(18); break; case iTwentyFour: TextSize(24); break; } sizeMenuRef = GetMenuRef(mSize); CheckMenuItem(sizeMenuRef,gCurrentFontSizeItem,false); CheckMenuItem(sizeMenuRef,menuItem,true); gCurrentFontSizeItem = menuItem; drawItemString("\pSize change"); } // ***************************************************************************** doSpecialMenu void doSpecialMenu(MenuItemIndex menuItem) { if(menuItem == iFirstItem) drawItemString("\pFirst Item"); } // ******************************************************************************** doSubMenus void doSubMenus(MenuItemIndex menuItem) { switch(menuItem) { case iFirstSubItem: drawItemString("\pSubitem 1"); break; case iSecondSubItem: drawItemString("\pSubitem 2"); break; } } // **************************************************************************** drawItemString void drawItemString(Str255 eventString) { RgnHandle tempRegion; WindowRef windowRef; Rect scrollBox; windowRef = FrontWindow(); tempRegion = NewRgn(); GetWindowPortBounds(windowRef,&scrollBox); ScrollRect(&scrollBox,0,-24,tempRegion); DisposeRgn(tempRegion); MoveTo(8,286); DrawString(eventString); } // *******************************************************************************************