home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
macintosh-c
/
macc-carbon-demos-nonbinhex.sit
/
macc-carbon-demos-nonbinhex
/
chap03-demo
/
Menus2
/
Menus2.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-07-05
|
20KB
|
695 lines
// *******************************************************************************************
// Menus2.c CLASSIC EVENT MODEL
// *******************************************************************************************
//
// This program is based on Menus1. The basic differences between this program and Menus1 are
// as follows:
//
// • 'xmnu' resources are used to extend the 'MENU' resources for some menus.
//
// • Extended modifier keys (Shift, Option, and Control) are used to extend the Command-key
// equivalents for two menu items in the Style menus.
//
// • There are two Style menus (Style ('xmnu') and Style (Programmatic). The two Style menus
// are intended to demonstrate assigning extended modifier keys to a menu item (1) via an
// 'xmnu' resource and (2) programmatically.
//
// • Command IDs are assigned to all menu items except those in the system-managed menus and
// the Font menu, and the associated menu handling code branches according to the command
// ID of the chosen menu item (as opposed to menu ID and menu item).
//
// • The Font menu is non-hierarchical. It is also WYSIWYG, meaning that each item is drawn
// in that font.
//
// • The delete-to-the-left, delete-to-the-right, page-up, and page-down keys are assigned as
// Command-key equivalents in the Size menu, and the glyphs are adjusted where necessary.
//
// • The submenu is attached to the second item in the Special menu programmatically rather
// than via the 'MENU' resource.
//
// • Colour icons are included in the menu items in the submenu.
//
// • Balloon help is provided, via 'hmnu' resources, for all menus.
//
// The extended modifier keys in the Style ('xmnu') menu are assigned via the 'xmnu' resource
// for that menu. The extended modifier keys in the Style (Programmatic) menu are assigned
// programmatically .
//
// The command IDs for items in the File, Edit, and Style ('xmnu') menus are assigned via the
// 'xmnu' resources for those menus. The command IDs for the items in the Style
// (Programmatic), Size, and Special menus, and the submenu, are assigned programmatically.
//
// The colour icon in the first submenu item is assigned via the 'MENU' resource. The colour
// icon in the second item is assigned programmatically via a call to
// SetMenuItemIconHandle.
//
// 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 drop-down menus and submenu (all preload, all non-purgeable).
//
// • 'xmnu' resources (preload, purgeable) for the drop-down menus (except the system-managed
// menus and the Font menu) and the submenu.
//
// • 'hmnu' resources (purgeable) providing balloon help for menus and menu items.
//
// • Two 'cicn' resources (purgeable) for the items in the submenu.
//
// • A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground,
// doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
//
// *******************************************************************************************
// ………………………………………………………………………………………………………………………………………………………………………………………………………………………… includes
#include <Carbon.h>
// …………………………………………………………………………………………………………………………………………………………………………………………………………………………… defines
#define rMenubar 128
#define mAppleApplication 128
#define mFile 129
#define iQuit 12
#define mFont 131
#define mStyleXmnu 132
#define mStyleProg 133
#define iPlain 1
#define iBold 3
#define iItalic 4
#define iOutline 6
#define iUnderline 5
#define iShadow 7
#define mSize 134
#define iTen 1
#define iTwelve 2
#define iEighteen 3
#define iTwentyFour 4
#define mSpecial 135
#define iFirst 1
#define iSecond 2
#define mSubmenu 136
#define iBat 1
#define iBowl 2
#define rWindowResource 128
#define rColourIcon 258
// …………………………………………………………………………………………………………………………………………………………………………………………………… global variables
Boolean gRunningOnX = false;
Boolean gDone;
MenuItemIndex gCurrentFontMenuItem = 0;
Style gCurrentStyle = 0;
MenuItemIndex gCurrentSizeMenuItem = 2;
// …………………………………………………………………………………………………………………………………………………………………………………………… 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 doCommand (MenuCommand);
void doFontMenu (MenuItemIndex);
void doCheckStyleMenuItem (MenuID);
void doCheckSizeMenuItem (MenuItemIndex);
void drawItemString (Str255);
// ************************************************************************************** main
void main(void)
{
EventRecord eventStructure;
WindowRef windowRef;
RGBColor foreColour = { 0xFFFF,0xFFFF,0xFFFF };
RGBColor backColour = { 0x4444,0x4444,0x9999 };
Rect portRect;
// ……………………………………………………………………………………………………………………………………………………………………………………………… do preliminaries
doPreliminaries();
// ……………………………………………………………………………………………………………………………………………………………………………………………………… open a window
if(!(windowRef = GetNewCWindow(rWindowResource,NULL,(WindowRef) -1)))
{
SysBeep(10);
ExitToShell();
}
SetPortWindowPort(windowRef);
TextSize(10);
RGBBackColor(&backColour);
RGBForeColor(&foreColour);
// ……………………………………………………………………………………………………………………… set up menu bar and menus, then show window
doGetMenus();
ShowWindow(windowRef);
GetWindowPortBounds(windowRef,&portRect);
EraseRect(&portRect);
// ……………………………………………………………………………………………………………………………………………………………………………………………………………… event loop
gDone = false;
while(!gDone)
{
if(WaitNextEvent(everyEvent,&eventStructure,180,NULL))
doEvents(&eventStructure);
}
}
// *************************************************************************** doPreliminaries
void doPreliminaries(void)
{
OSErr osError;
MoreMasterPointers(32);
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;
ItemCount hierMenuCount;
SInt16 a, numberOfItems, fontNumber;
Str255 fontName, smallSystemFontName;
CIconHandle cicnHdl;
// …………………………………………………………………………………………………………………………………………………………………………………… get and set menu bar
menubarHdl = GetNewMBar(rMenubar);
if(menubarHdl == NULL)
ExitToShell();
SetMenuBar(menubarHdl);
Gestalt(gestaltMenuMgrAttr,&response);
if(response & gestaltMenuMgrAquaLayoutMask)
{
menuRef = GetMenuRef(mFile);
if(menuRef != NULL)
{
DeleteMenuItem(menuRef,iQuit);
DeleteMenuItem(menuRef,iQuit - 1);
DisableMenuItem(menuRef,0);
}
gRunningOnX = true;
}
// ………………………………………………………………………………………………………………………………………………… set up Font menu and make WYSIWYG
GetFontName(kThemeSmallSystemFont,smallSystemFontName);
menuRef = GetMenuRef(mFont);
if(menuRef != NULL)
{
osError = CreateStandardFontMenu(menuRef,0,0,kNilOptions,&hierMenuCount);
if(osError == noErr)
{
numberOfItems = CountMenuItems(menuRef);
for(a=1;a<=numberOfItems;a++)
{
GetMenuItemText(menuRef,a,fontName);
GetFNum(fontName,&fontNumber);
SetMenuItemFontID(menuRef,a,fontNumber);
if(EqualString(fontName,smallSystemFontName,false,false))
{
CheckMenuItem(menuRef,a,true);
gCurrentFontMenuItem = a;
}
}
}
else ExitToShell();
}
else
ExitToShell();
// ………………………………………… programmatically set the extended modifiers in Style (Programmatic) menu
menuRef = GetMenuRef(mStyleProg);
SetMenuItemModifiers(menuRef,iOutline,kMenuShiftModifier + kMenuOptionModifier
+ kMenuControlModifier);
SetMenuItemModifiers(menuRef,iShadow,kMenuShiftModifier + kMenuOptionModifier);
// ………… insert submenu into menu list and programmatically attach it to Special menu, item 2
menuRef = GetMenu(mSubmenu);
if(menuRef != NULL)
{
InsertMenu(menuRef,hierMenu);
menuRef = GetMenuRef(mSpecial);
SetMenuItemHierarchicalID(menuRef,iSecond,mSubmenu);
}
else
ExitToShell();
// ……………… programmatically set command IDs for second Style, Size, Special menus and submenu
menuRef = GetMenuRef(mStyleProg);
SetMenuItemCommandID(menuRef,iPlain, 'plai');
SetMenuItemCommandID(menuRef,iBold, 'bold');
SetMenuItemCommandID(menuRef,iItalic, 'ital');
SetMenuItemCommandID(menuRef,iUnderline, 'unde');
SetMenuItemCommandID(menuRef,iOutline, 'outl');
SetMenuItemCommandID(menuRef,iShadow, 'shad');
menuRef = GetMenuRef(mSize);
SetMenuItemCommandID(menuRef,iTen, 'ten ');
SetMenuItemCommandID(menuRef,iTwelve, 'twel');
SetMenuItemCommandID(menuRef,iEighteen, 'eigh');
SetMenuItemCommandID(menuRef,iTwentyFour, 'twen');
menuRef = GetMenuRef(mSpecial);
SetMenuItemCommandID(menuRef,iFirst, 'firs');
menuRef = GetMenuRef(mSubmenu);
SetMenuItemCommandID(menuRef,iBat, 'bat ');
SetMenuItemCommandID(menuRef,iBowl, 'bowl');
// …………………………………………………………………… programmatically set the icon for the Bowl item in the submenu
cicnHdl = GetCIcon(rColourIcon);
SetMenuItemIconHandle(menuRef,iBowl,kMenuColorIconType,(Handle) cicnHdl);
// ………………… programmatically set Command-key equivalents to Size menu items and adjust glyphs
menuRef = GetMenuRef(mSize);
SetItemCmd(menuRef,iTen,0x08);
SetMenuItemKeyGlyph(menuRef,iTen,kMenuDeleteLeftGlyph);
SetItemCmd(menuRef,iTwelve,0x7f);
SetMenuItemKeyGlyph(menuRef,iTwelve,kMenuDeleteRightGlyph);
SetItemCmd(menuRef,iEighteen,0x0b);
SetMenuItemKeyGlyph(menuRef,iEighteen,kMenuPageUpGlyph);
SetItemCmd(menuRef,iTwentyFour,0x0c);
SetMenuItemKeyGlyph(menuRef,iTwentyFour,kMenuPageDownGlyph);
// …………………………… programmatically exclude the mark column and set the font in the Special menu
menuRef = GetMenuRef(mSpecial);
SetMenuExcludesMarkColumn(menuRef,true);
GetFNum("\pGadget",&fontNumber);
if(fontNumber != 0)
SetMenuFont(menuRef,fontNumber,12);
// ………………………………………………………………………… if running on Mac OS X, create Help menu and insert one item
if(gRunningOnX)
{
HMGetHelpMenu(&menuRef,NULL);
InsertMenuItem(menuRef,"\pMenus Help",0);
SetMenuItemCommandID(menuRef,1,'help');
}
// …………………………………………………………………………………………… set initial font, style, and size, and checkmark them
doCheckStyleMenuItem(mStyleXmnu);
doCheckStyleMenuItem(mStyleProg);
doCheckSizeMenuItem(iTen);
// ……………………………………………………………………………………………………………………………………………………………………………………………………… 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. Use EnableMenuCommand and DisableMenuCommand to enable/disable those
// menu items with command IDs.
}
// ****************************************************************************** doMenuChoice
void doMenuChoice(SInt32 menuChoice)
{
MenuID menuID;
MenuItemIndex menuItem;
OSErr osErr;
MenuCommand commandID;
menuID = HiWord(menuChoice);
menuItem = LoWord(menuChoice);
if(menuID == 0)
return;
else if(menuID == mFont)
doFontMenu(menuItem);
else
{
osErr = GetMenuItemCommandID(GetMenuRef(menuID),menuItem,&commandID);
if(osErr == noErr && commandID != 0)
doCommand(commandID);
}
HiliteMenu(0);
}
// ********************************************************************************* doCommand
void doCommand(MenuCommand commandID)
{
MenuRef menuRef;
switch(commandID)
{
// ………………………………………………………………………………………………………………………………………………………………………… Apple/Application menu
case 'abou': // About
drawItemString("\pAbout Menus2");
break;
// …………………………………………………………………………………………………………………………………………………………………………………………………………… File menu
case 'quit': // Quit
gDone = true;
break;
// …………………………………………………………………………………………………………………………………………………………………………………………………………… Edit menu
case 'undo': // Undo
drawItemString("\pUndo");
break;
case 'cut ': // Cut
drawItemString("\pCut");
break;
case 'copy': // Copy
drawItemString("\pCopy");
break;
case 'past': // Paste
drawItemString("\pPaste");
break;
case 'clea': // Clear
drawItemString("\pClear");
break;
// ……………………………………………………………………………………………………………… Style ('xmnu') and Style (Programmatic) menu
case 'plai': // Plain
gCurrentStyle = 0;
doCheckStyleMenuItem(mStyleXmnu);
doCheckStyleMenuItem(mStyleProg);
break;
case 'bold': // Bold
if(gCurrentStyle & bold)
gCurrentStyle -= bold;
else
gCurrentStyle |= bold;
doCheckStyleMenuItem(mStyleXmnu);
doCheckStyleMenuItem(mStyleProg);
break;
case 'ital': // Italics
if(gCurrentStyle & italic)
gCurrentStyle -= italic;
else
gCurrentStyle |= italic;
doCheckStyleMenuItem(mStyleXmnu);
doCheckStyleMenuItem(mStyleProg);
break;
case 'unde': // Underline
if(gCurrentStyle & underline)
gCurrentStyle -= underline;
else
gCurrentStyle |= underline;
doCheckStyleMenuItem(mStyleXmnu);
doCheckStyleMenuItem(mStyleProg);
break;
case 'outl': // Outline
if(gCurrentStyle & outline)
gCurrentStyle -= outline;
else
gCurrentStyle |= outline;
doCheckStyleMenuItem(mStyleXmnu);
doCheckStyleMenuItem(mStyleProg);
break;
case 'shad': // Shadow
if(gCurrentStyle & shadow)
gCurrentStyle -= shadow;
else
gCurrentStyle |= shadow;
doCheckStyleMenuItem(mStyleXmnu);
doCheckStyleMenuItem(mStyleProg);
break;
// …………………………………………………………………………………………………………………………………………………………………………………………………………… Size menu
case 'ten ': // 10
TextSize(10);
doCheckSizeMenuItem(iTen);
break;
case 'twel': // 12
TextSize(12);
doCheckSizeMenuItem(iTwelve);
break;
case 'eigh': // 18
TextSize(18);
doCheckSizeMenuItem(iEighteen);
break;
case 'twen': // 24
TextSize(24);
doCheckSizeMenuItem(iTwentyFour);
break;
// …………………………………………………………………………………………………………………………………………………………………………………………………… Special menu
case 'firs': // First
drawItemString("\pFirst Item");
break;
// ………………………………………………………………………………………………………………………………………………………………………………………………………………… submenu
case 'bat ': // Bat
menuRef = GetMenuRef(mSubmenu);
DisableMenuItem(menuRef,iBat);
EnableMenuItem(menuRef,iBowl);
drawItemString("\pBat");
break;
case 'bowl': // Bowl
menuRef = GetMenuRef(mSubmenu);
DisableMenuItem(menuRef,iBowl);
EnableMenuItem(menuRef,iBat);
drawItemString("\pBowl");
break;
case 'help':
AHGotoPage(CFSTR("Menus Help"),CFSTR("Menus.htm"),NULL);
break;
}
}
// ******************************************************************************** doFontMenu
void doFontMenu(MenuItemIndex menuItem)
{
MenuRef menuRef;
OSStatus osError;
FMFontFamily currentFontFamilyReference;
FMFontStyle fontStyle;
Str255 fontName;
menuRef = GetMenuRef(mFont);
osError = GetFontFamilyFromMenuSelection(menuRef,menuItem,¤tFontFamilyReference,
&fontStyle);
if(osError == noErr || osError == menuPropertyNotFoundErr)
{
TextFont(currentFontFamilyReference);
CheckMenuItem(menuRef,gCurrentFontMenuItem,false);
gCurrentFontMenuItem = menuItem;
CheckMenuItem(menuRef,gCurrentFontMenuItem,true);
GetMenuItemText(menuRef,menuItem,fontName);
drawItemString(fontName);
}
else
ExitToShell();
}
// ********************************************************************** doCheckStyleMenuItem
void doCheckStyleMenuItem(MenuID menuID)
{
MenuRef styleMenuRef;
static Boolean stringAlreadyDrawnOnce = false;
styleMenuRef = GetMenuRef(menuID);
CheckMenuItem(styleMenuRef,iPlain, gCurrentStyle == 0);
CheckMenuItem(styleMenuRef,iBold, gCurrentStyle & bold);
CheckMenuItem(styleMenuRef,iItalic, gCurrentStyle & italic);
CheckMenuItem(styleMenuRef,iUnderline,gCurrentStyle & underline);
CheckMenuItem(styleMenuRef,iOutline, gCurrentStyle & outline);
CheckMenuItem(styleMenuRef,iShadow, gCurrentStyle & shadow);
TextFace(gCurrentStyle);
if(!stringAlreadyDrawnOnce)
drawItemString("\pStyle change");
stringAlreadyDrawnOnce = !stringAlreadyDrawnOnce;
}
// *********************************************************************** doCheckSizeMenuItem
void doCheckSizeMenuItem(MenuItemIndex menuItem)
{
MenuRef sizeMenuRef;
sizeMenuRef = GetMenuRef(mSize);
CheckMenuItem(sizeMenuRef,gCurrentSizeMenuItem,false);
CheckMenuItem(sizeMenuRef,menuItem,true);
gCurrentSizeMenuItem = menuItem;
drawItemString("\pSize change");
}
// **************************************************************************** drawItemString
void drawItemString(Str255 eventString)
{
RgnHandle tempRegion;
WindowRef windowRef;
Rect scrollBox;
windowRef = FrontWindow();
tempRegion = NewRgn();
GetWindowPortBounds(windowRef,&scrollBox);
ScrollRect(&scrollBox,0,-30,tempRegion);
DisposeRgn(tempRegion);
MoveTo(8,286);
DrawString(eventString);
}
// *******************************************************************************************