Sprocket Menus 1
Volume Number: 11
Issue Number: 5
Column Tag: Getting Started
Sprocket Menus, Part 1
By Dave Mark, MacTech Magazine Regular Contributing Author
Note: Source code files accompanying article are located on MacTech CD-ROM or
source code disks.
My February ’93 Getting Started column featured a program called MenuMaster.
MenuMaster constructed a menu bar consisting of four menus: The traditional Apple,
File, and Edit menus, as well as a special Options menu (Figure 1). Selecting the
first item changes it from Change My Name to Change Me Back Again. Selecting
the first item again changes it back to Change My Name.
Selecting Disable Me disables the second item and enables the third item. If you
then select the newly enabled Enable Previous Item, it gets disabled and Disable
Me is reenabled.
If you select Add Extra Menu, a new menu is inserted in the menu bar and Add
Extra Menu is disabled. The new menu, titled Extra Menu, features a single item,
Delete Me. Selecting Delete Me deletes the extra menu from the menu bar and
reenables Add Extra Menu.
Finally, selecting Append Item adds an extra item (Can’t Delete Me...) to the
end of the menu. As its names implies, there’s no way to delete this extra item.
Fig. 1. MenuMaster’s Options menu.
A Sprocket Version of MenuMaster
This month we’re going to use Sprocket to implement most of MenuMaster’s
functionality. We’ll skip the ability to append an item to the end of a menu for two
reasons. First, appending a single item to the end of a menu just isn’t done that often
and isn’t particularly useful. More importantly (and probably for the same reason),
Sprocket doesn’t give you an easy way to append a new item to a menu.
If you come up with a good reason to add this functionality to Sprocket (or if you have
any comments or bugs to report), send e-mail to sprocket@hax.com.
As I mentioned last month, Sprocket based its menu-handling model on that used by
OpenDoc. At the heart of this model is a replacement for the MENU resource type. A
CMNU resource is just like a MENU resource, with one important addition. Each menu
item features a command number. You’ll use this command number to refer to the
item, instead of the more traditional method of specifying the menu the item belongs to,
along with the item’s position in the menu (e.g., menu 129, item 4).
Figure 2. The CMNU resource, featuring a Cmd-Num field for each menu item.
Check out the ResEdit snapshot in Figure 2. It shows the CMNU resource that
represents our new Options menu. The first menu item, Change My Name, is
selected. The command number for this item is 1000. When the user selects this item,
Sprocket will pass the associated command number (in this case, 1000) as a
parameter to the routine HandleMenuCommand() (it’s in the file
SprocketStarter.cp). Instead of creating a separate item dispatch routine for each
menu (HandleAppleMenu(), HandleFileMenu(), etc.), you’ll create a single switch
statement containing cases for all your commands.
Sprocket automatically creates a menu bar at application startup. In C++ terms,
Sprocket constructs a TMenuBar object, which is implemented in the files
TMenuBar.cp and TMenuBar.h. Here’s the TMenuBar class definition:
class TMenuBar
{
public:
Resource ('MBAR' and 'CMNU') Utilities
OSErr GetNewMenuBar(short whichMBAR);
MenuRef GetMenuFromCMNU(short whichMenu);
Menu command mapping functions
MenuCommandID GetCommand(MenuID menu, MenuItemID item);
void GetMenuAndItem(MenuCommandID commandNum,
MenuID * returnedMenu, MenuItemID * returnedItem);
OSErr RegisterCommand( MenuCommandID commandNum,
MenuID menu, MenuItemID item);
OSErr UnregisterCommand(MenuCommandID commandNum);
Menu enable/disable routines for menu items
void EnableCommand(MenuCommandID commandNum,
Boolean enable);
void EnableAndCheckCommand(MenuCommandID commandNum,
Boolean enable, Boolean check);
void GetItemString(MenuCommandID commandNum,
StringPtr itemString);
void SetItemString(MenuCommandID commandNum,