Important: The information in this document is obsolete and should not be used for new development.
Creating a Menu
You use various Menu Manager routines to set up the menus and the menu bar
for your application. You can use any of these methods to create pull-down menus for
your application:
Whenever possible you should define your menus in menu (
- You can create descriptions of your application's menus in
'MENU'
resources and describe your application's menu bar in an'MBAR'
resource. You use theGetNewMBar
function to read in descriptions of your menu bar and menus and create a new menu list, use theSetMenuBar
procedure to set the current menu list to your application's menu list, and use theDrawMenuBar
procedure to update the menu bar.- You can create descriptions of your application's menus in
'MENU'
resources, read them in usingGetMenu
, add them to the current menu list usingInsertMenu
, and update the menu bar usingDrawMenuBar
.- You can use
NewMenu
to create new empty menus; useAppendMenu
,InsertMenuItem
,InsertResMenu
, orAppendResMenu
to fill the menus with menu items; add the menus to the current menu list usingInsertMenu
; and update the menu bar usingDrawMenuBar
.
'MENU'
) resources and your menu bar in a menu bar ('MBAR'
) resource to make your application easier
to localize.To create a hierarchical menu, you need to create descriptions of the submenu and the menu to which the submenu is attached. Usually you create the description of both menus in
'MENU'
resources. You typically read in the description of the hierarchical menu usingGetNewMBar
(if you also provide an'MBAR'
resource). To read in the description of the submenu and insert it in the current menu list, use theGetMenu
function andInsertMenu
procedure.To create a pop-up menu, create descriptions of the pop-up menu and its menu items, create a control that uses the pop-up control definition function, and associate the control with a window or dialog box. You can display and manage the pop-up menu using the Dialog Manager or Control Manager routines.
Once the Menu Manager creates a menu for your application, if necessary you can add additional menu items to the menu using
AppendMenu
,InsertMenuItem
,InsertResMenu
, orAppendResMenu
. You can use various Menu Manager routines to change the appearance of menu items.The next sections describe how to create
'MENU'
and'MBAR'
resources. "Creating a Hierarchical Menu" on page 3-55 describes how to create a menu that has a submenu, and "Creating a Pop-Up Menu" on page 3-58 describes how to create pop-up menus.Creating a Menu Resource
Usually you should define your menus in menu ('MENU'
) resources so that you can easily localize the menu titles and menu items for other languages, cultures, or regions. A'MENU'
resource defines the menu title of a menu and the characteristics of menu items in a menu. Listing 3-1 shows a sample'MENU'
resource in Rez format for an application's Apple menu. (Rez is a resource compiler available with MPW. You can also define menus using a resource utility, such as ResEdit, available from APDA.)Listing 3-1 Rez input for a
'MENU'
resource for the Apple menu
#define mApple 128 resource 'MENU' (mApple, preload) { /*resource ID, preload resource*/ mApple, /*menu ID*/ textMenuProc, /*uses standard menu definition */ /* procedure*/ 0b1111111111111111111111111111101, /*enable About item, */ /* disable divider, */ /* enable all other items*/ enabled, /*enable menu title*/ apple, /*menu title*/ { /*first menu item*/ "About SurfWriter...", /*text of menu item */ /* (includes ellipsis)*/ /*item characteristics follow*/ noicon, /*icon number (if any) or */ /* script code (if any)*/ nokey, /*keyboard equivalent (if any) */ /* or submenu (if any) or */ /* small or reduced icon (if any)*/ nomark, /*marking character (if any) or */ /* menu ID of submenu (if any)*/ plain; /*style of menu item text*/ /*second menu item*/ "-", /*item text (divider)*/ noicon, nokey, nomark, plain /*item characteristics*/ } };You should also define help balloons for each of your application's menu items and each menu title when you create your menus. (Figure 3-21 on page 3-35 shows help balloons for an application's Cut command.) You define the help balloons for your application's menus in'hmmu'
resources. See the chapter "Help Manager" in Inside Macintosh: More Macintosh Toolbox for examples of how to create'hmmu'
resources.Listing 3-1 defines the resource ID of the Apple menu as 128. You can use any number equal to or greater than 128 as a resource ID for a menu. By convention, many applications use 128 as the resource ID of the first menu in the application's menu bar (the Apple menu) and use sequential numbers for the resource IDs of following menus.
Listing 3-1 also defines the menu ID of the Apple menu as 128. Once your application creates the menu, the Menu Manager uses the defined menu ID to refer to this menu. The number you define for the menu ID of a menu does not have to match the resource ID of the menu, but it is usually more convenient to use the same number. You can use any number greater than 0 for the menu ID of a pull-down or pop-up menu; submenus of an application can only use menu IDs from 1 through 235; submenus of a desk accessory must use menu IDs from 236 through 255.
The listing specifies that this menu uses the standard menu definition procedure. If you choose to create your own menu definition procedure, list its resource ID instead of the
textMenuProc
constant.After the resource ID of the menu definition procedure is a 32-bit number (expressed as
a 31-bit field followed by aBoolean
field), where bits 1-31 indicate if the correspond- ing menu item is disabled or enabled, and bit 0 indicates whether the menu is enabled
or disabled.The listing specifies in the 31-bit field that the first menu item should be enabled, that the second menu item should be disabled, and that the following menu items (item numbers 3 through 31) should be enabled when the menu is first created. After creating a menu, your application can enable or disable menu items using the
EnableItem
orDisableItem
procedure. If a menu contains more than 31 items, the Menu Manager automatically enables all items following the 31st item when the menu is enabled. Your application cannot disable any individual items following the 31st item. However, you can disable all items, including items after the 31st item, by disabling the entire menu.Listing 3-1 specifies that the menu title should be enabled when it is first created.
Your application can also disable or enable the menu title using theDisableItem
orEnableItem
procedure. When you disable a menu using theDisableItem
procedure, the Menu Manager disables all menu items in the menu (including any items following the 31st item) and dims the title of the menu.The resource listing identifies the title of the menu using the constant
apple
. If you specify theapple
constant as the title, the Menu Manager uses a small Apple icon as the title of the menu. The Menu Manager uses a color Apple icon if the monitor is set to display colors. The listing then defines the characteristics of each menu item in the menu. For each menu item, you need to define the text and any other characteristics of the menu item. For example, Listing 3-1 defines the first item in the Apple menu as the About command; note that the text of this menu item specifies three ellipsis points (...). Specify three ellipsis points following the text of a menu command if your application displays a dialog box requesting information from the user before performing the command. In general, you should not use ellipses if your application displays a confirmation alert after the user chooses a menu command; the About command is an exception to this guideline.Listing 3-1 defines other characteristics of the About command--it doesn't have an
icon to the left of the menu item text, it doesn't have a keyboard equivalent, it doesn't have any mark to the left of the menu item text, and the font style of the menu item
text is plain.By specifying various combinations of values in the icon field and keyboard equivalent field, you can define an icon (normal, small, reduced, or color), a keyboard equivalent, a submenu, or the script code of a menu item. Note that some characteristics are mutually exclusive (for example, an item can have a keyboard equivalent or submenu, but not both), as described in the following paragraphs. Table 3-6 on page 3-48 summarizes how the Menu Manager interprets these item characteristics.
Table 3-6 Table 3-6 Specifying submenus, script codes, reduced icons, small icons, and color icons of a menu item in a menu resource
Keyboard equivalent field Icon field Marking character field Description $1B Menu ID of submenu Indicates the item has a submenu. The marking character field specifies the
menu ID of the submenu.$1C Script code of item text Indicates the item text uses the script defined by the script code specified in the icon field. $1D Icon number of 'ICON'
resourceIndicates the item has an icon defined by an 'ICON'
resource and that it should be reduced to fit in a 16-by-16 bit rectangle.$1E Icon number
of'SICN'
resourceIndicates the item has an icon defined by an 'SICN'
resource.$00 or >$20 Icon number of 'ICON'
or'cicn'
resourceIndicates the item has an icon defined
by an'ICON'
or a'cicn'
resource.
(A value greater than $20 in the
keyboard equivalent field specifies the item's keyboard equivalent.)To assign an icon to a menu item, specify an icon number in place of the
noicon
constant. The icon number you specify should be a number from 1 through 255 (or from 1 through 254 for small icons and reduced icons); add 256 to your icon number and use the result for the resource ID of the color icon ('cicn'
) resource, icon ('ICON'
) resource, or small icon ('SICN'
) resource that describes the icons for the menu item. You must define the icon for a menu item in a'cicn'
, an'ICON',
or an'SICN'
resource; the Menu Manager uses only these types of resources for icons you define for your menu items. The Menu Manager first looks for a'cicn'
resource with the calculated resource ID and uses that icon if it finds it. If it doesn't find a'cicn'
resource (or if the computer doesn't have Color QuickDraw) and the keyboard equivalent field specifies $1E, the Menu Manager looks for an'SICN'
resource with the calculated resource ID. Otherwise, the Menu Manager looks for an'ICON'
resource and plots it in a 32-by-32 bit rectangle, unless the keyboard equivalent field contains $1D. If the keyboard equivalent field contains $1D, the Menu Manager reduces the icon to fit in a 16-by-16
bit rectangle.If you provide an
'ICON'
resource and specify thenokey
constant or a value greater than $20 as the keyboard equivalent, the Menu Manager enlarges the rectangle of the entire menu item to fit the 32-by-32 bit'ICON'
resource. If you specify a value of $1D as the keyboard equivalent of the menu item, the Menu Manager reduces the'ICON'
resource to fit in a 16-by-16 bit rectangle. If you provide an'SICN'
resource and specify a value of $1E as the keyboard equivalent of a menu item, the Menu Manager plots the small icon in a 16-by-16 bit rectangle. If you provide a'cicn'
resource, the Menu Manager automatically enlarges the enclosing rectangle of the menu item according to the rectangle specified in the'cicn'
resource. (For the Apple and Application menus, the Menu Manager automatically reduces the icon to fit within the enclosing rectangle of a menu item or uses the appropriate icon from the application's icon family, such as an'ics8'
resource, if one is available.) See the chapter "Finder Interface" in this book for details on how to create icons for your application.To assign a keyboard equivalent to a menu item, specify the 1-byte character that the user types in addition to the Command key in place of the
nokey
constant in your resource definition for the menu item. If your application attaches a submenu to a menu item, then specify thehierarchicalMenu
constant in place of thenokey
constant. A menu item can have either a keyboard equivalent or submenu defined for it, but not both. To indicate that a menu item has an icon that is defined in an'SICN'
resource, specify $1E in place of thenokey
constant. To indicate that a menu item has an icon that is defined in an'ICON'
resource and that the Menu Manager should reduce this icon to a 16-by-16 bit rectangle, specify $1D in place of thenokey
constant. Menu items that have small icons or reduced icons cannot have keyboard equivalents.To set the script code of a menu item's text, specify $1C in place of the
nokey
constant and define the desired script code in place of thenoicon
constant. If an item contains $1C in its keyboard equivalent field and a script code in its icon field, the Menu Manager draws the item's text in the script identified by the script code value if the corresponding script system is installed. If you do not specify a script code for a menu item, the Menu Manager displays the menu item's text in the system font of the current system script. For Roman scripts, the system font is Chicago and the system font size is 12.To assign a mark that appears to the left of the menu item text and to the left of any
icon, specify the marking character in place of thenomark
constant in your resource definition. If the menu item has a submenu, then specify the menu ID of the submenu in place of thenomark
constant. Submenus of an application must use menu IDs from
1 through 235; submenus of a desk accessory must use menu IDs from 236 through 255. Note that defining the menu ID of a submenu in a'MENU'
resource does not attach the submenu to its menu. You must use theGetMenu
function andInsertMenu
procedure to do this. "Creating a Hierarchical Menu," which begins on page 3-55, gives information on attaching a submenu to its menu.To assign a font style to a menu item, in your
'MENU'
resource use the constantsbold
,italic
,plain
,outline
, andshadow
to get their corresponding styles.Listing 3-1 defines the second menu item as a divider. When you use a hyphen as the first character in the string that defines the text of a menu item, the Menu Manager creates a divider that extends across the entire width of the menu item. You cannot assign any other characteristics to a divider.
The
'MENU'
resource for the Apple menu does not list any other menu items. Use theAppendResMenu
procedure to add the desktop items to the Apple menu after your application creates the menu. See "Adding Items to the Apple Menu" on page 3-70 for more information.Once you create a menu, you can append additional items to it using the
AppendMenu
,InsertMenuItem
,InsertResMenu
, orAppendResMenu
procedure. You can also change the characteristics of individual menu items using Menu Manager routines. See "Changing the Appearance of Items in a Menu" on page 3-59 for more information.Figure 3-12 on page 3-30 shows a typical Edit menu for an application. Listing 3-2 shows a
'MENU'
resource for this Edit menu.Listing 3-2 Rez input for a
'MENU'
resource for an Edit menu
#define mEdit 130 resource 'MENU' (mEdit, preload) { /*resource ID, preload resource*/ mEdit, /*menu ID*/ textMenuProc, /*uses standard menu definition */ /* procedure*/ 0b0000000000000000001001000000000, /*enable/disable first 31 menu */ /* items as appropriate*/ enabled, /*enable title*/ "Edit", /*text of menu title*/ { /*menu items*/ "Undo", noicon, "Z", nomark, plain; /*keyboard equivalent Command-Z*/ "-", noicon, nokey, nomark, plain; "Cut", noicon, "X", nomark, plain; /*keyboard equivalent Command-X*/ "Copy", noicon, "C", nomark, plain; /*keyboard equivalent Command-C*/ "Paste", noicon, "V", nomark, plain; /*keyboard equivalent Command-V*/ "Clear", noicon, nokey, nomark, plain; "Select All", noicon, "A", nomark, plain; /*keyboard equivalent Command-A*/ "-", noicon, nokey, nomark, plain; "Create Publisher...", noicon, nokey, nomark, plain; "Subscribe To...", noicon, nokey, nomark, plain; "Publisher Options...", noicon, nokey, nomark, plain; "-", noicon, nokey, nomark, plain; "Show Clipboard", noicon, nokey, nomark, plain } };Listing 3-2 defines the resource ID of the Edit menu as 130, defines the menu ID of the Edit menu as 130, and specifies that this menu uses the standard menu definition procedure. The listing defines the initial enabled state of the first 31 menu items and
also specifies that the menu title should be enabled when it is first created.The resource listing defines the title of the menu, Edit. It then defines the characteristics of each menu item in the menu. For each menu item, you need to specify the text of the menu item and any other characteristics of the menu item. For example, Listing 3-2 defines the first item in the Edit menu as the Undo command with these characteristics: there is no icon to the left of the menu item text, the menu item has a keyboard equivalent of Command-Z, it does not have any mark to the left of the menu item text, and the style of the menu item text is plain. The listing defines the second menu item as a divider line. It defines the Cut, Copy, and Paste commands; specifies keyboard equivalents for each of them; and defines the rest of the items in the menu.
Listing 3-3 shows another example of a resource description of a menu, the File menu of a typical application.
Listing 3-3 Rez input for a
'MENU'
resource for a File menu
resource 'MENU' (mFile, preload) { mFile, textMenuProc, 0b0000000000000000000010000000000, enabled, "File", { "New", noicon, "N", nomark, plain; "Open...", noicon, "O", nomark, plain; "-", noicon, nokey, nomark, plain; "Close", noicon, "W", nomark, plain; "Save", noicon, "S", nomark, plain; "Save As...", noicon, nokey, nomark, plain; "-", noicon, nokey, nomark, plain; "Page Setup...", noicon, nokey, nomark, plain; "Print...", noicon, "P", nomark, plain; "-", noicon, nokey, nomark, plain; "Quit", noicon, "Q", nomark, plain } };Creating a Menu Bar Resource
You typically define your application's menu bar using a menu bar ('MBAR'
) resource. Listing 3-4 shows an'MBAR'
resource, in Rez format, for a sample application.Listing 3-4 Rez input for an
'MBAR'
resource
#define rMenuBar 128 #define mApple 128 #define mFile 129 #define mEdit 130 resource 'MBAR' (rMenuBar, preload) {/*resource ID, preload*/ /*menus appear in the order listed here*/ { mApple, mFile, mEdit }; /*resource IDs for menus in */ /* this menu bar*/ };Listing 3-4 defines the'MBAR'
resource with resource ID 128. This'MBAR'
resource defines the order and resource IDs of the menus contained in it; it defines its first
three menus as the menus with resource IDs 128, 129, and 130. The Menu Manager
uses the assigned resource IDs to read in the menus when it creates a menu bar from
an'MBAR'
resource.Setting Up Your Application's Menu Bar
To create a menu list as defined in an'MBAR'
resource, use theGetNewMBar
function. For each menu defined by the'MBAR'
resource, theGetNewMBar
function creates a menu record for the menu, creates each menu according to its resource definition in its corresponding'MENU'
resource, and inserts each menu into the new menu list. TheGetNewMBar
function returns a handle to the created menu list. For example, this code creates a menu list for the menu bar defined by the'MBAR'
resource with resource ID 128 (defined by the constantrMenuBar
):
CONST rMenuBar = 128; VAR menuBar: Handle; menuBar := GetNewMBar(rMenuBar); {read menus and menu bar } { descriptions,create & return } { a handle to a new menu list}Use theSetMenuBar
procedure to set the current menu list to the menu list created
by your application and theDrawMenuBar
procedure to update the menu bar's appearance. For example, Listing 3-5 uses these two routines to set up the application's menu bar.Listing 3-5 Setting up an application's menus and menu bar
PROCEDURE MyMakeMenus; VAR menuBar: Handle; BEGIN {first use the GetNewMBar function to read menus in & create a } { new menu list. If you define an Apple menu, the Menu Manager } { inserts the Help and Application menus (and Keyboard menu if } { necessary) into the newly created menu list} menuBar := GetNewMBar(rMenuBar); IF menuBar = NIL THEN EXIT(MyMakeMenus); SetMenuBar(menuBar); {insert menus into the current menu list} DisposHandle(menuBar); {add desktop items in Apple Menu Items } { folder to Apple menu} AppendResMenu(GetMenuHandle(mApple), 'DRVR'); MyAdjustMenus; {adjust items and enabled state of menus} DrawMenuBar; {draw the menu bar} END;The code in Listing 3-5 creates the application's menu bar by reading in the definition from the'MBAR'
resource with resource ID 128, and it usesSetMenuBar
to set the current menu list to the newly created menu list. The code then adds the desktop
items in the Apple Menu Items folder to the Apple menu using theAppendResMenu
procedure.You can use the
GetMenuHandle
function to get a handle to the menu record of
any menu in the current menu list. You supply the menu ID of the desired menu as a parameter toGetMenuHandle
, andGetMenuHandle
returns a handle to the menu's menu record. Most Menu Manager routines require either a menu ID or a handle to
a menu record as a parameter.After creating the menu bar and adding any other menus or items as necessary, the code calls the
MyAdjustMenus
procedure to adjust the application's menus--for example, this procedure sets the enabled and disabled states of menu items in accordance with the current state of the application. (Listing 3-19 on page 3-76 shows the application-definedMyAdjustMenus
procedure used in Listing 3-5.) After adjusting the menus, the code in Listing 3-5 usesDrawMenuBar
to draw the menus in the menu bar according to their current enabled state and as they are defined in the current menu list.Usually you'll define the menus of your application and its menu bar using
'MENU'
resources and an'MBAR'
resource and using theGetNewMBar
function to read the resource definitions. However, you can choose to read in a'MENU'
resource using theGetMenu
function or to create a new empty menu usingNewMenu
. You can then insert
a menu into the current menu list using theInsertMenu
procedure. See "Creating Menus" on page 3-105 and "Adding Menus to and Removing Menus From the Current Menu List" on page 3-108 for information on forming your menus using these routines.If your application uses a submenu, you need to use the
GetMenu
function andInsertMenu
procedure to make these menus available to your application. See "Creating a Hierarchical Menu" on page 3-55 for information on creating submenus.
If your application uses a pop-up menu, you can use the pop-up control definition function and Dialog Manager or Control Manager routines to create and display
the pop-up menu. See "Creating a Pop-Up Menu" on page 3-58 for information on creating pop-up menus.The Menu Manager creates and initializes your application's menu color information table when your application calls
GetNewMBar
. You can add entries to your application's menu color information table if you want to use colors other than the default colors in your menus and menu bar. You can add entries to this table by providing menu color information table ('mctb'
) resources or by using theSetMCEntries
procedure. Usually you should use the default colors to help maintain
a consistent user interface.If you add menu color entries to your application's menu color information table and your application uses more than one menu bar, you need to save a copy of your application's menu color information table before changing menu bars. Use the
GetMCInfo
function before callingGetNewMBar
and callSetMCInfo
afterward to restore the menu color information table. Listing 3-6 shows a routine that saves and
then restores the menu color information table when creating a new menu bar.Listing 3-6 Saving and restoring menu color information
PROCEDURE MyChangeMenuBarAndSaveColorInfo; CONST rMenuBar2 = 129; VAR menu: MenuHandle; menuBar: Handle; currentMCTable: MCTableHandle; newMCTable: MCTableHandle; BEGIN currentMCTable := GetMCInfo; {save menu color info table} IF currentMCTable = NIL THEN EXIT(MyChangeMenuBarAndSaveColorInfo); menuBar := GetNewMBar(rMenuBar2);{read menus in & create new menu list} IF menuBar = NIL THEN EXIT(MyChangeMenuBarAndSaveColorInfo); newMCTable := GetMCInfo; {get new menu color info table} IF newMCTable = NIL THEN EXIT(MyChangeMenuBarAndSaveColorInfo); SetMCInfo(currentMCTable); {restore previous menu color info table} SetMenuBar(menuBar); {insert menus into the current menu list} DisposHandle(menuBar); AppendResMenu(GetMenuHandle(m2Apple), 'DRVR'); {add desktop items from } { Apple Menu Items folder to Apple menu} MyAdjustMenus; {adjust menu items} DrawMenuBar; {draw the menu bar} END;