Apple1992 Inside - Macintosh Toolbox - Essentials
Apple1992 Inside - Macintosh Toolbox - Essentials
INSIDE MACINTOSH
iii
About the Event Manager 2-16
Using the Event Manager 2-17
Obtaining Information About Events 2-18
Processing Events 2-21
Using the WaitNextEvent Function 2-22
Writing an Event Loop 2-24
Setting the Event Mask 2-26
Handling Events in a Dialog Box 2-29
Creating a Size Resource 2-30
Handling Low-Level Events 2-32
Responding to Mouse Events 2-33
Responding to Keyboard Events 2-38
Scanning for a Cancel Event 2-46
Responding to Update Events 2-47
Responding to Activate Events 2-50
Responding to Disk-Inserted Events 2-55
Responding to Null Events 2-57
Handling Operating-System Events 2-58
Responding to Suspend and Resume Events 2-60
Responding to Mouse-Moved Events 2-62
Handling High-Level Events 2-67
Responding to Events From Other Applications 2-69
Searching for a Specific High-Level Event 2-71
Determining the Sender of a High-Level Event 2-72
Sending High-Level Events 2-73
Requesting Return Receipts 2-77
Handling Apple Events 2-78
Event Manager Reference 2-78
Data Structures 2-78
The Event Record 2-79
The Target ID Record 2-81
The High-Level Event Message Record 2-82
The Event Queue 2-83
Event Manager Routines 2-84
Receiving Events 2-84
Sending Events 2-100
Converting Process Serial Numbers and Port Names 2-105
Reading the Mouse 2-108
Reading the Keyboard 2-110
Getting Timing Information 2-112
Application-Defined Routine 2-114
Filter Function for Searching the High-Level Event Queue 2-114
Resource 2-115
The Size Resource 2-115
Summary of the Event Manager 2-120
Pascal Summary 2-120
Constants 2-120
iv
Data Types 2-122
Event Manager Routines 2-123
Application-Defined Routine 2-124
C Summary 2-125
Constants 2-125
Data Types 2-127
Event Manager Routines 2-128
Application-Defined Routine 2-129
Assembly-Language Summary 2-130
Data Structures 2-130
Trap Macros 2-130
Global Variables 2-131
Result Codes 2-132
v
Changing the Appearance of Items in a Menu 3-57
Enabling and Disabling Menu Items 3-58
Changing the Text of an Item 3-59
Changing the Font Style of Menu Items 3-60
Changing the Mark of Menu Items 3-61
Changing the Icon or Script Code of Menu Items 3-62
Adding Items to a Menu 3-64
Adding Items to the Help Menu 3-67
Adding Items to the Apple Menu 3-68
Adding Fonts to a Menu 3-69
Handling User Choice of a Menu Command 3-70
Handling Mouse-Down Events in the Menu Bar 3-72
Adjusting the Menus of an Application 3-73
Determining if the User Chose a Keyboard Equivalent 3-77
Responding When the User Chooses a Menu Item 3-78
Handling the Apple Menu 3-80
Handling the Help Menu 3-81
Handling a Size Menu 3-82
Accessing Menus From a Dialog Box 3-84
Writing Your Own Menu Definition Procedure 3-87
Calculating the Dimensions of a Menu 3-89
Drawing Menu Items in a Menu 3-90
Determining Whether the Cursor Is in an Enabled Menu Item 3-92
Menu Manager Reference 3-95
Data Structures 3-95
The Menu Record 3-95
The Menu List 3-97
The Menu Color Information Table Record 3-98
Menu Manager Routines 3-102
Initializing the Menu Manager 3-103
Creating Menus 3-105
Adding Menus to and Removing Menus From the Current
Menu List 3-108
Getting a Menu Bar Description From an 'MBAR' Resource 3-110
Getting and Setting the Menu Bar 3-112
Drawing the Menu Bar 3-113
Responding to the User’s Choice of a Menu Command 3-114
Getting a Handle to a Menu Record 3-122
Adding and Deleting Menu Items 3-124
Getting and Setting the Appearance of Menu Items 3-130
Disposing of Menus 3-140
Counting the Items in a Menu 3-140
Highlighting the Menu Bar 3-141
Recalculating Menu Dimensions 3-142
Managing Entries in the Menu Color Information Table 3-143
Application-Defined Routine 3-148
The Menu Definition Procedure 3-148
vi
Resources 3-151
The Menu Resource 3-151
The Menu Bar Resource 3-155
The Menu Color Information Table Resource 3-155
The Menu Definition Procedure Resource 3-157
Summary of the Menu Manager 3-158
Pascal Summary 3-158
Constants 3-158
Data Types 3-158
Menu Manager Routines 3-159
Application-Defined Routine 3-162
C Summary 3-162
Constants 3-162
Data Types 3-163
Menu Manager Routines 3-164
Application-Defined Routine 3-166
Assembly-Language Summary 3-167
Data Structures 3-167
Global Variables 3-167
Result Codes 3-167
vii
Handling Keyboard Events in Windows 4-47
Handling Update Events 4-48
Handling Activate Events 4-50
Moving a Window 4-53
Zooming a Window 4-53
Resizing a Window 4-57
Closing a Window 4-60
Hiding and Showing a Window 4-62
Window Manager Reference 4-64
Window Manager Reference 4-65
Data Structures 4-65
The Color Window Record 4-65
The Window Record 4-69
The Window State Data Record 4-70
The Window Color Table Record 4-71
The Auxiliary Window Record 4-73
The Window List 4-74
Window Manager Routines 4-74
Initializing the Window Manager 4-74
Creating Windows 4-75
Naming Windows 4-85
Displaying Windows 4-86
Retrieving Window Information 4-91
Moving Windows 4-94
Resizing Windows 4-99
Zooming Windows 4-101
Closing and Deallocating Windows 4-103
Maintaining the Update Region 4-106
Setting and Retrieving Other Window Characteristics 4-109
Manipulating the Desktop 4-112
Manipulating Window Color Information 4-114
Low-Level Routines 4-116
Application-Defined Routine 4-120
The Window Definition Function 4-120
Resources 4-124
The Window Resource 4-124
The Window Definition Function Resource 4-127
The Window Color Table Resource 4-127
Summary of the Window Manager 4-130
Pascal Summary 4-130
Constants 4-130
Data Types 4-132
Window Manager Routines 4-134
Application-Defined Routine 4-136
C Summary 4-137
Constants 4-137
Data Types 4-139
viii
Window Manager Routines 4-140
Application-Defined Routine 4-143
Assembly-Language Summary 4-144
Data Types 4-144
Global Variables 4-145
x
Manipulating Items 6-44
Changing Static Text 6-46
Getting Text From Editable Text Items 6-48
Adding Items to an Existing Dialog Box 6-51
Using an Application-Defined Item to Draw the Bold Outline
for a Default Button 6-56
Using the Dialog Manager 6-61
Using the Dialog Manager 6-61
Displaying Alert and Dialog Boxes 6-61
Positioning Alert and Dialog Boxes 6-62
Deactivating Windows Behind Alert and Modal Dialog Boxes 6-64
Displaying Modeless Dialog Boxes 6-66
Adjusting Menus for Modal Dialog Boxes 6-68
Adjusting Menus for Movable Modal and Modeless Dialog Boxes 6-73
Displaying Multiple Alert and Dialog Boxes 6-74
Displaying Alert and Dialog Boxes From the Background 6-74
Including Color in Your Alert and Dialog Boxes 6-75
Handling Events in Alert and Dialog Boxes 6-77
Responding to Events in Controls 6-78
Responding to Events in Editable Text Items 6-79
Responding to Events in Alert Boxes 6-81
Responding to Events in Modal Dialog Boxes 6-82
Writing an Event Filter Function for Alert and Modal
Dialog Boxes 6-86
Responding to Mouse Events in Modeless and
Movable Modal Dialog Boxes 6-89
Responding to Keyboard Events in Modeless and
Movable Modal Dialog Boxes 6-94
Responding to Activate and Update Events in Modeless and Movable
Modal Dialog Boxes 6-97
Closing Dialog Boxes 6-100
Dialog Manager Reference 6-101
Data Structure 6-101
The Dialog Record 6-101
Dialog Manager Routines 6-102
Initializing the Dialog Manager 6-103
Creating Alerts 6-105
Creating and Disposing of Dialog Boxes 6-113
Manipulating Items in Alert and Dialog Boxes 6-120
Handling Text in Alert and Dialog Boxes 6-129
Handling Events in Dialog Boxes 6-135
Application-Defined Routines 6-143
Resources 6-147
The Dialog Resource 6-148
The Alert Resource 6-150
The Item List Resource 6-151
The Dialog Color Table Resource 6-156
The Alert Color Table Resource 6-157
The Item Color Table Resource 6-158
xi
Summary of the Dialog Manager 6-165
Pascal Summary 6-165
Constants 6-165
Data Types 6-166
Dialog Manager Routines 6-166
Application-Defined Routines 6-168
C Summary 6-168
Constants 6-168
Data Types 6-169
Dialog Manager Routines 6-170
Application-Defined Routines 6-172
Assembly-Language Summary 6-172
Data Structures 6-172
Global Variables 6-172
xii
Resources 7-56
The Signature Resource 7-57
The Icon List Resource 7-57
The Small Icon List Resource 7-58
The Large 4-Bit Color Icon Resource 7-59
The Small 4-Bit Color Icon Resource 7-60
The Large 8-Bit Color Icon Resource 7-61
The Small 8-Bit Color Icon Resource 7-62
The Icon Resource 7-63
The Color Icon Resource 7-64
The File Reference Resource 7-64
The Bundle Resource 7-65
The Missing-Application Name String 7-68
The Application-Missing Message String 7-68
The Version Resource 7-69
Summary of the Finder Interface 7-71
Pascal Summary 7-71
Constants 7-71
Data Types 7-73
Routines 7-74
C Summary 7-74
Constants 7-74
Data Types 7-76
Routines 7-77
Assembly-Language Summary 7-77
Data Structures 7-77
Result Codes 7-78
Glossary GL-1
Index IN-1
xiii
Figures, Tables, and Listings
xv
Listing 2-9 Responding to update events 2-50
Listing 2-10 Responding to activate events 2-53
Listing 2-11 Responding to disk-inserted events 2-56
Listing 2-12 Handling null events 2-57
Listing 2-13 Responding to operating-system events 2-59
Listing 2-14 Responding to suspend and resume events 2-61
Listing 2-15 Changing the cursor 2-65
Listing 2-16 Accepting a high-level event 2-70
Listing 2-17 Posting a high-level event by application signature 2-74
Listing 2-18 Using the PPCBrowser function to post a high-level event 2-76
Listing 2-19 A Rez template for a 'SIZE' resource 2-116
xvi
Figure 3-33 A pop-up menu in a dialog box 3-56
Figure 3-34 Icons in menu items 3-63
Figure 3-35 A Size menu with user-specified size added 3-82
Figure 3-36 Menu access from a modal dialog box 3-85
Figure 3-37 Structure of a compiled menu ('MENU') resource 3-152
Figure 3-38 The variable-length data that describes menu items as defined by
the standard menu definition procedure 3-153
Figure 3-39 Structure of a compiled menu bar ('MBAR') resource 3-155
Figure 3-40 Structure of a compiled menu color information table
('mctb') resource 3-156
Figure 3-41 Structure of a menu color entry in an 'mctb' resource 3-157
Listing 3-1 Rez input for a 'MENU' resource for the Apple menu 3-43
Listing 3-2 Rez input for a 'MENU' resource for an Edit menu 3-48
Listing 3-3 Rez input for a 'MENU' resource for a File menu 3-49
Listing 3-4 Rez input for an 'MBAR' resource 3-49
Listing 3-5 Setting up an application’s menus and menu bar 3-50
Listing 3-6 Saving and restoring menu color information 3-52
Listing 3-7 Rez input for a description of a hierarchical menu with
a submenu 3-54
Listing 3-8 Creating a hierarchical menu 3-55
Listing 3-9 Changing the text of a menu item 3-59
Listing 3-10 Setting the font style of menu items 3-60
Listing 3-11 Adding marks to and removing marks from menu items 3-61
Listing 3-12 Specifying icons for menu items 3-63
Listing 3-13 Rez input for text of menu items 3-66
Listing 3-14 Adding an item to the Help menu 3-68
Listing 3-15 Adding menu items to the Apple menu 3-69
Listing 3-16 Adding font names to a menu 3-70
Listing 3-17 Determining whether a mouse-down event occurred 3-72
Listing 3-18 Determining when the cursor is in the menu bar 3-72
Listing 3-19 Adjusting an application’s menus 3-74
Listing 3-20 Adjusting the File menu for a document window 3-74
Listing 3-21 Adjusting the Edit menu for a document window 3-75
Listing 3-22 Determining when a key is pressed 3-77
Listing 3-23 Checking a key-down event for a keyboard equivalent 3-78
Listing 3-24 Responding to the user’s choice of a menu command 3-79
Listing 3-25 Responding to the user’s choice of an item from the
Apple menu 3-80
Listing 3-26 Responding to the user’s choice of a command from the
Help menu 3-81
xvii
Listing 3-27 Handling the Size menu 3-83
Listing 3-28 A sample menu definition procedure 3-89
Listing 3-29 Calculating the size of a menu 3-90
Listing 3-30 Drawing menu items 3-91
Listing 3-31 Choosing menu items 3-93
xviii
Listing 4-9 Handling mouse-down events 4-44
Listing 4-10 Handling update events 4-50
Listing 4-11 Handling activate events 4-51
Listing 4-12 Zooming a window 4-55
Listing 4-13 Resizing a window 4-58
Listing 4-14 Adjusting scroll bars and content region when resizing
a window 4-59
Listing 4-15 Converting a window region to local coordinates 4-60
Listing 4-16 Handling a close command 4-60
Listing 4-17 Closing a document 4-61
Listing 4-18 Showing a hidden dialog box 4-64
Table 5-1 Mapping between new and previous names of Control Manager
routines 5-80
xix
Listing 5-3 Rez input for the control resources of radio buttons 5-21
Listing 5-4 Rez input for resources for a window and its scroll bars 5-23
Listing 5-5 Creating a document window with scroll bars 5-24
Listing 5-6 Rez input for the control resource of a pop-up menu 5-26
Listing 5-7 Responding to an update event for a window 5-29
Listing 5-8 Redrawing the controls in the update region 5-30
Listing 5-9 Detecting mouse-down events in a window 5-32
Listing 5-10 Detecting mouse-down events in a pop-up menu and a
button 5-33
Listing 5-11 Using the TrackControl function with a button 5-36
Listing 5-12 Using TrackControl with a pop-up menu 5-37
Listing 5-13 Responding to a click in a checkbox 5-38
Listing 5-14 Adjusting scroll bar settings and locations 5-39
Listing 5-15 Assigning settings to scroll bars 5-40
Listing 5-16 Adjusting the maximum and current settings for a scroll
bar 5-41
Listing 5-17 Using ScrollRect to scroll the bits displayed in the
window 5-47
Listing 5-18 Responding to mouse events in a scroll bar 5-53
Listing 5-19 Action procedures for scrolling through a text document 5-59
Listing 5-20 Moving the scroll box from the action procedures 5-61
Listing 5-21 An application-defined update routine 5-62
Listing 5-22 Redrawing a window containing graphics objects 5-63
Listing 5-23 Redrawing a window after scrolling a TextEdit edit record 5-65
Listing 5-24 Changing the size and location of a window’s scroll bars 5-67
xx
Figure 6-22 A less obscure alert message 6-41
Figure 6-23 A clear and helpful alert message 6-41
Figure 6-24 A pop-up menu in a dialog box 6-42
Figure 6-25 A selected scrolling list 6-45
Figure 6-26 An alert box that displays a document name 6-46
Figure 6-27 Two editable text items in a modeless dialog box 6-48
Figure 6-28 An existing dialog box and items to append 6-51
Figure 6-29 The dialog box after items are overlaid 6-52
Figure 6-30 The dialog box after items are appended to the right 6-52
Figure 6-31 The dialog box after items are appended to the bottom 6-53
Figure 6-32 A dialog box with an item appended relative to an
existing item 6-53
Figure 6-33 An alert box in front of a document window 6-63
Figure 6-34 An alert box on the main screen 6-63
Figure 6-35 An alert box in the alert position of the document
window screen 6-64
Figure 6-36 An alert box displayed only after the third alert stage 6-65
Figure 6-37 A modeless dialog box for changing text in a document 6-66
Figure 6-38 Menu access when displaying a modal dialog box 6-69
Figure 6-39 Three buttons for which CautionAlert reports events 6-81
Figure 6-40 Four items for which ModalDialog reports events 6-83
Figure 6-41 A modeless dialog box for which DialogSelect
reports events 6-91
Figure 6-42 Structure of a compiled dialog ('DLOG') resource 6-148
Figure 6-43 Structure of a compiled alert ('ALRT') resource 6-150
Figure 6-44 Structure of a compiled item list ('DITL') resource 6-152
Figure 6-45 Structure of compiled button, checkbox, radio button, static text,
and editable text items 6-153
Figure 6-46 Structure of compiled control, icon, and picture items 6-154
Figure 6-47 Structure of a compiled application-defined item 6-155
Figure 6-48 Structure of compiled help items 6-155
Figure 6-49 Structure of a compiled item color table resource 6-159
Figure 6-50 Structure of a compiled control color table 6-161
Figure 6-51 Structure of a compiled text style table 6-162
Table 6-1 Mapping between new and previous names of Dialog Manager
routines 6-102
xxi
Listing 6-10 Specifying where ParamText should substitute text in an alert
box message 6-48
Listing 6-11 Specifying editable text items in an item list 6-49
Listing 6-12 Getting the text entered by the user in an editable text item 6-49
Listing 6-13 Appending an item to an existing dialog box 6-54
Listing 6-14 Rez input for a dialog box and the item appended to it 6-55
Listing 6-15 Rez input for an application-defined item in an item list 6-57
Listing 6-16 Installing the draw procedure for an application-defined
item 6-58
Listing 6-17 Creating a draw procedure that draws a bold outline around the
default button 6-59
Listing 6-18 Deactivating the front window before displaying an
alert box 6-65
Listing 6-19 Using GetAlertStage to determine when to deactivate the
front window 6-66
Listing 6-20 Ensuring that the modeless dialog box isn’t already open before
creating it 6-67
Listing 6-21 Adjusting menus for various windows 6-70
Listing 6-22 Disabling menus for a modal dialog box with editable
text items 6-70
Listing 6-23 Adjusting the Edit menu for a modal dialog box 6-72
Listing 6-24 Rez input for a dialog color table resource using the system’s
default colors 6-75
Listing 6-25 Using DialogSelect during null events 6-79
Listing 6-26 Responding to events in a modal dialog box 6-83
Listing 6-27 A typical event filter function for alert and modal
dialog boxes 6-88
Listing 6-28 Handling mouse-down events for all windows 6-91
Listing 6-29 Using the DialogSelect function for responding to
mouse-down events 6-92
Listing 6-30 Hiding a modeless dialog box in response to a
Close command 6-94
Listing 6-31 Checking for key-down events involving the Command key 6-95
Listing 6-32 Checking for key-down events in a modeless dialog box 6-95
Listing 6-33 Responding to key-down events in a modeless dialog box 6-96
Listing 6-34 Activating a modeless dialog box 6-98
Listing 6-35 Updating a modeless dialog box 6-99
Figure 7-1 Application and document icons in a window on the desktop 7-4
Figure 7-2 A customized help balloon for an application icon 7-5
Figure 7-3 A Finder message identifying a missing application 7-5
Figure 7-4 Large black-and-white application icons for a company’s
product line 7-12
Figure 7-5 Default large black-and-white icons 7-12
Figure 7-6 A black-and-white icon and its mask for an application 7-13
Figure 7-7 The ResEdit view of an icon 7-14
Figure 7-8 Linking icon list resources and file reference resources in a
bundle resource 7-23
Figure 7-9 The default application-unavailable alert box 7-27
xxii
Figure 7-10 The application-unavailable alert box specifying an
application’s name 7-29
Figure 7-11 The application-unavailable alert box with a customized
message 7-30
Figure 7-12 The application-unavailable alert box for 'TEXT' and
'PICT' documents 7-30
Figure 7-13 The version data in the information window 7-33
Figure 7-14 Default and customized help balloons for application icons 7-38
Figure 7-15 The System Folder and related folders 7-42
Figure 7-16 Structure of a signature resource compiled as a string
('STR ') resource 7-57
Figure 7-17 Structure of a compiled icon list ('ICN#') resource 7-58
Figure 7-18 Structure of a compiled small icon list ('ics#') resource 7-59
Figure 7-19 Structure of a compiled large 4-bit color icon
('icl4') resource 7-60
Figure 7-20 Structure of a compiled small 4-bit color icon
('ics4') resource 7-61
Figure 7-21 Structure of a compiled large 8-bit color icon
('icl8') resource 7-62
Figure 7-22 Structure of a compiled small 8-bit color icon
('ics8') resource 7-63
Figure 7-23 Structure of a compiled icon ('ICON') resource 7-64
Figure 7-24 Structure of a compiled file reference ('FREF') resource 7-65
Figure 7-25 Structure of a compiled bundle ('BNDL') resource 7-66
Figure 7-26 Mapping local IDs to icon list resource IDs in a
bundle resource 7-67
Figure 7-27 Structure of superfluous local ID mapping for file reference
resources in a bundle resource 7-67
Figure 7-28 Structure of a compiled missing-application name
string resource 7-68
Figure 7-29 Structure of a compiled application-missing message
string resource 7-69
Figure 7-30 Format of a compiled version ('vers') resource 7-70
xxiii
P R E F A C E
This book, Inside Macintosh: Macintosh Toolbox Essentials, describes the essential
elements of a Macintosh application and the system software routines that you
can use to implement them.
If you are new to programming on the Macintosh computer, you should also
read Inside Macintosh: Overview for an introduction to general concepts of
Macintosh programming and Macintosh Human Interface Guidelines for a
complete discussion of user interface guidelines and principles that every
Macintosh application should follow.
This book describes events, windows, menus, controls, alert boxes, and dialog
boxes. It also discusses how your application interacts with the Finder.
Macintosh applications respond to user actions and to other hardware- and
software-related events. To design your application so that it can respond to
events (such as keyboard input, mouse input, changes in the appearance of
windows on the screen, and changes in your application’s processing status),
see the chapter “Event Manager” in this book.
To create menus and set up your application’s menu bar, see the chapter
“Menu Manager.” This chapter describes how to define the items in your
menus, how to enable and disable menus, how to allow the user to choose
a menu item, and how to respond once the user chooses a menu item.
To create windows in which the user can view or edit information, see the
chapter “Window Manager.” This chapter describes the basic types of
windows and discusses how your application can work together with the
Window Manager to support the standard user interface conventions
associated with manipulating a window, such as moving a window, zooming
a window, and resizing a window.
To create controls in your application’s windows—such as scroll bars—or to
create controls in dialog boxes—such as buttons or checkboxes—see the
chapter “Control Manager.”
To create dialog boxes or alert boxes—windows that your application uses to
communicate with or solicit information from the user—see the chapter
“Dialog Manager.”
To create icons for your applications and the documents it creates, see the
chapter “Finder Interface.” This chapter also introduces file types and
creators and describes the various kinds of resources (icons, file references,
and bundles) that the Finder needs to display your application and the
documents it creates.
After implementing the basic elements of a Macintosh application as described
in this book, you can add additional features, such as help balloons and
xxv
P R E F A C E
support for copy and paste, as described in Inside Macintosh: More Macintosh
Toolbox. You can also find detailed information about the Resource Manager in
Inside Macintosh: More Macintosh Toolbox.
Once you understand how to create menus, windows, and dialog boxes, you
can save information that the user enters in a window by writing the data to a
file. You can also open a previously saved file and read the information from
the file into a window. You use the File Manager to open, read, write, and close
files. See the chapter “Introduction to File Management” in Inside Macintosh:
Files for information on how to read and write files.
For information about drawing into a window or other graphics port, see
Inside Macintosh: Imaging.
For information on handling text in your application, see Inside
Macintosh: Text.
For information on communicating with other applications, see Inside
Macintosh: Interapplication Communication.
xxvi
P R E F A C E
Special Fonts 0
All code listings, reserved words, and names of actual data structures,
fields, constants, parameters, and routines are shown in Courier (this
is Courier).
Words that appear in boldface are key terms or concepts and are defined in
the Glossary.
Types of Notes 0
There are several types of notes used in this book.
Note
A note like this contains information that is interesting but possibly not
essential to an understanding of the main text. (An example appears on
page 2-7.) ◆
IMPORTANT
A note like this contains information that is essential for an
understanding of the main text. (An example appears on page 5-27.) ▲
▲ WARNING
Warnings like this indicate potential problems that you should be aware
of as you design your application. Failure to heed these warnings could
result in system crashes or loss of data. (An example appears on page
page 2-105.) ▲
Empty Strings 0
This book occasionally instructs you to provide an empty string in routine
parameters and resources. How you specify an empty string depends on what
language and development environment you are using. In Rez input files and
in C code, for example, you specify an empty string by using two double
quotation marks (""), and in Pascal you specify an empty string by using two
single quotation marks ('').
Assembly-Language Information 0
Inside Macintosh provides information about the registers for specific routines
like this:
Registers on entry
A0 Contents of register A0 on entry
Registers on exit
D0 Contents of register D0 on exit
xxvii
P R E F A C E
The left column indicates the byte offset of the field from the beginning of the
data structure. The second column shows the field name as defined in the
MPW Pascal interface files; the third column indicates the size of that field.
The fourth column provides a brief description of the use of the field. For a
complete description of each field, see the discussion of the data structure in
the reference section of the chapter.
xxviii
C H A P T E R 1
Figure 1-0
Listing 1-0
Table 1-0
1 Introduction to the
Macintosh Toolbox
Contents
Overview of the Macintosh Toolbox 1-4
Events 1-5
Menus 1-6
Windows 1-6
Controls 1-7
Alert Boxes and Dialog Boxes 1-8
Icons and Other Interactions With the Finder 1-10
Resources 1-11
Help Balloons 1-14
Copy and Paste 1-14
Related System Software Features 1-14
Drawing on the Screen 1-14
Handling Text 1-14
Managing Files 1-15
Allocating Memory and Launching Processes 1-15
Creating Publishers and Subscribers 1-15
Communicating With Other Applications 1-16
Designing Your Application 1-16
Contents 1-1
C H A P T E R 1
This chapter presents an introduction to the features provided by the Macintosh Toolbox.
The Macintosh Toolbox is a collection of system software routines that your application
can use to present a consistent and standard interface to the user; these routines also
allow you to simplify other tasks your application might need to perform.
A typical Macintosh application presents a friendly, intuitive, easy-to-use, visual inter-
face to the user. The careful design of a Macintosh application gives users the freedom
to perform actions and accomplish tasks according to their needs. The idea behind this
careful design is to put the user in control. In general, the user of a Macintosh application
should always be free to choose the next action he or she will perform. (This is the basic
tenet of the event loop and is explained in more detail in the chapter “Event Manager” in
this book.)
Figure 1-1 shows the screen as it might appear when a user is interacting with a typical
Macintosh application, such as SurfWriter. The SurfWriter application is an application
that lets a user do simple text editing. Like most Macintosh applications, the SurfWriter
application uses
■ menus to let the user choose commands
■ windows to allow the user to enter and edit information
■ scroll bars to allow the user to view more information in a window
Figure 1-1 The SurfWriter application with multiple windows on the desktop
Active window
Menu bar
Menu
1-3
C H A P T E R 1
■ other controls (such as the Change button) to let the user control various settings
or options
■ dialog boxes to solicit information from the user
You can create an application that incorporates these user-interface elements and that
helps users accomplish specific tasks by taking advantage of the routines provided by the
Macintosh Toolbox.
The best Macintosh applications are designed according to the guidelines in Macintosh
Human Interface Guidelines. You should always design your application so that it meets
the needs of its users and responds in consistent and expected ways. Macintosh Human
Interface Guidelines describes
■ the philosophy and the design principles behind the Macintosh interface
■ the parts of the Macintosh interface including the interface elements and behaviors
■ ways to do human interface design for Macintosh products
You can often get valuable feedback on the design of your application by performing user
testing. Do usability testing of your application early and often in the development phase
of your product.
Events 1
At the core of every Macintosh application is the application’s event loop. The event loop
is that piece of code in an application that processes and responds to user actions and
other events. You can use the Event Manager to retrieve information about these actions.
For example, you can get information that tells your application whether the user pressed
a key or the mouse button, whether one of your application’s windows needs updating
as a result of the user moving windows, or whether some other hardware or software
action requires a response from your application.
You should structure your application so that it can respond to events and so that the
user is able to perform tasks in any order. For example, a user should be able to type text
in a window, select a graphic and copy it, open a new document, paste in the graphic,
open another document, and then go back to the first window to select text and change
its typeface, size, or style.
Your application should respond to events in a way that lets the user switch between
your application and others whenever the user chooses to do so (for example, by clicking
in a window belonging to another application). Your application should also yield time to
other applications when it isn’t busy. System software provides a cooperative
multitasking environment that allows users to switch between many open applications
and that allows applications to receive available processing time when other applications
aren’t using the processor. System software coordinates the scheduling of processing time
between your application and other applications.
You can also let your application communicate with other applications in order to request
services or information from another application or to provide services to other
applications. You can use the Event Manager or Apple Event Manager to do this.
The chapter “Event Manager” in this book describes how to structure your event loop
and event-handling code to receive notification of user actions and changes in the
processing status of your application, how to communicate with other applications, and
how to respond to these events.
Menus 1
Menus are an important part of the design of a Macintosh application. Menus let users
view or choose an item from a list of choices or commands that your application
provides. You design your menus according to the tasks or actions your application
performs. All applications should support the Apple, File, Edit, Help, Keyboard, and
Application menus. Figure 1-1 on page 1-3 shows the File menu of the SurfWriter
application.
System software makes it easy for you to create pull-down, hierarchical, and pop-up
menus. The chapter “Menu Manager” in this book describes how to create your
application’s menus, set up your menu bar, display menus, and respond to the user’s
choice of an item from a menu.
Windows 1
Most applications interact with the user through windows. Figure 1-2 shows a common
window and its elements. The chapter “Window Manager” in this book describes the
types of windows your application can create and how to respond to user actions
involving windows.
Scroll bar
The user typically has one or more windows on the desktop, often from a number of
different applications. Although the user can have multiple windows on the desktop,
only one window is the active window. The active window is the window that appears
frontmost on the desktop and is identified by racing stripes in its title bar. Figure 1-2
shows an active window; in Figure 1-1 on page 1-3, the window titled SalesReport is an
inactive window.
All keyboard activity is directed toward the active window. You should make sure that
your application follows the human interface guidelines regarding active and inactive
windows. For example, you should show the scroll bars and highlight any selection in an
active window belonging to your application; you should hide the scroll bars and remove
highlighting from any selection in an inactive window belonging to your application. The
menu bar of your application also should always reflect the state of your application’s
active window—that is, your application should enable only those menu commands that
pertain to the active window.
You can use system software routines to assist you when your application needs to
create, move, size, zoom, or update the contents of your window. The chapter “Window
Manager” in this book describes how you can accomplish these tasks.
Controls 1
Most windows and dialog boxes contain controls. Controls are onscreen objects that the
user can manipulate with the mouse to cause an immediate action from your application
or to change settings in order to modify a future action.
Buttons, checkboxes, radio buttons, pop-up menus, and scroll bars are examples of
common controls used by most applications. Checkboxes, radio buttons, and pop-up
menus are most often used in dialog boxes; buttons are most often used in alert boxes or
dialog boxes; scroll bars are most often used in windows. Figure 1-3 illustrates these
types of controls.
Button
Checkbox
Radio buttons
Pop-up menu
Scroll bar
A button appears as a rounded rectangle with a title centered inside. Use a button to
perform an instantaneous action when the user clicks the button, such as completing
operations defined by a dialog box or acknowledging an error message in an alert box.
A checkbox appears as a small square with a title beside it; the box contains an X when
the setting associated with the box is on and is empty when the setting is off. Use a
checkbox to indicate an option that must be either off or on.
A radio button appears as a circle with a title beside it; the circle contains a small black
dot when the setting associated with the radio button is on and is empty when the setting
is off. Radio buttons are similar to checkboxes in that they retain and display
an on-or-off setting; however, only one radio button in a group of radio buttons should
be on at any one time. You must decide how to group your radio buttons, and your
application must ensure that only one radio button in a group is on.
A pop-up menu is a menu that appears in a dialog box or window. You can use pop-up
menus as an alternative to radio buttons, to allow the user to select from a list of choices
or settings.
A scroll bar appears as a light gray rectangle that has scroll arrows at each end of the
rectangle. A window can have a horizontal scroll bar, a vertical scroll bar, or both. You
can use scroll bars to let the user change the portion of a document that the user can view
within a window.
You can track and respond to user actions in controls, redraw controls, and manipulate
controls using Control Manager routines. You usually use the Dialog Manager to handle
most controls in dialog boxes or alert boxes for you. The chapter “Control Manager” in
this book describes how to create controls (with special emphasis on creating and using
scroll bars in windows), and the chapter “Dialog Manager” in this book provides
additional information about how to create controls in dialog boxes and alert boxes.
A dialog box is a window that you can use for the specific purpose of soliciting
additional information from the user. The Dialog Manager provides routines to help you
display dialog boxes and provides standard and consistent methods of interacting with
the user. Dialog boxes can contain editable text items, informative or instructional text,
and controls such as buttons and checkboxes. You can create modal, movable modal, or
modeless dialog boxes. Figure 1-5 shows an example of each type of dialog box.
A modal dialog box is a dialog box that puts the user in the state or “mode” of being able
to work only inside the dialog box. A modal dialog box is similar in appearance to an
alert box, except that a modal dialog box can contain editable text items and additional
controls, such as radio buttons and pop-up menus. The user cannot move a modal dialog
box, and the user can dismiss a modal dialog box only by clicking its buttons. You should
use a modal dialog box only when it’s essential for the user to complete an operation
before performing any other work.
A movable modal dialog box is a modal dialog box with a title bar (but no close box) that
allows the user to move the dialog box. The user can dismiss the dialog box only by
clicking its buttons; however, when you use movable modal dialog boxes, you should
allow the user to switch to another application if the user clicks in the window of another
application or chooses another application from the Apple or Application menu. Use a
movable modal dialog box when the user might need to move the dialog box to view
other areas of the screen or when the user can switch to another application without
affecting the state of your application.
A modeless dialog box is a dialog box that looks like a document window without a size
box or scroll bars. A modeless dialog box does not require the user to respond before
doing anything else. The user can move a modeless dialog box, move between a
modeless dialog box and other windows, and close a modeless dialog box just like a
document window. Whenever possible, use a modeless dialog box instead of a movable
modal or modal dialog box. Use a modeless dialog box when the user can perform other
operations—such as working in document windows—without dismissing the modeless
dialog box.
The chapter “Dialog Manager” in this book describes in detail how you can create alert
boxes and dialog boxes for your application.
Resources 1
Resources are basic elements of every Macintosh application. By defining descriptions of
menus, windows, controls, dialog boxes, sounds, fonts, and icons in resources, you can
make these and other elements easier to create and manage. Using resources also eases
translation of user interface elements into other languages.
A resource is any data stored according to a defined structure in the resource fork of
a file; the data in a resource is interpreted according to its resource type. You usually
create resources using a resource compiler or resource editor. This book shows resources
in Rez format; Rez is a resource compiler provided with the Macintosh Programmer’s
Workshop (available from APDA). You can also use other resource tools, such as ResEdit
(also available from APDA), to create the resources for your application.
Most of the managers described in this book use the Resource Manager to read resources
for you. For example, you can use the Menu Manager, Window Manager, Dialog
Manager, and Control Manager to read descriptions of your application’s menus,
windows, dialog boxes, and controls from resources. These managers all interpret a
resource’s data accordingly once it is read into memory. While you’ll typically use these
managers to access resources for you, you can also directly use the Resource Manager
to read and write resources.
The chapter “Resource Manager” in Inside Macintosh: More Macintosh Toolbox describes the
Resource Manager in detail. However, to help you understand how the Menu Manager,
Window Manager, Dialog Manager, and Control Manager use resources, this section
gives a brief overview of resources and provides a general introduction to the Resource
Manager.
Macintosh system software treats a file as a named, ordered sequence of bytes stored
on a Macintosh volume and divided into two forks, the data fork and the resource fork.
The data fork contains data that usually corresponds to data created by the user; the
application creating the file can store and interpret the data in the data fork in whatever
manner is appropriate. The resource fork of a file consists of a resource map and the
resources themselves.
When you write data to a file, you write to either the file’s resource fork or its data fork.
You typically read from and write to a file’s data fork using File Manager routines and
read from and write to a file’s resource fork using Resource Manager routines.
You typically store as resources data that has a defined structure—such as icons and
sounds—and descriptions of menus, controls, dialog boxes, and windows. When you
create a resource, you assign it a resource type and resource ID. A resource type is a
sequence of four characters that uniquely identifies a specific type of resource, and a
resource ID identifies by number a specific resource within that type. (You can also
use a resource name in place of a resource ID to identify a particular resource within a
resource type.) For example, to create a description of a menu in a resource, you create
a resource of type 'MENU' and give it a resource ID or resource name that is unique from
any other 'MENU' resources that you have defined. Some resources have restrictions on
the numbers you can use for resource IDs; in general, numbers 128 through 32767 are
available for your use.
System software defines a number of standard resource types, such as 'ALRT', 'CNTL',
'CODE', 'DITL', 'DLOG', 'FONT', 'ICN#', 'ICON', 'MBAR', 'MENU', 'STR ',
'STR#', and 'WIND'. You can use these resource types to define their corresponding
elements (for example, use a 'WIND' resource to define a window). You can also create
your own resource types if your application needs resources other than the standard
resource types defined by the system software.
The Resource Manager does not interpret the format of an individual resource type.
When you request a resource of a particular type with a given resource ID, the Resource
Manager looks for the specified resource and, if it finds it, reads the resource into
memory and returns a handle to it. Your application or other system software routines
can use the Resource Manager to read resources into memory. For example, when you
use the Window Manager to read a description of a window from a 'WIND' resource, the
Window Manager uses the Resource Manager to read the resource into memory. Once the
resource is in memory, the Window Manager interprets the resource’s data and creates a
window with the characteristics described by the resource.
System software stores certain resources used by the system software in the System
file. Although many of these resources are used only by the system software, your
application can access some of these resources if needed. For example, the standard
images for the I-beam and wristwatch cursors are stored as resources of type 'CURS'
in the System file. You can use these resources to change the appearance of the cursor
used by your application.
Occasionally you may need to write resources to the resource fork of a file. For example,
if your application saves the last position and size of a window (as determined by
the user), you can store this information in the resource fork of the document in a
resource defined by your application. The next time the user opens the document, your
application can read the location saved in this resource and position the document
accordingly.
You typically store the resources specific to your application, such as descriptions of its
menus, windows, controls, and dialog boxes, in the resource fork of your application.
You can store resources specific to a document created by your application in the resource
fork of the document file.
The resource map in the resource fork of a file contains entries that provide the location
of each resource in the resource fork. When the Resource Manager opens the resource
fork of a file, it reads the resource map into memory. As the Resource Manager reads
resources into memory, it replaces their entries in the resource map with handles to their
data in memory. The Resource Manager always searches the resource map in memory,
not the resource map of the resource fork on disk, when it searches for a resource. If a
requested resource is in memory, the Resource Manager uses the resource in memory;
otherwise it reads the resource from the resource fork on disk into memory.
Once the Resource Manager has opened a resource fork and read its resource map into
memory, it keeps the map in memory until the file is closed. You can specify that a
resource be read into memory immediately when the Resource Manager opens a file’s
resource fork, or you can specify that the Resource Manager read it into memory only
when needed. The Resource Manager stores resources from resource forks opened by
your application in relocatable blocks in your application’s heap. You can also specify
whether the Resource Manager should purge a resource from memory in order to make
room in memory for other data. If you specify that a resource is purgeable, you need to
use the Resource Manager to make sure the resource is in memory before accessing it
through its resource handle.
When a user opens your application, system software opens your application’s resource
fork. When your application opens a file, your application typically opens both the
file’s data fork and the file’s resource fork. When your application requests a resource
from the Resource Manager, the Resource Manager follows a specific search order.
(If necessary, your application can change the search order using Resource Manager
routines.) The Resource Manager normally looks first for the resource in the resource fork
of the last file that your application opened. So, if your application has a single file open,
the Resource Manager looks first in that file’s resource fork. If the Resource Manager
doesn’t find the resource there, it continues to search each resource fork open to your
application in the reverse order that the files were opened. After looking in the resource
forks of files your application has opened, the Resource Manager searches your
application’s resource fork. If it doesn’t find the resource there, it searches the resource
fork of the System file.
This search path allows your application to use resources defined in the System file, to
override resources defined in the System file, to share resources between files by using
resources stored in your application’s resource fork, and to override your application-
defined resources and use resources specific to a document.
A Macintosh file always contains both a resource fork and a data fork, although one
or both of those forks can be empty. Document files typically contain the document’s data
in the data fork and any document-specific resources—such as preference settings,
window location, and the document icon—in the resource fork. The resource fork
of an application typically includes resources that describe the application’s menus,
windows, controls, dialog boxes, and icons, as well as the code itself, which is also stored
as a resource.
Whether you store data in the data fork or the resource fork of a document file depends
largely on whether you can structure that data in a useful manner as a resource.
For example, it’s often convenient to store document-specific settings, such as the
document’s previous window size and location, as a resource in the document’s resource
fork. Data that is likely to be edited by the user is usually stored in the data fork of
a document.
A resource fork can contain at most 2700 resources. The Resource Manager uses a linear
search when searching a resource fork’s resource types and resource IDs. In general, you
should not create more than 500 resources of the same type in any one resource fork.
Inside Macintosh: More Macintosh Toolbox describes resources and the use of the Resource
Manager in more detail. For information on writing data to a file’s data fork, see Inside
Macintosh: Files.
Help Balloons 1
Your application can provide help balloons for elements such as menus, dialog boxes, or
the content area of a window. The chapter “Help Manager” in Inside Macintosh: More
Macintosh Toolbox describes how your application can provide help balloons. You can also
create help balloons for some elements of your application’s interface—such as its
menus—using the application BalloonWriter, which is available from APDA.
Handling Text 1
You can use the system software routines provided by TextEdit to greatly simplify basic
text editing and formatting that your application would otherwise have to implement.
For example, most applications use editable text items in dialog boxes; your application
can use the Dialog Manager (which calls TextEdit) to automatically handle user
interaction in editable text items. The Dialog Manager and your application can use
TextEdit to insert new text, delete characters that the user backspaces over, scroll text
within a window, cut text, copy text, paste text, select text, and handle word wrapping.
Most applications use TextEdit only for simple text editing in a dialog box and use their
own techniques for handling editable text in document windows.
You should design your application so that it can handle text in more than one language
or script. System software provides many routines to help you accomplish this. For
example, if your application automatically displays the date in the footer of your
document, you can use Text Utility routines to automatically display the date in the
format common to the current script. Similarly, if your application provides a Find
command, it can use Text Utility routines to search according to the word-break tables
and according to the current script.
See Inside Macintosh: Text for information on how you can provide support for text editing
in documents created by your application and for information on designing your
application so that it can support text editing in more than one language or script.
Managing Files 1
When the user chooses the Save or Save As menu command, you usually write to a file
the data that the user has entered in the active window. When the user selects a file using
the Open command, you read information from a file. You can use the File Manager to
read and write files. You can use the system software routines provided by the Standard
File Package to present a standard and consistent interface to the user when saving and
opening files. See the chapters “Introduction to File Management” and “Standard File
Package” in Inside Macintosh: Files for information about these topics.
Figure 2-0
Listing 2-0
Table 2-0
2 Event Manager
Contents
Introduction to Events 2-4
Low-Level Events 2-8
Operating-System Events 2-10
High-Level Events 2-13
Priority of Events 2-15
Switching Contexts 2-15
About the Event Manager 2-16
Using the Event Manager 2-17
Obtaining Information About Events 2-18
Processing Events 2-21
Using the WaitNextEvent Function 2-22
Writing an Event Loop 2-24
Setting the Event Mask 2-26
Handling Events in a Dialog Box 2-29
Creating a Size Resource 2-30
Handling Low-Level Events 2-32
Responding to Mouse Events 2-33
Responding to Keyboard Events 2-38
Scanning for a Cancel Event 2-46
Responding to Update Events 2-47
Responding to Activate Events 2-50
Responding to Disk-Inserted Events 2-55
Responding to Null Events 2-57
Handling Operating-System Events 2-58
Responding to Suspend and Resume Events 2-60
Responding to Mouse-Moved Events 2-62
Handling High-Level Events 2-67
Responding to Events From Other Applications 2-69
Searching for a Specific High-Level Event 2-71
Determining the Sender of a High-Level Event 2-72
Contents 2-1
C H A P T E R 2
2-2 Contents
C H A P T E R 2
Event Manager 2
This chapter describes how your application can use the Toolbox Event Manager to
receive information about actions performed by the user, to receive notice of changes in
the processing status of your application, and to communicate with other applications.
For example, you can retrieve information from the Toolbox Event Manager that gives
your application details about whether the user has pressed a key or the mouse button,
whether one of your application’s windows needs updating, or whether some other
hardware-related or software-related action requires a response from your application.
Your application also uses the Event Manager to support the cooperative, multitasking
environment available on Macintosh computers. This environment allows users to switch
between many open applications and allows other applications to receive background
processing time. By using Event Manager routines, you allow the system software to
coordinate the scheduling of processing time between your application and other
applications.
The Event Manager and Process Manager maintain the cooperative, multitasking
environment. The Process Manager coordinates the scheduling of applications, and the
Event Manager communicates information about changes in your application’s
processing status to your application.
See the chapter “Process Manager” in Inside Macintosh: Processes for complete information
on how the Process Manager schedules applications for execution.
You can use the Event Manager to communicate with other applications. Your application
can also communicate with other applications using the services of the Apple Event
Manager.
The Event Manager and Apple Event Manager routines that let your application
communicate with other applications depend on the services of the Program-to-Program
Communications (PPC) Toolbox. The services performed by the Event Manager and
Apple Event Manager meet the needs of most applications for interapplication
communication. However, to get additional control or capabilities not provided by the
Event Manager or Apple Event Manager, you can choose to access the PPC Toolbox
directly. The chapter “Program-to-Program Communications Toolbox” in Inside
Macintosh: Interapplication Communication describes the PPC Toolbox routines that are
available to your application.
For a comparison of the services provided by the Event Manager, Apple Event Manager,
and PPC Toolbox, see Inside Macintosh: Interapplication Communication. For additional
information about Apple events, including descriptions of how to process the required
Apple events, see Inside Macintosh: Interapplication Communication.
This chapter describes both the Toolbox Event Manager and the Operating System Event
Manager. The Operating System Event Manager maintains a queue in which it stores
hardware-related occurrences that you may want your application to respond to. The
Toolbox Event Manager communicates the information maintained by the Operating
System Event Manager to your application. In most cases, your application needs to
interact only with the Toolbox Event Manager. In this chapter, the name Event Manager
refers to the Toolbox Event Manager.
2-3
C H A P T E R 2
Event Manager
This chapter provides a general introduction to events and then explains how you can
use the Event Manager to
■ receive keypresses and mouse clicks as input for your application
■ receive indication that your application’s windows need to be activated or updated
■ allow other applications to use the available system resources when your application
isn’t using them
■ communicate with other applications
Introduction to Events 2
Most Macintosh applications receive information about hardware and software
occurrences that require a response from the application, through events. An event is the
means by which the Event Manager communicates information about user actions,
changes in the processing status of the application, and other occurrences that require a
response from the application.
The Event Manager communicates information about events that occur through the event
record. The EventRecord data type defines the event record. The event record contains
information about what type of event occurred (a mouse click or keypress, for example)
and contains additional information associated with the event (for example, for a
keypress the Event Manager also reports which key was pressed).
Most Macintosh applications are event-driven—that is, they respond to various changes
or occurrences and take action based on the nature of the event. Typically, a Macintosh
application repeatedly checks to see if an event has occurred and, if so, responds to the
event. If no events are pending, the application can choose to relinquish the processor for
a specified amount of time or can perform other tasks before checking again to see
whether an event has occurred.
Your application typically retrieves events from the Event Manager and also relinquishes
processor time by using the WaitNextEvent function. If any events are pending for
your application, the WaitNextEvent function returns the event to your application. If
no events are pending for your application, the WaitNextEvent function may allocate
processing time to other applications.
When multiple applications are open, the user chooses one to interact with at any given
time. The active application (or foreground process) is the one currently interacting with
the user. The foreground process displays its menu bar, and its windows are in front of
the windows of all other applications. (The term process refers to an open application or,
in some cases, an open desk accessory.)
There can be only one foreground process at any one time; however, multiple processes
can exist in the background. A background process is a process that is not currently
interacting with the user. The foreground process has first priority for accessing the
CPU. Other processes can access the CPU only when the foreground process yields time
to them.
Event Manager
By using WaitNextEvent to retrieve events, you allow other applications to make use of
processing time that your application would otherwise not use. When your application is
in the background, it in turn can receive processing time when other applications
relinquish the CPU. Using WaitNextEvent also allows users to switch between
multiple open applications.
An application that is in the background can get CPU time but can’t interact with the user
while it is in the background. (However, the user can choose to bring the application to
the foreground—for example, by clicking in one of the application’s windows.) An
application can also post a notification request using the Notification Manager if the
application is in the background and requires the user’s attention. Any application that
has the canBackground flag set in its size ('SIZE') resource is eligible to obtain access
to the CPU when it is in the background.
At any given time a process is either in the foreground or the background; a process can
switch between the two states at well-defined times.
The Event Manager ensures that switching between applications occurs in a smooth
fashion—by sending your application an event when it is about to be suspended and
sending it an event when it has processing time again and can resume executing. The
Event Manager and Process Manager coordinate this switching and scheduling of
processor time among many applications.
Your application can receive various types of events: low-level events, operating-system
events, and high-level events.
The Event Manager returns low-level events to your application for occurrences such as
the user pressing the mouse button, releasing the mouse button, pressing a key on the
keyboard, or inserting a disk. The Event Manager also returns low-level events to your
application if your application needs to activate (make changes to a window based on
whether it is in front or not) or update (redraw the contents of) one of its windows. When
your application requests an event and there are no other events to report, the Event
Manager returns a null event.
The Event Manager returns operating-system events to your application when the
processing status of your application is about to change or has changed. For example, if
a user brings your application to the foreground, the Process Manager sends an event
through the Event Manager to your application. Some of the work of reactivating your
application is done automatically, both by the Process Manager and by the Window
Manager; your application must take care of any further processing needed as a result of
your application being reactivated.
The Event Manager returns high-level events to your application as a result of
communication directed to your application from another application or process.
Low-level events, except for update events and null events, are always directed to the
foreground process. Operating-system events are also always directed to the foreground
process. High-level events, update events, and null events can be directed to the
foreground process or background processes.
Event Manager
You can specify which types of events you want your application to receive. You do this
by specifying an event mask as a parameter to various Event Manager routines. An event
mask allows you to mask out the events you are not interested in receiving. For example,
you can accept all events except high-level events.
Events can originate from a number of different sources: the Operating System Event
Manager, Window Manager, Process Manager, and PPC Toolbox. Figure 2-1 shows the
relationships between the Toolbox Event Manager, other parts of the system software,
and your application.
Operating System
Event Manager
Event 20
Operating Event 19 PPC
System Toolbox
event
queue
Event 1
The Operating System Event Manager creates and maintains a queue referred to as the
Operating System event queue. The Operating System Event Manager detects and
reports low-level hardware-related events such as mouse clicks, keypresses, and disk
insertions. The Operating System Event Manager places these events in the Operating
System event queue. The Toolbox Event Manager retrieves events from this event queue
and returns events, one at a time at your application’s request, to your application.
Event Manager
A maximum of 20 events can be pending in the Operating System event queue. If the
Operating System event queue becomes full, the Operating System Event Manager
begins to discard old events to make room for new ones as events are posted. The
Operating System Event Manager always discards the oldest event in the queue when
it must discard an event. However, this is not a common occurrence; your application
typically processes events much faster than the user can generate them. The actual
capacity of the event queue is determined by system startup information stored on
the startup volume; see the chapter “File Manager” in Inside Macintosh: Files for system
startup information.
The Event Manager can also report events from the Window Manager and Process
Manager. If a window needs to be updated, activated, or deactivated, the
Window Manager directs an event to the Toolbox Event Manager. Similarly, the
Process Manager directs an event to the Toolbox Event Manager if the processing
status of your application changes. The Toolbox Event Manager reports these events
to your application.
Note
On computers running System 6, MultiFinder provides some of
the capabilities supplied by the Process Manager in System 7. On
computers running System 6 without MultiFinder, only a single-
application environment is supported. ◆
Your application can use the Event Manager to send and receive high-level events. To
transmit high-level events between applications, the Event Manager uses the PPC
Toolbox on behalf of your application. For each open application capable of receiving
high-level events, the Event Manager maintains a separate queue, referred to as the
application’s high-level event queue, to store high-level events. The size of an
application’s high-level event queue is limited only by the amount of available memory.
Your application’s event stream consists of those events that are available to your
application for retrieval when it makes a request for an event. For example, when your
application is in the background, its event stream can contain only update events, null
events, and high-level events.
When your application asks the Event Manager for the next event, the Event Manager
returns the next available event according to its priority. In general, the Event Manager
returns events in this order of priority:
1. low-level events
2. operating-system events
3. high-level events
The next sections describe low-level events, operating-system events, and high-level
events in greater detail.
Event Manager
Low-Level Events 2
The Event Manager uses low-level events to report very low-level hardware and
software occurrences. Low-level events report
■ actions by the user (such as pressing the mouse button, typing on the keyboard, or
inserting a disk)
■ changes in windows on the screen
■ that the Event Manager has no other events to report
Low-level events that report actions by the user include mouse-down, mouse-up,
key-down, key-up, auto-key, and disk-inserted events. The Event Manager reports any of
these events when the user performs the action associated with each event.
Mouse-down and mouse-up events report that the user pressed or released the mouse
button. For these events the Event Manager returns the location of the cursor at the time
the mouse button was pressed or released. Key-down and key-up events report that the
user pressed or released a key. Auto-key events report that the user has held a key down
for a certain amount of time. For keyboard-related events, the Event Manager reports
which key was pressed. For mouse-related and keyboard-related events, the Event
Manager also reports the state of the modifier keys (the Option, Command, Caps Lock,
Control, and Shift keys) at the time of the event.
When the user inserts a disk, the Operating System attempts to mount the volume on the
disk by calling the File Manager function PBMountVol. The Operating System Event
Manager then generates a disk-inserted event. If the user is interacting with a standard
file dialog box, the Standard File Package intercepts the disk-inserted event and handles
it. Otherwise, the event is left in the event queue for your application to retrieve. In most
cases your application can handle unexpected disk-inserted events by simply checking to
see if the volume was successfully mounted.
Update events and activate events are two types of low-level events that the Event
Manager can report as a result of changes in the appearance of windows on the screen.
For example, if a user is working with several open documents belonging to your
application, you can allow the user to switch from one document to another when the
user clicks in the appropriate window. You can determine whether the user clicked in
another window by using the Window Manager function FindWindow; if the user
clicked in another window, you can then use the Window Manager procedure
SelectWindow to generate the necessary activate events. Before the Event Manager
sends your application any activate events relating to this occurrence, the Window
Manager does some work for you, such as unhighlighting the deactivated window and
highlighting the newly activated window. At your application’s next request for an event,
the Event Manager returns an activate event.
An activate event indicates the window involved and whether the window is becoming
activated or deactivated. Your application should perform any other necessary actions to
complete the transformation of the window from active to inactive or vice versa. For
example, when a window becomes active, your application should show any scroll bars
and restore any selections.
Event Manager
Your application typically receives an activate event for the window being deactivated,
followed by an activate event for the window becoming active at your application’s next
request for an event.
Note
If the user switches between your application and another application
(by clicking in the window of another application, for example), your
application is responsible for activating or deactivating any windows
as appropriate. Your application is notified of this occurrence
through operating-system events. If your application has the
acceptSuspendResumeEvents and doesActivateOnFGSwitch
flags set in its 'SIZE' resource, your application is notified of the switch
through an operating-system event and does not receive a separate
activate event when the user switches between applications. ◆
The Window Manager generates update events to control the appearance of windows on
the screen. The Window Manager keeps track of the front-to-back ordering of windows
and allows windows to overlap other windows. The Window Manager coordinates the
display of windows. When one window covers another window and then the user moves
the first window, the Window Manager generates an update event so that the contents of
the newly exposed area can be updated. The Event Manager reports update events as
needed to the applications whose windows need updating. Unlike other low-level
events, update events can be directed to the foreground process or background processes.
Activate and update events generated by the Window Manager are not placed into the
Operating System event queue but are sent directly to the Event Manager.
The Event Manager reports a null event when your application requests an event and
your application’s event stream does not contain any of the requested event types. By
using the WaitNextEvent function, you can yield time to other processes when null
events are the only pending events for your application.
When your application receives a null event, your application can do idle processing
(such as blinking the caret) if it is in the foreground or do other tasks if it is in the
background. If you want your application to receive null events when it is in the
background, you must set the canBackground flag in your application’s 'SIZE'
resource. If your application does not perform any processing in response to null events
when it is in the background, then set the cannotBackground flag. If you set the
cannotBackground flag, the Event Manager does not report null events to your
application when it is in the background. However, the Event Manager still reports
update events (and high-level events if the isHighLevelEventAware flag is set in the
'SIZE' resource) to your application when it is in the background regardless of how the
background flag is set.
Figure 2-2 shows the various kinds of low-level events your application can receive. See
“Handling Low-Level Events” beginning on page 2-32 for complete details of how your
application should respond to low-level events.
Event Manager
Key-up Disk-
Key-down inserted
Auto-key
Mouse-up
Mouse-down
Operating System
Event Manager
Event 20
Event 19 Operating
System
event
queue
Event 1
Activate
Update
Window Toolbox Event
Manager Manager
Event stream
Operating-System Events 2
The cooperative, multitasking environment allows the user to interact with your
application and with other applications. The Process Manager coordinates the scheduling
of applications, and the Event Manager communicates information about changes in the
operating status of applications to the applications involved.
For example, when your application is about to be switched into the background, the
Event Manager sends it a suspend event. Then, when your application is switched back
into the foreground, it receives a resume event. These types of events, as well as a special
type of mouse event, the mouse-moved event, are known as operating-system events.
Figure 2-3 illustrates how the Event Manager helps provide this cooperative,
multitasking environment. The Process Manager generates suspend, resume, and
mouse-moved events, and the Event Manager reports these events to applications.
Event Manager
Operating System
Event Manager
Event 20
Event 19 Operating
System
event
queue
Event 1
Suspend
Resume
Mouse-moved
Process Toolbox Event
Manager Manager
Event stream
Note
If your application sets the acceptSuspendResumeEvents and
doesActivateOnFGSwitch flags in its 'SIZE' resource, your
application is also responsible for activating or deactivating any
windows as appropriate in response to operating-system events. For
maximum compatibility, your application should set these flags and
handle suspend and resume events. See “The Size Resource” beginning
on page 2-115 for more information on these and other flags in the
'SIZE' resource. ◆
When your application receives a suspend event, it does not actually switch to the
background until it makes its next request to receive events from the Event Manager. At
the time that it receives the suspend event, your application should convert any private
scrap into the global scrap if necessary. Your application should hide scroll bars, remove
the highlighting from any selections, and hide any floating windows. If your application
Event Manager
shows a window that displays the Clipboard contents, you should hide this window also.
Then you should call WaitNextEvent to relinquish the CPU and allow the Operating
System to schedule other processes for execution. It is important to minimize the
processing you do in response to a suspend event so that the computer appears
responsive to the user.
When control returns to your application, the first event it receives is a resume event.
Your application should convert the global scrap back to its private scrap, if necessary.
Your application should also restore any windows to the state the user left them in at the
time of the previous suspend event. For example, your application should show any
scroll bars, highlight any selections, and show any floating windows. See “Responding to
Suspend and Resume Events” beginning on page 2-60 for complete details of how your
application should respond to these events.
The events that your application can receive in the background are update, null, and
high-level events. When your application is in the background, it should not perform any
processing that would make the foreground process appear unresponsive to the user.
When receiving events in the background, your application should perform any needed
action in response to an event and then quickly return.
Your application should never interact with the user when it is in the background. If you
need to notify the user of some special occurrence while your application is executing
in the background, you should use the Notification Manager to queue a notification
request. You should not attempt to display an alert box while your application is in the
background. Instead, your application can specify that the Notification Manager play
a sound, display an alert box, cause a small icon representing your application to
blink in alternation with the Application menu icon, display a diamond next to your
application’s name in the Application menu, or put a combination of these actions
into effect.
These actions are designed to alert the user that another application needs the user’s
attention. By using the Notification Manager you help maintain the user interface
principle of giving the user control, as the user can choose to bring the application
requesting attention to the foreground at the user’s convenience. See the chapter
“Notification Manager” in Inside Macintosh: Processes for examples of how to post
notification requests.
Another kind of operating-system event is the mouse-moved event. You can request that
the Event Manager send your application a mouse-moved event whenever the cursor
is outside of a region that you specify to the WaitNextEvent function. For example, you
can use mouse-moved events as a convenient way for your application to change the
appearance of the cursor as the user moves the cursor from the text area of a document to
the scroll bar. See “Responding to Mouse-Moved Events” beginning on page 2-62 for
detailed examples.
Event Manager
High-Level Events 2
The Event Manager provides routines that let applications communicate with each other
by exchanging high-level events. A high-level event is an event that your application can
send to another application to give it some information, to receive some information from
it, or to have it perform some action.
For example, your application can send a high-level event to another application
instructing that application to perform a specific action, such as adding a row to a
spreadsheet or changing the font size of a paragraph. Your application can also send a
high-level event to another application requesting information from that application—for
example, requesting a dictionary application to return the definition of a particular word.
When you send a high-level event to another application, you can also include additional
information or commands in an optional data buffer. For example, your application can
use a high-level event to send a list of new words and definitions to a dictionary
application.
Note
High-level events are available only in system software
version 7.0 or later. ◆
Figure 2-4 on the next page shows three different applications communicating with each
other by sending and receiving high-level events. The Event Manager uses the PPC
Toolbox to transmit high-level events. The Event Manager maintains a high-level event
queue for each application that has identified itself as capable of receiving high-level
events. The high-level event queues are limited in size only by available memory.
For effective communication between applications, your application must define the set
of high-level events it responds to and let other applications know the events it accepts.
By implementing the capabilities to send events to and receive events from other
applications, you allow other applications to interact with your application and provide
enhanced capabilities to your users.
Generally, there is no restriction on the type of processing that one application can
request from another by sending it a high-level event. For a high-level event sent by one
application to be understood by another application, however, the sender and receiver
must agree on a protocol, that is, on the way the event is to be interpreted. Apple events
are high-level events whose structure and interpretation are determined by the Apple
Event Interprocess Messaging Protocol (AEIMP).
Your application should support the required Apple events, as described in Inside
Macintosh: Interapplication Communication. The Finder uses the required Apple events to
provide your application with information when it is opened and to give it the names of
documents to open or print when the user opens or prints documents from the Finder.
Event Manager
Operating System
Event Manager
Event 20
Operating Event 19 PPC
System Toolbox
event
queue
Event 1
Event stream
High-level
events
In addition, you may want your application to support other common Apple events.
For example, the Edition Manager uses Apple events to communicate information
about document sections among the various applications that may publish sections
or subscribe to them. The Edition Manager sends the appropriate Apple events
to applications that want to maintain up-to-date subscriber sections within their
documents. If a user alters a section of a document that has previously been published
and updates the edition, the Edition Manager might post an Apple event to the
application indicating that a new edition is available. The application receiving the Apple
event can then update the subscriber or ignore the information, as the user dictates. For
complete information on responding to Apple events sent by the Edition Manager, see
the chapter “Edition Manager” in Inside Macintosh: Interapplication Communication.
Event Manager
Note
All Macintosh system software that sends or receives high-level events
uses the Apple events protocol. ◆
Priority of Events 2
Each type of event has a certain priority. The Event Manager returns events in this order
of priority:
1. activate events
2. mouse-down, mouse-up, key-down, key-up, and disk-inserted events in FIFO (first-in,
first-out) order
3. auto-key events
4. update events (in front-to-back order of windows)
5. operating-system events (suspend, resume, mouse-moved)
6. high-level events
7. null events
Several of the Event Manager routines can be restricted to operate on one or more specific
types of events. You do this by disabling (or “masking out”) the events you are not
interested in receiving. See “Setting the Event Mask” beginning on page 2-26 for details
about specifying the types of events you wish to receive.
Switching Contexts 2
Processes running in the background receive processing time when the foreground
process makes an event call (that is, calls WaitNextEvent or EventAvail) and there
are no events pending for that foreground process. A process running in the background
should relinquish the CPU regularly to ensure a timely return to the foreground process
when necessary.
In System 7 (or with MultiFinder in earlier versions), the available processing time is
distributed among multiple processes through a procedure known as context switching (or
just switching). All switching occurs at a well-defined time, namely, when an application
calls WaitNextEvent. When a context switch occurs, the Process Manager allocates
processing time to a process other than the one that had been receiving processing time.
Two types of context switching may occur: major and minor.
Event Manager
A major switch is a complete context switch: an application’s windows are moved from
the back to the front, or vice versa. In a major switch, two applications are involved, the
one being switched to the foreground and the one being switched to the background. The
Process Manager switches the A5 worlds of both applications, as well as the relevant
low-memory environments. If those applications receive suspend and resume events,
they are so notified at the time that a major switch occurs.
A minor switch occurs when the Process Manager gives time to a background process
without bringing the background process to the front. The two processes involved in a
minor switch can be two background processes or a foreground process and a
background process. As in a major switch, the Process Manager switches the A5 worlds
and the low-memory environments of the two processes. However, the order of windows
is not switched, and neither process receives either suspend or resume events.
When the frontmost window is an alert box or a modal dialog box, major switching does
not occur, although minor switching can. To determine whether major switching can
occur, the Operating System checks (among other things) to see if the window definition
procedure of the frontmost window is dBoxProc, because the type dBoxProc is
specifically reserved for alert boxes and modal dialog boxes. (If the frontmost window is
a movable modal dialog box, major switching can still occur.)
Note
Your application can also get switched out if it calls a system software
routine that makes an event call. For example, when your application
calls ModalDialog, a minor switch can occur. ◆
Your application can receive processing time and perform tasks in the background,
but your application should not interact with the user or perform tasks that would slow
down the responsiveness of the foreground process.
Your application indicates scheduling options to the Operating System, such as whether
the application can use null-event processing time when in the background, whether it
can accept suspend and resume events, and so forth, by setting flags in its size ('SIZE')
resource. Every application executing in System 7, as well as every application executing
in System 6 with MultiFinder, should contain a 'SIZE' resource. See “Creating a Size
Resource” beginning on page 2-30 for details on how to specify this information.
Event Manager
Event Manager
When your application starts, you can call the FlushEvents procedure to empty
the Operating System event queue of any low-level events left unprocessed by
another application. For example, you might want to remove any mouse-down
events or keyboard events that the user might have entered while the Finder launched
your application.
This section shows how to retrieve events from the Event Manager, how to mask out
unwanted events, how to specify memory and scheduling options for your application,
and how to handle each type of event received from the Event Manager.
TYPE EventRecord =
RECORD
what: Integer; {event code}
message: LongInt; {event message}
when: LongInt; {ticks since startup}
where: Point; {mouse location}
modifiers: Integer; {modifier flags}
END;
Field descriptions
what The what field indicates the type of event received. The type of
event can be identified by these constants:
CONST
nullEvent = 0; {no other pending events}
mouseDown = 1; {mouse button pressed}
mouseUp = 2; {mouse button released}
keyDown = 3; {key pressed}
keyUp = 4; {key released}
autoKey = 5; {key repeatedly held down}
updateEvt = 6; {window needs updating}
diskEvt = 7; {disk inserted}
activateEvt = 8; {activate/deactivate window}
osEvt = 15;{operating-system event-- }
{ resume, suspend, or }
{ mouse-moved}
kHighLevelEvent = 23;{high-level event}
Event Manager
when The when field indicates the time when the event was posted (in
ticks since system startup). When needed, you can use the when
field to compare how much time has elapsed between successive
mouse events.
where For low-level events and operating-system events, the where field
contains the location of the cursor at the time the event was posted
(in global coordinates).
For high-level events, the where field contains a second event
specifier, the event ID. The event ID defines the particular type of
event within the class of events defined by the message field of the
high-level event. For high-level events, you should interpret the
where field as having the data type OSType, not Point.
Event Manager
modifiers The modifiers field contains information about the state of the
modifier keys and the mouse button at the time the event was
posted. For activate events, this field also indicates whether the
window should be activated or deactivated. In System 7 it also
indicates whether a mouse-down event caused your application to
switch to the foreground.
Each of the modifier keys is represented by a specific bit in the modifiers field of the
event record. Figure 2-5 shows how to interpret the modifiers field. You can examine
the modifiers field of the event record to determine which, if any, of the modifier keys
were pressed at the time of the event. The modifier keys include the Option, Command,
Caps Lock, Control, and Shift keys. If your application attaches special meaning to any of
these keys in combination with other keys or when the mouse button is down, you can
test the state of the modifiers field to determine the action your application should
take. For example, you can use this information to determine whether the user pressed
the Command key and another key at the same time to make a menu selection.
Bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
* * * * * *
1 if right Control key down, 0 if not
1 if right Option key down, 0 if not
1 if right Shift key down, 0 if not
1 if Control key down, 0 if not
1 if Option key down, 0 if not
1 if Caps Lock key down, 0 if not
1 if Shift key down, 0 if not
1 if Command key down, 0 if not
1 if mouse button up, 0 if not
1 if window being deactivated or if mouse-down event caused a foreground switch, 0 if deactivated
Bit 0 in the modifiers field gives additional information that is valid only if the event is
an activate event or a mouse-down event.
For activate events, the value of bit 0 is 1 if the window pointed to by the event message
should be activated, and the value is 0 if the window should be deactivated.
For mouse-down events in System 7, bit 0 indicates whether a mouse-down event caused
your application to switch to the foreground. If so, bit 0 contains 1; otherwise,
it contains 0.
Event Manager
You can also use these constants as masks to test the setting of various bits in the
modifiers field:
Note that the bit giving information about the mouse button is set if the mouse button is
up. The bits for the modifier keys are set if the corresponding key is down.
Some keyboards do not distinguish between the right or left Control, Shift, and Option
keys; for example, the virtual key code for the right Shift key and left Shift key might be
the same. For these keyboards, if the user presses the Control, Shift, or Option key, the
Event Manager sets only the bits corresponding to the shiftKey, optionKey, and
controlKey constants. For keyboards that do distinguish between these keys, the Event
Manager sets the bits in the modifiers field to indicate whether the right or left Control,
Shift, or Option keys were pressed. For example, the Event Manager sets bit 13 in the
modifiers field if the user presses the right Shift key and sets bit 9 if the user presses
the left Shift key. In most cases your application should not need to distinguish between
the left and right Control, Shift, and Option keys.
Processing Events 2
Applications receive events one at a time by asking the Event Manager for the next
available event. You use Event Manager routines to receive (or in the case of
EventAvail, simply to look at) the next available event that is pending for your
application. You supply an event record as a parameter to the Event Manager routines
that retrieve events. The Event Manager fills out the event record with the relevant
information about that event and returns it to your application.
Your application can use the WaitNextEvent function to retrieve events from the Event
Manager. If no events are pending for your application, the WaitNextEvent function
may allocate processing time to other applications. If an event is pending for your
application, the WaitNextEvent function returns the next available event of a specified
type and removes the returned event from your application’s event stream.
The EventAvail function gets the next available event of a specified type and returns it
to your application, but does not remove the event from your application’s event stream.
EventAvail thus allows your application to look at an event in the event stream
without actually processing the event.
Event Manager
Note
You can also use the GetNextEvent function to retrieve and remove an
event; however, you should use WaitNextEvent to provide greater
support for multitasking. ◆
Event Manager
VAR
eventMask: Integer;
event: EventRecord;
cursorRgn: RgnHandle;
mySleep: LongInt;
gotEvent: Boolean;
The code in Listing 2-1 specifies that WaitNextEvent should return the next pending
event of any kind, give up the processor if no events are pending, and return a
mouse-moved event if the user moves the cursor out of the specified region.
The WaitNextEvent function returns after retrieving an event or after the time specified
in the sleep parameter has expired. If there are no events of the types specified by the
eventMask parameter (other than null events) pending for your application, and the
time specified in the sleep parameter has not expired, WaitNextEvent may allocate
processing time to background processes. Once an
event for your application occurs or the time specified in the sleep parameter
expires, your application receives processing time again.
WaitNextEvent returns a function result of TRUE if it has retrieved any event other than
a null event. If there are no events of the types specified by the eventMask parameter
(other than null events) pending for the application, WaitNextEvent
returns FALSE.
Before returning an event to your application, WaitNextEvent performs other
processing and may intercept the event. The WaitNextEvent function:
■ Calls the Operating System Event Manager function SystemEvent to determine
whether the event should be handled by your application or the Operating System.
For example, if the event is a Command–Shift–number key sequence, the Event
Manager intercepts the event and calls the corresponding 'FKEY' resource to perform
the associated action.
■ Makes the alarm go off if the alarm is set and the current time is the alarm time. The
user sets the alarm using the Alarm Clock desk accessory.
Event Manager
■ Calls the SystemTask procedure, which gives time to each open desk accessory or
device driver to perform any periodic action defined for it. A desk accessory or device
driver specifies how often the periodic action should occur, and SystemTask gives
time to the desk accessory or device driver at the appropriate interval.
In System 7, the WaitNextEvent function reports a suspend event to your
application when
■ your application is in the foreground and the user opens a desk accessory or other
item from the Apple menu,
■ the user clicks in the window belonging to a desk accessory or another application, or
■ the user chooses another process from the Application menu.
After your application is switched out, the Event Manager directs events (other than
events your application can receive in the background) to the newly activated process
until the user switches back to your application or another application.
PROCEDURE MyEventLoop;
VAR
cursorRgn: RgnHandle;
gotEvent: Boolean;
event: EventRecord;
BEGIN
cursorRgn := NewRgn; {pass an empty region the first time thru}
REPEAT
gotEvent := WaitNextEvent(everyEvent, event, MyGetSleep,
cursorRgn);
IF (event.what <> kHighLevelEvent) AND (NOT gInBackground)
THEN MyAdjustCursor(event.where, cursorRgn);
IF gotEvent THEN {the event isn’t a null event, }
DoEvent(event) { so handle it}
ELSE {no event (other than null) to handle }
DoIdle(event); { right now, so do idle processing}
UNTIL gDone; {loop until user quits}
END;
Event Manager
Note
If your application uses modeless dialog boxes, you need to
appropriately handle events in them. You can choose to handle events for
modeless dialog boxes using the same routines that you use to handle
events in other windows; this is the approach used throughout this
chapter. Alternatively, you can choose to call the IsDialogEvent
function in your event loop. See “Handling Events in a Dialog Box” on
page 2-29 for information on handling events in alert boxes, modal
dialog boxes, movable modal dialog boxes, and modeless dialog boxes.
For additional information on dialog boxes, see the chapter “Dialog
Manager” in this book. ◆
If you intend to design your application to run in either a single-application environ-
ment (such as System 6 without MultiFinder) or a multiple-application environment,
the very beginning of your event loop should test to make sure the WaitNextEvent
function is available. If WaitNextEvent is not available, your code should use
GetNextEvent to retrieve events. If your code uses GetNextEvent, it should also
call SystemTask to allow desk accessories to perform periodic actions. However,
your code should always use WaitNextEvent if it is available, rather than
GetNextEvent. If your application calls WaitNextEvent, it should not call the
SystemTask procedure.
The event loop shown in Listing 2-2 calls an application-defined procedure, DoEvent, to
determine what kind of event the call to WaitNextEvent retrieved. Listing 2-3 defines a
simple DoEvent procedure. The DoEvent procedure examines the value of the what
field of the event record to determine the type of event received and then calls an
appropriate application-defined routine to further process the event.
Event Manager
The next sections describe how to set the event mask, handle events in dialog boxes,
and create your application’s 'SIZE' resource. Following sections show code that can
handle each kind of event.
Event Manager
that type. If the bit is set to 0, the Event Manager does not return events of that type. To
accept all types of events, set every bit of the event mask to 1. You can do this using the
constant everyEvent.
Figure 2-6 shows the bits corresponding to each event type in the event mask.
Bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
* * * * * *
Activate event
Disk-inserted event
Update event
Auto-key event
Key-up event
Key-down event
Mouse-up event
Mouse-down event
You can use these constants when referring to the bits in the event mask that correspond
to each individual event type:
Event Manager
You can select any subset of events by adding or subtracting these constants. For
example, you can use this code to accept only high-level events and mouse-down events
and mask out all other events:
The everyEvent constant indicates that you wish to receive every type of event. To
accept all events except mouse-up events, you can use the code:
Masking out specific types of events does not remove those events from the event stream.
If a type of event is masked out, the Event Manager simply ignores it when reporting
events from the event stream. Note that you cannot mask out null events by setting the
event mask. The Event Manager always returns a null event if no other events are
pending. However, if you do not want the Event Manager to report null events to your
application when it is in the background, you can set the cannotBackground flag in
your application’s 'SIZE' resource.
In most cases you should always use everyEvent as your event mask. The user expects
most applications to respond to keyboard, mouse, update, and other events.
The types of events returned to your application are also affected by the system event
mask. The Event Manager maintains a system event mask for each application. The
system event mask controls which low-level event types get posted in the Operating
System event queue. The Event Manager uses the system event mask of the current
process (the process that is currently executing and the process associated with the
CurrentA5 global variable) when determining which low-level events to post in the
Operating System event queue. The system event mask is an integer with 1 bit for
each corresponding low-level event type. These constants refer to the bits that represent
the corresponding low-level event types in the system event mask:
When a low-level event (other than an update or activate event) occurs, the Operating
System Event Manager posts the low-level event in the Operating System event queue
only if the bit corresponding to the low-level event type is set in the system event mask of
the current process. When your application starts, the Operating System initializes the
system event mask of your application to post mouse-up, mouse-down, key-down,
auto-key, and disk-inserted events in the Operating System event queue. Thus, the
system event mask has this initial setting:
systemEventMask := everyEvent - keyUpMask;
Event Manager
Your application should not change the system event mask except to enable key-up
events if your application needs to respond to key-up events. (Most applications ignore
key-up events.) If your application needs to receive key-up events, you can change the
system event mask using the Operating System Event Manager procedure
SetEventMask. Note that your application cannot rely on receiving key-up events when
it is not the current process. For example, if your application is the foreground (and
current) process and a minor switch occurs, the Event Manager uses the system event
mask of the background process (now the current process) when posting low-level event
types. When your application becomes the current process again, the Event Manager uses
the system event mask of your application when posting low-level events.
Event Manager
handle. This is the approach used throughout this chapter. Alternatively, you can choose
to call the IsDialogEvent function in your event loop. If you do this, you can use the
IsDialogEvent function to determine whether the event involves a modeless dialog
box that belongs to your application. If the event involves a modeless dialog box
(including null events) and a modeless dialog box is active, IsDialogEvent returns
TRUE. Otherwise, IsDialogEvent returns FALSE.
If IsDialogEvent returns TRUE, your application can check to see what type of event
occurred and, depending on the type of event, it can choose to handle the event itself.
Regardless of the approach you use, if your application chooses not to handle the event,
it should call DialogSelect. The DialogSelect function handles events for modeless
dialog boxes (including null events). It also blinks the caret in editable text items when
necessary.
For more information on the DialogSelect function and events in dialog boxes, see the
chapter “Dialog Manager” in this book.
Note
If the amount of available memory is between the minimum and the
preferred sizes, the Finder displays a dialog box asking if the user wants
to run the application using the amount of memory available. If your
application does not have a 'SIZE' resource, it is assigned a default
partition size of 512 KB and the Process Manager uses a default value
of FALSE for all specifications normally defined by constants in the
flags field. ◆
Event Manager
When you define a 'SIZE' resource, you should give it a resource ID of –1. A user can
modify the preferred size in the Finder’s information window for your application. If the
user does alter the partition size, the Operating System creates a new 'SIZE' resource
having a resource ID of 0. At application launch time, the Process Manager looks for a
'SIZE' resource with ID 0; if this resource is not found, it uses your original 'SIZE'
resource with ID –1. This new 'SIZE' resource is also created when the user modifies
any of the other settings in the resource.
When creating a 'SIZE' resource, you first need to determine the various operating
characteristics of your application. For example, if your application has nothing useful to
do when it is in the background, then you should not set the canBackground flag.
Similarly, if you have not tested your application in an environment that uses all 32 bits
of a handle or pointer for memory addresses, then you should not set the
is32BitCompatible flag.
Listing 2-4 shows the Rez input for a sample 'SIZE' resource. (Rez is a resource
compiler available with the MPW environment.)
Event Manager
The 'SIZE' resource specification in Listing 2-4 indicates, among other things, that the
application accepts suspend and resume events, does processing in the background using
null events, activates or deactivates any windows as necessary in response to
operating-system events, can execute in both the foreground and background, and
doesn’t want to receive any mouse event associated with a resume event that was caused
by the user clicking in the application’s front window. It also indicates that the
application doesn’t want to receive Application Died events, can work in 24-bit or 32-bit
addressing mode, does accept high-level events, including both local and network
high-level events, does handle stationery documents, and doesn’t use TextEdit’s inline
input services. In this example, the Rez-input file must define values for the constants
kPrefSize and kMinSize; for example, if kPrefSize is set to 50, the preferred
partition size is 50 KB.
The numbers you specify as your application’s preferred and minimum memory sizes
depend on the particular memory requirements of your application. Your application’s
memory requirements depend on the size of your application’s static heap, dynamic
heap, A5 world, and stack. (See “Introduction to Memory Management” in Inside
Macintosh: Memory for complete details about these areas of your application’s partition.)
The static heap size includes objects that are always present during the execution of your
application—for example, code segments, Toolbox data structures for window records,
and so on.
Dynamic heap requirements come from various objects created on a per-document basis
(which may vary in size proportionally with the document itself) and objects that are
required for specific commands or functions.
The size of the A5 world depends on the amount of global data and the number of
intersegment jumps your application contains.
The stack contains variables, return addresses, and temporary information. The size of
the application stack varies among computers, so you should base your values for the
stack size according to the stack size required on a Macintosh Plus computer (8 KB).
The Process Manager automatically adjusts your requested amount of memory to
compensate for the different stack sizes on different machines. For example, if you
request 512 KB, more stack space (approximately 16 KB) will be allocated on machines
with larger default stack sizes.
Unfortunately, it is difficult to forecast all of these conditions with any great degree of
reliability. You should be able to determine reasonably accurate estimates for the stack
size, static heap size, A5 world, and jump table. In addition, you can use tools such as
MacsBug’s heap-exploring commands to help you empirically determine your
application’s dynamic memory requirements.
See “The Size Resource” beginning on page 2-115 for additional information on the
meaning of each of the fields and flags of a 'SIZE' resource.
Event Manager
of event and respond appropriately. The following sections discuss how to respond to
mouse events, keyboard events (including certain specific keyboard events, such as when
the user presses the Command key and period key at the same time), update events,
activate events, disk-inserted events, and null events.
Event Manager
which of your application’s windows, if any, the mouse button was pressed in and, if
applicable, to find which part of the window it was pressed in. The FindWindow
function also reports whether the given mouse location is in the menu bar or, in some
cases, in a window belonging to a desk accessory (if the desk accessory was launched in
your application’s partition).
The what field of the event record for a mouse event contains the mouseDown or
mouseUp constant to report that the mouse button was pressed or released. The
message field is undefined. The when field contains the number of ticks since the system
last started up. You can use the when field to compare how much time has elapsed
between successive mouse events; for example, you might use this information to help
detect mouse double clicks.
The where field of the event record contains the location of the cursor at the time the
mouse button was pressed or released. You can pass this location to the FindWindow
function; the FindWindow function maps the given mouse location to particular areas
of the screen.
The modifiers field contains information about the state of the modifier keys at the
time the mouse button was pressed or released. Your application can perform different
actions based on the state of the modifier keys. For example, your application might let
the user extend a selection or select multiple objects at a time if the Shift key was down at
the time of the mouse-down event.
Listing 2-5 shows code that handles mouse-down events. The DoMouseDown procedure
is an application-defined procedure that is called from the DoEvent procedure.
(Listing 2-3 on page 2-26 shows the DoEvent procedure.)
Event Manager
When your application retrieves a mouse-down event, call the Window Manager
function FindWindow to map the location of the cursor to particular areas of the screen.
Given a mouse location, the FindWindow function returns as its function result a value
that indicates whether the mouse location is in the menu bar, in one of your application’s
windows, or, in some cases, in a desk accessory window. If the mouse location is in an
application window, the function result indicates which part of the window the mouse
location is in. You can test the function result of FindWindow against these constants to
determine the mouse location at the time of the mouse-down event:
Event Manager
Event Manager
FindWindow can return any of the constants inContent, inDrag, inGrow, inGoAway,
inZoomIn, or inZoomOut if the given mouse location is in your application’s active
window. If the cursor is in the content area, your application should perform any actions
appropriate to your application. Note that scroll bars are part of the content region. In
most cases, if the cursor is in the content area, your application first needs to determine
whether the mouse location is in the scroll bar or any other controls and then respond
appropriately. The DoMouseDown procedure calls the application-defined procedure
DoContentClick to handle mouse-down events in the content area of the active
window. If your application needs to determine whether the mouse-down event caused a
foreground switch (and you set the getFrontClicks flag in your application’s 'SIZE'
resource), your DoContentClick procedure can test bit 0 in the modifiers field of the
event record (normally your application does not test for this condition).
See the chapter “Control Manager” in this book for an example DoContentClick
procedure and for detailed information on implementing controls in your
application’s windows.
If the mouse location is in any of the other specified regions of an active application
window, your application should perform the action corresponding to that region.
For example, if the cursor is in the drag region, your application should call the
Window Manager procedure DragWindow to allow the user to drag the window to
a new location.
If the mouse location is in an inactive application window, FindWindow can return the
inContent or inDrag constant, but does not distinguish between any other areas of the
window. In this case, if FindWindow reports the inContent constant, your application
should bring the inactive window to the front using the SelectWindow procedure
(unless the active window is a movable modal dialog box). If the active window is a
movable modal dialog box, then your application should use the SysBeep procedure to
play the system alert sound rather than activating the selected window. Also, if your
application interprets the first mouse click in an inactive window as a request to activate
the window and perform an action, you can process the event again. However, note that
most users expect the first click in an inactive window to activate
the window without performing any additional action. If FindWindow reports inDrag
for an inactive application window, your application should call the DragWindow
procedure to allow the user to drag the window to a new location (unless the active
window is a movable modal dialog box, in which case your application should simply
play the system alert sound).
If you’re using TextEdit to handle text editing and call TEClick, TEClick automatically
interprets mouse double clicks appropriately, including allowing the user to select a word
by double-clicking it. Your application must provide the means to allow double- clicking
in this manner in all other contexts.
You can detect mouse double clicks by comparing the time and location of a mouse-up
event with that of the immediately following mouse-down event. The GetDblTime
function returns the recommended difference in ticks that should exist between the
occurrence of a mouse-up and mouse-down event for those two mouse events to be
considered a double click.
Event Manager
You should interpret mouse events as a double click if both of these conditions are true:
■ The times of the mouse-up event and mouse-down event differ by a number of ticks
less than or equal to the value returned by the GetDblTime function.
■ The locations of the two mouse-down events separated by the mouse-up event are
sufficiently close to each other. How you determine this value depends on your
application and the context in which the mouse-down events occurred. For example,
in a word-processing application, you might consider two mouse-down events a
double click if the mouse locations both mapped to the same character, whereas in a
graphics application you might consider it a double click if the sum of the horizontal
and vertical difference between the two mouse locations is no more than five pixels.
The Event Manager also provides other routines that give information about the mouse.
You can find the current mouse location using the GetMouse procedure. You can
determine the current state of the mouse button using the Button, StillDown, and
WaitMouseUp functions. See “Reading the Mouse” beginning on page 2-108 for detailed
information on these routines.
Event Manager
Also note that certain keyboards have different physical layouts or contain additional
keys, such as function keys. If your application supports function keys or other special
keys, you should follow the guidelines in Macintosh Human Interface Guidelines when
determining what action to take when the user presses one of these keys.
Certain keystroke combinations are handled by the Event Manager and not returned to
your application. If the user holds down the Command and Shift keys while pressing a
numeric key to produce a special effect, that special effect occurs. Apple provides three
standard Command–Shift–number key sequences. The standard Command–Shift–
number key sequences are 1 for ejecting the disk in the internal drive, 2 for ejecting the
disk in a second internal drive or for ejecting the disk in an external drive if the computer
has only one internal drive, and 3 for taking a snapshot of the screen and storing it as a
TeachText document on the startup volume.
The action corresponding to a Command–Shift–number key sequence is implemented
as a routine that takes no parameters and is stored in an 'FKEY' resource with a resource
ID that corresponds to the number that activates it. Apple reserves 'FKEY' resources
with resource IDs 1 through 4 for its own use; if you provide an 'FKEY' resource, use a
resource ID between 5 and 9.
You can disable the Event Manager’s processing of Command–Shift–number key
sequences for numbers 3 through 9 by setting the system global variable ScrDmpEnb
(a byte) to 0. However, in most cases you should not disable the Event Manager’s
processing of these events.
The what field of the event record for a keyboard-related event contains either the
keyDown or keyUp constant to indicate that the key was pressed or released, or the
autokey constant to indicate that the key is being held down.
The Event Manager sets the system event mask of your application to accept all events
except key-up events. Most applications ignore key-up events. If your application needs
to receive key-up events, you can change the system event mask of your application
using the Operating System Event Manager procedure SetEventMask.
In the low-order word the message field contains the character code and virtual key
code that corresponds to the key pressed by the user.
The virtual key code represents the key pressed or released by the user; this value is
always the same for a specific physical key on a particular keyboard. For example, on
the Apple Keyboard II, ISO layout, the virtual key code for the fifth key to the right
of the Tab key (the key labeled “T” ) is always $11, regardless of which modifier keys
are also pressed.
To determine the virtual key code that corresponds to a specific physical key, system
software uses a hardware-specific key-map ('KMAP') resource that specifies the virtual
key codes for a particular keyboard. After determining the virtual key code of the key
pressed by the user, system software uses a script-specific keyboard-layout ('KCHR')
resource to map a virtual key code to a specific character code. Any given script system
has one or more 'KCHR' resources. For example, a particular computer might contain the
French 'KCHR' resource in addition to the standard U.S. 'KCHR' resource. In this
situation, the current 'KCHR' resource determines whether virtual key codes are mapped
to the French or U.S. character set.
Event Manager
The character code represents a particular character. The character code that is generated
depends on the virtual key code, the state of the modifier keys, and the current 'KCHR'
resource. For example, the U.S. 'KCHR' resource specifies that for the virtual key code
$2D (the fifth key to the left of the Shift key and labeled “N” on an Apple Keyboard II,
Domestic layout), the character code is $6E when no modifier keys are pressed; the
character code is $4E when this key is pressed in combination with the Shift key.
Character codes for the Roman script system are specified in the extended version of
ASCII (the American Standard Code for Information Interchange).
The message field contains additional information for ADB keyboards. The low-order
byte of the high-order word contains the ADB address of the keyboard where the
keyboard event occurred. Figure 2-7 shows the structure of the message field of the
event record for keyboard events.
Figure 2-7 The message field of the event record for keyboard events
31 24 23 16 15 8 7 0
Usually your application uses the character code, rather than the virtual key code, when
responding to keyboard events. You can use these two constants to access the virtual key
code and character code in the message field:
The when field contains the number of ticks since the system last started up. You can
use the when field to compare how much time has expired between successive
keyboard events.
The where field of the event record contains the location of the cursor at the time the key
was pressed or released. You typically disregard the mouse location when processing
keyboard events.
The modifiers field contains information about the state of the modifier keys at the
time the key was pressed or released. Your application can perform different actions
based on the state of the modifier keys. For example, your application might perform an
action associated with a corresponding menu command if the Command key was down
at the time of the key-down event.
System software can support a number of different types of keyboards, for example, the
Apple Keyboard II, the Apple Extended keyboards, or other keyboards. The system
software uses various keyboard resources and international resources to manage different
types of keyboards. Figure 2-8 illustrates how system software maps keys to character
codes.
Event Manager
'KMAP'
resource
'itlk'
resource
Modifier state
When a user presses or releases a key on the keyboard, the keyboard generates a raw
key code. The system software uses a 'KMAP' resource to map the raw key code to a
hardware-independent virtual key code and to set bits indicating the state of the modifier
keys. A 'KMAP' resource specifies the physical arrangement of a particular keyboard and
indicates the virtual key codes that correspond to each physical key.
If the optional key-remap ('itlk') resource is present, the system software remaps the
virtual key codes and modifier state for some key combinations on certain keyboards
before using the 'KCHR' resource. The 'itlk' resource can reintroduce hardware
dependence because certain scripts, languages, and regions need subtle differences in
layout for specific keyboards. If present, the 'itlk' resource affects only a few keys.
After mapping the virtual key code and the state of the modifier keys through an
optional 'itlk' resource, the system software uses a 'KCHR' resource to produce the
character code representing the key that was pressed or released. The 'KCHR' resource
specifies how to map the setting of the modifier keys and a virtual key code to a character
code.
Event Manager
After mapping the key, the Event Manager returns the virtual key code and the character
code in the message field of the event record.
Figure 2-9 shows the virtual key codes as specified by the 'KMAP' resource for the Apple
Keyboard II, ISO layout. The labels for the keys on the keyboard are shown using the U.S.
keyboard layout. The virtual key codes are shown in hexadecimal.
Figure 2-9 Virtual key codes for the Apple Keyboard II, ISO layout
7F7F
± 0A ! 12 @ 13 # 14 $ 15 % 17 ^ 16 & 1A 1C ( 19 ) 1D 1B + 18 33 47 51 4B 43
§ 1 2 3 4 5 6 7 8 9 0 = = /
30 0C 0D 0E 0F 11 10 20 22 1F 23 { 21 } 1E 24 59 5B 5C 4E
Q W E R T Y U I O P [ ] 7 8 9 _
36 00 01 02 03 05 04 26 28 25 : 29 " 27 2A 56 57 58 45
A S D F G H J K L ; 4 5 6 +
'
38 ~32 06 07 08 09 0B 2D 2E 2B 2F ?2C 38 3E 53 54 55 4C
Z X C V B N M , . / 1 2 3
3B 3A 37 31 35 3B 3C 3D 52 41
ctrl esc 0 .
Figure 2-10 shows the virtual key codes as specified by the 'KMAP' resource for the
Apple Extended Keyboard II, one that uses the Domestic (ANSI) layout, and one that
uses the ISO layout. The labels for the keys on the ISO keyboard are shown using the
French keyboard layout. The virtual key codes are shown in hexadecimal.
If a user of an Apple Extended Keyboard II (using the U.S. 'KCHR' resource) presses the
key labeled “C” and no modifier keys, the system software maps this through the 'KMAP'
and 'KCHR' resources to produce a virtual key code of $08 and the character code $63 (the
character “c”) in the message field of the event record. If the user presses the key labeled
“C” and the Option key, then the system software maps this to virtual key code $08 and
the character code $8D (the character “ç”) in the message field.
As another example, if a user of an Apple Extended Keyboard II, Domestic layout, is
using the U.S. 'KCHR' resource and presses the key labeled “M” the system software
maps this through the 'KMAP' and 'KCHR' resources to produce a virtual key code of $2E
and the character code $6D (the character “m”) in the message field of the event record.
If a user of an Apple Extended Keyboard II, ISO layout, is using the French 'KCHR'
resource and presses the key labeled “M” the system software maps this through the
'KMAP' and 'KCHR' resources to produce a virtual key code of $29 and the character
code $6D (the character “m”) in the message field of the event record.
See Inside Macintosh: Text for additional information about the keyboard resources and
how the Script Manager manages various scripts.
2A del
75 77 79
30 0C 0D 0E 0F 11 10 20 22 1F 23 { 21 } 1E 59 5B 5C 4E
Event Manager
page _
tab Q W E R T Y U I O P [ ]
2
end down 7 8 9
caps 39 00 01 02 03 05 04 26 28 25 : 29 " 27 24 56 57 58 45
lock A S D F G H J K L ; return 4 5 6 +
'
38 06 07 08 09 0B 2D 2E 2B 2F ? 2C 38 7E 53 54 55 4C
A Z E R T Y U I O P v $ 7 8 9 _
24
39 00 01 02 03 05 04 26 28 25 29 % 27 £ 2A 56 57 58 45
Q S D F G H J K L M ù 4 5 6 +
38 > 32 06 07 08 09 0B 2D ? 2E . 2B / 2F + 2C 38 7E 53 54 55 4C
< W X C V B N , ; : = 1 2 3
3B alt 3A 37 31 37 alt 3A 3B 7B 7D 7C 52 41
ctrl ctrl 0 ,
2-43
C H A P T E R 2
Event Manager
Listing 2-6 shows code that handles key-down and auto-key events. The DoKeyDown
procedure is an application-defined procedure that is called from the DoEvent
procedure. (Listing 2-3 on page 2-26 shows the DoEvent procedure.)
The DoKeyDown procedure in Listing 2-6 first extracts the character code of the key
pressed from the message field of the event record. It then checks the modifiers field
of the event record to determine if the Command key was pressed at the time of the
event. If so, and if the event is a key-down event, the code calls the application-defined
procedure MyAdjustMenus, and then calls another application-defined routine,
DoMenuCommand, to perform the menu command associated with that key. (The
MyAdjustMenus procedure adjusts the menus appropriately, and according to whether
the current window is a document window or modeless dialog box. See the chapter
“Menu Manager” in this book for code that defines the MyAdjustMenus procedure.)
Otherwise, the code calls the application-defined procedure MyHandleKeyDown to
handle the event.
Listing 2-7 shows the application-defined routine MyHandleKeyDown.
Event Manager
myData: MyDocRecHnd;
te: TEHandle;
windowType: Integer;
BEGIN
window := FrontWindow;
{determine the type of window--document, modeless, etc.}
windowType := MyGetWindowType(window);
IF windowType = kMyDocWindow THEN
BEGIN
key := CHR(BAnd(event.message, charCodeMask));
IF window <> NIL THEN
BEGIN
IF key = char(kTab) THEN {handle special characters}
MyDoTab(event)
ELSE
BEGIN
myData := MyDocRecHnd(GetWRefCon(window));
te := myData^^.editRec;
IF
(te^^.teLength - (te^^.selEnd - te^^.selStart) + 1
< kMaxTELength) THEN
BEGIN
TEKey(key, te); {insert character in document}
MyAdjustScrollBars(window, FALSE);
MyAdjustTE(window);
myData^^.windowDirty := TRUE;
END;
END;
END;
END
ELSE
MyHandleKeyDownInModeless(event, windowType);
END;
Event Manager
Event Manager
Event Manager
update events to the appropriate applications; any applications with windows that
require updating receive the necessary update events according to the normal processing
of events.
If more than one window needs updating, the Event Manager issues update events for
the frontmost window first. This means that updating of windows occurs in front-to-back
order, which is what the user expects.
When one of your application’s windows needs to be updated, the Window Manager
calls the window definition function of that window, requesting that it draw the window
frame. The Window Manager then generates an update event for that window. The Event
Manager reports any update events for your application’s windows to your application,
and your application should update the window contents as necessary.
In response to an update event, your application should first call the BeginUpdate
procedure. The BeginUpdate procedure temporarily replaces the visible region of the
window’s graphics port (that part of the window that is visible on the screen) with the
intersection of the visible region and update region of the window. The BeginUpdate
procedure then clears the update region of the window—preventing the update event for
this occurrence from being reported again.
After calling BeginUpdate, your application should draw the window’s contents, either
entirely or in part. You can draw either the entire content region or only the area in the
visible region. In either case, the Window Manager allows only what falls within the
visible region to be drawn on the screen. (Because the BeginUpdate procedure
intersects the visible region with the update region, the visible region at this point
corresponds to any visible parts of the old update region.)
The EndUpdate procedure restores the normal visible region of the window’s
graphics port.
Figure 2-11 shows how an application updates its windows. In this example, Window 1
partially covers Window 2. When the user moves Window 1 so that more of Window 2 is
exposed, the Window Manager requests the window definition function of the window
to update the window frame, and accumulates the area requiring updating in the update
region of the window.
When the application receives an update event for this window, the message field of the
event record contains a pointer to the window that needs updating. Your application can
call BeginUpdate, draw the window’s contents, and then call EndUpdate. This
completes the handling of the update event.
Your application can receive update events when it is in the foreground or in the
background. In the example shown in Figure 2-11, Window 1 and Window 2 could
belong to the same application or different applications. In either case, the Event
Manager reports an update event to the application whose window contents
need updating.
Event Manager
Update region
Your application should respond to update events or at least call the BeginUpdate
procedure in response to an update event. If you do not call the BeginUpdate
procedure, your application continues to receive update events for the window (until
the update region is empty). You should always make sure that you match a call to
BeginUpdate with a call to EndUpdate. By calling the BeginUpdate and EndUpdate
procedures, you indicate to the Window Manager that you have updated the window
and handled the update event.
Event Manager
The DoUpdate procedure in Listing 2-9 first determines if the window is a document
window or a modeless dialog box. The MyGetWindowType function is an
application-defined routine that returns the kMyDocWindow constant if the window is a
document window and returns other application-defined constants if the window is a
modeless dialog box.
If the window is a document window, the procedure does all its drawing of the window
within calls to the BeginUpdate and EndUpdate procedures. The application-defined
routine MyDrawWindow performs the actual updating of the document window contents.
See the chapter “Window Manager” in this book for code that shows the
MyGetWindowType and MyDrawWindow routines.
If the window is a modeless dialog box, the code calls the application-defined
DoUpdateMyDialog procedure to update the contents of the dialog box. See the chapter
“Dialog Manager” in this book for details on handling update events in dialog boxes.
Event Manager
first determine whether the user clicked in another window by using the Window
Manager function FindWindow; if so, you can use the Window Manager procedure
SelectWindow to generate the necessary activate events.
Before returning to your application and before your application receives any events
relating to this occurrence, the SelectWindow procedure does some work for you, such
as removing the highlighting from the window to be deactivated and highlighting the
newly activated window. At your application’s next request for an event, the Event
Manager returns an activate event.
An activate event indicates the window involved and whether the window is being
activated or deactivated. Your application should perform any other actions needed to
complete the action of the window becoming active or inactive. For example, when a
window becomes active, your application should show any scroll bars and restore
selections as necessary.
Your application typically receives an activate event (with a flag that indicates the
window should be deactivated) for the window being deactivated, followed by an
activate event for the window becoming active.
Activate events are not placed into the Operating System event queue but are sent
directly to the Event Manager.
Figure 2-12 on the next page shows two documents belonging to the same application,
with Window 1 the active window. When the user clicks in Window 2, your application
receives a mouse-down event and can use the FindWindow function to determine
whether the mouse location is in an inactive window. If so, your application should call
the SelectWindow procedure. The SelectWindow procedure removes highlighting
of Window 1, highlights Window 2, and generates activate events for both of these
occurrences. The Event Manager reports the activate events one at a time to your
application; in this example, the first activate event indicates that Window 1 should be
deactivated. Your application should hide the scroll bars and remove the highlighting
from any selections as necessary.
The next activate event indicates that Window 2 should be activated. Your application
should show the scroll bars and restore any selections as necessary. If the window needs
updating as a result of being activated, the Event Manager sends your application an
update event so that your application can update the window contents.
Your application also needs to activate or deactivate windows in response to suspend
and resume events. If you set the acceptSuspendResumeEvents flag and the
doesActivateOnFGSwitch flag in your application’s 'SIZE' resource, your
application is responsible for activating or deactivating your application’s
windows in response to handling suspend and resume events. If you set the
acceptSuspendResumeEvents flag and do not set the doesActivateOnFGSwitch
flag, your application receives an activate event immediately following a suspend or
resume event. In most cases, you should set both the acceptSuspendResumeEvents
and doesActivateOnFGSwitch flags in your application’s 'SIZE' resource.
Event Manager
Window 1 is active.
User clicks in Window 2.
Application receives a
mouse-down event and
calls FindWindow,
then SelectWindow.
HISTORY OF THE HORSE
HISTORY OF THE BREED AND ITS ADVERSE EFFECTS
ON THE DEVELOPMENT OF THE PLEASURE MOUNT
Window Manager
removes highlighting of
Window 1.
Window Manager
highlights Window 2.
Application shows
scroll bars of Window 2
in response to activate
event and updates
window contents in
response to update
event.
HISTORY OF THE HORSE
HISTORY OF THE BREED AND ITS ADVERSE EFFECTS
ON THE DEVELOPMENT OF THE PLEASURE MOUNT
Event Manager
The what field of an event record for an activate event contains the activateEvt
constant. The message field contains a pointer to the window being activated or
deactivated. The modifiers field contains additional information about the activate
event, along with information about the state of the modifier keys at the time the event
was posted. Your application can examine bit 0 of the modifiers field of the event
record to determine if the window should be activated or deactivated. Bit 0 of the
modifiers field is 1 if the window should be activated and 0 if the window should be
deactivated. You can use the activeFlag constant to test the state of this bit in the
modifiers field.
The when field of the event record contains the number of ticks since the system last
started up. The where field of the event record contains the location of the cursor at the
time the activate event occurred.
Upon receiving an activate event that indicates the window is being deactivated, your
application should hide any scroll bars and remove the highlighting from any selections
as necessary.
Upon receiving an activate event that indicates the window is becoming active, your
application should show any scroll bars, highlight any selections, and otherwise restore
the window to the state it was in when it was last active. For example, your application
should restore the insertion point to its previous position, and the document should be
scrolled to the position in which the user last left it. Your application should also adjust
its menus appropriately for the newly active window—adjusting the marks and enabled
state of menu items based on the state of the active window.
Listing 2-10 shows an application-defined procedure that responds to activate events.
Event Manager
BEGIN
{restore any selections or display caret}
MyRestoreSelection(window);
{adjust menus as appropriate for this document window}
MyAdjustMenus;
{activate any scroll bars}
vScrollBar^^.contrlVis := kControlVisible;
hScrollBar^^.contrlVis := kControlVisible;
{invalidate area of scroll bars to force update}
InvalRect(vScrollBar^^.contrlRect);
InvalRect(hScrollBar^^.contrlRect);
{invalidate area of size box, if any}
growRect := window^.portRect;
WITH growRect DO
BEGIN
top := bottom - kScrollbarAdjust;
left := right - kScrollbarAdjust;
END; {end of WITH growRect statement}
InvalRect(growRect);
END
ELSE {window is being deactivated}
BEGIN
{unhighlight selection (if any) or hide the caret}
MyHideSelection;
HideControl(vScrollBar); {hide any scroll bars}
HideControl(hScrollBar);
DrawGrowIcon(window); {change size box immediately}
END;
HUnLock(Handle(myData));
END; {end of kMyDocWindow}
Event Manager
Event Manager
If you do mask out disk-inserted events, the event stays in the Operating System event
queue until your application calls the Standard File Package or until an application that
does handle disk-inserted events becomes the foreground process. This situation can be
confusing to the user, so your application should handle disk-inserted events at the time
that they occur.
If the volume was successfully mounted and your application either does not use the
Standard File Package or prompts the user to insert a disk, then you can choose to
respond to disk-inserted events in whatever way is appropriate for your application.
The Dialog Manager procedure ModalDialog masks out disk-inserted events. (The
Standard File Package changes the mask in order to receive disk-inserted events.) If one
of your application’s modal dialog boxes needs to respond to disk-inserted events, then
you can change the event mask from within the event filter function that you supply as
one of the parameters to ModalDialog. Otherwise, your application can respond to the
disk-inserted event after the user dismisses the modal dialog box.
The what field of the event record contains the diskEvt constant to indicate a
disk-inserted event. The message field contains the drive number in the low-order word
and the result code from the PBMountVol function in the high-order word. Your
application can examine the high-order word to determine if the attempt to mount the
volume was successful. If the volume was not successfully mounted, your application
can notify the user using the Disk Initialization Manager function DIBadMount. If the
volume was successfully mounted, your application can use the drive number returned
in the low-order word for accessing the disk.
Listing 2-11 shows a procedure that handles disk-inserted events. If the disk was not
successfully mounted, the procedure notifies the user using the DIBadMount function.
Otherwise, it does not take any action. See the chapter “Disk Initialization Manager”
in Inside Macintosh: Files for information on the routines provided by the Disk
Initialization Manager.
Event Manager
BEGIN
Event Manager
window := FrontWindow;
{determine the type of window--document, modeless, etc.}
windowType := MyGetWindowType(window);
CASE windowType OF
kMyDocWindow:
IF (NOT gInBackground) THEN
BEGIN
myData := MyDocRecHnd(GetWRefCon(window));
TEIdle(myData^^.editRec);
END;
kMyGlobalChangesID:
result := DialogSelect(event, window, itemHit);
END; {of CASE}
END;
Bit Contents
0 0 if a suspend event
1 if a resume event
1 0 if Clipboard conversion not required
1 if Clipboard conversion required
2–23 Reserved
24–31 suspendResumeMessage if a suspend or resume event
mouseMovedMessage if a mouse-moved event
Event Manager
Note that you need to examine bits 24–31 of the message field to determine what kind of
operating-system event you have received. Bits 24–31 in the message field contain one of
these two constants:
If the event is a suspend or resume event, you need to examine bit 0 to determine
whether that event is a suspend or resume event. Bits 0 and 1 are meaningful only if bits
24–31 indicate that the event is a suspend or resume event. You can use the resumeFlag
constant to determine whether the event is a suspend or resume event. If the event is a
resume event, you can use the convertClipboardFlag constant to determine whether
Clipboard conversion from the Clipboard to your application’s scrap is required:
Whenever the user performs a copy or cut operation, your application should copy the
selected data either to its private scrap or, if your application doesn’t have a private
scrap, to the Clipboard. If your application uses a private scrap, you need to convert the
data from your private scrap to the Clipboard whenever your application receives a
suspend event. Likewise, you need to convert any data from the Clipboard (if it has
changed) when your application receives a resume event. For resume events, the value of
bit 1 of the message field is 1 if your application needs to read in the new contents of the
Clipboard.
Listing 2-13 shows a procedure that responds to operating-system events.
The DoOSEvent procedure in Listing 2-13 is called from the DoEvent procedure (shown
in Listing 2-3 on page 2-26) whenever the application receives an operating-system event.
The DoOSEvent procedure examines the high byte of the message field to determine
whether the event is a mouse-moved, suspend, or resume event, and it then calls an
application-defined procedure to handle the event. Note that most applications either
adjust the cursor in response to mouse-moved events or adjust the cursor in their event
loop whenever any type of event is received. The code in this chapter uses the latter
Event Manager
approach, and thus the DoOSEvent procedure simply calls its DoIdle procedure in
response to mouse-moved events. The next two sections show the code that handles
suspend, resume, and mouse-moved events.
Note
If you set the acceptSuspendResumeEvents flag and do not set the
doesActivateOnFGSwitch flag in your application’s 'SIZE'
resource, your application receives an activate event immediately
following a suspend or resume event. In most cases, you should set both
the acceptSuspendResumeEvents and doesActivateOnFGSwitch
flags in your application’s 'SIZE' resource. ◆
Your application can use the Scrap Manager functions InfoScrap, ZeroScrap,
PutScrap, and GetScrap to read data from and write data to the Clipboard.
See the chapter “Scrap Manager” in Inside Macintosh: More Macintosh Toolbox for
additional details.
Event Manager
Note
If your application does not handle suspend and resume events (as
indicated by a flag in its 'SIZE' resource), then the Operating System
has to trick your application into performing scrap coercion to ensure
that the contents of the Clipboard can be transferred from one applica-
tion to another. This process adds to the time it takes to move the
foreground application to the background and vice versa. ◆
Listing 2-14 shows a procedure that responds to suspend and resume events. The
DoSuspendResumeEvent procedure first gets a pointer to the front window using
the Window Manager function FrontWindow. It then examines bit 0 of the message
field of the event record to determine whether the event is a suspend or resume event.
If the event is a resume event, the code examines bit 1 of the message field of the
event record to determine whether it needs to read in the contents of the scrap. If so,
the code calls an application-defined routine, MyConvertScrap, that reads in the
scrap and converts the contents to its private scrap. It then sets a private global flag,
gInBackground, to FALSE, to indicate that the application is not in the background. It
then calls another application-defined routine, DoActivate (shown in Listing 2-10), to
activate the application’s front window.
For suspend events, the DoSuspendResumeEvent procedure calls the
application-defined MyConvertScrap procedure to copy the contents of its private
scrap to the global scrap. It then sets a private global flag, gInBackground, to TRUE, to
indicate that the application is in the background. Finally, it calls another
application-defined routine to deactivate the application’s front window.
Event Manager
Your application can receive processing time while in the background and perform tasks
in the background, but your application should not interact with the user or perform
tasks that would slow down the responsiveness of the foreground process.
If you need to notify the user of some special occurrence while your application is
executing in the background, you should use the Notification Manager to queue a
notification request. See the chapter “Notification Manager” in Inside Macintosh:
Processes for examples of how to post notification requests.
Event Manager
the cursor-handling routines and for specific details of how your application can define
its own cursors.
1
Hot spot
Figure 2-14 shows four other common cursors that are available to your application: the
I-beam, crosshairs, plus sign, and wristwatch cursors.
Figure 2-14 The I-beam, crosshairs, plus sign, and wristwatch cursors
The I-beam, crosshairs, plus sign, and wristwatch cursors are defined as resources,
and your application can get a handle to any of these cursors by specifying their
corresponding resource IDs to the GetCursor function. These constants specify the
resource IDs for the I-beam, crosshairs, plus sign, and wristwatch cursors:
Event Manager
You can change the appearance of the cursor using the SetCursor procedure or other
cursor-handling routines. You can also define your own cursors, store them in resources,
and use them as needed in your application.
Your application usually needs to change the shape of the cursor as the user moves the
cursor to different areas within a document. Your application can use mouse-moved
events to accomplish this. Your application also needs to adjust the cursor in response to
resume events. Most applications adjust the cursor once through the event loop in
response to almost all events.
You can request that the Event Manager report mouse-moved events whenever
the cursor is outside of a specified region that you pass as a parameter to the
WaitNextEvent function. If you specify an empty region or a NIL handle to
the WaitNextEvent function, WaitNextEvent does not report mouse-moved events.
If you specify a nonempty region in the mouseRgn parameter to the WaitNextEvent
function, WaitNextEvent returns a mouse-moved event whenever the cursor is out of
this region. For example, Figure 2-15 shows a document window. An application might
define two regions: a region that encloses the text area of a window (the I-beam region),
and a region that defines the scroll bars and all other areas outside the text area (the arrow
region). By specifying the I-beam region to WaitNextEvent, the mouse driver continues
to display the I-beam cursor until the user moves the cursor out of this region.
I-beam region
ISTORY OF THE HORSE
ARTICLE PRESENTS A HISTORY OF THE HORSE,
LUDING A THOROUGH STUDY OF THE BREEDS
Arrow region
(outside I-beam region)
When the user moves the cursor out of the I-beam region, WaitNextEvent reports a
mouse-moved event. Your application can then change the I-beam cursor to the arrow
cursor and change the mouseRgn parameter to the area defined by the scroll bars and
all other areas outside of the I-beam region. The cursor now remains an arrow until the
user moves the cursor out of this region, at which point your application receives a
mouse-moved event.
Figure 2-16 shows how an application might change the cursor from the I-beam cursor to
the arrow cursor after receiving a mouse-moved event.
Event Manager
Figure 2-16 Changing the cursor from the I-beam cursor to the arrow cursor
Arrow cursor
ISTORY OF THE HORSE
S ARTICLE PRESENTS A HISTORY OF THE HORSE,
LUDING A THOROUGH STUDY OF THE BREEDS
I-beam cursor
ISTORY OF THE HORSE
ARTICLE PRESENTS A HISTORY OF THE HORSE,
LUDING A THOROUGH STUDY OF THE BREEDS
Note that your application should recalculate the mouseRgn parameter when it receives
a mouse-moved event; otherwise, it will continue to receive mouse-moved events as long
as the cursor position is outside the original region.
After receiving any event other than a high-level event, the MyEventLoop procedure
(shown in Listing 2-2 on page 2-24) calls the application-defined procedure
MyAdjustCursor to adjust the cursor. After adjusting the cursor, if the event is an
operating-system event, the DoEvent procedure calls the DoOSEvent procedure. The
DoOSEvent procedure calls the DoIdle procedure for mouse-moved events. The
DoIdle procedure simply calls TEIdle to blink the caret in the text-editing window.
Listing 2-15 shows the application-defined routine MyAdjustCursor.
Event Manager
BEGIN
{initialize regions for arrow and I-beam}
arrowRgn := NewRgn;
ibeamRgn := NewRgn;
Event Manager
kMyGlobalChangesID:
MyCalcCursorRgnForModelessDialogBox(window, region);
kNil:
BEGIN
MySetRegionNoWindows(kNil, region);
SetCursor(arrow);
END;
END; {of CASE}
END;
Event Manager
To receive high-level events, you must set the appropriate flags in your application’s
'SIZE' resource. You must set the isHighLevelEventAware flag if your application
is to receive any high-level events. You must set the localAndRemoteHLEvents
flag for your application to receive high-level events sent from another computer on
the network. In addition, to receive high-level events from another computer, your
application must be shared and Program Linking must be enabled. The user shares your
application by selecting your application in the Finder and choosing Sharing from the
File menu and enables Program Linking from the Sharing Setup control panel.
If you set the isHighLevelEventAware flag in your application’s 'SIZE' resource,
your application receives the Finder information in the form of Apple events. The Finder
information is the information your application can use to determine which files to open
or print. Your application must respond to the required Apple events (Open Application,
Open Documents, Print Documents, and Quit Application) that are sent by the Finder if
your application sends or receives high-level events.
The what field in the event record of a high-level event contains the kHighLevelEvent
constant.
To determine the type of high-level event received, your application needs to examine the
message and where fields of the event record. For high-level events, these two fields of
the event record have special meanings.
The message field and the where field of the event record together define the specific
type of high-level event received. Your application should interpret these fields as having
the data type OSType, not LongInt or Point.
The message field contains the event class of the high-level event. For example, Apple
events sent by the Edition Manager have the event class 'sect'. You can define your own
group of events that are specific to your application. If you have registered your
application signature with Apple Computer, Inc., then you can use your signature to
define the class of events that belong to your application. Note, however, that Apple
reserves the use of all event classes whose names contain only lowercase letters and
nonalphabetic characters.
For high-level events, the where field in the event record contains a second message
specifier, called the event ID. The event ID defines the particular type of event (or
message) within the class of events defined by the event class. For example, the Section
Read event sent by the Edition Manager has event class 'sect' and event ID 'read'. The
Open Documents event sent by the Finder has event class 'aevt' and event ID 'odoc'.
You can define your own set of event IDs corresponding to your own event class. For
example, if the message field contains 'biff' and the where field contains 'cmd1', then
the high-level event indicates the type of event defined by 'cmd1' within the class of
events defined by the application with the signature 'biff'.
Note
If your application supports Apple events, you can call the
AEProcessAppleEvent function to determine the type of Apple event
received, rather than examining the message and where fields. ◆
Event Manager
Note that because the where field of an event record for a high-level event is used to
select a specific kind of event (within the class determined by the message field),
high-level event records do not contain the mouse location at the time of the event. You
should not interpret the where field before interpreting the what field because different
event classes can contain overlapping sets of event IDs.
Unlike low-level events and operating-system events, high-level events may not be
completely determined by the event record returned to your application when it calls
WaitNextEvent. For example, you might still need to know which other application
sent you the high-level event or what additional data that application wants to send you.
Your application can obtain this further information about the high-level event by calling
the AcceptHighLevelEvent function. The additional information associated with a
high-level event includes
■ the identity of the sender of the event
■ a unique number that identifies the request associated with the event or associates the
particular event with a request from a previous event
■ the address and length of a data buffer that can contain optional data
To obtain this additional information, your application must call
AcceptHighLevelEvent before calling WaitNextEvent again. By convention,
calling AcceptHighLevelEvent indicates that your application intends to process
the high-level event.
To accept an Apple event, call the AEProcessAppleEvent function instead of
the AcceptHighLevelEvent function. The Apple Event Manager also extracts
any additional information associated with the Apple event at your application’s request.
This chapter discusses how to accept high-level events using the
AcceptHighLevelEvent function; for information on the AEProcessAppleEvent
function, see Inside Macintosh: Interapplication Communication.
Note
To respond to an Apple event, use the Apple Event Manager, as
described in Inside Macintosh: Interapplication Communication. ◆
Listing 2-16 on the next page illustrates how to respond to a high-level event.
The DoHighLevelEvent procedure in Listing 2-16 first determines the type of high-
level event received by checking the message and where fields of the event record. It
then uses AcceptHighLevelEvent to get any additional data associated with the
event. This particular application recognizes only one type of high-level event. If the
event is not of this type, the code assumes that the event is an Apple event and calls
AEProcessAppleEvent to handle the event.
Event Manager
In general, you cannot know in advance how big the optional data buffer is, so you can
allocate a zero-length buffer and then resize it if the call to AcceptHighLevelEvent
returns the bufferIsSmall result code.
Event Manager
reference number that identifies the connection with the other application as well as the
port name and location name of the sender. If the high-level event requires that you
return information, you can use the information returned in the target ID record to
send an event back to the requesting application. See “Determining the Sender of a
High-Level Event” on page 2-72 and “Sending High-Level Events” on page 2-73 for
specific information on the target ID record.
The second parameter to AcceptHighLevelEvent, the reference constant parameter, is
a unique number that identifies the request associated with the event or identifies that
the particular event is related to a request from a previous event. If you send a response
to this event, you should use the same value for the reference constant so that the sender
of the event can associate the reply with the original request.
The third parameter points to any additional data associated with the event. Any data
in this additional buffer is defined by the particular high-level event. On input, the fourth
parameter to AcceptHighLevelEvent, the length parameter, contains the
size of the buffer. If no error occurs, on output the length parameter contains the size
of the message accepted. If the AcceptHighLevelEvent function returns the result
code bufferIsSmall, the length parameter contains the size of the message yet to
be received.
Event Manager
TYPE HighLevelEventMsg =
RECORD
HighLevelEventMsgHeaderLength: Integer;
version: Integer;
reserved1: LongInt;
theMsgEvent: EventRecord;
userRefCon: LongInt;
postingOptions: LongInt;
msgLength: LongInt;
END;
HighLevelEventMsgPtr= ^HighLevelEventMsg;
When you call GetSpecificHighLevelEvent and it executes your filter function for a
high-level event waiting in the high-level event queue, the fields of the high-level event
message record are filled in by the Event Manager. You can then compare the fields of this
record to the information in the yourDataPtr parameter to determine whether that
event suits your needs. For example, the yourDataPtr parameter might contain the
signature of a return receipt. You can test its value against the event class of the event
record contained in the theMsgEvent field of the high-level event message record.
TYPE TargetID =
RECORD
sessionID: LongInt; {session reference number}
name: PPCPortRec; {sender's port name}
location: LocationNameRec; {sender's location name}
recvrName: PPCPortRec; {reserved}
END;
Event Manager
The sessionID field corresponds to the session reference number created by the PPC
Toolbox. This is a 32-bit number that uniquely identifies a PPC Toolbox session (or
connection) with another application. The name and location fields contain the
sender’s port name and location name. If the sending application is on the same
computer as the receiving application, you can determine the sending application’s
process serial number by calling the GetProcessSerialNumberFromPortName
function.
Note
To send an Apple event, use the Apple Event Manager function
AESend. The Apple Event Manager uses the Event Manager to post
Apple events. For information on posting Apple events, see Inside
Macintosh: Interapplication Communication. ◆
When you post a high-level event to an application on the same computer, you can
specify its recipient in one of four ways:
■ by port name and location name (specified in a target ID record)
■ by a session reference number
■ by the application’s creator signature
■ by a process serial number
To specify the recipient of a high-level event sent across a network, you can use only
the receiving application’s port name and location name or its session reference number.
You can use any of the four ways when sending high-level events to applications on the
local computer.
You specify the recipient of a high-level event in the receiverID parameter when you
use the PostHighLevelEvent function. To specify a port name and location name,
provide the address of a target ID record in the receiverID parameter. To specify a
process serial number, provide its address in the receiverID parameter. To specify a
session reference number, or signature, provide the data in the receiverID parameter.
When you are replying to a high-level event, it is easy to identify the recipient because
you can use the target ID record that you receive from AcceptHighLevelEvent, the
Event Manager
session reference number contained in that target ID record, or the process serial number
(if the receiving process is local). Note that replying by session reference number is
always the fastest way to respond to a high-level event.
When you are not replying to a previous event, you need to determine the identity of
the target application yourself. You can use one of several methods to do this. If the target
application is on the local computer, you can search for that application’s creator
signature or its process serial number by calling the GetProcessInformation
function. See the chapter “Process Manager” in Inside Macintosh: Processes for a detailed
explanation of the GetProcessInformation function and for examples of how to use
it to generate a list of process serial numbers of all open processes on the local computer.
If the application to which you want to send a high-level event is located on a remote
computer, you need to identify it either by its session reference number or by its port
name and location name. You can call the PPCBrowser function to let the user browse
for a specific port. You can call the IPCListPorts function to obtain a list of all ports
registered with the target PPC Toolbox. See the chapter “Program-to-Program
Communications Toolbox” in Inside Macintosh: Interapplication Communication for an
explanation of both of these functions.
As just described, you can identify the recipient of the high-level event in one of four
ways. Listing 2-17 illustrates how to send a high-level event to an application on the local
computer using the application’s creator signature. In this example, an application is
sending a high-level event to the application with the creator signature of 'boff'. The
specific high-level event being sent is identified by the event class 'boff' and the event
ID 'cmd1'.
PROCEDURE MyPostTest;
VAR
myEvent: EventRecord; {an event record}
myRecvID: OSType; {receiver ID}
myOpts: LongInt; {posting options}
myErr: OSErr;
BEGIN
myEvent.what := kHighLevelEvent;
myEvent.message := LongInt('boff'); {event class}
myEvent.where := Point(LongInt('cmd1')); {event ID}
{the receiver is identified by its signature and }
{ a return receipt is requested}
myOpts := receiverIDisSignature + nReturnReceipt;
myRecvID := 'boff'; {receiver's signature}
myErr := PostHighLevelEvent(myEvent, Ptr(myRecvID), 0, NIL, 0,
myOpts);
IF myErr <> noErr THEN
DoError(myErr);
END;
Event Manager
Event Manager
myHLEvent.what := kHighLevelEvent;
myHLEvent.message := LongInt('Dict');
myHLEvent.where := Point(LongInt('Defn'));
Event Manager
Note
You should avoid passing handles to the receiving application in an
attempt to share a block of data. It is better to put the relevant data into a
buffer (as illustrated in Listing 2-18) and pass the address of the buffer. If
you absolutely must share data by passing a handle, make sure that the
block of data is located in the system heap. ◆
If a high-level event is posted successfully, PostHighLevelEvent returns the result
code noErr, which indicates only that the event was successfully passed to the PPC
Toolbox. Your application needs to call another Event Manager routine (EventAvail,
GetNextEvent, or WaitNextEvent) to give the other application an opportunity to
receive the event.
The event you send might require the other application to return some information to
your application by sending a high-level event back to your application. You can scan for
the response by using GetSpecificHighLevelEvent. If your application must wait
for this event, you might want to display a wristwatch cursor or take other action as
appropriate to your application. You also might want to implement a timeout mechanism
in case your application never receives a response to the event.
Return receipts are posted by the Event Manager on the computer of the receiving
application (and not by the receiving application itself). No data buffer is associated with
a return receipt. However, the posting Event Manager sets the modifiers field of the
high-level event record to one of the following values:
CONST msgWasNotAccepted = 0;
msgWasFullyAccepted = 1;
msgWasPartiallyAccepted = 2;
The msgWasNotAccepted constant indicates that your event was not accepted by
the receiving application. This means that the receiving application was notified
of the arrival of your event (through WaitNextEvent) but did not call
AcceptHighLevelEvent to accept the event. The msgWasFullyAccepted constant
indicates that the receiving application did call AcceptHighLevelEvent and retrieved
all the data in the optional data buffer. The msgWasPartiallyAccepted constant
Event Manager
Data Structures 2
This section describes the event record, target ID record, high-level event message record,
and structure of the Operating System event queue. The Event Manager
Event Manager
uses event records to return information about events. You can use a target ID record
to specify or identify the address of another application or process with which your
application is communicating. If your application supplies a filter function as a parameter
to the GetSpecificHighLevelEvent function, your filter function
receives information about high-level events in a high-level event message record.
When your application uses an Event Manager routine to retrieve an event, the Event
Manager returns information about the retrieved event in an event record. The
EventRecord data type defines the event record.
TYPE EventRecord =
RECORD
what: Integer; {event code}
message: LongInt; {event message}
when: LongInt; {ticks since startup}
where: Point; {mouse location}
modifiers: Integer; {modifier flags}
END;
Field descriptions
what The what field indicates the type of event received. The type of
event can be identified by these constants:
CONST
nullEvent = 0; {no other pending events}
mouseDown = 1; {mouse button pressed}
mouseUp = 2; {mouse button released}
keyDown = 3; {key pressed}
keyUp = 4; {key released}
autoKey = 5; {key repeatedly held down}
updateEvt = 6; {window needs updating}
diskEvt = 7; {disk inserted}
activateEvt = 8; {activate/deactivate window}
osEvt = 15;{operating-system event-- }
{ resume, suspend, or }
{ mouse-moved}
kHighLevelEvent = 23;{high-level event}
Note that in System 7, event types with the values 9 through 14 are
undefined and reserved for future use by Apple. All other values for
the what field are also reserved for use by Apple.
Event Manager
when The when field indicates the time when the event was posted (in
ticks since system startup).
where For low-level events and operating-system events, the where field
contains the location of the cursor at the time the event was posted
(in global coordinates).
For high-level events, the where field contains a second event
specifier, the event ID. The event ID defines the particular type of
event within the class of events defined by the message field of the
high-level event. For high-level events, you should interpret the
where field as having the data type OSType, not Point.
modifiers The modifiers field contains information about the state of the
modifier keys and the mouse button at the time the event was
posted. For activate events, this field also indicates whether the
Event Manager
TYPE TargetID =
RECORD
sessionID: LongInt; {session reference number}
name: PPCPortRec; {port name}
location: LocationNameRec; {location name}
recvrName: PPCPortRec; {reserved}
END;
Field descriptions
sessionID For high-level events that your application receives, this field
contains the session reference number created by the PPC Toolbox.
This is a 32-bit number that uniquely identifies a PPC Toolbox
session (or connection) with another application. This field is not
used by your application when sending a high-level event to
another process. (To send a high-level event that specifies the
recipient by session reference number, provide a pointer to a session
reference number in the receiverID parameter and use the
receiverIDisSessionID constant in the postingOptions
parameter to PostHighLevelEvent.)
name For high-level events that your application receives, this field
contains a PPC port record that specifies the port name of the
process from which the high-level event originated. When sending a
high-level event to a process on a local or remote computer, you can
specify the port name of the recipient process in a PPC port record
that you provide in this field.
Event Manager
TYPE HighLevelEventMsg =
RECORD
HighLevelEventMsgHeaderLength: Integer;
version: Integer;
reserved1: LongInt;
theMsgEvent: EventRecord;
userRefCon: LongInt;
postingOptions: LongInt;
msgLength: LongInt;
END;
Field descriptions
HighLevelEventMsgHeaderLength
Reserved for use by the Event Manager.
version Reserved for use by the Event Manager.
reserved1 Reserved for use by the Event Manager.
theMsgEvent The event record of a high-level event. Your filter function can
compare the fields of this event record to determine whether the
high-level event is the desired event. If your filter function finds the
desired event, it should call AcceptHighLevelEvent to accept the
event and remove the event from the high-level event queue, and
return TRUE as its function result.
Event Manager
The event queue is a standard Macintosh Operating System queue that the Operating
System Event Manager maintains. Only mouse-up, mouse-down, key-up, key-down,
auto-key, and disk-inserted events are stored in the Operating System event queue. In
most cases, your application should not access the event queue directly. Instead you
usually use the WaitNextEvent function, which can retrieve events from this queue as
well as from other sources.
The event queue consists of a header followed by the actual entries in the queue. The
event queue has the same header as all standard Macintosh Operating System queues.
The Qhdr data type defines the queue header.
TYPE QHdr =
RECORD
qFlags: Integer; {queue flags}
qHead: QElemPtr; {first queue entry}
qTail: QElemPtr; {last queue entry}
END;
The EvQEl data type defines an entry in the Operating System event queue.
TYPE EvQEl =
RECORD
qLink: QElemPtr; {next queue entry}
qType: Integer; {queue type (ORD(evType))}
evtQWhat: Integer; {event code}
evtQMessage: LongInt; {event message}
evtQWhen: LongInt; {ticks since startup}
evtQWhere: Point; {mouse location}
evtQModifiers: Integer; {modifier flags}
END;
Each entry in the event queue begins with 4 bytes of flags followed by a pointer to the
next queue entry. The flags are maintained by and internal to the Operating System Event
Manager. The queue entries are linked by pointers, and the first field of the EvQEl data
type, which represents the structure of a queue entry, begins with a pointer to the next
queue entry. Thus you cannot directly access the flags using the EvQEl data type.
Event Manager
Receiving Events 2
You can use the WaitNextEvent or GetNextEvent function to retrieve an event from
the Event Manager and remove the event from the event stream. To provide greater
support for multitasking, however, you should use the WaitNextEvent function instead
of GetNextEvent whenever possible. You can use the EventAvail function
to look at an event without removing it from the event stream. You can use the
AcceptHighLevelEvent function to get additional information associated with a
high-level event and GetSpecificHighLevelEvent to search for a specific high-
level event.
The FlushEvents procedure removes all low-level events from the Operating System
event queue. In general, your application should not empty the event queue.
You can use the SystemClick procedure to route events to desk accessories when
necessary. The SystemTask and SystemEvent routines are used by the Event Manager,
and your application usually does not need to call these two routines.
You usually use the functions provided by the Toolbox Event Manager to retrieve events
from the event stream. Even if you are interested only in the events stored in the
Operating System event queue, you can retrieve these events using the Toolbox Event
Manager by setting the event mask to mask out all events except keyboard, mouse, and
disk-inserted events. However, you can choose to use Operating System Event Manager
routines to perform this task.
The Operating System Event Manager provides two functions, GetOSEvent and
OSEventAvail, to retrieve events from the Operating System event queue. In most
cases, your application will not need to use these two functions.
If your application needs to receive key-up events, you can change the system event
mask of your application using the SetEventMask procedure. The GetEvQHdr function
returns a pointer to the header of the Operating System event queue.
Event Manager
WaitNextEvent 2
You can use the WaitNextEvent function to retrieve events one at a time from the Event
Manager.
eventMask A value that indicates which kinds of events are to be returned; this
parameter is interpreted as a sum of event mask constants. You can use
these constants to specify the event mask:
CONST
mDownMask = 2; {mouse-down event (bit 1)}
mUpMask = 4; {mouse-up event (bit 2)}
keyDownMask = 8; {key-down event (bit 3)}
keyUpMask = 16; {key-up event (bit 4)}
autoKeyMask = 32; {auto-key event (bit 5)}
updateMask = 64; {update event (bit 6)}
diskMask = 128; {disk-inserted event (bit 7)}
activMask = 256; {activate event (bit 8)}
highLevelEventMask
= 1024; {high-level event (bit 10)}
osMask = -32768; {operating-system (bit 15)}
To accept all events, you can specify the everyEvent constant as the
event mask:
CONST
everyEvent = -1; {every event}
Event Manager
DESCRIPTION
The WaitNextEvent function returns FALSE as its function result if the event being
returned is a null event or if WaitNextEvent has intercepted the event; otherwise,
WaitNextEvent returns TRUE. The WaitNextEvent function calls the Operating
System Event Manager function SystemEvent to determine whether the event should
be handled by the application or the Operating System.
If no events are pending for your application, WaitNextEvent waits for a specified
amount of time for an event. (During this time, processing time may be allocated to
background processes.) If an event occurs, it is returned as the value of the parameter
theEvent, and WaitNextEvent returns a function result of TRUE. If the specified
time expires and there are no pending events for your application, WaitNextEvent
returns a null event in theEvent and a function result of FALSE.
Before returning an event to your application, WaitNextEvent performs other
processing and may intercept the event.
The WaitNextEvent function intercepts Command–Shift–number key sequences and
calls the corresponding 'FKEY' resource to perform the associated action. The Event
Manager’s processing of Command–Shift–number key sequences with numbers 3
through 9 can be disabled by setting the ScrDmpEnable global variable (a byte) to 0.
The WaitNextEvent function also makes the alarm go off if the alarm is set and
the current time is the alarm time. The user sets the alarm using the Alarm Clock
desk accessory.
Event Manager
The WaitNextEvent function also calls the SystemTask procedure, which gives time
to each open desk accessory or device driver to perform any periodic action defined
for it. A desk accessory or device driver specifies how often the periodic action should
occur, and SystemTask gives time to the desk accessory or device driver at the
appropriate interval.
Some high-level events may be fully specified by their event records only, while others
may include additional information in an optional buffer. To get any additional
information and to find the sender of the event, use the AcceptHighLevelEvent
function.
If the returned event is a high-level event and your application supports Apple events,
use the Apple Event Manager function AEProcessAppleEvent to respond to the Apple
event and to get additional information associated with the Apple event.
SPECIAL CONSIDERATIONS
In System 7, if your application is in the foreground and the user opens a desk accessory
or other item from the Apple menu, clicks in the window belonging to another
application or desk accessory, or chooses another process from the Application menu, the
next event reported to your application by the WaitNextEvent function is a suspend
event. After your application is switched out, the Event Manager directs events (other
than events your application can receive in the background) to the newly activated
process until the user switches back to your application or another application.
Note
In a single-application environment in System 6, and in a multiple-
application environment in which the desk accessory is launched in
the application’s partition (for example, a desk accessory opened by the
user from the Apple menu while holding down the Option key), the
Event Manager handles events for desk accessories in a slightly
different manner.
In these environments, when mouse-up, activate, update, and keyboard
events (including keyboard equivalents of menu commands) occur, the
Event Manager checks to see whether the active window belongs to a
desk accessory and whether the desk accessory can handle the event. If
so, it sends the event to the desk accessory and WaitNextEvent returns
FALSE to your application. Also note that in these environments, the
Event Manager returns TRUE for mouse-down events, regardless of
whether the mouse-down event is for a desk accessory or not. For
mouse-down events in these situations, if the mouse button was
pressed while the cursor was in a desk accessory window (as indicated
by the inSystem constant returned by the FindWindow function),
your application should call the SystemClick procedure. The
SystemClick procedure handles mouse-down events as appropriate
for desk accessories, including sending your application an activate
event to deactivate its front window if the desk accessory window needs
to be activated. ◆
Event Manager
SEE ALSO
For examples that use the WaitNextEvent function, see Listing 2-1 on page 2-23 and
Listing 2-2 on page 2-24.
To get information about the sender of a high-level event and to retrieve any
additional data associated with the high-level event, see the description of the
AcceptHighLevelEvent function on page 2-90. For details on how to process
an Apple event, see the description of the AEProcessAppleEvent function in
Inside Macintosh: Interapplication Communication.
For information on how to retrieve an event without removing it from the event stream,
see the description of the EventAvail function, immediately following.
EventAvail 2
You can use the EventAvail function to retrieve the next available event from
the Event Manager without removing the returned event from your application’s
event stream.
eventMask A value that indicates which kinds of events are to be returned; this
parameter is interpreted as a sum of event mask constants. You can use
these constants to specify the event mask:
CONST
mDownMask = 2; {mouse-down event (bit 1)}
mUpMask = 4; {mouse-up event (bit 2)}
keyDownMask = 8; {key-down event (bit 3)}
keyUpMask = 16; {key-up event (bit 4)}
autoKeyMask = 32; {auto-key event (bit 5)}
updateMask = 64; {update event (bit 6)}
diskMask = 128; {disk-inserted event (bit 7)}
activMask = 256; {activate event (bit 8)}
highLevelEventMask
= 1024; {high-level event (bit 10)}
osMask = -32768; {operating-system (bit 15)}
To accept all events, you can specify the everyEvent constant as the
event mask:
CONST
everyEvent = -1; {every event}
Event Manager
theEvent The next available event of the specified type or types. The EventAvail
function does not remove the returned event from the event stream, but
does return the information about the event in an event record. The event
record includes the type of event received and other information.
DESCRIPTION
EventAvail returns FALSE as its function result if the event being returned is a null
event; otherwise, EventAvail returns TRUE.
Like WaitNextEvent, the EventAvail function calls the SystemTask procedure to
give time to each open desk accessory or device driver to perform any periodic action
defined for it. The EventAvail function also makes the alarm go off if the alarm is set
and the current time is the alarm time. The user sets the alarm using the Alarm Clock
desk accessory.
SPECIAL CONSIDERATIONS
If EventAvail returns a low-level event from the Operating System event queue, the
event will not be accessible later if, in the meantime, the event queue becomes full and
the event is discarded from it; however, this is not a common occurrence.
SEE ALSO
See “The Event Record,” beginning on page 2-79, for a description of the fields in the
event record.
GetNextEvent 2
Although you should normally use WaitNextEvent, you can also use the
GetNextEvent function to retrieve events one at a time from the Event Manager.
eventMask A value that indicates which kinds of events are to be returned; this
parameter is interpreted as a sum of event mask constants (listed in
“Setting the Event Mask” beginning on page 2-26). If no event of any of
the designated types is available, GetNextEvent returns a null event.
theEvent The next available event of the specified type or types. The
GetNextEvent function removes the returned event from the
event stream and returns the information about the event in an
event record. The event record includes the type of event received
and other information.
Event Manager
DESCRIPTION
GetNextEvent returns FALSE as its function result if the event being returned is a null
event or if GetNextEvent has intercepted the event; otherwise, GetNextEvent returns
TRUE. The GetNextEvent function calls the Operating System Manager function
SystemEvent to determine whether the event should be handled by the application or
the Operating System.
Like WaitNextEvent, the GetNextEvent function calls the SystemTask procedure to
give time to each open desk accessory or device driver to perform any periodic action
defined for it. The GetNextEvent function also makes the alarm go off if the alarm is set
and the current time is the alarm time. (The user sets the alarm using the Alarm Clock
desk accessory.)
The GetNextEvent function also intercepts Command–Shift–number key sequences
and calls the corresponding 'FKEY' resource to perform the associated action. The Event
Manager’s processing of Command–Shift–number key sequences with numbers
3 through 9 can be disabled by setting the ScrDmpEnable global variable (a byte) to 0.
SPECIAL CONSIDERATIONS
For greater support of the multitasking environment, your application should use
WaitNextEvent instead of GetNextEvent whenever possible. If your application does
call GetNextEvent, it should also call the SystemTask procedure.
SEE ALSO
See “The Event Record,” beginning on page 2-79, for a description of the fields in the
event record. For information on the SystemTask procedure, see page 2-95.
AcceptHighLevelEvent 2
After receiving a high-level event (other than an Apple event), use the
AcceptHighLevelEvent function to get any additional information associated
with the event.
sender Identifies the sender of the event; this information is returned in a target
ID record. The sender parameter contains the session reference number
that identifies the connection with the other application and the port name
and location name of the sender.
Event Manager
msgRefcon Uniquely identifies the communication associated with this event. If you
send a response to this event, you should specify the same value for the
msgRefcon parameter so that the sender of the event can associate the
reply with the original request.
msgBuff Specifies where the AcceptHighLevelEvent function should return any
additional data associated with the event. Your application is responsible
for allocating the memory for the additional data pointed
to by the msgBuff parameter and for setting the msgLen parameter to the
number of bytes that you have allocated for the data.
If the msgBuff parameter points to an area in memory that is
not large enough to hold all the data associated with the event,
AcceptHighLevelEvent returns as much data as the specified
memory area can hold, returns the amount of data remaining in the
msgLen parameter, and returns the result code bufferIsSmall.
msgLen Contains the size of the data (in bytes) pointed to by the msgBuff
parameter. If AcceptHighLevelEvent returns the result code
bufferIsSmall, the msgLen parameter contains the number of bytes
remaining. You can call AcceptHighLevelEvent again to receive the
rest of the data.
DESCRIPTION
When your application receives a high-level event, you can use the
AcceptHighLevelEvent function to get additional data associated with the
event. The AcceptHighLevelEvent function returns information that identifies
the sender of the event and the unique message reference constant of the event.
Your application should allocate memory for any additional data associated with the
event, then supply a pointer to the data area and also provide the length in bytes of the
data area.
SPECIAL CONSIDERATIONS
The AcceptHighLevelEvent function may move or purge memory. You should not
call this function from within an interrupt, such as in a completion routine or VBL task.
ASSEMBLY-LANGUAGE INFORMATION
The trap macro and routine selector for the AcceptHighLevelEvent function are
Trap macro Selector
_OSDispatch $0033
RESULT CODES
noErr 0 No error
bufferIsSmall –607 Buffer is too small
noOutstandingHLE –608 No outstanding high-level event
Event Manager
SEE ALSO
GetSpecificHighLevelEvent 2
FUNCTION GetSpecificHighLevelEvent
(aFilter: GetSpecificFilterProcPtr;
yourDataPtr: UNIV Ptr; VAR err: OSErr): Boolean;
DESCRIPTION
Event Manager
SPECIAL CONSIDERATIONS
ASSEMBLY-LANGUAGE INFORMATION
SEE ALSO
See “Filter Function for Searching the High-Level Event Queue” on page 2-114 for more
information about how to define a filter function and the parameters that
GetSpecificHighLevelEvent passes to your filter function.
FlushEvents 2
The FlushEvents procedure removes low-level events from the Operating System
event queue. Note that FlushEvents does not remove any types of events not stored
in the Operating System event queue.
You can choose to use the FlushEvents procedure when your application first starts to
empty the Operating System event queue of any keystrokes or mouse events generated
by the user while the Finder loaded your application. In general, however, your
application should not empty the queue at any other time as this loses user actions and
makes your application and the computer appear unresponsive to the user.
whichMask A value that indicates which kinds of low-level events are to be removed
from the Operating System event queue; this parameter is interpreted
as a sum of event mask constants. The whichMask and stopMask
parameters together specify which events to remove.
Event Manager
stopMask A value that limits which low-level events are to be removed from the
Operating System event queue; this parameter is interpreted as a sum
of event mask constants. FlushEvents does not remove any low-
level events that are specified by the stopMask parameter. To remove
all events specified by the whichMask parameter, specify 0 as the
stopMask parameter.
DESCRIPTION
FlushEvents removes only low-level events stored in the Operating System event
queue; it does not remove activate, update, operating-system, or high-level events.
You specify which low-level events to remove using the whichMask and stopMask
parameters. FlushEvents removes the low-level events specified by the whichMask
parameter, up to but not including the first event of any type specified by the
stopMask parameter.
If the event queue doesn’t contain any of the events specified by the whichMask
parameter, FlushEvents does not remove any events from the queue.
ASSEMBLY-LANGUAGE INFORMATION
You must set up register D0 with the event mask (whichMask) and stop mask before
calling FlushEvents. When FlushEvents returns, register D0 contains 0 if all events
were removed from the queue or, if all events were not removed from the queue, an
event code that specifies the type of event that caused the removal process to stop.
Registers on entry
D0 Event mask (low-order word)
Stop mask (high-order word)
Registers on exit
D0 0 if all events were removed from the queue, or the event code
of the event that stopped the search (low-order word)
SEE ALSO
See “Setting the Event Mask” beginning on page 2-26 for information on how to specify
an event mask.
SystemClick 2
After receiving a mouse-down event, your application should call the Window
Manager function FindWindow to determine where the cursor was when the mouse
button was pressed. If FindWindow returns the inSysWindow constant, call the
SystemClick procedure to handle the event.
Event Manager
DESCRIPTION
If a mouse-down event occurred in a desk accessory’s window, the SystemClick
procedure determines which part of the desk accessory’s window the cursor was in when
the mouse button was pressed and routes the event to the appropriate desk accessory as
necessary.
If the mouse button was pressed while the cursor was in the content region of the desk
accessory’s window and the window is active, SystemClick sends the mouse-down
event to the desk accessory to process. If the mouse-down event occurred in the content
region of the window and the window is inactive, SystemClick makes it the active
window. It does this by sending your application an activate event to deactivate its
front window and directing an event to the desk accessory to activate its window.
If the mouse button was pressed while the cursor was in the drag region or go-away
region, SystemClick calls the Window Manager routine DragWindow or
TrackGoAway, as appropriate. If TrackGoAway reports that the user closed the desk
accessory, SystemClick sends a close message to the desk accessory.
SEE ALSO
See “The Event Record,” beginning on page 2-79, for a description of the fields in the
event record.
SystemTask 2
PROCEDURE SystemTask;
DESCRIPTION
The SystemTask procedure gives time to each open desk accessory or driver to
perform the periodic action defined for it. A desk accessory or device driver specifies
how often the periodic action should occur, and SystemTask gives time to the desk
accessory or device driver at the appropriate interval.
If your application calls GetNextEvent, your application should call SystemTask at
least every sixtieth of a second. This usually corresponds to calling SystemTask once
Event Manager
each time through your event loop. If your application does a large amount of
processing, you may need to call SystemTask more than once in your event loop.
SEE ALSO
For a description of the WaitNextEvent function and the GetNextEvent function, see
page 2-85 and page 2-89, respectively.
SystemEvent 2
DESCRIPTION
SystemEvent returns FALSE as its function result if the event should be handled by the
application; otherwise, SystemEvent takes any appropriate actions and returns TRUE.
For activate, update, mouse-up, and keyboard events (including keyboard equivalents of
commands), SystemEvent checks to see whether the active window belongs to a desk
accessory and whether that desk accessory can handle that type of event. If so,
SystemEvent sends the event to the desk accessory and returns TRUE. Otherwise,
SystemEvent returns FALSE.
For mouse-down events and null events, SystemEvent returns FALSE.
For disk-inserted events, SystemEvent attempts to mount the disk using the
PBMountVol function but returns FALSE so that the application can perform further
processing if necessary.
ASSEMBLY-LANGUAGE INFORMATION
If the SEvtEnb global variable (a byte) contains 0, SystemEvent always returns FALSE.
SEE ALSO
See “The Event Record,” beginning on page 2-79, for a description of the fields in the
event record. For a description of the PBMountVol function, see the chapter “File
Manager” in Inside Macintosh: Files.
Event Manager
GetOSEvent 2
The Toolbox Event Manager calls the GetOSEvent function to retrieve low-level events
stored in the Operating System event queue. In most cases your application should not
use this function.
mask A value that indicates which kinds of events are to be returned; this
parameter is interpreted as a sum of event mask constants. GetOSEvent
returns only low-level events stored in the Operating System event queue;
it does not return activate, update, operating-system, or high-level events.
If no low-level event of any of the designated types is available,
GetOSEvent returns a null event.
theEvent The next available low-level event of the specified type or types in the
Operating System event queue. The GetOSEvent function removes the
returned event from the Operating System event queue and returns the
information about the event in an event record. The event record includes
the type of event received and other information.
DESCRIPTION
The GetOSEvent function retrieves and removes an event from the Operating System
event queue. GetOSEvent returns FALSE as its function result if the event being
returned is a null event; otherwise, GetOSEvent returns TRUE. GetOSEvent does not
intercept or respond to the event in any way. It also does not process Command–Shift–
number key combinations or process any alarms set by the user through the Alarm Clock
desk accessory.
ASSEMBLY-LANGUAGE INFORMATION
You must set up register A0 with the address of an event record and register D0 with the
event mask before invoking GetOSEvent. When GetOSEvent returns, register D0
indicates whether the returned event is a null event or an event other than a null event
and the returned event is accessible through register A0.
Registers on entry
A0 Address of event record
D0 Event mask (low-order word)
Registers on exit
A0 Address of event record
D0 0 if GetOSEvent returns any event other than a null event, or
–1 if it returns a null event (low-order byte)
Event Manager
SEE ALSO
See “The Event Record,” beginning on page 2-79, for a description of the fields in the
event record. See “Setting the Event Mask,” beginning on page 2-26, for information on
how to specify an event mask.
OSEventAvail 2
The Toolbox Event Manager uses the OSEventAvail function to retrieve an event from
the Operating System event queue without removing it. In most cases your application
does not need to use this function.
mask A value that indicates which kinds of events are to be returned; this
parameter is interpreted as a sum of event mask constants.
OSEventAvail returns only low-level events stored in the Operating
System event queue; it does not return activate, update, operating-system,
or high-level events. If no low-level event of any of the designated types is
available, OSEventAvail returns a null event.
theEvent The next available event of the specified type or types. The
OSEventAvail function does not remove the returned event from the
Operating System event queue but does return information about the
event in an event record. The event record includes the type of event
received and other information.
DESCRIPTION
The OSEventAvail function retrieves an event from the Operating System event queue
without removing it from the queue. The OSEventAvail function returns FALSE as its
function result if the event being returned is a null event; otherwise, OSEventAvail
returns TRUE.
OSEventAvail does not intercept or respond to the event in any way. It also does not
process Command–Shift–number key combinations or process any alarms set by the user
through the Alarm Clock desk accessory.
SPECIAL CONSIDERATIONS
If the OSEventAvail function returns a low-level event from the Operating System
event queue, the event will not be accessible later if, in the meantime, the event
queue becomes full and the event is discarded from it; however, this is not a common
occurrence.
Event Manager
ASSEMBLY-LANGUAGE INFORMATION
You must set up register A0 with the address of an event record and register D0 with the
event mask before invoking OSEventAvail. When OSEventAvail returns, register D0
indicates whether the returned event is a null event or some other event, and the
returned event is accessible through register A0.
Registers on entry
A0 Address of event record
D0 Event mask (low-order word)
Registers on exit
A0 Address of event record
D0 0 if OSEventAvail returns any event other than a null event,
or –1 if it returns a null event (low-order byte)
SEE ALSO
See “The Event Record,” beginning on page 2-79, for a description of the fields in the
event record. See “Setting the Event Mask,” beginning on page 2-26, for information on
how to specify an event mask
SetEventMask 2
The SetEventMask procedure sets the system event mask of your application to the
specified mask. Your application should not call the SetEventMask procedure to disable
any event types from being posted. Use SetEventMask only to enable key-up events if
your application needs to respond to key-up events.
theMask An event mask that specifies which events should be posted in the
Operating System event queue.
DESCRIPTION
The SetEventMask procedure sets the system event mask of your application according
to the parameter theMask. The Operating System Event Manager posts only low-level
events (other than update or activate events) corresponding to bits in the system event
mask of the current process when posting events in the Operating System event queue.
The system event mask of an application is initially set to post mouse-up, mouse-down,
key-down, auto-key, and disk-inserted events into the Operating System event queue.
Event Manager
ASSEMBLY-LANGUAGE INFORMATION
The system event mask of the current application is available in the SysEvtMask system
global variable.
SEE ALSO
For additional information on event masks, see “Setting the Event Mask” beginning on
page 2-26.
GetEvQHdr 2
The Event Manager uses the GetEvQHdr function to get a pointer to the header of the
Operating System event queue. In most cases your application should not call the
GetEvQHdr function.
DESCRIPTION
The GetEvQHdr function returns a pointer to the header of the Operating System
event queue.
ASSEMBLY-LANGUAGE NOTE
The EventQueue system global variable contains the header of the event queue.
SEE ALSO
See “The Event Queue” on page 2-83 for information on the structure of the Operating
System event queue.
Sending Events 2
You can send events to other applications or processes using the PostHighLevelEvent
function. To send Apple events to other applications, use the Apple Event Manager
function AESend. The Operating System Event Manager also provides the PPostEvent
and PostEvent functions for posting low-level events to the Operating System event
queue. The PostEvent function is used by the Toolbox Event Manager. In most cases
your application should not use the PostEvent function.
Event Manager
PostHighLevelEvent 2
theEvent The event to send. Your application should fill out the what, message,
and where fields of the event record. Specify the kHighLevelEvent
constant in the what field, the event class of the high-level event in the
message field, and the event ID in the where field. You do not need to fill
out the when or modifiers fields; the Event Manager automatically
assigns the appropriate values to these fields when you send the message.
receiverID
The recipient of the high-level event. When sending an event to another
application on the local computer, you can specify the recipient of the
event by session reference number, process serial number, signature, or
port name and location name. When sending an event to an application on
a remote computer, you can specify the recipient only by the session
reference number or by the port name and location name.
To specify a port name and location name, provide the address of a target
ID record in the receiverID parameter. To specify a process serial
number, provide its address in the receiverID parameter. To specify a
session reference number, or signature, provide the data (cast to the Ptr
data type) in the receiverID parameter.
msgRefcon A unique number that identifies the communication associated with this
event. Your application can set this field to any value it chooses. If you are
replying to a high-level event, you should use the same value in the
msgRefcon parameter as specified in the high-level event that originated
the request.
msgBuff A pointer to a data buffer that contains any additional data for the event.
msgLen The size (in bytes) of the data buffer pointed to by the msgBuff
parameter.
postingOptions
Options associated with the receiverID parameter and delivery options
associated with the event. You can specify one or more delivery options to
indicate whether you want the other application to receive the event at the
next opportunity and to indicate whether you want acknowledgment that
the event was received by the other application. You use the options
associated with the receiverID parameter to indicate how you are
specifying the recipient of the event—whether by port name and location
name in a target ID record, by session reference number, by process serial
number, or by signature.
Event Manager
CONST
nAttnMsg
= $00000001; {give this message priority}
nReturnReceipt
= $00000200; {return receipt requested}
receiverIDisTargetID
= $00005000; {ID is port name and location name}
receiverIDisSessionID
= $00006000; {ID is PPC session reference number}
receiverIDisSignature
= $00007000; {ID is creator signature}
receiverIDisPSN
= $00008000; {ID is process serial number}
DESCRIPTION
The PostHighLevelEvent function posts the high-level event to the specified process.
If the application to which you are sending a high-level event terminates, you receive
the result code sessionClosedErr the next time your application calls
PostHighLevelEvent to send another high-level event to the terminated application. If
you do not care about any state information about that session, you can just resend your
event. Otherwise, you must restart another session and resend your event.
If your application is running in the background and posts a high-level event that
requires the network authentication dialog box to be displayed, PostHighLevelEvent
returns the noUserInteractionAllowed result code, does not display the network
authentication dialog box, and does not send the event. If your application receives the
noUserInteractionAllowed result code, you can use the Notification Manager to
inform the user that your application needs attention. When the user brings your
application to the foreground, you can repost the event. If the reposting is successful,
your application can continue to post high-level events without further user interaction.
Note that PostHighLevelEvent can return noUserInteractionAllowed only on
the first posting of a high-level event to a remote target.
SPECIAL CONSIDERATIONS
The PostHighLevelEvent function may move or purge memory. You should not call
this function from within an interrupt, such as in a completion routine or VBL task.
ASSEMBLY-LANGUAGE INFORMATION
The trap macro and routine selector for the PostHighLevelEvent function are
Trap macro Selector
_OSDispatch $0034
Event Manager
SEE ALSO
For details on how to send Apple events to other applications using the AESend function,
see Inside Macintosh: Interapplication Communication.
RESULT CODES
noErr 0 No error
connectionInvalid –609 Connection is invalid
noUserInteractionAllowed –610 Cannot interact directly with user
sessionClosedErr –917 Session closed
PPostEvent 2
In most cases your application does not need to post events in the Operating System
event queue; however, if you must do so, you can use the PPostEvent function.
eventCode A value that indicates the type of event to post into the Operating System
event queue. The types of events that can be posted in this queue are
represented by these constants: mouseDown, mouseUp, keyDown, keyUp,
autoKey, and diskEvt. Do not attempt to post any other type of event in
the Operating System event queue.
eventMsg A long integer that contains the contents of the message field for the
event that PPostEvent should post in the queue.
qEl PPostEvent returns a pointer to the event queue entry of the posted
event in this parameter.
DESCRIPTION
In the eventCode and eventMsg parameters, you specify the value for the what and
message fields of the event’s event record. The PPostEvent function fills out the when,
where, and modifiers fields of the event record with the current time, current mouse
location, and current state of the modifier keys and mouse button.
The PPostEvent function returns a pointer to the event queue entry of the posted event
in the qEl parameter. You can change any fields of the posted event by changing the
fields of its event queue entry. For example, you can change the posted event’s modifier
keys by changing the value of the evtQModifiers field of the event queue entry.
The PPostEvent function posts only events that are enabled by the system event mask.
If the event queue is full, PPostEvent removes the oldest event in the queue and posts
the new event.
Event Manager
▲ WARNING
Do not post any events other than mouse-down, mouse-up, key-down,
key-up, auto-key, and disk-inserted events in the Operating System
event queue. Attempting to post other events into the Operating
System event queue interferes with the internal operation of the
Event Manager. ▲
ASSEMBLY-LANGUAGE INFORMATION
You must set up register A0 and register D0 before invoking PPostEvent. The
PPostEvent function returns values in registers A0 and D0.
Registers on entry
A0 Event number (low-order word)
D0 Event message (long)
Registers on exit
A0 Pointer to an event queue entry (long)
D0 Result code (low-order word)
RESULT CODES
evtNotEnb 1 Event type not valid—event not posted
noErr 0 No error
SEE ALSO
For a description of the entries in the event queue, see “The Event Queue” on page 2-83.
PostEvent 2
The Toolbox Event Manager uses the PostEvent function to post events into the
Operating System event queue. In most cases your application should not call the
PostEvent function.
eventNum A value that indicates the type of event to post into the Operating System
event queue. The types of events that can be posted in this queue are
represented by these constants: mouseDown, mouseUp, keyDown, keyUp,
autoKey, and diskEvt. Do not attempt to post any other type of event in
the Operating System event queue.
eventMsg A long integer that contains the contents of the message field for the
event that PostEvent should post in the queue.
Event Manager
DESCRIPTION
In the eventNum and eventMsg parameters, you specify the value for the what and
message fields of the event’s event record. The PostEvent function fills out the when,
where, and modifiers fields of the event record with the current time, current mouse
location, and current state of the modifier keys and mouse button.
The PostEvent function posts only events that are enabled by the system event mask. If
the event queue is full, PostEvent removes the oldest event in the queue and posts the
new event.
Note that if you use PostEvent to repost an event, the PostEvent function fills out the
when, where, and modifier fields of the event record, giving these fields of the
reposted event different values from the values contained in the original event.
▲ WARNING
Do not post any events other than mouse-down, mouse-up, key-down,
key-up, auto-key, and disk-inserted events in the Operating System
event queue. Attempting to post other events into the Operating
System event queue interferes with the internal operation of the
Event Manager. ▲
ASSEMBLY-LANGUAGE INFORMATION
You must set up register A0 with the event code and register D0 with the event
message before invoking PostEvent. When PostEvent returns, register D0
contains the result code.
Registers on entry
A0 Event number (low-order word)
D0 Event message (long)
Registers on exit
D0 Result code (low-order word)
RESULT CODES
evtNotEnb 1 Event type not valid—event not posted
noErr 0 No error
Event Manager
GetProcessSerialNumberFromPortName 2
FUNCTION GetProcessSerialNumberFromPortName
(portName: PPCPortRec;
VAR PSN: ProcessSerialNumber): OSErr;
portName The port name registered to a process whose serial number you want.
PSN Returns the process serial number of the process designated by the
portName parameter. You can use the returned process serial number to
send a high-level event to that process. Do not interpret the value of the
process serial number.
DESCRIPTION
SPECIAL CONSIDERATIONS
ASSEMBLY-LANGUAGE INFORMATION
RESULT CODES
noErr 0 No error
noPortErr –903 Invalid port name
SEE ALSO
For a description of the PPCPortRec data type, see the chapter “Program-to-Program
Communications Toolbox” in Inside Macintosh: Interapplication Communication.
Event Manager
GetPortNameFromProcessSerialNumber 2
FUNCTION GetPortNameFromProcessSerialNumber
(VAR portName: PPCPortRec;
PSN: ProcessSerialNumber): OSErr;
portName Returns the port name of the process designated by the PSN parameter.
You can use the returned port name to send a high-level event to
that process.
PSN The process serial number of the process whose port name you want.
DESCRIPTION
SPECIAL CONSIDERATIONS
ASSEMBLY-LANGUAGE INFORMATION
RESULT CODES
noErr 0 No error
procNotFound –600 No eligible process with specified process
serial number
SEE ALSO
For a description of the PPCPortRec data type, see the chapter “Program-to-Program
Communications Toolbox” in Inside Macintosh: Interapplication Communication.
Event Manager
The Event Manager provides routines you can use to get information about the mouse.
You can get the current mouse location using the GetMouse procedure. You can use
the Button function to determine whether the user pressed the mouse button. After
receiving a mouse-down event, you can use the StillDown function to determine
whether the mouse button is still down, and you can use WaitMouseUp to determine if
the user subsequently released the mouse.
GetMouse 2
You can use the GetMouse procedure to obtain the current mouse location.
mouseLoc Returns the current mouse location in local coordinates of the current
graphics port (for example, the active window). Note that this value
differs from the value of the where field of the event record, which
specifies the mouse location in global coordinates.
Button 2
You can use the Button function to determine whether the user pressed the
mouse button.
DESCRIPTION
The Button function looks in the Operating System event queue for a mouse-down
event. If it finds one, the Button function returns TRUE; otherwise, it returns FALSE. To
determine whether the mouse button is still down after a mouse-down event, use the
StillDown function.
SEE ALSO
See “The Event Queue” on page 2-83 for information about the Operating System
event queue.
Event Manager
StillDown 2
After receiving a mouse-down event, you can use the StillDown function to determine
if the mouse button is still down.
DESCRIPTION
The StillDown function looks in the Operating System event queue for a mouse
event. If it finds one, the StillDown function returns FALSE. If it does not find any
mouse events pending in the Operating System event queue, the StillDown function
returns TRUE.
SEE ALSO
See “The Event Queue” on page 2-83 for information about the Operating System
event queue.
WaitMouseUp 2
After receiving a mouse-down event, you can use the WaitMouseUp function to
determine if the user subsequently released the mouse.
DESCRIPTION
The WaitMouseUp function looks in the Operating System event queue for a mouse-up
event. If it finds one, the WaitMouseUp function removes the mouse-up event from the
queue and returns TRUE. If it does not find any mouse events pending in the Operating
System event queue, the WaitMouseUp function returns FALSE.
SEE ALSO
See “The Event Queue” on page 2-83 for information about the Operating System
event queue.
Event Manager
The Event Manager reports keyboard events one at a time at your application’s request
when you use the WaitNextEvent, EventAvail, or GetNextEvent function. In
addition to getting keyboard events when the user presses or releases a key, you can
directly read the keyboard (and keypad) at any time using the GetKeys procedure.
You can also use the KeyTranslate function to convert virtual key codes to character
code values using a specified 'KCHR' resource.
GetKeys 2
You can use the GetKeys procedure to obtain the current state of the keyboard.
theKeys Returns the current state of the keyboard, including the keypad, if any.
The GetKeys procedure returns this information using the KeyMap data
type.
TYPE KeyMap = PACKED ARRAY[0..127] OF Boolean;
Each key on the keyboard or keypad corresponds to an element in the
KeyMap array. The index for a particular key is the same as the key’s
virtual key code minus 1. For example, the key with virtual key code 38
(the “J” key on the Apple Keyboard II) can be accessed as KeyMap[37] in
the returned array. A KeyMap element is TRUE if the corresponding key is
down and FALSE if it isn’t. The maximum number of keys that can be
down simultaneously is two character keys plus any combination of the
five modifier keys.
DESCRIPTION
You can use the GetKeys procedure to determine the current state of the keyboard at any
time. For example, you can determine whether one of the modifier keys is down by itself
or in combination with another key using the GetKeys procedure.
KeyTranslate 2
You can use the KeyTranslate function to convert a virtual key code to a character
code based on a 'KCHR' resource. The KeyTranslate function is also available as the
KeyTrans function.
Event Manager
transData A pointer to the 'KCHR' resource that you want the KeyTranslate
function to use when converting the key code to a character code.
keycode A 16-bit value that your application should set so that bits 0–6 contain the
virtual key code and bit 7 contains either 1 to indicate an up stroke or 0 to
indicate a down stroke of the key. Bits 8–15 have the same interpretation
as the high byte of the modifiers field of the event record and should be
set according to the needs of your application.
state A value that your application should set to 0 the first time it calls
KeyTranslate or any time your application calls KeyTranslate with a
different 'KCHR' resource. Thereafter, your application should pass the
same value for the state parameter as KeyTranslate returned in the
previous call.
DESCRIPTION
The KeyTranslate function returns a 32-bit value that gives the character code for the
virtual key code specified by the keycode parameter. Figure 2-17 shows the structure of
the 32-bit number that KeyTranslate returns.
31 24 23 16 15 8 7 0
The KeyTranslate function returns the values that correspond to one or possibly two
characters that are generated by the specified virtual key code. For example, a given
virtual key code might correspond to an alphabetic character with a separate accent
character. For example, when the user presses Option-E followed by N, you can map this
through the KeyTranslate function using the U.S. 'KCHR' resource to produce ´n,
which KeyTranslate returns as two characters in the bytes labeled Character code 1
and Character code 2. If KeyTranslate returns only one character code, it is always in
the byte labeled Character code 2. However, your application should always check both
bytes labeled Character code 1 and Character code 2 in Figure 2-17 for possible values
that map to the virtual key code.
SEE ALSO
For additional information on the 'KCHR' resource and the KeyTranslate function, see
Inside Macintosh: Text.
Event Manager
You can get the current number of ticks since the system last started up using the
TickCount function. You can use this function to compare the number of ticks that have
expired since a given event or other action occurred.
By using the GetDblTime function, you can get the suggested maximum difference in
ticks that should exist to consider two mouse events a double click. The user can adjust
this value using the Mouse control panel. Using the GetCaretTime function you can get
the suggested maximum difference in ticks that should exist between blinks of the caret
in editable text. The user can adjust this value using the General Controls panel.
TickCount 2
You can use the TickCount function to get the current number of ticks (a tick is
approximately 1/60 of a second) since the system last started up.
DESCRIPTION
The TickCount function returns a long integer that indicates the current number of ticks
since the system last started up. You can use this value to compare the number of ticks
that have elapsed since a given event or other action occurred. For example, you could
compare the current value returned by TickCount with the value of the when field of an
event record.
The tick count is incremented during the vertical retrace interrupt, but this interrupt can
be disabled. Your application should not rely on the tick count to increment with absolute
precision. Your application also should not assume that the tick count always increments
by 1; an interrupt task might keep control for more than one tick. If your application
keeps track of the previous tick count and then compares this value with the current tick
count, your application should compare the two values by checking for a “greater than or
equal” condition rather than “equal to previous tick count plus 1.”
▲ WARNING
Don’t rely on the tick count being exact; it’s usually accurate to within
one tick, but this level of accuracy is not guaranteed. ▲
ASSEMBLY-LANGUAGE NOTE
The value returned by TickCount is also accessible in the global variable Ticks.
Event Manager
GetDblTime 2
DESCRIPTION
The GetDblTime function returns the suggested maximum elapsed time, in ticks,
between a mouse-up event and a mouse-down event. The user can adjust this value
using the Mouse control panel.
If your application distinguishes a double click of the mouse from a single click, your
application should use the value returned by GetDblTime to make this distinction. If
your application uses TextEdit, the TextEdit procedures automatically recognize and
handle double clicks of text within a TextEdit edit record by appropriately highlighting or
unhighlighting the selection.
ASSEMBLY-LANGUAGE NOTE
The value returned by GetDblTime is also accessible in the system global variable
DoubleTime.
GetCaretTime 2
You can use the GetCaretTime function to get the suggested difference in ticks that
should exist between blinks of the caret (usually a vertical bar marking the insertion
point) in editable text. The user can adjust this value using the General Controls panel.
DESCRIPTION
If your application supports editable text, your application should use the value returned
by GetCaretTime to determine how often to blink the caret. If your application uses
only TextEdit, you can use TextEdit procedures to automatically blink the caret at the
time interval that the user specifies in the General Controls panel.
ASSEMBLY-LANGUAGE NOTE
Event Manager
Application-Defined Routine 2
When you use GetSpecificHighLevelEvent, you supply a filter function so
that your application can search for a specific event in the high-level event queue
of your application.
MyFilter 2
yourDataPtr
Specifies the criteria your filter function should use to select a specific
event. For example, you can specify the yourDataPtr parameter as a
reference constant to search for a particular event, as a pointer to a target
ID record to search for a specific sender of an event, or as an event class to
search for a specific class of event.
msgBuff Contains a pointer to a record of data type HighLevelEventMsg, which
provides: the event record for the high-level event and the reference
constant of the event. The HighLevelEventMsg data type is described in
“The High-Level Event Message Record” on page 2-82.
sender Contains the target ID record of the application that sent the event. The
TargetID data type is described in “The Target ID Record” on page 2-81.
DESCRIPTION
Your filter function can compare the contents of the yourDataPtr parameter with the
contents of the msgBuff and sender parameters. If your filter function finds a match, it
can call AcceptHighLevelEvent, if necessary, and your filter function should return
TRUE. If your filter function does not find a match, it should return FALSE.
Event Manager
SEE ALSO
Resource 2
This section explains the structure of a 'SIZE' resource and the meaning of each of its
fields. You are responsible for creating the information in this resource.
Note
If the amount of available memory is between the minimum and the
preferred sizes, the Finder displays a dialog box asking if the user wants
to run the application using the amount of memory available. If your
application does not have a 'SIZE' resource, it is assigned a default
partition size of 512 KB and the Process Manager uses a default value
of FALSE for all specifications normally defined by constants in the
flags field. ◆
When you define a 'SIZE' resource, you should give it a resource ID of –1. A user can
modify the preferred size in the Finder’s information window for your application. If the
user does alter the preferred partition size, the Operating System creates a new 'SIZE'
resource having resource ID 0. The Process Manager also creates a new 'SIZE' resource
when the user modifies any of the other settings in the resource.
Event Manager
In system software version 7.1 the user can also modify the minimum size in the Finder’s
information window for your application. In version 7.1, if the user alters either the
minimum or the preferred partition size, the Operating System creates two new 'SIZE'
resources, one with resource ID 0 and one with resource ID 1.
At application launch time, the Process Manager looks for a 'SIZE' resource with ID 0
for the preferred partition size; if this resource is not found, it uses your original 'SIZE'
resource with ID –1. In version 7.1, the Process Manager looks for a 'SIZE' resource
with ID 0 for the preferred size and looks for a 'SIZE' resource with ID 1 for the
minimum size; if these resources are not found, it uses your original 'SIZE' resource
with ID –1.
Listing 2-19 shows the structure of the 'SIZE' resource in Rez format. See Listing 2-4 in
“Creating a Size Resource,” beginning on page 2-30 for a sample 'SIZE' resource for
an application.
type 'SIZE' {
boolean reserved; /*reserved*/
boolean ignoreSuspendResumeEvents, /*ignores suspend-resume events*/
acceptSuspendResumeEvents; /*accepts suspend-resume events*/
boolean reserved; /*reserved*/
boolean cannotBackground, /*can't use background null events*/
canBackground; /*can use background null events*/
boolean needsActivateOnFGSwitch, /*needs activate event following */
/* major switch*/
doesActivateOnFGSwitch; /*activates own windows in */
/* response to OS events*/
boolean backgroundAndForeground, /*app has a user interface*/
onlyBackground; /*app has no user interface*/
boolean dontGetFrontClicks, /*don’t return mouse events */
/* in front window on resume*/
getFrontClicks; /*do return mouse events */
/* in front window on resume*/
boolean ignoreAppDiedEvents, /*applications use this*/
acceptAppDiedEvents; /*app launchers use this*/
boolean not32BitCompatible, /*works with 24-bit addr*/
is32BitCompatible; /*works with 24- or 32-bit addr*/
boolean notHighLevelEventAware, /*can't use high-level events*/
isHighLevelEventAware; /*can use high-level events*/
boolean onlyLocalHLEvents, /*only local high-level events*/
localAndRemoteHLEvents; /*also remote high-level events*/
boolean notStationeryAware, /*can't use stationery documents*/
isStationeryAware; /*can use stationery documents*/
boolean dontUseTextEditServices, /*can't use inline services*/
useTextEditServices; /*can use inline services*/
Event Manager
The nonreserved bits in the flags field have the following meanings:
Flag descriptions
acceptSuspendResumeEvents
When set, indicates that your application can process suspend and
resume events (which the Operating System sends to your
application before sending it into the background or when bringing
it into the foreground).
Note
If you set the acceptSuspendResumeEvents flag, you should
also set the doesActivateOnFGSwitch flag. ◆
canBackground When set, indicates that your application wants to receive null event
processing time while in the background. If your application has
nothing to do in the background, you should not set this flag.
doesActivateOnFGSwitch
When set, indicates that your application takes responsibility for
activating and deactivating any windows in response to a suspend
or resume event. If the acceptSuspendResumeEvents flag is set,
if the doesActivateOnFGSwitch flag is not set, and if your
application is suspended, then your application receives an activate
event following the suspend event. However, if you set the
doesActivateOnFGSwitch flag, then your application won’t
receive activate events associated with operating-system events, and
you must take care of activation and deactivation when it receives
the corresponding suspend or resume event. This means that if a
window of your application is frontmost, you should treat
a suspend event as though a deactivate event were received as
well (assuming that both the doesActivateOnFGSwitch and
acceptSuspendResumeEvents flags are set). For example, you
should hide scroll bars, hide any caret, and unhighlight any selected
text if your application moves to the background. If you do not set
this flag, the Process Manager creates an offscreen window to force
the activate and deactivate events to occur.
onlyBackground When set, indicates that your application runs only in the back-
ground. Usually this is because it does not have a user interface
and cannot run in the foreground.
getFrontClicks When set, indicates that your application is to receive the
mouse-down and mouse-up events that are used to bring your
application into the foreground when the user clicks in your
Event Manager
Note
Some early versions of MultiFinder do not send application-died
events, and your application should not depend on receiving them if
it is running in System 6. These events are provided primarily for
use by debuggers. ◆
is32BitCompatible
When set, indicates that your application can be run with the 32-bit
Memory Manager. You should not set this flag unless you have
thoroughly tested your application on a 32-bit system (such as
a Macintosh IIci computer running System 7 in 32-bit mode or under
A/UX).
isHighLevelEventAware
When set, indicates that your application can send and receive
high-level events. If this flag is not set, the Event Manager does
not give your application high-level events when you call
Event Manager
Event Manager
Pascal Summary 2
Constants 2
{event masks}
everyEvent = -1; {every event}
mDownMask = 2; {mouse-down event (bit 1)}
mUpMask = 4; {mouse-up event (bit 2)}
keyDownMask = 8; {key-down event (bit 3)}
keyUpMask = 16; {key-up event (bit 4)}
autoKeyMask = 32; {auto-key event (bit 5)}
updateMask = 64; {update event (bit 6)}
diskMask = 128; {disk-inserted event (bit 7)}
activMask = 256; {activate event (bit 8)}
highLevelEventMask = 1024; {high-level event (bit 10)}
osMask = -32768; {operating-system event (bit 15)}
Event Manager
Event Manager
Data Types 2
TYPE
EventRecord =
RECORD
what: Integer; {event code}
message: LongInt; {event message}
when: LongInt; {ticks since startup}
where: Point; {mouse location}
modifiers: Integer; {modifier flags}
END;
TargetID =
RECORD
sessionID: LongInt; {session reference number (not }
{ used if posting an event)}
name: PPCPortRec; {port name}
location: LocationNameRec; {location name}
recvrName: PPCPortRec; {reserved}
END;
HighLevelEventMsg =
RECORD
HighLevelEventMsgHeaderLength: Integer; {reserved}
version: Integer; {reserved}
reserved1: LongInt; {reserved}
theMsgEvent: EventRecord; {event record}
userRefCon: LongInt; {reference constant}
postingOptions: LongInt; {reserved}
msgLength: LongInt; {reserved}
END;
HighLevelEventMsgPtr = ^HighLevelEventMsg;
HighLevelEventMsgHdl = ^HighLevelEventMsgPtr;
GetSpecificFilterProcPtr = ProcPtr;
Event Manager
EvQElPtr = ^EvQEl;
Receiving Events
FUNCTION WaitNextEvent (eventMask: Integer; VAR theEvent: EventRecord;
sleep: LongInt; mouseRgn: RgnHandle): Boolean;
FUNCTION EventAvail (eventMask: Integer; VAR theEvent: EventRecord)
: Boolean;
FUNCTION GetNextEvent (eventMask: Integer; VAR theEvent: EventRecord)
: Boolean;
FUNCTION AcceptHighLevelEvent
(VAR sender: TargetID; VAR msgRefcon: LongInt;
msgBuff: Ptr; VAR msgLen: LongInt): OSErr;
FUNCTION GetSpecificHighLevelEvent
(aFilter: GetSpecificFilterProcPtr; yourDataPtr:
UNIV Ptr; VAR err: OSErr)
: Boolean;
PROCEDURE FlushEvents (whichMask: Integer; stopMask: Integer);
PROCEDURE SystemClick (theEvent: EventRecord; theWindow: WindowPtr);
PROCEDURE SystemTask;
FUNCTION SystemEvent (theEvent: EventRecord): Boolean;
FUNCTION GetOSEvent (mask: Integer; VAR theEvent: EventRecord)
: Boolean;
FUNCTION OSEventAvail (mask: Integer; VAR theEvent: EventRecord)
: Boolean;
PROCEDURE SetEventMask (theMask: Integer);
FUNCTION GetEvQHdr : QHdrPtr;
Event Manager
Sending Events
FUNCTION PostHighLevelEvent (theEvent: EventRecord; receiverID: Ptr;
msgRefcon: LongInt; msgBuff: Ptr;
msgLen: LongInt; postingOptions: LongInt)
: OSErr;
FUNCTION PPostEvent (eventCode: Integer; eventMsg: LongInt;
VAR qEl: EvQElPtr): OSErr;
FUNCTION PostEvent (eventNum: Integer; eventMsg: LongInt): OSErr;
Application-Defined Routine 2
Event Manager
C Summary 2
Constants 2
enum {
/*event codes*/
nullEvent = 0, /*no other pending events*/
mouseDown = 1, /*mouse button pressed*/
mouseUp = 2, /*mouse button released*/
keyDown = 3, /*key pressed*/
keyUp = 4, /*key released*/
autoKey = 5, /*key repeatedly held down*/
updateEvt = 6, /*window needs updating*/
diskEvt = 7, /*disk inserted*/
activateEvt = 8, /*activate/deactivate window*/
osEvt = 15, /*operating-system events */
/* (suspend, resume, mouse-moved)*/
/*event masks*/
mDownMask = 2, /*mouse-down (bit 1)*/
mUpMask = 4, /*mouse-up (bit 2)*/
keyDownMask = 8, /*key-down (bit 3)*/
keyUpMask = 16, /*key-up (bit 4)*/
autoKeyMask = 32, /*auto-key (bit 5)*/
updateMask = 64, /*update (bit 6)*/
diskMask = 128, /*disk-inserted (bit 7)*/
activMask = 256, /*activate (bit 8)*/
highLevelEventMask = 1024, /*high-level (bit 10)*/
osMask = -32768 /*operating-system (bit 15)*/
};
enum {
everyEvent = -1, /*every event*/
Event Manager
systemOptionsMask = 0x00000F00,
nReturnReceipt = 0x00000200, /*return receipt requested*/
priorityMask = 0x000000FF, /*mask for priority options*/
nAttnMsg = 0x00000001, /*give this message priority*/
Event Manager
Data Types 2
struct EventRecord {
short what; /*event code*/
long message; /*event message*/
long when; /*ticks since startup*/
Point where; /*mouse location*/
short modifiers; /*modifier flags*/
};
typedef struct EventRecord EventRecord;
struct TargetID {
long sessionID; /*session reference number (not */
/* used if posting an event)*/
PPCPortRec name; /*port name*/
LocationNameRec location; /*location name*/
PPCPortRec recvrName; /*reserved*/
};
struct HighLevelEventMsg {
unsigned short HighLevelEventMsgHeaderLength; /*reserved*/
unsigned short version; /*reserved*/
unsigned long reserved1; /*reserved*/
EventRecord theMsgEvent; /*event record*/
unsigned long userRefCon; /*ref constant*/
unsigned long postingOptions; /*reserved*/
unsigned long msgLength; /*reserved*/
};
Event Manager
Receiving Events
pascal Boolean WaitNextEvent (short eventMask, EventRecord *theEvent,
unsigned long sleep, RgnHandle mouseRgn);
pascal Boolean EventAvail (short eventMask, EventRecord *theEvent);
pascal Boolean GetNextEvent (short eventMask, EventRecord *theEvent);
pascal OSErr AcceptHighLevelEvent
(TargetID *sender, unsigned long *msgRefcon, Ptr
msgBuff, unsigned long *msgLen);
pascal Boolean GetSpecificHighLevelEvent
(GetSpecificFilterProcPtr aFilter,
void *yourDataPtr, OSErr *err);
pascal void FlushEvents (short whichMask, short stopMask);
pascal void SystemClick (const EventRecord *theEvent,
WindowPtr theWindow);
pascal void SystemTask (void);
pascal Boolean SystemEvent (const EventRecord *theEvent);
pascal Boolean GetOSEvent (short mask, EventRecord *theEvent);
pascal Boolean OSEventAvail (short mask, EventRecord *theEvent);
pascal void SetEventMask (short theMask);
#define GetEvQHdr() ((QHdrPtr) 0x014A)
Sending Events
pascal OSErr PostHighLevelEvent
(const EventRecord *theEvent,
unsigned long receiverID,
unsigned long msgRefcon, Ptr msgBuff,
unsigned long msgLen,
unsigned long postingOptions);
Event Manager
Application-Defined Routine 2
Event Manager
Assembly-Language Summary 2
Data Structures 2
Trap Macros 2
Selector Routine
$0033 AcceptHighLevelEvent
$0034 PostHighLevelEvent
Event Manager
Selector Routine
$0035 GetProcessSerialNumberFromPortName
$0045 GetSpecificHighLevelEvent
$0046 GetPortNameFromProcessSerialNumber
Global Variables 2
CaretTime The suggested difference in ticks that should exist between blinks of the caret
in editable text.
DoubleTime The suggested maximum difference in ticks that should exist between the
time of a mouse-up event and a mouse-down event for your application to
consider those two mouse events a double click.
EventQueue The header of the event queue.
KeyRepThresh The value of the auto-key rate (the amount of time, in ticks, that must elapse
before the Event Manager generates a subsequent auto-key event).
KeyThresh The value of the auto-key threshold (the amount of time, in ticks, that must
elapse before the Event Manager generates an auto-key event).
ScrDmpEnable A byte that, if set to 0, disables the Event Manager’s processing of
Command–Shift–number key combinations with numbers 3 through 9.
SEvtEnb A byte that, if set to 0, causes the SystemEvent function to always return
FALSE.
SysEvtMask The system event mask of the current application.
Ticks A long integer that indicates the current number of ticks since the system last
started up.
Event Manager
Result Codes 2
noErr 0 No error
procNotFound –600 No eligible process with specified process serial number
bufferIsSmall –607 Buffer is too small
noOutstandingHLE –608 No outstanding high-level event
connectionInvalid –609 Connection is invalid
noUserInteractionAllowed –610 Cannot interact directly with user
noPortErr –903 Invalid port name
Figure 3-0
Listing 3-0
Table 3-0
3 Menu Manager
Contents
Introduction to Menus 3-5
Menu and Menu Bar Definition Routines 3-9
The Menu Bar 3-9
Menus 3-11
Menu Items 3-12
Groups of Menu Items 3-14
Keyboard Equivalents for Menu Commands 3-16
Menus Added Automatically by the Menu Manager 3-19
The Apple Menu 3-20
The File Menu 3-22
The Edit Menu 3-24
The Font Menu 3-26
The Size Menu 3-27
The Help Menu 3-29
The Keyboard Menu 3-32
The Application Menu 3-33
Pop-Up Menus 3-33
Hierarchical Menus 3-38
About the Menu Manager 3-39
How the Menu Manager Maintains Information About Menus 3-40
How the Menu Manager Maintains Information About an Application’s
Menu Bar 3-40
Using the Menu Manager 3-41
Creating a Menu 3-42
Creating a Menu Resource 3-43
Creating a Menu Bar Resource 3-49
Setting Up Your Application’s Menu Bar 3-50
Creating a Hierarchical Menu 3-53
Creating a Pop-Up Menu 3-56
Contents 3-1
C H A P T E R 3
3-2 Contents
C H A P T E R 3
Resources 3-151
The Menu Resource 3-151
The Menu Bar Resource 3-155
The Menu Color Information Table Resource 3-155
The Menu Definition Procedure Resource 3-157
Summary of the Menu Manager 3-158
Pascal Summary 3-158
Constants 3-158
Data Types 3-158
Menu Manager Routines 3-159
Application-Defined Routine 3-162
C Summary 3-162
Constants 3-162
Data Types 3-163
Menu Manager Routines 3-164
Application-Defined Routine 3-166
Assembly-Language Summary 3-167
Data Structures 3-167
Global Variables 3-167
Result Codes 3-167
Contents 3-3
C H A P T E R 3
Menu Manager 3
You can use the Menu Manager to create and manage the menus in your application.
Menus allow the user to view or choose from a list of choices and commands that your
application provides.
All Macintosh applications should provide these standard menus: the Apple menu, the
File menu, and the Edit menu. If you include an Apple menu as a menu of your
application, the Menu Manager automatically adds the Help and Application menus to
your application’s menu bar; it adds the Keyboard menu if more than one keyboard
layout or input method is installed.
Menus are typically stored as resources. This chapter describes the menu-related
resources. See the chapter “Introduction to the Macintosh Toolbox” in this book for
general information on resources and see the chapter “Resource Manager” in Inside
Macintosh: More Macintosh Toolbox for information on Resource Manager routines.
See Macintosh Human Interface Guidelines for additional examples of menus that
incorporate many principles of user interface design. Inside Macintosh: Text contains
further information on localizing your application for worldwide markets.
You can choose to provide help balloons for your application’s menus. See the chapter
“Help Manager” in Inside Macintosh: More Macintosh Toolbox for additional details on
providing help balloons for your application’s menus.
You often present a dialog box to the user as a result of the user’s choice of a menu
command that requires additional information before you can perform the command. See
the chapter “Dialog Manager” later in this book for information on creating dialog boxes
in your application.
For additional information on processing events, see the chapter “Event Manager” earlier
in this book.
This chapter provides an introduction to menus and the menu bar, and it then describes
■ various types of menus your application can use
■ standard menus
■ how to store menus as resources
■ how to create menus
■ how to create a menu bar
■ how to change characteristics of menu items
■ how to add items to a menu
Introduction to Menus 3
A menu is a user interface element you can use in your application to allow the user to
view or choose an item from a list of choices and commands that your application
provides. Menus can appear in several different forms: pull-down menus, hierarchical
menus, and pop-up menus.
Menu Manager
A pull-down menu is identified by a menu title (a word or an icon) in the menu bar. Your
application can use pull-down menus in the menu bar to allow users to choose a
command or perform an action on a selected object. A pop-up menu is a menu that does
not appear in the menu bar, but appears elsewhere on the screen when the user presses
the mouse button while the cursor is in a particular place. Pop-up menus are most often
accessed from a dialog box. Your application can use pop-up menus to let the user select
one choice from a list of many or to set a specific value. A submenu refers to a menu that
is attached to another menu. A menu to which a submenu is attached is referred to as a
hierarchical menu.
Figure 3-1 shows examples of a pull-down menu, a submenu, and a pop-up menu.
The standard menu bar extends across the top of the startup screen and contains the title
of each available pull-down menu. Your application’s menu bar should always provide at
least the Apple menu, the File menu, and the Edit menu. When you insert the Apple
menu in your application’s menu bar, the Menu Manager automatically adds the Help
and Application menus to your application’s menu bar. It also adds the Keyboard menu
if multiple script systems are installed or if a certain bit is set in the 'itlc' resource.
Your application can include as many other menus as fit on the smallest screen on which
your application runs, and you should create only as many items as are essential to your
application.
If your application uses a menu bar, you should make it always visible and available for
use. If you do not always wish to display the menu bar (for example, if your application
allows the user to view a screen presentation), you can give the user the option of
viewing the presentation on the entire screen without the menu bar showing. However,
you must provide a way, such as a keyboard equivalent for a command, for the user to
access the menu bar or to make the menu bar reappear.
Using menus in your application allows the user to explore many possible choices and
options without having to choose any particular one. By providing help balloons for
Menu Manager
your menus, you further allow users to learn about the possible actions or consequences
of a particular menu choice without having to choose the menu command to find out
what happens.
Figure 3-2 shows the SurfWriter application’s menu bar with the Edit menu displayed.
This application supports the standard Apple, File, and Edit menus; the Help and
Application menus; and in addition supports two other application-specific menus.
Figure 3-2 The SurfWriter application’s menu bar with the Edit menu displayed
Menu
bar
Each menu has a menu title and one or more menu items associated with it. You should
name each menu so that the title describes or relates to the actions the user can perform
from that menu. For example, the Edit menu of a typical application contains commands
that let the user edit the contents of a document.
Your application can disable any menu. The Menu Manager indicates that a menu is
disabled by dimming its menu title. (In Figure 3-2, the Colors menu is disabled.) The
Menu Manager dims all menu items of a disabled menu. The user can still pull down and
examine the items in a disabled menu, but cannot choose any of the items.
Your application can also disable individual menu items. The Menu Manager dims the
appearance of a disabled item and does not highlight it when the user rests the cursor on
that item. If the user releases the mouse button while the cursor is over a disabled menu
item, the Menu Manager reports that the user did not choose a menu command. (You can
determine if this happened, however, by using the MenuChoice function.)
In Figure 3-2, the Paste command is disabled; the SurfWriter application disables the Paste
command if the Clipboard is empty. SurfWriter also disables the Publisher Options
command when the current selection does not contain a publisher or a subscriber. As
explained in the chapter “Help Manager” in Inside Macintosh: More Macintosh Toolbox, your
application should provide help balloons for disabled items that describe what the item
normally does and explain why the item is not available at this time.
Menu Manager
Note
Although enabled and disabled are the constants you use in a
resource file to display or to dim menus and menu items, you shouldn’t
use these terms in your help balloons or user documentation. Instead use
the terms menus, menu commands, and menu items for those that are
enabled, and use the terms not available and dimmed to distinguish those
that have been disabled. ◆
The Menu Manager highlights an enabled menu item when the cursor is over it.
Enabled items do not have a dim appearance and can be chosen by the user.
Your application specifies whether menu items are enabled or disabled when it first
defines and creates a menu. You can also disable or enable menu items at any time after
creating a menu. You should enable a menu item whenever your application allows the
user to choose the action associated with that item, and you should disable an item
whenever the user cannot choose that item. For example, if the user selects text and then
presses the mouse button while the cursor is in the menu bar, you should enable the
Copy command in the Edit menu. You should disable the Copy command in the Edit
menu if the user has not selected anything to copy.
Your application can also specify other characteristics of menu items, such as whether the
item has a marking character next to its text (for example, a checkmark) or whether the
item has a keyboard equivalent (for example, Command-C for the Copy command).
“Menu Items” beginning on page 3-12 describes the characteristics of individual menu
items in more detail.
The user typically chooses commands by moving the cursor to the menu bar and
pressing the mouse button while the cursor is over a menu title. When the user presses
the mouse button while the cursor is in the menu bar, your application should call the
MenuSelect function. The MenuSelect function tracks the mouse, displays and
removes menus as the user drags the cursor through the menu bar, highlights menu titles
as the user drags the cursor over them, displays the menu items associated with a
selected menu, highlights enabled menu items as the user drags through a menu, and
handles all user activity until the user releases the mouse button.
The user chooses a menu item by releasing the mouse button while the cursor is over a
particular enabled menu item. When the user chooses a menu item, the Menu Manager
briefly blinks the chosen menu item (to confirm the choice) and then removes the menu
from the display. The Menu Manager leaves the title of the chosen menu highlighted to
provide feedback to the user.
The MenuSelect function returns information that allows your application to determine
which menu item was chosen. Your application then typically responds by performing
the desired command. When your application completes the requested action, your
application should unhighlight the menu title, indicating to the user that the action is
complete.
The user can move the cursor out of the menu (or menu bar) at any time; the Menu
Manager displays any currently visible menu as long as the mouse button is pressed. (If
the cursor is outside of the menu, the Menu Manager removes any highlighting of the
menu item.) If the user releases the mouse button outside of a menu, the MenuSelect
Menu Manager
function reports that the user did not choose a menu item, and the Menu Manager
removes any currently visible menu. Your application should not take any action if the
user does not choose a menu item.
Menu Manager
menu that appears in your menu bar. You use Menu Manager routines to create the
menus and menu bar based on these resource definitions.
Your application can change the enabled state of a menu, add menus to or remove menus
from its menu bar, or change the characteristics of any menu items. Whenever your
application changes the enabled state of a menu or the number of menus in its menu bar,
your application must call the DrawMenuBar procedure to update the menu bar’s
appearance.
The menu bar (as defined by the standard menu bar definition function) is white, with a
height that is tall enough to display menu titles in the height of the system font and
system font size, and with a black lower border that is one pixel tall. The menu bar is as
wide as the screen and always appears on the monitor designated by the user as the
startup screen. (The user selects a startup screen using the Monitors control panel.) The
menu bar appears at the top of the screen, and nothing except the cursor can appear in
front of it. Figure 3-3 shows the menu bar of the SurfWriter application.
The menu bar helps to indicate the active application. The active application is the one
whose menu bar is currently showing and whose icon appears as the menu title of the
Application menu.
The titles of menus appear in the menu bar. A menu title is a text string (except for the
Apple, Help, Keyboard, and Application menus, the titles of which contain a small icon).
Menu titles always appear in the system font and system font size (for Roman scripts, the
system font is Chicago and the system font size is 12).
You can insert any number of menu titles in the menu bar; however, less than 10 is
usually optimum. Keep in mind that not all users have the same size monitor. Design
your menu bar so that all titles can fit in the menu bar of the smallest screen on which
your application can run. You should also consider localization issues when designing
the number of menus that fit in your menu bar—not all menu titles might fit in the menu
bar once the menu titles are translated. For example, English text often grows 50 percent
larger when translated to other languages.
Figure 3-4 shows the SurfWriter application’s menu bar with menu titles that have been
localized for another script system.
Figure 3-4 The SurfWriter application’s menu bar localized for another script system
Menu Manager
Menus 3
A menu (as defined by the standard menu definition procedure) is a list of menu items
arranged vertically and contained in a rectangle. The rectangle is shaded and can extend
vertically for the length of the screen. If a menu has more items than will fit on the screen,
the standard menu definition procedure adds a downward-pointing triangular indicator
to the last item on the screen, and it automatically scrolls through the additional items
when the user moves the cursor past the last menu item currently showing on the screen.
When the user begins to scroll through the menu, the standard menu definition
procedure adds an upward-pointing triangular indicator to the top item on the screen to
indicate that the user can scroll the menu back to its original position.
Each menu can have color information associated with it. If you do not define the colors
for your menus in your application’s menu color information table, the Menu Manager
uses the default colors for your menus and menu bar. The default colors are black text on
a white background. In most cases the default colors should meet the needs of your
application. “The Menu Color Information Table Record” on page 3-98 and “The Menu
Color Information Table Resource” on page 3-155 give information on how you can
define colors for your application’s menus.
Your application’s menus can contain any number of menu items. “Menu Items”
(the next section) describes the visual variations that you can use when defining your
menu items.
You typically define the order and resource IDs of the menus in your application’s menu
bar in an 'MBAR' resource. You should define your 'MBAR' resource such that the Apple
menu is the first menu in the menu bar. You should define the next two menus as the File
and Edit menus, followed by any other menus that your application uses. You do not
need to define the Keyboard, Help, or Application menus in your 'MBAR' resource; the
Menu Manager automatically adds them to your application’s menu bar if your
application calls the GetNewMBar function and your menu bar includes an Apple menu
or if your application inserts the Apple menu into the current menu list using the
InsertMenu procedure.
You define the menu title and characteristics of each individual menu item in a 'MENU'
resource. “Creating a Menu Resource” on page 3-43 describes the 'MENU' resource in
more detail.
Pop-up menus do not appear in the menu bar but appear elsewhere on the screen. You
often use pop-up menus in a dialog box when you want the user to be able to make a
selection from a large list of choices. For example, rather than displaying the choices
as a number of radio buttons, you can use a pop-up menu to display the choices at the
user’s convenience.
A hierarchical menu refers to either a pull-down or pop-up menu that has a submenu
attached to it. (However, you should avoid attaching a submenu to a pop-up menu
whenever possible, as this can make the interface more complex and less intuitive to
the user.)
Menu Manager
“Creating a Pop-Up Menu” on page 3-56 gives additional information about pop-up
menus, and “Creating a Hierarchical Menu” on page 3-53 describes hierarchical menus in
more detail.
Menu Items 3
A menu item can contain text or can be a line (a divider) separating groups of choices. A
divider is always dimmed, and it has no other characteristics associated with it.
Each menu item (other than dividers) can have a number of visual characteristics:
■ An icon to the left of the menu item’s text. If you define an icon for a menu item, use
an icon that gives a symbolic representation of the menu item’s meaning or effect. You
can specify an icon, a small icon, a reduced icon, or a color icon as the icon for a menu
item; however, items with small or reduced icons cannot have submenus and cannot
be drawn in a script other than the current system script.
■ A checkmark or other marking character to the left of the menu item’s text (and to the
left of the item’s icon, if any). Use such a mark if you need to denote the status of the
menu item or the mode it controls. A menu item can have a mark or a submenu, but
not both.
■ The symbol for the Command key ( ) and another 1-byte character to the right of the
menu item’s text (referred to as the keyboard equivalent of a command). Use this if your
application allows the user to invoke the menu command from the keyboard by
pressing the Command key and one or more other keys in combination, just as if the
user had chosen the command from the menu. An item that has a keyboard equivalent
cannot have a submenu, a small icon, or a reduced icon and cannot be drawn in a
script other than the current system script.
■ A triangular indicator to the right of the menu item’s text to indicate that the item has
a submenu. A menu item that has a submenu cannot have a keyboard equivalent, a
marking character, a small icon, or a reduced icon and cannot be drawn in a script
other than the current system script.
■ A font style—either plain or one of various other styles—for the menu item’s text. You
can set the menu item’s style to bold, italic, underline, outline, shadow, or any
combination of these.
■ The text of the menu item. Choose words for menu items that declare the action that
occurs when the user chooses the command (usually verbs, such as Print or Save). You
can also use adjectives if the command changes the attribute of a selected object (for
example, Bold or Italic). Unless you specify otherwise, the text of menu items appears
in the script of the system font and system font size (for Roman scripts, the system font
is Chicago and the system font size is 12 points). If you want a menu item’s text to
appear in a script other than the current system script, you can specify a script code for
the text. The Menu Manager draws the item’s text in the script identified by the script
code if the script for the specified script system is installed. A menu item that is drawn
in another script cannot have a submenu, small icon, or reduced icon.
■ Three ellipsis points (...) as the last character in the text of the menu item. Use ellipses
in the text of menu items to indicate that your application displays a dialog box that
requests more information from the user before executing the command. Do not use
Menu Manager
ellipses in menu items that display informational dialog boxes that do not require
additional information from the user. In addition, you should not use ellipses if your
application displays a confirmation alert after the user chooses a menu command. For
example, if the user makes changes to a document, then chooses the Close command,
your application can display a confirmation alert box, asking the user whether the
document should be saved before closing. This type of command should not contain
ellipses in its text.
If your application displays a dialog box requesting more information in response to
the choice of a menu command, do include ellipses in the menu item’s text. For
example, the Open command includes ellipses in its text because the user must
provide additional information: the name of the file to open. When you request more
information from the user in a dialog box, you should provide an OK button or its
equivalent in the dialog box that the user can select to perform the command. The
dialog box should also include a Cancel button or its equivalent so that the user can
cancel the command. See the chapter “Dialog Manager” in this book for information
on creating dialog boxes.
■ A dimmed appearance. When your application disables a menu item, the Menu
Manager dims the menu item to indicate that the user can’t choose it. Note that the
Menu Manager dims the entire menu item, including any mark or icon, the menu text,
and any keyboard equivalent symbol. Divider lines always have a dimmed
appearance, regardless of whether your application enables them or not. When your
application disables an entire menu, the Menu Manager dims the menu title and all
menu items in that menu.
Figure 3-5 shows two menus with menu items that illustrate many of the characteristics
that you can use when defining your menu items.
Disabled
command
Italic text style
Keyboard
equivalent
When the primary line direction is right to left (as is the case for non-Roman script
systems such as Arabic) the Menu Manager reverses the order of elements in menu items.
For example, any marking character appears to the far right and any keyboard equivalent
appears to the far left of the menu item’s text.
Menu Manager
On a monitor that is set to display only black and white, the Menu Manager displays
dividers as dotted lines. In all other cases, the Menu Manager displays dividers as
appropriate, based on the current color table. For example, on a monitor set to display
4-bit color or greater, the Menu Manager typically displays dividers as gray lines.
Your menu can contain as many menu items as you wish. However, only the first
31 menu items can be individually disabled (all menu items past 31 are always enabled
if the menu is enabled and always disabled if the menu is disabled). If your menu items
exceed the length of the screen, the user must scroll to view the additional items. Keep
in mind that the fewer the menu items in a menu, the simpler and clearer the menu is
for the user.
Menu Manager
You can also group a set of attribute commands together if a number of the attributes in
the group can be in effect at any one time (an accumulating group). In an accumulating
group, use checkmarks to indicate that multiple attributes are in effect. In this type
of group, you also need to provide a command that cancels all the other attributes. For
example, a Style menu that lets the user choose any combination of font styles should
also include a Plain Text command that cancels all the other attributes. Figure 3-7 shows a
Style menu; in this example, the Bold and Outline attributes are both in effect.
You can also use a combination of checkmarks and dashes to help indicate the state of the
user’s content. For example, in a menu that reflects the state of a selection, place a
checkmark next to an item if the attribute applies to the entire selection; place a dash next
to an item if the attribute applies to only part of the selection. Figure 3-8 shows a Style
menu that indicates that the selection contains more than one style. In this figure, the
Bold attribute applies to the entire selection; the Underline attribute applies to only part
of the selection.
Menu Manager
Your application should adjust its menus appropriately before displaying its menus.
For example, you should add checkmarks or dashes to items that are attributes as
necessary, based on the state of the user’s document and according to the type of window
that is in the front. See “Adjusting the Menus of an Application” on page 3-73 for more
information.
Another way to show the presence or absence of an attribute is to use a toggled
command. Use a toggled command if the attribute has two states and you want to allow
the user to move between the two states using a single menu command. For example,
your application could provide a Show Borders command when the borders surrounding
publishers and subscribers are not showing in a document. When the user chooses the
Show Borders command, your application should show the borders and change the
menu item to Hide Borders. When the user chooses the Hide Borders command, your
application should hide the borders surrounding any publishers or subscribers and
change the menu item to Show Borders. Use a toggled command only when the wording
of the two versions of the command is not confusing to the user. Choose a verb phrase as
the text of a toggled command; the text should clearly indicate the action your
application performs when the user chooses the item. See “Changing the Text of an Item”
on page 3-59 for further information on providing a toggled command.
Menu Manager
perform the associated menu command, if any. See the chapter “Event Manager” in this
book for additional information about the modifiers field of the event record.
The keyboard layout ('KCHR') resource of some keyboards masks or cancels the effect of
the Shift key when the Command key is also pressed. For example, with a U.S. keyboard
layout, when a user presses Command-S, the character code in the message field of the
event record is $73 (the character code for “s”); when a user presses Command-Shift-S,
the character code in the message field of the event record is also $73. However, not all
'KCHR' resources mask the Shift key in this way.
Furthermore, when your application uses the MenuKey function to process Command-
key equivalents, MenuKey does not distinguish between uppercase and lowercase letters.
The MenuKey function takes the 1-byte character passed to it and calls the UpperText
procedure (which provides localizable uppercase conversion of the character). Thus,
MenuKey translates any lowercase character to uppercase when comparing a keyboard
event to keyboard equivalents. If your application must distinguish between lowercase
and uppercase characters for keyboard equivalents, you need to provide your own
method for handling such keyboard equivalents.
The key you specify for a Command-key equivalent must be a 1-byte character and is
usually a letter (although you can specify 1-byte characters other than letters). For
consistency and to provide greater support for localizing your application, you should
always specify any letters for keyboard equivalents in uppercase when you define your
application’s menu commands.
If you wish to provide other types of keyboard equivalents in addition to Command-key
equivalents, your application must take additional steps to support them. If your
application allows the user to hold down more than one modifier key to invoke a
keyboard equivalent, your application must provide in the menu item a visual indication
that represents this keyboard combination. In most cases your application must use its
own method (other than MenuKey) for mapping the keyboard equivalent to the
corresponding menu item.
If you specify a key other than a letter for a Command-key equivalent or use more than
one modifier key for a keyboard equivalent, you should choose keys and keyboard
combinations that can be easily localized for other regions.
If your application uses other keyboard equivalents, you can examine the state of the
modifier keys and use the KeyTranslate function, if necessary, to help map the
keyboard equivalent to a particular menu item. See the chapter “Event Manager” in this
book for information on the KeyTranslate function, and see the discussion of 'KCHR'
resources in Inside Macintosh: Text for information on how various keyboard combinations
map to specific character codes.
One command that isn’t listed in a menu but can be invoked from the keyboard is the
Command-period ( -.) or Cancel command. You detect a Command-period command
in a method similar to the method for detecting other keyboard equivalents—you
examine the modifiers field of a keyboard event to determine whether the Command
key was pressed. In this case, however, if the user pressed the period key in addition to
the Command key, rather than invoking a menu command your application should
cancel the current operation.
Menu Manager
You typically define the Command-key equivalents for your application’s menu
commands when you define the menu commands in a 'MENU' resource. The Menu
Manager displays the Command-key equivalent for a menu command (if it has one)
to the right of the menu item’s text (or to the left of the item’s text for right-to-left
script systems).
Apple reserves several keyboard equivalents for common commands. You should use
these keyboard equivalents for commands in the File and Edit menus of your application.
Table 3-1 show the keyboard equivalents for standard commands.
Note
You should use the keyboard equivalents Z, X, C, and V for the editing
commands Undo, Cut, Copy, and Paste in order to provide support for
editing in desk accessories and dialog boxes. ◆
Apple also reserves several keyboard equivalents for use with worldwide versions of
system software, localized keyboards, and keyboard layouts. Table 3-2 shows these
keyboard equivalents. Your application should not use the keyboard equivalents listed in
Table 3-2 for its own menu commands.
See Inside Macintosh: Text for more discussion of handling keyboard equivalents in other
script systems.
The key combinations listed in Table 3-1 and Table 3-2 are reserved across all
applications. Even if your application doesn’t support one of these menu commands, it
shouldn’t use these keyboard equivalents for another command. This guideline is for the
user’s benefit. Reserving these key combinations provides guaranteed, predictable
behavior across all applications.
Menu Manager
Keys Action
–Space bar Rotate through enabled script systems
–Option–Space bar Rotate through keyboard layouts or input methods
within the active script system
–modifier key–Space bar Reserved
–Right arrow Change keyboard layout to the current keyboard
layout of the Roman script
–Left arrow Change keyboard layout to the current keyboard
layout of the system script
Table 3-3 shows other common keyboard equivalents. These keyboard equivalents are
secondary to the standard keyboard equivalents listed in Table 3-1 and Table 3-2. If your
application doesn’t support one of the functions in Table 3-3, then you can use the
equivalent as you wish.
You shouldn’t assign keyboard equivalents to infrequently used menu commands. Only
add keyboard equivalents for the commands that your users employ most frequently.
Menu Manager
The Help menu icon or both the Help menu icon and the Keyboard menu icon disappear
from the menu bar if your application inserts a menu whose title extends into the space
occupied by one or both of those icons. This allows your application to reclaim any space
in the menu bar that would have been occupied by one or both of those two menu icons,
if necessary. However, if your application inserts a menu whose title is long enough to
overlap space occupied by the Application menu icon, the overlapping portion of that
title disappears behind the Application menu icon. The Application menu icon is always
displayed in the menu bar.
Because the Menu Manager inserts the Help, Keyboard, and Application menus into your
application’s current menu bar, you should not make any assumptions about the last
menu (or menus) in your menu bar. Apple also reserves the right to add other
system-handled menus to your application’s menu bar; for compatibility you should
define your menu bar such that there is room for the Help, Keyboard, and Application
menus and at least one additional system-handled menu.
Your application does not need to take any action if the user chooses an item from the
Keyboard or Application menu; the Menu Manager performs any appropriate actions for
these two menus. If the user chooses an item that your application added to the Help
menu, your application should perform the corresponding action.
The following sections describe the Help, Keyboard, and Application menus in more
detail, and they also describe other menus in a typical application, including the Apple,
File, and Edit menus.
Menu Manager
Note
The Apple Menu Items folder is available in System 7 and later. In System 6,
the AppendResMenu and InsertResMenu procedures add only the desk
accessories in the System file to the specified menu when you specify
'DRVR' as the resource type to add in the parameter theType. ◆
The user can place any desktop object in the Apple Menu Items folder. When the user
places an item in this folder, the system software automatically adds it to the list of items
in the Apple menu of all open applications.
When the user chooses an item other than your application’s About command from
the Apple menu, your application should call the OpenDeskAcc function. The
OpenDeskAcc function prepares to open the desktop object chosen by the user; for
example, if the user chooses the Alarm Clock desk accessory, the OpenDeskAcc function
prepares to open the Alarm Clock. The OpenDeskAcc function schedules the Alarm
Clock desk accessory for execution and returns to your application. On your application’s
next call to WaitNextEvent, it receives a suspend event, and then
the Alarm Clock desk accessory becomes the foreground process.
If the user chooses a desktop object other than a desk accessory or an application, the
OpenDeskAcc function also takes the appropriate action. For example, as shown in
Figure 3-9, if the user chooses a document called MyTideReport created by the SurfWriter
application, the OpenDeskAcc function prepares to open the SurfWriter application (if it
isn’t already open) and schedules the SurfWriter application for execution. The
SurfWriter application is instructed to open the MyTideReport document when it
becomes the foreground process.
When the user chooses your application’s About command, your application can
display a dialog box or an alert box that contains your application’s name, version
number, copyright information, or other information as necessary. Your application
should provide an OK button in the dialog box; the user clicks the OK button to close
the dialog box.
Menu Manager
Figure 3-10 shows the alert box that the SurfWriter application displays when the user
chooses the About command from the application’s Apple menu.
If your application provides any application-specific Help commands, place these in the
Help menu, not the Apple menu.
Menu Manager
Table 3-4 describes the standard commands in the File menu and the actions your
application should take when a user chooses them.
Command Action
New Open a new, untitled document.
Open... Display the Open dialog box using the Standard File Package.
Close Close the active window (which may be a document window,
modeless dialog box, or other type of window). If the active window
is a document and the document has been changed since the last save,
display a dialog box asking the user if the document should be saved
before closing.
Save Save the active document to a disk, including any changes made to
that document since the last time it was saved. If the user chooses
Save for a new untitled document (one that the user hasn’t named
yet), display the Save dialog box using the Standard File Package.
Save As... Save a copy of the active document under a new name provided by
the user. Display the Save dialog box using the Standard File Package.
After your application saves the document, the document should
remain open and active.
Page Setup... Display the Page Setup dialog box to let the user specify printing
parameters such as the paper size and printing orientation. Your
application can provide other printing options as appropriate. Your
application should save the user’s Page Setup printing preferences for
the document when the user saves the document.
Print... Display the Print job dialog box to let the user specify various
parameters, such as print quality and number of copies. Print the
document if the user clicks the Print button. The options specified in
the Print dialog box apply to only the current printing operation, and
your application should not save these settings with the document or
restore the settings when the user chooses Print again.
Quit Quit your application after performing any necessary cleanup
operations. If any open documents have been changed since the user
last saved them, display the Save dialog box once for each open
document that requires saving. If any background or lengthy
operation is still in progress, notify the user, giving the user the option
to continue and not quit the application.
See Macintosh Human Interface Guidelines for additional commands that you can provide
in the File menu. See the chapter “Introduction to File Management” in Inside Macintosh:
Files for information on how to perform the actions associated with the commands in the
File menu. See the chapter “Standard File Package” in Inside Macintosh: Files for
information on the standard file dialog boxes. See the chapter “Printing Manager” in
Inside Macintosh: Imaging for information on displaying the Page Setup and Print job
dialog boxes.
Menu Manager
The New, Open, Close, Save, Print, and Quit commands have the keyboard equivalents
shown in Figure 3-11 on page 3-22. These keyboard equivalents are reserved for these
menu commands; do not assign these keyboard equivalents to any menu command other
than the ones shown in Figure 3-11.
The standard editing commands (Undo, Cut, Copy, Paste, and Clear) in your
application’s Edit menu should appear in the order shown in Figure 3-12. Whenever
possible, you should add an additional word or phrase to clarify what action your
application will reverse when the user chooses the Undo command. For example,
Figure 3-12 shows an application’s Edit menu that uses the phrase Undo Typing when
typing was the last action performed by the user. If your application can’t undo the last
operation, you should change the text of the Undo command to Can’t Undo and disable
the menu item. See “Changing the Text of an Item” on page 3-59 for an example of how
to change the text of a menu item.
You can include other commands in your application’s Edit menu if they’re related to
editing or changing the content of your application’s documents. If you add commands
to the Edit menu, add them after the standard menu commands. For example, if
appropriate, your application should support a Select All command. If your application
supports both the Clear and Select All commands, they should appear in the order shown
in Figure 3-12.
Menu Manager
Table 3-5 describes the standard commands in the Edit menu and the actions your
application should take when a user chooses them.
Command Action
Undo Reverse the effect of the previous operation. You should add the
name of the last operation to the Undo command. For example,
change the item to read Undo Typing if the user just finished
entering some text in a document. If your application cannot
undo the previous operation, disable this menu item and change
the phrase to Can’t Undo.
Cut Remove the data in the current selection, if any. Store the cut
selection in the scrap (on the Clipboard). This replaces the
previous contents of the scrap.
Copy Copy the data in the current selection, if any. Copy the selection
to the scrap (the Clipboard). This replaces the previous contents
of the scrap.
Paste Paste the data from the scrap at the insertion point; this replaces
any current selection.
Clear Remove the data in the highlighted selection; do not copy the
data to the scrap (Clipboard).
Select All Highlight all data in the document.
Create Publisher... Display the Create Publisher dialog box (using the Edition
Manager). Create an edition based on the selected data if the
user clicks the Publish button.
Subscribe To... Display the Subscribe To dialog box (using the Edition
Manager). Allow the user to insert data from an edition if the
user clicks the Subscribe button.
Publisher Options... Display the Publisher Options dialog box (using the Edition
Manager) and allow the user to set or change options associated
with the publisher. Change this menu item to Subscriber
Options if the current selection includes a subscriber. When the
user chooses the Subscriber Options command, display the
Subscriber Options dialog box.
Show Clipboard Display the contents of the Clipboard in a window. Change
this item to Hide Clipboard when the Clipboard window is
showing. When the user chooses Hide Clipboard, hide the
window displaying the Clipboard contents and change the
menu item to Show Clipboard.
The Undo, Cut, Copy, Paste, and Select All commands have the keyboard equivalents
shown in Figure 3-12 on page 3-24. These keyboard equivalents are reserved for these
menu commands; do not assign these keyboard equivalents to any menu command other
than the ones shown in Figure 3-12. See the chapter “Scrap Manager” in Inside Macintosh:
More Macintosh Toolbox for information on copying data to and from the scrap. See the
Menu Manager
In the Font menu, you can use dashes to indicate that the selection contains more than
one font. (Place a checkmark next to an item if the entire selection contains only one font.)
If the current selection contains more than one font, place a dash next to the name of each
font that the selection contains. See “Changing the Mark of Menu Items” on page 3-61 for
information on adding dashes and checkmarks to a menu item.
Menu Manager
Figure 3-14 shows the use of dashes to indicate that a selection contains more than one
font. In this figure, part of the selection contains a Helvetica® font and part of the
selection contains a Palatino font.
Figure 3-14 A Font menu showing a selection containing more than one font
Menu Manager
Your application should also provide a method that allows users to choose any point size.
You can add an Other command to the end of the Size menu for this purpose. When the
user chooses this command, display a dialog box that allows the user to choose any
available font size. You can include an editable text item in which the user can type the
desired font size. Figure 3-16 shows a dialog box an application might display when the
user chooses the Other command from the Size menu.
Figure 3-16 A dialog box to select a new point size for a font
Figure 3-17 shows the Other dialog box after the user has entered a new font size
of 31.
Menu Manager
If the user enters a font size not currently in the menu, your application should add a
checkmark to the Other menu command and include the font size as part of the text of
the Other command. You should show the font size in parentheses after the text Other,
as shown in Figure 3-18.
If a selection contains more than one nonstandard size, you should include the text
Mixed in parentheses following the word Other. In this case leave the editable text field
of the Other dialog box blank when the user chooses the Other (Mixed) command.
See “Handling a Size Menu” on page 3-82 for more information on how to respond to the
user’s choice of a command from the Size menu. See the chapter “Dialog Manager” for
information on creating a dialog box.
Menu Manager
command from the Apple menu, you should instead append a command for your own
help to the Help menu. This gives users one consistent place to obtain help information.
When adding your own items to the Help menu, include the name of your application in
the command so that users can easily determine which application the help relates to.
Figure 3-19 shows the Help menu for the SurfWriter application. This application
appends one item to the end of the standard Help menu: SurfWriter Help. When the
user chooses this item, the application provides access to any application-specific
help information.
You add items to the Help menu by using the HMGetHelpMenuHandle function and the
AppendMenu procedure. Apple reserves the right to change the number of standard
items in the Help menu. You should always append any additional items to the end. See
“Adding Items to the Help Menu” on page 3-67 for specific examples.
The user turns Balloon Help on or off by choosing Show Balloons or Hide Balloons from
the Help menu. The Help Manager automatically enables or disables Balloon Help when
the user chooses Show Balloons or Hide Balloons from the Help menu. The setting of
help is global and affects all applications.
When the user turns on Balloon Help, the Help Manager displays small help balloons as
the user moves the cursor over areas such as scroll bars, buttons, menus, or rectangular
areas in windows or dialog boxes that have help information associated with them.
Help balloons are rounded-rectangle windows that contain explanatory information for
the user.
The Help Manager provides help balloons for the menu titles of the Apple, Help,
Application, and Keyboard menus. The Help Manager also provides help balloons for
menu items in the Application and Keyboard menus, for any item from the Apple Menu
Items folder in the Apple menu, and for the standard items in the Help menu. The Help
Manager provides these help balloons only if your application uses the standard menu
definition procedure.
Your application should provide the content of help balloons for all other menu items
and menus in your application.
Figure 3-20 shows the default help balloons for the Apple menu title and Application
menu title.
Menu Manager
Figure 3-20 Default help balloons for the Apple menu and Application menu
Figure 3-21 shows help balloons for an application’s Cut command when it is enabled
and when it is disabled.
Figure 3-21 Help balloons for different states of the Cut command
Your application can provide the content for help balloons for your menus and menu
items. You define the help balloons for your application using 'hmmu' resources.
For information on how to define the help balloons for your application’s menus
in 'hmmu' resources, see the chapter “Help Manager” in Inside Macintosh: More Macintosh
Toolbox.
Menu Manager
Script
Active keyboard layout boundary
MM-05 (MM-05.a)
Figure 3 22 Acccessing the keyboard menu from an application
Menu Manager
When the user chooses an item from the Keyboard menu, the Menu Manager handles it
appropriately. For example, if the user chooses a different keyboard layout in a different
script, the Menu Manager changes the current keyboard layout and script system to the
item chosen by the user. See Inside Macintosh: Text for further information on supporting
text and handling text in multiple scripts in your application.
Pop-Up Menus 3
You can use pop-up menus to present the user with a list of choices in a dialog box or
window. Pop-up menus are especially useful in dialog boxes that require the user to
select one choice from a list of many or to set a specific value.
In System 7, the standard pop-up menu is implemented by a control definition function.
This section explains how the standard pop-up control definition function provides
support for pop-up menus. The chapter “Control Manager” in this book explains controls
in detail.
Menu Manager
A pop-up menu appears as a rectangle with a one-pixel border and a one-pixel drop
shadow. Pop-up menus are identified by a downward-pointing triangle that appears
in the pop-up box. The title of the pop-up menu appears next to the pop-up box.
Figure 3-24 shows a pop-up menu.
Pop-up Pop-up
title box
To display a pop-up menu, the user presses the mouse button while the cursor is over the
pop-up title or pop-up box. If the pop-up menu is in a dialog box and your application
uses the Dialog Manager, the Dialog Manager uses the pop-up control definition function
to display the pop-up menu and to handle all user interaction in the pop-up menu. If the
pop-up menu is in one of your application’s windows, your application needs to
determine which control the cursor was in when the user pressed the mouse button. Your
application can then use the Control Manager routines to display the pop-up menu and
to handle user interaction in the control.
Just like MenuSelect, the pop-up control definition function highlights the pop-up
menu title and highlights menu items appropriately as the user drags the cursor through
the menu items. The pop-up control definition function also highlights the default
(current) menu item when the pop-up menu is first displayed and adds the checkmark to
the menu item. Once the user releases the mouse button, the pop-up control definition
function causes the chosen item (if any) to blink, unhighlights the menu title, changes the
text in the pop-up box, and stores the item number of the chosen item as the value of the
control. Your application can use the Control Manager function GetControlValue to
get the menu item chosen by the user.
Figure 3-25 shows a pop-up menu in its closed state (as it appears initially to the user)
and its open state (as it appears when the user presses the mouse button while the cursor
is in the pop-up menu).
If you don’t provide a title for a pop-up menu, the current menu item serves as the title.
In most cases you should create pop-up menus that have titles. Choose a title that reflects
the contents of the menu or indicates the purpose of the menu.
Menu Manager
Figure 3-26 shows the process of a user making a selection from a pop-up menu.
1. 2.
3. 4.
In step 1 in Figure 3-26, the user presses the mouse button while the cursor is over the
pop-up box. When this occurs, your application can use the Dialog Manager or Control
Manager to call the pop-up control definition function. In step 2, the pop-up control
definition function highlights the title of the pop-up menu, removes the downward-
pointing triangle from the pop-up box, adds a checkmark to the current item, highlights
the current item, and displays the contents of the pop-up menu. In step 3, the pop-up
control definition function handles all user interaction, highlighting and unhighlighting
menu items, until the user releases the mouse button. When the user releases the mouse
button, the pop-up control definition function closes the pop-up menu, unhighlights the
pop-up menu title, sets the text of the pop-up box to the item chosen by the user, and
stores the item number of the chosen item as the value of the control. Step 4 shows the
appearance of the closed pop-up menu after the pop-up control definition function
performs these actions.
If your application does not use the standard pop-up control definition function, you
can create your own control definition function and you can choose to use the
PopUpMenuSelect function to help your application handle pop-up menus. In this case,
when the user presses the mouse button when the cursor is in a pop-up menu,
your application should call the PopUpMenuSelect function. Your application must
Menu Manager
If you need to show only a few choices, you may find that using checkboxes or radio
buttons is more appropriate for your application. For example, in Figure 3-27 the
selection of columns is implemented with radio buttons rather than a pop-up menu.
Whenever possible, you should show all available choices to the user. Note that in this
example the amount of space occupied by the radio buttons is about the same as the
amount of space required for a corresponding pop-up menu.
Use pop-up menus to allow the user to choose one option from a set of many choices.
Don’t use a pop-up menu for multiple-choice lists where the user can make more than
one selection. If you do, the text in the menu box will not fully describe the selections in
effect. For example, don’t use a pop-up menu for font style selections. In a dialog box,
font style selections are more appropriately implemented as checkboxes. Figure 3-28
shows a dialog box that uses checkboxes instead of a pop-up menu to allow the user to
select more than one font style. The Size and Font choices are implemented as pop-up
menus in this example, since the user can choose only one size and one font from a list
of many.
Menu Manager
Never use a pop-up menu as a way to provide more commands. Pop-up menus should
not contain actions (verbs) but can contain attributes (adjectives) or settings that allow
the user to choose one from many. For these reasons, you should not use Command-key
equivalents for pop-up menu items.
Your application can also use type-in pop-up menus when appropriate. Use a type-in
pop-up menu to give the user a list of choices and to allow the user to type in an
additional choice. The standard pop-up control definition function that implements
pop-up menus does not provide specific support for type-in menus. You can create your
own control definition function to handle type-in pop-up menus. If you do so, your
type-in pop-up menu should adhere to the guidelines described here. Figure 3-29 shows
a typical type-in pop-up menu in its closed and open states.
Figure 3-29 A type-in pop-up menu in its closed and open states
Your application is responsible for drawing and highlighting the type-in field of the
pop-up menu. Your application does not need to highlight the title of a type-in pop-up
menu; your application should highlight the type-in field instead.
If the user types in a value that is already in the menu, make that item the current item. If
the user types a value that does not match any of the items in the pop-up menu, add the
item to the top of the menu and add a divider below the item to separate it from the rest
of the standard items. Figure 3-30 on the next page shows a type-in pop-up menu with a
user’s choice added to it.
Menu Manager
A type-in pop-up menu should allow the user to type in a single additional choice. That
is, a standard type-in pop-up menu does not accumulate the user’s choices in the menu.
For example, if the user types in a value of 13, then types in a new choice, such as 43, the
menu should appear as shown in Figure 3-30, except that the type-in field and menu item
that previously contained 13 is replaced by 43.
A type-in pop-up menu should also allow the user to type in any of the standard values
in the menu or choose any of the standard items in the pop-up menu. If the user types in
or chooses any of the standard items, you should remove any user-specified item
previously added to the menu. For example, as shown in Figure 3-30, the user specified a
nonstandard size of 13. If the user then types in or selects 9, your application should
return the pop-up menu to its standard state, as shown in Figure 3-29 on page 3-37.
Hierarchical Menus 3
A hierarchical menu is a menu that has a submenu attached to it. Hierarchical menus can
be useful when your application needs to offer additional choices to the user without
taking up extra space in the menu bar. If you use a hierarchical menu in your application,
use it to give the user additional choices or to choose attributes, not to choose additional
commands.
In a hierarchical menu, a menu item serves as the title of a submenu; this menu item
contains a triangle to identify that the item has a submenu. The triangle appears in the
location of the keyboard equivalent. The title of a submenu should represent the choices
it contains. Figure 3-31 shows a menu with a submenu whose menu title is Label Style.
When a user drags the cursor through a hierarchical menu and rests the cursor on a menu
item that has a submenu, the Menu Manager displays the submenu after a brief delay.
The title of the submenu remains highlighted while the user browses through the
submenu; the Menu Manager unhighlights the menu title of the submenu when the user
releases the mouse button.
Hierarchical menus are useful for providing lists of related items, such as font sizes and
font styles. Never use more than one level of hierarchical menus (in other words, don’t
attach a submenu to another submenu). You can assign keyboard equivalents to the
menu items of a submenu; however, if you do so, you make it harder for the user to
quickly scan all menus for their keyboard equivalents.
Menu Manager
Menu Manager
Menu Manager
The current menu list contains handles to the menu records of all menus in the current
menu bar and the menu records of any submenus or pop-up menus that you have
inserted into the current menu list. Your application typically creates a menu list using
GetNewMBar, and it then sets the current menu list to its newly created menu list using
SetMenuBar. You can insert other menus in the current menu list using the GetMenu
function and InsertMenu procedure.
The Menu Manager displays the menu bar and the titles of all pull-down menus that
are defined in the current menu list when your application calls the DrawMenuBar
procedure. The Menu Manager displays the menus in the menu bar in the same order
that they appear in the current menu list.
The Menu Manager provides routines for adding menus to and removing menus from
the current menu list; your application should never access a menu list directly. To refer
to a menu list, use the handle returned by GetNewMBar or GetMenuBar.
The Menu Manager inserts the Help menu, the Keyboard menu if necessary, and the
Application menu into your application’s menu list if your application calls the
GetNewMBar function and your menu bar includes an Apple menu; your application
then uses SetMenuBar to set the current menu list to the newly created menu list. The
Menu Manager also inserts these menus into your application’s current menu list if your
application inserts the Apple menu into the current menu list using the InsertMenu
procedure. Therefore, you should not make any assumptions about the last menu (or
menus) in your application’s current menu list.
When your application inserts a submenu into the current menu list, the Menu Manager
stores a handle to the menu record of the submenu in the submenu portion of the current
menu list. Similarly, when your application inserts a pop-up menu into the current menu
list, the Menu Manager stores a handle to the menu record of the pop-up menu in the
submenu portion of the current menu list.
Menu Manager
Your application needs to initialize QuickDraw, the Font Manager, and the Window
Manager before using the Menu Manager. Your application can accomplish this using the
InitGraf, InitFonts, and InitWindows procedures. To initialize the Menu Manager,
use the InitMenus procedure.
If your application uses pop-up menus, use the Gestalt function with the
gestaltPopUpAttr selector to determine if the control definition function for
pop-up menus is available. See Inside Macintosh: Operating System Utilities for information
about the Gestalt function.
To create the pull-down menus in your application’s menu bar, you need to
■ create descriptions of each pull-down menu in 'MENU' resources
■ create an 'MBAR' resource that lists the order and resource ID of each menu
■ use the GetNewMBar function and SetMenuBar procedure to set up your menu bar
and use the DrawMenuBar procedure to draw your menu bar
The next section, “Creating a Menu,” explains these steps in detail.
After creating your application’s menu bar, you can enable or disable your menu items,
add marks such as checkmarks or dashes to menu items, or add items to any of your
menus as needed. See “Enabling and Disabling Menu Items” on page 3-58, “Changing
the Mark of Menu Items” on page 3-61, and “Adding Items to a Menu” beginning on
page 3-64 for information on these topics.
“Handling User Choice of a Menu Command,” beginning on page 3-70, shows how to
handle mouse-down events in the menu bar, adjust the menus of your application, and
determine if the user chose a keyboard equivalent of a command.
“Responding When the User Chooses a Menu Item,” beginning on page 3-78, describes
how your application should respond once the user chooses an item and also shows how
to handle the user’s choice of a command from the Apple and Help menus.
If your application displays dialog boxes, see “Accessing Menus From a Dialog Box”
beginning on page 3-84.
Finally, if your application needs to create submenus or pop-up menus, see “Creating a
Hierarchical Menu” on page 3-53 and “Creating a Pop-Up Menu” on page 3-56.
Creating a Menu 3
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:
■ 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 the
GetNewMBar function to read in descriptions of your menu bar and menus and create
a new menu list, use the SetMenuBar procedure to set the current menu list to your
application’s menu list, and use the DrawMenuBar procedure to update the menu bar.
■ You can create descriptions of your application’s menus in 'MENU' resources, read
them in using GetMenu, add them to the current menu list using InsertMenu, and
update the menu bar using DrawMenuBar.
Menu Manager
■ You can use NewMenu to create new empty menus; use AppendMenu,
InsertMenuItem, InsertResMenu, or AppendResMenu to fill the menus with
menu items; add the menus to the current menu list using InsertMenu; and update
the menu bar using DrawMenuBar.
Whenever possible you should define your menus in menu ('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 using GetNewMBar (if you also provide an 'MBAR' resource). To read in the
description of the submenu and insert it in the current menu list, use the GetMenu
function and InsertMenu 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, or AppendResMenu. 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-53 describes how to create a menu that has a submenu,
and “Creating a Pop-Up Menu” on page 3-56 describes how to create pop-up menus.
Listing 3-1 Rez input for a 'MENU' resource for the Apple menu
Menu Manager
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-31 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.
Menu Manager
After the resource ID of the menu definition procedure is a 32-bit number (expressed as
a 31-bit field followed by a Boolean 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 or
DisableItem 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 the DisableItem or
EnableItem procedure. When you disable a menu using the DisableItem 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 the apple 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-46 summarizes how
the Menu Manager interprets these item characteristics.
Menu Manager
Table 3-6 Specifying submenus, script codes, reduced icons, small icons, and color icons of a
menu item in a menu resource
Keyboard
equivalent Marking
field Icon field character field Description
$1B Menu ID of Indicates the item has a submenu. The
submenu marking character field specifies the
menu ID of the submenu.
$1C Script code of item Indicates the item text uses the script
text defined by the script code specified in the
icon field.
$1D Icon number of Indicates the item has an icon defined by an
'ICON'resource 'ICON' resource and that it should be
reduced to fit in a 16-by-16 bit rectangle.
$1E Icon number Indicates the item has an icon defined by an
of 'SICN' 'SICN' resource.
resource
$00 or >$20 Icon number of Indicates the item has an icon defined
'ICON' or by an 'ICON' or a 'cicn'resource.
'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 the nokey 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,
Menu Manager
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 the hierarchicalMenu constant in place of the nokey 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 the nokey 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 the nokey 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 the noicon 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 the nomark constant in your resource
definition. If the menu item has a submenu, then specify the menu ID of the submenu in
place of the nomark 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 the GetMenu function and InsertMenu procedure
to do this. “Creating a Hierarchical Menu,” which begins on page 3-53, gives information
on attaching a submenu to its menu.
To assign a font style to a menu item, in your 'MENU' resource use the constants bold,
italic, plain, outline, and shadow 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 the
AppendResMenu 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-68 for
more information.
Once you create a menu, you can append additional items to it using the AppendMenu,
InsertMenuItem, InsertResMenu, or AppendResMenu 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-57 for more information.
Menu Manager
Figure 3-12 on page 3-24 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
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
Menu Manager
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
Menu Manager
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.
CONST
rMenuBar = 128;
VAR
menuBar: Handle;
Use the SetMenuBar procedure to set the current menu list to the menu list created
by your application and the DrawMenuBar 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.
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}
Menu Manager
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 uses SetMenuBar 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 the AppendResMenu
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 to GetMenuHandle, and GetMenuHandle 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-74 shows the application-defined
MyAdjustMenus procedure used in Listing 3-5.) After adjusting the menus, the code in
Listing 3-5 uses DrawMenuBar 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 the GetNewMBar function to read the
resource definitions. However, you can choose to read in a 'MENU' resource using the
GetMenu function or to create a new empty menu using NewMenu. You can then insert
a menu into the current menu list using the InsertMenu 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 and
InsertMenu procedure to make these menus available to your application. See
“Creating a Hierarchical Menu” on page 3-53 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-56 for information on
creating pop-up menus.
Menu Manager
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 the SetMCEntries 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 calling GetNewMBar and call SetMCInfo 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.
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;
Menu Manager
When a user drags the cursor through a menu and rests it on a menu item with a
submenu attached to it, the Menu Manager displays the submenu after a brief delay.
The title of the submenu remains highlighted while the user browses through the
submenu; the Menu Manager unhighlights the menu title of the submenu when the
user releases the mouse button.
Your application is responsible for placing any marks next to the current choice or
attribute of the submenu. For example, in Figure 3-32 the application placed the
checkmark next to the Numeric menu item to indicate the current choice. If the user
makes a new choice from the menu, your application should update the menu items
accordingly.
You can specify that a particular menu item has a submenu by identifying this
characteristic (using the hierarchicalMenu constant) when you define the menu item
in its 'MENU' resource. You cannot assign keyboard equivalents to a menu item that has
a submenu. (You can define keyboard equivalents for the menu items in the submenu,
but this is not recommended.) You identify the menu ID of the submenu in place of the
marking character in the menu item’s resource description. Thus, a menu item that has a
submenu cannot have a marking character and cannot have a keyboard equivalent.
Menu Manager
To insert a submenu into the current menu list, you must use the InsertMenu
procedure. The GetNewMBar function does not read in the resource descriptions of
any submenus.
Listing 3-7 shows the 'MENU' resource for an application-defined menu called Outline.
The Outline menu contains a number of menu items, including the Label Style menu
item. The description of this menu item contains the constant hierarchicalMenu,
which indicates that the item has a submenu. This menu item description also contains
the menu ID of the submenu (defined by the mSubMenu constant). The menu ID of a
submenu of an application must be from 1 through 235; the menu ID of a submenu of a
desk accessory must be from 236 through 255.
The submenu is defined by the menu with the menu ID specified by the Label Style menu
item. You define the menu items of a submenu in the same way as you would a
pull-down menu (except you shouldn’t define keyboard equivalents for items in a
submenu, and you shouldn’t attach a submenu to another submenu).
Listing 3-7 Rez input for a description of a hierarchical menu with a submenu
Menu Manager
When you use GetNewMBar to read in menu descriptions and create a new menu list,
GetNewMBar records the menu ID of any submenu in the menu record but does not read
in the description of the submenu. To read a description of a submenu, use the GetMenu
function. To actually insert a submenu into the current menu list, you must use the
InsertMenu procedure.
When needed, your application can use the GetMenu function to read a description of
the characteristics of a menu from a 'MENU' resource. The GetMenu function creates a
menu record for the menu, allocating space for the menu record in your application’s
heap. The GetMenu function creates the menu and menu items (and fills in the menu
record) according to its 'MENU' resource. The GetMenu function does not insert the
menu into a menu list. When you’re ready to add it to the current menu list, use the
InsertMenu procedure.
Listing 3-8 uses the GetMenu function to read the description of a submenu and uses the
InsertMenu procedure to insert the menu into the current menu list.
Menu Manager
To insert a submenu into the current menu list using the InsertMenu procedure, specify
–1 in the second parameter to insert the menu into the submenu portion of the menu list.
As the user traverses menu items, if a menu item has a submenu the MenuSelect
function looks in the submenu portion of the menu list for the submenu; it searches for a
menu with a defined menu ID that matches the menu ID specified by the hierarchical
menu item. If it finds a menu with a matching menu ID, it attaches the submenu to the
menu item and allows the user to browse through the submenu.
To create a pop-up menu, create a control that uses the pop-up control definition
function, define the pop-up menu and its menu items, and associate the control with a
window or dialog box. You can use Dialog Manager or Control Manager routines to
display pop-up menus.
For example, if you define a modal dialog box that contains a pop-up control and use the
Dialog Manager to display and help handle events in the dialog box, the Dialog Manager
automatically uses the pop-up control definition function to draw the control and also to
handle user interaction when the user presses the mouse button while the cursor is over a
pop-up control.
If your application defines a control in one of your application’s windows, you can use
TrackControl and other Control Manager routines to handle the pop-up menu.
The pop-up control definition function draws a box around the pop-up box, draws the
drop shadow, inserts the text into the pop-up box, draws the downward-pointing
triangle, and draws the pop-up title. When a dialog box contains a control that uses the
Menu Manager
pop-up control definition function and the user presses the mouse button while the
cursor is in the pop-up control, the pop-up control definition function highlights the
pop-up menu title, displays the pop-up menu, and handles all user interaction until the
user releases the mouse button. When the user releases the mouse button, the pop-up
control definition function closes the pop-up box, draws the user’s choice in the pop-up
box (or restores the previous item if the user did not make a new choice), stores the user’s
choice as the value of the control, and unhighlights the pop-up menu title. Your
application can use the Control Manager function GetControlValue to get the value of
the control and to determine the currently selected item in the pop-up menu.
To create a pop-up control, create a control and specify that the control uses the pop-up
control definition function by specifying the popupMenuProc constant:
CONST popupMenuProc = 1008; {pop-up menu control}
If you specify popupMenuProc (plus any appropriate variation code) as the procID
field of the resource description of a control, when your application creates the control
(by using the Dialog Manager or by using GetNewControl) the Control Manager creates
the pop-up control, which includes the pop-up title and the pop-up box with a one-pixel
drop shadow. The appearance of the pop-up title and the values in the menu are
controlled by other values stored in the resource (or other parameters passed to
NewControl). See the chapter “Control Manager” in this book for information on
the NewControl function.
If your application does not use the standard pop-up control definition function, you
can create your own control definition function to implement pop-up menus. In this
case you can use the PopUpMenuSelect function to draw the pop-up menu and track
the cursor within the menu. Your application is responsible for highlighting the title of
the pop-up menu before calling PopUpMenuSelect and unhighlighting the title
afterward (to duplicate the behavior of menu titles in the menu bar). Your application
must also set the mark of the items in the pop-up menu as appropriate if you use the
PopUpMenuSelect function.
For more information on creating controls, see the chapter “Control Manager” in this
book. For listings that define the dialog box shown in Figure 3-33, see the chapter “Dialog
Manager” in this book.
Menu Manager
VAR
menu: MenuHandle;
Menu Manager
If you disable or enable an entire menu, call DrawMenuBar when you need to update the
menu bar’s appearance. If you do not need to update the menu bar immediately, you can
use the InvalMenuBar procedure instead of DrawMenuBar, thus reducing flickering in
the menu bar. Rather than drawing the menu bar twice as in the previous example, you
can use InvalMenuBar instead of DrawMenuBar, causing the Event Manager to redraw
the menu bar the next time it scans for update events. The InvalMenuBar procedure is
available in System 7 and later. See page 3-114 for additional details on the
InvalMenuBar procedure.
PROCEDURE MyToggleHideShow;
VAR
myMenu: MenuHandle;
item: Integer;
itemString: Str255;
BEGIN
myMenu := GetMenuHandle(mEdit);
item := iToggleHideShow;
IF gToggleState = kShow THEN
BEGIN
GetIndString(itemString, kMyStrings, kShowClipboard);
gToggleState := kHide;
END
Menu Manager
ELSE
BEGIN
GetIndString(itemString, kMyStrings, kHideClipboard);
gToggleState := kShow;
END;
SetMenuItemText(myMenu, item, itemString);
END;
Note that if you use the SetMenuItemText procedure, you should define the text of the
menu item in a string resource or string list resource (for example, using an 'STR ' or
'STR#' resource). This makes your application easier to localize.
TYPE
StyleItem = (bold, italic, underline, outline, shadow,
condense, extend);
Style = SET OF StyleItem;
You can set the style of a menu item to zero, one, or more than one of the styles defined
by the StyleItem data type. You can set the style of a menu item to the empty set to
obtain the plain font style.
Listing 3-10 shows code that sets the style of menu items listed in an application’s
Style menu.
VAR
menu: MenuHandle;
itemStyle: Style;
To get the style of a menu item, you can use the GetItemStyle procedure.
Menu Manager
As another example of the use of marks in menus, Listing 3-11 shows code that sets the
mark of items in an application-defined Directory menu. It sets the marking character of
the menu item of the last directory accessed to a checkmark, sets the marking character of
the second-last directory accessed to the diamond mark, and removes the mark from the
third-last directory accessed.
Listing 3-11 Adding marks to and removing marks from menu items
VAR
menu: MenuHandle;
itemMark: Char;
{get handle to Directory menu}
menu := GetMenuHandle(mDirectory);
itemMark := CHR(checkMark);
SetItemMark(menu, gLastDir, itemMark); {set mark to checkmark}
itemMark := CHR(diamondMark);
SetItemMark(menu, gOldLastDir, itemMark); {set mark to diamond}
itemMark := CHR(noMark);
SetItemMark(menu, gSecondLastDir, itemMark);{remove any mark}
Menu Manager
You can also set the mark of a menu item to a checkmark using the CheckItem
procedure:
VAR
menu: MenuHandle;
{get handle to Directory menu}
menu := GetMenuHandle(mDirectory);
CheckItem(menu, gLastDir, TRUE); {set to checkmark}
CheckItem(menu, gSecondLastDir, FALSE);{remove checkmark or }
{ any other mark}
Menu Manager
The Menu Manager automatically fits the icon in the menu item according to your
specifications. If the Menu Manager uses a 'cicn' resource, it automatically enlarges the
enclosing rectangle of the menu item according to the rectangle specified in the 'cicn'
resource. If the Menu Manager uses an 'ICON' resource and the item specifies the
nokey constant as the keyboard equivalent, the Menu Manager enlarges the rectangle of
the menu item to fit the 32-by-32 bit 'ICON' resource. You can request that the Menu
Manager reduce an 'ICON' resource to the size of a 16-by-16 bit small icon by specifying
a value of $1D as the item’s keyboard equivalent. To request that the Menu Manager use
an 'SICN' resource instead of an 'ICON' resource, specify a value of $1E as the item’s
keyboard equivalent.
This code sets the icon of a menu item to a specified icon.
VAR
menu: MenuHandle;
itemIcon: Byte;
itemIcon := 5;
menu := GetMenuHandle(mWeather);
{set the icon for this item in the Weather menu}
SetItemIcon(menu, iBeachWeather, itemIcon);
Listing 3-12 shows the Rez description of three menu items, each of which contains icons.
The first menu item has an icon with resource ID 261 (5 plus 256) and is defined by a
resource type of either 'cicn' or 'ICON'. The second menu item has an icon with
resource ID 262 (6 plus 256) and is identified by either a 'cicn' resource or an 'ICON'
resource; however, in this case, the value of $1D requests the Menu Manager to reduce
the 'ICON' resource to a small icon. The third menu item has an icon with resource ID
263 (7 plus 256) and is defined by either a 'cicn' resource or an 'SICN' resource.
Menu Manager
0b0000000000000000001011101100111,
enabled, “Weather",
{
"Beach Weather", /*item has icon or color icon */
/* with icon number 5*/
5, nokey, nomark, plain;
"Ski Weather", /*item has reduced icon or color */
/* icon with icon number 6*/
6, $1D, nomark, plain;
"Kite-Flying Weather",/*item has small icon or */
/* color icon with icon number 7*/
7, $1E, nomark, plain
}
};
See the chapter “Finder Interface” in this book for details on how to create icons.
Menu Manager
You specify a handle to the menu record of the menu to which you want to add the item
or items, and you specify a string describing the items to add as parameters to the
AppendMenu or InsertMenuItem procedure. The string you pass to these procedures
should consist of the text and any characteristics of the menu items. You can specify a
hyphen as the menu item text to create a divider line. You can also use various
metacharacters in the text string to separate menu items and to specify certain
characteristics of the menu items. The metacharacters aren’t displayed in the menu.
Here is a list of the metacharacters you can use in the text string that you specify to the
AppendMenu or InsertMenuItem procedure:
Metacharacter Description
; or Return Separates menu items.
^ When followed by an icon number, defines the icon for the item. If the
keyboard equivalent field contains $1C, this number is interpreted as
a script code.
! When followed by a character, defines the mark for the item. If the
keyboard equivalent field contains $1B, this value is interpreted as
the menu ID of a submenu of this menu item.
< When followed by one or more of the characters B, I, U, O, and S,
defines the character style of the item to Bold, Italic, Underline,
Outline, or Shadow, respectively.
/ When followed by a character, defines the keyboard equivalent for the
item. When followed by $1B, specifies that this menu item has a
submenu. To specify that the menu item has a script code, small icon,
or reduced icon, use the SetItemCmd procedure to set the keyboard
equivalent field to $1C, $1D, or $1E, respectively.
( Defines the menu item as disabled.
You can specify any, all, or none of these metacharacters in the text string to define the
characteristics of a menu item. Note that the metacharacters that you specify aren’t
displayed in the menu item. (To use any of these metacharacters in the text of a menu
item, first use AppendMenu or InsertMenuItem, specifying at least one character as the
item’s text. Then use the SetMenuItemText procedure to set the item’s text to the
desired string.)
Note
If you add menu items using the AppendMenu or InsertMenuItem
procedure, you should define the text and any marks or keyboard
equivalents in resources for easier localization. ◆
Listing 3-13 shows a string list ('STR#') resource that stores the text of the menu items
used in the next examples.
Menu Manager
Here’s code that uses the AppendMenu procedure to append a menu item with no
specific characteristics other than its text to the menu identified by the menu handle in
the myMenu variable. The text for the menu item is “Just Text” as stored in the 'STR#'
resource with resource ID 300.
VAR
myMenu: MenuHandle;
itemString: Str255;
myMenu := GetMenuHandle(mLibrary);
GetIndString(itemString, 300, 1);
AppendMenu(myMenu, itemString);
To insert an item after a given menu item, use the InsertMenuItem procedure. For
example, this code inserts the menu item Pick a Color after the menu item with the item
number specified by the iRed constant. The text for the new menu item consists of the
string “Pick a Color…” as stored in the 'STR#' resource with resource ID 300.
VAR
myMenu: MenuHandle;
itemString: Str255;
myMenu := GetMenuHandle(mColors);
GetIndString(itemString, 300, 2);
InsertMenuItem(myMenu, itemString, iRed);
If you do not explicitly specify a value for an item characteristic in the text string that you
pass to AppendMenu or InsertMenuItem, the procedure assigns the default value for
that characteristic. The Menu Manager defines the default item characteristics as no icon,
no marking character, no keyboard equivalent, and plain text style. AppendMenu and
InsertMenuItem enable the added menu items unless you specify otherwise.
This code appends a menu item with the text “Everything” to the menu identified by the
menu handle in the myMenu variable. The text and other characteristics of this menu item
are stored in the 'STR#' resource shown in Listing 3-13. It also specifies that this menu
Menu Manager
item is disabled, has an icon with resource ID 258 (2 + 256), and has the “=” character as a
marking character; the style of the text is Bold; and the menu item has a keyboard
equivalent of Command-E.
VAR
myMenu: MenuHandle;
itemString: Str255;
myMenu := GetMenuHandle(mLibrary);
GetIndString(itemString, 300, 3);
AppendMenu(myMenu, itemString);
This code appends multiple items to the Edit menu using AppendMenu:
VAR
myMenu: MenuHandle;
myMenu := GetMenuHandle(mEdit);
AppendMenu(myMenu, 'Undo/Z;-;Cut/X;Copy/C;Paste/V');
The InsertMenuItem procedure differs from AppendMenu in how it handles the given
text string when the text string specifies multiple items. The InsertMenuItem
procedure inserts the items in the reverse of their order in the text string. For example,
this code inserts menu items into the Edit menu using InsertMenuItem and is
equivalent to the previous example:
VAR
myMenu: MenuHandle;
myMenu := GetMenuHandle(mEdit);
InsertMenuItem(myMenu, 'Paste/V';Copy/C;Cut/X;-;Undo/Z',0);
Once you’ve added a menu item to a menu, you can change any of its characteristics
using Menu Manager routines, as described in “Changing the Appearance of Items in a
Menu” on page 3-57.
Menu Manager
PROCEDURE MyAddHelpItem;
VAR
myMenu: MenuHandle;
myErr: OSErr;
itemString: Str255;
BEGIN
myErr := HMGetHelpMenuHandle(myMenu);
IF myErr = noErr THEN
IF myMenu <> NIL THEN
BEGIN
{get the string (with index kSurfHelp) from the 'STR#' }
{ resource with resource ID kMyStrings}
GetIndString(itemString, kMyStrings, kSurfHelp);
AppendMenu(myMenu, itemString);
END;
END;
When you add items to the Help menu, the Help Manager automatically adds a divider
between the end of the standard Help menu items and your items.
Be sure to use an 'hmnu' resource and specify the kHMHelpMenuID constant as the
resource ID to provide help balloons for items you’ve added to the Help menu. (The Help
Manager automatically creates the help balloons for the Help menu title and the standard
Help menu items.) See the chapter “Help Manager” in Inside Macintosh: More Macintosh
Toolbox for specific information on the 'hmnu' resource.
The Help Manager automatically processes the event when a user chooses any of the
standard menu items in the Help menu. The Help Manager automatically enables and
disables help when the user chooses Show Balloons or Hide Balloons from the Help
menu. The setting of Balloon Help is global and affects all applications. See “Handling
the Help Menu” on page 3-81 for information on responding to the user when the user
chooses one of your appended items.
Menu Manager
After inserting the Apple menu into your application’s menu bar (by using GetNewMBar
or GetMenu and InsertMenu), your application can add items to it. Listing 3-15 shows
code that uses GetMenuHandle to get a handle to the application’s Apple menu. The
code then uses the AppendResMenu procedure, specifying that AppendResMenu should
add all desktop items in the Apple Menu Items folder to the application’s Apple menu.
VAR
myMenu: MenuHandle;
myMenu := GetMenuHandle(mApple);
IF myMenu <> NIL THEN
AppendResMenu(myMenu, 'DRVR');{add desktop items in the }
{ Apple Menu Items folder }
{ to the Apple menu}
Listing 3-16 on page 3-70 shows a complete sample that sets up an application’s menu
bar, adds items to the Apple menu, adds items to the Font menu, and then updates the
appearance of the menu bar.
Menu Manager
PROCEDURE MyMakeAllMenus;
VAR
menu: MenuHandle;
menuBar: Handle;
BEGIN
{read menus in & create new menu list}
menuBar := GetNewMBar(rMenuBar);
IF menuBar = NIL THEN
EXIT(MyMakeAllMenus);
SetMenuBar(menuBar); {insert menus into the current menu list}
DisposHandle(menuBar);
myMenu := GetMenuHandle(mApple);
IF myMenu <> NIL THEN {add desktop items in }
AppendResMenu(myMenu, 'DRVR'); { Apple Menu Items }
{ folder to Apple menu}
myMenu := GetMenuHandle(mFont);
IF myMenu <> NIL THEN
AppendResMenu(myMenu, 'FONT'); {add font names to the }
{ Font menu--this adds all bitmapped and TrueType fonts }
{ in the Fonts folder to the Font menu}
MyAddHelpItem; {add app-specific item to Help menu}
MyAdjustMenus; {adjust menu items}
DrawMenuBar; {draw the menu bar}
END;
Your application should indicate the current font to the user by placing the appropriate
mark next to the text of the menu item that lists the font name. (“Changing the Mark of
Menu Items” on page 3-61 explains how to add marks to and remove marks from menu
items; Figure 3-13 on page 3-26 and Figure 3-14 on page 3-27 show examples of typical
Font menus.)
If your application allows the user to change the font style or font size of text, you should
provide separate Size and Style menus. See “Handling a Size Menu” beginning on
page 3-82 for information on providing a Size menu in your application.
Menu Manager
For a command with a keyboard equivalent, your application should allow the user to
choose the command by pressing the keys that correspond to the keyboard equivalent
of that menu command. If the user presses the Command key and another key, your
application should adjust its menus and then call the MenuKey function to map this
combination to a keyboard equivalent. The MenuKey function returns as its function
result a value that indicates the corresponding menu and menu item of the keyboard
equivalent.
When the user chooses a menu command, your application should perform the action
associated with that command. The MenuSelect and MenuKey functions highlight the
menu title of the menu containing the chosen menu command. After your application
performs any operation associated with the menu command chosen by the user, your
application should unhighlight the menu title by using the HiliteMenu procedure.
However, if in response to a menu command your application displays a window that
contains editable text (such as a modal dialog box), you should unhighlight the menu
title immediately so that the user can access the Edit menu or other appropriate menus.
In other words, any time the user can use a menu, make sure that the menu title is
not highlighted.
When the user chooses a menu command that involves an operation that takes a long
time, display the animated wristwatch cursor or display a status dialog box to give the
user feedback that the operation is in progress.
If you want the users of your application to be able to record their actions (such as menu
commands, text input, or any sequence of actions) for later playback, your application
should send itself Apple events whenever a user performs a significant action. To do this
for menu commands, your application typically sends itself an Apple event to perform
the action associated with the chosen menu command. For example, when a user chooses
the New command from the File menu, your application can choose to send itself a
Create Element event. Your application then creates the new document in response to this
event. For information on sending Apple events in response to menu commands, see
Inside Macintosh: Interapplication Communication.
The next sections show how your application can
■ determine if the user pressed the mouse button while the cursor was in the menu bar
■ adjust its menus—enabling and disabling commands according to the current state of
the document—before displaying menus or before responding to the user’s choice of a
keyboard equivalent of a command
■ determine if the user chose the keyboard equivalent of a menu command
■ respond to the user when the user chooses a menu command
The next sections also show how your application should respond when the user chooses
an item from the Apple or Help menu.
Menu Manager
Menu Manager
You can use the FindWindow function to map the mouse location at the time the
user pressed the mouse button to general areas of the screen. If the mouse location
is in the menu bar, the FindWindow function returns the constant inMenuBar. In Listing
3-18, if the mouse location associated with the mouse-down event is in the
menu bar, the DoMouseDown procedure first calls another application-defined procedure,
MyAdjustMenus, to adjust the menus. Listing 3-19 shows the MyAdjustMenus
procedure.
The DoMouseDown procedure then calls an application-defined procedure,
DoMenuCommand. The DoMouseDown procedure passes as a parameter to
the DoMenuCommand procedure the value returned from the MenuSelect function.
The MenuSelect function displays menus and handles all user interaction until the user
releases the mouse button. The MenuSelect function returns a long integer indicating
whether the user chose a menu command, and if so, it indicates which menu and which
command the user chose.
Listing 3-24 on page 3-79 shows the DoMenuCommand procedure.
Menu Manager
PROCEDURE MyAdjustMenus;
VAR
window: WindowPtr;
windowType: Integer;
BEGIN
window := FrontWindow;
windowType := MyGetWindowType(window);
CASE windowType OF
kMyDocWindow:
BEGIN {document window is in front, adjust items appropriately}
MyAdjustFileMenuForDocWindow;
MyAdjustEditMenuForDocWindow;
{adjust other menus as needed}
END; {of adjusting menus for a document window}
kMyDialogWindow:
{adjust menus accordingly for any dialog box}
MyAdjustMenusForDialogs;
kDAWindow:{adjust menus accordingly for a DA window}
MyAdjustMenusForDA;
kNil:{adjust menus accordingly when there isn't a front window}
MyAdjustMenusNoWindows;
END; {of CASE}
DrawMenuBar;
END;
PROCEDURE MyAdjustFileMenuForDocWindow;
VAR
window: WindowPtr;
menu: MenuHandle;
myData: MyDocRecHnd;
BEGIN
window := FrontWindow;
3-74 Using the Menu Manager
C H A P T E R 3
Menu Manager
PROCEDURE MyAdjustEditMenuForDocWindow;
VAR
window: WindowPtr;
menu: MenuHandle;
selection, undo: Boolean;
isSubscriber: Boolean;
undoText: Str255;
offset: LongInt;
BEGIN
window := FrontWindow;
menu := GetMenuHandle(mEdit); {get a handle to the Edit menu}
IF menu = NIL THEN {add your own error handling}
EXIT (MyAdjustEditMenuForDocWindow);
undo := MyIsLastActionUndoable(undoText);
IF undo THEN {if action can be undone}
BEGIN
SetMenuItemText(menu, iUndo, undoText);
EnableItem(menu, iUndo);
END
Menu Manager
The procedure in Listing 3-21 adjusts the items in the Edit menu as appropriate for a
document window of the application. The code enables the Undo command if the
application can undo the last command, enables the Cut and Copy commands if there’s a
selection that can be cut or copied, enables the Paste command if there’s text data in the
Menu Manager
scrap, and enables the menu items relating to publishers and subscribers appropriately,
according to whether the current selection contains a publisher or subscriber. The
application-defined MySelectionContainsSubscriberOrPublisher function
returns TRUE if the current selection contains a single subscriber or a single publisher and
returns FALSE otherwise. If the MySelectionContainsSubscriberOrPublisher
function returns TRUE, the code sets the text for the Publisher Options (or Subscriber
Options) command and enables the menu item. If the function returns FALSE, the code
disables the Publisher Options (or Subscriber Options) command.
If your application determines that the user pressed a key, you need to determine whether
the user chose the keyboard equivalent of a menu command. You can do this by
examining the modifiers field of the event record describing the key-down event. If
the Command key was also pressed, then your application should call the MenuKey
function. The MenuKey function scans the current menu list for a menu item that has a
matching keyboard equivalent and returns the menu and menu item, if any. Although you
should not define the same keyboard equivalent for more than one command, the
MenuKey function scans the menus from right to left, scanning the items from top to
bottom, and returns the first matching keyboard equivalent that it finds.
Menu Manager
Listing 3-23 extracts the pressed key from the message field of the event record and
then examines the modifiers field to determine if the Command key was also pressed.
If so, the application first adjusts its menus and then calls an application-defined
procedure, DoMenuCommand. The DoKeyDown procedure passes as a parameter to
the DoMenuCommand procedure the value returned from the MenuKey function.
Listing 3-24 shows the DoMenuCommand procedure.
Menu Manager
not map to any keyboard equivalent in your application’s menus, the functions return 0
in the high word and the value of the low word is undefined. The MenuSelect function
also returns 0 in the high word when the user selects an item in the Application or
Keyboard menu. The MenuSelect function (and MenuKey function, if the command has
a keyboard equivalent) returns the kHMHelpMenuID constant in the high word and the
menu item in the low word when the user selects an item that your application appended
to the Help menu.
Listing 3-24 shows an application-defined procedure, DoMenuCommand. This procedure
takes the appropriate action based on which menu command the user chose.
The DoMenuCommand procedure is called by the application after the application
determines that either the user pressed the mouse button while the cursor was in the
menu bar (in which case the application calls MenuSelect to allow the user to choose
a command) or the user pressed the Command key and another key (in which case the
application calls the MenuKey function). In either case, the application passes the
function result returned by MenuSelect or MenuKey as a parameter to the
DoMenuCommand procedure.
Menu Manager
Listing 3-25 Responding to the user’s choice of an item from the Apple menu
When the user chooses an item other than your application’s About command from
the Apple menu, your application should call the OpenDeskAcc function. The
OpenDeskAcc function prepares to open the desktop object chosen by the user; for
example, if the user chose a document created by the TeachText application, the
OpenDeskAcc function schedules the TeachText application for execution (or prepares to
open it if it isn’t already open) and returns to your application. On your application’s
next call to WaitNextEvent, your application receives a suspend event, and then
Menu Manager
the Process Manager makes TeachText the foreground application and instructs TeachText
to open the chosen document.
Listing 3-26 Responding to the user’s choice of a command from the Help menu
Apple reserves the right to change the number of standard items in the Help menu. To
determine the number of items in the Help menu, call the CountMItems function.
Menu Manager
Menu Manager
When the user chooses the Other command, you should display the current font size in a
dialog box and allow the user to choose a new size. Figure 3-16 on page 3-28 shows a
sample dialog box an application might display in response to the user’s choice of the
Other command.
You should always specify the text of the Other command in the plain font style (as
shown in Figure 3-35) and never outlined, regardless of whether the current font is a
TrueType font that supports that size or a bitmapped font that exists at that size in the
Fonts folder.
Listing 3-27 shows an application-defined procedure that handles the user’s choice of an
item in the Size menu shown in Figure 3-35.
Menu Manager
If the user chooses an item from the Size menu, the MyHandleSizeCommand procedure
first counts the current number of items in the menu. If the user chooses the last item in
the menu (the Other command), the procedure displays a dialog box like the one shown
in Figure 3-16 on page 3-28 to let the user choose a size other than the ones currently
shown in the menu. The application-defined function MyDisplayOtherBox also adds a
checkmark to the Other command if the user chose a new size, adds the new size to the
text of the Other command, and returns the chosen size in the sizeChosen variable.
If the user chose the Larger or Smaller command from the Size menu, the code calls an
application-defined routine, DoMakeLargerOrSmaller, to perform the requested
action. The DoMakeLargerOrSmaller procedure also adds a checkmark and adds the
new size to the text of the Other command if the new size does not match any size in
the menu. The procedure returns the chosen size in the sizeChosen variable.
If the user chose any size currently displayed in the menu, the MyHandleSizeCommand
procedure adjusts the marking character of the menu items appropriately. The code
removes the checkmark from the previous menu item and adds a checkmark to the menu
item representing the new size chosen by the user. The code uses an application-defined
function, MyItemToSize, to map the item number of the chosen menu item to a given
size and returns this size in the sizeChosen variable.
The code then uses the application-defined procedure MyResizeSelection to update
the document’s state and resize the user’s selection, if any, to the chosen size.
Note
In System 6, user access to menus in the menu bar is prohibited from an
alert box or a modal dialog box unless your application specifically
allows it. For example, in System 6, your application must provide a
filter procedure to replace the standard filter procedure if you want to
support the keyboard equivalents of the standard Edit menu commands
in a modal dialog box. In System 7, you can let the Menu Manager enable
these commands for you. ◆
Menu Manager
When your application displays a modeless or movable modal dialog box, your
application should adjust its menus as appropriate for that dialog box. For example,
when a movable modal dialog box is the frontmost window, your application should
enable the Apple menu, enable the Edit menu if your dialog box contains an editable text
item, enable or disable any other menus as needed, and disable any items it added to the
Help menu if the user can’t perform those actions while the dialog box is displayed.
When your application displays an alert box, system software automatically disables all
of your application’s menus except for the Help menu (in which all items are disabled
except for the Show Balloons/Hide Balloons command).
When your application displays a modal dialog box, your application should also enable
and disable its menus as appropriate. For example, you should enable the Edit menu if
your dialog box contains an editable text item and disable any items it added to the Help
menu if the user can’t perform those actions while the dialog box is displayed. If your
application handles access to the menu bar from a modal dialog box, it should disable the
Apple menu or the first item in the Apple menu.
If your application does not specifically handle access to the menu bar from an alert box
or a modal dialog box, in some cases the Menu Manager automatically disables the
appropriate menus for you, as described in the following paragraphs.
When your application displays an alert box or a modal dialog box (that is, a window of
type dBoxProc), the Menu Manager (in conjunction with the Dialog Manager) always
appropriately adjusts the system-handled menus and performs these actions:
1. Disables all menu items in the Help menu except the Show Balloons (or Hide Balloons)
command, which it enables.
2. Disables all menu items in the Application menu.
3. Enables the Keyboard menu if it appears in the menu bar, except for the About
Keyboards command, which it disables.
Menu Manager
In addition, if your application then calls the ModalDialog procedure, the Menu
Manager (in conjunction with the Dialog Manager) performs two other actions:
4. Disables all of your application’s menus.
5. Enables commands with the standard keyboard equivalents Command-X,
Command-C, and Command-V if the modal dialog box contains a visible and active
editable text field. The user can then use either the menu commands or their keyboard
equivalents to cut, copy, and paste text. (The menu item having keyboard equivalent
Command-X must be one of the first five menu items.)
When the user dismisses the modal dialog box, the Menu Manager restores all menus to
the state they were in prior to the appearance of the modal dialog box.
In some cases actions 4 and 5 do not occur when you call ModalDialog. The enabling
and disabling described in steps 4 and 5 do not occur if any of these conditions is true:
■ Your application does not have an Apple menu.
■ Your application has an Apple menu, but the menu is disabled when the modal dialog
box is displayed.
■ Your application has an Apple menu, but the first item in that menu is disabled when
the dialog box is displayed.
Note
If your application already handles access to the menu bar from a
modal dialog box and you do not want the automatic menu enabling and
disabling provided by System 7 to occur, you should ensure that one or
more of those conditions is true when you display a modal
dialog box. ◆
When your application displays alert boxes or modal dialog boxes with no editable
text items, your application can allow system software to handle menu bar access. In
all other cases, your application should handle its own menu bar access.
System software always leaves the Help, Keyboard, and Application menus and their
commands available when you display movable modal dialog boxes and modeless
dialog boxes. For these types of dialog boxes, you must disable menus as appropriate and
handle menu bar access as appropriate given their contents.
When your application displays a movable modal dialog box (a window of type
movableDBoxProc), your application does not need to adjust the system-handled
menus but should disable all its other menus except the Apple menu and—if your
movable modal dialog box contains editable text items—the Edit menu. Leave the
Apple menu enabled so that the user can use it to open other applications, and leave the
Edit menu enabled so that the user can use the Cut, Copy, and Paste commands within
the editable text item. (You can also leave your Undo and Clear commands enabled;
otherwise, disable all other commands in the Edit menu.)
When your application removes a movable modal dialog box, modeless dialog box, or
modal dialog box with editable text items, your application must restore to their previous
states any menus that it disabled prior to displaying the dialog box. See the chapter
“Dialog Manager” in this book for additional information on dialog boxes.
Menu Manager
Menu Manager
If you provide your own menu definition procedure, it should also perform these tasks.
Your menu definition procedure should also support scrolling in menus and color in
menus and provide support for Balloon Help.
If you provide your own menu definition procedure, store it in a resource of type 'MDEF'
and include its resource ID in the description of each menu that uses your own menu
definition procedure. If you create a menu using GetMenu (or GetNewMBar), the Menu
Manager reads the menu definition procedure into memory and stores a handle to it in
the menuProc field of the menu’s menu record.
When your application uses GetMenu (or GetNewMBar) to create a new menu that uses
your menu definition procedure, the Menu Manager creates a menu record for the menu
and fills in the menuID, menuProc, enableFlags, and menuData fields according to
the menu’s resource description. The Menu Manager also reads in the data for each menu
item and stores it as variable data at the end of the menu record. The menu definition
procedure is responsible for interpreting the contents of the data. For example, the
standard menu definition procedure interprets this data as described in “The Menu
Resource” beginning on page 3-151. After reading in a resource description of a menu,
the Menu Manager requests the menu definition procedure to calculate the size of
the menu and to store these values in the menuWidth and menuHeight fields of the
menu’s menu record.
Note that when drawing a menu, the Menu Manager first requests your menu definition
procedure to calculate the dimensions (the menu rectangle) of the menu. Next the Menu
Manager requests the menu bar definition function to draw the structure (shadow) of the
menu and erase the contents of the menu to its background color. Then the Menu
Manager requests your menu definition procedure to draw the items in the menu. As the
user moves the cursor into and out of menu items, the Menu Manager requests your
menu definition procedure to highlight and unhighlight items appropriately. Your menu
definition procedure should also determine when to add scrolling indicators to a menu
and scroll the menu appropriately when the cursor is in a scrolling item. Your menu
definition is responsible for showing and removing any help balloons associated with a
menu item.
When the Menu Manager requests your menu definition procedure to perform an action
on a menu, it provides your procedure with a handle to its menu record. This allows your
procedure to access the data in the menu record and to use any data in the variable data
portion of the menu record to appropriately handle the menu items. However, your
menu definition procedure should not assume that the A5 register is properly set up, so
your procedure can’t refer to any of the QuickDraw global variables.
The Menu Manager passes a value to your menu definition procedure in the message
parameter that indicates the action your menu definition procedure should perform. The
Menu Manager always passes a handle to the menu record of the menu that the
operation should affect in the parameter theMenu. Depending on the requested action,
the Menu Manager passes additional information in other parameters.
Menu Manager
Listing 3-28 shows how you might declare a menu definition procedure.
BEGIN
CASE message OF
mDrawMsg:
MyDrawMenu(theMenu, menuRect);
mChooseMsg:
MyChooseItem(theMenu, menuRect, hitPt, whichItem);
mSizeMsg:
MySizeTheMenu(theMenu);
mPopUpMsg:
MyCalcMenuRectForOpenPopUpBox(theMenu, hitPt, menuRect);
END;
END;
The next sections describe in more detail how your menu definition procedure should
respond when it receives the mDrawMsg, mChooseMsg, or mSizeMsg constant in the
message parameter. For a complete description of the menu definition procedure and
the parameters passed to your procedure by the Menu Manager, see “The Menu
Definition Procedure” beginning on page 3-148.
Menu Manager
{calculate the width of the menu (the width of the longest item): }
{ for each item calculate the width as }
{ width = iconWidth + markWidth + textWidth + subMenuWidth }
{ + cmdKeyComboWidth }
{ If an item doesn't have a characteristic, use 0 as the width of }
{ that characteristic. }
{ To calculate the width of item's text, must consider script code and }
{ width of the font. }
{ The width of the menu should not exceed the right or left }
{ boundaries of the screen. }
{ Store the width in the menu's menu record}
theMenu^^.menuWidth := MyCalcMenuWidth(itemDataPtr, numItems);
HUnLock(Handle(theMenu));
END;
Menu Manager
parameter, requesting that your procedure draw the menu items. When your menu
definition procedure receives this constant, it should draw the menu items of the menu
specified by the parameter theMenu inside the rectangle specified by the menuRect
parameter. The Menu Manager sets the current graphics port to the Window Manager
port before calling your menu definition procedure. Your menu definition procedure can
determine how to draw the menu items by examining the data in the menu record.
If your menu definition procedure supports color menus, your procedure should
check the application’s menu color information table for the colors to use to draw
each item. If the application’s menu color information table contains a color entry for
an item, draw the item using that color. If the table does not contain an item entry for
a particular item, use the default item color defined in the menu title entry. If a menu title
entry doesn’t exist, use the default item color defined in the menu bar entry. If the menu
bar entry doesn’t exist, draw the item using black on white.
If your menu definition procedure supports scrolling menus, it should insert scrolling
indicators if necessary when drawing the menu items.
Listing 3-30 shows an application-defined support routine, MyDrawMenu, used by the
application’s menu definition procedure. The MyDrawMenu procedure draws each item
in the menu, according to the item’s defined characteristics. Disabled items should be
drawn using the colors returned by the GetGray function. Pass the RGB color of the
item’s background in the bkgnd parameter to the GetGray function; pass the RGB color
of the item’s enabled text in the fgnd parameter. The GetGray function returns TRUE if
there’s an available color between the two specified colors and returns in the fgnd
parameter the color in which you should draw the item.
Menu Manager
Menu Manager
cursor past the last item to view more items), place a downward-pointing triangular
indicator in place of the last item in the menu. If the user can scroll the menu down
(by dragging the cursor past the first item to view the items originally at the top of
the menu), place an upward-pointing triangular indicator in place of the first item
in the menu.
For all menus, your menu definition procedure should set the global variable
MenuDisable appropriately each time a new item is highlighted. Set MenuDisable to
the menu ID and item number of the last menu item chosen, whether or not it’s disabled.
The MenuChoice function uses the value in MenuDisable to determine if a chosen
menu item is disabled.
Listing 3-31 shows an application-defined support routine, MyChooseItem, used by the
application’s menu definition procedure. This routine determines which item, if any, the
point specified by the hitPt parameter is in. If the item is in an enabled menu item that
is different from the previous item, the MyChooseItem procedure unhighlights the old
item and highlights the new item. However, the MyChooseItem procedure does not
highlight the new item if the item is in a divider or disabled item.
The procedure also removes any help balloons as appropriate and, if Balloon Help is
turned on, displays any help balloon of the new item (for any item other than a divider or
scrolling indicator). The MyChooseItem procedure returns the item number of the new
item in the whichItem parameter or returns 0 if no item is chosen. Although not shown
in the listing, if the item is a disabled item, the procedure returns 0 in the whichItem
parameter and sets the MenuDisable global variable to the menu ID and item number
of the disabled item.
Menu Manager
item := 1;
max := numItems + 1;
currentOffset := 0;
nextOffset := 0;
REPEAT
itemRect := MyCalcItemRect(item, menuRect, currentOffset, nextOffset);
IF PtInRect(hitPt, itemRect) THEN {hitPt is in this item}
itemChosen := item;
item := item + 1;
UNTIL (item = MAX) OR (itemChosen <> 0);
IF itemChosen = 0 THEN
BEGIN {the mouse isn't in any item of this menu;unhighlight previous item}
MyNotInMenu(menuRect, oldWhichItem);
END
ELSE
BEGIN {the mouse is in this menu item. }
{ First see if a previous item was highlighted}
IF ((oldWhichItem <> 0) AND (oldWhichItem <> itemChosen)) THEN
BEGIN
{a previous item was highlighted--unhighlight it}
itemRect := MyCalcOldItemRect(oldWhichItem, menuRect);
IF HMGetBalloons THEN {if Balloon Help is on then }
HMRemoveBalloon;{ remove any balloon that might be showing}
MyHighlightItem(itemRect, oldWhichItem, FALSE);
END;
IF HMGetBalloons and MyIsItemDivider(itemChosen) THEN
{Balloon Help is on and item is divider}
HMRemoveBalloon;{remove any balloon that might be showing}
IF MyIsItemEnabled(itemChosen) THEN
BEGIN
{the item is enabled, so highlight the item the cursor is in}
itemRect := MyCalcNewItemRect(itemChosen, menuRect, currentOffset);
{the highlighting routine must also support scrolling correctly }
{ (if the cursor is in a scrolling item, don't highlight the item)}
inScroll := MyIsScrollItem(itemChosen);
MyHighlightItem(itemRect, itemChosen, inScroll);
IF HMGetBalloons AND inScroll THEN
HMRemoveBalloon {remove any balloon that might be showing}
ELSE
BEGIN {display help balloon for this item, if any}
IF HMGetBalloons THEN
Menu Manager
BEGIN
IF StillDown THEN {mouse button is still down in this item}
{this routine sets up the needed parameters and then }
{ calls HMShowMenuBalloon}
MyShowMenuBalloon(itemChosen, itemRect);
END;
END;
END;
END;
END;
Data Structures 3
This section describes the menu record, menu list, and menu color information table. The
Menu Manager maintains information about the menus in your application in menu
records. The Menu Manager maintains information about all the menus in a menu bar in
a data structure called the menu list.
The Menu Manager stores color information about your application’s menus in a menu
color information table. You can add entries to your application’s menu color information
table if you want to use colors other than the default colors for your menu bar or menus.
You can add entries to this table by using the SetMCEntries procedure or by providing
'mctb' resources.
Menu Manager 3
Field descriptions
menuID A number that identifies the menu. Each menu in your application
must have a unique menu ID. Your application specifies the menu
ID when you create the menu. Thereafter you can use the menu ID
and the GetMenuHandle function to get a handle to the menu’s
menu record.
When you define hierarchical menus, you must use a number from 1
through 235 for the menu ID of a submenu of an application; use a
number from 236 through 255 for the submenu of a desk accessory.
menuWidth The horizontal dimensions of the menu, in pixels.
menuHeight The vertical dimensions of the menu, in pixels.
menuProc A handle to the menu definition procedure of the menu. The Menu
Manager uses this menu definition procedure to draw the menu.
enableFlags A value that represents the enabled state of the menu title and
the first 31 items in the menu. All menu items greater than 31
are enabled by default and can be disabled only by disabling the
entire menu.
menuData A string that defines the title of the menu. Although the menuData
field is defined by the data type Str255 in the MenuInfo data
structure, the Menu Manager allocates only the storage necessary for
the title: the number of characters in the title of the string plus 1.
itemDefinitions
Variable-length data that defines the characteristics of each menu
item in the menu. If the menu uses the standard menu definition
procedure, this data can be conceptually defined in this manner:
itemData: ARRAY[1..X] OF
itemString: String; {text of menu item}
itemIcon: Byte; {icon number minus 256}
Menu Manager
Menu Manager
The structure of the menu list is private to the Menu Manager. For conceptual purposes,
however, its general structure is defined here.
TYPE DynamicMenuList =
RECORD
lastMenu: Integer; {offset to last pull-down menu}
lastRight: Integer; {pixel location of right edge }
{ of rightmost menu in menu bar}
mbResID: Integer; {upper 13 bits are the resource ID of menu }
{ bar defn function, low 3 bits the variant}
menu: ARRAY[1..X] {variable array with one record for }
OF MenuRec; { each menu}
lastHMenu: Integer; {offset to last submenu or pop-up menu}
menuTitleSave: {handle to bits behind inverted menu title}
pixMapHandle;
hMenu: ARRAY[1..Y] {variable array with one record for }
OF HMenuRec;{ each submenu or pop-up menu}
END;
The Menu Manager dynamically allocates the records that contain handles to the menu
records of menus in the menu bar, submenus, and pop-up menus. These records can be
defined conceptually as the MenuRec and HMenuRec data types. The Menu Manager
uses a data structure similar to that of the MenuRec data type to store information about
pull-down menus in the menu list.
TYPE MenuRec =
RECORD
menuOH: MenuHandle; {handle to menu's menu record}
menuLeft: Integer; {pixel location of left edge }
{ of this menu}
END;
The Menu Manager stores information about submenus and pop-up menus at the end of
a menu list in a data structure similar to that of the HMenuRec data type.
TYPE HMenuRec =
RECORD
menuHOH: MenuHandle; {handle to menu's menu record}
reserved: Integer; {reserved}
END;
Menu Manager
by adding entries to your application’s menu color information table by using Menu
Manager routines or by defining these entries in an 'mctb' resource. Note that the menu
color information table uses a format that is different from the standard color table
format.
The Menu Manager maintains information about an application’s menu color
information table as an array of menu color entry records.
The first two fields of a menu color entry record, mctID and mctItem, define whether
the entry is a menu bar entry, a menu title entry, or a menu item entry. The following four
fields specify color information for whatever type of entry the mctID and mctItem fields
describe. The value of the mctID field in the last entry in a menu color information table
is –99, and the rest of the fields of the last entry are reserved. The Menu Manager
automatically creates the last entry in a menu color information table; your application
should not use the value –99 as the menu ID of a menu if you wish to add a menu color
entry for it.
The Menu Manager creates your application’s menu color information table the first
time your application calls InitMenus or InitProcMenu. It creates the menu color
information table as initially empty except for the last entry, which indicates the end
of the table.
Menu Manager
Table 3-7 shows how the Menu Manager interprets the mctID and mctItem fields for
each type of menu color entry in a menu color information table.
A menu bar entry is defined by a menu color entry record that contains 0 in both the
mctID and mctItem fields. You can define only one menu bar entry in a menu color
information table. If you don’t provide a menu bar entry for your application’s menu
color information table, the Menu Manager uses the standard menu bar colors (black text
on a white background), and it uses the standard colors for the other menu elements. You
can provide a menu bar entry to specify default colors for the menu title, the background
of a displayed menu, the items in a menu, and the menu bar. The color information fields
for a menu bar entry are interpreted as follows:
■ mctRGB1 specifies the default color for menu titles. If a menu doesn’t have a menu
title entry, the Menu Manager uses the value in this field as the color of the menu title.
■ mctRGB2 specifies the default color for the background of a displayed menu. If a
menu doesn’t have a menu title entry, the Menu Manager uses the value in this field as
the color of the menu’s background when it is displayed.
■ mctRGB3 specifies the default color for the items in a displayed menu. If a menu item
doesn’t have a menu item entry or a default color defined in a menu title entry, the
Menu Manager uses the value in this field as the color of the menu item.
■ mctRGB4 specifies the default color for the menu bar. If a menu doesn’t have a menu
bar entry (and doesn’t have any menu title entries), the Menu Manager uses the
standard colors for the menu bar.
A menu title entry is defined by a menu color entry record that contains a menu ID in the
mctID field and 0 in the mctItem field. You can define only one menu title entry for each
menu. If you don’t provide a menu title entry for a menu in your application’s menu
color information table, the Menu Manager uses the colors defined by the menu bar
entry. If a menu bar entry doesn’t exist, the Menu Manager uses the standard colors
Menu Manager
(black on white). You can provide a menu title entry to specify a color for the title and
background of a specific menu and a default color for its items. The color information
fields for a menu title entry are interpreted as follows:
■ mctRGB1 specifies the color for the menu title of the specified menu. If a menu doesn’t
have a menu title entry, the Menu Manager uses the default value defined
in the menu bar entry.
■ mctRGB2 specifies the default color for the menu bar. If a menu color information table
doesn’t have a menu bar entry, the Menu Manager uses the value in this field as the
color of the menu bar. If a menu bar entry already exists, the Menu Manager replaces
the value in the mctRGB2 field of the menu title entry with the value defined in the
mctRGB4 field of the menu bar entry.
■ mctRGB3 specifies the default color for the items in the menu. If a menu item doesn’t
have a menu item entry or a default color defined in a menu bar entry, the Menu
Manager uses the value in this field as the color of the menu item.
■ mctRGB4 specifies the color for the background of the menu.
A menu item entry is defined by a menu color entry record that contains a menu ID in
the mctID field and an item number in the mctItem field. You can define only one menu
item entry for each menu item. If you don’t provide a menu item entry for an item in
your application’s menu color information table, the Menu Manager uses the colors
defined by the menu title entry (or by the menu bar entry if the menu containing the item
doesn’t have a menu title entry). If neither a menu title entry nor a menu bar entry exists,
the Menu Manager draws the mark, text, and keyboard equivalent in black. You can
provide a menu item entry to specify a color for the mark, text, and keyboard equivalent
of a specific menu item. The color information fields for a menu item entry are
interpreted as follows:
■ mctRGB1 specifies the color for the mark of the menu item. If a menu item doesn’t
have a menu item entry, the Menu Manager uses the default value defined in the menu
title entry or the menu bar entry.
■ mctRGB2 specifies the color for the text of the menu item. If a menu item doesn’t have
a menu item entry, the Menu Manager uses the default value defined in the menu title
entry or the menu bar entry. The Menu Manager also draws a black-and-white icon of
a menu item using the same color as defined by the mctRGB2 field. (Use a 'cicn'
resource to provide a menu item with a color icon.)
■ mctRGB3 specifies the color for the keyboard equivalent of the menu item. If a menu
item doesn’t have a menu item entry, the Menu Manager uses the default value
defined in the menu title entry or the menu bar entry.
■ mctRGB4 specifies the color for the background of the menu. If the menu color
information table doesn’t have a menu title entry for the menu this item is in, or
doesn’t have a menu bar entry, the Menu Manager uses the value in this field as the
background color of the menu. If a menu title entry already exists, the Menu Manager
replaces the value in the mctRGB4 field of the menu item entry with the value defined
in the mctRGB4 field of the menu title entry (or with the mctRGB2 field of the menu
bar entry).
Menu Manager
You can use the GetMCInfo function to get a copy of your application’s menu color
information table and the SetMCEntries procedure to set entries of your application’s
menu color information table, or you can provide 'mctb' resources that define the color
entries for your menus.
The GetMenu, GetNewMBar, and ClearMenuBar routines can also modify the entries in
the menu color information table. The GetMenu function looks for an 'mctb' resource
with a resource ID equal to the value in the menuID parameter. If it finds one, it adds the
entries to the application’s menu color information table.
The GetNewMBar function builds a new menu color information table when it creates the
new menu list. If you want to save the current menu color information table, call
GetMCInfo before calling GetNewMBar.
The ClearMenuBar procedure reinitializes both the current menu list and the menu
color information table.
Table 3-8 Mapping between new and previous names of Menu Manager routines
Menu Manager
InitMenus 3
The InitMenus procedure allocates space for your application’s current menu list in
your application’s heap. Your application needs to call InitMenus only once to initialize
the Menu Manager and the current menu list for your application.
PROCEDURE InitMenus;
DESCRIPTION
The InitMenus procedure creates the current menu list with no menus, submenus, or
pop-up menus. InitMenus also creates your application’s menu color information table.
After allocating the menu color information table, InitMenus looks for an 'mctb'
resource with resource ID 0. You can provide an 'mctb' resource with a resource ID of 0
as one of your application’s resources if you want to use colors other than the default
colors for your application’s menu bar and menus. If InitMenus finds and successfully
loads an 'mctb' resource, it adds the information contained in that resource to the menu
color information table (using SetMCEntries).
The InitMenus procedure also draws an empty menu bar.
SPECIAL CONSIDERATIONS
Your application must initalize QuickDraw, the Font Manager, and the Window Manager
(using the InitGraf, InitFonts, and InitWindows procedures) before initializing
the Menu Manager.
SEE ALSO
To set up the menus for your application’s menu bar, use GetNewMBar and
SetMenuBar, described on page 3-111 and page 3-112, respectively. You can also add
menus to the current menu list using the InsertMenu procedure, described on
page 3-108.
To remove all menus from the current menu list, use the ClearMenuBar procedure,
described on page 3-110.
If your application uses its own menu bar definition function, use the InitProcMenu
procedure to set the mbResID field of the current menu list to the resource ID of your
custom 'MBDF' resource.
Menu Manager
See “The Menu Color Information Table Resource” on page 3-155 for a description of the
'mctb' resource.
See the chapter “Window Manager” in this book for a description of the InitWindows
procedure. See Inside Macintosh: Imaging and Inside Macintosh: Text for descriptions of the
InitGraf and InitFonts procedures.
InitProcMenu 3
Apple recommends that you use the standard menu bar definition function. However, if
your application provides its own menu bar definition function, use the InitProcMenu
procedure to set the mbResID field of the current menu list to the resource ID of your
custom 'MBDF' resource.
resID The resource ID of your application’s menu bar definition function in the
upper 13 bits of this parameter; the variant in the lower 3 bits. You must
use a resource ID greater than $100.
For resources of type 'MBDF', Apple reserves resource IDs $000 through
$100 for its own use.
DESCRIPTION
The InitProcMenu procedure creates the current menu list if it hasn’t already been
created by a previous call to InitMenus. The InitProcMenu procedure stores the
resource ID that you specify in the mbResID field of the current menu list. The Menu
Manager uses the menu bar definition function referred to in this field to draw the menu
bar and to perform basic operations on menus.
SPECIAL CONSIDERATIONS
The resource ID of your application’s menu bar definition function is maintained in the
current menu list until your application next calls InitMenus; InitMenus initializes the
mbResID field with the resource ID of the standard menu bar definition function. This
can affect applications such as development environments that control other applications
that may call InitMenus.
SEE ALSO
See the description of the InitMenus procedure on page 3-103; you should use
InitMenus if your application uses the standard menu bar definition function.
Menu Manager
Creating Menus 3
You can use the NewMenu or GetMenu function to create a pull-down menu, although
you usually create all the menus in your menu bar at once by providing an 'MBAR'
resource and using the GetNewMBar function. See “Getting and Setting the Menu Bar”
on page 3-112 for information on creating a menu bar. You typically use the NewMenu or
GetMenu function to create submenus or pop-up menus.
The NewMenu function creates a menu with the specified title, assigns it the specified
menu ID, and creates a menu record for the menu. Use AppendMenu, InsertMenuItem,
AppendResMenu, or InsertResMenu to add items to menus you create with NewMenu.
The GetMenu function creates a menu with the title, items, and characteristics defined in
a specified 'MENU' resource.
Both NewMenu and GetMenu allocate space in your application’s heap for the menu
record and return a handle to the menu’s newly created menu record.
To add menus created by NewMenu or GetMenu to the current menu list, use the
InsertMenu procedure. To update the menu bar with any new menu titles, use
DrawMenuBar.
NewMenu 3
You can use the NewMenu function to create an empty menu with a specified title and
menu ID. In most cases you should store information about your menus (such as their
titles, items, and characteristics) in resources; use the GetMenu or GetNewMBar function
to create menus from resource definitions.
menuID The menu ID of the menu. (Note that this is not the resource ID of a
'MENU' resource.) The menu ID is a number that identifies the menu. Use
positive menu IDs for menus belonging to your application. Use negative
menu IDs for desk accessories (except for submenus of a desk accessory).
Submenus must have menu IDs from 1 through 255. For submenus of an
application, use menu IDs from 1 through 235; for submenus of a desk
accessory, use menu IDs from 236 through 255. Apple reserves the menu
ID of 0.
menuTitle The title of the new menu. Note that in most cases you should store
the titles of menus in resources, so that your menu titles can be more
easily localized.
Menu Manager
DESCRIPTION
The NewMenu function creates a menu with the specified title, assigns it the specified
menu ID, creates a menu record for the menu, and returns a handle to the menu record. It
sets up the menu record to use the standard menu definition procedure (and it reads the
standard menu definition procedure into memory if it isn’t already there). The NewMenu
function does not insert the newly created menu into the current menu list.
After creating a menu with NewMenu, use AppendMenu, InsertMenuItem,
AppendResMenu, or InsertResMenu to add menu items to the menu. To add a menu
created by NewMenu to the current menu list, use the InsertMenu procedure. To update
the menu bar with any new menu titles, use the DrawMenuBar procedure.
SPECIAL CONSIDERATIONS
To release the memory associated with a menu that you created using NewMenu, first
call DeleteMenu to remove the menu from the current menu list and to remove any
entries for this menu in your application’s menu color information table; then call
DisposeMenu to dispose of the menu’s menu record. After disposing of a menu, use
DrawMenuBar to update the menu bar.
If the NewMenu function is unable to create the menu record, it returns NIL as its function
result.
SEE ALSO
For information on how to add items to a menu, see the description of AppendMenu on
page 3-124, InsertMenuItem on page 3-126, AppendResMenu on page 3-128, and
InsertResMenu on page 3-129. For information on InsertMenu, see page 3-108. To
dispose of a menu, see the description of DeleteMenu on page 3-109 and DisposeMenu
on page 3-140.
GetMenu 3
Use the GetMenu function to create a menu with the title, items, and other characteristics
defined in a 'MENU' resource with the specified resource ID. You typically use this
function only when you create submenus; you can create all your pull-down menus at
once using the GetNewMBar function, and you can create pop-up menus using the
standard pop-up control definition function.
resourceID The resource ID of the 'MENU' resource that defines the characteristics of
the menu. (You usually use the same number for a menu’s resource ID as
the number that you specify for the menu ID in the menu resource.)
Menu Manager
DESCRIPTION
The GetMenu function creates a menu according to the specified menu resource, and it
also creates a menu record for the menu. It reads the menu definition procedure
(specified in the menu resource) into memory if it isn’t already in memory, and it stores
a handle to the menu definition procedure in the menu record. The GetMenu function
does not insert the newly created menu into the current menu list.
After reading the 'MENU' resource, the GetMenu function searches for an 'mctb'
resource with the same resource ID as the 'MENU' resource. If GetMenu finds this
'mctb' resource, it uses the information in the 'mctb' resource to add entries for this
menu to the application’s menu color information table. The GetMenu function uses
SetMCEntries to add the entries defined by the 'mctb' resource to the application’s
menu color information table. If GetMenu doesn’t find this 'mctb' resource, it uses the
default colors specified in the menu bar entry of the application’s menu color
information, or, if the menu bar entry doesn’t exist, it uses the standard colors for
the menu.
The GetMenu function returns a handle to the menu record of the menu. You can use the
returned menu handle to refer to this menu in most Menu Manager routines. If GetMenu
is unable to read the menu or menu definition procedure from the resource file, GetMenu
returns NIL.
After creating a menu with GetMenu, you can use AppendMenu, InsertMenuItem,
AppendResMenu, or InsertResMenu to add more menu items to the menu if necessary.
To add a menu created by GetMenu to a menu list, use the InsertMenu procedure. To
update the menu bar with any new menu titles, use the DrawMenuBar procedure.
Storing the definitions of your menus in resources (especially menu titles and menu
items) makes your application easier to localize.
▲ WARNING
Menus in a resource must not be purgeable. ▲
SPECIAL CONSIDERATIONS
To release the memory associated with a menu that you read from a resource file using
GetMenu, first call DeleteMenu to remove the menu from the menu list and to remove
any menu title entry or menu item entries for this menu in the application’s menu color
information table, then call the Resource Manager procedure ReleaseResource to
dispose of the menu’s menu record. Use DrawMenuBar to update the menu bar.
▲ WARNING
Call GetMenu only once for a particular menu. If you need the handle of
a menu currently in the menu list, use GetMenuHandle or the Resource
Manager function GetResource. ▲
Menu Manager
SEE ALSO
For a description of the 'MENU' resource, see “The Menu Resource” on page 3-151; for a
sample 'MENU' resource in Rez format, see Listing 3-2 on page 3-48. For information on
the 'mctb' resource, see “The Menu Color Information Table Resource” on page 3-155.
For details on how to add items to a menu, see the description of AppendMenu on
page 3-124, InsertMenuItem on page 3-126, AppendResMenu on page 3-128, and
InsertResMenu on page 3-129. To remove a menu, see the description of DeleteMenu
on page 3-109. To update the menu bar, use the DrawMenuBar procedure, described on
page 3-113.
Adding Menus to and Removing Menus From the Current Menu List 3
After creating a menu with NewMenu or GetMenu, use the InsertMenu procedure to
insert the menu into the current menu list. Use the DeleteMenu procedure to delete
a menu from the current menu list; use the ClearMenuBar procedure to remove all
menus from the current menu list.
InsertMenu 3
Use the InsertMenu procedure to insert an existing menu into the current menu list.
theMenu A handle to the menu record of the menu. The NewMenu and GetMenu
functions return a handle to a menu record that you can use in this
parameter.
beforeID A number that indicates where in the current menu list the menu should
be inserted. InsertMenu inserts the menu into the current menu list
before the menu whose menu ID equals the number specified in the
beforeID parameter. If the number in the beforeID parameter is 0 (or it
isn’t the ID of any menu in the menu list), InsertMenu adds the new
menu after all others (except before the Help, Keyboard, and Application
menus). If the menu is already in the current menu list or the menu list is
already full, InsertMenu does nothing.
You can specify –1 for the beforeID parameter to insert a submenu into
the current menu list. The submenus in the submenu portion of the menu
list do not have to be currently associated with a hierarchical menu item;
you can store submenus in the menu list and later specify that a menu
item has a submenu if needed. However, note that the MenuKey function
scans all menus in the menu list for keyboard equivalents, including
submenus that are not associated with any menu item. You should not
define keyboard equivalents for submenus that are in the current menu
list but not associated with a menu item.
Menu Manager
You can also specify –1 for the beforeID parameter to insert a pop-up
menu into the current menu list. However, if you use the standard
pop-up control definition function, the pop-up control automatically
inserts the menu into the current menu list according to the needs of the
pop-up control.
DESCRIPTION
The InsertMenu procedure inserts into the current menu list the menu identified by the
specified handle to a menu record. To update the menu bar to reflect the new menu, use
DrawMenuBar.
SEE ALSO
For details on how to update your application’s menu bar, see the description of
DrawMenuBar on page 3-113.
DeleteMenu 3
Use the DeleteMenu procedure to delete an existing menu from the current menu list.
menuID The menu ID of the menu to delete from the current menu list. If the menu
list does not contain a menu with the specified menu ID, DeleteMenu
does nothing.
DESCRIPTION
The DeleteMenu procedure deletes the menu identified by the specified menu ID
from the current menu list, and it removes all color entries for that menu from the
application’s menu color information table. DeleteMenu does not release the memory
occupied by the menu’s menu record. To release the memory occupied by the menu’s
associated data structures, use DisposeMenu if you created the menu using NewMenu;
use the Resource Manager procedure ReleaseResource if you created the menu using
GetMenu or you read the resource in using GetNewMBar.
The DeleteMenu procedure first checks the submenu portion of the current menu list for
a menu ID with the specified ID. If it finds such a menu, it deletes that menu and returns.
If DeleteMenu doesn’t find the menu in the submenu portion, it checks the regular
portion of the current menu list. This allows a desk accessory to delete a submenu
without deleting an application’s menu whose menu ID might conflict with the menu ID
defined by a desk accessory.
After deleting a menu, use DrawMenuBar to update the menu bar to reflect the changes
to the current menu list.
Menu Manager
SEE ALSO
For details on how to dispose of a menu’s associated data structures using
DisposeMenu, see “Disposing of Menus” on page 3-140. For information on the
ReleaseResource procedure, see the chapter “Resource Manager” in Inside
Macintosh: More Macintosh Toolbox.
ClearMenuBar 3
Use the ClearMenuBar procedure to delete all menus from the current menu list.
PROCEDURE ClearMenuBar;
DESCRIPTION
The ClearMenuBar procedure deletes all menus from the current menu list and deletes
all color entries from the application’s menu color information table. ClearMenuBar
does not release the memory occupied by any of the menus’ menu records or the menu
color information table. To release the memory occupied by the data structures associated
with the menus, use DisposeMenu for each menu you created using NewMenu; use
ReleaseResource for each menu you created using GetMenu or if you read the
resource in using GetNewMBar.
After deleting all menus from the current menu list, use DrawMenuBar to update the
appearance of the menu bar.
SEE ALSO
To update your application’s menu bar, see the description of DrawMenuBar on
page 3-113. For information on the ReleaseResource procedure, see the chapter
“Resource Manager” in Inside Macintosh: More Macintosh Toolbox.
Menu Manager
GetNewMBar 3
Use the GetNewMBar function to read in the definition of a menu bar from an 'MBAR'
resource.
menuBarID The resource ID of an 'MBAR' resource that specifies the menus for a
menu bar.
DESCRIPTION
The GetNewMBar function reads in the definition of a menu bar and its associated menus
from an 'MBAR' resource. The 'MBAR' resource identifies the order of menus contained
in its menu bar. For each menu, it also specifies the menu’s resource ID. The
GetNewMBar function reads in each menu from the 'MENU' resource with the resource
ID specified in the 'MBAR' resource.
The GetNewMBar function creates a menu list for the menu bar defined by the 'MBAR'
resource and returns a handle to the menu list. (If the resource isn’t already in memory,
GetNewMBar reads it into memory.) If GetNewMBar can’t read the resource,
GetNewMBar returns NIL. GetNewMBar uses GetMenu to read in each individual menu.
After reading in menus from an 'MBAR' resource, use SetMenuBar to make the menu
list created by GetNewMBar the current menu list. Then use DrawMenuBar to update the
menu bar.
To release the memory occupied by the data structures associated with the menus in a
menu list, use DisposeMenu for each menu you created using NewMenu; use the
Resource Manager procedure ReleaseResource for each menu you created using
GetMenu or if you read the resource in using GetNewMBar. To release the memory
occupied by a menu list, use the Memory Manager procedure DisposeHandle.
SPECIAL CONSIDERATIONS
The GetNewMBar function first saves the current menu list and then clears the current
menu list and your application’s menu color information table. It then creates a
new menu list. Before returning a handle to the new menu list, the GetNewMBar function
restores the current menu list to the previously saved menu list, but GetNewMBar does
not restore the previous menu color information table. To save
and then restore your application’s current menu color information table, call the
GetMCInfo function before GetNewMBar and call the SetMCInfo procedure afterward.
While you supply only the resource ID of an 'MBAR' resource to the GetNewMBar
function, your application often needs to use the menu IDs defined in each of your
menus’ 'MENU' resources. Most Menu Manager routines require either a menu ID
or a handle to a menu record to perform operations on a specific menu. For menus in
the current menu list, you can use the GetMenuHandle function to get the handle to
a menu record of a menu with a given menu ID.
Menu Manager
SEE ALSO
For a description of the 'MENU' resource, see “The Menu Resource” on page 3-151; for a
sample 'MENU' resource in Rez format, see Listing 3-2 on page 3-48. For a description of
the 'MBAR' resource, see “The Menu Bar Resource” on page 3-155; for a sample 'MBAR'
resource in Rez format, see Listing 3-4 on page 3-49. For information on the 'mctb'
resource, see “The Menu Color Information Table Resource” on page 3-155. For
information about the Resource Manager, see Inside Macintosh: More Macintosh Toolbox.
GetMenuBar 3
Use the GetMenuBar function to get a handle to a copy of the current menu list.
DESCRIPTION
The GetMenuBar function creates a copy of the current menu list and returns a handle to
the copy. You can save the returned menu list and then add menus to or remove menus
from the current menu list (using InsertMenu, DeleteMenu, or ClearMenuBar). You
can later restore the saved menu list using SetMenuBar.
To release the memory occupied by a saved menu list, use the Memory Manager’s
DisposeHandle procedure.
▲ WARNING
GetMenuBar doesn’t copy the menu records, just the menu list (which
contains handles to the menu records). Do not dispose of any menus in a
saved menu list if you wish to restore the menu list later. ▲
SetMenuBar 3
Use the SetMenuBar procedure to set the current menu list to a specified menu list.
menuList A handle to a menu list that specifies the menus for a menu bar. You
should specify a handle returned by GetMenuBar or GetNewMBar.
Menu Manager
DESCRIPTION
The SetMenuBar procedure copies the given menu list to the current menu list. As with
GetMenuBar, SetMenuBar doesn’t copy the menu records, just the menu list (which
contains handles to the menu records).
You can use SetMenuBar to restore a menu list that you previously saved using
GetMenuBar or to set the current menu list to a menu list created by GetNewMBar.
The SetMenuBar procedure sets only the current menu list; to update the menu bar
according to the new menu list, use the DrawMenuBar procedure.
GetMBarHeight 3
Use the GetMBarHeight function if you need to determine the current height of the
menu bar. When the Roman script system is the current system script, the menu bar is
20 pixels high. If a non-Roman script is the current system script, the menu bar may be
greater than 20 pixels high to accommodate the current system font.
DESCRIPTION
The GetMBarHeight function returns the current height, in pixels, of the menu bar.
DrawMenuBar 3
Use the DrawMenuBar procedure to draw the menu bar based on the current menu list.
PROCEDURE DrawMenuBar;
DESCRIPTION
The DrawMenuBar procedure draws (or redraws) the menu bar according to the current
menu list. You must call DrawMenuBar to update the menu bar after adding menus to or
deleting menus from the current menu list using InsertMenu or DeleteMenu, after
setting the current menu list using SetMenuBar, after changing the enabled state of a
menu, or after any other routine that changes the current menu list.
Menu Manager
InvalMenuBar 3
PROCEDURE InvalMenuBar;
DESCRIPTION
The InvalMenuBar procedure marks the menu bar as changed and in need
of updating. When the Event Manager scans update regions for regions that require
updating, the Event Manager also checks to determine whether the menu bar
requires updating (because of a call to InvalMenuBar). If the menu bar needs updating,
the Event Manager calls the DrawMenuBar procedure to draw the menu bar.
You can use InvalMenuBar instead of DrawMenuBar to minimize blinking in the menu
bar. For example, if you have several application-defined routines that can change the
enabled state of a menu and each calls DrawMenuBar, you can replace the calls to
DrawMenuBar with calls to InvalMenuBar. In this way the menu bar is redrawn only
once instead of multiple times in quick succession. If you need to make immediate
changes to the menu bar, use DrawMenuBar. If you want to redraw the menu bar at most
once each time through your event loop, use InvalMenuBar. The InvalMenuBar
procedure is available only in System 7.
Menu Manager
Your application should adjust its menus before calling MenuSelect or MenuKey. For
example, you should enable or disable menu items as appropriate and add any
applicable checkmarks or dashes to items that show attributes.
MenuSelect 3
Use the MenuSelect function to allow the user to choose a menu item from the menus
in your application’s menu bar.
startPt The point (in global coordinates) representing the location of the cursor at
the time the mouse button was pressed.
DESCRIPTION
When the user presses the mouse button while the cursor is in the menu bar, your
application receives a mouse-down event. To handle mouse-down events in the menu
bar, pass the location of the cursor at the time of the mouse-down event as the startPt
parameter to MenuSelect. The MenuSelect function displays and removes menus as
the user moves the cursor over menu titles in the menu bar, and it handles all user
interaction until the user releases the mouse button.
As the user drags the cursor through the menu bar, the MenuSelect function highlights
the title of the menu the cursor is currently over and displays all items in that menu. If
the user moves the cursor so that it is over a different menu, the MenuSelect function
removes the previous menu and unhighlights its menu title.
The MenuSelect function highlights and unhighlights menu items as the user drags the
cursor over the items in a menu. The MenuSelect function highlights a menu item if the
item is enabled and the cursor is currently over it; it removes such highlighting when the
user moves the cursor to another menu item. The MenuSelect function does not
highlight disabled menu items.
If the user chooses an enabled menu item (including any item from a submenu), the
MenuSelect function returns a value as its function result that indicates which menu
and menu item the user chose. The high-order word of the function result contains the
menu ID of the menu, and the low-order word contains the item number of the menu
item chosen by the user. The MenuSelect function leaves the menu title highlighted;
after performing the chosen task your application should unhighlight the menu title
using the HiliteMenu procedure.
If the user chooses an item from a submenu, MenuSelect returns the menu ID of the
submenu in the high-order word and the item chosen by the user in the low-order word
of its function result. The MenuSelect function also highlights the title of the menu in
the menu bar that the user originally displayed in order to begin traversing to the
submenu. After performing the chosen task, your application should unhighlight the
menu title.
Menu Manager
If the user releases the mouse button while the cursor is over a disabled item, in the menu
bar, or outside of any menu, the MenuSelect function returns 0 in the high-order word
of its function result and the low-order word is undefined. If it is necessary for your
application to find the item number of the disabled item, your application can call
MenuChoice to return the menu ID and menu item.
If the user chooses an enabled item in a menu that a desk accessory has inserted into your
application’s menu list, MenuSelect uses the SystemMenu procedure to process this
occurrence and returns 0 to your application in the high-order word.
SPECIAL CONSIDERATIONS
When the MenuSelect function pulls down a menu, it stores the bits behind the menu
as a relocatable object in the application heap of your application.
ASSEMBLY-LANGUAGE INFORMATION
The InitMenus and InitProcMenu procedures initialize the MenuHook and
MBarHook global variables to 0. If you choose, you can store the addresses of routines
that MenuSelect calls in these global variables. The MenuHook global variable contains
the address (if any) of a routine that MenuSelect calls repeatedly while the mouse
button is down. MenuSelect does not pass any parameters to this routine.
The MBarHook global variable contains the address (if any) of a routine that
MenuSelect calls after a menu title is highlighted and the menu rectangle is calculated
but before the menu is drawn. The menu rectangle is the rectangle (in global coordinates)
in which the menu will be drawn. MenuSelect passes a pointer to the menu rectangle
on the stack. If you provide the address of a routine in the MBarHook global variable, it
should normally return 0 in the D0 register, indicating that MenuSelect should
continue; returning 1 causes MenuSelect to cancel its operation and return immediately
to the application.
The MenuSelect function uses the global variable MBarEnable to determine if all
menus in the current menu bar belong to a desk accessory or an application. If the
MBarEnable global variable is nonzero, then all menus in the current menu bar belong
to a desk accessory. If the MBarEnable global variable is 0, then all menus in the current
menu bar belong to an application. If you’re writing a desk accessory, you may need to
set the MBarEnable global variable to a nonzero value; if you’re writing an application,
you should not change the value of the MBarEnable global variable.
The global variable TheMenu contains the ID of the currently highlighted menu in the
menu bar. If the user chooses an item from a submenu, TheMenu contains the menu ID of
the submenu, not the menu to which the submenu is attached.
SEE ALSO
For information on adjusting your application’s menus before calling MenuSelect, see
“Adjusting the Menus of an Application” beginning on page 3-73.
Menu Manager
See the description of the HiliteMenu procedure on page 3-119 for details on how to
unhighlight a menu. For information on how to determine if the user chose a disabled
item, see the description of the MenuChoice function on page 3-118.
MenuKey 3
If the user presses another key while holding down the Command key, call the MenuKey
function to determine if the keyboard combination maps to the keyboard equivalent of a
menu item in a menu in the current menu list.
DESCRIPTION
The MenuKey function maps the given character to the menu and menu item with that
keyboard equivalent. The MenuKey function returns as its function result a value that
indicates the menu ID and menu item that has the keyboard equivalent corresponding to
the given character.
The MenuKey function does not distinguish between uppercase and lowercase letters. It
takes the 1-byte character passed to it and calls the UpperText procedure (which
provides localizable uppercase conversion of the character). Thus, MenuKey translates
any lowercase character to uppercase when comparing a keyboard event to keyboard
equivalents. This allows a user to invoke a keyboard equivalent command, such as the
Copy command, by pressing the Command key and “c” or “C”. For consistency between
applications, you should define the keyboard equivalents of your commands so that they
appear in uppercase in your menus.
If the given character maps to an enabled menu item in the current menu list, MenuKey
highlights the menu title of the chosen menu, returns the menu ID in the high-order word
of its function result, and returns the chosen menu item in the low-order word of its
function result. After performing the chosen task, your application should unhighlight
the menu title using the HiliteMenu procedure.
If the given character does not map to an enabled menu item in the current menu list,
MenuKey returns 0 in its high-order word and the low-order word is undefined.
If the given character maps to a menu item in a menu that a desk accessory has inserted
into your application’s menu list, MenuSelect uses the SystemMenu procedure to
process this occurrence and returns 0 to your application in the high-order word.
You should not define menu items with identical keyboard equivalents. The MenuKey
function scans the menus from right to left and the items from top to bottom. If you have
defined more than one menu item with identical keyboard equivalents, MenuKey returns
the first one it finds.
Menu Manager
The MenuKey function first searches the regular portion of the current menu list for a
menu item with a keyboard equivalent matching the given key. If it doesn’t find one
there, it searches the submenu portion of the current menu list. If the given key maps to a
menu item in a submenu, MenuKey highlights the menu title in the menu bar that the
user would normally pull down to begin traversing to the submenu. Your application
should perform the desired command and then unhighlight the menu title.
You shouldn’t assign a Command–Shift–number key sequence to a menu item as its
keyboard equivalent; Command–Shift–number key sequences are reserved for use as
'FKEY' resources. Command–Shift–number key sequences are not returned to your
application, but instead are processed by the Event Manager. The Event Manager invokes
the 'FKEY' resource with a resource ID that corresponds to the number that activates it.
Apple reserves the Command-key codes $1B (Control-[ ) through $1F (Control-_ ) to
indicate meanings other than keyboard equivalents. MenuKey ignores these character
codes and returns a function result of 0 if you specify any of these values in the ch
parameter. Your application should not use these character codes for its own use.
The global variable TheMenu contains the ID of the currently highlighted menu in the
menu bar. If the user chooses an item from a submenu, TheMenu contains the menu ID of
the submenu, not the menu to which the submenu is attached.
▲ WARNING
Do not define a “circular” hierarchical menu—that is, a hierarchical
menu in which a submenu has a submenu whose submenu is
a hierarchical menu higher in the chain. If MenuKey detects a circular
hierarchical menu, it creates a system error with error number 86. ▲
SEE ALSO
To unhighlight a menu, use the HiliteMenu procedure, described on page 3-119. To
provide support for keyboard equivalents other than Command-key equivalents, see the
discussion of 'KCHR' resources in Inside Macintosh: Text.
MenuChoice 3
If your application needs to find the item number of a disabled menu item that the
user attempted to choose, you can use the MenuChoice function to return the chosen
menu item.
DESCRIPTION
If the user chooses a disabled menu item, the MenuChoice function returns a value that
indicates which menu and menu item the user chose. The high-order word of the
Menu Manager
function result contains the menu ID of the menu, and the low-order word contains the
item number of the menu item chosen by the user.
The MenuChoice function returns 0 as the low-order word of its function result if the
mouse button was released while the cursor was in the menu bar or outside the menu.
SPECIAL CONSIDERATIONS
The Menu Manager updates the global variable MenuDisable whenever a menu is
displayed. As the user moves the cursor over each item, the Menu Manager calls the
menu definition procedure of the menu to update the MenuDisable global variable to
reflect the current menu ID and menu item. The standard menu definition procedure
updates the global variable MenuDisable appropriately. If your application uses its own
menu definition procedure, your menu definition procedure should support this feature;
if you use a menu definition procedure that does not update the global variable
MenuDisable appropriately, the result returned by MenuChoice is undefined.
HiliteMenu 3
You can use the HiliteMenu procedure to highlight or unhighlight menu titles. For
example, after performing a menu command chosen by the user, use the HiliteMenu
procedure to unhighlight the menu title.
menuID The menu ID of the menu whose title should be highlighted. If the menu
title of the specified menu is already highlighted, HiliteMenu does
nothing. If the menu ID is 0 or the specified menu ID isn’t in the current
menu list, HiliteMenu unhighlights whichever menu title is currently
highlighted (if any).
DESCRIPTION
The MenuSelect and MenuKey functions highlight the title of the menu containing
the item chosen by the user. After performing the chosen task, your application
should unhighlight the menu title by calling HiliteMenu and passing 0 in the
menuID parameter.
The HiliteMenu procedure highlights a menu title by first saving the bits behind the
title rectangle and then drawing the highlighted title. HiliteMenu unhighlights a menu
title by restoring the bits behind the menu title.
The global variable TheMenu contains the ID of the currently highlighted menu in the
menu bar. If the user chooses an item from a submenu, TheMenu contains the menu ID of
the submenu, not the menu to which the submenu is attached.
Menu Manager
SEE ALSO
To highlight the entire menu bar, use the FlashMenuBar procedure, described on
page 3-141.
PopUpMenuSelect 3
To display a pop-up menu without using the standard pop-up control definition
function, use the PopUpMenuSelect function to display the pop-up menu anywhere
on the screen. If your application uses the standard pop-up control definition function,
your application does not need to use PopUpMenuSelect.
menu A handle to the menu record of the menu. The NewMenu, GetMenu, and
GetMenuHandle functions return a handle to a specified menu’s menu
record.
Top The top coordinate of the pop-up box when it is closed. This value should
be in global coordinates.
Left The left coordinate of the pop-up box when it is closed. This value should
be in global coordinates.
PopUpItem The item number of the current item minus 1. This value should
correspond to the user’s previous choice from this menu. If the user has
not previously made a choice, this value should be set to the default value.
DESCRIPTION
The PopUpMenuSelect function uses the location specified by the Top and Left
parameters to determine where to display the specified item of the pop-up menu. The
PopUpMenuSelect function displays the pop-up menu so that the menu item specified
in the PopUpItem parameter appears highlighted at the specified location. Figure 3-24 on
page 3-34 shows the pop-up title and pop-up box of a pop-up menu.
The PopUpMenuSelect function highlights and unhighlights menu items and handles
all user interaction until the user releases the mouse button. The PopUpMenuSelect
function returns the menu ID of the chosen menu in the high-order word of its function
result and the chosen menu item in the low-order word.
Your application is responsible for highlighting the pop-up title, setting the mark of the
current menu item appropriately, and drawing the text and downward-pointing
indicator in the pop-up box before calling PopUpMenuSelect. Your application should
also make sure the pop-up menu is in the submenu portion of the current menu list
before calling PopUpMenuSelect. (You can use the InsertMenu procedure and specify
–1 in the beforeID parameter to insert the pop-up menu into the current menu list.)
Menu Manager
After calling PopUpMenuSelect, your application can delete the pop-up menu from the
current menu list or leave it in the current menu list.
Your application is also responsible for storing the current value of the menu item,
drawing the text and downward-pointing indicator in the pop-up box, and
unhighlighting the pop-up title after calling PopUpMenuSelect. If you use the standard
pop-up control definition function, these actions are performed for you by the pop-up
control and your application does not need to call PopUpMenuSelect.
When implementing pop-up menus, you should follow the guidelines for pop-up menus
described in Macintosh Human Interface Guidelines. For example, you should define the
pop-up box of your pop-up menu as a rectangle that is the same height as a menu item,
with a one-pixel drop shadow, and should make the pop-up box wide enough to show
the currently selected item and a downward-pointing indicator.
SystemMenu 3
The MenuSelect and MenuKey functions call the SystemMenu procedure when the
user chooses an item in a menu that belongs to a desk accessory launched in your
application’s partition. Your application should not need to call the SystemMenu
procedure.
menuResult The value that indicates the menu and menu item chosen by the user. The
menu ID is in the high-order word, and the menu item is in the low-order
word. The menu ID for a menu belonging to a desk accessory is a negative
number.
DESCRIPTION
The SystemMenu procedure directs the desk accessory to perform the appropriate action
for the given menu item by calling the desk accessory’s control routine and passing the
accMenu constant in the csCode parameter. The desk accessory should perform the
desired action and return. See Inside Macintosh: Devices for more information on desk
accessories.
ASSEMBLY-LANGUAGE INFORMATION
If you’re writing a desk accessory, you may need to set the MBarEnable global variable
to appropriate values. If the MBarEnable global variable is nonzero, then all menus in
the current menu bar belong to a desk accessory. If the MBarEnable global variable is 0,
then all menus in the current menu bar belong to an application. If you’re writing an
application, you should not change the value of the MBarEnable global variable.
Menu Manager
SystemEdit 3
When the user chooses one of the standard editing commands in the Edit menu (Undo,
Cut, Copy, Paste, and Clear), call the SystemEdit function to determine whether the
active window belongs to a desk accessory that is launched in your application’s
partition. If so, the SystemEdit function directs the desk accessory to perform the
editing command and returns TRUE. If the active window does not belong to a desk
accessory launched in your application’s partition, SystemEdit returns FALSE and your
application should process the command.
editCmd The item number of the standard editing command chosen by the user.
GetMenuHandle 3
You can use the GetMenuHandle function to get a handle to the menu record of any of
your application’s menus other than its Help menu. (Use the HMGetHelpMenuHandle
function to get a handle to the menu record of your application’s Help menu.) The
GetMenuHandle function is also available as the GetMHandle function.
menuID The menu ID of the menu. (Note that this is not the resource ID,
although you often assign the menu ID so that it matches the resource ID.)
You assign a menu ID in the 'MENU' resource of a menu. If you
do not define your menus in 'MENU' resources, you can assign a menu
ID using NewMenu.
DESCRIPTION
The GetMenuHandle function returns a handle to the menu record of the menu having
the specified menu ID. If the menu is in the current menu list, GetMenuHandle returns a
handle to the menu record of the menu as its function result. Otherwise,
GetMenuHandle returns NIL as its function result.
Menu Manager
SPECIAL CONSIDERATIONS
To get a handle to a menu record of a pop-up menu that you create using the pop-up
control definition function, dereference the cntrlData field of the pop-up menu’s
control record instead of using GetMenuHandle.
HMGetHelpMenuHandle 3
Use the HMGetHelpMenuHandle function to get a handle to the menu record of your
application’s Help menu.
DESCRIPTION
The HMGetHelpMenuHandle function returns in the mh parameter a copy of a handle to
the menu record of your application’s Help menu. With this handle, you can append
items to your application’s Help menu by using the AppendMenu procedure or other
related Menu Manager routines. The Help Manager automatically adds the divider that
separates your items from the rest of the Help menu items.
Be sure to define help balloons for your items in the Help menu by creating an 'hmnu'
resource and specifying the kHMHelpMenuID constant as its resource ID.
The Menu Manager functions MenuSelect and MenuKey return a result with the menu
ID in the high-order word and the menu item in the low-order word. The MenuSelect
function (and the MenuKey function, if the user chooses an item with a keyboard
equivalent) returns the kHMHelpMenuID constant in the high-order word when the user
chooses an appended item from the Help menu. The menu item number of the appended
menu item is returned in the low-order word of the function result. Apple reserves the
right to change the number of standard items in the Help menu. To determine the
number of items in the Help menu, call the CountMItems function.
SPECIAL CONSIDERATIONS
Do not use the GetMenuHandle function to get a handle to the menu record of the Help
menu. GetMenuHandle returns a handle to the menu record of the global Help menu,
not the menu record of the Help menu that is specific to your application.
RESULT CODES
noErr 0 No error
paramErr –50 Error in parameter list
memFullErr –108 Not enough room in heap zone
resNotFound –192 Unable to read resource
hmHelpManagerNotInited –855 Help menu not set up
Menu Manager
SEE ALSO
For examples of how to add items to your application’s Help menu and how to handle
the user’s choice of an item in the Help menu, see Listing 3-14 on page 3-68 and
Listing 3-26 on page 3-81. See the chapter “Help Manager” in Inside Macintosh: More
Macintosh Toolbox for information on creating help balloons for the menus of
your application.
AppendMenu 3
Use the AppendMenu procedure to append one or more items to a menu previously
created using NewMenu, GetMenu, or GetNewMBar.
menu A handle to the menu record of the menu to which you wish to append
the menu item or items.
data A string that defines the characteristics of the new menu item or items.
Note that in most cases you should store the text of a menu item in a
resource, so that your menu items can be more easily localized. The
AppendMenu procedure appends the menu items in the order in which
they are listed in the data parameter.
DESCRIPTION
The AppendMenu procedure appends any defined menu items to the specified menu. The
menu items are added to the end of the menu. You specify the text of any menu items
and their characteristics in the data parameter. You can embed metacharacters in the
string to define various characteristics of a menu item.
Menu Manager
Here are the metacharacters that you can specify in the data parameter:
Metacharacter Description
; or Return Separates menu items.
^ When followed by an icon number, defines the icon for the item. If the
keyboard equivalent field contains $1C, this number is interpreted as
a script code.
! When followed by a character, defines the mark for the item. If the
keyboard equivalent field contains $1B, this value is interpreted as
the menu ID of a submenu of this menu item.
< When followed by one or more of the characters B, I, U, O, and S,
defines the character style of the item to Bold, Italic, Underline,
Outline, or Shadow, respectively.
/ When followed by a character, defines the keyboard equivalent for the
item. When followed by $1B, specifies that this menu item has a
submenu. To specify that the menu item has a script code, small icon,
or reduced icon, use the SetItemCmd procedure to set the keyboard
equivalent field to $1C, $1D, or $1E, respectively.
( Defines the menu item as disabled.
You can specify any, all, or none of these metacharacters in the text string. The
metacharacters that you specify aren’t displayed in the menu item. (To use any of these
metacharacters in the text of a menu item, first use AppendMenu, specifying at least one
character as the item’s text, and then use the SetMenuItemText procedure to set the
item’s text to the desired string.)
Note
If you add menu items using the AppendMenu procedure, you should
define the text and any marks or keyboard equivalents in resources for
easier localization. ◆
You can specify the first character that defines the text of a menu item as a hyphen to
create a divider line. The string in the data parameter can be blank (containing one or
more spaces), but it should not be an empty string.
If you do not define a specific characteristic of a menu item, the AppendMenu procedure
assigns the default characteristic to the menu item. If you do not define any characteristic
other than the text for a menu item, the AppendMenu procedure inserts the menu item so
that it appears in the menu as an enabled item, without an icon or a mark, in the plain
character style, and without a keyboard equivalent.
You can use AppendMenu to append items to a menu regardless of whether the menu is
in the current menu list.
SEE ALSO
See “Adding Items to a Menu” on page 3-64 for examples of appending items to a menu.
Menu Manager
InsertMenuItem 3
Use the InsertMenuItem procedure to insert one or more items to a menu previously
created using NewMenu, GetMenu, or GetNewMBar.
The InsertMenuItem procedure is also available as the InsMenuItem procedure.
theMenu A handle to the menu record of the menu to which you wish to add the
menu item or items.
itemString
A string that defines the characteristics of the new menu items. Note that
in most cases you should store the text of a menu item in a resource, so
that your menu items can be more easily localized. You can specify the
contents of the itemString parameter using metacharacters; the
InsertMenuItem procedure accepts the same metacharacters as the
AppendMenu procedure. However, if you specify multiple items, the
InsertMenuItem procedure inserts the items in the reverse of their order
in the itemString parameter.
afterItem The item number of the menu item after which the new menu items are to
be added. Specify 0 in the afterItem parameter to insert the new items
before the first menu item; specify the item number of a current menu
item to insert the new menu items after it; specify a number greater than
or equal to the last item in the menu to append the new items to the end of
the menu.
DESCRIPTION
The InsertMenuItem procedure inserts any defined menu items to the specified menu.
The menu items are inserted according to the location specified by the afterItem
parameter. You specify the text of any menu items and their characteristics in the
itemString parameter. You can embed metacharacters in the string you specify to
define various characteristics of a menu item. The metacharacters aren’t displayed in
the menu.
Here are the metacharacters you can specify in the itemString parameter:
Metacharacter Description
; or Return Separates menu items.
^ When followed by an icon number, defines the icon for the item. If the
keyboard equivalent field contains $1C, this number is interpreted as
a script code.
! When followed by a character, defines the mark for the item. If the
keyboard equivalent field contains $1B, this value is interpreted as
the menu ID of a submenu of this menu item.
Menu Manager
Metacharacter Description
< When followed by one or more of the characters B, I, U, O, and S,
defines the character style of the item to Bold, Italic, Underline,
Outline, or Shadow, respectively.
/ When followed by a character, defines the keyboard equivalent for the
item. When followed by $1B, specifies that this menu item has a
submenu. To specify that the menu item has a script code, small icon,
or reduced icon, use the SetItemCmd procedure to set the keyboard
equivalent field to $1C, $1D, or $1E, respectively.
( Defines the menu item as disabled.
You can specify any, all, or none of these metacharacters in the text string. The
metacharacters that you specify aren’t displayed in the menu item. To use any of these
metacharacters in the text of a menu item, first use InsertMenuItem, specifying at least
one character as the item’s text, and then use the SetMenuItemText procedure to set
the item’s text to the desired string.
Note
If you add menu items using the InsertMenuItem procedure, you
should define the text and any marks or keyboard equivalents in
resources for easier localization. ◆
You can specify the first character that defines the text of a menu item as a hyphen to
create a divider line. The string in the itemString parameter can be blank (containing
one or more spaces), but it should not be an empty string.
If you do not define a specific characteristic of a menu item, the InsertMenuItem
procedure assigns the default characteristic to the menu item. If you do not define any
characteristic other than the text for a menu item, the InsertMenuItem procedure
inserts the menu item so that it appears in the menu as an enabled item, without an icon
or a mark, in the plain character style, and without a keyboard equivalent.
You can use InsertMenuItem to insert items into a menu regardless of whether the
menu is in the current menu list.
SEE ALSO
See “Adding Items to a Menu” beginning on page 3-64 for examples.
DeleteMenuItem 3
Menu Manager
theMenu A handle to the menu record of the menu from which you want to delete
the menu item.
item The item number of the menu item to delete. If you specify 0 or a number
greater than the last item in the menu, DeleteMenuItem does not delete
any item from the menu.
DESCRIPTION
The DeleteMenuItem procedure deletes a specified menu item from a menu. The
DeleteMenuItem procedure also deletes the item’s menu item entry from your
application’s menu color information table (if an entry exists). You should not delete
items from an existing menu unless the user expects the menu (such as a menu that lists
open documents) to change.
AppendResMenu 3
Use the AppendResMenu procedure to search all resource files open to your application
for a given resource type and to append the names of any resources it finds to a specified
menu. The specified menu must have been previously created using NewMenu, GetMenu,
or GetNewMBar.
The AppendResMenu procedure is also available as the AddResMenu procedure.
theMenu A handle to the menu record of the menu to which to append the names
of any resources of a given type that AppendResMenu finds.
theType A four-character code that identifies the resource type for which to search.
DESCRIPTION
The AppendResMenu procedure searches all resource files open to your application for
resources of the type defined by the parameter theType. It appends the names of any
resources it finds of the given type to the end of the specified menu. AppendResMenu
appends the names of found resources in alphabetical order; it does not alphabetize items
already in the menu. The AppendResMenu procedure does not add resources with
names that begin with a period (.) or a percent sign (%) to the menu.
The AppendResMenu procedure assigns default characteristics to each menu item. Each
appended menu item appears in the menu as an enabled item, without an icon or a mark,
in the plain character style, and without a keyboard equivalent. To get the name or to
change other characteristics of an item appended by AppendResMenu, use the Menu
Manager routines described in “Getting and Setting the Appearance of Menu Items”
beginning on page 3-130.
Menu Manager
If you specify that AppendResMenu add resources of type 'DRVR' to your Apple menu,
AppendResMenu adds the name (and icon) of each item in the Apple Menu Items folder
to the menu.
If you specify that AppendResMenu append resources of type 'FONT' or 'FOND', the
Menu Manager performs special processing for any resources it finds that have font
numbers greater than $4000. If the script system associated with the font name is installed
in the system, AppendResMenu stores information in the itemDefinitions array (in
the itemIcon and itemCmd fields for that item) in the menu’s menu record. This allows
the Menu Manager to display the font name in the correct script.
SPECIAL CONSIDERATIONS
The AppendResMenu procedure calls the Resource Manager procedure SetResLoad
(specifying TRUE in the load parameter) before returning. The AppendResMenu
procedure reads the resource data of the resources it finds into memory. If your
application does not want the Resource Manager to read resource data into memory
when your application calls other routines that read resources, you need to call
SetResLoad and specify FALSE in the load parameter after AppendResMenu returns.
SEE ALSO
Listing 3-15 on page 3-69 shows a sample that adds items from the Apple Menu Items
folder to the Apple menu, and Listing 3-16 on page 3-70 shows a sample that adds font
names to a menu. See Inside Macintosh: More Macintosh Toolbox for information on the
Resource Manager.
InsertResMenu 3
Use the InsertResMenu procedure to search all resource files open to your application
for a given resource type and to insert the names of any resources it finds to a specified
menu. The items are inserted after the specified menu item. The specified menu must
have been previously created using NewMenu, GetMenu, or GetNewMBar.
theMenu A handle to the menu record of the menu to which to add the names of
any resources of a given type that InsertResMenu finds.
theType A four-character code that identifies the resource type for which to search.
afterItem A number that indicates where in the menu to insert the names of any
resources of the given type that InsertResMenu finds. Specify 0 in the
afterItem parameter to insert the items before the first menu item;
specify the item number of a menu item already in the menu to insert the
items after the specified item number. If you specify a number greater than
or equal to the last item in the menu, the items are inserted at the end of
the menu.
Menu Manager
DESCRIPTION
The InsertResMenu procedure searches all resource files open to your application for
resources of the type defined by the parameter theType. It inserts the names of any
resources it finds of the given type at the specified location in the specified menu.
InsertResMenu adds the names of found resources in alphabetical order; it does not
alphabetize items already in the menu.
The InsertResMenu procedure does not add resources with names that begin with a
period (.) or a percent sign (%) to the menu.
The InsertResMenu procedure assigns default characteristics to each menu item. Each
appended menu item appears in the menu as an enabled item, without an icon or a mark,
in the plain character style, and without a keyboard equivalent. To get the name or to
change other characteristics of an item appended by InsertResMenu, use the Menu
Manager routines described in the next section, “Getting and Setting the Appearance of
Menu Items.”
If you specify that InsertResMenu add resources of type 'DRVR' to your Apple menu,
InsertResMenu adds the name (and icon) of each item in the Apple Menu Items folder
to the menu.
If you specify that InsertResMenu add resources of type 'FONT' or 'FOND', the Menu
Manager performs special processing for any resources it finds that have font numbers
greater than $4000. If the script associated with the font name is currently active,
InsertResMenu stores information in the itemDefinitions array (in the itemIcon
and itemCmd fields for that item) in the menu’s menu record that allows the Menu
Manager to display the font name in the correct script.
SPECIAL CONSIDERATIONS
The InsertResMenu procedure calls the Resource Manager procedure SetResLoad
(specifying TRUE in the load parameter) before returning. The InsertResMenu
procedure reads the resource data of the resources it finds into memory. If your
application does not want the Resource Manager to read resource data into memory
when your application calls other routines that read resources, you need to call
SetResLoad and specify FALSE in the load parameter after InsertResMenu returns.
Menu Manager
EnableItem 3
theMenu A handle to the menu record of the menu containing the menu item
to enable.
item The item number of the menu item to enable, or 0 to enable the entire
menu. You cannot individually enable a menu item with an item number
greater than 31.
If you specify 0 in the item parameter, the EnableItem procedure
enables the menu title and all items in the menu that were not previously
individually disabled.
DESCRIPTION
The EnableItem procedure enables a specified menu item so that it no longer appears
dim and so that the user can choose the menu item.
Note that, if you enable a menu, the EnableItem procedure enables the menu title but
only enables those menu items that are not currently disabled as a result of your
application previously calling DisableItem and specifying each item’s item number.
For example, if all items in your application’s Edit menu are enabled, you can disable the
Cut and Copy commands individually using DisableItem. If you choose to disable the
entire menu by passing 0 as the item parameter to DisableItem, the menu and all its
items are disabled. If you then enable the entire menu by passing 0 as the item
parameter to EnableItem, the menu and its items are enabled, except for the Cut and
Copy commands, which remain disabled. In this case, to enable the Cut and Copy
commands you must enable each one individually using EnableItem.
If your application enables a menu using EnableItem, it should call DrawMenuBar to
update the menu bar’s appearance.
SEE ALSO
See “Enabling and Disabling Menu Items” on page 3-58 for examples of enabling items in
a menu.
DisableItem 3
Menu Manager
theMenu A handle to the menu record of the menu containing the menu item
to disable.
item The item number of the menu item to disable, or 0 to disable the entire
menu. You cannot individually disable a menu item with an item number
greater than 31.
If you specify 0 in the item parameter, the DisableItem procedure
disables the menu title and all items in the menu, including menu items
with item numbers greater than 31.
DESCRIPTION
The DisableItem procedure disables a specified menu item so that it appears dim and
cannot be chosen by the user.
If your application disables a menu using DisableItem, your application should call
DrawMenuBar to update the menu bar’s appearance.
SEE ALSO
See “Enabling and Disabling Menu Items” on page 3-58 for examples of disabling items
in a menu.
GetMenuItemText 3
Use the GetMenuItemText procedure to get the text of a specific menu item. The
GetMenuItemText procedure is also available as the GetItem procedure.
theMenu A handle to the menu record of the menu containing the menu item whose
text you wish to get.
item The item number of the menu item. The GetMenuItemText procedure
returns the text of this item.
itemString The GetMenuItemText procedure returns the text of the menu item in
this parameter.
DESCRIPTION
The GetMenuItemText procedure returns the text of the specified menu item in the
itemString parameter. Use other Menu Manager routines to get information about
the other characteristics of a menu item.
Menu Manager
SetMenuItemText 3
Use the SetMenuItemText procedure to set the text of a specific menu item to a given
string. The SetMenuItemText procedure is also available as the SetItem procedure.
theMenu A handle to the menu record of the menu containing the menu item whose
text you wish you to set.
item The item number of the menu item. The SetMenuItemText procedure
sets the text of this item.
itemString The SetMenuItemText procedure sets the text of the menu item
according to the string specified in the itemString parameter. The
SetMenuItemText procedure does not recognize metacharacters or set
any other characteristics of the menu item. The itemString parameter
can be blank, but it should not be an empty string.
DESCRIPTION
The SetMenuItemText procedure sets the text of the specified menu item to the text
specified in the itemString parameter. The SetMenuItemText procedure does not
recognize any metacharacters used by the AppendMenu and InsertMenuItem
procedures. Use other Menu Manager routines to set other characteristics of a menu item.
If you set the text of a menu item using the SetMenuItemText procedure, you should
store the text in a string resource so that your application can be more easily localized.
SEE ALSO
See Listing 3-9 on page 3-59 for an example of setting the text of a menu item.
GetItemStyle 3
Use the GetItemStyle procedure to get the style of the text in a specific menu item.
theMenu A handle to the menu record of the menu containing the menu item whose
style you wish to get.
item The item number of the menu item. The GetItemStyle procedure
returns the style of the text for this item.
Menu Manager
chStyle The GetItemStyle procedure returns the style of the text for this item in
the chStyle parameter. The chStyle parameter is a set defined by the
Style data type.
TYPE
StyleItem = (bold, italic, underline, outline,
shadow, condense, extend);
Style = SET OF StyleItem;
DESCRIPTION
The GetItemStyle procedure returns the style of the text of the specified menu item in
the chStyle parameter. The returned style can be one or more of the styles defined by
the Style data type, or it is the empty set if the style of the text is Plain.
SetItemStyle 3
Use the SetItemStyle procedure to set the style of the text in a specific menu item.
theMenu A handle to the menu record of the menu containing the menu item whose
style you wish to set.
item The item number of the menu item. The SetItemStyle procedure sets
the style of the text for this item.
chStyle The SetItemStyle procedure sets the style of the text for this item
according to the style described by the chStyle parameter. The chStyle
parameter is a set defined by the Style data type.
TYPE
StyleItem = (bold, italic, underline, outline,
shadow, condense, extend);
Style = SET OF StyleItem;
You can set the style to one or more of the styles defined by the Style
data type, or you can set it to Plain by specifying an empty set in the
chStyle parameter.
DESCRIPTION
The SetItemStyle procedure sets the style of the text of the specified menu item to the
style or styles defined by the chStyle parameter.
SEE ALSO
See Listing 3-10 on page 3-60 for examples of setting the style of a menu item.
Menu Manager
GetItemMark 3
Use the GetItemMark procedure to get the mark of a specific menu item or the menu ID
of the submenu associated with the menu item.
theMenu A handle to the menu record of the menu containing the menu item whose
mark or submenu you wish to get.
item The item number of the menu item. The GetItemMark procedure returns
the mark of this item or, if this item has a submenu associated with it,
returns the menu ID of the submenu in the markChar parameter.
markChar The GetItemMark procedure returns the mark or the submenu of this
item in the markChar parameter. A menu item can have a mark or a
submenu attached to it, but not both. If this menu item has a marking
character, the GetItemMark procedure returns the mark. If this menu
item has a submenu associated with it, the GetItemMark procedure
returns the menu ID of the submenu. If the item doesn’t have a mark or
a submenu, GetItemMark returns 0 in this parameter.
DESCRIPTION
If the item has a mark or submenu, the GetItemMark procedure returns the mark or the
menu ID of the submenu of the specified menu item in the markChar parameter (or 0 if
the item doesn’t have a mark or a submenu).
SetItemMark 3
Use the SetItemMark procedure to set the mark of a specific menu item or to change or
set the submenu associated with a menu item.
theMenu A handle to the menu record of the menu containing the menu item whose
mark or submenu you wish to set.
item The item number of the menu item. The SetItemMark procedure sets the
mark or the submenu of this item.
markChar The SetItemMark procedure sets the mark or submenu of this item
according to the information in the markChar parameter.
Menu Manager
To set the mark of a menu item, specify the marking character in the
markChar parameter. You can also use one of these constants to specify
that the item has no mark, has a checkmark as the marking character, or
has the diamond symbol as the marking character:
CONST
noMark = 0; {no marking character}
checkMark = $12; {checkmark}
diamondMark = $13; {diamond symbol}
To set the submenu associated with this menu item, specify the menu ID
of the submenu in the markChar parameter.
DESCRIPTION
The SetItemMark procedure sets the mark or the submenu of the specified menu item.
SEE ALSO
See Listing 3-11 on page 3-61 for examples of setting the mark of a menu item.
CheckItem 3
Use the CheckItem procedure to set the mark of a specific menu item to a checkmark or
to remove a mark from a menu item.
theMenu A handle to the menu record of the menu containing the menu item whose
mark you wish to set to a checkmark or whose mark you wish to remove.
item The item number of the menu item.
checked The CheckItem procedure sets or removes the mark of the item according
to the information in the checked parameter.
To set the mark of a menu item to a checkmark, specify TRUE in the
checked parameter. To remove a checkmark or any other mark from a
menu item, specify FALSE in the checked parameter.
DESCRIPTION
The CheckItem procedure sets the mark of the specified menu item to a checkmark or
removes any mark from the menu item.
SEE ALSO
See Listing 3-11 on page 3-61 for examples of setting the mark of a menu item.
Menu Manager
GetItemIcon 3
Use the GetItemIcon procedure to get the icon or script code of a specific menu item. If
the menu item’s keyboard equivalent field contains $1C, the returned number represents
the script code of the menu item. Otherwise, the returned number represents the item’s
icon number.
theMenu A handle to the menu record of the menu containing the menu item whose
icon or script code you wish to get.
item The item number of the menu item. The GetItemIcon procedure returns
the icon number or script code of this item.
iconIndex For menu items that do not specify $1C in the keyboard equivalent field,
the GetItemIcon procedure returns the icon number of the item’s icon in
this parameter. The icon number returned in this parameter is a value
from 1 through 255 if the menu item has an icon associated with it and is 0
otherwise. You can add 256 to the icon number to generate the resource ID
of the 'cicn', 'ICON', or 'SICN' resource that describes the icon of the
menu item. For example, if the GetItemIcon procedure returns 5 in this
parameter, then the icon of the menu item is described by an icon resource
with resource ID 261.
For menu items that contain $1C in the keyboard equivalent field, the
GetItemIcon procedure returns the script code of the menu item. The
Menu Manager displays the menu item using this script code if the
corresponding script system is installed.
DESCRIPTION
The GetItemIcon procedure returns the icon number or script code of the specified
menu item in the iconIndex parameter (or 0 if the item doesn’t have an icon or a
script code).
SetItemIcon 3
Use the SetItemIcon procedure to set the icon number or script code of a specific menu
item. Usually you display menu items in the current system script; however, if needed,
you can use the SetItemIcon procedure to set the script code of a menu item. For an
item’s script code to be set, the keyboard equivalent field of the item must contain $1C. If
the keyboard equivalent field contains any other value, the SetItemIcon procedure
interprets the specified number as the item’s icon number.
Menu Manager
theMenu A handle to the menu record of the menu containing the menu item whose
icon (or script code) you wish to set.
item The item number of the menu item. The SetItemIcon procedure sets the
icon (or script code) of this item.
iconIndex If the menu item’s keyboard equivalent field does not contain $1C, the
SetItemIcon procedure sets the icon number of the item’s icon to the
number defined in this parameter. The icon number you specify should be
a value from 1 through 255 (or from 1 through 254 if the item has a small
or reduced icon) or 0 if the item does not have an icon.
The Menu Manager adds 256 to the icon number to generate the resource
ID of the 'cicn' or 'ICON' resource that describes the icon of the menu
item. For example, if you specify 5 as the value of the iconIndex
parameter, when the Menu Manager needs to draw the item, it looks for
an icon resource with resource ID 261.
If the menu item’s keyboard equivalent field contains $1C, the
SetItemIcon procedure sets the script code of the menu item to the
number defined in the iconIndex parameter. The Menu Manager
displays the menu item using the specified script code if the
corresponding script system is installed.
You can specify 0 in the iconIndex parameter to indicate that the item
uses the current system script and does not have an icon number.
DESCRIPTION
The SetItemIcon procedure sets the icon number or script code of the specified menu
item to the value in the iconIndex parameter.
SEE ALSO
See “Changing the Icon or Script Code of Menu Items” beginning on page 3-62 for
examples of setting the icon of a menu item.
GetItemCmd 3
Use the GetItemCmd procedure to get the value of the keyboard equivalent field of a
menu item.
theMenu A handle to the menu record of the menu containing the menu item whose
keyboard equivalent field you wish to get.
item The item number of the menu item. The GetItemCmd procedure returns
the keyboard equivalent field of this item.
Menu Manager
cmdChar The value of the item’s keyboard equivalent field. The Menu Manager
uses this value to map keyboard equivalents to menu commands or to
indicate special characteristics of the menu item.
If the cmdChar parameter contains $1B, the menu item has a submenu; a
value of $1C indicates that the item has a script code; a value of $1D
indicates that the Menu Manager reduces the item’s 'ICON' resource; and
a value of $1E indicates that the item has an 'SICN' resource.
DESCRIPTION
The GetItemCmd procedure returns the value in the keyboard equivalent field of the
specified menu item in the cmdChar parameter (or 0 if the item doesn’t have a keyboard
equivalent, submenu, script code, reduced icon, or small icon).
SetItemCmd 3
Use the SetItemCmd procedure to set the value of the keyboard equivalent field of a
menu item. You usually define the keyboard equivalents and other characteristics of your
menu items in 'MENU' resources rather than using the SetItemCmd procedure.
theMenu A handle to the menu record of the menu containing the menu item whose
keyboard equivalent field you wish to set.
item The item number of the menu item. The SetItemCmd procedure sets the
keyboard equivalent field of this item to the value specified in the
cmdChar parameter.
cmdChar The value of the item’s keyboard equivalent field. The Menu Manager
uses this value to map keyboard equivalents to menu commands or to
define special characteristics of the menu item.
To indicate that the menu item has a submenu, specify $1B in the
cmdChar parameter; specify a value of $1C to indicate that the item has a
script code; specify a value of $1D to indicate that the Menu Manager
should reduce the item’s 'ICON' resource to the size of a small icon; and
specify a value of $1E to indicate that the item has an 'SICN' resource.
The values $01 through $1A, as well as $1F and $20, are reserved for use
by Apple. You should not use any of these reserved values in the cmdChar
parameter.
DESCRIPTION
The SetItemCmd procedure sets the value in the keyboard equivalent field of the
specified menu item in the cmdChar parameter (you can specify 0 if the item doesn’t
have a keyboard equivalent, submenu, script code, reduced icon, or small icon). If you
Menu Manager
specify that the item has a submenu, you should provide the menu ID of the submenu as
the item’s marking character. If you specify that the item has a script code, provide the
script code in the icon field of the menu item. If you specify that the item has an 'SICN'
or a reduced'ICON' resource, provide the icon number in the icon field of the item.
Disposing of Menus 3
If you no longer need a menu in the menu list, you can delete the menu using
DeleteMenu. You should then release the memory associated with that menu using
the DisposeMenu procedure if you created the menu using NewMenu; otherwise,
use the Resource Manager procedure ReleaseResource. See the chapter “Resource
Manager” in Inside Macintosh: More Macintosh Toolbox for information on the
ReleaseResource routine.
DisposeMenu 3
To release the memory occupied by a menu’s associated data structures, use either the
DisposeMenu procedure or the Resource Manager procedure ReleaseResource.
Use DisposeMenu if you created the menu using NewMenu; use ReleaseResource if
you created the menu using GetMenu or read the resource in using GetNewMBar.
You should delete the menu from the current menu list using DeleteMenu or
ClearMenuBar before calling the DisposeMenu procedure.
theMenu A handle to the menu record of the menu you wish to dispose of.
DESCRIPTION
The DisposeMenu procedure releases the memory occupied by the specified menu’s
menu record. The handle that you pass in the parameter theMenu is not valid after
DisposeMenu returns.
SEE ALSO
To delete a menu from the current menu list, see the description of the DeleteMenu
procedure on page 3-109.
Menu Manager
CountMItems 3
You can count the number of items in a menu using the CountMItems function.
theMenu A handle to the menu record of the menu whose items your application
needs to count.
DESCRIPTION
The CountMItems function counts the number of items in the specified menu and
returns as its function result the number of items in the menu.
FlashMenuBar 3
Use the FlashMenuBar procedure to highlight (invert) a menu title or the entire menu
bar. You can call FlashMenuBar twice in a row to make the menu bar blink.
menuID The menu ID of the menu whose title you want to invert. Use 0 in this
parameter to invert the entire menu bar. If the specified menu ID does not
exist in the current menu list, the FlashMenuBar procedure inverts the
entire menu bar.
DESCRIPTION
The FlashMenuBar procedure inverts the title of the specified menu or inverts the menu
bar. To prevent unexpected colors from appearing in the menu bar, you should
not call FlashMenuBar to invert a menu title while the entire menu bar is inverted.
Menu Manager
Only one menu title can be inverted at a time. If no menus are currently highlighted,
calling FlashMenuBar with a specific menu ID inverts the title of that menu. If you call
FlashMenuBar again specifying another menu ID that is different from that of the
previously inverted menu title, FlashMenuBar restores the previously highlighted
menu to normal and then inverts the title of the specified menu.
SEE ALSO
You can also highlight a menu using the HiliteMenu procedure, described on
page 3-119.
SetMenuFlash 3
Use the SetMenuFlash procedure to set the number of times a menu item blinks when
the user chooses an enabled menu item. The user sets this value using the General
Controls panel, and in most cases your application should not change the value set by the
user.
count The number of times an enabled menu item should blink when the user
chooses it. This value is initially set to 3 by the General Controls panel. A
count of 0 disables the blinking. Values greater than 3 can be slow and
distracting to the user.
DESCRIPTION
The SetMenuFlash procedure sets the number of times that the Menu Manager causes a
menu item to blink when the user chooses an enabled menu item.
The appearance of blinking in a menu item is determined by the menu’s menu definition
procedure.
ASSEMBLY-LANGUAGE INFORMATION
The global variable MenuFlash contains the current count (number of times) a menu
item blinks when chosen by the user.
Menu Manager
CalcMenuSize 3
theMenu A handle to the menu record of the menu whose dimensions need
recalculating.
DESCRIPTION
The CalcMenuSize procedure uses the menu definition procedure of the specified menu
to calculate the dimensions of the menu.
GetMCInfo 3
Use the GetMCInfo function to get a handle to a copy of your application’s menu color
information table.
Menu Manager
DESCRIPTION
The GetMCInfo function creates a copy of your application’s menu color information
table and returns a handle to the copy. If the copy fails, GetMCInfo returns NIL.
SEE ALSO
See “The Menu Color Information Table Record” beginning on page 3-98 for a
description of the format of the menu color information table.
SetMCInfo 3
Use the SetMCInfo procedure to set your application’s menu color information table.
DESCRIPTION
The SetMCInfo procedure copies the table specified by the menuCTbl parameter
to your application’s menu color information table. If successful, the SetMCInfo
procedure is responsible for disposing of your application’s current menu color
information table, so your application does not need to explicitly dispose of the
current table.
Your application should call the Memory Manager function MemError to determine
whether the SetMCInfo procedure successfully copied the table. If the SetMCInfo
procedure cannot successfully copy the table, it does not dispose of the current menu
color information table and the MemError function returns a nonzero result code. If the
SetMCInfo procedure is able to successfully copy the table, it disposes of the current
menu color information table and the MemError function returns the noErr result code.
If the menu color information table specifies a new menu bar color or new menu title
colors, your application should call DrawMenuBar after calling SetMCInfo.
Note that GetNewMBar does not save your application’s current menu color information
table. If your application changes menu bars, you can save and restore your application’s
current menu color information table by calling GetMCInfo before GetNewMBar and
calling SetMCInfo afterward.
SEE ALSO
See “The Menu Color Information Table Record” beginning on page 3-98 for a
description of the format of the menu color information table. For an example of using
the GetMCInfo and SetMCInfo routines to save and restore menu color information,
see Listing 3-6 on page 3-52. See Inside Macintosh: Memory for information on the
MemError function
Menu Manager
DisposeMCInfo 3
Use the DisposeMCInfo procedure to dispose of a menu color information table. The
DisposeMCInfo procedure is also available as the DispMCInfo procedure.
DESCRIPTION
The DisposeMCInfo procedure disposes of the menu color information table referred to
by the menuCTbl parameter.
GetMCEntry 3
Use the GetMCEntry function to return information about an entry in your application’s
menu color information table. You can get information about the menu bar entry, a menu
title entry, or a menu item entry.
menuID The menu ID that the GetMCEntry function should use to return
information about the menu color information table. Specify 0 in the
menuID parameter (and the menuItem parameter) to get the menu bar
entry. Specify the menu ID of a menu in the current menu list in the
menuID parameter and 0 in the menuItem parameter to get a specific
menu title entry. Specify the menu ID of a menu in the current menu list in
the menuID parameter and an item number in the menuItem parameter
to get a specific menu item entry.
menuItem The menu item that the GetMCEntry function should use to return
information about the menu color information table. If you specify 0 in
this parameter, GetMCEntry returns either the menu bar entry or the
menu title entry, depending on the value of the menuID parameter. If you
specify the item number of a menu item in this parameter and the menu
ID of a menu in the current menu list in the menuID parameter,
GetMCEntry returns a specific menu item entry.
DESCRIPTION
The GetMCEntry function returns a menu bar entry, a menu title entry, or a menu item
entry according to the values specified in the menuID and menuItem parameters. If
the GetMCEntry function finds the specified entry in your application’s menu color
information table, it returns a pointer to a record of data type MCEntry. If the specified
entry is not found, GetMCEntry returns NIL.
Menu Manager
▲ WARNING
The menu color information table is relocatable, so the pointer returned
by the GetMCEntry function may not be valid across routines that may
move or purge memory. Your application should make a copy of the
menu color entry record if necessary. ▲
SEE ALSO
“The Menu Color Information Table Record” beginning on page 3-98 describes the entries
in a menu color information table.
SetMCEntries 3
Use the SetMCEntries procedure to set entries in your application’s menu color
information table. You can set any or all of your application’s menu item entries and
menu title entries or the menu bar entry.
numEntries The number of entries contained in the array of menu color entry records.
menuCEntries
A pointer to an array of menu color entry records. Specify the number of
records in the array in the numEntries parameter.
DESCRIPTION
The SetMCEntries procedure sets any specified menu bar entry, menu title entry, or
menu item entry according to the values specified in the menu color entry records. If
an entry already exists for a specified menu color entry, the SetMCEntries procedure
updates the entry in your application’s menu color information table with the new
values. If the entry doesn’t exist, it is added to your application’s menu color information
table.
If any of the added entries specify a new menu bar color or new menu title colors, your
application should call DrawMenuBar to update the menu bar with the new colors.
SPECIAL CONSIDERATIONS
The SetMCEntries procedure may move or purge memory. Your application should
make sure that the array specified by the menuCEntries parameter is nonrelocatable
before calling SetMCEntries.
Menu Manager
SEE ALSO
“The Menu Color Information Table Record” beginning on page 3-98 describes the entries
in a menu color information table.
DeleteMCEntries 3
Use the DeleteMCEntries procedure to delete one or all entries for a specific menu
from your application’s menu color information table. You can delete a menu item entry,
a menu title entry, the menu bar entry, or all menu item entries of a specific menu. The
DeleteMCEntries procedure is also available as the DelMCEntries procedure.
DESCRIPTION
The DeleteMCEntries procedure deletes a menu bar entry, a menu title entry, a menu
item entry, or all menu item entries of a given menu, according to the values specified in
the menuID and menuItem parameters. If the GetMCEntry function does not find the
specified entry in your application’s menu color information table, it does not delete the
entry. Your application should not delete the last entry in your application’s menu color
information table.
If any of the deleted entries changes the menu bar color or a menu title color, your
application should call DrawMenuBar to update the menu bar.
Menu Manager
Application-Defined Routine 3
Apple provides a standard menu definition procedure and standard menu bar definition
function. The Menu Manager uses the menu definition procedure and menu bar
definition function to display and perform basic operations on menus and the menu bar.
Although the Menu Manager allows you to provide your own menu bar definition
function, Apple recommends that you use the standard menu bar definition function.
Similarly, in most cases the standard menu definition procedure should meet the needs of
most applications. However, if your application has special needs, you can choose to
provide your own menu definition procedure. If you do so, define your menu definition
procedure so that it emulates the standard behavior of menus as much as possible. If you
define your own menus, they should follow the guidelines described in this chapter and
in Macintosh Human Interface Guidelines.
MyMenuDef 3
You can provide your own menu definition procedure if you need special features in a
menu other than those provided by the standard menu definition procedure. This section
describes how to define your own menu definition procedure, defines the parameters
passed to your procedure by the Menu Manager, and describes the general actions your
procedure should perform.
message A number that identifies the operation that the menu definition proce-
dure should perform. The message parameter can contain any one of
these values:
Menu Manager
CONST
mDrawMsg = 0; {draw the menu}
mChooseMsg = 1; {tell which item was chosen }
{ and highlight it}
mSizeMsg = 2; {calculate menu dimensions}
mPopUpMsg = 3; {calculate rectangle of }
{ the pop-up box}
Your menu definition procedure should not respond to any value other
than the four constants listed above.
theMenu A handle to the menu record of the menu that the operation should affect.
menuRect The rectangle (in global coordinates) in which the menu is located; the
Menu Manager provides this information to the menu definition
procedure only when the value in the message parameter is the
mDrawMsg or mChooseMsg constant.
When the value in the message parameter is the mPopUpMsg constant,
the menu definition procedure should calculate and then return the
dimensions of the pop-up box in this parameter. When the value in the
message parameter is the mSizeMsg constant, the menu definition
procedure should calculate the horizontal and vertical dimensions of the
menu rectangle and store these values in the menuWidth and
menuHeight fields of the menu record.
hitPt A mouse location (in global coordinates). The Menu Manager provides
information in this parameter to the menu definition procedure when the
value in the message parameter is the mChooseMsg or mPopUpMsg
constant. When the menu definition procedure receives the mChooseMsg
constant in the message parameter, it should determine whether the
mouse location specified in the hitPt parameter is in an enabled menu
item and highlight or unhighlight the item specified in the whichItem
parameter appropriately. When the menu definition procedure receives
the mPopUpMsg constant in the message parameter, the hitPt parameter
contains the top-left coordinates of the closed pop-up box, which your
procedure can use to calculate the rectangle of the open pop-up box.
whichItem The item number of the last item chosen from this menu (or 0 if an item
hasn’t been chosen). The Menu Manager provides information in this
parameter to the menu definition procedure when the value in the
message parameter is the mChooseMsg constant. When the menu
definition procedure receives the mChooseMsg constant in the
message parameter, it should determine whether the mouse location
specified in the hitPt parameter is in an enabled menu item. If so, the
menu definition procedure should unhighlight the item specified by
the whichItem parameter, highlight the new item, and return the new
item number in whichItem. If the mouse location isn’t in an enabled
menu item, the menu definition procedure should unhighlight the
item specified by the whichItem parameter and return 0 in the
whichItem parameter.
Menu Manager
DESCRIPTION
The Menu Manager calls your menu definition procedure whenever it needs your
definition procedure to perform a certain action on a specific menu. The action
your menu definition procedure should perform depends on the value of the
message parameter.
If you provide your own menu definition procedure, store it in a resource of type 'MDEF'
and include its resource ID in the description of each menu that uses your own definition
procedure. If you create a menu using GetMenu (or GetNewMBar), the Menu Manager
reads the menu definition procedure into memory and stores a handle to it in the
menuProc field of the menu’s menu record.
If you create a menu using NewMenu, the Menu Manager stores a handle to the standard
menu definition procedure in the menuProc field of the menu’s menu record. In this case
you must replace the value in the menuProc field with a handle to your own procedure
and then call the CalcMenuSize procedure. If your menu definition procedure is in a
resource file, you can get its handle by using the Resource Manager to read it from the
resource file into memory. However, note that you should usually store your menus in
resources (rather than using NewMenu) to make your application easier to localize. See
the “Resource Manager” chapter in Inside Macintosh: More Macintosh Toolbox for
information on the Resource Manager.
The menu definition procedure is responsible for drawing the contents of the menu and
its menu items, determining whether the cursor is in a displayed menu, highlighting and
unhighlighting menu items, and calculating a menu’s dimensions.
When the Menu Manager requests your menu definition procedure to perform an action
on a menu, it provides your procedure with a handle to its menu record. This allows your
procedure to access the data in the menu record and to use any data in the variable data
portion of the menu record to appropriately handle the menu items.
When the Menu Manager creates a menu as a result of an application calling GetMenu or
GetNewMBar, it fills out the menuID, menuProc, enableFlags, menuTitle, and
itemDefinitions fields of the menu record according to its resource definition. If the
menu is managed by your menu definition procedure, the Menu Manager calls your
procedure (specifying mSizeMsg) to calculate and fill in the menuHeight and
menuWidth fields of the menu record. The menu items are described by a variable length
field (itemDefinitions) in the menu record. Your menu definition procedure can
define and use this variable-length data in any manner it chooses.
For pop-up menus that are not implemented as controls, the Menu Manager uses the
menu definition procedure to support pop-up menus. If your menu definition procedure
supports pop-up menus, it should respond appropriately to the mPopUpMsg constant.
The Menu Manager specifies the mPopUpMsg constant in the message parameter and
calls your menu definition procedure whenever it needs to calculate the rectangle
bounded by the pop-up box for a pop-up menu that is managed by your menu definition
procedure. The parameter theMenu contains a handle to the menu record
of the pop-up menu, the hitPt parameter contains the top-left coordinates of the pop-
up box, and whichItem contains the previously chosen item. Your menu definition
procedure should calculate the rectangle in which the pop-up menu is to appear
Menu Manager
and return this rectangle in the menuRect parameter. If the menu is so large that it
scrolls, return the actual top of the menu in the whichItem parameter. For pop-up
menus, your menu definition procedure also must place the pop-up menu’s scrolling
information in the global variables TopMenuItem and AtMenuBottom. Place in
TopMenuItem the pixel value of the top of the scrollable menu, and place in
AtMenuBottom the pixel value of the bottom of the scrollable menu.
Note
Your menu definition procedure should not assume that the A5
register is properly set up, so your procedure can’t refer to any of
the QuickDraw global variables. ◆
SEE ALSO
For additional information on how your menu definition procedure should respond
when it receives the mDrawMsg, mChooseMsg, or mSizeMsg constant in the message
parameter, see “Writing Your Own Menu Definition Procedure” beginning on page 3-87.
Resources 3
This section describes the menu ('MENU') resource, menu bar ('MBAR') resource, and
menu color information table ('mctb') resource. Usually you should define your menus
using 'MENU' resources, define the menus in your menu bar in an 'MBAR' resource, and
use the GetNewMBar function to read in the descriptions of your menus and menu bar.
If you want to use colors other than the default colors in a menu, you can provide an
'mctb' resource with the same resource ID as its corresponding 'MENU' resource, or
you can provide an 'mctb' resource with resource ID 0 to define colors for all your
menus and your menu bar.
If you choose to provide your own menu definition procedure, you should store your
routine in an 'MDEF' resource.
To create a 'MENU', an 'MBAR', or an 'mctb' resource, either you can specify the
resource description in an input file and compile the resource using a resoure compiler,
such as Rez, or you can directly create your resources in a resource file using a tool such
as ResEdit. This section describes the structures of these resources after they are compiled
by the Rez resource compiler. If you are interested in creating the Rez input files for these
resources, see “Using the Menu Manager,” beginning on page 3-41, for detailed
information.
Menu Manager
▲ WARNING
Menus in a resource must not be purgeable. ▲
Figure 3-37 shows the format of a compiled 'MENU' resource. See Listing 3-1 on
page 3-43 for a description of a 'MENU' resource in Rez input format.
Menu ID 2
Placeholder 2
Placeholder 1
Menu Manager
reading in the menu’s resource data, the Menu Manager reads in the menu definition
procedure, if necessary. The Menu Manager stores a handle to the menu’s menu
definition procedure in the menuProc field of the menu record.
■ Placeholder (an integer containing 0).
■ The initial enabled state of the menu and first 31 menu items. This is a 32-bit value,
where bits 1–31 indicate if the corresponding menu item is disabled or enabled, and bit
0 indicates whether the menu is enabled or disabled. The Menu Manager
automatically enables menu items greater than 31 when a menu is created.
■ The length (in bytes) of the menu title.
■ The title of the menu.
■ Variable-length data that describes the menu items. If you provide your own menu
definition procedure, you can define and provide this variable-length data according
to the needs of your procedure. The Menu Manager simply reads in the data for each
menu item and stores it as variable data at the end of the menu record. The menu
definition procedure is responsible for interpreting the contents of the data. For
example, the standard menu definition procedure interprets this data according to the
description given in the following paragraphs.
■ Placeholder (a byte containing 0) to indicate the end of the menu item definitions.
If you use the standard menu definition procedure, your 'MENU' resource should
describe the menu items in this manner. For each menu item, you need to provide its text,
the icon number, the keyboard equivalent or other value ($1B to indicate the menu item
has a submenu, $1C to indicate a script code other than the system script for the item’s
text, $1D to indicate the item’s icon should be reduced, or $1E to indicate that an 'SICN'
icon should be used), the marking character of the menu item or menu ID of the menu
item’s submenu, and the font style of the menu item’s text. If an item doesn’t have a
particular characteristic, specify 0 for that characteristic. Figure 3-38 shows the
variable-length data portion of a compiled 'MENU' resource that uses the standard menu
definition procedure.
Figure 3-38 The variable-length data that describes menu items as defined by the standard
menu definition procedure
Menu Manager
The variable-length data portion of a compiled version of a 'MENU' resource that uses
the standard menu definition procedure contains the following elements:
■ Length (in bytes) of the menu item’s text.
■ Text of the menu item.
■ Icon number, script code, or 0 (as specified by the noicon constant in a Rez input file)
if the menu item doesn’t contain an icon and uses the system script. The icon number
is a number from 1 through 255 (or from 1 through 254 for small or reduced icons). The
Menu Manager adds 256 to the icon number to generate the resource ID of the menu
item’s icon. If a menu item has an icon, you should also provide a 'cicn' or an
'ICON' resource with the resource ID equal to the icon number plus 256. If you want
the Menu Manager to reduce an 'ICON' resource to the size of a small icon, also
provide the value $1D in the keyboard equivalent field. If you provide an 'SICN'
resource, provide $1E in the keyboard equivalent field. Otherwise, the Menu Manager
looks first for a 'cicn' resource with the calculated resource ID and uses that icon. If
you want the Menu Manager to draw the item’s text in a script other than the system
script, specify the script code here and also provide $1C in the keyboard equivalent
field. If the script system for the specified script is installed, the Menu Manager draws
the item’s text using that script. An item that is drawn in a script other than the system
script cannot also have an icon.
■ Keyboard equivalent (specified as a 1-byte character), the value $1B (as specified by
the constant hierarchicalMenu in a Rez input file) if the item has a submenu, the
value $1C if the item uses a script other than the system script, or 0 (as specified by the
nokey constant in a Rez input file) if the item has neither a keyboard equivalent nor a
submenu and uses the system script. A menu item can have a keyboard equivalent, a
submenu, a small icon, a reduced icon, or a script code, but not more than one of these
characteristics. For items containing icons, you can provide $1D in this field if you
want the Menu Manager to reduce an 'ICON' resource to the size
of a small icon. Provide $1E if you want the Menu Manager to use an 'SICN' resource
for the item’s icon. The values $01 through $1A as well as $1F and $20 are reserved for
use by Apple; your application should not use any of these reserved values in this
field.
■ Marking character, the menu ID of the item’s submenu, or 0 (as specified by the
nomark constant in a Rez input file) if the item has neither a mark nor a submenu. A
menu item can have a mark or a submenu, but not both. Submenus of an application
should have menu IDs from 1 through 235; submenus of a desk accessory should have
menu IDs from 236 through 255.
■ Font style of the menu item. The constants bold, italic, plain, outline, and
shadow can be used in a Rez input file to define their corresponding styles.
If you provide your own menu definition procedure, you should use the same format
for your resource descriptions of menus as shown in Figure 3-37. You can use the same
format or a format of your choosing to describe menu items. You can also use bits 1–31
of the enableFlags field of the menu record as you choose; however, bit 0 must still
indicate whether the menu is enabled or disabled.
Menu Manager
Number of menus 2
Menu Manager
use GetMenu to read in the resource description of the menu (or GetNewMBar to read
in all menus in the menu bar), the Menu Manager also reads in any associated 'mctb'
resource (if it exists). “The Menu Color Information Table Record” beginning on
page 3-98 describes the format of the menu color information table.
Figure 3-40 shows the format of a compiled 'mctb' resource.
Figure 3-40 Structure of a compiled menu color information table ('mctb') resource
Number of entries 2
Menu Manager
ID 2
Item 2
RGB1 6
RGB2 6
RGB3 6
RGB4 6
■ RGB3: for a menu bar entry, the default color of items in a displayed menu; for a menu
title entry, the default color for items in a specific menu; for a menu item entry, the
color for the keyboard equivalent of a specific item.
■ RGB4: for a menu bar entry, the default color of the menu bar; for a menu title entry,
the background color of a specific menu; for a menu item entry, the background color
of a specific menu.
Menu Manager
Pascal Summary 3
Constants 3
CONST
noMark = 0; {menu item doesn't have a marking character}
Data Types 3
TYPE
MenuInfo = {menu record}
RECORD
menuID: Integer; {number that identifies the menu}
menuWidth: Integer; {width (in pixels) of the menu}
menuHeight: Integer; {height (in pixels) of the menu}
menuProc: Handle; {menu definition procedure}
enableFlags:LongInt; {indicates whether menu and }
{ menu items are enabled}
Menu Manager
Creating Menus
FUNCTION NewMenu (menuID: Integer; menuTitle: Str255)
: MenuHandle;
FUNCTION GetMenu (resourceID: Integer): MenuHandle;
Menu Manager
Adding Menus to and Removing Menus From the Current Menu List
PROCEDURE InsertMenu (theMenu: MenuHandle; beforeID: Integer);
PROCEDURE DeleteMenu (menuID: Integer);
PROCEDURE ClearMenuBar;
Menu Manager
Disposing of Menus
PROCEDURE DisposeMenu (theMenu: MenuHandle);
Menu Manager
Application-Defined Routine 3
C Summary 3
Constants 3
enum {
#define noMark '\0' /*menu item doesn't have a marking character*/
Menu Manager
Data Types 3
Menu Manager
Creating Menus
pascal MenuHandle NewMenu (short menuID, const Str255 menuTitle);
pascal MenuHandle GetMenu (short resourceID);
Adding Menus to and Removing Menus From the Current Menu List
pascal void InsertMenu (MenuHandle theMenu, short beforeID);
pascal void DeleteMenu (short menuID);
pascal void ClearMenuBar (void);
Menu Manager
Menu Manager
Disposing of Menus
pascal void DisposeMenu (MenuHandle theMenu);
Application-Defined Routine 3
Menu Manager
Assembly-Language Summary 3
Data Structures 3
Global Variables 3
AtMenuBottom The pixel value at the bottom of the scrollable menu.
MBarEnable Contains 0 if all menus in the current menu bar belong to an application; contains
a nonzero value if all menus belong to a desk accessory.
MBarHeight Contains current height of the menu bar, in pixels.
MBarHook Address of routine that MenuSelect calls repeatedly while the mouse button
is down.
MenuCInfo Contains a handle to application’s menu color information table.
MenuDisable Contains the menu ID and item number of the last item chosen, regardless of
whether the item was disabled or enabled.
MenuFlash Contains the current count (number of times) a menu item blinks when chosen by
the user.
MenuHook Address of routine that MenuSelect calls after a menu title is highlighted and
the menu rectangle is calculated but before the menu is drawn.
TheMenu Contains the menu ID of the highlighted menu in the menu bar.
TopMenuItem The pixel value at the top of the scrollable menu.
Result Codes 3
noErr 0 No error
paramErr –50 Error in parameter list
memFullErr –108 Not enough room in heap zone
resNotFound –192 Unable to read resource
hmHelpManagerNotInited –855 Help menu not set up
Figure 4-0
Listing 4-0
Table 4-0
4 Window Manager
Contents
Introduction to Windows 4-4
Active and Inactive Windows 4-6
Types of Windows 4-8
Window Regions 4-12
Dialog Boxes and Alert Boxes 4-13
Controls 4-14
Windows on the Desktop 4-15
About the Window Manager 4-16
Graphics Ports 4-17
Window Records 4-19
Color Windows 4-20
Events in Windows 4-21
Using the Window Manager 4-22
Managing Multiple Windows 4-23
Creating a Window 4-25
Defining a Window Resource 4-25
Creating a Window From a Resource 4-27
Positioning a Document Window on the Desktop 4-30
Drawing the Window Contents 4-39
Updating the Content Region 4-40
Maintaining the Update Region 4-41
Handling Events in Windows 4-41
Handling Mouse Events in Windows 4-42
Handling Keyboard Events in Windows 4-47
Handling Update Events 4-48
Handling Activate Events 4-50
Moving a Window 4-53
Zooming a Window 4-53
Resizing a Window 4-57
Closing a Window 4-60
Contents 4-1
C H A P T E R 4
4-2 Contents
C H A P T E R 4
Window Manager 4
This chapter describes how your application can use the Window Manager to create and
manage windows.
A Macintosh application uses windows for most communication with the user, from
discrete interactions like presenting and acknowledging alert boxes to open-ended
interactions like creating and editing documents. Users generally type words and
formulas, draw pictures, or otherwise enter data in a window on the screen. Your
application typically lets the user save this data in a file, open saved files, and view
the saved data in a window. See the chapter “Introduction to File Management” in
Inside Macintosh: Files for more information about handling files.
A window can be any size or shape, and the user can display any number of windows,
within the limits of available memory, on the screen at once.
The Window Manager defines a set of standard windows and provides a set of routines
for managing them. The Window Manager helps your application display windows that
are consistent with the Macintosh user interface. See Macintosh Human Interface Guidelines
for a detailed description of windows and their behavior.
You typically store information about your windows in resources. This chapter describes
the standard window resources. For general information on resources, see the chapter
“Introduction to the Macintosh Toolbox” in this book. For information on Resource
Manager routines, see the chapter “Resource Manager” in Inside Macintosh: More
Macintosh Toolbox.
The Window Manager itself depends on QuickDraw, the part of the Macintosh system
software that handles quick manipulation of graphics. QuickDraw supports drawing into
graphics ports, which are individual and complete drawing environments with
independent coordinate systems. Each window represents a graphics port, which is
described in Inside Macintosh: Imaging.
To maintain its windows, your application needs to know what actions the user is taking
on the desktop. It receives this information through events, which are messages that
describe user actions and report on the processing status of your application. This
chapter describes the events that affect window display and considers mouse-down and
keyboard events as they relate to windows. For a complete description of events and how
your application handles them, see the chapter “Event Manager” in this book.
Most document windows contain controls, which are screen images the user manipulates
to control the display or the behavior of the application. This chapter illustrates the
controls most commonly used in windows. For more information on creating and
responding to controls, see the chapter “Control Manager” in this book.
You use the Window Manager to create and display a new window when the user creates
a new document or opens an existing document. When the user clicks or holds down the
mouse button while the cursor is in a window created by your application, you use the
Window Manager to determine the location of the mouse action and to
alter the window display as appropriate. When the user closes a window, you use the
Window Manager to remove the window from the screen.
4-3
C H A P T E R 4
Window Manager
This chapter describes how the Window Manager supports windows and then explains
how you can use the Window Manager to
■ create and display windows
■ handle events in windows
■ change the display when the user moves or resizes windows
■ remove windows
Introduction to Windows 4
A window is a user interface element, an area on the screen in which the user can enter
or view information.
The user can have multiple windows on the desktop at once, from a number of different
applications. The user can change the size and location of most windows and can place
windows entirely or partially in front of other windows. Figure 4-1 shows a few windows
on the desktop.
Your application typically creates document windows that allow the user to enter and
display text, graphics, or other information. For an illustration of a document window in
full color, see Plate 1 at the beginning of this book.
Window Manager
A document window is a view into the document—if the document is larger than the
window, the window is a view of a portion of the document. Your application can put
one or more windows on the screen, each window showing a view of a document or of
auxiliary information used to process the document.
The Window Manager defines and supports a set of standard window elements through
which the user can manipulate windows. It’s important that your application follow the
standard conventions for drawing, moving, resizing, and closing windows. By presenting
the standard interface, you make experienced users instantly familiar with many aspects
of your application, allowing them to focus on learning its unique features.
Figure 4-2 illustrates a standard document window and its elements.
Scroll arrow
Scroll box
Scroll bar
Scroll arrow
Size box
The title bar displays the name of the window and indicates whether it’s active or not.
The Window Manager displays the title of the window in the center of the title bar, in the
system font and system font size. If the system font is in the Roman script system, the
title bar is 20 pixels high.
When the user creates a new document, you ordinarily display a new document window
with the title “untitled”, spelled in lowercase letters. If the user creates a second new
document window without saving the first, you title the second window “untitled 2”,
with a space between the word and the number. Continue to add 1 to the number in the
title as long as the user continues to create new windows without saving previously
numbered, untitled windows.
When the user opens a saved document, you assign the document’s filename to the
window in which it is displayed.
The user expects to move a window by dragging it by its title bar. You can support
moving the window by calling the Window Manager’s DragWindow procedure, as
described in “Moving a Window” on page 4-53.
Window Manager
The close box offers the user a quick way to close a window. You can use the
TrackGoAway function to track mouse activity in the close box and the CloseWindow
and DisposeWindow procedures to close windows. Closing windows is described in
“Closing a Window” beginning on page 4-60.
The zoom box offers the user a quick way to switch between two different window sizes.
You use the TrackBox function to track mouse activity in the zoom box and the
ZoomWindow procedure to zoom windows. Zooming windows is described in “Zooming
a Window” beginning on page 4-53.
The size box lets the user change the size and dimensions of the window. You use the
GrowWindow function to track mouse activity in the size box and the SizeWindow
procedure to resize windows. Sizing windows is described in “Resizing a Window”
beginning on page 4-57.
The scroll bars let the user see different parts of a document that contains more
information than can be displayed at once in the window. Although the Macintosh user
interface guidelines specify that you place scroll bars on the right and lower edges of a
window that needs them, scroll bars are not part of the window structure. You create and
control the scroll bars through the Control Manager, described in the chapter “Control
Manager” in this book.
The content region is the part of the window in which your application displays the
contents of a document, the size box, and the window controls.
The window frame is the part of the window drawn automatically by the Window
Manager—the title bar, including the close box and zoom box, and the window’s outline.
The structure region is the entire screen area occupied by a window, including the frame
and content region. (See Figure 4-10 on page 4-12.)
Window Manager
To make a window active, the user clicks anywhere in its contents or frame. When
the user activates one of your windows, you call the Window Manager to highlight
the window frame and title bar; you activate the controls and window contents.
As a window becomes active, it appears to the user to move forward, in front of all
other windows.
When the user clicks in an inactive document window, you should make the window
active but not make any selections in the window in response to the click. To make a
selection in the window, the user must click again. This behavior protects the user from
losing an existing selection unintentionally when activating a window.
Note
The Finder makes selections in response to the first click in an inactive
window, because this action is more natural for the way Finder windows
are used. You might find that users expect the first click to cause a
selection in some other special-purpose windows created by your
application. This behavior is seldom appropriate in document
windows. ◆
When a window that belongs to your application becomes inactive, the Window
Manager redraws the frame, removing the highlighting from the title bar and hiding
the close and zoom boxes. Your application hides the controls and the size box and
removes highlighting from application-controlled elements.
When the user reactivates a window, reinstate the window as it was before it was
deactivated. Draw the scroll box in the same position and restore the insertion point or
highlight the previous selection.
Window Manager
Types of Windows 4
Because windows have so many uses, their appearances vary. The Window Manager
defines a number of window types that meet the basic needs of most applications. A
window type is the general description of how a window looks and behaves. Some
windows have title bars and others don’t, for example, and windows can have almost
any combination of the window-manipulation elements: close box, zoom box, and
size box.
This section describes the nine basic window types supported by the Window Manager
and their uses. You can create windows of these types by specifying one of the window
type constants: zoomDocProc, dBoxProc, altDBoxProc, plainDBoxProc,
movableDBoxProc, noGrowDocProc, documentProc, zoomNoGrow, and rDocProc.
For instructions for creating windows, see “Creating a Window” beginning on page 4-25.
To give the user maximum flexibility and control, you can use the zoomDocProc
window type for your document windows. A zoomDocProc window supports all of the
window-manipulation elements shown in Figure 4-2 on page 4-5: title bar, close box,
zoom box, and size box. The Window Manager does not necessarily draw the close box
and size box, however. You must call the Window Manager’s DrawGrowIcon procedure
to draw the size box, and you can optionally suppress the close box when you create the
window. For more information on defining a window’s characteristics, see “Creating a
Window” beginning on page 4-25.
Figure 4-4 illustrates a window of type zoomDocProc with a close box, as drawn by the
Window Manager before you add the size box and scroll bars.
zoomDocProc
In most cases, a window of type zoomDocProc should contain both a close box and a
size box. When the related document contains more data than fits in the window, you
activate the scroll bars and adjust them to show where in the document the user is
working. Figure 4-5 illustrates a window of type zoomDocProc with a size box and scroll
bars.
Window Manager
Figure 4-5 A window of type zoomDocProc, with size box and inactive scroll bars
You also use windows to display alert boxes and dialog boxes. This section describes the
window types used for alert boxes and dialog boxes. For more thorough descriptions of
the different kinds of alert boxes and dialog boxes, see the chapter “Dialog Manager” in
this book.
Alert boxes and fixed-position modal dialog boxes contain no window-manipulation
elements. The user cannot move, resize, zoom, or close them manually. An alert box or a
modal dialog box remains on the screen as the active window until the Dialog Manager
or your application removes it—usually when the user completes the interaction by
clicking one of the buttons. Figure 4-6 illustrates the three window types available for
alert boxes and fixed-position modal dialog boxes.
Figure 4-6 Window types for alert boxes and fixed-position modal dialog boxes
When you want to let the user move a modal dialog box window—in order, for example,
to see text that might be obscured by the window—you can implement a movable modal
dialog box. A movable modal dialog box cannot be resized, closed, or zoomed, but it can
be moved. Figure 4-7 on the next page illustrates the movableDBoxProc window type.
Like a fixed-position modal dialog box, the movable modal dialog box remains active
until the user completes the dialog.
Window Manager
movableDBoxProc
Whenever possible, avoid modal dialog boxes and instead use modeless dialog boxes,
which allow the user to perform other tasks without dismissing the dialog box. Windows
of type noGrowDocProc, used for displaying modeless dialog boxes, can be moved or
closed but not resized or zoomed. You can implement modeless dialog boxes with other
window types if necessary, but it’s easier to conform to the user interface guidelines if
you keep your dialog box windows as simple as possible. Figure 4-8 illustrates the
modeless dialog box window.
noGrowDocProc
The Window Manager also supports a few window types that are seldom used. The
documentProc window type, for example, has a title bar and supports a close box and
size box but no zoom box. The zoomNoGrow window type is virtually never appropriate:
zoomNoGrow supports a close box and a zoom box, but not a size box. The rDocProc
window type is a rounded-corner window with a title bar and a close box; it is used by
desk accessories. Figure 4-9 illustrates these three seldom-used window types.
The window definition function defines the general appearance and behavior of a
window. The system software and various Window Manager routines call a window’s
window definition function when they need to perform certain window-dependent
actions, such as drawing or resizing a window’s frame.
Window Manager
The Window Manager supplies two standard window definition functions that handle
the nine standard window types. A window definition function draws the window’s
frame, draws the close box and window title (if any), determines which region the cursor
is in within the window, calculates the window’s structure and content regions, draws
the window’s zoom box (if any), draws the window’s size box (if any), and performs any
special initialization or disposal tasks.
A single window definition function can support up to 16 different window types. The
window definition function defines a variation code, an integer from 0 through 15, for
each window type it supports.
A window definition ID is a single value incorporating both the window’s definition
function and its variation code. (The resource ID of the window definition function
is stored in the upper 12 bits of the integer, and the variation code is stored in the
lower 4 bits.) The window-type constants described in this section are in fact window
definition IDs.
Window
Constant definition ID Description
documentProc 0 movable, sizable window, no zoom box
dBoxProc 1 alert box or modal dialog box
plainDBox 2 plain box
altDBoxProc 3 plain box with shadow
noGrowDocProc 4 movable window, no size box or zoom box
movableDBoxProc 5 movable modal dialog box
zoomDocProc 8 standard document window
zoomNoGrow 12 zoomable, nonresizable window
rDocProc 16 rounded-corner window
You can provide your own window definition function if you need a window with
unusual characteristics, as described in “The Window Definition Function” beginning
on page 4-120. Always be careful to conform window behavior to the guidelines in
Macintosh Human Interface Guidelines.
Window Manager
Window Regions 4
The Window Manager recognizes a number of different special-purpose window
regions, which are defined by either the Window Manager or the window definition
functions.
The most obvious window regions are the parts of the visible window that the user
manipulates to control the display. These window regions correspond to the standard
window parts. The drag region is the area occupied by the title bar, except for the close
box and zoom box. (The user moves the window by dragging it by its title bar.) The size
region, close region, and zoom region are the areas occupied by the size box, close box,
and zoom box, respectively.
When the user presses the mouse button while the cursor is in one of your windows, you
use the Window Manager function FindWindow to determine the region in which the
mouse-down event occurred. (The FindWindow function calls the window’s window
definition function, which defines and interprets the window-manipulation regions.)
Depending on the result, you then call the appropriate Window Manager routine or your
own routine for handling the event. For more information about determining where the
cursor is when the user presses the mouse button, see “Handling Mouse Events in
Windows” on page 4-42. For discussions of how to use the Window Manager routines for
moving, sizing, closing, and zooming windows, see “Moving a Window” beginning on
page 4-53 and the sections that follow it.
The Window Manager also makes a broad distinction between the parts of the window
it draws automatically and the parts drawn by your application. The Window Manager
draws the window frame—the title bar, including the close box and zoom box, and
the window’s outline. (The Window Manager also draws the size box, but only when
your application calls the DrawGrowIcon procedure.) Your application is responsible for
drawing the content region—that is, the part of the window in which the contents
of a document, the size box, and the window controls (including the scroll bars)
are displayed.
The entire screen area occupied by a window, including the window outline, title bar, and
content region, is the structure region. Figure 4-10 illustrates the frame, content region,
and structure region of a window.
Window Manager
The drawing region of a graphics port associated with a window encompasses only the
window’s content region.
As the user creates, moves, resizes, and closes windows on the desktop, portions of
windows may be obscured and uncovered. The Window Manager keeps track of these
changes, accumulating a dynamic region known as the update region for each window.
The update region contains all areas of a window’s content region that need updating.
The Event Manager periodically scans the update regions of all windows on the desktop,
generating update events for windows whose update regions are not empty. When your
application receives an update event, it redraws the update region. Both your application
and the Window Manager can manipulate a window’s update region. The sections
“Updating the Content Region” on page 4-40 and “Maintaining the Update Region” on
page 4-41 describe how the Window Manager and your application track and use the
update region.
Window Manager
Use the noGrowDocProc window type for modeless dialog boxes. You typically use
the Dialog Manager to handle events in a modeless dialog box, much like events in
a movable modal dialog box. Your application handles window-manipulation events in
modeless dialog boxes just as it handles them in document windows.
If you use complex dialog boxes, you might find it’s more efficient to use the Window
Manager and other parts of the Toolbox, instead of the Dialog Manager, to create and
manage your own dialog box windows. Again, see the chapter “Dialog Manager” in this
book for a list of characteristics to consider when evaluating the complexity of a dialog
box and for examples of customized dialog boxes.
Controls 4
Most windows contain controls, which are screen images that the user manipulates to
control the display or the behavior of the application. The most common control in a
document window is the scroll bar, illustrated in Figure 4-11.
Scroll box
Scroll bar
Scroll arrow
You use scroll bars to show the relative position, within the entire document, of the
portion of the document displayed in the window. You should allow the user to drag the
scroll box or click in the gray areas or the scroll arrows to move parts of the document
into and out of the window. You activate scroll bars in a window any time there is more
data than can be shown at one time in the space available.
You use the Control Manager to create, display, and manipulate the scroll bars and any
other controls in your windows. Each control “belongs” to a window and is displayed
within the graphics port that represents that window. For each window your application
creates, the Window Manager maintains a control list, a series of entries pointing to the
descriptions of the controls associated with the window.
Window Manager
Most alert boxes and dialog boxes contain buttons, rounded rectangles that cause
an immediate or continuous action when clicked, and most dialog boxes contain
additional screen images, like radio buttons, that display and retain settings. Figure 4-12
illustrates a dialog box with buttons, radio buttons, and a number of other controls and
dialog items.
Pop-up control
Application-
defined (list)
Button
Static text
Editable text
Radio Icon
button
Buttons ordinarily appear only in alert boxes and dialog boxes. Most of the other
elements illustrated in Figure 4-12 appear only in dialog boxes. If you use the Dialog
Manager to create your alert boxes and dialog boxes, it draws your controls for you and
lets you know when the user has clicked one of them. You can, however, call the Control
Manager yourself to display and track buttons and other controls in any windows your
application creates. You can also write your own control definition functions to create and
control other kinds of controls. For a complete description of how to create and support
controls, see the chapter “Control Manager” in this book.
Window Manager
The user can interact with only one application at a time. The application with which the
user is interacting (that is, the application that owns the window in which the user is
working) is the active application, or foreground process, and the others are inactive
applications, or background processes. One way the user can switch applications is by
clicking in a window that belongs to a background process. The Process Manager then
generates events telling the previously active application that it’s about to be suspended
and telling the newly active application that it can resume processing. (For more infor-
mation about the workings of foreground and background processes and about the
events that support simultaneous running of multiple applications, see the chapter
“Event Manager” in this book.)
Your application is likely to have multiple windows on the desktop at once: one or more
document windows, possibly one or more dialog box windows, and possibly some other
special-purpose windows. The section “Managing Multiple Windows” beginning on
page 4-23 suggests a technique for keeping track of multiple windows.
On the original Macintosh computer, the desktop area was limited to a single screen of
known dimensions. Contemporary systems, however, can support multiple monitors of
various sizes and capabilities. To place its windows in the appropriate place on the
desktop, your application must pay attention to what screen space is available and where
the user is working. For the rules governing window placement, see Macintosh Human
Interface Guidelines. For techniques for managing windows on multiple screens, see
“Positioning a Document Window on the Desktop” beginning on page 4-30.
The entire area of the desktop—that is, the screen area that is not occupied by the menu
bar—is known as the gray region. The Window Manager maintains a pointer to the gray
region in a global variable named GrayRgn; you can retrieve a pointer to the gray region
with the Window Manager function GetGrayRgn.
Window Manager
also generates activate events that tell your application which windows to activate
and deactivate.
The Window Manager has built-in support for the nine basic window types described in
“Types of Windows” beginning on page 4-8. When you are using one of these window
types, the Window Manager draws the window’s frame, determines what region of the
window the cursor is in, calculates the window’s structure and content regions, draws
the window’s size box, draws the window’s close box and zoom box, and performs any
special initialization or disposal tasks. If necessary, you can write your own window
definition function to handle other types of windows.
Graphics Ports 4
Each window represents a QuickDraw graphics port, which is a drawing environment
with its own coordinate system. (See Inside Macintosh: Imaging for a complete description
of graphics ports and coordinate systems.) When you create a window, the Window
Manager creates a graphics port in which the window’s contents are displayed.
The location of a window on the screen is defined in global coordinates—that is,
coordinates that reflect the entire potential drawing space. QuickDraw and Color
QuickDraw recognize a coordinate plane whose origin is the upper-left corner of the
main screen, whose positive x-axis extends rightward, and whose positive y-axis extends
downward. In QuickDraw, the horizontal offset is ordinarily labeled h, and the vertical
offset v. Figure 4-13 illustrates the QuickDraw global coordinate system.
–6
–5
–4
–3
–2
–1 x=h
–6 –5 –4 –3 –2 –1
1 2 3 4 5 6
1
2
3
4
5
6 y=v
Window Manager
Note
The orientation of the vertical axis, while convenient for computer
graphics, differs from mathematical convention. Also, the coordinate
plane is bounded by the limits of QuickDraw coordinates, which range
from –32,768 to 32,767.
QuickDraw stores points and rectangles in its own data structures of
type Point and Rect. In these structures, the vertical coordinate (v)
appears first, followed by the horizontal coordinate (h). Most, but not all,
QuickDraw routines that handle points require you to specify the
coordinates in this order. ◆
When QuickDraw creates a new graphics port (usually because you’ve created a new
window through the Window Manager), it defines a bounding rectangle for the port, in
global coordinates. Ordinarily, the bounding rectangle represents the entire area of the
screen on which the window appears. The bounding rectangle is stored in the graphics
port data structure, in the bounds field of a structure called a pixel map in Color
QuickDraw and a bitmap in QuickDraw.
The graphics port data structure also includes a field called portRect, which defines
a rectangle to be used for drawing. In a graphics port that represents a window, the
portRect rectangle represents the window’s content region.
Note
When you place a window on the screen, you specify the location of its
content region, in global coordinates. Remember to allow space for
the window’s title bar. On the main screen, remember to leave space for
the menu bar. In the Roman script system, both the standard document
title bar and the menu bar are 20 pixels high. You can determine the
height of the menu bar with the Menu Manager GetMBarHeight
function. You can calculate the height of the title bar by comparing the
top of the window’s structure region with the top of the window’s
content region. See Listing 4-12 on page 4-55 for a sample procedure that
considers the menu bar and title bar when placing a window on the
screen. ◆
Within the port rectangle, the drawing area is described in local coordinates—that is, in
the coordinate system defined by the port rectangle. You draw into a window in local
coordinates, without regard to the window’s location on the screen (which is described in
global coordinates). Figure 4-14 illustrates the local and global coordinate systems for a
sample window 180 pixels high by 300 pixels wide, placed with its content region
70 pixels down and 60 pixels to the right of the upper-left corner of the screen.
When the Window Manager creates a window, it places the origin of the local coordinate
system at the upper-left corner of the window’s port rectangle. You can redefine
the coordinates of the port rectangle’s upper-left corner with the QuickDraw
procedure SetOrigin.
The Event Manager describes mouse events in global coordinates, and you do most of
your window manipulation in global coordinates. You generally display user data and
manipulate your controls in local coordinates. When you need to convert between the
two, you can call the QuickDraw functions GlobalToLocal and LocalToGlobal,
described in Inside Macintosh: Imaging.
Window Manager
h
(0,0) in local coordinates
v (90,60) in global coordinates
Window Records 4
Each window has a number of descriptive characteristics such as a title, control list, and
visibility status. The Window Manager stores this information in a window record,
which is a data structure of type WindowRecord.
The window record includes
■ the window’s graphics port data structure
■ the window’s class, which specifies whether it was created directly through the
Window Manager or indirectly through the Dialog Manager
■ the window title
■ a series of flags that specify whether the window is visible, whether it’s highlighted,
whether it has a zoom box, and whether it has a close box
■ pointers to the structure, content, and update regions
■ a handle to the window’s definition function
■ a handle to the window’s control list
■ an optional handle to a picture of the window’s contents
■ a reference constant field that your application can use as needed
The window record is described in detail in “The Color Window Record” beginning on
page 4-65.
The first field in the window record is the window’s graphics port. The WindowPtr data
type is therefore defined as a pointer to a graphics port.
Window Manager
You draw into a window by drawing into its graphics port, passing a window pointer to
the QuickDraw drawing routines. You also pass window pointers to most Window
Manager routines.
You don’t usually need to access or directly modify fields in a window record. When you
do, however, you can refer to them through the WindowPeek data type, which is a
pointer to a window record.
The close box, drag region, zoom box, and size box are not included in the window
record because they don’t necessarily have the formal data structure for regions
as defined in QuickDraw. The window definition function determines where these
regions are.
Your application seldom accesses a window record directly; the Window Manager
automatically updates the window record when you make any changes to the window,
such as changing its title. The Window Manager also supplies routines for changing and
reading some parts of the window record.
Color Windows 4
Since the introduction of Color QuickDraw, the Window Manager has supported color
windows. Color windows are displayed in color graphics ports, as described in Inside
Macintosh: Imaging. The color window record is exactly like the window record described
in “Window Records” on page 4-19, except that it contains a color graphics port instead
of a monochrome graphics port.
Whether or not your application uses color explicitly, and whether or not a color monitor
is currently installed, your application should work with color windows whenever Color
QuickDraw is available. Once you have created a window, you can use the window
record and window pointer for a color window interchangeably with the window record
and window pointer for a monochrome window.
On a monitor that is set to display 4-bit color or greater, the Window Manager
automatically displays the window title and parts of the frame and controls in color (or
gray scale, depending on the capabilities of the monitor). The user can adjust these colors
through the Color control panel. Except in unusual circumstances, your application
should not try to change the colors of the window frame. On a monitor that’s set to
display 1-bit color, the Window Manager draws the window title, frame, and controls in
black and white.
Various elements of a window’s colors are controlled by the window color table, which
contains a series of part codes for different window elements and the RGB values
associated with each part.
Because the user can select window display colors for the entire desktop, and because the
Window Manager performs some complex display calculations automatically if you
don’t override it, your application typically uses the default system window color table.
Window Manager
If your application explicitly controls the colors used in a window, however, you can
define your own window color tables.
You define a window color table for a window by providing a window color table
resource (that is, a resource of type 'wctb') with the same resource ID as the window’s
'WIND' resource. The Window Manager creates a window color table when it creates the
window record. The Window Manager maintains its own linked list, using auxiliary
window records, which associates your application’s windows with their corresponding
window color tables. The window color table and the auxiliary window record are
described in “The Window Color Table Record” beginning on page 4-71 and “The
Auxiliary Window Record” beginning on page 4-73.
Except in unusual circumstances, your application doesn’t need to manipulate window
color tables or the auxiliary window record.
For compatibility with other applications in the shared environment, your application
should not manipulate system color tables directly but should use the Palette Manager, as
described in Inside Macintosh: Imaging. If your application provides its own window and
control definition functions, they should apply the user’s desktop color choices just as the
default definition functions do.
Events in Windows 4
Events are messages that describe user actions and report on the processing status of
your application. The Window Manager generates two kinds of events: activate
events and update events. Activate events tell your application that a specified
window is becoming active or inactive. Update events tell your application that it
must redraw part or all of a window’s content region. The section “Handling Events in
Windows” beginning on page 4-41 describes when these events occur and how your
application responds.
One of the basic functions of the Window Manager is to report where the cursor is
when your application receives a mouse-down event. The Window Manager function
FindWindow tells your application whether the cursor is in a window and, if it’s in
a window, which window it’s in and where in that window (that is, the title bar, the
drag region, and so on). You can use the FindWindow function as a first filter for
mouse-down events, separating events that merely affect the window display from
events that manipulate user data.
The Window Manager also provides a set of routines that help you implement the
standard window-manipulation conventions:
Window Manager
The next section, “Using the Window Manager,” describes how you can use the Window
Manager to move, resize, zoom, and close windows.
You can call the Control Manager to handle events in window controls, as described in
the chapter “Control Manager” in this book. If you use the Dialog Manager for your alert
boxes and modal dialog boxes, the Dialog Manager handles keyboard activity and mouse
events in these windows. You can also use the Dialog Manager to handle keyboard
activity and mouse events in the content region of movable modal dialog boxes and
modeless dialog boxes. Your application, however, must handle mouse events in the title
bar and close box of a movable modal or modeless dialog box.
When your application is active, a mouse-down event in a window belonging to any
other application, including the Finder, switches your application to the background
(unless there’s an alert box or a modal dialog box pending, in which case the Dialog
Manager merely sounds the system alert).
Window Manager
Your application typically uses the Window Manager in conjunction with both the
Control Manager and the Dialog Manager. You use the Control Manager to define, draw,
and manipulate controls in your windows. If your window includes scroll bars, for
example, you can use the TrackControl function to track the mouse while the user
drags the scroll box. You can use the Dialog Manager to create, display, and track events
in alert boxes and dialog boxes.
System 7 provides help balloons for the window frame—that is, the title bar, zoom box,
and close box—of a window created with one of the standard window definition
functions. You should provide help balloons for your window content region—that is, the
size box, controls, and data area—and for the window frames of any window types you
define. See the chapter “Help Manager” in Inside Macintosh: More Macintosh Toolbox for a
description of how to use help balloons.
Before using the Window Manager, you must call the procedure InitGraf to initialize
QuickDraw, the procedure InitFonts to initialize the Font Manager, and finally the
procedure InitWindows to initialize the Window Manager.
Window Manager
The SurfWriter application stores document information about the user’s data, the
window display, and the file, if any, associated with the data in a document record. The
document record takes this form:
TYPE MyDocRec =
RECORD
editRec: TEHandle; {handle to text being edited}
vScrollBar: ControlHandle; {control handle to the }
{ vertical scroll bars}
hScrollBar: ControlHandle; {control handle to the }
{ horizontal scroll bars}
fileRefNum: Integer; {reference number for file}
fileFSSpec: FSSpec; {FSSpec record for file}
windowDirty: Boolean; {whether data has changed }
{ since last save}
END;
MyDocRecPtr = ^MyDocRec;
MyDocRecHnd = ^MyDocRecPtr;
The SurfWriter application creates a document record every time it creates a document
window, and it stores a handle to the document record in the refCon field of the
window record. (See the chapter “Introduction to File Management” in Inside Macintosh:
Files for a more complete illustration of how to use document records.)
When SurfWriter creates a modeless dialog box or a movable modal dialog box, it stores a
constant that represents that dialog box (that is, it specifies the constant in the dialog
resource, and the Window Manager sets the refCon field to that value when it creates
the window record). For example, a refCon value of 20 might specify a modeless dialog
box that accepts input for the Find command, and a value of 21 might specify a modeless
dialog box that accepts input for the spelling checker.
When SurfWriter receives notification of an event in one of its windows, it first
determines the function of the window and then dispatches the event as appropriate.
Listing 4-1 illustrates an application-defined routine MyGetWindowType that determines
the window’s type.
Note
The MyGetWindowType function determines the type of a window from
among a set of application-defined window types, which reflect the
different kinds of windows the application creates. These window types
are different from the standard window types defined by the definition
functions, which determine how windows look and behave. To find out
which one of the standard window types a window is, call the Window
Manager function GetWVariant. ◆
The sample code later in this chapter calls the MyGetWindowType function as part of its
event-handling procedure, described in the section “Handling Events in Windows”
beginning on page 4-41.
Window Manager
Notice that MyGetWindowType checks whether the window belongs to a desk accessory.
This step ensures compatibility with older versions of system software. When your
application is running in System 7, it should receive events only for its own windows and
for windows belonging to desk accessories that were launched in its partition. See Inside
Macintosh: Memory for information about partitions and Inside Macintosh: Processes for
information about launching applications and desk accessories.
Creating a Window 4
You typically specify the characteristics of your windows—such as their initial size,
location, title, and type—in window ('WIND') resources. Once you have defined your
window resources, you can call the function GetNewCWindow (or GetNewWindow) to
create windows.
Window Manager
Listing 4-2 shows a window resource, in Rez input format, that an application might use
to create a document window. The resource specifies the attributes for windows created
from the resource of type 'WIND' with resource ID 128. The system software loads the
resource into memory immediately after opening the resource file, and the Memory
Manager can purge the memory occupied by the resource.
Listing 4-2 Rez input for a window ('WIND') resource for a document window
The four numbers in the first element of this resource specify the upper-left and lower-
right corners, in global coordinates, of a rectangle that defines the initial size and
placement of the window’s content region. Your application can change this rectangle
before displaying the window, either programmatically or through an optional
positioning code described later in this section. When specifying a window’s position on
the desktop, remember to leave room for the window’s frame and, on the main screen,
for the menu bar.
The second element contains the window’s definition ID, which specifies both the
window definition function that will handle the window and an optional variation code
that defines a window type. If you are using one of the standard window types
(described in “Types of Windows” beginning on page 4-8), you need to specify only one
of the window-type constants listed in “The Window Resource” beginning on page 4-124.
The third element in the window resource specifies whether the window is initially
visible or invisible. This element determines only whether the Window Manager displays
the window when it first creates it, not whether the window can be seen on the screen. (A
window entirely covered by other windows, for example, might be “visible,” even
though the user cannot see it.) You typically create new windows in an invisible state,
build the content area of the window, and then display the completed window by calling
ShowWindow to make it visible.
Window Manager
The fourth element in the window resource specifies whether the window has a close
box. Only some of the standard window types (zoomDocProc, noGrowDocProc,
documentProc, zoomNoGrow, and rDocProc) support close boxes. The close-box
element has no effect if the second field of the resource specifies a window type that does
not support a close box. The Window Manager draws the close box when it draws the
window frame.
The fifth element in the window resource is a reference constant, in which your
application can store whatever data it needs. When it builds a new window record, the
Window Manager stores in the refCon field whatever value you specify here. You can
also put a placeholder here (such as 0x0, in this example) and then set the refCon field
yourself by calling the SetWRefCon procedure.
The sixth element in the window resource is a string that specifies the window title.
The optional seventh element in the window resource specifies a positioning rule that
overrides the window position specified by the rectangle in the first element. In the
window resource for a document window, you typically specify the positioning constant
staggerParentWindowScreen. For a complete list of the positioning constants and
their effects, see “The Window Resource” beginning on page 4-124.
The positioning constants are convenient when the user is creating a new document or
when you’re handling your own dialog boxes and alert boxes. When you’re creating a
new window to display a previously saved document, however, the new window should
appear, if possible, in the same rectangle as the previous window (that is, the window
used during the last save). For the rules of window placement, see “Positioning a
Document Window on the Desktop” beginning on page 4-30.
Use the function GetNewCWindow or GetNewWindow to create a window from a
'WIND' resource.
Window Manager
Window Manager
ELSE
good := FALSE; {clear success flag}
IF good THEN
BEGIN {create scroll bars}
vScrollBar := GetNewControl(rVScroll, window);
hScrollBar := GetNewControl(rHScroll, window);
good := (vScrollBar <> NIL) AND (hScrollBar <> NIL);
END;
IF good THEN {it's a good document}
BEGIN
MyAdjustScrollBars(window, FALSE); {adjust scroll bars}
fileRefNum := 0; {no file yet}
windowDirty := FALSE; {no changes yet}
IF newDocument THEN {if it's a new (empty) document, }
ShowWindow(window); { make it visible}
END;
END; {end of WITH statement}
HUnlock(Handle(myData)); {unlock document record}
END; {end of IF (window <> NIL) AND (myData <> NIL)}
IF NOT good THEN
BEGIN
IF windStorage <> NIL THEN {memory for window record was allocated}
DisposePtr(windStorage); {dispose of it}
IF myData <> NIL THEN {memory for document record was allocated}
BEGIN
IF myData^^.editRec <> NIL THEN {edit record was allocated}
TEDispose(myData^^.editRec); {dispose of it}
DisposeHandle(Handle(myData)); {dispose of document record}
END;
IF window <> NIL THEN {window pointer exists, but it's invalid}
CloseWindow(window); {clean up window pointer}
window := NIL; {set window to NIL to indicate failure}
END;
END; {DoNewCmd}
The DoNewCmd procedure first sets the window pointer and success flags to show
that a valid window doesn’t yet exist. Then it calls the application-defined function
MyPtrAllocationProc, which allocates memory for a window record from a block
set aside during program initialization for that purpose. If MyPtrAllocationProc
successfully allocates memory and returns a valid pointer, DoNewCmd creates a window,
specifying the 'WIND' resource with resource ID 128, as specified by the constant
rDocWindow. Using this window resource (defined in Listing 4-2 on page 4-26), the
Window Manager creates an invisible window of type zoomDocProc. Because
the behind parameter to GetNewCWindow or GetNewWindow has the value
WindowPtr(–1), the Window Manager places the new window in front of all others
on the desktop.
Window Manager
The DoNewCmd procedure then creates a document record. It locks the document record
in memory while manipulating it, sets the refCon field in the window record so that it
points to the document record, and fills in the document record. While filling in the
document record, DoNewCmd sets up a TextEdit record to hold the user’s data. If that
succeeds, DoNewCmd sets up horizontal and vertical scroll bars. If that succeeds,
DoNewCmd adjusts the scroll bars (see the chapter “Control Manager” in this book for the
application-defined procedure MyAdjustScrollbars) and fills in the remaining parts
of the document record. If the window is being created to display a new document, that
is, if no user data needs to be read from a disk, DoNewCmd calls the ShowWindow
procedure to make the window visible immediately.
If your window resource specifies that a new window is visible, GetNewCWindow
displays the window immediately. If you’re creating a document window, however,
you’re more likely to create the window in an invisible state and then make it visible
when you’re ready to display it.
■ If you’re creating a window because the user is creating a new document, you can
display the window immediately by calling the procedure ShowWindow to make the
window frame visible. This change in visibility adds to the update region and triggers
an update event. Your application then invokes its own procedure for drawing the
content region in response to the update event.
■ If you’re creating a new window to display a saved document, you must retrieve the
user’s data before displaying it. (See Inside Macintosh: Files for information about
reading saved files.) If possible, the size and location of the window that displays the
document should be the same as when the document was last saved. (See the next
section, “Positioning a Document Window on the Desktop,” for a discussion of
window placement.) Once you have positioned the window and set up its content
region, you can make the window visible by calling ShowWindow, which triggers an
update event. Your application then invokes its own procedure for drawing the
content region.
Window Manager
If the user closes one or more document windows, display subsequent windows in the
“empty” positions before adding more positions below and to the right. Figure 4-16
illustrates how you fill in an empty position when the user opens a new document after
closing one created earlier.
untitled 4
untitled 5
Window Manager
Window Manager
The user state is the last size and location the user established for the window.
The standard state is what your application determines is the most convenient size for
the window, considering the function of the document and the screen space available. For
a more complete description of the standard state, see “Zooming a Window” beginning
on page 4-53. Your application typically calculates the standard state each time the user
zooms to that state.
The user and standard states are stored in the state data record, whose handle appears in
the dataHandle field of the window record.
TYPE WStateData =
RECORD
userState: Rect; {size and location established by user}
stdState: Rect; {size and location established by }
{ application}
END;
When the user saves a document, you must save the user state rectangle and the state of
the window (that is, whether the window is in the user state or the standard state). Then,
when the user opens the document again later, you can replicate the window’s status.
You typically store the state data as a resource in the resource fork of the document file.
Window Manager
Listing 4-4 illustrates an application-defined data structure for storing the window’s user
rectangle and state.
Listing 4-4 Application-defined data structure for storing a window’s state data
TYPE MyWindowState =
RECORD
userStateRect: Rect; {user state rectangle}
zoomState: Boolean; {window state: TRUE = standard; }
{ FALSE = user}
END;
MyWindowStatePtr = ^MyWindowState;
MyWindowStateHnd = ^MyWindowStatePtr;
This structure translates into an application-defined resource that is stored in the resource
fork of the document when the user saves the document.
Listing 4-5 shows an application-defined routine for saving a document’s state data. The
SurfWriter application calls the procedure MySaveWindowPosition when the user
saves a document.
Window Manager
Window Manager
Listing 4-6 Positioning the window when the user opens a saved document
Window Manager
{move window}
MoveWindow(myWindow, curStateRect.left, curStateRect.top, FALSE);
{Convert to local coordinates and resize window.}
GetPort(savePort);
SetPort(myWindow);
GlobalToLocal(curStateRect.topLeft);
GlobalToLocal(curStateRect.botRight);
SizeWindow(myWindow, curStateRect.right, curStateRect.bottom, TRUE);
IF resourceGood THEN {reset user state and standard }
BEGIN { state--SizeWindow may have changed them}
MySetWindowUserState(myWindow, lastUserStateRect);
MySetWindowStdState(myWindow, stdStateRect);
END;
ReleaseResource(Handle(myStateHandle)); {clean up}
CloseResFile(myRefNum);
HUnLock(Handle(myData));
END;
The MyVerifyPosition routine, not shown here, compares the saved location against
available screen space. (See Listing 4-12 on page 4-55 for a strategy for comparing the
saved rectangle with the available screen space.) MyVerifyPosition alters the user
state rectangle, if necessary (using the same size, if possible, but placing it on available
screen space) and calculates a new standard state for displaying the window on the
screen containing the user state.
After determining valid user and standard state rectangles, the procedure
MySetWindowPosition sets a temporary positioning rectangle to the appropriate
size and location, based on the state of the document’s window when the document
was saved. The MySetWindowPosition procedure then calls the Window Manager
procedures MoveWindow and SizeWindow to establish the window’s location and
size before cleaning up.
The SurfWriter application calls MySetWindowPosition from its routine for opening
saved documents, after reading the document’s data from its data fork. Listing 4-7 shows
the application-defined DoOpenFile function that SurfWriter calls when the user opens
a saved document.
Window Manager
BEGIN
DoNewCmd(FALSE, myWindow); {FALSE tells DoNewCmd not to }
{ show the window}
IF myWindow = NIL THEN
BEGIN
DoOpenFile := kOpenFileError;
Exit(DoOpenFile);
END;
SetWTitle(myWindow, mySpec.name);
{open the file's data fork, passing the file spec-- }
{ FSpOpenDF returns a file reference number}
myErr := FSpOpenDF(mySpec, fsRdWrPerm, myFileRefNum);
IF (myErr <> noErr) AND (myErr <> opWrErr) THEN {open failed}
BEGIN {clean up}
DisposeWindow(myWindow);
DoOpenFile := myErr;
Exit(DoOpenFile);
END;
{get a handle to the window's document record}
myData := MyDocRecHnd(GetWRefCon(myWindow));
myData^^.fileRefNum := myFileRefNum; {save file ref num}
myData^^.fileFSSpec := mySpec; {save fsspec}
myErr := DoReadFile(myWindow); {read file's data}
{retrieve saved state data and establish valid position}
MySetWindowPosition(myWindow);
{MyResizeWindow invalidates the whole portRgn, guaranteeing }
{ an update event--the window's contents are redrawn then}
MyResizeWindow(myWindow);
ShowWindow(myWindow); {show window}
DoOpenFile := myErr;
END;
Window Manager
The MyDrawWindow procedure first sets the current port to the window’s port and gets a
handle to the window’s document record. Using the data in the document record, the
procedure first erases the content region, draws the controls, and draws the size box.
Finally, it draws the user’s data, in this case the contents of a TextEdit edit record.
Window Manager
If your application creates a window that contains a static display, you can let the
Window Manager take care of drawing and updating the content region by placing a
handle to a picture in the windowPic field of the window record. See the description
of the SetWindowPic procedure on page 4-110.
Figure 4-18 Moving one window and adding to another window’s update region
Update region
Window Manager
The Event Manager periodically scans the update regions of all windows on the desktop.
If it finds one whose update region is not empty, it generates an update event for that
window. When your application receives an update event, it redraws as much of the
content area as necessary, as described in the section “Handling Update Events”
beginning on page 4-48.
As the user makes changes to a document, your application must update both the
document data and the document display in the content area of its window. You can
use one of two strategies for updating the display:
■ If your application doesn’t require continuous scrolling or rapid response, you can add
changed areas of the content region to the window’s update region. The Event
Manager then sends your application an update event, and your application invokes
its standard update procedure.
■ For continuous scrolling and a faster response time, you can draw directly into the
content area of the window.
In either case, your application ultimately draws in the graphics port that represents
the window. You draw controls through the Control Manager, and you draw text
and graphics with the routines described in Inside Macintosh: Text and Inside Macintosh:
Imaging.
Window Manager
Window Manager
When the user presses the mouse button while the cursor is in a window, FindWindow
not only returns a constant that identifies the window region but also sets a variable
parameter that points to the window.
In System 7, if FindWindow returns inDesk, the cursor is somewhere other than in the
menu bar, one of your windows, or a window created by a desk accessory launched in
your application’s partition. The function may return inDesk if, for example, the cursor
is in the window frame but not in the drag region, close box, or zoom box. FindWindow
seldom returns the value inDesk, and you can generally ignore the rare instances of this
function result.
If the user presses the mouse button with the cursor in the menu bar (inMenuBar),
you call your own routines for displaying menus and allowing the user to choose
menu items.
The FindWindow function returns the value inSysWindow only when the user presses
the mouse button with the cursor in a window that belongs to a desk accessory launched
in your application’s partition. You can then call the SystemClick procedure, passing it
the event record and window pointer. The SystemClick procedure, documented in the
chapter “Event Manager” in this book, makes sure that the event is handled by the
appropriate desk accessory.
The FindWindow function returns one of the other values when the user presses
the mouse button while the cursor is in one of your application’s windows. Your
response depends on whether the cursor is in the active window and, if not, what
kind of window is active.
When you receive a mouse-down event in the active window, you route the event to the
appropriate routine for changing the window display or the document contents. When
the user presses the mouse button while the cursor is in the zoom box, for example, you
call the Window Manager function TrackBox to highlight the zoom box and track the
mouse until the button is released.
When you receive a mouse-down event in an inactive window, your response depends
on what kind of window is active:
■ If the active window is a movable modal dialog box, you should sound the system
alert and take no other action. (If the active window is a modal dialog box handled by
the ModalDialog procedure, the Dialog Manager doesn’t pass the event to your
application but sounds the system alert itself.)
Window Manager
■ If the active window is a document window or a modeless dialog box, you can call
SelectWindow, passing it the window pointer. The SelectWindow procedure
removes highlighting from the previously active window, brings the newly activated
window to the front, highlights it, and generates the activate and update events
necessary to tell all affected applications which windows must be redrawn.
Listing 4-9 illustrates an application-defined procedure that handles mouse-down events.
Window Manager
The DoMouseDown procedure first calls FindWindow to map the location of the cursor to
a part of the screen or a region of a window.
If the cursor is in the menu bar, DoMouseDown calls other application-defined procedures
for adjusting and displaying menus and accepting menu choices.
If the cursor is in a window created by a desk accessory, DoMouseDown calls the
SystemClick procedure, which handles mouse-down events for desk accessories from
within applications.
If the cursor is in the content area of a window, DoMouseDown first checks to see whether
the cursor is in the currently active window by comparing the window pointer returned
by FindWindow with the result returned by the function FrontWindow. If
the cursor is in an inactive window, DoMouseDown checks to see if the active window
is a movable modal dialog box. (If the front window is an alert box or a fixed-position
modal dialog box, an application does not receive mouse-down events in other
windows.) If the active window is a movable modal dialog box and the cursor is in
another window, DoMouseDown simply sounds the system alert and waits for another
event. If the active window is not a movable modal dialog box, DoMouseDown
calls SelectWindow to activate the window in which the cursor is located. The
SelectWindow procedure relayers the windows as necessary, adjusts the highlighting,
and sends the application a pair of activate events to deactivate the previously active
window and activate the newly active window. DoMouseDown merely activates
the window in which the cursor is located; it does not make a selection in the newly
activated window in response to the first click in that window.
If the cursor is in the content area of the active window, the DoMouseDown procedure
calls another application-defined procedure (DoContentClick) that handles mouse
events in the content area.
If the cursor is in the drag region of a window, DoMouseDown first checks whether the
drag region is in an inactive window while a movable modal dialog box is active. In
that case, DoMouseDown merely sounds the system alert and waits for another event. In
any other case, DoMouseDown calls the Window Manager procedure DragWindow,
which displays an outline of the window, moves the outline as long as the user continues
to drag the window, and calls MoveWindow to draw the window in its new location
when the user releases the mouse button. After the window is drawn in its new location,
it is the active window, whether or not it was active before.
Window Manager
If the cursor is in the size box, DoMouseDown calls another application-defined routine
(DoGrowWindow, shown in Listing 4-13 on page 4-58) that resizes the window.
If the mouse press occurs in the close box, DoMouseDown calls the TrackGoAway
function, which highlights the close box and tracks all mouse activity until the user
releases the mouse button. As long as the user holds down the mouse button and leaves
the cursor in the close box, TrackGoAway leaves the close box highlighted, as illustrated
in Figure 4-19. If the user moves the cursor out of the close box, TrackGoAway removes
the highlighting.
When the user releases the mouse button, TrackGoAway returns TRUE if the
cursor is still in the close box and FALSE if it is not. If TrackGoAway returns TRUE,
DoMouseDown calls the application-defined procedure DoCloseCmd to close the
window. Listing 4-16 on page 4-60 shows the DoCloseCmd procedure.
If the mouse press occurs in the zoom box, the DoMouseDown procedure first calls
TrackBox, which highlights the zoom box and tracks all mouse activity until the user
releases the mouse button. As long as the user holds down the mouse button and leaves
the cursor in the zoom box, TrackBox leaves the zoom box highlighted, as illustrated in
Figure 4-20. If the user moves the cursor out of the zoom box, TrackBox removes the
highlighting.
When the user releases the mouse button, TrackBox returns TRUE if the cursor is still in
the zoom box and FALSE if it is not. If TrackBox returns TRUE, DoMouseDown calls the
application-defined procedure DoZoomWindow to zoom the window. Listing 4-12 on
page 4-55 shows the DoZoomWindow procedure.
Window Manager
Window Manager
Window Manager
Figure 4-21 The effects of BeginUpdate and EndUpdate on the visible region and
update region
Window 2’s
visible region
Window 2’s
update region
Update region Update region Update region
empty empty empty
Window Manager
The DoUpdate procedure first determines whether the window being updated is a
document window or some other application-defined window by calling the
application-defined procedure MyGetWindowType (shown in Listing 4-1 on
page 4-25). If the window is a document window, DoUpdate calls BeginUpdate
to establish the temporary visible region, calls the application-defined procedure
MyDrawWindow (shown in Listing 4-8 on page 4-39) to redraw the content region,
and then calls EndUpdate to restore the visible region.
If the window is an alert box or a dialog box, DoUpdate calls the application-defined
procedure DoUpdateMyDialog, which is not shown here.
Window Manager
When you receive the event for the previously active window, you
■ hide the controls and size box
■ remove or alter any highlighting of selections in the window
When you receive the event for the newly active window, you
■ draw the controls and size box
■ restore the content area as necessary, adding the insertion point in its former location
or highlighting any previously highlighted selections
If the newly activated window also needs updating, your application also receives an
update event, as described in the previous section, “Handling Update Events.”
Note
A switch to one of your application’s windows from a different
application is handled through suspend and resume events, not activate
events. See the chapter “Event Manager” in this book for a description of
how your application can share processing time. ◆
Listing 4-11 illustrates the application-defined procedure DoActivate, which handles
activate events.
Window Manager
BEGIN
{restore selections and insert caret--if using }
{ TextEdit, for example, call TEActivate}
TEActivate(editRec);
MyAdjustMenus; {adjust menus for window}
{handle the controls}
docVScroll^^.contrlVis := kControlVisible;
docHScroll^^.contrlVis := kControlVisible;
InvalRect(docVScroll^^.contrlRect);
InvalRect(docHScroll^^.contrlRect);
growRect := window^.portRect;
WITH growRect DO {handle the size box}
BEGIN {adjust for the scroll bars}
top := bottom - kScrollbarAdjust;
left := right - kScrollbarAdjust;
END;
InvalRect(growRect);
END
ELSE {window is becoming inactive}
BEGIN
TEDeactivate(editRec); {call TextEdit to deactivate data}
HideControl(docVScroll); {hide the scroll bars}
HideControl(docHScroll);
DrawGrowIcon(window); {draw the size box}
END;
HUnLock(Handle(myData)); {unlock document record}
END; {of kMyDocWindow statement}
END; {of CASE statement}
END;
The DoActivate procedure first determines the general type of the window; that is,
it calls an application-defined function that returns a constant identifying the type
of the window: a Find dialog box, a Check Spelling dialog box, or a document window.
Listing 4-1 on page 4-25 shows the MyGetWindowType function.
If the target of the activate event is a dialog box window, DoActivate calls other
application-defined routines for activating and deactivating those dialog boxes. The
DoActivateFindDBox and DoActivateCheckSpellDBox routines are not shown
here. (The DoActivate procedure does not check for alert boxes and modal dialog
boxes, because the Dialog Manager’s ModalDialog procedure automatically handles
activate events.)
Window Manager
If the target is a document window and the activate event specifies that the window is
becoming active, DoActivate highlights any user selections in the window and draws
the insertion point where appropriate. It then makes the controls visible, adds the area
occupied by the scroll bars to the update region, and adds the area occupied by the size
box to the update region. (Placing window area in the update region guarantees an
update event. When the application receives the update event, it calls the application-
defined procedure DoUpdate to draw the update region, which in this case includes the
size box and scroll bars.)
If the target is a document window, and the activate event specifies that the window
is becoming inactive, the DoActivate procedure calls the TextEdit procedure
TEDeactivate to remove highlighting from user selections, calls the Control Manager
procedure HideControl to hide the scroll bars, and calls the Window Manager
procedure DrawGrowIcon to draw the size box and the outline of the scroll bar area.
Moving a Window 4
When the user drags a window by the title bar (except for the close and zoom box
regions), the window should move, following the cursor as it moves on the
desktop. Your application can easily let the user move the window by calling the
DragWindow procedure.
The DragWindow procedure draws an outline of the window on the screen and
moves the outline as the user moves the mouse. When the user releases the mouse
button, DragWindow calls the MoveWindow function, which redraws the window in
its new location.
For an example of moving a window, see the inDrag case in Listing 4-9 on page 4-44.
Zooming a Window 4
The zoom box allows the user to alternate quickly between two window positions and
sizes: the user state and the standard state.
The user state is the window size and location established by the user. If your application
does not supply an initial user state, the user state is simply the size and location of the
window when it was created, until the user resizes it.
The standard state is the window size and location that your application considers most
convenient, considering the function of the document and the screen space available. In a
word-processing application, for example, a standard-state window might show a
full page, if possible, or a page of full width and as much length as fits on the screen.
If the user changes the page size through Page Setup, the application might adjust the
standard state to reflect the new page size. If your application does not define a standard
state, the Window Manager automatically sets the standard state to the entire gray region
on the main screen, minus a three-pixel border on all sides. (See Macintosh Human
Interface Guidelines for a detailed description of how your application determines where
to open and zoom windows.) The user cannot change a window’s standard state.
Window Manager
The user and standard states are stored in a record whose handle appears in the
dataHandle field of the window record.
TYPE WStateData =
RECORD
userState: Rect; {size and location established by user}
stdState: Rect; {size and location established by }
{ application}
END;
The Window Manager sets the initial values of the userState and stdState fields
when it fills in the window record, and it updates the userState field whenever the
user resizes the window. You typically compute the standard state every time the user
zooms to the standard state, to ensure that you’re zooming to an appropriate location.
When the user presses the mouse button with the cursor in the zoom box, the
FindWindow function specifies whether the window is in the user state or the standard
state: when the window is in the standard state, FindWindow returns inZoomIn
(meaning that the window is to be zoomed “in” to the user state); when the window is in
the user state, FindWindow returns inZoomOut (meaning that the window is to be
zoomed “out” to the standard state).
When FindWindow returns either inZoomIn or inZoomOut, your application can call
the TrackBox function to handle the highlighting of the zoom box and to determine
whether the cursor is inside or outside the box when the button is released. If TrackBox
returns TRUE, your application can call the ZoomWindow procedure to resize the window
(after computing a new standard state). If TrackBox returns FALSE, your application
doesn’t need to do anything. Listing 4-9 on page 4-44 illustrates the use of TrackBox in
an event-handling routine.
Listing 4-12 illustrates an application-defined procedure, DoZoomWindow, which an
application might call when TrackBox returns TRUE after FindWindow returns either
inZoomIn or inZoomOut. Because the user might have moved the window to a different
screen since it was last zoomed, the procedure first determines which screen contains the
largest area of the window and then calculates the ideal window size for that screen
before zooming the window.
The screen calculations in the DoZoomWindow procedure depend on the routines for
handling graphics devices that were introduced at the same time as Color QuickDraw.
Therefore, DoZoomWindow checks for the presence of Color QuickDraw before
comparing the window to be zoomed with the graphics devices in the device list. If Color
QuickDraw is not available, DoZoomWindow assumes that it’s running on a computer
with a single screen.
Window Manager
Window Manager
If the user is zooming the window to the standard state, DoZoomWindow calculates a new
standard size and location based on the application’s own considerations, the current
location of the window, and the available screens. The DoZoomWindow procedure always
places the standard state on the screen where the window is currently displayed or, if the
window spans screens, on the screen containing the largest area
of the window.
Window Manager
The bulk of the code in Listing 4-12 is devoted to determining which screen should
display the window in the standard state. The sample code shown here establishes
a standard state that simply occupies the gray area on the chosen screen, minus
three pixels on all sides. Your application should establish a standard state appropriate
to its own documents. When calculating the standard state, move the window as little
as possible from the user state. If possible, anchor one corner of the standard state
rectangle to one corner of the user state rectangle.
If the user is zooming the window to the user state, DoZoomWindow doesn’t have to
perform any calculations, because the user state rectangle stored in the state data record
should represent a valid screen location.
After calculating the standard state, if necessary, DoZoomWindow calls the ZoomWindow
procedure to redraw the window frame in the new size and location and then calls the
application-defined procedure MyResizeWindow to redraw the window’s content
region. Listing 4-14 on page 4-59 shows the MyResizeWindow procedure.
Resizing a Window 4
The size box, in the lower-right corner of a window’s content region, allows the user to
change a window’s size.
When the user positions the cursor in the size box and presses the mouse button, your
application can call the Window Manager’s GrowWindow function. This function
displays a grow image—a gray outline of the window’s frame and scroll bar areas, which
expands or contracts as the user drags the size box. The grow image indicates where the
window edges would be if the user released the mouse button at any
given moment.
To avoid unmanageably large or small windows, you supply lower and upper size limits
when you call GrowWindow. The sizeRect parameter to GrowWindow specifies both
the lower and upper size limits in a single structure of type Rect. The values in the
sizeRect structure represent window dimensions, not screen coordinates:
■ You supply the minimum vertical measurement in sizeRect.top.
■ You supply the minimum horizontal measurement in sizeRect.left.
■ You supply the maximum vertical measurement in sizeRect.bottom.
■ You supply the maximum horizontal measurement in sizeRect.right.
Most applications specify a minimum size big enough to include all parts of the structure
area and the scroll bars. Because the user cannot move the cursor beyond the edges of the
screen, you can safely set the maximum size to the largest possible rectangle.
When the user releases the mouse button, GrowWindow returns a long integer that
describes the window’s new height (in the high-order word) and width (in the low-order
word). A value of 0 means that the window’s size did not change. When GrowWindow
returns any value other than 0, you call SizeWindow to resize the window.
Window Manager
Note
Use the utility functions HiWord and LoWord to retrieve the high-order
and low-order words, respectively. ◆
When you change a window’s size, you must erase and redraw the window’s scroll bars.
Listing 4-13 illustrates the application-defined procedure DoGrowWindow for tracking
mouse activity in the size box and resizing the window.
Window Manager
Listing 4-14 Adjusting scroll bars and content region when resizing a window
Window Manager
Closing a Window 4
The user closes a window either by clicking the close box, in the upper-left corner of the
window, or by choosing Close from the File menu.
When the user presses the mouse button while the cursor is in the close box, your
application calls the TrackGoAway function to track the mouse until the user releases the
button, as illustrated in Listing 4-9 on page 4-44. If the user releases the button while the
cursor is outside the close box, TrackGoAway returns FALSE, and your application does
nothing. If TrackGoAway returns TRUE, your application invokes its own procedure for
closing a window.
The specific steps you take when closing a window depend on what kind of information
the window contains and whether the contents need to be saved. The sample code in this
chapter recognizes four kinds of windows: the modeless dialog box containing the Find
dialog, the modeless dialog box containing the Spell Check dialog, a standard document
window, and a window associated with a desk accessory that was launched in the
application’s partition.
Listing 4-16 illustrates an application-defined procedure, DoCloseCmd, that determines
what kind of window is being closed and follows the appropriate strategy. The
application calls DoCloseCmd when the user clicks a window’s close box or chooses
Close from the File menu.
PROCEDURE DoCloseCmd;
VAR
myWindow: WindowPtr; {pointer to window's record}
myData: MyDocRecHnd; {handle to a document record}
windowType: Integer; {application-defined window type}
Window Manager
BEGIN
myWindow := FrontWindow;
windowType := MyGetWindowType(myWindow);
CASE windowType OF
kMyFindModelessDialog: {for modeless dialog boxes, }
HideWindow(myWindow); { hide window}
kMySpellModelessDialog: {for modeless dialog boxes, }
HideWindow(myWindow); { hide window}
kDAWindow: {for desk accessories, close the DA}
CloseDeskAcc(WindowPeek(myWindow)^.windowKind);
kMyDocWindow: {for documents, handle file first}
BEGIN
myData := MyDocRecHnd(GetWRefCon(myWindow));
MyCloseDocument(myData);
END;
END; {of CASE}
END;
The DoCloseCmd procedure first determines which window is the active window
and then calls the application-defined function MyGetWindowType to identify the
window’s type, as defined by the application. If the window is a modeless dialog box,
MyCloseCmd merely hides the window, leaving the data structures in memory. For
a sample routine that displays a hidden window, see Listing 4-18 on page 4-64.
If the window is associated with a desk accessory, the DoCloseCmd procedure calls
the CloseDeskAcc procedure to close the desk accessory. This case is included
only for compatibility; in System 7 desk accessories are seldom launched in an
application’s partition.
If the window is associated with a document, DoCloseCmd reads the document
record and then calls the application-defined procedure MyCloseDocument to handle
the closing of a document window. Listing 4-17 illustrates the MyCloseDocument
procedure.
Window Manager
BEGIN
GetWTitle(docWindow, title); {get window title}
ParamText(title, '', '', ''); {set up dialog text}
{deactivate window before displaying Save dialog}
DoActivate(docWindow, FALSE, event);
{put up Save dialog and retrieve user response}
item := CautionAlert(kSaveAlertID, @MyEventFilter);
IF item = kCancel THEN {user clicked Cancel}
Exit(MyCloseDocument); {exit without closing}
IF item = kSave THEN {user clicked Save}
DoSaveCmd; {save the document}
{otherwise user clicked Don't Save-- }
{ close document in either case}
myErr := DoCloseFile(myData); {close document}
{Add your own error handling.}
END;
{close window whether or not user saved}
CloseWindow(docWindow); {close window}
DisposePtr(Ptr(docWindow)); {dispose of window record}
END;
Window Manager
To reverse the HideWindow procedure, you must call both ShowWindow, which makes
the window visible, and SelectWindow, which makes it the active window. Figure 4-22
illustrates how the three procedures affect the window’s status on the screen.
Before HideWindow
After HideWindow
After ShowWindow
After SelectWindow
Window Manager
PROCEDURE DoShowModelessFindDialogBox;
BEGIN
IF gFindDialog = NIL THEN {no Find dialog box exists yet}
BEGIN
{create Find dialog box}
gFindDialog := GetNewDialog(rFindModelessDialog, NIL,
Pointer(-1));
IF gFindDialog = NIL THEN {creation failed}
Exit(DoShowModelessFindDialogBox); {exit}
{store value that identifies dbox in window refCon field}
SetWRefCon(gFindDialog, LongInt(kMyFindModelessDialog))
ShowWindow(gFindDialog); {make dialog box visible}
END
ELSE {dialog box already exists}
BEGIN
ShowWindow(gFindDialog); {make it visible}
SelectWindow(gFindDialog); {select it}
END;
END;
Window Manager 4
Data Structures 4
This section describes the Window Manager data structures: the window record, the
color window record, the state data record, the window color table record, the auxiliary
window record, and the window list.
A window record or color window record describes an individual window. It includes
the record for the graphics port in which the window is displayed.
The state data record stores two rectangles, known as the user state and the standard
state, which define the size and location of the window as specified by the user and by
your application. Your application switches between the two states when the user clicks
the zoom box.
A window color table defines the colors to be used for drawing the window’s frame and
highlighting selected text. Ordinarily, you use the default window color table, which
produces windows in the colors selected by the user through the Color control panel. If
your application has some unusual need to control the frame colors, you can set up your
own window color tables.
The Window Manager uses auxiliary window records to associate a window with its
window color table.
The Window Manager uses the window list to track all of the windows on the desktop.
Window Manager
The routines that manipulate color windows get color information from the window
color tables and the auxiliary window record described in the sections “The Window
Color Table Record” on page 4-71 and “The Auxiliary Window Record” on page 4-73.
TYPE CWindowRecord =
RECORD
port: CGrafPort; {window's graphics port}
windowKind: Integer; {class of the window}
visible: Boolean; {visibility}
hilited: Boolean; {highlighting}
goAwayFlag: Boolean; {presence of close box}
spareFlag: Boolean; {presence of zoom box}
strucRgn: RgnHandle; {handle to structure region}
contRgn: RgnHandle; {handle to content region}
updateRgn: RgnHandle; {handle to update region}
windowDefProc: Handle; {handle to window definition }
{ function}
dataHandle: Handle; {handle to window state }
{ data record}
titleHandle: StringHandle; {handle to window title}
titleWidth: Integer; {title width in pixels}
controlList: ControlHandle; {handle to control list}
nextWindow: CWindowPeek; {pointer to next window }
{ record in window list}
windowPic: PicHandle; {handle to optional picture}
refCon: LongInt; {storage available to your }
{ application}
END;
Field descriptions
port The graphics port record that describes the graphics port in which
the window is drawn.
The graphics port record, which is documented in Inside Macintosh:
Imaging, defines the rectangle in which drawing can occur, the
window’s visible region, the window’s clipping region, and a
collection of current drawing characteristics such as fill pattern, pen
location, and pen size.
windowKind The class of window—that is, how the window was created.
The Window Manager fills in this field when it creates the window
record. It places a negative value in windowKind when the window
Window Manager
Window Manager
Note
The close box, drag region, zoom box, and size box are not included in
the window record because they don’t necessarily have the formal data
structure for regions as defined in QuickDraw. The window definition
function determines where these regions are. ◆
Window Manager
Window Manager
WStateData =
RECORD
userState: Rect; {size and location established by user}
stdState: Rect; {size and location established by app}
END;
Field descriptions
userState A rectangle that describes the window size and location established
by the user.
The Window Manager initializes the user state to the size and
location of the window when it is first displayed, and then updates
the userState field whenever the user resizes a window. Although
the user state specifies both the size and location of the window, the
Window Manager updates the state data record only when the user
resizes a window—not when the user merely moves a window.
stdState The rectangle describing the window size and location that your
application considers the most convenient, considering the function
of the document, the screen space available, and the position of the
window in its user state. If your application does not define a
standard state, the Window Manager automatically sets the
standard state to the entire gray region on the main screen, minus a
three-pixel border on all sides. The user cannot change a window’s
standard state.
Your application typically calculates and sets the standard state each
time the user zooms to the standard state. In a word- processing
application, for example, a standard state window might show a full
page, if possible, or a page of full width and as much length as fits
on the screen. If the user changes the page size through Page Setup,
the application might adjust the standard state to reflect the new
page size. (See Macintosh Human Interface Guidelines for a detailed
description of how your application determines where to open and
zoom windows.)
The ZoomWindow procedure changes the size of a window according to the values in the
window state data record. The procedure changes the window to the user state when the
user zooms “in” and to the standard state when the user zooms “out.” For a detailed
description of zooming windows, see “Zooming a Window” beginning on page 4-53. For
Window Manager
descriptions of the routines you call when zooming windows, see “Zooming Windows”
beginning on page 4-101.
TYPE WinCTab =
RECORD
wCSeed: LongInt; {reserved}
wCReserved: Integer; {reserved}
ctSize: Integer; {number of entries in table -1}
ctTable: ARRAY[0..4] OF ColorSpec;
{array of color specification }
{ records}
END;
Field descriptions
wCSeed Reserved.
wCReserved Reserved.
ctSize The number of entries in the table, minus 1. If you’re building a
color table for use with the standard window definition function, the
maximum value of this field is 12. Custom window definition
functions can use color tables of any size.
Window Manager
Note
The part codes in System 5 and System 6 are significantly different
from the part codes described here, which apply only to System 7. ◆
The window parts can appear in any order in the table.
The rgb field of a ColorSpec record contains three words of data
that specify the red, green, and blue values of the color to be used.
The RGBColor data type is defined in Inside Macintosh: Imaging.
Window Manager
When your application creates a window, the Window Manager first looks for a resource
of type 'wctb' with the same resource ID as the 'WIND' resource used for the window.
If it finds one, it creates a window color table for the window from the information in that
resource, and then displays the window in those colors. If it doesn’t find a window color
table resource with the same resource ID as your window resource, the Window Manager
uses the default system window color table, read into the heap during application
startup.
After creating a window, you can change the entries in a window’s window color table
with the SetWinColor procedure, described on page 4-114.
See “The Window Color Table Resource” on page 4-127 for a description of the window
color table resource.
AuxWinRec =
RECORD
awNext: AuxWinHandle; {handle to next record}
awOwner: WindowPtr; {pointer to window }
{ associated with this }
{ record}
awCTable: CTabHandle; {handle to color table}
dialogCItem: Handle; {storage used by }
{ Dialog Manager}
awFlags: LongInt; {reserved}
awReserved: CTabHandle; {reserved}
awRefCon: LongInt; {reference constant, }
{ for application's use}
END;
Field descriptions
awNext A handle to the next record in the auxiliary window list, used by the
Window Manager to maintain the auxiliary window list as a linked
list. If a window is using the default auxiliary window record, this
value is NIL.
awOwner A pointer to the window that uses this record. The awOwner field of
the default auxiliary window record is set to NIL.
Window Manager
awCTable A handle to the window’s color table. Unless you specify otherwise,
this is a handle to the system window color table.
dialogCItem Private storage for use by the Dialog Manager.
awFlags Reserved.
awReserved Reserved.
awRefCon The reference constant, typically used by an application to associate
the auxiliary window record with a document record.
Except in unusual circumstances, your application doesn’t need to manipulate window
color tables or the auxiliary window record.
For compatibility with other applications in the shared environment, your application
should not manipulate system color tables directly but should go through the Palette
Manager, documented in Inside Macintosh: Imaging. If your application provides its own
window and control definition functions, these functions should apply the user’s desktop
color choices the same way the standard window and control definition functions do.
The Window Manager maintains information about the windows on the desktop in a
private structure called the window list. The window list contains pointers to all windows
on the desktop, both visible and invisible, and contains other information that the
Window Manager uses to maintain the desktop.
Your application should not directly access the information in a window list. The
structure of the window list is private to the Window Manager.
The global variable WindowList contains a pointer to the first window in the
window list.
Window Manager
Ordinarily, your application does not need to know about the Window Manager port.
If necessary, however, you can retrieve a pointer to it by calling the procedure
GetWMgrPort or GetCWMgrPort. Your application should not draw directly into
the Window Manager port, except through custom window definition functions.
The Window Manager draws your application’s windows into the Window Manager
port. The port rectangle of the Window Manager port is the bounding rectangle of the
main screen (screenBits.bounds). To accommodate systems with multiple monitors,
QuickDraw recognizes a port rectangle of screenBits.bounds as a special case and
allows drawing on all parts of the desktop.
InitWindows 4
The procedure InitWindows initializes the Window Manager for your application.
Before calling InitWindows, you must initialize QuickDraw and the Font Manager by
calling the InitGraf and InitFonts procedures, documented in Inside Macintosh:
Imaging and Inside Macintosh: Text.
PROCEDURE InitWindows;
DESCRIPTION
The InitWindows procedure initializes the Window Manager.
ASSEMBLY-LANGUAGE INFORMATION
When the desktop needs to be redrawn any time after initialization, the Window
Manager checks the global variable DeskHook, which can be used as a pointer to an
application-defined routine for drawing the desktop. This variable is ordinarily set to 0,
but not until after system startup. If you’re displaying windows in code that is to be
executed during startup, set DeskHook to 0. Note that the use of the Window Manager’s
global variables is not guaranteed to be compatible in system software versions later than
System 6.
Creating Windows 4
You can create windows in two ways:
■ from a window resource (a resource of type 'WIND'), with the GetNewCWindow and
GetNewWindow functions
■ from a collection of window characteristics passed as parameters to the NewCWindow
and NewWindow functions
Creating windows from resources allows you to localize your application for different
languages and to change the characteristics of your windows during application
development by changing only the window resources.
Window Manager
GetNewCWindow 4
Use the GetNewCWindow function to create a color window with the properties defined
in the 'WIND' resource with a specified resource ID.
windowID The resource ID of the 'WIND' resource that defines the properties of
the window.
wStorage A pointer to memory space for the window record.
If you specify a value of NIL for wStorage, the GetNewCWindow
function allocates the window record as a nonrelocatable object in the
heap. You can reduce the chances of heap fragmentation by allocating the
memory your application needs for window records early in your
initialization code. Whenever you need to create a window, you can
allocate memory from your own block and pass a pointer to it in the
wStorage parameter.
behind A pointer to the window that appears immediately in front of the new
window on the desktop.
To place a new window in front of all other windows on the desktop,
specify a value of Pointer(–1). When you place a window in front of all
others, GetNewCWindow removes the highlighting from the previously
active window, highlights the newly created window, and generates the
appropriate activate events. Note that if you create an invisible window in
front of all others on the desktop, the user sees no active window until you
make the new window visible (or make another window active).
To place a new window behind all other windows, specify a value of NIL.
DESCRIPTION
The GetNewCWindow function creates a new color window from the specified window
resource and returns a pointer to the newly created window record. You can use the
returned window pointer to refer to this window in most Window Manager routines. If
GetNewCWindow is unable to read the window or window definition function from the
resource file, it returns NIL.
Window Manager
The GetNewCWindow function looks for a 'wctb' resource with the same resource ID as
that of the 'WIND' resource. If it finds one, it uses the window color information in the
'wctb' resource for coloring the window frame and highlighting selected text.
If the window’s definition function (specified in the window resource) is not already in
memory, GetNewCWindow reads it into memory and stores a handle to it in the window
record. It allocates space in the application heap for the structure and content regions of
the window and asks the window definition function to calculate those regions.
To create the window, GetNewCWindow retrieves the window characteristics from the
window resource and then calls the NewCWindow function, passing the characteristics
as parameters.
The GetNewCWindow function creates a window in a color graphics port. Before calling
GetNewCWindow, verify that Color QuickDraw is available. Your application typically
sets up its own global variables reflecting the system setup during initialization by calling
the Gestalt function. See Inside Macintosh: Overview for more information about
establishing the local configuration.
SPECIAL CONSIDERATIONS
Note that the GetNewCWindow function returns a value of type WindowPtr, not
CWindowPtr.
If you let the Window Manager create the window record in your application’s heap, call
DisposeWindow to dispose of the window’s window record. If you allocated the
memory for the window record yourself and passed a pointer to the storage to
GetNewCWindow, use the procedure CloseWindow to close the window and the
procedure DisposePtr, documented in Inside Macintosh: Memory, to dispose of the
window record.
SEE ALSO
See Listing 4-3 on page 4-28 for an example that calls GetNewCWindow to create a new
window from a window resource.
For more information about window characteristics and the window resource, see the
description of NewCWindow beginning on page 4-79 and the description of the 'WIND'
resource in the section “The Window Resource” beginning on page 4-124.
For the procedures for closing a window and removing the structures from memory, see
the descriptions of the DisposeWindow procedure on page 4-105, the CloseWindow
procedure on page 4-104, and the DisposePtr procedure in Inside Macintosh: Memory.
See Listing 4-17 on page 4-61 for an example of closing a document window.
Window Manager
GetNewWindow 4
Use the GetNewWindow function to create a new window from a window resource
when Color QuickDraw is not available. The GetNewWindow function takes the same
parameters as GetNewCWindow and returns a value of type WindowPtr. The only
difference is that it creates a monochrome graphics port, not a color graphics port.
The window record and graphics port record that describe monochrome and color
graphics ports are the same size and can be used interchangeably in most Window
Manager routines.
windowID The resource ID of the 'WIND' resource that defines the properties of the
window.
wStorage A pointer to memory space for the window record.
If you specify a value of NIL for wStorage, the GetNewWindow function
allocates the window record as a nonrelocatable object in the heap. You
can reduce the chances of heap fragmentation by allocating the memory
your application needs for window records early in your initialization
code. Whenever you need to create a window, you can allocate memory
from your own block and pass a pointer to it in the wStorage parameter.
behind A pointer to the window that appears immediately in front of the new
window on the desktop.
To place a new window in front of all other windows on the desktop,
specify a value of Pointer(–1). When you place a window in front of all
others, GetNewWindow removes the highlighting from the previously
active window, highlights the newly created window, and generates the
appropriate activate events. Note that if you create an invisible window in
front of all others on the desktop, the user sees no active window until you
make the new window visible (or make another window active).
To place a new window behind all other windows, specify a value of NIL.
DESCRIPTION
Like GetNewCWindow, GetNewWindow creates a new window from a window resource,
but it creates a monochrome window. The GetNewWindow function creates a new
window from the specified window resource and returns a pointer to the newly created
window record. You can use the returned window pointer to refer to this window in most
Window Manager routines. If GetNewWindow is unable to read the window or window
definition function from the resource file, it returns NIL.
If the window’s definition function (specified in the window resource) is not already in
memory, GetNewWindow reads it into memory and stores a handle to it in the window
record. It allocates space in the application heap for the structure and content regions of
the window and asks the window definition function to calculate those regions.
Window Manager
To create the window, GetNewWindow retrieves the window characteristics from the
window resource and then calls the function NewWindow, passing the characteristics
as parameters.
SPECIAL CONSIDERATIONS
If you let the Window Manager create the window record in your application’s heap, call
DisposeWindow to dispose of the window’s window record. If you allocated the
memory for the window record yourself and passed a pointer to GetNewWindow, use the
procedure CloseWindow to close the window and the procedure DisposePtr,
documented in Inside Macintosh: Memory, to dispose of the window record.
SEE ALSO
For more information about window characteristics and the window resource, see the
description of NewWindow beginning on page 4-82 and the description of the 'WIND'
resource in the section “The Window Resource” beginning on page 4-124.
For the procedures for closing a window and removing the structures from memory, see
the descriptions of the DisposeWindow procedure on page 4-105, the CloseWindow
procedure on page 4-104, and the DisposePtr procedure in Inside Macintosh: Memory.
NewCWindow 4
You can use the NewCWindow function to create a window with a specified list of
characteristics.
wStorage A pointer to the window record. If you specify NIL as the value of
wStorage, NewCWindow allocates the window record as a nonrelocatable
object in the application heap. You can reduce the chances of heap
fragmentation by allocating memory from a block of memory reserved for
this purpose by your application and passing a pointer to it in the
wStorage parameter.
boundsRect A rectangle, in global coordinates, specifying the window’s initial size and
location. This parameter becomes the port rectangle of the window’s
graphics port. For the standard window types, the boundsRect field
defines the content region of the window. The NewCWindow function
places the origin of the local coordinate system at the upper-left corner of
the port rectangle.
Window Manager
Note
The NewCWindow function actually calls the QuickDraw procedure
OpenCPort to create the graphics port. The bitmap, pen pattern,
and other characteristics of the window’s graphics port are the same
as the default values set by OpenCPort, except for the character font,
which is set to the application font instead of the system font. ◆
title A string that specifies the window’s title.
If the title is too long to fit in the title bar, the title is truncated. If the
window has a close box, characters are truncated at the end of the title; if
there’s no close box, the title is centered and truncated at both ends.
To suppress the title in a window with a title bar, pass an empty string, not
NIL, in the title parameter.
visible A Boolean value indicating visibility status: TRUE means that the Window
Manager displays the window; FALSE means it does not.
If the value of the visible parameter is TRUE, the Window Manager
draws a new window as soon as the window exists. The Window
Manager first calls the window definition function to draw the window
frame. If the value of the goAwayFlag parameter is also TRUE and the
window is frontmost (that is, if the value of the behind parameter is
Pointer(–1)), the Window Manager instructs the window definition
function to draw a close box in the window frame. After drawing the
frame, the Window Manager generates an update event to trigger your
application’s drawing of the content region.
When you create a window, you typically specify FALSE as the value of
the visible parameter. When you’re ready to display the window, you
call the ShowWindow procedure, described on page 4-88.
procID The window’s definition ID, which specifies both the window definition
function and the variation code within that definition function.
The Window Manager supports nine standard window types, which
are handled by two window definition functions. You can create windows
of the standard types by specifying one of the window definition ID
constants:
CONST
documentProc = 0; {standard document }
{ window, no zoom box}
dBoxProc = 1; {alert box or modal }
{ dialog box}
plainDBox = 2; {plain box}
altDBoxProc = 3; {plain box with shadow}
noGrowDocProc = 4; {movable window, }
{ no size box or zoom box}
movableDBoxProc = 5; {movable modal dialog box}
zoomDocProc = 8; {standard document window}
zoomNoGrow = 12; {zoomable, nonresizable }
{ window}
rDocProc = 16; {rounded-corner window}
Window Manager
DESCRIPTION
The NewCWindow function creates a window as specified by its parameters, adds it to the
window list, and returns a pointer to the newly created window record. You can use the
returned window pointer to refer to this window in most Window Manager routines. If
NewCWindow is unable to read the window definition function from the resource file, it
returns NIL.
The NewCWindow function looks for a 'wctb' resource with the same resource ID as the
'WIND' resource. If it finds one, it uses the window color information in the 'wctb'
resource for coloring the window frame and highlighting.
If the window’s definition function is not already in memory, NewCWindow reads it
into memory and stores a handle to it in the window record. It allocates space for the
structure and content regions of the window and asks the window definition function
to calculate those regions.
Storing the characteristics of your windows as resources, especially window titles and
window items, makes your application easier to localize.
The NewCWindow function creates a window in a color graphics port. Creating color
windows whenever possible ensures that your windows appear on color monitors with
whatever color options the user has selected. Before calling GetNewCWindow, verify that
Color QuickDraw is available. Your application typically sets up its own set of global
Window Manager
variables reflecting the system setup during initialization by calling the Gestalt
function. See the chapter Inside Macintosh: Overview for more information about
establishing the local configuration.
Note that the function NewCWindow returns a value of type WindowPtr, not
CWindowPtr.
SPECIAL CONSIDERATIONS
If you let the Window Manager create the window record in your application’s heap,
call the DisposeWindow procedure to close the window and dispose of its window
record. If you allocated the memory for the window record yourself and passed a
pointer to NewCWindow, use the CloseWindow procedure to close the window and
the DisposePtr procedure, documented in Inside Macintosh: Memory, to dispose of the
window record.
SEE ALSO
For the procedures for closing a window and removing the structures from memory, see
the descriptions of the DisposeWindow procedure on page 4-105, the CloseWindow
procedure on page 4-104, and the DisposePtr procedure in Inside Macintosh: Memory.
NewWindow 4
Use the NewWindow function to create a new window with the characteristics specified
by a list of parameters when Color QuickDraw is not available. The NewWindow function
takes the same parameters as NewCWindow and, like NewCWindow, returns a WindowPtr
as its function result. The only difference is that NewWindow creates a window in a
monochrome graphics port, not a color graphics port. The window record and graphics
port record that describe monochrome and color graphics ports are the same size and can
be used interchangeably in most Window Manager routines.
wStorage A pointer to the window record. If you specify NIL as the value of
wStorage, NewWindow allocates the window record as a nonrelocatable
object in the heap. You can reduce the chances of heap fragmentation by
allocating the storage from a block of memory reserved for this purpose
by your application and passing a pointer to it in the wStorage
parameter.
Window Manager
boundsRect A rectangle, in global coordinates, specifying the window’s initial size and
location. This parameter becomes the port rectangle of the window’s
graphics port. For the standard window types, boundsRect defines
the content region of the window. The NewWindow function places
the origin of the local coordinate system at the upper-left corner of the
port rectangle.
Note
The NewWindow function actually calls the QuickDraw procedure
OpenPort to create the graphics port. The bitmap, pen pattern, and
other characteristics of the window’s graphics port are the same as
the default values set by OpenPort, except for the character font,
which is set to the application font instead of the system font. The
coordinates of the graphics port’s port boundaries and visible region
are changed along with its port rectangle. ◆
title A string that specifies the window’s title.
If the title is too long to fit in the title bar, the title is truncated. If the
window has a close box, characters at the end of the title are truncated; if
there’s no close box, the title is centered and truncated at both ends.
To suppress the title in a window with a title bar, pass an empty string, not
NIL.
visible A Boolean value indicating visibility status: TRUE means that the Window
Manager displays the window; FALSE means it does not.
If the value of the visible parameter is TRUE, the Window Manager
draws a new window as soon as the window exists. The Window
Manager first calls the window definition function to draw the window
frame. If the value of the goAwayFlag parameter (described below) is
also TRUE and the window is frontmost (that is, if the value of the behind
parameter is Pointer(–1)), the Window Manager instructs the window
definition function to draw a close box in the window frame. After
drawing the frame, the Window Manager generates an update event to
trigger your application’s drawing of the content region.
When you create a window, you typically specify FALSE as the value of
the visible parameter. When you’re ready to display the window, you
call the ShowWindow procedure, described on page 4-88.
theProc The window’s definition ID, which specifies both the window definition
function and the variation code for that definition function.
The Window Manager supports nine standard window types, which are
handled by two window definition functions. You can create windows of
the standard types by specifying one of the type constants:
CONST
documentProc = 0; {standard document }
{ window, no zoom box}
dBoxProc = 1; {alert box or modal }
{ dialog box}
plainDBox = 2; {plain box}
Window Manager
DESCRIPTION
The NewWindow function creates a window as specified by its parameters, adds it to the
window list, and returns a pointer to the newly created window record. You can use the
returned window pointer to refer to this window in most Window Manager routines. If
NewWindow is unable to read the window definition function from the resource file, it
returns NIL.
If the window’s definition function is not already in memory, NewWindow reads it into
memory and stores a handle to it in the window record. It allocates space for the
structure and content regions of the window and asks the window definition function to
calculate those regions.
Storing the characteristics of your windows as resources, especially window titles and
window items, makes your application easier to localize.
Window Manager
SPECIAL CONSIDERATIONS
If you let the Window Manager create the window record in your application’s heap, call
the DisposeWindow procedure to close the window and dispose of its window record. If
you allocated the memory for the window record yourself and passed a pointer to
NewCWindow, use the CloseWindow procedure to close the window and the
DisposePtr procedure, documented in Inside Macintosh: Memory, to dispose of the
window record.
SEE ALSO
For the procedures for closing a window and removing the structures from memory, see
the descriptions of the DisposeWindow procedure on page 4-105, the CloseWindow
procedure on page 4-104, and the DisposePtr procedure in Inside Macintosh: Memory.
Naming Windows 4
This section describes the procedures that set and retrieve a window’s title.
SetWTitle 4
DESCRIPTION
The SetWTitle procedure changes a window’s title to the specified string, both in the
window record and on the screen, and redraws the window’s frame as necessary.
When the user opens a previously saved document, you typically create a new (invisible)
window with the title “untitled” and then call SetWTitle to give the window the
document’s name before displaying it. You also call SetWTitle when the user saves a
document under a new name.
To suppress the title in a window with a title bar, pass an empty string, not NIL.
Always use SetWTitle instead of directly changing the title in a window’s
window record.
Window Manager
GetWTitle 4
DESCRIPTION
The GetWTitle procedure returns the title of the window in the title parameter.
Your application seldom needs to determine a window’s title. It might need to do so,
however, when presenting user dialog boxes during operations that can affect multiple
files. A spell-checking command, for example, might display a dialog box that lets the
user select from all currently open documents.
When you need to retrieve a window’s title, you should always use GetWTitle instead
of reading the title from a window’s window record.
Displaying Windows 4
This section describes the Window Manager routines that change a window’s display
and position in the window list but not its size or location on the desktop. Note that the
Window Manager automatically draws all visible windows on the screen.
Your application typically uses only a few of the routines described in this section:
DrawGrowIcon, SelectWindow, ShowWindow, and, occasionally, HideWindow.
DrawGrowIcon 4
DESCRIPTION
The DrawGrowIcon procedure draws a window’s size box or, if the window can’t be
sized, whatever other image is appropriate. You call DrawGrowIcon when drawing the
content region of a window that contains a size box.
The exact appearance and location of the image depend on the window type and the
window’s active or inactive state. The DrawGrowIcon procedure automatically checks
the window’s type and state and draws the appropriate image.
Window Manager
In an active document window, DrawGrowIcon draws the grow image in the size box in
the lower-right corner of the window’s graphics port rectangle, along with the lines
delimiting the size box and scroll bar areas. To draw the size box but not the scroll bar
outline, set the clipRgn field in the window’s graphics port to be a 15-by-15 pixel
rectangle in the lower-right corner of the window.
The DrawGrowIcon procedure doesn’t erase the scroll bar areas. If you use
DrawGrowIcon to draw the size box and scroll bar outline, therefore, you should
erase those areas yourself when the window size changes, even if the window
doesn’t contain scroll bars.
In an inactive document window, DrawGrowIcon draws the lines delimiting the size box
and scroll bar areas and erases the size box.
SEE ALSO
See Listing 4-8 on page 4-39 for an example that draws a window’s content region,
including the size box. See Listing 4-11 on page 4-51 for an example that calls
DrawGrowIcon to remove the size-box icon when a window becomes inactive.
SelectWindow 4
DESCRIPTION
The SelectWindow procedure removes highlighting from the previously active window,
brings the specified window to the front, highlights it, and generates the activate events
to deactivate the previously active window and activate the specified window. If the
specified window is already active, SelectWindow has no effect.
Even if the specified window is invisible, SelectWindow brings the window to the
front, activates the window, and deactivates the previously active window. Note that in
this case, no active window is visible on the screen. If you do select an invisible window,
be sure to call ShowWindow immediately to make the window visible (and accessible to
the user).
Call SelectWindow when the user presses the mouse button while the cursor is in the
content region of an inactive window.
Window Manager
SEE ALSO
See Listing 4-9 on page 4-44 for an example that calls SelectWindow to change
the active window when the user presses the mouse button while the cursor is
in an inactive window.
See Listing 4-18 on page 4-64 for an example that uses SelectWindow and ShowWindow
together to restore a window’s active, visible status after it has
been made invisible with HideWindow.
ShowWindow 4
DESCRIPTION
The ShowWindow procedure makes an invisible window visible. If the specified window
is already visible, ShowWindow has no effect. Your application typically creates a new
window in an invisible state, performs any necessary setup of the content region, and
then calls ShowWindow to make the window visible.
When you display a previously invisible window by calling ShowWindow, the Window
Manager draws the window frame and then generates an update event to trigger your
application’s drawing of the content region.
If the newly visible window is the frontmost window, ShowWindow highlights it if
it’s not already highlighted and generates an activate event to make it active. The
ShowWindow procedure does not activate a window that is not frontmost on the desktop.
Note
Because ShowWindow does not change the front-to-back ordering of
windows, it is not the inverse of HideWindow. If you make the frontmost
window invisible with HideWindow, and HideWindow has activated
another window, you must call both ShowWindow and SelectWindow
to bring the original window back to the front. ◆
SEE ALSO
See Listing 4-16 on page 4-60 for an example that temporarily hides a dialog box
window when the user closes it. See Listing 4-18 on page 4-64 for the example that
calls ShowWindow to display the window again later.
Window Manager
HideWindow 4
DESCRIPTION
The HideWindow procedure make a visible window invisible. If you hide the frontmost
window, HideWindow removes the highlighting, brings the window behind it to
the front, highlights the new frontmost window, and generates the appropriate
activate events.
To reverse the actions of HideWindow, you must call both ShowWindow, to make the
window visible, and SelectWindow, to select it.
SEE ALSO
See Listing 4-16 on page 4-60 for an example that calls HideWindow to temporarily
hide a dialog box window when the user closes it. See Listing 4-18 on page 4-64 for the
companion example that redisplays the window later.
ShowHide 4
DESCRIPTION
The ShowHide procedure sets a window’s visibility to the status specified by the
showFlag parameter. If the value of showFlag is TRUE, ShowHide makes the window
visible if it’s not already visible and has no effect if it’s already visible. If the value of
showFlag is FALSE, ShowHide makes the window invisible if it’s not already invisible
and has no effect if it’s already invisible.
The ShowHide procedure never changes the highlighting or front-to-back ordering of
windows and generates no activate events.
Window Manager
▲ WARNING
Use this procedure carefully and only in special circumstances where
you need more control than that provided by HideWindow and
ShowWindow. Do not, for example, use ShowHide to hide the active
window without making another window active. ▲
HiliteWindow 4
DESCRIPTION
The HiliteWindow procedure sets a window’s highlighting status to the specified state.
If the value of the fHilite parameter is TRUE, HiliteWindow highlights the specified
window; if the specified window is already highlighted, the procedure has no effect.
If the value of fHilite is FALSE, HiliteWindow removes highlighting from the
specified window; if the window is not already highlighted, the procedure has no effect.
Your application doesn’t normally need to call HiliteWindow. To make a window
active, you can call SelectWindow, which handles highlighting for you.
BringToFront 4
DESCRIPTION
The BringToFront procedure puts the specified window at the beginning of the
window list and redraws the window in front of all others on the screen. It does
not change the window’s highlighting or make it active.
Your application does not ordinarily call BringToFront. The user interface guidelines
specify that the frontmost window should be the active window. To bring a window to
the front and make it active, call the SelectWindow procedure.
Window Manager
SendBehind 4
DESCRIPTION
The SendBehind procedure moves the window pointed to by the parameter
theWindow behind the window pointed to by the parameter behindWindow. If the
move exposes previously obscured windows or parts of windows, SendBehind redraws
the frames as necessary and generates the appropriate update events to
have any newly exposed content areas redrawn.
If the value of behindWindow is NIL, SendBehind sends the window to be moved
behind all other windows on the desktop. If the window to be moved is the active
window, SendBehind removes its highlighting, highlights the newly exposed frontmost
window, and generates the appropriate activate events.
Note
Do not use SendBehind to deactivate a window after you’ve made a
new window active with the SelectWindow procedure. The
SelectWindow procedure automatically deactivates the previously
active window. ◆
FindWindow 4
When your application receives a mouse-down event, call the FindWindow function to
map the location of the cursor to a part of the screen or a region of a window.
Window Manager
thePoint The point, in global coordinates, where the mouse-down event occurred.
Your application retrieves this information from the where field of the
event record.
theWindow A parameter in which FindWindow returns a pointer to the window in
which the mouse-down event occurred, if it occurred in a window. If it
didn’t occur in a window, FindWindow sets theWindow to NIL.
DESCRIPTION
The FindWindow function returns an integer that specifies where the cursor was when
the user pressed the mouse button. You typically call FindWindow whenever you receive
a mouse-down event. The FindWindow function helps you dispatch the event by
reporting whether the cursor was in the menu bar or in a window when the mouse
button was pressed and, if it was in a window, which window and which region of the
window. If the mouse-down event occurred in a window, FindWindow places a pointer
to the window in the parameter theWindow.
The FindWindow function returns an integer that specifies one of nine regions:
The FindWindow function returns inDesk if the cursor is not in the menu bar, a desk
accessory window, or any window that belongs to your application. The FindWindow
function might return this value if, for example, the user presses the mouse button while
the cursor is on the window frame but not in the title bar, close box, or zoom box. When
FindWindow returns inDesk, your application doesn’t need to do anything. In System
7, when the user presses the mouse button while the cursor is on the desktop or in a
window that belongs to another application, the Event Manager sends your application a
suspend event and switches to the Finder or another application.
The FindWindow function returns inMenuBar when the user presses the mouse button
with the cursor in the menu bar. Your application typically adjusts its menus and then
calls the Menu Manager’s function MenuSelect to let the user choose menu items.
The FindWindow function returns inSysWindow when the user presses the mouse
button while the cursor is in a window belonging to a desk accessory that was launched
in your application’s partition. This situation seldom arises in System 7. When the user
Window Manager
SEE ALSO
See Listing 4-9 on page 4-44 for an example that calls FindWindow to determine the
location of the cursor and then dispatches the mouse-down event depending on
the results.
FrontWindow 4
Window Manager
DESCRIPTION
The FrontWindow function returns a pointer to the first visible window in the
window list (that is, the active window). If there are no visible windows, FrontWindow
returns NIL.
SEE ALSO
See Listing 4-9 on page 4-44 for an example that calls FrontWindow to determine
whether an event occurred in the active window.
See Listing 4-12 on page 4-55 for an example that calls FrontWindow to determine
whether to display a window in front of other windows after changing its size.
See Listing 4-16 on page 4-60 and Listing 4-17 on page 4-61 for examples that call
FrontWindow to determine which window is affected by a user command directed
at the active window.
Moving Windows 4
This section describes the procedures that move windows on the desktop.
To move a window, your application ordinarily needs to call only the DragWindow
procedure, which itself calls the DragGrayRgn function, and the MoveWindow
procedure. The DragGrayRgn function drags a dotted outline of the window on the
screen, following the motion of the cursor, as long as the user holds down the mouse
button. The DragGrayRgn function itself calls the PinRect function to contain the point
where the cursor was when the mouse button was first pressed inside the
available desktop area. When the user releases the mouse button, DragWindow calls
MoveWindow, which moves the window to a new location.
DragWindow 4
When the user drags a window by its title bar, use the DragWindow procedure to move
the window on the screen.
Window Manager
DESCRIPTION
The DragWindow procedure moves a dotted outline of the specified window around the
screen, following the movement of the cursor until the user releases the mouse button.
When the button is released, DragWindow calls MoveWindow to move the window to its
new location. If the specified window isn’t the active window (and the Command key
wasn’t down when the mouse button was pressed), DragWindow makes it the active
window by setting the front parameter to TRUE when calling MoveWindow. If the
Command key was down when the mouse button was pressed, DragWindow moves the
window without making it active.
SEE ALSO
The DragWindow procedure calls both MoveWindow and DragGrayRgn, which are
described in this section.
See Listing 4-9 on page 4-44 for an example that calls DragWindow when the user presses
the mouse button while the cursor is in the drag region.
MoveWindow 4
Window Manager
DESCRIPTION
The MoveWindow procedure moves the specified window to the location specified by the
hGlobal and vGlobal parameters, without changing the window’s size. The upper-left
corner of the window’s port rectangle is placed at the point (vGlobal,hGlobal). The
local coordinates of the upper-left corner are unaffected.
Your application doesn’t normally call MoveWindow. When the user drags a window by
dragging its title bar, you can call DragWindow, which in turn calls MoveWindow when
the user releases the mouse button.
DragGrayRgn 4
Window Manager
DESCRIPTION
The DragGrayRgn function moves a gray outline of a region on the screen, following the
movements of the cursor, until the mouse button is released. It returns the difference
between the point where the mouse button was pressed and the offset point—that is, the
point in the region whose horizontal and vertical offsets from the upper-left corner of the
region’s enclosing rectangle are the same as the offsets of the starting point when the user
pressed the mouse button. The DragGrayRgn function stores the vertical difference
between the starting point and the offset point in the high-order word of the return value
and the horizontal difference in the low-order word.
The DragGrayRgn function limits the movement of the region according to the
constraints set by the limitRect and slopRect parameters:
■ As long as the cursor is inside the limitRect rectangle, the region’s outline follows it
normally. If the mouse button is released while the cursor is within this rectangle, the
return value reflects the simple distance that the cursor moved in each dimension.
■ When the cursor moves outside the limitRect rectangle, the offset point stops at the
edge of the limitRect rectangle. If the mouse button is released while the cursor
is outside the limitRect rectangle but inside the slopRect rectangle, the return
value reflects only the difference between the starting point and the offset point,
regardless of how far outside of the limitRect rectangle the cursor may have moved.
(Note that part of the region can fall outside the limitRect rectangle, but not the
offset point.)
■ When the cursor moves outside the slopRect rectangle, the region’s outline
disappears from the screen. The DragGrayRgn function continues to track the cursor,
however, and if the cursor moves back into the slopRect rectangle, the outline
reappears. If the mouse button is released while the cursor is outside the slopRect
rectangle, both words of the return value are set to $8000. In this case, the Window
Manager does not move the window from its original location.
Figure 4-23 on page 4-98 illustrates how the region stops moving when the offset point
reaches the edge of the limitRect rectangle. The cursor continues to move, but the
region does not.
If the mouse button is released while the cursor is anywhere inside the slopRect
rectangle, the Window Manager redraws the window in its new location, which is
calculated from the value returned by DragGrayRgn.
Window Manager
slopRect startPt
limitRect theRgn
The user presses the mouse button with the cursor at startPt.
ASSEMBLY-LANGUAGE INFORMATION
You can set the global variable DragHook to point to an optional procedure, defined
by your application, which will be called by DragGrayRgn as long as the mouse
button is held down. (If there’s an actionProc procedure, it is called first.) If you
want DragGrayRgn to draw the region’s outline in a pattern other than gray, you
can store the pattern in the global variable DragPattern and then invoke the macro
_DragTheRgn. Note that the use of the Window Manager’s global variables is not
guaranteed to be compatible with system software versions later than System 6.
Window Manager
PinRect 4
The DragGrayRgn function uses the PinRect function to contain a point within a
specified rectangle.
DESCRIPTION
The PinRect function returns a point within the specified rectangle that is as close as
possible to the specified point. (The high-order word of the returned long integer is the
vertical coordinate; the low-order word is the horizontal coordinate.)
If the specified point is within the rectangle, PinRect returns the point itself. If not, then
■ if the horizontal position is to the left of the rectangle, PinRect returns the left edge as
the horizontal coordinate
■ if the horizontal position is to the right of the rectangle, PinRect returns the right
edge minus 1 as the horizontal coordinate
■ if the vertical position is above the rectangle, PinRect returns the top edge as the
vertical coordinate
■ if the vertical position is below the rectangle, PinRect returns the bottom edge minus
1 as the vertical coordinate
Note
The 1 is subtracted when the point is below or to the right of the
rectangle so that a pixel drawn at that point lies within the rectangle. If
the point is exactly on the bottom or the right edge of the rectangle,
however, 1 should be subtracted but isn’t. ◆
Resizing Windows 4
This section describes the procedures you can use to track the cursor while the user
resizes a window and to draw the window in a new size.
GrowWindow 4
Use the GrowWindow function to allow the user to change the size of a window. The
GrowWindow function displays an outline (grow image) of the window as the user
moves the cursor to make the window larger or smaller; it handles all user interaction
Window Manager
until the user releases the mouse button. After calling GrowWindow, you call the
SizeWindow procedure to change the size of the window.
DESCRIPTION
The GrowWindow function moves a dotted-line image of the window’s right and lower
edges around the screen, following the movements of the cursor until the mouse button
is released. It returns the new dimensions, in pixels, of the resulting window: the height
in the high-order word of the returned long-integer value and the width in the low-order
word. You can use the functions HiWord and LoWord to retrieve only the high-order and
low-order words, respectively.
A return value of 0 means that the new size is the same as the size of the current
port rectangle.
ASSEMBLY-LANGUAGE INFORMATION
You can set the global variable DragHook to point to an optional procedure, defined by
your application, which will be called by GrowWindow as long as the mouse button is
held down. (If there’s an actionProc procedure, the actionProc procedure is called
first.) Note that the use of the Window Manager’s global variables is not guaranteed to be
compatible with system software versions later than System 6.
SEE ALSO
See Listing 4-13 on page 4-58 for an example that calls GrowWindow when the user
presses the mouse button while the cursor is in the size box.
Window Manager
SizeWindow 4
DESCRIPTION
The SizeWindow procedure changes the size of the window’s graphics port rectangle to
the dimensions specified by the w and h parameters, or does nothing if the values of w
and h are 0. The Window Manager redraws the window in the new size, recentering the
title and truncating it if necessary. Your application calls SizeWindow immediately after
calling GrowWindow, to adjust the window to any changes made by the user through the
size box.
SEE ALSO
See Listing 4-13 on page 4-58 for an example that calls SizeWindow to resize a window
based on the return value of GrowWindow.
Zooming Windows 4
This section describes the procedures you can use to track mouse activity in the zoom box
and to zoom windows.
TrackBox 4
Use the TrackBox function to track the cursor when the user presses the mouse button
while the cursor is in the zoom box.
Window Manager
theWindow A pointer to the window record of the window in which the mouse button
was pressed.
thePt The location of the cursor when the mouse button was pressed. Your
application receives this point from the where field in the event record.
partCode The part code (either inZoomIn or inZoomOut) returned by the
FindWindow function.
DESCRIPTION
The TrackBox function tracks the cursor when the user presses the mouse button while
the cursor is in the zoom box, retaining control until the mouse button is released. While
the button is down, TrackBox highlights the zoom box while the cursor is in the zoom
region, as illustrated in Figure 4-20 on page 4-47.
When the mouse button is released, TrackBox removes the highlighting from the zoom
box and returns TRUE if the cursor is within the zoom region and FALSE if it is not.
Your application calls the TrackBox function when it receives a result code of either
inZoomIn or inZoomOut from the FindWindow function. If TrackBox returns TRUE,
your application calculates the standard state, if necessary, and calls the ZoomWindow
procedure to zoom the window. If TrackBox returns FALSE, your application
does nothing.
ASSEMBLY-LANGUAGE INFORMATION
You can set the global variable DragHook to point to an optional procedure, defined by
your application, which will be called by TrackBox as long as the mouse button is held
down. (If there’s an actionProc procedure, the actionProc procedure is called first.)
Note that the use of the Window Manager’s global variables is not guaranteed to be
compatible with system software versions later than System 6.
SEE ALSO
See Listing 4-12 on page 4-55 for an example that calls TrackBox to track cursor activity
when the user presses the mouse button while the cursor is in the zoom box.
ZoomWindow 4
Use the ZoomWindow procedure to zoom the window when the user has pressed and
released the mouse button with the cursor in the zoom box.
Window Manager
DESCRIPTION
The ZoomWindow procedure zooms a window in or out, depending on the value of
the partCode parameter. Your application calls ZoomWindow, passing it the part
code returned by FindWindow, when it receives a result of TRUE from TrackBox.
The ZoomWindow procedure then changes the window’s port rectangle to either
the user state (if the part code is inZoomIn) or the standard state (if the part code is
inZoomOut), as stored in the window state data record, described in the section
“Zooming a Window” beginning on page 4-53.
If the part code is inZoomOut, your application ordinarily calculates and sets the
standard state before calling ZoomWindow.
For best results, call the QuickDraw procedure EraseRect, passing the window’s
graphics port as the port rectangle, before calling ZoomWindow.
SEE ALSO
See Listing 4-12 on page 4-55 for an example that calculates and sets the standard state
and then calls ZoomWindow to zoom a window.
TrackGoAway 4
Use the TrackGoAway function to track the cursor when the user presses the mouse
button while the cursor is in the close box.
theWindow A pointer to the window record of the window in which the mouse-down
event occurred.
thePt The location of the cursor at the time the mouse button was pressed. Your
application receives this point from the where field of the event record.
Window Manager
DESCRIPTION
The TrackGoAway function tracks cursor activity when the user presses the mouse
button while the cursor is in the close box, retaining control until the user releases the
mouse button. While the button is down, TrackGoAway highlights the close box as long
as the cursor is in the close region, as illustrated in Figure 4-19 on page 4-46.
When the mouse button is released, TrackGoAway removes the highlighting from the
close box and returns TRUE if the cursor is within the close region and FALSE if it is not.
Your application calls the TrackGoAway function when it receives a result code of
inGoAway from the FindWindow function. If TrackGoAway returns TRUE, your
application calls its own procedure for closing a window, which can call either the
CloseWindow procedure or the DisposeWindow procedure to remove the window
from the screen. (Before removing a document window, your application ordinarily
checks whether the document has changed since the associated file was last saved.
See the chapter “Introduction to File Management” in Inside Macintosh: Files for a
general discusion of handling files.) If TrackGoAway returns FALSE, your application
does nothing.
ASSEMBLY-LANGUAGE INFORMATION
You can set the global variable DragHook to point to an optional procedure, defined by
your application, which will be called by TrackGoAway as long as the mouse button is
held down. (If there’s an actionProc procedure, the actionProc procedure is called
first.) Note that the use of the Window Manager’s global variables is not guaranteed to be
compatible with system software versions later than System 6.
SEE ALSO
See Listing 4-9 on page 4-44 for an example that calls TrackGoAway to track cursor
activity when the user presses the mouse button while the cursor is in the close box.
CloseWindow 4
Use the CloseWindow procedure to remove a window if you allocated memory yourself
for the window’s window record.
DESCRIPTION
The CloseWindow procedure removes the specified window from the screen and deletes
it from the window list. It releases the memory occupied by all data structures associated
with the window except the window record itself.
Window Manager
If you allocated memory for the window record and passed a pointer to it as one of the
parameters to the functions that create windows, call CloseWindow when you’re done
with the window. You must then call the Memory Manager procedure DisposePtr to
release the memory occupied by the window record.
▲ WARNING
If your application allocated any other memory for use with a window,
you must release it before calling CloseWindow. The Window Manager
releases only the data structures it created.
Also, CloseWindow assumes that any picture pointed to by the window
record field windowPic is data, not a resource, and it calls the
QuickDraw procedure KillPicture to delete it. If your application
uses a picture stored as a resource, you must release the memory it
occupies with the ReleaseResource procedure and set the
windowPic field to NIL before closing the window. ▲
Any pending update events for the window are discarded. If the window being removed
is the frontmost window, the window behind it, if any, becomes the active window.
SEE ALSO
See Listing 4-17 on page 4-61 for an example that calls CloseWindow to remove a
window from the screen.
See Listing 4-3 on page 4-28 for an example that calls CloseWindow to clean up memory
when an attempt to create a new window fails.
DisposeWindow 4
Use the DisposeWindow procedure to remove a window if you let the Window
Manager allocate memory for the window record.
DESCRIPTION
The DisposeWindow procedure removes a window from the screen, deletes it from the
window list, and releases the memory occupied by all structures associated with the
window, including the window record. (DisposeWindow calls CloseWindow and then
releases the memory occupied by the window record.)
Window Manager
▲ WARNING
If your application allocated any other memory for use with a window,
you must release it before calling DisposeWindow. The Window
Manager releases only the data structures it created.
The DisposeWindow procedure assumes that any picture pointed to by
the window record field windowPic is data, not a resource, and it calls
the QuickDraw procedure KillPicture to delete it. If your application
uses a picture stored as a resource, you must release the memory it
occupies with the ReleaseResource procedure and set the
windowPic field to NIL before closing the window. ▲
Any pending update events for the window are discarded. If the window being removed
is the frontmost window, the window behind it, if any, becomes the active window.
BeginUpdate 4
Use the BeginUpdate procedure to start updating a window when you receive an
update event for that window.
theWindow A pointer to the window’s window record. Your application gets this
information from the message field in the update event record.
DESCRIPTION
The BeginUpdate procedure limits the visible region of the window’s graphics port to
the intersection of the visible region and the update region; it then sets the window’s
update region to an empty region. After calling BeginUpdate, your application redraws
either the entire content region or only the visible region. In either case, only the parts of
the window that require updating are actually redrawn on the screen.
Every call to BeginUpdate must be matched with a subsequent call to EndUpdate after
your application redraws the content region.
Note
In Pascal, BeginUpdate and EndUpdate can’t be nested. That is,
you must call EndUpdate before the next call to BeginUpdate.
You can nest BeginUpdate and EndUpdate calls in assembly
language if you save and restore the copy of the visRgn, a copy
of which is stored, in global coordinates, in the global variable
SaveVisRgn. ◆
Window Manager
SPECIAL CONSIDERATIONS
If you don’t clear the update region when you receive an update event, the Event
Manager continues to send update events until you do.
SEE ALSO
See Figure 4-21 on page 4-49 for an illustration of how BeginUpdate and EndUpdate
affect the visible region and update region. See Listing 4-10 on page 4-50 for an example
that updates a window.
EndUpdate 4
DESCRIPTION
The EndUpdate procedure restores the normal visible region of a window’s graphics
port. When you receive an update event for a window, you call BeginUpdate, redraw
the update region, and then call EndUpdate. Each call to BeginUpdate must be
balanced by a subsequent call to EndUpdate.
SEE ALSO
See Figure 4-21 on page 4-49 for an illustration of how BeginUpdate and EndUpdate
affect the visible region and update region. See Listing 4-10 on page 4-50 for an example
that updates a window.
InvalRect 4
Window Manager
DESCRIPTION
The InvalRect procedure adds a specified rectangle to the update region of the
window whose graphics port is the current port. Specify the rectangle in local
coordinates. The Window Manager clips it, if necessary, to fit in the window’s
content region.
Both your application and the Window Manager use the InvalRect procedure.
When the user enlarges a window, for example, the Window Manager uses InvalRect
to add the newly created content region to the update region. Your application uses
InvalRect to add the two rectangles formerly occupied by the scroll bars in the smaller
content area.
InvalRgn 4
DESCRIPTION
The InvalRgn procedure adds a specified region to the update region of the window
whose graphics port is the current port. Specify the region in local coordinates. The
Window Manager clips it, if necessary, to fit in the window’s content region.
SEE ALSO
See Listing 4-13 on page 4-58 for an example that uses InvalRgn to add part of the
window’s content region to the update region.
ValidRect 4
Use the ValidRect procedure to remove a rectangle from a window’s update region.
Window Manager
DESCRIPTION
The ValidRect procedure removes a specified rectangle from the update region of the
window whose graphics port is the current port. Specify the region in local coordinates.
The Window Manager clips it, if necessary, to fit in the window’s content region.
Your application uses ValidRect to tell the Window Manager that it has already drawn
a rectangle and to cancel any updates accumulated for that area. You can thereby
improve response time by reducing redundant redrawing.
Suppose, for example, that you’ve resized a window that contains a size box and
scroll bars. Depending on the dimensions of the newly sized window, the new size
box and scroll bar areas may or may not have been accumulated into the window’s
update region. After calling SizeWindow, you can redraw the size box or scroll bars
immediately and then call ValidRect for the areas they occupy. If they were in fact
accumulated into the update region, ValidRect removes them so that you do not have
to redraw them with the next update event.
SEE ALSO
See Listing 4-13 on page 4-58 for an example that uses ValidRect to remove part of the
window’s content region from the update region.
ValidRgn 4
DESCRIPTION
The ValidRgn procedure removes a specified region from the update region of the
window whose graphics port is the current port. Specify the region in local coordinates.
The Window Manager clips it, if necessary, to fit in the window’s content region.
Window Manager
SetWindowPic 4
Use the SetWindowPic procedure to establish a picture that the Window Manager can
draw in a window’s content region.
DESCRIPTION
The SetWindowPic procedure stores in a window’s window record a handle to a picture
to be drawn in the window. When the window’s content region must be updated, the
Window Manager then draws the picture or part of the picture, as necessary, instead of
generating an update event.
Note
The CloseWindow and DisposeWindow procedures assume that any
picture pointed to by the window record field windowPic is stored as
data, not as a resource. If your application uses a picture stored as a
resource, you must release the memory it occupies by calling the
Resource Manager’s ReleaseResource procedure and set the
WindowPic field to NIL before you close the window. ◆
GetWindowPic 4
DESCRIPTION
The GetWindowPic function returns a handle to the picture to be drawn in a specified
window’s content region. The handle must have been stored previously with the
SetWindowPic procedure.
Window Manager
SetWRefCon 4
Use the SetWRefCon procedure to set the refCon field of a window record.
DESCRIPTION
The SetWRefCon procedure places the specified data in the refCon field of the specified
window record. The refCon field is available to your application for any
window-related data it needs to store.
SEE ALSO
See Listing 4-3 on page 4-28 for an example that sets the refCon field. See Listing 4-16 on
page 4-60 for an example that uses the contents of the refCon field.
GetWRefCon 4
Use the GetWRefCon function to retrieve the reference constant from a window’s
window record.
DESCRIPTION
The GetWRefCon function returns the long integer data stored in the refCon field of the
specified window record.
SEE ALSO
See the section “Managing Multiple Windows” beginning on page 4-23 for suggested
ways to use the refCon field. See Listing 4-1 on page 4-25 for an example of an
application-defined routine that gets the refCon field.
Window Manager
GetWVariant 4
DESCRIPTION
The GetWVariant function returns the variation code of the specified window.
Depending on the window’s window definition function, the result of GetWVariant can
represent one of the standard window types listed in the section “Creating a Window”
beginning on page 4-25 or a variation code defined by your own window definition
function.
SEE ALSO
See “Types of Windows” beginning on page 4-8 for a definition of variation codes. See
“The Window Definition Function” beginning on page 4-120 for a detailed description of
variation codes.
SetDeskCPat 4
Use the SetDeskCPat procedure to set the desktop pattern on a computer that supports
Color QuickDraw.
DESCRIPTION
The SetDeskCPat procedure sets the desktop pattern to a specified pixel pattern, which
can be drawn in more than two colors. After a call to SetDeskCPat, the desktop is
automatically redrawn in the new pattern. If the specified pattern is a binary pattern
(with a pattern type of 0), it is drawn is the current foreground and background colors. If
the value of the deskPixPat parameter is NIL, SetDeskCPat uses the standard binary
desk pattern (that is, the 'ppat' resource with resource ID 16).
Window Manager
Note
For compatibility with other Macintosh applications and the
system software, applications should ordinarily not change the
desktop pattern. ◆
The Window Manager’s desktop-painting routines can paint the desktop either in the
binary pattern stored in the global variable DeskPattern or in a new pixel pattern. The
desktop pattern used at startup is determined by the value of the parameter-RAM bit flag
called pCDeskPat. If the value of pCDeskPat is 0, the Window Manager uses the new
pixel pattern; if not, it uses the binary pattern stored in DeskPattern. The user can
change the color pattern through the General Controls panel, which changes the value
of pCDeskPat.
GetGrayRgn 4
Use the GetGrayRgn function to retrieve a handle to the current desktop region.
DESCRIPTION
The GetGrayRgn function returns a handle to the current desktop region from the global
variable GrayRgn.
The desktop region represents all available screen space, that is, the desktop area
displayed by all monitors attached to the computer. Ordinarily, your application
doesn’t need to access the desktop region directly.
When your application calls DragWindow to let the user drag a window, it can use
GetGrayRgn to set the limiting rectangle to the entire desktop area.
SEE ALSO
See Listing 4-9 on page 4-44 for an example that uses GetGrayRgn to specify the limiting
rectangle when calling DragWindow to let the user move a window.
GetCWMgrPort 4
Use the GetCWMgrPort procedure to retrieve a pointer to the Window Manager port on
a system that supports Color QuickDraw.
Window Manager
DESCRIPTION
The GetCWMgrPort procedure places a pointer to the color Window Manager port in the
parameter wMgrCPort. The GetCWMgrPort procedure is available only on computers
with Color QuickDraw.
The Window Manager port is a graphics port that occupies all of the main screen.
Ordinarily, your application doesn’t need to access the Window Manager port.
Note
Do not change any regions of the Window Manager port. If you do, the
Window Manager might not handle overlapping windows properly. ◆
GetWMgrPort 4
Use the GetWMgrPort procedure to retrieve a pointer to the Window Manager port on a
system with only the original monochrome QuickDraw.
DESCRIPTION
The GetWMgrPort procedure places a pointer to the Window Manager port in the
parameter wPort.
The Window Manager port is a graphics port that occupies all of the main screen.
Ordinarily, your application doesn’t need to access the Window Manager port.
Note
Do not change any regions of the Window Manager port. If you do, the
Window Manager might not handle overlapping windows properly. ◆
SetWinColor 4
Window Manager
DESCRIPTION
The SetWinColor procedure sets a window’s color table. If the window has no auxiliary
window record, it creates a new one with the specified window color table and adds it to
the auxiliary window list. If the window already has an auxiliary record, its window
color table is replaced. The Window Manager then redraws the window frame and
highlighted text in the new colors and sets the window’s background color to the new
content color.
If the new color table has the same entries as the default color table, SetWinColor
changes the auxiliary window record so that it points to the default color table.
Window color table resources (resources of type 'wctb') should not be purgeable.
If you specify a value of NIL for the parameter theWindow, SetWinColor changes the
default color table in memory. Your application shouldn’t, however, change the default
color table.
SEE ALSO
For a description of a window color table, see “The Window Color Table Record” on
page 4-71. For a description of the auxiliary window record, see “The Auxiliary Window
Record” on page 4-73. For a description of the 'wctb' resource, see “The Window Color
Table Resource” on page 4-127.
GetAuxWin 4
DESCRIPTION
The GetAuxWin function returns a Boolean value that reports whether or not the
window has an auxiliary window record, and it sets the variable parameter awHndl
to the window’s auxiliary window record.
If the window has no auxiliary window record, GetAuxWin places the default window
color table in awHndl and returns a value of FALSE.
Window Manager
SEE ALSO
For a description of the auxiliary window record, see “The Auxiliary Window Record” on
page 4-73.
Low-Level Routines 4
This section describes the low-level routines that are called by higher-level Window
Manager routines. Ordinarily, you won’t need to use these routines.
CheckUpdate 4
The Event Manager uses the CheckUpdate function to scan the window list for
windows that need updating.
DESCRIPTION
The CheckUpdate function scans the window list from front to back, checking for a
visible window that needs updating (that is, a visible window whose update region is not
empty). If it finds one whose window record contains a picture handle, it redraws the
window itself and continues through the list. If it finds a window record whose update
region is not empty and whose window record does not contain a picture handle, it stores
an update event in the parameter theEvent and returns TRUE. If it finds no such
window, it returns FALSE.
The Event Manager is the only software that ordinarily calls CheckUpdate.
ClipAbove 4
The Window Manager uses the ClipAbove procedure to determine the clip region of the
Window Manager port for displaying a window.
DESCRIPTION
The ClipAbove procedure sets the clip region of the Window Manager port to
be the area of the desktop that intersects the current clip region, minus the
structure regions of all the windows in front of the specified window.
Window Manager
The ClipAbove procedure retrieves the desktop region from the global
variable GrayRgn.
SaveOld 4
The Window Manager uses the SaveOld procedure to save a window’s current structure
and content regions preparatory to updating the window.
DESCRIPTION
The SaveOld procedure saves the specified window’s current structure region and
content region for the DrawNew procedure. Each call to SaveOld must be balanced
by a subsequent call to DrawNew.
DrawNew 4
The Window Manager uses the DrawNew procedure to erase and update changed
window regions.
DESCRIPTION
The DrawNew procedure erases the parts of a window’s structure and content regions
that are part of the window’s former state and part of its new state but not both. That is,
(OldStructure XOR NewStructure) UNION (OldContent XOR NewContent)
If the update parameter is set to TRUE, DrawNew also updates the erased regions.
▲ WARNING
In Pascal, SaveOld and DrawNew are not nestable. ▲
ASSEMBLY-LANGUAGE INFORMATION
In assembly language, you can nest SaveOld and DrawNew if you save and restore the
values of the global variables OldStructure and OldContent.
Window Manager
PaintOne 4
The Window Manager uses the PaintOne procedure to redraw the invalid, exposed
portions of one window on the desktop.
DESCRIPTION
The PaintOne procedure “paints” the invalid portion of the specified window and
all windows above it. It draws as much of the window frame as is in clobberedRgn
and, if some content region is exposed, erases the exposed area (paints it with the
background pattern) and adds it to the window’s update region. If the value of the
window parameter is NIL, the window is the desktop, and PaintOne paints it with
the desktop pattern.
ASSEMBLY-LANGUAGE INFORMATION
The global variables SaveUpdate and PaintWhite are flags used by PaintOne.
Normally both flags are set. Clearing SaveUpdate prevents clobberedRgn from being
added to the window’s update region. Clearing PaintWhite prevents clobberedRgn
from being erased before being added to the update region (this is useful, for example, if
the background pattern of the window isn’t the background pattern of the desktop). The
Window Manager sets both flags periodically, so you should clear the appropriate flags
each time you need them to be clear.
PaintBehind 4
The Window Manager uses the PaintBehind procedure to redraw a series of windows
in the window list.
startWindow
A pointer to the window’s complete window record.
clobberedRgn
A handle to the region that has become invalid.
Window Manager
DESCRIPTION
The PaintBehind procedure calls PaintOne for startWindow and all the windows
behind startWindow, clipped to clobberedRgn.
ASSEMBLY-LANGUAGE INFORMATION
Because PaintBehind clears the global variable PaintWhite before calling PaintOne,
clobberedRgn isn’t erased. The PaintWhite global variable is reset
after the call to PaintOne.
CalcVis 4
The Window Manager uses the CalcVis procedure to calculate the visible region
of a window.
DESCRIPTION
The CalcVis procedure calculates the visible region of the specified window by starting
with its content region and subtracting the structure region of each window in front of it.
CalcVisBehind 4
The Window Manager uses the CalcVisBehind procedure to calculate the visible
regions of a series of windows.
startWindow
A pointer to a window’s window record.
clobberedRgn
A handle to the desktop region that has become invalid.
DESCRIPTION
The CalcVisBehind procedure calculates the visible regions of the window specified by
the startWindow parameter and all windows behind startWindow that intersect
clobberedRgn. It is called after PaintBehind.
Window Manager
Application-Defined Routine 4
This section describes the window definition function. The Window Manager supplies
window definition functions that handle the standard window types described in “Types
of Windows” beginning on page 4-8.
MyWindow 4
The window definition function is responsible for drawing the window frame, reporting
the region where mouse-down events occur, calculating the window’s structure region
and content region, drawing the size box, resizing the window frame when the user
drags the size box, and performing any customized initialization or disposal tasks.
You can give your window definition function any name you wish. It takes four
parameters and returns a result code:
Window Manager
message A code for the task to be performed. The message parameter has one of
these values:
CONST
wDraw = 0; {draw window frame}
wHit = 1; {report where mouse-down event }
{ occurred}
wCalcRgns = 2; {calculate strucRgn and contRgn}
wNew = 3; {perform additional }
{ initialization}
wDispose = 4; {perform additional disposal }
{ tasks}
wGrow = 5; {draw grow image during resizing}
wDrawGIcon = 6; {draw size box and scroll bar }
{ outline}
Window Manager
■ If the value of the param parameter is wInZoom, add highlighting to, or remove it
from, the window’s zoom box. Figure 4-20 on page 4-47 illustrates the zoom box
with and without highlighting as drawn by the Window Manager’s window definition
function.
Note
When the Window Manager calls a window definition function
with a message of wDraw, it stores a value of type Integer in the param
parameter without clearing the high-order word. When processing the
wDraw message, use only the low-order word of the param parameter.
◆
The window frame typically but not necessarily includes the window’s title, which
should be displayed in the system font and system font size. The Window Manager
port is already set to use the system font and system font size.
When designing a title bar that includes the window title, allow at least 16 pixels
vertically to support localization for script systems in which the system font can be no
smaller than 12 points.
Note
Nothing drawn outside the window’s structure region is visible. ◆
Window Manager
Calculating Regions 4
When you receive the wCalcRgns message, you calculate the window’s structure and
content regions based on the current graphics port’s port rectangle. These regions, whose
handles are in the strucRgn and contRgn fields of the window record, are in global
coordinates. The Window Manager requests this operation only if the window is visible.
▲ WARNING
When you calculate regions for your own type of window, do not alter
the clip region or the visible region of the window’s graphics port. The
Window Manager and QuickDraw take care of this for you. Altering the
clip region or visible region may damage other windows. ▲
Disposing of a Window 4
When you receive the wDispose message, you can perform any additional tasks
necessary for disposing of a window. You might, for example, release memory that was
allocated by the initialization routine. The dispose routine for a standard document
window disposes of the wStateData record.
Resizing a Window 4
When you receive the wGrow message, draw a grow image of the window. With the
wGrow message you receive a pointer to a rectangle, in global coordinates, whose
upper-left corner is aligned with the port rectangle of the window’s graphics port. Your
grow image should fit inside the rectangle. As the user drags the mouse, the Window
Manager sends repeated wGrow messages, so that you can change your grow image to
match the changing mouse location.
Draw the grow image in the current graphics port, which is the Window Manager port,
in the current pen pattern and pen mode. These are set up (as gray and notPatXor) to
conform to the Macintosh user interface guidelines.
The grow routine for a standard document window draws a dotted (gray) outline of the
window and also the lines delimiting the title bar, size box, and scroll bar areas.
Window Manager
Note
If the size box is located in the window frame instead of the content
region, do nothing in response to the wDrawGIcon message, instead
drawing the size box in response to the wDraw message. ◆
The routine that draws a size box for an active document window draws the size box in
the lower-right corner of the port rectangle of the window’s graphics port. It also draws
lines delimiting the size box and scroll bar areas. For an inactive document window, it
erases the size box and draws the delimiting lines.
Resources 4
This section describes the resources used by the Window Manager:
■ the 'WIND' resource, used for describing the characteristics of windows
■ the 'WDEF' resource, which holds a window definition function
■ the 'wctb' resource, which defines the colors to be used for a window’s frame
and highlighting
You typically define a window resource for each type of window that your application
creates. Figure 4-24 illustrates a compiled 'WIND' resource.
Initial rectangle 8
Window definition ID 2
Visibility status 2
Reference constant 4
Window title n
Positioning specfication 2
Window Manager
Diameters of
Window definition ID curvature
rDocProc 16, 16
rDocProc + 2 4, 4
rDocProc + 4 6, 6
rDocProc + 6 10, 10
Window Manager
■ A specification that determines whether or not the window has a close box. The
Window Manager draws the close box when it draws the window frame. The window
type specified in the second field determines whether a window can support a close
box; this field determines whether the close box is present.
■ A reference constant, which your application can use for whatever data it needs to
store. When it builds a new window record, the Window Manager stores, in the
refCon field, whatever value you specify in the fifth element of the window resource.
You can also put a placeholder here and then set the refCon field yourself with the
SetWRefCon procedure.
■ A string that specifies the window title. The first byte of the string specifies the length
of the string (that is, the number of characters in the title plus 1 byte for the length),
in bytes.
■ An optional positioning specification that overrides the window position established
by the rectangle in the first field. The positioning value can be one of the integers
defined by the constants listed here. In these constant names, the terms have the
following meanings:
center Centered both horizontally and vertically, relative either to a
screen or to another window (if a window to be centered
relative to another window is wider than the window that
preceded it, it is pinned to the left edge; a narrower window
is centered)
stagger Located 10 pixels to the right and 10 pixels below the
upper-left corner of the last window (in the case of staggering
relative to a screen, the first window is placed just below
the menu bar at the left edge of the screen, and subsequent
windows are placed on that screen relative to the
first window)
alert position Centered horizontally and placed in the “alert position”
vertically, that is, with about one-fifth of the window or
screen above the new window and the rest below
parent window The window in which the user was last working
The seventh element of the resource can contain one of the values specified by
these constants:
Window Manager
The positioning constants are convenient when the user is creating new documents or
when you are handling your own dialog boxes and alert boxes. When you are creating
a new window to display a previously saved document, however, you should display
the new window in the same rectangle as the previous window (that is, the window
the document occupied when it was last saved). For more information, see
“Positioning a Document Window on the Desktop” beginning on page 4-30.
Use the GetNewCWindow or GetNewWindow function to read a 'WIND' resource. Both
functions create a new window record and fill it in according to the values specified in a
'WIND' resource.
Window Manager
Unused 6
Part identifier 2
Red value 2
Green value 2
Blue value 2
Part identifier 2
Red value 2
Green value 2
Blue value 2
Window Manager
The color values are simply the intensity of the red, green, and blue in each window
part (see Inside Macintosh: Imaging for a description of RGB color).
Window Manager 4
Pascal Summary 4
Constants 4
CONST
{window types}
documentProc = 0;{movable, sizable window, no zoom box}
dBoxProc = 1;{alert box or modal dialog box}
plainDBox = 2;{plain box}
altDBoxProc = 3;{plain box with shadow}
noGrowDocProc = 4;{movable window, no size box or }
{ zoom box}
movableDBoxProc = 5; {movable modal dialog box}
zoomDocProc = 8; {standard document window}
zoomNoGrow = 12; {zoomable, nonresizable window}
rDocProc = 16; {rounded-corner window}
{window kinds}
dialogKind = 2; {dialog or alert box window}
userKind = 8; {window created by the application}
Window Manager
Window Manager
Data Types 4
CWindowRecord =
RECORD
port: CGrafPort; {window's graphics port}
windowKind: Integer; {class of window}
visible: Boolean; {visibility}
hilited: Boolean; {highlighting}
goAwayFlag: Boolean; {presence of close box}
spareFlag: Boolean; {presence of zoom box}
strucRgn: RgnHandle; {handle to structure region}
contRgn: RgnHandle; {handle to content region}
updateRgn: RgnHandle; {handle to update region}
windowDefProc: Handle; {handle to window definition function}
dataHandle: Handle; {handle to window state data record}
titleHandle: StringHandle; {handle to window title}
titleWidth: Integer; {title width in pixels}
controlList: ControlHandle; {handle to control list}
nextWindow: CWindowPeek; {pointer to next window record in }
{ window list}
windowPic: PicHandle; {handle to optional picture}
refCon: LongInt; {storage available to your application}
END;
WindowPtr = GrafPtr;
WindowPeek = ^WindowRecord;
WindowRecord =
RECORD {all fields have same use as }
{ in color window record}
port: GrafPort; {window's graphics port}
windowKind: Integer; {class of window}
visible: Boolean; {visibility}
hilited: Boolean; {highlighting}
goAwayFlag: Boolean; {presence of close box}
spareFlag: Boolean; {presence of zoom box}
strucRgn: RgnHandle; {handle to structure region}
contRgn: RgnHandle; {handle to content region}
updateRgn: RgnHandle; {handle to update region}
windowDefProc: Handle; {handle to window definition function}
dataHandle: Handle; {handle to window state data record}
Window Manager
WStateDataPtr = ^WStateData;
WStateDataHandle = ^WStateDataPtr;
WCTabPtr = ^WinCTab;
WCTabHandle = ^WCTabPtr;
ColorSpec =
RECORD
value: Integer; {part identifier}
rgb: RGBColor; {RGB value}
END;
AuxWinHandle= ^AuxWinPtr;
AuxWinPtr = ^AuxWinRec;
Window Manager
Creating Windows
FUNCTION GetNewCWindow (windowID: Integer; wStorage: Ptr;
behind: WindowPtr): WindowPtr;
FUNCTION GetNewWindow (windowID: Integer; wStorage: Ptr;
behind: WindowPtr): WindowPtr;
FUNCTION NewCWindow (wStorage: Ptr; boundsRect: Rect;
title: Str255; visible: Boolean;
procID: Integer; behind: WindowPtr;
goAwayFlag: Boolean;
refCon: LongInt): WindowPtr;
FUNCTION NewWindow (wStorage: Ptr; boundsRect: Rect;
title: Str255; visible: Boolean;
theProc: Integer; behind: WindowPtr;
goAwayFlag: Boolean;
refCon: LongInt): WindowPtr;
Naming Windows
PROCEDURE SetWTitle (theWindow: WindowPtr; title: Str255);
PROCEDURE GetWTitle (theWindow: WindowPtr; VAR title: Str255);
Displaying Windows
PROCEDURE DrawGrowIcon (theWindow: WindowPtr);
PROCEDURE SelectWindow (theWindow: WindowPtr);
PROCEDURE ShowWindow (theWindow: WindowPtr);
PROCEDURE HideWindow (theWindow: WindowPtr);
PROCEDURE ShowHide (theWindow: WindowPtr; showFlag: Boolean);
PROCEDURE HiliteWindow (theWindow: WindowPtr; fHilite: Boolean);
PROCEDURE BringToFront (theWindow: WindowPtr);
PROCEDURE SendBehind (theWindow, behindWindow: WindowPtr);
Window Manager
Moving Windows
PROCEDURE DragWindow (theWindow: WindowPtr;
startPt: Point; boundsRect: Rect);
PROCEDURE MoveWindow (theWindow: WindowPtr;
hGlobal, vGlobal: Integer; front: Boolean);
FUNCTION DragGrayRgn (theRgn: RgnHandle; startPt: Point;
limitRect, slopRect: Rect; axis: Integer;
actionProc: ProcPtr): LongInt;
FUNCTION PinRect (theRect: Rect; thePt: Point): LongInt;
Resizing Windows
FUNCTION GrowWindow (theWindow: WindowPtr;
startPt: Point; sizeRect: Rect): LongInt;
PROCEDURE SizeWindow (theWindow: WindowPtr; w, h: Integer;
fUpdate: Boolean);
Zooming Windows
FUNCTION TrackBox (theWindow: WindowPtr; thePt: Point;
partCode: Integer): Boolean;
PROCEDURE ZoomWindow (theWindow: WindowPtr;
partCode: Integer; front: Boolean);
Window Manager
Low-Level Routines
FUNCTION CheckUpdate (VAR theEvent: EventRecord): Boolean;
PROCEDURE ClipAbove (window: WindowPeek);
PROCEDURE SaveOld (window: WindowPeek);
PROCEDURE DrawNew (window: WindowPeek; update: Boolean);
PROCEDURE PaintOne (window: WindowPeek; clobberedRgn: RgnHandle);
PROCEDURE PaintBehind (startWindow: WindowPeek;
clobberedRgn: RgnHandle);
PROCEDURE CalcVis (window: WindowPeek);
PROCEDURE CalcVisBehind (startWindow: WindowPeek;
clobberedRgn: RgnHandle);
Application-Defined Routine 4
Window Manager
C Summary 4
Constants 4
enum {
/*window types*/
documentProc = 0, /*movable, sizable window, no zoom box*/
dBoxProc = 1, /*alert box or modal dialog box*/
plainDBox = 2, /*plain box*/
altDBoxProc = 3, /*plain box with shadow*/
noGrowDocProc = 4, /*movable window, no size box or zoom box*/
movableDBoxProc = 5, /*movable modal dialog box*/
zoomDocProc = 8, /*standard document window*/
zoomNoGrow = 9, /*zoomable, nonresizable window*/
rDocProc = 16, /*rounded-corner window*/
/*window kinds*/
dialogKind = 2, /*dialog or alert box window*/
userKind = 8, /*window created by the application*/
enum {
/*axis constraints on DragGrayRgn*/
noConstraint = 0, /*no constraints*/
hAxisOnly = 1, /*move on horizontal axis only*/
vAxisOnly = 2 /*move on vertical axis only*/
};
Window Manager
enum {
/*window definition function task codes*/
wDraw = 0, /*draw window frame*/
wHit = 1, /*report where mouse-down occurred*/
wCalcRgns = 2, /*calculate strucRgn and contRgn*/
wNew = 3, /*perform additional initialization*/
wDispose = 4, /*perform additional disposal tasks*/
wGrow = 5, /*draw grow image during resizing*/
wDrawGIcon = 6, /*draw size box and scroll bar outline*/
Window Manager
Data Types 4
struct CWindowRecord {
CGrafPort port; /*window's graphics port*/
short windowKind; /*class of the window*/
Boolean visible; /*visibility*/
Boolean hilited; /*highlighting*/
Boolean goAwayFlag; /*presence of close box*/
Boolean spareFlag; /*presence of zoom box*/
RgnHandle strucRgn; /*handle to structure region*/
RgnHandle contRgn; /*handle to content region*/
RgnHandle updateRgn; /*handle to update region*/
Handle windowDefProc; /*handle to window definition */
/* function*/
Handle dataHandle; /*handle to window state data record*/
StringHandle titleHandle; /*handle to window title*/
short titleWidth; /*title width in pixels*/
ControlHandle controlList; /*handle to control list*/
struct CWindowRecord *nextWindow; /*next window in window list*/
PicHandle windowPic; /*handle to optional picture*/
long refCon; /*storage available to your */
/* application*/
};
struct WindowRecord {
GrafPort port; /*window's graphics port*/
short windowKind; /*class of the window*/
Boolean visible; /*visibility*/
Boolean hilited; /*highlighting*/
Boolean goAwayFlag; /*presence of close box*/
Boolean spareFlag; /*presence of zoom box*/
RgnHandle strucRgn; /*handle to structure region*/
RgnHandle contRgn; /*handle to content region*/
RgnHandle updateRgn; /*handle to update region*/
Handle windowDefProc; /*handle to window definition */
/* function*/
Handle dataHandle; /*handle to window state data record*/
StringHandle titleHandle; /*handle to window title*/
short titleWidth; /*title width in pixels*/
ControlHandle controlList; /*handle to window's control list*/
struct WindowRecord *nextWindow; /*next window in window list*/
Window Manager
struct WStateData {
Rect userState; /*user state*/
Rect stdState; /*standard state*/
};
struct AuxWinRec {
struct AuxWinRec **awNext; /*handle to next record*/
WindowPtr awOwner; /*pointer to window */
CTabHandle awCTable; /*handle to color table*/
Handle dialogCItem; /*storage used by Dialog Manager*/
long awFlags; /*reserved*/
CTabHandle awReserved; /*reserved*/
long awRefCon; /*reference constant, for use by */
/* application*/
};
struct WinCTab {
long wCSeed; /*reserved*/
short wCReserved; /*reserved*/
short ctSize; /*number of entries in table —1*/
ColorSpec ctTable[5]; /*array of color specification records*/
};
Window Manager
Creating Windows
pascal WindowPtr GetNewCWindow
(short windowID, void *wStorage,
WindowPtr behind);
pascal WindowPtr GetNewWindow
(short windowID, void *wStorage,
WindowPtr behind);
pascal WindowPtr NewCWindow (void *wStorage, const Rect *boundsRect,
ConstStr255Param title, Boolean visible,
short procID, WindowPtr behind,
Boolean goAwayFlag, long refCon);
pascal WindowPtr NewWindow (void *wStorage, const Rect *boundsRect,
ConstStr255Param title, Boolean visible,
short theProc, WindowPtr behind,
Boolean goAwayFlag, long refCon);
Naming Windows
pascal void SetWTitle (WindowPtr theWindow, ConstStr255Param title);
pascal void GetWTitle (WindowPtr theWindow, Str255 title);
Displaying Windows
pascal void DrawGrowIcon (WindowPtr theWindow);
pascal void SelectWindow (WindowPtr theWindow);
pascal void ShowWindow (WindowPtr theWindow);
pascal void HideWindow (WindowPtr theWindow);
pascal void ShowHide (WindowPtr theWindow, Boolean showFlag);
pascal void HiliteWindow (WindowPtr theWindow, Boolean fHilite);
pascal void BringToFront (WindowPtr theWindow);
pascal void SendBehind (WindowPtr theWindow, WindowPtr behindWindow);
Moving Windows
pascal void DragWindow (WindowPtr theWindow, Point startPt,
const Rect *boundsRect);
pascal void MoveWindow (WindowPtr theWindow, short hGlobal,
short vGlobal, Boolean front);
Window Manager
Resizing Windows
pascal long GrowWindow (WindowPtr theWindow, Point startPt,
const Rect *bBox);
pascal void SizeWindow (WindowPtr theWindow, short w, short h,
Boolean fUpdate);
Zooming Windows
pascal Boolean TrackBox (WindowPtr theWindow, Point thePt,
short partCode);
pascal void ZoomWindow (WindowPtr theWindow, short partCode,
Boolean front);
Window Manager
Low-Level Routines
pascal Boolean CheckUpdate (EventRecord *theEvent);
pascal void ClipAbove (WindowPeek window;)
pascal void SaveOld (WindowPeek window);
pascal void DrawNew (WindowPeek window, Boolean update);
pascal void PaintOne (WindowPeek window, RgnHandle clobberedRgn);
pascal void PaintBehind (WindowPeek startWindow,
RgnHandle clobberedRgn);
pascal void CalcVis (WindowPeek window);
pascal void CalcVisBehind (WindowPeek startWindow,
RgnHandle clobberedRgn);
Application-Defined Routine 4
Window Manager
Assembly-Language Summary 4
Data Types 4
Window Manager
Global Variables 4
AuxWinHead Handle to beginning of auxiliary window list.
CurActivate Pointer to window to receive activate event.
CurDeactive Pointer to window to receive deactivate event.
DeskHook Address of procedure for painting desktop.
DeskPattern Pattern in which desktop is painted (8 bytes).
DragHook Address of optional procedure to execute during TrackGoAway, TrackBox,
DragWindow, GrowWindow, and DragGrayRgn.
DragPattern Pattern of dragged region’s outline (8 bytes).
GrayRgn Handle to desktop region.
OldContent Handle to saved content region.
OldStructure Handle to saved structure region.
PaintWhite Flag indicating whether to paint window white before update event (2 bytes).
SaveUpdate Flag indicating whether to generate update events (2 bytes).
SaveVisRgn Handle to saved visible region.
WindowList Pointer to first window in window list.
WMgrPort Pointer to Window Manager port.
Figure 5-0
Listing 5-0
Table 5-0
5 Control Manager
Contents
Introduction to Controls 5-4
Buttons 5-5
Checkboxes 5-5
Radio Buttons 5-6
Pop-Up Menus 5-6
Scroll Bars 5-7
Other Controls 5-11
Active and Inactive Controls 5-11
The Control Definition Function 5-14
About the Control Manager 5-14
Using the Control Manager 5-15
Creating and Displaying a Control 5-15
Creating a Button, Checkbox, or Radio Button 5-17
Creating Scroll Bars 5-21
Creating a Pop-Up Menu 5-25
Updating a Control 5-29
Responding to Mouse Events in a Control 5-30
Determining a Mouse-Down Event in a Control 5-31
Tracking the Cursor in a Control 5-35
Determining and Changing Control Settings 5-37
Scrolling Through a Document 5-43
Scrolling in Response to Events in the Scroll Box 5-53
Scrolling in Response to Events in Scroll Arrows and Gray Areas 5-57
Drawing a Scrolled Document Inside a Window 5-62
Moving and Resizing Scroll Bars 5-65
Defining Your Own Control Definition Function 5-71
Control Manager Reference 5-72
Data Structures 5-72
The Control Record 5-73
The Auxiliary Control Record 5-76
Contents 5-1
C H A P T E R 5
5-2 Contents
C H A P T E R 5
Control Manager 5
This chapter describes how your application can use the Control Manager to create
and manage controls. Controls are onscreen objects that the user can manipulate with the
mouse. By manipulating controls, the user can take an immediate action or change
settings to modify a future action. For example, a scroll bar control allows a user to
immediately change the portion of the document that your application displays, whereas
a pop-up menu control for baud rate might allow the user to change the rate by which
your application handles subsequent data transmissions.
Read this chapter to learn how and when to implement controls. Virtually all applica-
tions need to implement controls, at least in the form of scroll bars for document
windows. You use Control Manager routines, resources, and data structures to imple-
ment scroll bars in your application’s document windows.
The other standard Macintosh controls are buttons, checkboxes, radio buttons, and
pop-up menus. You can use the Control Manager to create and manage these controls,
too. Alternatively, you can use the Dialog Manager to implement these controls in alert
boxes and dialog boxes more easily. (You typically use an alert box to warn a user of
an unusual situation, and you typically use a dialog box to ask the user for information
necessary to carry out a command.) The chapter “Dialog Manager” in this book describes
in detail how to implement controls in alert and dialog boxes. However, in certain
situations—for instance, when you need to implement highly complex dialog boxes—
you may want to use Control Manager routines to manage these types of controls
directly; read this chapter for information on how to do so.
For scrolling lists of graphic or textual information (similar to the list of files that system
software presents after the user chooses the Open command from the File menu), your
application can use the List Manager to implement the scroll bars. See the chapter “List
Manager” in Inside Macintosh: More Macintosh Toolbox for more information.
The Control Manager offers routines for automatically handling user-generated
mouse events in controls and redrawing controls in response to update events. For
further information about events and event handling, see the chapter “Event Manager”
in this book.
You typically use a control resource—a resource of type 'CNTL'—to specify the type,
size, location, and other attributes of a control. See the chapter “Introduction to the
Macintosh Toolbox” in this book for general information about resources; detailed
information about the Resource Manager and its routines is provided in the chapter
“Resource Manager” in Inside Macintosh: More Macintosh Toolbox.
Every control you create must be associated with a particular window. All of the controls
for a window are stored in a control list referenced by the window’s window record. See
the chapter “Window Manager” in this book for general information about windows.
(When you use the Dialog Manager to implement a control, the Dialog Manager
associates it with its respective dialog box or alert box, as described in the chapter
“Dialog Manager.”)
5-3
C H A P T E R 5
Control Manager
This chapter provides an introduction to the use of controls, and then discusses how
you can
■ create and display controls
■ determine whether mouse-down events have occurred in controls
■ respond to mouse-down events in controls
■ change the settings in controls
■ use scroll bars to move a document in a window
■ move and resize controls for a window
■ define your own control definition function to create nonstandard controls
Introduction to Controls 5
The Control Manager provides several standard controls. Figure 5-1 illustrates these
standard controls: buttons, checkboxes, radio buttons, pop-up menus, and scroll bars.
You can also design and implement your own custom controls.
Button
Checkbox
Radio buttons
Pop-up menu
Scroll bar
Buttons, checkboxes, and radio buttons are the simplest controls. They consist of only a
title and an outline shape, and they respond to only mouse clicks. A pop-up menu is
slightly more complex. This control has a menu attached to its title, and it must respond
when the user drags the cursor across the menu. A scroll bar, because it consists of
different parts that behave differently, is the most complex of the standard controls. Even
though a scroll bar has several parts, it is still only one control.
The Control Manager displays these standard controls in colors that provide aesthetic
consistency across all monitors, from black-and-white displays to 8-bit color displays.
To ensure consistency across applications, you generally shouldn’t change the default
Control Manager
colors of controls, although the Control Manager does allow you to do so with the
SetControlColor procedure (described on page 5-101) or the control color table
resource (described on page 5-121).
Standard controls and common custom controls are described in the next
several sections.
Buttons 5
Buttons appear on the screen as rounded rectangles with a title centered inside. When the
user clicks a button, your application should perform the action described by the button
title. Typically, buttons allow the user to perform actions instantaneously—for example,
completing the operations defined by a dialog box or acknowledging an error message in
an alert box.
Make your buttons large enough to surround their titles. In every window or dialog box
in which you display buttons, you should designate one button as the default button by
drawing a thick black outline around it (as shown in Figure 5-2). Your application should
respond to key-down events involving the Enter and Return keys as if the user had
clicked the default button. (In your alert boxes, the Dialog Manager automatically
outlines the default button; you must outline the default button in your dialog boxes.)
You normally use buttons in alert boxes and dialog boxes. See the chapter “Dialog
Manager” for additional details about where to display buttons, what to title them, how
to respond to events involving them, and how to draw an outline around them.
Checkboxes 5
Checkboxes provide alternative choices. Typically you use checkboxes in dialog boxes so
that users can specify information necessary for completing a command. Checkboxes act
like toggle switches, turning a setting either off or on. Use checkboxes to indicate one or
more options that must be either off or on. A checkbox appears as a small square with a
title alongside it; use the Control Manager procedure SetControlValue to place an X
in the box when the user selects it by clicking it on and to remove the X when the user
deselects it by clicking it off. Figure 5-3 shows a selected checkbox.
Control Manager
When you design a dialog box, you can include any number of checkboxes—including
only one. Checkboxes are independent of each other, even when they offer related
options. Within a dialog box, it’s a good idea to group sets of related checkboxes and to
provide some visual demarcation between different groups.
Each checkbox has a title. It can be very difficult to title the option in an unambiguous
way. The title should reflect two clearly opposite states. For example, in a Finder’s Info
window, a checkbox provides the option to lock a file. The checkbox is titled simply
Locked. The clearly opposite state, when the option is off, is unlocked.
If you can’t devise a checkbox title that clearly implies an opposite state, you might be
better off using two radio buttons. With two radio buttons, you can use two titles, thereby
clarifying the states.
Checkboxes are frequently used in dialog boxes to set or modify future actions instead of
specifying actions to be taken immediately. See the chapter “Dialog Manager” in this
book for a detailed discussion of how and where to display checkboxes in dialog boxes.
Radio Buttons 5
Like checkboxes, radio buttons retain and display an on-or-off setting. You organize
radio buttons in a group to offer a choice among several alternatives—typically, inside a
dialog box. Radio buttons are small circles; when the user clicks a radio button to turn it
on, use the Control Manager procedure SetControlValue to fill the radio button with
a small black dot. The user can have only one radio button setting in effect at one time. In
other words, radio buttons are mutually exclusive. However, the Control Manager cannot
determine how your radio buttons are grouped; therefore, when the user turns on one
radio button, it is up to your application to use SetControlValue to turn off the others
in that group.
A set of radio buttons normally has two to seven items; each set must always have at
least two radio buttons. Each set of radio buttons must have a label that identifies the
kind of choices the group offers. Also, each button must have a title that identifies what
the radio button does. This title can be a few words or a phrase. A set of radio buttons is
never dynamic—that is, its contents should never change according to the context. (If you
need to display more than seven items, or if the items change as the context changes, you
should use a pop-up menu instead.)
Radio buttons represent choices that are related but not necessarily opposite. For
example, a pair of radio buttons may provide a choice between using the modem port or
the printer port, as shown in Figure 5-1 on page 5-4. If more than one set of radio buttons
is visible at one time, you need to demarcate the sets from one another. For example, you
can draw a dotted line around a set of radio buttons to separate it from other elements in
a dialog box.
Pop-Up Menus 5
Pop-up menus, introduced in the chapter “Menu Manager” in this book, provide the
user with a simple way to choose from among a list of choices without having to move
the cursor to the menu bar. As an alternative to a group of radio buttons, a pop-up menu
Control Manager
is particularly useful for specifying a group of settings or values that number five or
more, or whose settings or values might change. Like the items in a set of radio buttons,
the items in a pop-up menu are mutually exclusive—that is, only one choice from the
menu can be in effect at any time. Figure 5-8 on page 5-12 illustrates the choices available
in a pop-up menu that has been selected by the user.
Never use a pop-up menu as a way to provide the user with commands. Pop-up
menus should not list actions (that is, verbs); instead, they should list attributes (that
is, adjectives) or settings from which the user can choose one option.
Scroll Bars 5
Scroll bars change what portion of a document the user can view within the document’s
window. A scroll bar is a light gray rectangle with scroll arrows at each end. Inside the
scroll bar is a square called the scroll box. The rest of the scroll bar is called the gray area.
Windows can have a horizontal scroll bar, a vertical scroll bar, or both. A vertical scroll
bar lies along the right side of a window. A horizontal scroll bar runs along the bottom of
a window. Figure 5-4 shows the parts of a scroll bar.
Scroll arrow
Gray area
Scroll box
Gray area
Scroll arrow
If the user drags the scroll box, clicks a scroll arrow, or clicks anywhere in the gray area,
your application “moves” the document accordingly; use Control Manager routines as
appropriate to move the scroll box. Figure 5-5 illustrates, and the next few sections
explain, several key behaviors of a scroll bar.
A scroll bar represents the entire document in one dimension, top to bottom or right to
left. The scroll box shows the position, relative to the whole document, of the visible
portion of the document. If the scroll box is halfway between the top and bottom of the
scroll bar, then what the user sees should be about halfway through the document. Use
the SetControlValue or SetControlMaximum procedure to move the scroll box
whenever your application resizes a window and whenever it scrolls through a
document for any reason other than responding to the user dragging the scroll box.
Control Manager
After the user drags the scroll box, the Control Manager redraws the scroll box in its new
position. You then use the GetControlValue function to determine the position of the
scroll box, and you display the appropriate portion of the document. By dragging the
scroll box, the user can move quickly through the document. For example, to see the
beginning of the document, the user drags the scroll box to the top of the scroll bar. Your
application then scrolls to the top of the document.
At either end of the scroll bar are scroll arrows that indicate the direction of movement
through the document. For instance, when the user clicks the top scroll arrow, your
application needs to move toward the beginning of the document. Thus, the document
moves down, seemingly in the opposite direction. By clicking the scroll arrow, the user
tells your application, “Show me more of the document that’s hidden in this direction.”
Your application uses the SetControlValue procedure to move the scroll box in the
direction of the arrow being clicked. In this way, the scroll box continues to represent
the approximate position of the visible part of the document in relation to the whole
document. For example, when the user clicks the top scroll arrow, you move the
document down to bring more of the top of the document into view, and you move the
scroll box up, as illustrated in Figure 5-5.
Document
scroll direction
Document
scroll direction
Control Manager
Each click of a scroll arrow should move the document a distance of one unit in the
chosen direction. Your application determines what one unit equals. For example, a word
processor should move one line of text for each click in the arrow. A spreadsheet should
move one row or one column, depending on the direction of the arrow. To ensure smooth
scrolling effects, it’s usually best to specify the same size units within a document. When
the user holds down the mouse button while the cursor is in a scroll arrow, your
application should continuously scroll through the document in the indicated direction
until the user releases the mouse button or your application has scrolled as far as
possible.
The rest of the area within the scroll bar—excluding the scroll box and the scroll arrows—
is called the gray area. When the user clicks the gray area of a scroll bar, your application
should move the displayed area of the document by an entire window of information
minus one scroll unit. For example, if the window displays 15 lines of text and the user
clicks the gray area below the scroll box, your application should move the document up
14 lines so that the bottom line of the previous view appears at the top of the new view.
(This retained line helps the user see the newly displayed material in context.) You must
also move the scroll box an appropriate distance in that direction. For example, when the
user clicks the gray area below the scroll box, move the document view by one window
toward the bottom of the document and use SetControlValue to move the scroll box
accordingly.
When your application scrolls through a document—for example, when the user
manipulates a scroll bar—your application must move the document’s coordinate space
in relation to the window’s coordinate space. Your application uses the scroll box to
indicate the location of the top of the displayed portion of the document relative to the
rest of the document.
For example, if a text window contains 15 lines of text and the user scrolls 30 lines from
the top of the document, the scroll box should be set to a value of 30. The window
displays all of the lines between line 30 and line 45, as shown in Figure 5-6 on the next
page. The scroll box always indicates the displacement between the beginning of the
document and the top of the displayed portion of the document.
To prevent the user from scrolling past the edge of the document and seeing a blank
window, you should—for a vertical scroll bar—allow the document to scroll no farther
than the length of the document minus the height of the window, excluding the
15-pixel-deep region for the horizontal scroll bar at the bottom edge of the window.
Likewise, for a horizontal scroll bar, you should allow the document to scroll no farther
than the width of the document minus the width of the window—here, too, excluding
the 15-pixel-wide region for the vertical scroll bar at the right edge of the window.
Control Manager
Figure 5-6 Spatial relations between a document and a window, and their representation by
a scroll bar
Document
space
Scroll bar
values
0
30
45
90
Maximum 90
scrolling value
End of 105
document
For example, the document shown in Figure 5-6 is 105 lines long. So that the last 15 lines
will fill the window when the user scrolls to the end of the document, the application
does not scroll beyond 90 lines. Because the user has scrolled to line 30 of a maximum
90 lines, the scroll box appears a third of the way down the scroll bar.
“Scrolling Through a Document” beginning on page 5-43 describes in detail how to scroll
through a document in a window.
Control Manager
Other Controls 5
If you need controls other than the standard ones provided by the Control Manager,
you can design and implement your own. Typically, the only types of controls you
might need to implement are sliders or dials. Sliders and dials (which differ only in
appearance) are similar to scroll bars in that they graphically represent a range of
values that a user can set. Use an indicator—such as a sliding switch or a dial needle—
to indicate the current setting for the control and to let the user set its value. (For scroll
bars, the scroll box is the indicator.)
If you want to display a value not under the user’s direct control (for example, the
amount of free space remaining on a disk), you should use a status bar or other type
of graphic instead of a slider or dial.
Figure 5-7 illustrates several custom controls, which are used for purposes such as setting
the speaker volume, the gray-scale saturation level, and the relative position
of a slide within a presentation. As in this figure, be sure to include meaningful labels
that indicate the range and the direction of your control’s indicator.
A scroll bar is a slider representing the entire contents of a window, and the user uses the
scroll box to move to a specific location in that content. Don’t use scroll bars to represent
any other concept (for instance, changing a setting). Otherwise, your departure from the
consistent Macintosh interface might confuse the user.
Control Manager
Button
Checkbox
Radio buttons
Pop-up menu
Scroll arrow
Scroll box
Your application, in turn, should respond appropriately to mouse events involving active
controls. Most often, your application waits until the user releases the mouse button
before taking any action; as long as the user holds down the mouse button when the
cursor is over a control, you typically let TrackControl react to the mouse-down event;
TrackControl then informs your application the moment the user releases the mouse
button when the cursor is over an active control.
As soon as the user releases the mouse button, your application should
■ perform the task identified by the button title when the cursor is over an active button
■ toggle the value of the checkbox when the cursor is over an active checkbox (The
Control Manager then draws or removes the checkmark, as appropriate.)
■ turn on the radio button and turn off all other radio buttons in the group when the
cursor is over an active radio button
■ use the new setting chosen by the user when the cursor is over an active pop-up menu
■ show more of the document in the direction of the scroll arrow when the cursor is over
the scroll arrow or gray area of an active scroll bar, and move the scroll box
accordingly
■ determine where the user has dragged the scroll box when the cursor is over the scroll
box and then display the corresponding portion of the document
Sometimes your application should respond even before the user releases the mouse
button—that is, your application should undertake some continuous action as long as the
Control Manager
user holds down the mouse button when the cursor is in an active control. Most typically,
when the user moves the cursor to a scroll arrow or gray area and then holds down the
mouse button, your application should continuously scroll through the document until
the user releases the mouse button or until the user can’t scroll any farther. To perform
this kind of action, you define an action procedure and specify it to TrackControl;
TrackControl calls your action procedure as long as the user holds down the mouse
button.
Whenever it is inappropriate for your application to a respond to a mouse-down event in
a control, you should make it inactive. An inactive control is one that the user can’t use
because it has no meaning or effect in the current context—for example, the scroll bars
in an empty window. The Control Manager continues to display an inactive control so
that it remains visible, but in a manner that indicates its state to the user. As shown in
Figure 5-9, the Control Manager dims inactive buttons, checkboxes, radio buttons, and
pop-up menus, and it lightens the gray area and removes the scroll box from inactive
scroll bars.
Button
Checkbox
Radio buttons
Pop-up menu
Scroll bar
You can use the HiliteControl procedure to make any control inactive and then active
again. Except for scroll bars (which you should hide using the HideControl procedure),
you should use HiliteControl to make all other controls inactive when their windows
are not frontmost. You typically use controls other than scroll bars in dialog boxes. See
the chapter “Dialog Manager” in this book for a discussion of how to make buttons, radio
buttons, checkboxes, and pop-up menus inactive and active.
You make scroll bars inactive when the document is smaller than the window in which
you display it. To make a scroll bar inactive, you typically use the SetControlMaximum
procedure to make the scroll bar’s maximum value equal to its minimum value, in which
case the Control Manager automatically makes the scroll bar inactive. To make it active
again, you typically use SetControlMaximum to make its maximum value larger than
its minimum value.
Control Manager
Control
Constant definition ID Control
pushButProc 0 Button
checkBoxProc 1 Checkbox
radioButProc 2 Radio button
scrollBarProc 16 Scroll bar
popupMenuProc 1008 Pop-up menu
The control definition function for scroll bars figures out whether a scroll bar is vertical or
horizontal from a rectangle you specify when you create the control.
Control Manager
Control Manager
result a handle to the control. (You use a control’s handle when referring to the control in
most other Control Manager routines; when you create scroll bars or pop-up menus for a
window, you should store their handles in one of your application’s own data structures
for later reference.)
When you specify in the control resource that a control is initially visible and you use the
GetNewControl function, the Control Manager uses the control’s control definition
function to draw the control inside its window. The Control Manager draws the control
immediately, without using your window’s standard updating mechanism. If you specify
that a control is invisible, you can use the ShowControl procedure when you want to
draw the control. Again, the Control Manager draws the control without using your
window’s standard updating mechanism. (Of course, even when the Control Manager
draws the control, it might be completely or partially obscured from the user by
overlapping windows or other objects.)
When your application receives an update event for a window that contains controls, you
use the UpdateControls procedure in your application’s standard window- updating
code to redraw all the controls in the update region of the window.
Note
When you use the Dialog Manager to implement buttons, radio buttons,
checkboxes, or pop-up menus in alert boxes and dialog boxes, Dialog
Manager routines automatically use Control Manager routines to create
and update these controls for you. If you implement any controls other
than buttons, radio buttons, checkboxes, and pop-up menus in alert or
dialog boxes—and whenever you implement any controls (scroll bars, for
example) in your application’s windows—you must explicitly use either
the GetNewControl or the NewControl function to create the controls.
You must always use the UpdateControls procedure to update
controls you put in your own windows. ◆
When you use the Window Manager procedure DisposeWindow or CloseWindow to
remove a window, either procedure automatically removes all controls associated with
the window and releases the memory they occupy.
When you no longer need a control in a window that you want to keep, you can use the
DisposeControl procedure, described on page 5-108, to remove it from the screen,
delete it from its window’s control list, and release the control record and all other
associated data structures from memory. You can use the KillControls procedure,
described on page 5-108, to dispose of all of a window’s controls at once.
The next section, “Creating a Button, Checkbox, or Radio Button,” provides a general
discussion of the control resource as well as a more detailed description of the use of the
control resource to specify buttons, checkboxes, and radio buttons in your application’s
windows. The two following sections, “Creating Scroll Bars” (beginning on page 5-21)
and “Creating a Pop-Up Menu” (beginning on page 5-25), describe those elements of the
control resource that differ from the control resources for buttons, checkboxes, and radio
buttons. “Updating a Control” beginning on page 5-29 then offers an example of how
you can use the UpdateControls procedure within your window-updating code.
Control Manager
Note
For the Control Manager to draw a control properly inside a window, the
window must have its upper-left corner at local coordinates (0,0). If you
use the QuickDraw procedure SetOrigin to change a window’s local
coordinate system, be sure to change it back—so that the upper-left
corner is again at (0,0)—before drawing any of its controls. Because
many Control Manager routines can (at least potentially) redraw a
control, the safest policy after changing a window’s local coordinate
system is to change the coordinate system back before calling any
Control Manager routine. ◆
Control Manager
SetPort(myWindow);
gMyPlayButtonCtlHandle := GetNewControl(rPlayButton, myWindow);
IF (gMyPlayButtonCtlHandle = NIL) THEN
MyCreatePlaySoundsWindow := kControlErr;
END
ELSE
MyCreatePlaySoundsWindow := kNoSoundWindow;
END;
You supply the following information in the control resource for a button, checkbox,
radio button, or scroll bar:
■ a rectangle, specified by coordinates local to the window, that determines the control’s
size and location
■ the initial setting for the control
■ a constant (either visible or invisible) that specifies whether the control should
be drawn on the screen immediately
■ the maximum setting for the control
■ the minimum setting for the control
■ the control definition ID
■ a reference value, which your application may use for any purpose
■ the title of the control; or, for scroll bars, an empty string
Control Manager
As explained in “Creating a Pop-Up Menu” beginning on page 5-25, the values you
supply in a control resource for a pop-up menu differ from those you specify for other
buttons, checkboxes, radio buttons, and scroll bars.
Buttons are drawn to fit the rectangle exactly. To allow for the tallest characters in
the system font, there should be at least a 20-point difference between the top and bottom
coordinates of the rectangle. Listing 5-2 uses a rectangle with coordinates (87,187,107,247)
to describe the size and location of the control within the window. Remember that the
Control Manager will not draw controls properly unless the upper-left corner of the
window coincides with the coordinates (0,0).
In Listing 5-2, the initial and minimum settings for the button are 0 and the maximum
setting is 1. In control resources for buttons, checkboxes, and radio buttons, supply these
values as the initial settings:
■ For buttons, which don’t retain a setting, specify a value of 0 for the initial and
minimum settings and 1 for the maximum setting.
■ For checkboxes and radio buttons, which retain an on-or-off setting, specify a value of
0 when you want to the control to be initially off. To turn a checkbox or radio button
on, assign it an initial setting of 1. In response, the Control Manager places an X in a
checkbox or a black dot in a radio button.
Because the visible identifier is specified in this example, the control is drawn
immediately in its window. If you use the invisible identifier, your control is not
drawn until your application uses the ShowControl procedure. When you want to
make a visible control invisible, you can use the HideControl procedure.
In Listing 5-2, the maximum setting for the button is 1, which you, too, should specify in
your control resources as the maximum setting for buttons, checkboxes, and radio
buttons. In Listing 5-2, the minimum setting for the button is 0, which you, too, should
specify in your control resources as the minimum setting for buttons, checkboxes, and
radio buttons.
In Listing 5-2, the pushButProc constant is used to specify the control definition ID. Use
the checkBoxProc constant to specify a checkbox and the radioButProc constant to
specify a radio button.
Listing 5-2 specifies a reference value of 0. Your application can use this value for any
purpose (except when you add the popupUseAddResMenu variation code to the
popupMenuProc control definition function, as described in “Creating a Pop-Up Menu”
beginning on page 5-25).
Finally, the string "Play" is specified as the title of the control. Buttons, checkboxes,
and radio buttons require a title that communicates their purpose to the user. (The
chapter “Dialog Manager” in this book offers extensive guidelines on appropriate titles
for buttons.)
When specifying a title, make sure it fits in the control’s rectangle; otherwise, the
Control Manager truncates the title. For example, it truncates the titles of checkboxes
and radio buttons on the right in Roman scripts, and it centers and truncates both ends of
button titles.
Control Manager
If you localize your application for use with worldwide versions of system software, the
titles may become longer or shorter. Translated text is often 50 percent longer than U.S.
English text. You may need to resize your controls to accommodate the translated text.
By default, the Control Manager displays control titles in the system font. To make it
easier to localize your application for use with worldwide versions of system software,
you should not change the font. Do not use a smaller font, such as 9-point Geneva; some
script systems, such as KanjiTalk, require 12-point fonts. You can spare yourself future
localization effort by leaving all control titles in the system font.
Follow book-title style when you capitalize control titles. In general, capitalize one-word
titles and capitalize nouns, adjectives, verbs, and prepositions of four or more letters in
multiple-word titles. You usually don’t capitalize words such as in, an, or and. For
capitalization rules, see the Apple Publications Style Guide, available from APDA.
The Control Manager allows button, checkbox, and radio button titles of multiple lines.
When specifying a multiple-line title, end each line with the ASCII character code $0D
(carriage return). If the control is a button, each line is horizontally centered, and the
font leading is inserted between lines. (The height of each line is equal to the distance
from the ascent line to the descent line plus the leading of the font used. Be sure to make
the total height of the rectangle greater than the number of lines times this height.) If
the control is a checkbox or a radio button, the text is justified as appropriate for the
user’s current script system, and the checkbox or button is vertically centered within
its rectangle.
Figure 5-11 shows the Play Sounds window with four additional controls: radio buttons
titled Droplet, Quack, Simple Beep, and Wild Eep.
Only one of these radio buttons can be on at a time. Listing 5-3 initially sets the Droplet
radio button to 1, turning it on by default. This listing also shows the control resources
for the other buttons, all initially set to 0 to turn them off.
For a checkbox or a radio button, always allow at least a 16-point difference between the
top and bottom coordinates of its rectangle to accommodate the tallest characters in the
system font.
Control Manager
Listing 5-3 Rez input for the control resources of radio buttons
Control Manager
scroll to, assign an initial value of 0 as the maximum setting in the control resource; the
control definition function automatically makes a scroll bar inactive when its minimum
and maximum settings are identical. Thereafter, your window-handling routines should
set and maintain the maximum setting, as described in “Determining and Changing
Control Settings” beginning on page 5-37.
By convention, a scroll bar is 16 pixels wide, so there should be a 16-point difference
between the left and right coordinates of a vertical scroll bar’s rectangle and between the
top and bottom coordinates of a horizontal scroll bar’s rectangle. (If you don’t provide a
16-pixel width, the Control Manager scales the scroll bar to fit the width you specify.) A
standard scroll bar should be at least 48 pixels long, to allow room for the scroll arrows
and scroll box.
The Control Manager draws lines that are 1 pixel wide for the rectangle enclosing the
scroll bar. As shown in Figure 5-12, the outside lines of a scroll bar should overlap the
lines that the Window Manager draws for the window frame.
Figure 5-12 How a scroll bar should overlap the window frame
1-pixel overlap
(–1,285) (0,300)
16 pixels
1-pixel overlap
To determine the rectangle for a vertical scroll bar, perform the following calculations and
use their results in your control resource. (Do not include the area of the title bar in your
calculations.)
■ top coordinate = combined height of any items above the scroll bar – 1
■ left coordinate = width of window – 15
■ bottom coordinate = height of window – 14
■ right coordinate = width of window + 1
Control Manager
To determine the rectangle for a horizontal scroll bar, perform the following calculations
and use their results in your control resource.
■ top coordinate = height of window – 15
■ left coordinate = combined width of any items to the left of the scroll bar – 1
■ bottom coordinate = height of window + 1
■ right coordinate = width of window – 14
The top coordinate of a vertical scroll bar is –1, and the left coordinate of a horizontal
scroll bar is –1, unless your application uses part of the window’s typical scroll bar areas
(in particular, those areas opposite the size box) for displaying information or specifying
additional controls. For example, your application may choose to display the current
page number of a document in the lower-left corner of the window—that is, in a small
area to the left of its window’s horizontal scroll bar. See Macintosh Human Interface
Guidelines for a discussion of appropriate uses of a window’s scroll bar areas for
additional items and controls.
Just as the maximum settings of a window’s scroll bars change when the user resizes the
document’s window, so too do the scroll bars’ coordinate locations change when the user
resizes the window. Although you must specify an initial maximum setting and location
in the control resource for a scroll bar, your application must be able to change them
dynamically—typically, by storing handles to each scroll bar in a document record when
you create a window, and then by using Control Manager routines to change control
settings (as described in “Determining and Changing Control Settings” beginning on
page 5-37) and sizes and locations of controls (as described in “Moving and Resizing
Scroll Bars” beginning on page 5-65).
Listing 5-4 shows a window resource (described in the chapter “Window Manager” in
this book) for creating a window, and two control resources for creating the window’s
vertical and horizontal scroll bars. The rectangle for the initial size and shape of the
window is specified in global coordinates, of course, and the rectangles for the two scroll
bars are specified in coordinates local to the window.
Listing 5-4 Rez input for resources for a window and its scroll bars
/*initial window*/
resource 'WIND' (rDocWindow, preload, purgeable) {
{64, 60, 314, 460}, /*initial rectangle for window*/
zoomDocProc, invisible, goAway, 0x0, "untitled"
};
/*initial vertical scroll bar*/
resource 'CNTL' (rVScroll, preload, purgeable) {
{-1, 385, 236, 401}, /*initial rectangle for control*/
/*initial setting, visibility, max, min, ID, refcon, title*/
0, invisible, 0, 0, scrollBarProc, 0, ""
};
Control Manager
Listing 5-5 shows an application-defined procedure called DoNew that uses the
GetNewWindow and GetNewControl functions to create a window and its scroll bars
from the resources in Listing 5-4.
The DoNew routine uses Window Manager routines to create a window; its window
resource specifies that the window is invisible. The window resource specifies an initial
size and location for the window, but because the window is invisible, this window is not
drawn.
Control Manager
Then DoNew creates a document record and stores a handle to it in the myData variable.
The SurfWriter sample application uses this document record to store the data that the
user creates in this window—as well as handles to the scroll bars that it creates. The
SurfWriter sample application later uses these control handles to handle scrolling
through the document and to move and resize the scroll bars when the user resizes the
window. (See the chapter “Window Manager” in this book for more information about
creating such a document record.)
To create scroll bars, DoNew uses GetNewControl twice—once for the vertical scroll bar
and once for the horizontal scroll bar. The GetNewControl function returns a control
handle; DoNew stores these handles in the vScrollBar and hScrollBar fields of its
document record for later reference.
Because the window and the scroll bars are invisible, nothing is drawn onscreen
yet for the user. Before drawing the window and its scroll bars, DoNew calls
another application-defined procedure, MyAdjustScrollBars. In turn,
MyAdjustScrollBars calls other application-defined routines that move and
resize the scroll bars to fit the window and then calculate the maximum settings of
these controls. (Listing 5-14 on page 5-39 shows the MyAdjustScrollBars procedure.)
After creating the window and its scroll bars, and then sizing and positioning them
appropriately, DoNew uses the Window Manager procedure ShowWindow to display the
window with its scroll bars.
Control Manager
Listing 5-6 Rez input for the control resource of a pop-up menu
Listing 5-6 specifies a rectangle with the coordinates (90,18,109,198). Figure 5-14
illustrates the rectangle for this pop-up menu.
50 pixels (109,198)
(Title width) (Lower-right corner of
enclosing rectangle)
Listing 5-6 uses the popupTitleLeftJust constant to specify the position of the
control title. Specify any combination of the following constants (or their values) to
inform the Control Manager where and how to draw the pop-up menu’s title:
Control Manager
myData: MyDocRecHnd;
window: WindowPtr;
Listing 5-6 specifies 50 pixels (in place of a maximum setting) as the width of the control
title. After it creates the control, the Control Manager sets the maximum value in the
pop-up menu’s control record to the number of items in the pop-up menu. Figure 5-14
illustrates this title width for the pop-up menu.
Listing 5-6 uses a kPopUpMenu constant to specify the resource ID of a 'MENU' resource
(in place of a minimum setting for the control). (See the chapter “Menu Manager” in this
book for a description of the 'MENU' resource type.) After it creates the control, the
Control Manager assigns 1 as the minimum setting in the pop-up menu’s control record.
IMPORTANT
When using the ResEdit application, version 2.1.1, you must use the
same resource ID when specifying the menu resource and the control
resource that together define a pop-up menu. ▲
You can also specify a different control definition ID by adding any or all of the following
constants (or the variation codes they represent) to the popupMenuProc constant:
CONST popupFixedWidth = $0001; {use fixed-width control}
popupUseAddResMenu = $0004; {use resource for menu items}
popupUseWFont = $0008; {use window font}
The reference value that you specify in the control resource (and stored by the Control
Manager in the contrlRfCon field of the control record) is available for your
application’s use. However, if you specify popupUseAddResMenu as a variation code,
Control Manager
Constant Description
popUpFixedWidth Uses a constant control width. If your application specifies
this value, the pop-up control definition function does not
resize the control horizontally to fit long menu items. The
width of the pop-up box is set to the width of the control,
minus the width of the pop-up title your application
specifies when it creates the control. If a menu item in a
pop-up box does not fit in the space provided, the text is
truncated to fit, and three ellipsis points (...) are appended
at the end. If you do not specify this variation code, the
pop-up control definition function may resize the control
horizontally.
popupUseAddResMenu Gets menu items from a resource other than the 'MENU'
resource. If your application specifies this value when
creating a pop-up menu, the control definition function
interprets the value in the contrlRfCon field of the control
record as a value of type ResType. The control definition
function uses the Menu Manager procedure
AppendResMenu to add resources of that type to the menu.
popupUseWFont Uses the font of the specified window. If your application
specifies this value, the pop-up control definition function
draws the pop-up menu title using the font and size of
the window containing the control instead of using the
system font.
the Control Manager coerces the value in the contrlRfCon field of the control record
to the type ResType and then uses AppendResMenu to add items of that type to the
pop-up menu. For example, if you specify a reference value of LongInt('FONT') as the
reference value, the control definition function appends a list of the fonts installed
in the system to the menu associated with the pop-up menu. After the control has been
created, your application can use the control record’s contrlRfCon field for whatever
use it requires. You can determine which menu item is currently chosen by calling
GetControlValue.
Whenever the pop-up menu is redrawn, its control definition function calls the Menu
Manager procedure CalcMenuSize. This procedure recalculates the size of the
menu associated with the control (to allow for the addition or deletion of items in the
menu). The pop-up control definition function may also update the width of the pop-
up menu to the sum of the width of the pop-up title, the width of the longest item in the
menu, the width of the downward-pointing arrow, and a small amount of white space.
As previously described, your application can override this behavior by adding the
variation code popupFixedWidth to the pop-up control definition ID.
You should not use the Menu Manager function GetMenuHandle to obtain a handle to
a menu associated with a pop-up control. If necessary, you can obtain the menu handle
(and the menu ID) of a pop-up menu by dereferencing the contrlData field of the
pop-up menu’s control record. The contrlData field of a control record is a handle to a
block of private information. For pop-up menu controls, this field is a handle to a pop-up
private data record, which is described on page 5-77.
Control Manager
Updating a Control 5
Your program should use the UpdateControls procedure upon receiving an update
event for a window that contains controls such as scroll bars. (Window Manager routines
such as SelectWindow, ShowWindow, and BringToFront do not automatically
call UpdateControls to display the window’s controls. Instead, they merely add
the appropriate regions to the window’s update region. This in turn generates an
update event.)
Note
The Dialog Manager automatically updates the controls you use in alert
boxes and dialog boxes. ◆
When your application receives an update event for a window that contains controls, use
the UpdateControls procedure in your window-updating code to redraw all the
controls in the update region of the window. Call UpdateControls after using the
Window Manager procedure BeginUpdate and before using the Window Manager
procedure EndUpdate.
When you call UpdateControls, you pass it parameters specifying the window to
be updated and the window area that needs updating. Use the visible region of
the window’s graphics port, as referenced in the port’s visRgn field, to specify the
window’s update region.
Listing 5-7 shows an application-defined routine, DoUpdate, that responds to an update
event. The DoUpdate routine calls the Window Manager procedure BeginUpdate. To
redraw this portion of the window, DoUpdate then calls another of its own procedures,
MyDrawWindow.
Listing 5-8 illustrates how the SurfWriter sample application updates window controls
and other window contents by using its own application-defined routine,
Control Manager
For more information about updating window contents, see the chapter “Window
Manager” in this book.
Control Manager
Note
The Dialog Manager procedure ModalDialog automatically calls
FindWindow, FindControl, and TrackControl for mouse-down
events in the controls of alert and modal dialog boxes. You can use the
Dialog Manager function DialogSelect, which automatically calls
FindWindow, FindControl, and TrackControl, to help you handle
mouse events in your movable modal and modeless dialog boxes. ◆
Control Manager
Control Manager
In Listing 5-9, when FindWindow reports a mouse-down event in the content region of a
window containing controls, DoMouseDown calls another application-defined procedure,
DoContentClick, and passes it the window pointer returned by the FindWindow
function as well as the event record.
Listing 5-10 shows an application-defined procedure, DoContentClick, that uses this
information to determine whether the mouse-down event occurred in a control.
CASE windowType OF
kPlaySoundsModelessDialogBox:
BEGIN
SetPort(window);
mouse := event.where; {get the mouse location}
GlobalToLocal(mouse); {convert to local coordinates}
part := FindControl(mouse, window, control);
IF control = gSpeedPopUpControlHandle THEN
{mouse-down in Modem Speed pop-up menu}
DoPopUpMenu(mouse, control);
CASE part OF
inButton: {mouse-down in Play button}
DoPlayButton(mouse, control);
inCheckBox: {mouse-down in checkbox}
DoDrumRollCheckBox(mouse, control);
OTHERWISE
;
END; {of CASE for control part codes}
END; {of kPlaySoundsModelessDialogBox case}
Control Manager
Figure 5-15 shows the Play Sounds window; DoContentClick uses the FindControl
function to determine whether the mouse-down event occurred in the pop-up menu, the
Play button, or the Add Drum Roll checkbox.
First, however, DoContentClick uses the event record to determine the cursor location,
which is specified in global coordinates. Because the FindControl function expects the
cursor location in coordinates local to the window, DoContentClick uses the
QuickDraw procedure GlobalToLocal to convert the point stored in the where field of
the event record to coordinates local to the current window. The GlobalToLocal
procedure takes one parameter, a point in global coordinates—where the upper-left
corner of the entire bit image is coordinate (0,0). See Inside Macintosh: Imaging for more
information about the GlobalToLocal procedure.
Control Manager
Control Manager
When the user presses the mouse button when the cursor is in the Play button,
TrackControl inverts the Play button. If the user releases the mouse button after
moving the cursor outside the control part, TrackControl stops inverting the
button and returns the value 0, in which case DoPlayButton does nothing.
If, however, the user releases the mouse button with the cursor in the Play button,
TrackControl stops inverting the Play button and returns the value for the inButton
constant. Then DoPlayButton calls the Sound Manager procedure SysBeep to play the
system alert sound (which is described in the chapter “Dialog Manager” in this book).
Before releasing the mouse button, the user can move the cursor away from the control
part and then return to it, and TrackControl will still return the part code when the
user releases the mouse button.
For buttons, checkboxes, radio buttons, and the scroll box in a scroll bar, your application
typically passes NIL to TrackControl to use no action procedure. However,
TrackControl still responds visually to mouse events in active controls. That is, when
the user presses the mouse button with the cursor over a control whose action procedure
is set to NIL, TrackControl changes the control’s display appropriately until the user
releases the mouse button.
For scroll arrows and for the gray areas of a scroll box, you need to define your own
action procedures. You pass a pointer to the action procedure as one of the parameters to
TrackControl, as described in “Scrolling in Response to Events in Scroll Arrows and
Gray Areas” beginning on page 5-57.
For a pop-up menu, you must pass Pointer(-1) to TrackControl for its action
procedure; this causes TrackControl to use the action procedure defined in the pop-up
control definition function.
Listing 5-10 on page 5-33 calls an application-defined routine, DoPopUpMenu, when
FindControl reports a mouse-down event in a pop-up menu. Listing 5-12 shows how
DoPopUpMenu uses TrackControl to handle user interaction in the pop-up menu. By
passing Pointer(-1) to TrackControl, DoPopUpMenu uses the action procedure
defined in the pop-up control definition function.
Control Manager
The action procedure for pop-up menus highlights the pop-up menu title, displays the
pop-up menu, and handles all user interaction while the user drags up and down the
menu. When the user releases the mouse button, the action procedure closes the pop-up
box, draws the user’s choice in the pop-up box (or restores the previous item if the user
doesn’t make a new choice), and removes the highlighting of the pop-up title. The
pop-up control definition function then changes the value of the contrlValue field of
the control record to the number of the menu item chosen by the user.
Because buttons do not retain settings, responding to them is very straightforward: when
the user clicks a button, your application should immediately undertake the action
described by the button’s title. For pop-up menus and other types of controls, you must
determine their current settings before responding to the user’s action. For example,
before responding, you need to know which item the user has chosen in a pop-up menu,
whether a checkbox is checked, or how far the user has moved the scroll box. The action
you take may, in turn, involve changing other control settings. Determining and changing
control settings are described in the next section.
After learning how to determine and change control settings, see “Scrolling Through a
Document” beginning on page 5-43 for a detailed discussion of how to respond to mouse
events in scroll bars.
Control Manager
Applications must adjust some controls in response to events other than mouse events in
the controls themselves. For example, when the user resizes a window, your application
must use the Control Manager procedures MoveControl and SizeControl to move
and resize the scroll bars appropriately.
Your application can use the GetControlValue function to determine the current
setting of a control, and it can use the GetControlMaximum function to determine a
control’s maximum setting.
You can use the SetControlValue procedure to change the control’s setting and
redraw the control accordingly. You can use the SetControlMaximum procedure to
change a control’s maximum setting and to redraw the indicator or scroll box to reflect
the new setting.
In response to user action involving a control, your application often needs to change the
setting and possibly redraw the control. When the user clicks a checkbox, for example,
your application must determine whether the checkbox is currently selected or not, and
then switch its setting. When you use SetControlValue to switch a checkbox setting,
the Control Manager either draws or removes the X inside the checkbox, as appropriate.
When the user clicks a radio button, your application must determine whether the radio
button is already on and, if not, turn the previously selected radio button off and turn the
newly selected radio button on.
Figure 5-15 on page 5-34 shows a checkbox in the Play Sounds window. When the user
clicks the checkbox to turn it on, the application adds a drum roll to the sound it plays
whenever the user clicks the Play button.
Listing 5-13 shows the application-defined routine DoDrumRollCheckBox, which
responds to a click in a checkbox. This routine uses the GetControlValue function to
determine the last value of the checkbox and then uses the SetControlValue
procedure to change it. The GetControlValue function returns a control’s current
setting, which is stored in the contrlValue field of the control record. The
SetControlValue procedure sets the contrlValue field to the specified value and
redraws the control to reflect the new setting. (For checkboxes and radio buttons, the
value 1 fills the control with the appropriate mark, and the value 0 removes the mark. For
scroll bars, SetControlValue redraws the scroll box at the appropriate position along
the scroll bar. For a pop-up menu, SetControlValue displays in its pop-up box the
name of the menu item corresponding to the specified value.)
Control Manager
Control Manager
To prevent the user from scrolling past the edge of the document and seeing a blank
window, you should limit the scroll bars’ maximum settings, as illustrated in Figure 5-6
on page 5-10. If the window is larger than the document (which can easily happen with
small documents on large monitors), your application should make the maximum scroll
bar settings identical to their minimum settings. In this case, the Control Manager then
makes the scroll bars inactive, which is appropriate when all the information fits in
the window.
Control Manager
Listing 5-16 shows the application-defined MyAdjustHV procedure, used for adjusting
the current and maximum settings for a scroll bar. When passed TRUE in the isVert
parameter, MyAdjustHV calculates and adjusts the maximum and current settings for the
vertical scroll bar; when passed FALSE, it calculates and adjusts those settings for the
horizontal scroll bar.
In this example, the document consists of monostyled text stored in a TextEdit edit
record. The viewRect field of a TextEdit edit record specifies the rectangle where the text
is visible; because viewRect already excludes the scroll bar regions, MyAdjustHV does
not need to subtract the scroll bar regions from the window height or width when
calculating the maximum settings for these scroll bars. (For more information about
TextEdit in general and the edit record in particular, see Inside Macintosh: Text.)
Listing 5-16 Adjusting the maximum and current settings for a scroll bar
Control Manager
Control Manager
thereby reducing the maximum setting, SetControlMaximum moves the scroll box
to indicate the new position relative to the smaller document.
When the user adds information to or removes information from a document or adjusts
its window size, your application may need to adjust the current setting of the scroll bar
as well. The MyAdjustHV routine calculates a new current setting for the control and
then uses SetControlValue to assign that setting to the control as well as to reposition
the scroll box accordingly.
The destination rectangle, specified in the destRect field of the edit record, is the
rectangle in which the text is drawn, whereas the view rectangle is the rectangle in which
the text is actually visible. By subtracting the top coordinate of the destination rectangle
from the top coordinate of the view rectangle, and dividing the result by the line height,
MyAdjustHV derives the number of the line currently displayed at the top of the
window. This is the line number MyAdjustHV uses for the current setting of the vertical
scroll bar.
To derive the current setting of the horizontal scroll bar in terms of pixels, MyAdjustHV
subtracts the left coordinate of the destination rectangle from the left coordinate of the
view rectangle.
Control Manager
When the user clicks a gray area of a scroll bar, your application should scroll by a
distance of just less than the height or width of the window. To determine this height and
width, you can use the contrlOwner field of the scroll bar’s control record. This field
contains a pointer to the window record. When you scroll by a distance of one window, it
is best to retain part of the previous window. This retained portion helps the user place
the material in context. For example, if the user scrolls down by a distance of one
window in a text document, the line at the top of the window should be the one that
previously appeared at the bottom of the window.
The scrolling direction is determined by whether the scrolling distance is expressed as a
positive or negative number. When the user scrolls down or to the right, the scrolling
distance is a negative number; when the user scrolls up or to the left, the scrolling
distance is a positive number. For example, when the user scrolls from the beginning of a
document to a line located 200 pixels down, the scrolling distance is –200 pixels on the
vertical scroll bar. When the user scrolls from there back to the start of the document, the
scrolling distance is 200 pixels.
Determining the scrolling distance is only the first step. In brief, your application should
take the following steps to scroll through a document in response to the user’s
manipulation of a scroll bar.
1. Use the FindControl, GetControlValue, and TrackControl functions to help
calculate the scrolling distance.
2. If you are scrolling for any reason other than the user dragging the scroll box, use the
SetControlValue procedure to move the scroll box a corresponding amount.
3. Use a routine—such as the QuickDraw procedure ScrollRect or the TextEdit
procedure TEPinScroll—to move the bits displayed in the window by the
calculated scrolling distance. Then either use a call that generates an update event
or else directly call your application’s DoUpdate routine, which should perform
the rest of these steps.
4. Use the UpdateControls procedure to update the scroll bars and then call the
Window Manager procedure DrawGrowIcon to redraw the size box.
5. Use the QuickDraw procedure SetOrigin to change the window origin by an
amount equal to the scroll bar settings so that the upper-left corner of the document
lies at (0,0) in the window’s local coordinate system. (You perform this step so that
your application’s document-drawing routines can draw in the correct area of the
window.)
6. Call your application’s routines for redrawing the document inside the window.
7. Use the SetOrigin procedure to reset the window origin to (0,0) so that future
Window Manager and Control Manager routines draw in the correct area of the
window.
8. Return to your event loop.
These steps are explained in greater detail in the rest of this section.
Control Manager
Note
It is not necessary to use SetOrigin as described in the rest of this
chapter. This procedure merely helps you to offset the window origin
by the scroll bars’ current settings when you update the window, so
that you can locate objects in a document using a coordinate system
where the upper-left corner of the document is always at (0,0). As an
alternative to this approach, your application can leave the upper-left
corner of the window (called the window origin) located at (0,0) and
instead offset the items in your document by an amount equal to the
scroll bars’ settings. The QuickDraw procedures OffsetRect,
OffsetRgn, SubPt, and AddPt, which are described in Inside Macintosh:
Imaging, are useful if you pursue this alternate approach. ◆
When the user saves a document, your application should store the data in your own
application-defined data structures. (For example, the sample code in this chapter
stores a handle to a TextEdit edit record in a document record. The edit record contains
information about the text, such as it length and its own local coordinate system, and
a handle to the text itself.) You typically store information about the objects your
application displays onscreen by using coordinates local to the document, where the
upper-left corner of the document is located at (0,0).
The left side of Figure 5-16 on the next page illustrates a case in which the user has just
opened an existing document, and the SurfWriter sample application displays the top of
the document. In this example, the document consists of 35 lines of monostyled text, and
the line height throughout is 10 pixels. Therefore, the document is 350 pixels long. When
the user first opens the document, the window origin is identical to the upper-left point
of the document’s space: both are at (0,0).
In this example, the window displays 15 lines of text, which amount to 150 pixels. Hence,
the maximum setting for the scroll bar is 200 because the vertical scroll bar’s maximum
setting is the length of the document minus the height of its window.
Imagine that the user drags the scroll box halfway down the vertical scroll bar. Because
the user wishes to scroll down, the SurfWriter application must move the text of the
document up so that more of the bottom of the document shows. Moving a document up
in response to a user request to scroll down requires a scrolling distance with a negative
value. (Likewise, moving a document down in response to a user request to scroll up
requires a scrolling distance with a positive value.)
Using FindControl, TrackControl, and GetControlValue, the SurfWriter
application determines that it must move the document up by 100 pixels—that is,
by a scrolling distance of –100 pixels. (Using FindControl, TrackControl, and
GetControlValue to determine the scrolling distance is explained in detail in
“Scrolling in Response to Events in the Scroll Box” beginning on page 5-53.)
Control Manager
When the user first opens a document After the application moves the document
vertically by —100 pixels
(—100,0)
(0,0) (0,0)
Update
region
(150,0) (150,0)
(250,0)
(350,0)
The SurfWriter application then uses the QuickDraw procedure ScrollRect to shift
the bits displayed in the window by a distance of –100 pixels. The ScrollRect
procedure moves the document upward by 100 pixels (that is, by 10 lines); 5 lines from
the bottom of the previous window display now appear at the top of the window,
and the SurfWriter application adds the rest of the window to an update region for
later updating.
The ScrollRect procedure doesn’t change the coordinate system of the window;
instead it moves the bits in the window to new coordinates that are still in the window’s
local coordinate system. For purposes of updating the window, you can think of this
as changing the coordinates of the entire document, as illustrated in the right side of
Figure 5-16.
The ScrollRect procedure takes four parameters: a rectangle to scroll, a horizontal
distance to scroll, a vertical distance to scroll, and a region handle. Typically, when
specifying the rectangle to scroll, your application passes a value representing the content
region minus the scroll bar regions, as shown in Listing 5-17.
Control Manager
Listing 5-17 Using ScrollRect to scroll the bits displayed in the window
IMPORTANT
You must first pass a horizontal distance as a parameter to ScrollRect
and then pass a vertical distance. Notice that when you specify a point in
the QuickDraw coordinate system, the opposite is true: you name the
vertical coordinate first and the horizontal coordinate second. ▲
Although each scroll bar is 16 pixels along its shorter dimension, the
DoGraphicsScroll procedure shown in Listing 5-17 subtracts only 15 pixels
because the edge of the scroll bar overlaps the edge of the window frame, leaving
only 15 pixels of the scroll bar in the content region of the window.
The bits that ScrollRect shifts outside of the rectangle specified by myScrollRect are
not drawn on the screen, and they are not saved—it is your application’s responsibility to
keep track of this data.
The ScrollRect procedure shifts the bits a distance of hDistance pixels horizontally
and vDistance pixels vertically; when DoGraphicsScroll passes positive values in
these parameters, ScrollRect shifts the bits in the myScrollRect parameter to the
right and down, respectively. This is appropriate when the user intends to scroll left or
up, because when the SurfWriter application finishes updating the window, the user sees
more of the left and top of the document, respectively. (Remember: to scroll up or left,
move the document down or right, both of which are in the positive direction.)
When DoGraphicsScroll passes negative values in these parameters, ScrollRect
shifts the bits in the myScrollRect parameter to the left or up. This is appropriate when
the user intends to scroll right or down, because when the SurfWriter application finishes
updating the window, the user sees more of the right and the bottom of the document.
(Remember: to scroll down or right, move the document up or left, both of which are in
the negative direction.)
Control Manager
In Figure 5-16, the SurfWriter application determines a vertical scrolling distance of –100,
which it passes in the vDistance parameter as shown here:
If, however, the user were to move the scroll box back to the beginning of the document
at this point, the SurfWriter application would determine that it has a distance of
100 pixels to scroll up, and it would therefore pass a positive value of 100 in the
vDistance parameter.
After using ScrollRect to move the bits that already exist in the window, the
SurfWriter application should draw the bits in the update region of the window by using
its standard window-updating code.
As previously explained, ScrollRect in effect changes the coordinates of the document
relative to the local coordinates of the window. In terms of the window’s local coordinate
system, the upper-left corner of the document is now at (–100, 0), as shown on the right
side of Figure 5-16. To facilitate updating the window, the SurfWriter application uses the
QuickDraw procedure SetOrigin to change the local coordinate system of the window
so that the SurfWriter application can treat the upper-left corner of the document as again
lying at (0,0).
The SetOrigin procedure takes two parameters: the first is a new horizontal coordinate
for the window origin, and the second is a new vertical coordinate for the window origin.
IMPORTANT
Like ScrollRect, SetOrigin requires you to pass a horizontal
coordinate and then a vertical coordinate. Notice that when you
specify a point in the QuickDraw coordinate system, the opposite
is true: you name the vertical coordinate first and the horizontal
coordinate second. ▲
Any time you are ready to update a window (such as after scrolling it), you can use
GetControlValue to determine the current setting of the horizontal scroll bar and
pass this value as the new horizontal coordinate for the window origin. Then use
GetControlValue to determine the current setting of the vertical scroll bar and pass
this value as the new vertical coordinate for the window origin. Using SetOrigin in this
fashion shifts the window’s local coordinate system so that the upper-left corner of the
document is always at (0,0) when you redraw the document within its window.
For example, after the user manipulates the vertical scroll bar to move (either up or
down) to a location 100 pixels from the top of the document, the SurfWriter application
makes the following call:
SetOrigin(0, 100);
Although the scrolling distance was –100, which is relative, the current setting for the
scroll bar is now at 100. (Because you specify a point in the QuickDraw coordinate
system by its vertical coordinate first and then its horizontal coordinate, the order of
parameters to SetOrigin may be initially confusing.)
Control Manager
The left side of Figure 5-17 shows how the SurfWriter application uses the SetOrigin
procedure to move the window origin to the point (100,0) so that the upper-left corner of
the document is now at (0,0) in the window’s local coordinate system. This restores the
document’s original coordinate space and makes it easier for the application to draw in
the update region of the window.
After the application restores the document’s After the application updates the window’s
original coordinates contents
(0,0) (0,0)
(100,0) (100,0)
Update
region
(250,0) (250,0)
(350,0) (350,0)
After restoring the document’s original coordinates, the SurfWriter application updates
the window, as shown on right side of Figure 5-17. The application draws lines 16
through 24, which it stores in its document record as beginning at (160,0) and ending
at (250,0).
To review what has happened up to this point: the user has dragged the scroll box
one-half of the distance down the vertical scroll bar; the SurfWriter application
determines that this distance amounts to a scroll distance of –100 pixels; the SurfWriter
application passes this distance to ScrollRect, which shifts the bits in the window
100 pixels upward and creates an update region for the rest of the window; the
SurfWriter application passes the vertical scroll bar’s current setting (100 pixels) in a
parameter to SetOrigin so that the document’s local coordinates are used when the
update region of the window is redrawn; and, finally, the SurfWriter application draws
the text in the update region of the window.
However, the window origin cannot be left at (100,0); instead, the SurfWriter application
must use SetOrigin to reset it to (0,0) after performing its own drawing, because the
Control Manager
Window and Control Managers always assume the window’s upper-left point is at (0,0)
when they draw in a window. Figure 5-18 shows how the application uses SetOrigin to
set the window origin back to (0,0) at the conclusion of its window-updating routine.
After the update, the application begins processing events in its event loop again.
(0,0)
(150,0)
(250,0)
The left side of Figure 5-19 illustrates what happens when the user scrolls all the way
to the end of the document—a distance of another 10 lines, or 100 pixels. After the
SurfWriter application calls ScrollRect, the bottom 5 lines from the previous window
display appear at the top of the new window and the bottom of the window becomes
a new update region. Because the user has scrolled a total distance of 200 pixels, the
application uses SetOrigin to change the window origin to (200,0), as shown on the
right side of Figure 5-19.
The left side of Figure 5-20 shows the SurfWriter application drawing in the update
region of the window; the right side of the figure shows the SurfWriter application
restoring the window origin to (0,0).
Control Manager
After the application moves the document After the application restores the document’s
vertically by another —100 pixels original coordinates
(—200,0) (0,0)
(0,0) (200,0)
Update Update
region region
(150,0) (350,0)
Figure 5-20 Updating a window’s contents and returning the window origin to (0,0)
After the application updates the window’s After the application restores the window
contents origin to (0,0)
(0,0) (—200,0)
(200,0) (0,0)
(350,0) (150,0)
Control Manager
How your application determines a scrolling distance and how it then moves the bits in
the window by this distance are explained in greater detail in the next two sections,
“Scrolling in Response to Events in the Scroll Box” and “Scrolling in Response to Events
in Scroll Arrows and Gray Areas.” “Drawing a Scrolled Document Inside a Window,”
which follows these two sections, describes what your application should do in its
window-updating code to draw in a window that has been scrolled. You can find more
detailed information about the SetOrigin and ScrollRect procedures in Inside
Macintosh: Imaging.
So far, this discussion has assumed that you are scrolling in response to the user’s
manipulation of a scroll bar. Most of the time, the user decides when and where to scroll.
However, in addition to user manipulation of scroll bars, there are four cases in which
your application must scroll through the document. Your application design must take
these cases into account.
■ When your application performs an operation whose side effect is to make a new
selection or move the insertion point, you should scroll to show the new selection. For
example, when the user invokes a search operation, your application locates the
desired text. If this text appears in a part of the document that isn’t currently visible,
you should scroll to show the selection. Such scrolling might also be necessary after
the user invokes a paste operation. If the insertion point appears after the end of
whatever was pasted, scroll until the selection and the new insertion point are visible.
■ When the user enters information from the keyboard at the edge of a window, you
should scroll to incorporate and display the new information. The user’s focus will be
on the new information, so it doesn’t make sense to maintain the document’s position
and record the new information out of the user’s view. In general, a word processor
scrolls one line of text, and a database or spreadsheet scrolls one field. Graphics
applications should scroll to display an entire object when possible. Otherwise,
determine how quickly your application can redraw the window contents during
scrolling and adjust the scrolling to minimize blinking and redrawing. Try to ensure
that the scrolling is sufficiently fast so as not to annoy users but not so fast as to
confuse them.
■ When the user moves the cursor past the edge of the window while holding down the
mouse button to make an extended selection, you should scroll the window in the
direction of cursor movement. The rate of scrolling can be the same as if the user were
holding down the mouse button on the corresponding scroll arrow. In some cases it
makes sense to vary the scrolling speed so that it is faster as the user moves the cursor
farther away from the edge of the window.
■ Sometimes the user selects something, scrolls to a new location, and then tries to
perform an operation on the selection. In this case, you should scroll so that the
selection is showing before your application performs the operation. Showing the
selection makes it clear to the user what is being changed.
When designing the document-scrolling routines for your application, also try to keep
the following user interface guidelines in mind:
■ Whenever your application scrolls automatically, avoid unnecessary scrolling. Users
want to control the position of documents, so your application should move a
document only as much as necessary. Thus, if part of a selection is already showing in
a window, don’t scroll at all. One exception to this rule is when the hidden part of the
Control Manager
selection is more important than the visible part; then scroll to show the important
part. For example, suppose a user selects a large block of text and only the bottom is
currently visible. If the user then types a character, your application must scroll to the
location of the newly typed characters so that they are visible.
■ If your application can scroll in one orientation to reveal the selection, don’t scroll in
both orientations. That is, if you can scroll vertically to show the selection, don’t also
scroll horizontally.
■ When you can show context on either side of a selection, it’s useful to do so. It’s
also better to position a selection somewhere near the middle of a window than
against a corner. When the selection is too large to fit in the window, it’s helpful to
display unselected information at either the beginning or the end of the selection
to provide context.
Control Manager
When the user presses the mouse button while the cursor is in a visible, active scroll box,
FindControl returns as its result the part code for a scroll box. That part code and the
constant you can use to represent it are listed here:
As shown in Listing 5-18, when FindControl returns the value for inThumb, your
application should immediately call GetControlValue to determine the current setting
of the scroll bar. If the user drags the scroll box, you subtract from this setting the new
current setting that becomes available when the user releases the mouse button, and you
use this result for your scrolling distance.
Control Manager
After using GetControlValue to determine the current setting of the scroll bar, use
TrackControl to follow the movements of the cursor inside the scroll box and to drag a
dotted outline of the scroll box in response to the user’s movements.
When the user releases the mouse button, TrackControl returns inThumb if the cursor
is still in the scroll box or 0 if the cursor is outside the scroll box. When TrackControl
returns 0, your application does nothing. Otherwise, your application again uses
GetControlValue to calculate the distance to scroll.
Calculate the distance to scroll by calling GetControlValue and subtracting the new
current setting of the scroll bar from its previous setting, which you determine by calling
GetControlValue before the user releases the mouse button. If this distance is not 0,
you should move the bits in the window by this distance and update the contents of the
rest of the window.
Before scrolling, you must determine if the scroll bar is a vertical scroll bar or a horizon-
tal scroll bar. As previously explained in this chapter, you should store handles to your
scroll bars in a document record, one of which you create for every document. By
comparing the field containing the vertical scroll bar handle, you can determine whether
the control handle returned by FindControl is the handle to the vertical scroll bar. If so,
the user has moved the scroll box of the vertical scroll box. If not, the user has moved the
scroll box of the horizontal scroll bar.
After determining which scroll bar contains the scroll box that the user has dragged, you
move the document contents of the window by the appropriate scrolling distance. That
is, for a positive scrolling distance in the vertical scroll bar, move the bits in the window
down by that distance. When you update the window, this displays more lines from the
top of the document—which is appropriate when the user moves the scroll box up. For a
positive scrolling distance in the horizontal scroll bar, move the bits in the window to the
right by that distance. When you update the window, this displays more lines from the
left side of the document—which is appropriate when the user moves the scroll box to the
left. (Remember: to scroll up or left, move the document down or right, both of which are
in the positive direction.)
For a negative scrolling distance in the vertical scroll bar (such as that shown in
Figure 5-16 on page 5-46), move the bits in the window up by that distance. When you
update the window, this displays more lines from the bottom of the document—which
is appropriate when the user moves the scroll box down. For a negative scrolling distance
in the horizontal scroll bar, move the bits in the window to the left by that distance. When
you update the window, this displays more lines from the right side of the document—
which is appropriate when the user moves the scroll box to the right. (Remember: to scroll
down or right, move the document up or left, both of which are in the negative
direction.)
The previous examples in this chapter have shown an application that uses a TextEdit
edit record to store monostyled text created by the user. For simple text-handling
needs, TextEdit provides many routines that simplify your work; for example, the
TEPinScroll procedure scrolls through the text in the view rectangle of an edit record
by the number of pixels specified by your application; TEPinScroll stops scrolling
when the last line scrolls into the view rectangle.
Control Manager
The TEPinScroll procedure takes three parameters: the number of pixels to move the
text horizontally, the number of pixels to move the text vertically, and a handle to an edit
record. Positive values in the first two parameters move the text right and down,
respectively, and negative values move the text left and up.
The DoContentClick procedure, illustrated in Listing 5-18 on page 5-53, passes the
scrolling distance in the second parameter of TEPinScroll for a vertical scroll bar, and
it passes the scrolling distance in the first parameter for a horizontal scroll bar.
Listing 5-16 on page 5-41 shows an application-defined routine, MyAdjustHV, called by
the SurfWriter sample application whenever it creates, opens, or resizes a window. This
routine defines the current and maximum settings for a vertical scroll bar in terms of lines
of text.
The DoContentClick procedure on page 5-53 uses GetControlValue to determine
the control’s current setting—which for the vertical scroll bar DoContentClick
calculates as some number of lines. When determining the vertical scroll bar’s scrolling
distance, DoContentClick again calculates a value representing some number of lines.
However, TEPinScroll expects pixels, not lines, to be passed in its parameters. There-
fore, DoContentClick multiplies the scrolling distance (which it calculates as some
number of lines of text) by the line height (which is maintained in the edit record for
monostyled text as some number of pixels). In this way, DoContentClick passes a
scrolling distance—in terms of pixels—to TEPinScroll, as shown in this code fragment.
Figure 5-16 on page 5-46 illustrates a scrolling distance of –10 lines. If the line height
is 10 pixels, the SurfWriter application passes –100 as the second parameter to
TEPinScroll.
The TEPinScroll procedure adds the scrolled-away area to the update region and
generates an update event so that the text in the edit record’s view rectangle can be
updated. In its code that handles update events for windows, the SurfWriter sample
application then uses the TEUpdate procedure—as described in “Drawing a Scrolled
Document Inside a Window” beginning on page 5-62— for its windows that include
TextEdit edit records.
To learn more about TEPinScroll, the TextEdit edit record, and other facilities offered
by TextEdit, see Inside Macintosh: Text.
The QuickDraw procedure ScrollRect is a more general-purpose routine for moving
bits in a window when scrolling. If you use ScrollRect to scroll the bits displayed
in the window, you should define a routine like DoGraphicsScroll, shown in
Listing 5-17 on page 5-47, and use it instead of TEPinScroll, which is used in
Listing 5-18 on page 5-53.
The ScrollRect procedure returns in the updateRegion parameter the area that
needs to be updated. The DoGraphicsScroll procedure shown in Listing 5-17 on
page 5-47 then uses the QuickDraw procedure InvalRgn to add this area to the update
Control Manager
region, forcing an update event. In your code for handling update events, you draw in
the area of the window from which ScrollRect has moved the bits, as described in
“Drawing a Scrolled Document Inside a Window” beginning on page 5-62.
When a mouse-down event occurs in the scroll arrows or gray areas of the vertical
scroll bar, the DoContentClick routine in Listing 5-18 on page 5-53 calls
TrackControl and passes it a pointer to an application-defined action procedure
called MyVerticalActionProc. For the horizontal scroll bar, DoContentClick
calls TrackControl and passes it a pointer to an action procedure called
MyHorzntlActionProc. These action procedures are described in the next section.
Control Manager
When FindControl returns one of these part codes, your application should
immediately call TrackControl. As long as the user holds down the mouse button
while the cursor is in a scroll arrow, TrackControl highlights the scroll arrow,
as shown in Figure 5-8 on page 5-12. When the user releases the mouse button,
TrackControl removes the highlighting.
For all of the other standard controls, as well as for the scroll box in a scroll bar, your
application doesn’t respond until TrackControl reports a mouse-up event in the same
control part where the mouse-down event initially occurred. However, for scroll arrows
and gray areas, your application must respond by scrolling the document before
TrackControl reports that the user has released the mouse button. When you call
TrackControl for scroll arrows and gray areas, you must define an action procedure
that scrolls appropriately until TrackControl reports that the user has released the
mouse button.
When the user releases the mouse button or moves the cursor away from the scroll arrow
or gray area, TrackControl returns as its result one of the previously listed values that
represent the control part. As shown in Listing 5-18 on page 5-53, the DoContentClick
procedure tests for the part codes inUpButton, inDownButton, inPageUp, and
inPageDown to determine when a mouse-down event occurs in a
scroll arrow or a gray area.
When the user presses or holds down the mouse button while the cursor is in either
the scroll arrow or the gray area of the vertical scroll bar, DoContentClick calls
TrackControl and passes it a pointer to an application-defined action procedure
called MyVerticalActionProc. For the horizontal scroll bar, DoContentClick
calls TrackControl and passes it a pointer to an action procedure called
MyVerticalActionProc. In turn, TrackControl calls these action procedures to
scroll continuously until the user releases the mouse button.
Note
As an alternative to passing a pointer to your action procedure
in a parameter to TrackControl, you can use the SetControlAction
procedure to store a pointer to the action procedure in the
contrlAction field in the control record. When
you pass Pointer(–1) instead of a procedure pointer to
TrackControl, TrackControl uses the action procedure
pointed to in the control record. ◆
Listing 5-19 shows two sample action procedures: MyVerticalActionProc—which
responds to mouse events in the scroll arrows and gray areas of a vertical scroll bar—
and MyHorzntlActionProc—which responds to those same events in a horizontal
scroll bar. When TrackControl calls these action procedures, it passes a control handle
and an integer representing the part of the control in which the mouse event occurred.
Both MyVerticalActionProc and MyHorzntlActionProc use the constants
inUpButton, inDownButton, inPageUp, and inPageDown to test for the control part
passed by TrackControl.
Control Manager
Control Manager
myData := MyDocRecHnd(GetWRefCon(window));
HLock(Handle(myData));
CASE part OF
inUpButton, inDownButton: {get a few pixels}
scrollDistance := kButtonScroll;
inPageUp, inPageDown: {get a window's width}
scrollDistance := myData^^.editRec^^.viewRect.right -
myData^^.editRec^^.viewRect.left;
END; {of part CASE}
IF (part = inDownButton) OR (part = inPageDown) THEN
scrollDistance := -scrollDistance;
MyMoveScrollBox(control, scrollDistance);
IF scrollDistance <> 0 THEN
TEPinScroll(scrollDistance, 0, myData^^.editRec);
HUnLock(Handle(myData));
END;
END; {of MyHorzntlActionProc}
Control Manager
scrolling a simple monostyled text document stored as a TextEdit edit record. For
a discussion of using the more general-purpose QuickDraw scrolling routine
ScrollRect, see the previous section, “Scrolling in Response to Events in the Scroll
Box” beginning on page 5-53.)
The TEPinScroll procedure automatically creates an update region and invokes an
update event. In its window-updating code, the SurfWriter application uses the
TEUpdate procedure to draw the text in the update region, as shown in Listing 5-23 on
page 5-65.
The action procedures continue moving the text by the specified distances over and over
until the user releases the mouse button and TrackControl completes. If there is no
more area to scroll through, TEPinScroll automatically stops scrolling, as your
application should if you implement your own scrolling routine.
Listing 5-20 shows how the application-defined procedure MyMoveScrollBox uses
GetControlValue, GetControlMaximum, and SetControlValue to move the scroll
box an appropriate distance while the action procedures scroll through the document.
The MyMoveScrollBox procedure uses GetControlMaximum to determine the
maximum scrolling distance, GetControlValue to determine the current setting for the
scroll box, and SetControlValue to assign the new setting and move the scroll box.
Use of the SetControlMaximum and SetControlValue routines is described in
“Determining and Changing Control Settings” beginning on page 5-37;
GetControlMaximum is described in detail on page 5-104.
Listing 5-20 Moving the scroll box from the action procedures
The previous two sections have described how to move the bits displayed in the window;
the next section describes how to draw into the update region.
Control Manager
Control Manager
Control Manager
Notice that MyDrawGraphicsWindow calls SetOrigin only after calling the necessary
Window Manager and Control Manager routines, because the Window Manager and
Control Manager always expect the window origin to be at (0,0).
By using SetOrigin to change the window origin, MyDrawGraphicsWindow can treat
the objects in its document as being located in a coordinate system where the upper-left
corner of the document is always at (0,0). Then MyDrawGraphicsWindow calls another
of its own routines, DrawMyObjects, to draw the objects it has stored in its document
record for the window.
After performing all its own drawing in the window, MyDrawGraphicsWindow again
uses SetOrigin—this time to reset the window origin to (0,0) so that future Window
Manager and Control Manager routines will draw into the correct area of the window.
Figure 5-16 through Figure 5-20 earlier in this chapter help to illustrate how to use
SetOrigin to offset the window’s coordinate system so that you can treat the objects
in your document as fixed in the document’s own coordinate space. However, it is not
necessary for your application to use SetOrigin. Your application can leave the
window’s coordinate system fixed and instead offset the items in your document by the
amount equal to the scroll bar settings. The QuickDraw procedures OffsetRect,
OffsetRgn, SubPt, and AddPt, which are described in Inside Macintosh: Imaging,
are useful if you pursue this approach.
Note
The SetOrigin procedure does not move the window’s clipping region.
If you use clipping regions in your windows, use the QuickDraw
procedure GetClip to store your clipping region immediately after your
first call to SetOrigin. Before calling your own window-drawing
routine, use the QuickDraw procedure ClipRect to define a new
clipping region—to avoid drawing over your scroll bars, for example.
After calling your own window-drawing routine, use the QuickDraw
procedure ClipRect to restore the original clipping region. You
can then call SetOrigin again to restore the window origin to (0,0) with
your original clipping region intact. See Inside Macintosh:
Imaging for detailed descriptions of clipping regions and of these
QuickDraw routines. ◆
The previous examples in this chapter have shown an application that uses a TextEdit
edit record to store the information created by the user. For simple text-handling
needs, TextEdit provides many routines that simplify your work; for example, the
TEPinScroll procedure (used in Listing 5-18 on page 5-53 and Listing 5-19 on
page 5-59) resets the view rectangle of text stored in an edit record by the amount of
pixels specified by the application. The TEPinScroll procedure then generates an
update event for the window. The TextEdit procedure TEUpdate should then be called in
an application’s update routine to draw the update region of the scrolled window.
Listing 5-23 shows an application-defined procedure, MyDrawWindow, that uses
TEUpdate to update the text in windows of type kMyDocWindow. The TEUpdate
procedure manages all necessary shifting of coordinates during window updating, so
MyDrawWindow does not have to call SetOrigin as it does when it uses ScrollRect.
Control Manager
Control Manager
6. Use the ShowControl procedure to make each scroll bar visible in its new location.
Figure 5-21 illustrates how to move and resize scroll bars in a resized window; if your
application neglected to use the HideControl procedure, the user would see each of
these steps as it took place.
Control Manager
Listing 5-24 Changing the size and location of a window’s scroll bars
CONST
kScrollbarWidth = 16; {conventional width}
kScrollbarAdjust = kScrollbarWidth - 1; {to align with window frame}
kScrollTweek = 2; {to align scroll bars with size box}
Control Manager
Control Manager
Figure 5-22 A vertical scroll bar before the application moves it within a resized window
1 pixel
(–1,270) (0,300)
(–1,285)
16 pixels
Figure 5-23 A vertical scroll bar after the application moves its upper-left point
1-pixel overlap
(–1,285) (0,300)
16 pixels
1-pixel overlap
Control Manager
Control Manager
Note
When you design a dial or slider, be sure to include meaningful labels
that indicate to users the range and the direction of the indicator. ◆
Rather than create such a control yourself, you might be tempted to use a scroll bar for
this purpose. Do not do so. Using a scroll bar for any purpose other than scrolling
through a window compromises the consistency of the Macintosh interface.
To define your own nonstandard control, you must write a control definition function,
compile it as a resource of type 'CDEF', and include it in your resource file. (For more
information about creating resources, see the chapter “Resource Manager” in Inside
Macintosh: More Macintosh Toolbox.)
Control Manager
When you use Control Manager routines, they in turn call your control definition
function as necessary. For example, for the control in Figure 5-24 to work properly, its
control definition function must be able to
■ draw the control—including repositioning its indicator, making it inactive or active,
and highlighting its control parts appropriately when mouse events occur in them
■ determine when a mouse-down event occurs in a control part
■ calculate the region of the control and its indicator
■ move the indicator and update the control record with a new setting
You can also use your control definition function to modify or expand certain Control
Manager behaviors; for example, you can implement your own manner of dragging an
indicator, and you can perform your own type of control initialization.
For details about writing a control definition function, see “Defining Your Own Control
Definition Function” beginning on page 5-109.
Data Structures 5
This section describes the control record, the auxiliary control record, the pop-up menu
private data record, and the control color table record.
Your application doesn’t specifically create the control record, the auxiliary control
record, or the pop-up menu private data record; rather, your application simply
creates any necessary resources and uses the appropriate Control Manager routines.
The Control Manager creates these records as necessary.
Control Manager 5
You can use Control Manager routines to change values in the control record, or you
can access and change its fields yourself; normally, you don’t change the values in
the auxiliary control record. However, both the control record and the auxiliary
control record have fields in which your application can store information as you
deem appropriate.
You can obtain the menu handle and the menu ID of the menu associated with a pop-up
menu by dereferencing the contrlData field of the control record, which, for pop-up
menu controls, contains a handle to a pop-up private data record. This record contains
the menu handle and the menu ID for the associated menu.
You use a control color table record only when you want to use nonstandard colors for a
control that you create while your application is running. Your application probably
shouldn’t ever create a control color table record because you should use the system’s
default colors to ensure consistency of the interface across applications.
TYPE ControlRecord =
PACKED RECORD
nextControl: ControlHandle; {next control}
contrlOwner: WindowPtr; {control's window}
contrlRect: Rect; {rectangle}
contrlVis: Byte; {255 if visible}
contrlHilite: Byte; {highlight state}
contrlValue: Integer; {control's current setting}
contrlMin: Integer; {control's minimum setting}
contrlMax: Integer; {control's maximum setting}
contrlDefProc: Handle; {control definition function}
contrlData: Handle; {data used by contrlDefProc}
contrlAction: ProcPtr; {action procedure}
contrlRfCon: LongInt; {control's reference value}
contrlTitle: Str255; {control's title}
END;
Control Manager
Field descriptions
nextControl A handle to the next control associated with this control’s window.
All the controls belonging to a given window are kept in a linked
list, beginning in the controlList field of the window record and
chained together through the nextControl fields of the individual
control records. The end of the list is marked by a NIL value; as new
controls are created, they’re added to the beginning of the list.
contrlOwner A pointer to the window to which this control belongs.
contrlRect The rectangle that completely encloses the control, in the local
coordinates of the control’s window. You can use the MoveControl
and SizeControl procedures to change the rectangle stored in this
field.
contrlVis The invisible/visible state for the control. When the value of this
field is 0, the Control Manager does not draw the control (its state is
invisible); when the value of this field is 255, the Control Manager
draws the control (its state is visible). Note that even when a control
is visible, it might still be obscured from sight by an overlapping
window or some other object. You can use the HideControl
procedure to change this field from visible to invisible, and you can
use the ShowControl procedure to change this field from invisible
to visible.
contrlHilite Specifies whether and how the control is to be displayed, indicating
whether it’s active or inactive and, if active, whether it’s selected.
The value of 0 signifies an active control that is not selected. A value
from 1 through 253 signifies a part code designating the part of
the (active) control to highlight, indicating that the user is pressing
the mouse button while the cursor is in that part. The value
255 signifies that the control is to be made inactive and drawn
accordingly. The HiliteControl procedure lets you change the
value of this field.
contrlValue The control’s current setting. For buttons, checkboxes, and radio
buttons, 0 means the control is off and 1 means it’s on. For scroll bars
and other sliders, contrlValue may take any value within the
range specified in the contrlMin and contrlMax fields. For
pop-up menus, this value is the item number of the menu item
chosen by the user; if the user hasn’t chosen a menu item, it is the
item number of the first menu item. For other controls, you can use
this field as you wish. You can use the GetControlValue function
to determine the value of this field, and you can use the
SetControlValue procedure to change the value of this field.
contrlMin The control’s minimum possible setting. For on-and-off controls—
like checkboxes and radio buttons—this value should be 0 (meaning
that the control is off). For scroll bars and other sliders, this can be
any appropriate minimum value. For controls—like buttons—
that don’t retain a setting, this value should be 0. For pop-up menus,
the Control Manager sets this field to 1. For other
controls, you can use this field as you wish. You can use the
GetControlMinimum function to determine the value of this field,
and you can use the SetControlMinimum procedure to change the
value of this field.
Control Manager
contrlMax The control’s maximum possible setting. For on-and-off controls like
checkboxes and radio buttons, this value should be 1 (meaning that
the control is on). For scroll bars and other sliders, this can be any
appropriate maximum value. When you make the maximum setting
of a scroll bar equal to its minimum setting, the control definition
function automatically makes the scroll bar inactive. When you
make the maximum setting exceed the minimum, the control
definition function makes the scroll bar active again. For controls—
like buttons—that don’t retain a setting, this value should be 1. For
pop-up menus, the Control Manager sets this value to the number of
items in the menu. For other controls, you can use this field as you
wish. You can use the GetControlMaximum function to determine
the value of this field, and you can use the SetControlMaximum
procedure to change the value of this field.
contrlDefProc A handle to the control definition function for this type of
control. When you create a control, you identify its type with
a control definition ID, which is converted into a handle to the
control definition function and stored in this field. Thereafter,
the Control Manager uses this handle to access the definition
function; you should never need to refer to this field directly.
Note
In systems running in 24-bit mode, the high-order byte of the
contrlDefProc field contains the variant, which the Control
Manager gets from the control definition ID. ◆
contrlData Reserved for use by the control definition function, typically to hold
additional information specific to a particular control type. For
example, the control definition function for scroll bars uses this field
for a handle to the region containing the scroll box. (If no more than
4 bytes of additional information are needed, the definition function
may store the information directly in the contrlData field rather
than using a handle.) The control definition function for pop-up
menus uses this field to store a pop-up private data record, which is
described on page 5-77.
contrlAction A pointer to the control’s action procedure, if any. The
TrackControl function may call this procedure to respond to
the user’s dragging of the control, and this procedure responds
by repeatedly performing some action as long as the user holds
down the mouse button. See the description of TrackControl
on page 5-90 for more information about the action procedure.
You can use the GetControlAction function to determine the
current value of this field and the SetControlAction procedure
to change it.
contrlRfCon The control’s reference value, which your application may use
for any purpose. You can use the GetControlReference
function to determine the current value of this field and the
SetControlReference procedure to change it.
contrlTitle The control title, if any. You can use the GetControlTitle
procedure to determine the current value of this field and the
SetControlTitle procedure to change it.
Control Manager
TYPE AuxCtlRec =
RECORD
acNext: AuxCtlHandle; {handle to next AuxCtlRec}
acOwner: ControlHandle; {handle to this record's control}
acCTable: CCTabHandle; {handle to control color table }
{ record}
acFlags: Integer; {reserved}
acReserved: LongInt; {reserved for future use}
acRefCon: LongInt; {for use by application}
END;
Field descriptions
acNext A handle to the next record in the auxiliary control list.
acOwner The handle of the control to which this auxiliary record belongs;
used as an ID field.
acCTable The handle to a control color table record. (The control color table
record is described on page 5-77.)
acFlags Reserved for use by the Control Manager.
acReserved Reserved for future expansion.
acRefCon A reference value, which your application may use for any purpose.
On systems using 32-bit mode, every control has its own auxiliary record, and
the acCTable field contains a handle to the default control color table unless
your application uses the SetControlColor procedure or creates a control color
table resource.
Control Manager
When drawing a control, the standard control definition functions search the linked list of
auxiliary control records for the auxiliary control record whose acOwner field points to
the control being drawn. If the standard control definition functions find an auxiliary
control record for the control, they use the control color table specified in the acCTable
field. If the standard control definition functions do not find an auxiliary control record
for the control, they use the default system colors.
TYPE popupPrivateData =
RECORD
mHandle: MenuHandle; {handle to menu record}
mID: Integer; {menu ID}
mPrivate: ARRAY[0..0] OF SignedByte; {reserved}
END;
Field descriptions
mHandle Contains a handle to the menu.
mID The menu ID of the menu.
mPrivate Reserved.
You can use the standard pop-up control definition function to manage pop-up menus.
For information on creating pop-up menus, see “Creating a Pop-Up Menu” beginning on
page 5-25. See the chapter “Menu Manager” in this book for additional information.
TYPE CtlCTab =
RECORD
ccSeed: LongInt; {reserved; set to 0}
ccRider: Integer; {reserved; set to 0}
Control Manager
Field descriptions
ccSeed Reserved in control color tables; set to 0.
ccRider Reserved in control color tables; set to 0.
ctSize The number of ColorSpec records in the next field. For controls
drawn with the standard definition procedure, this field is always 3,
because a standard control has three parts: frame, control body, and
scroll box for scroll bars, and frame, control body, and text for other
controls. If you want to supply ColorSpec records for additional
parts, you must define your own controls, as described in “Defining
Your Own Control Definition Function” beginning on page 5-109.
ctTable An array of ColorSpec records. Each ColorSpec record describes
the color of a different control part. Here is how a ColorSpec
record is defined:
TYPE ColorSpec =
RECORD
partIdentifier: Integer; {control part}
partRGB: RGBColor; {color of part}
END;
Control Manager
When highlighted, scroll arrows are filled with the foreground color.
A deactivated scroll bar shows no scroll box and displays its gray
areas in a solid background color with no pattern.
The ColorSpec records for a control can appear in any order. If you
include a part identifier that is not found, the Control Manager uses
the first ColorSpec record with an identifiable part. If you do not
specify a part identifier, the Control Manager uses the default color
for that part.
The partRGB field of the ColorSpec record specifies an RGBColor
record, which in turn specifies the red, green, and blue values for the
part’s color. Use three 16-bit unsigned integers to give the intensity
values for the three additive primary colors. Here is how the
RGBColor record is defined:
TYPE RGBColor =
RECORD
red: Integer; {red value for control part}
green: Integer; {green value for control part}
blue: Integer; {blue value for control part}
END;
When you create a control color table record, your application should not deallocate it if
another control is still using it.
When drawing a control, the standard control definition functions search the linked list of
auxiliary control records for the record whose acOwner field points to that control.
If a standard control definition function finds such a record, it uses the color table
designated by that record; otherwise, it uses the default system colors. Each control using
Control Manager
colors other than the system default has its own auxiliary control record, even if that
control uses the same control color table record as another control; two or more auxiliary
records can share the same control color table record. (Auxiliary control records are
described on page 5-76.)
If you create a control definition function (as explained in “Defining Your Own Control
Definition Function” beginning page 5-109), you can use color tables of any desired size
and define their contents in any way you wish, except that part indices 1 through 127 are
reserved for system definition. Any such nonstandard control definition function should
bypass the defaulting mechanism by allocating an explicit auxiliary record for every
control it creates.
Table 5-1 Mapping between new and previous names of Control Manager routines
Control Manager
Creating Controls 5
To create a control, you should generally use the GetNewControl function, which takes
information about the control from a control resource. Like menu resources, control
resources isolate descriptive information from your application code, making your
application easier to modify or translate. However, you can also use the NewControl
function—for which you pass descriptive information in parameters—to create controls.
Both GetNewControl and NewControl return a handle to the control record of the
newly created control. Thereafter, your application normally refers to the control by this
handle, because most other Control Manager routines expect a control handle as their
first parameter. When you create scroll bars and pop-up menus, you should store their
handles in one of your application’s own data structures for later reference.
When you use the Dialog Manager to implement buttons, radio buttons, checkboxes, and
pop-up menus in alert boxes and dialog boxes, the Dialog Manager automatically uses
the Control Manager to create these controls for you. If you implement other controls in
alert or dialog boxes, and whenever you implement controls—such as scroll bars—in
your application’s windows, you must use either GetNewControl or NewControl to
create these controls.
GetNewControl 5
DESCRIPTION
The GetNewControl function creates a control record from the information in the
specified control resource, adds the control record to the control list for the specified
window, and returns as its function result a handle to the control. You use this handle
when referring to the control in most other Control Manager routines. After making a
copy of the control resource, GetNewControl releases the memory occupied by the
original control resource before returning.
If you provide a control color table resource with the same resource ID as the control
resource, GetNewControl creates an auxiliary control record that uses the colors you
specify in your control color table resource. If you don’t provide a control color table,
GetNewControl creates an auxiliary control record that uses the default control color
table if the computer is running in 32-bit mode.
Control Manager
The control resource specifies the rectangle for the control, its initial setting, its visibility
state, its maximum and minimum settings, its control definition ID, a reference value,
and its title (if any). After you use GetNewControl to create the control, you can change
the current setting, the maximum setting, the minimum setting, the reference value, and
the title by using, respectively, the SetControlValue, SetControlMaximum,
SetControlMinimum, SetControlReference, and SetControlTitle procedures.
You can use the MoveControl and SizeControl procedures to change the control’s
rectangle. You can use the GetControlValue, GetControlMaximum,
GetControlMinimum, GetControlReference, and GetControlTitle functions to
determine the control values.
If the control resource specifies that the control should be visible, the Control Manager
draws the control. If the control resource specifies that the control should initially be
invisible, you can use the ShowControl procedure to make the control visible.
If GetNewControl can’t read the control resource from the resource file,
GetNewControl returns NIL.
SEE ALSO
See Listing 5-1 on page 5-17 and Listing 5-5 on page 5-24 for examples of how to use
GetNewControl to create, respectively, a button and a scroll bar. For information about
windows’ control lists, see the chapter “Window Manager” in this book.
NewControl 5
To create a control, you can use the NewControl function, which accepts in its
parameters the information that describes the control. Generally, you should instead use
the GetNewControl function to create a control. The GetNewControl function takes
information about the control from a control resource, and as a result your application is
easier to modify or translate into other languages.
theWindow A pointer to the window in which you want to attach the control. All
coordinates pertaining to the control are interpreted in this window’s local
coordinate system.
boundsRect The rectangle, specified in the given window’s local coordinates, that
encloses the control and thus determines its size and location.
Control Manager
title For controls that need a title—such as buttons, checkboxes, radio buttons,
and pop-up menus—the string for that title. For controls that don’t use
titles, pass an empty string.
visible The visible/invisible state for the control. If you pass TRUE in this
parameter, NewControl draws the control immediately, without using
your window’s standard updating mechanism. If you pass FALSE, you
must later use the ShowControl procedure to display the control.
value The initial setting for the control. For controls—such as buttons—that
don’t retain a setting, pass 0 in this parameter. For controls—such as
checkboxes and radio buttons—that retain an on-or-off setting, pass 0 in
this parameter for a control that is off, and pass 1 for a control that is on.
For controls—such as scroll bars and sliders—that can take a range of
settings, specify whatever value is appropriate within that range.
min The minimum setting for the control. For controls—such as buttons—that
don’t retain a setting, pass 0 in this parameter. For controls—such as
checkboxes and radio buttons—that retain an on-or-off setting, use 0
(meaning “off”) for the minimum value. For controls—such as scroll bars
and sliders—that can take a range of settings, specify whatever minimum
value is appropriate.
max The maximum setting for the control. For controls—such as buttons—that
don’t retain a setting, pass 1 in this parameter. For controls—such as
checkboxes and radio buttons—that retain an on-or-off setting, use 1
(meaning “on”) for the maximum value. For controls—such as scroll bars
and sliders—that can take a range of settings, specify whatever maximum
value is appropriate. When you make the maximum setting of a scroll bar
equal to its minimum setting, the control definition function automatically
makes the scroll bar inactive; when you make the maximum setting
exceed the minimum, the control definition function makes the scroll bar
active again.
procID The control definition ID, which leads to the control definition function for
this type of control. The control definition function is read into memory if
it isn’t already in memory. The control definition IDs and their constants
for the standard controls are listed here. (You can also define your own
control definition function and specify it the procID parameter.)
CONST
pushButProc = 0; {button}
checkBoxProc = 1; {checkbox}
radioButProc = 2; {radio button}
useWFont = 8; {add to above to display }
{ title in window font}
scrollBarProc = 16; {scroll bar}
popupMenuProc = 1008; {pop-up menu}
popupFixedWidth = $0001; {add to popupMenuProc to }
{ use a fixed-width ctrl}
Control Manager
{ specify a value of }
{ type ResType in the }
{ contrlRfCon field of }
{ the control record; }
{ Menu Manager adds }
{ resources of this type }
{ to the menu}
popupUseWFont = $0008; {add to popupMenuProc to }
{ display in window font}
refCon The control’s reference value, which is set and used only by
your application.
DESCRIPTION
The NewControl function creates a control record from the information you specify in
its parameters, adds the control record to the control list for the specified window, and
returns as its function result a handle to the control. You use this handle when referring
to the control in most other Control Manager routines.
The NewControl function creates an auxiliary control record that uses the default
control color table if the computer is running in 32-bit mode.
If you need to use colors other than the default colors for the control, create a control
color table record and use the SetControlColor procedure.
When specifying the rectangle in the boundsRect parameter, keep the following
guidelines in mind:
■ Buttons are drawn to fit the rectangle exactly. To accommodate the tallest characters in
the system font, allow at least a 20-point difference between the top and bottom
coordinates of the rectangle.
■ For checkboxes and radio buttons, there should be at least a 16-point difference
between the top and bottom coordinates.
■ By convention, scroll bars are 16 pixels wide, so there should be a 16-point difference
between the left and right (or top and bottom) coordinates. (If there isn’t, the scroll bar
is scaled to fit the rectangle.) A standard scroll bar should be at least 48 pixels long, to
allow room for the scroll arrows and scroll box.
The Control Manager displays control titles in the system font. When specifying a title for
the control in the title parameter, make sure the title fits in the control’s rectangle;
otherwise, NewControl truncates the title. For example, NewControl truncates the
titles of checkboxes and radio buttons on the right in Roman scripts, and it centers and
truncates both ends of the button titles.
The Control Manager allows multiple lines of text in the titles of buttons, checkboxes, and
radio buttons. When specifying a multiple-line title, separate the lines with the ASCII
character code $0D (carriage return). If the control is a button, each line is horizontally
centered, and the font leading is inserted between lines. (The height of each line is equal
to the distance from the ascent line to the descent line plus the leading of the font used.
Control Manager
Be sure to make the total height of the rectangle greater than the number of lines times
this height.) If the control is a checkbox or a radio button, the text is justified as
appropriate for the user’s current script system, and the checkbox or button is vertically
centered within its rectangle.
After you use NewControl to create the control, you can change the current setting,
the maximum setting, the minimum setting, the reference value, and the title by using,
respectively, the SetControlValue, SetControlMaximum, SetControlMinimum,
SetControlReference, and SetControlTitle procedures. You can use the
MoveControl and SizeControl procedures to change the control’s rectangle. You
can use the GetControlValue, GetControlMaximum, GetControlMinimum,
GetControlReference, and GetControlTitle functions to determine the
control values.
SPECIAL CONSIDERATIONS
The title of a button, checkbox, radio button, or pop-up menu normally appears in the
system font, which in Roman script systems is 12-point Chicago. Do not use a smaller
font; some script systems, such as KanjiTalk, require 12-point fonts. You should generally
use the system font in your controls; doing so will simplify localization effort. However,
if you absolutely need to display a control title in the font currently associated with the
window’s graphics port, you can add the popupUseWFont constant to the pop-up menu
control definition ID or add the useWFont constant to the other standard control
definition IDs.
SEE ALSO
For information about windows’ control lists, see the chapter “Window Manager” in
this book. Control definition IDs for other controls are discussed in “Defining Your Own
Control Definition Function” beginning on page 5-109.
Drawing Controls 5
If you specify that a control is initially visible (either in the control resource or in a
parameter to NewControl), the Control Manager draws the control inside its window
when you call either the GetNewControl or the NewControl function. In either case,
the Control Manager draws the control immediately, without using your window’s
standard updating mechanism. If you specify that a control is invisible, you can use the
ShowControl procedure when you want to draw the control.
Note that even a visible control might be completely or partially obscured by overlapping
windows or other objects.
When your application receives an update event for a window that contains controls,
use UpdateControls to redraw the necessary controls in the updated window. Note
that the Dialog Manager automatically draws and updates controls in alert boxes and
dialog boxes.
Control Manager
ShowControl 5
To draw a control that is currently invisible, you can use the ShowControl procedure.
DESCRIPTION
If the specified control is invisible, the ShowControl procedure makes it visible and
immediately draws the control within its window without using your window’s
standard updating mechanism. If the control is already visible, ShowControl has
no effect.
You can make a control invisible in several ways:
■ You can specify that it’s invisible in its control resource.
■ You can specify that it’s invisible in a parameter to the NewControl function.
■ You can use the HideControl procedure to change a visible control into an
invisible one.
■ You can directly change the contrlVis field of the control’s control record.
SPECIAL CONSIDERATIONS
The ShowControl procedure draws the control in its window, but the control can still be
completely or partially obscured by overlapping windows or other objects.
SEE ASO
Listing 5-14 on page 5-39 illustrates the use of ShowControl to redisplay scroll bars after
moving and resizing them.
UpdateControls 5
To update controls in a window, you can use the UpdateControls procedure. The
UpdateControls procedure is also available as the UpdtControl procedure.
Control Manager
DESCRIPTION
The UpdateControls procedure draws those controls that are in the specified update
region. This procedure is faster than the DrawControls procedure, which draws all of
the controls in a window. By contrast, UpdateControls draws only those controls in
the update region.
Your application should call UpdateControls upon receiving an update event for a
window that contains controls. Window Manager routines such as SelectWindow,
ShowWindow, and BringToFront do not automatically call DrawControls to display
the window’s controls. They just add the appropriate regions to the window’s update
region, generating an update event.
In response to an update event, you normally call UpdateControls after using the
Window Manager procedure BeginUpdate and before using the Window Manager
procedure EndUpdate. You should set the updateRgn parameter to the visible region of
the window’s port, as specified in the port’s visRgn field.
SPECIAL CONSIDERATIONS
If your application draws parts of a control outside of its rectangle, UpdateControls
might not redraw it.
The Dialog Manager handles update events for controls in alert boxes and dialog boxes.
SEE ALSO
Listing 5-8 on page 5-30 illustrates the use of UpdateControls. The BeginUpdate and
EndUpdate procedures are described in the chapter “Window Manager” in this book.
See the chapter “Dialog Manager” in this book for more information about including
controls in alert boxes and dialog boxes.
DrawControls 5
Although you should generally use the UpdateControls procedure to update controls
in a window, you can instead use the DrawControls procedure.
DESCRIPTION
The DrawControls procedure draws all controls currently visible in the specified
window. The controls are drawn in reverse order of creation; thus, in case of overlapping
controls, the control created first appears frontmost in the window.
Control Manager
Because the UpdateControls procedure redraws only those controls that need
updating, your application should generally use it instead of DrawControls upon
receiving an update event for a window that contains controls.
You should call either DrawControls or UpdateControls after calling the Window
Manager procedure BeginUpdate and before calling EndUpdate.
SPECIAL CONSIDERATIONS
The Dialog Manager automatically draws and updates controls in alert boxes and
dialog boxes.
Window Manager routines such as SelectWindow, ShowWindow, and BringToFront
do not automatically update the window’s controls. They just add the appropriate
regions to the window’s update region, generating an update event.
SEE ALSO
See the chapter “Dialog Manager” in this book for more information about including
controls in alert boxes and dialog boxes. See the chapter “Window Manager” in this book
for more information about Window Manager routines.
Draw1Control 5
Although you should generally use the UpdateControls procedure to update controls,
you can use the Draw1Control procedure to update a single control.
DESCRIPTION
The Draw1Control procedure draws the specified control if it’s visible within its
window. The UpdateControls procedure automatically calls Draw1Control.
Control Manager
FindControl 5
To determine whether a mouse-down event has occurred in a control and, if so, in which
part of that control, use the FindControl function.
DESCRIPTION
When the user presses the mouse button while the cursor is in a visible, active control,
FindControl returns as its function result a part code identifying the control’s part; the
function also returns a handle to the control in the parameter theControl. The part
codes that FindControl returns, and the constants you can use to represent them, are
listed here:
The pop-up control definition function does not define part codes for pop-up menus.
Instead, your application should store the handles for your pop-up menus when you
create them. Your application should then test the handles you store against the handles
returned by FindControl before responding to users’ choices in pop-up menus.
If the mouse-down event occurs in an invisible or inactive control, or if it occurs outside a
control, FindControl sets theControl to NIL and returns 0 as its function result.
Control Manager
When a mouse-down event occurs, your application should call FindControl after
using the Window Manager function FindWindow to ascertain that a mouse-down event
has occurred in the content region of a window containing controls.
Before calling FindControl, use the GlobalToLocal procedure to convert the point
stored in the where field (which describes the location of the mouse-down event) of the
event record to coordinates local to the window. Then, when using FindControl, pass
this point in the parameter thePoint.
In the parameter theWindow, pass the window pointer returned by the FindWindow
function.
After using FindControl to determine that a mouse-down event has occurred in
a control, you generally use the TrackControl function, which automatically
follows the movements of the cursor and responds as appropriate until the user releases
the mouse button.
SPECIAL CONSIDERATIONS
The Dialog Manager automatically calls FindControl and TrackControl for
mouse-down events inside controls of alert boxes and dialog boxes.
The FindControl function also returns NIL in the parameter theControl and 0 as
its function result if the window is invisible or if it doesn’t contain the given point.
(However, FindWindow won’t return a window pointer to an invisible window or to one
that doesn’t contain the point where the mouse-down event occurred. As long as you call
FindWindow before FindControl, this situation won’t arise.)
SEE ALSO
Listing 5-10 on page 5-33 illustrates the use of FindControl for detecting mouse-down
events in a pop-up menu and a button; Listing 5-18 on page 5-53 illustrates its use for
detecting mouse-down events in scroll bars.
The FindWindow function is described in the chapter “Window Manager” in this book.
The GlobalToLocal procedure is described in Inside Macintosh: Imaging.
The event record is described in the chapter “Event Manager” in this book. See the
chapter “Dialog Manager” in this book for more information about including controls in
alert boxes and dialog boxes.
TrackControl 5
To follow and respond to cursor movements in a control and then to determine the
control part in which the mouse-up event occurs, use the TrackControl function.
Control Manager
DESCRIPTION
The TrackControl function follows the user’s cursor movements in a control and
provides visual feedback until the user releases the mouse button. The visual feedback
given by TrackControl depends on the control part in which the mouse-down event
occurs. When highlighting is appropriate, for example, TrackControl highlights the
control part (and removes the highlighting when the user releases the mouse button).
When the user holds down the mouse button while the cursor is in an indicator (such as
the scroll box of a scroll bar) and moves the mouse, TrackControl responds by
dragging a dotted outline of the indicator.
The TrackControl function returns as its function result the control’s part code if the
user releases the mouse button while the cursor is inside the control part, or 0 if the user
releases the mouse button while the cursor is outside the control part. For control parts,
the TrackControl function returns the same values (represented by the constants
inButton, inCheckBox, inUpButton, inDownButton, inPageUp, inPageDown, and
inThumb) returned by the FindControl function, as described on page 5-89.
When TrackControl returns a value other than 0 as its function result, your applica-
tion should respond as appropriate to a mouse-up event in that control part. When
TrackControl returns 0 as its function result, your application should do nothing.
If the user releases the mouse button when the cursor is in an indicator such as a scroll
box, TrackControl calls the control’s control definition function to reposition the
indicator. The control definition function for scroll bars, for example, responds to the user
dragging a scroll box by redrawing the scroll box, calculating the control’s current setting
according to the new relative position of the scroll box, and storing the current setting in
the control record. Thus, if the minimum and maximum settings are 0 and 10, and the
scroll box is in the middle of the scroll bar, 5 is stored as the current setting. For a scroll
bar, your application must then respond by scrolling to the corresponding relative
position in the document.
Generally, you use TrackControl after using the FindControl function. In the
parameter theControl of TrackControl, pass the control handle returned by the
FindControl function, and in the parameter thePoint, supply the same point you
passed to FindControl (that is, a point in coordinates local to the window).
Control Manager
While the user holds down the mouse button with the cursor in one of the standard con-
trols, TrackControl performs the following actions, depending on the value you pass
in the parameter actionProc. (For other controls, what you pass in this parameter de-
pends on how you define the control.)
■ If you pass NIL in the actionProc parameter, TrackControl uses no action
procedure and therefore performs no additional actions beyond highlighting the
control or dragging the indicator. This is appropriate for buttons, checkboxes, radio
buttons, and the scroll box of a scroll bar.
■ If you pass a pointer to an action procedure in the actionProc parameter, you must
provide the procedure, and it must define some action that your application repeats as
long as the user holds down the mouse button. This is appropriate for the scroll
arrows and gray areas of a scroll bar.
■ If you pass Pointer(–1) in the actionProc parameter, TrackControl looks in
the contrlAction field of the control record for a pointer to the control’s action
procedure. This is appropriate when you are tracking the cursor in a pop-up menu.
(You can use the GetControlAction function to determine the value of this field,
and you can use the SetControlAction procedure to change this value.) If the
contrlAction field of the control record contains a procedure pointer,
TrackControl uses the action procedure it points to; if the field of the control record
also contains the value Pointer(–1), TrackControl calls the control’s control
definition function to perform the necessary action; you may wish to do this if you
define your own control definition function for a custom control. If the field of the
control record contains the value NIL, TrackControl performs no action.
SPECIAL CONSIDERATIONS
When you need to handle events in alert and dialog boxes, Dialog Manager routines
automatically call FindControl and TrackControl.
ASSEMBLY-LANGUAGE INFORMATION
The TrackControl function invokes the Window Manager function DragGrayRgn, so
you can use the global variables DragHook and DragPattern.
SEE ALSO
See “Defining Your Own Action Procedures” beginning on page 5-115 for information
about an action procedure to specify in the actionProc parameter. See “Defining Your
Own Control Definition Function” beginning on page 5-109 for information about
creating a control definition function.
Listing 5-11 on page 5-36, Listing 5-12 on page 5-37, Listing 5-13 on page 5-38,
and Listing 5-18 on page 5-53 illustrate the use of TrackControl for responding to
mouse-down events in, respectively, a button, a pop-up menu, a checkbox, and a
scroll bar.
See the chapter “Dialog Manager” in this book for more information about including
controls in alert boxes and dialog boxes.
Control Manager
TestControl 5
DESCRIPTION
When the control specified by the parameter theControl is visible and active,
TestControl tests which part of the control contains the point specified by the
parameter thePt. For its function result, TestControl returns the part code of the
control part, or 0 if the point is outside the control.
If the control is invisible or inactive, TestControl returns 0.
Control Manager
SetControlValue 5
To change the current setting of a control and redraw it accordingly, you can use the
SetControlValue procedure. The SetControlValue procedure is also available as
the SetCtlValue procedure.
theControl A handle to the control whose current setting you wish to change.
theValue The new setting for the control.
DESCRIPTION
The SetControlValue procedure changes the contrlValue field of the control record
to the specified value and redraws the control to reflect the new setting. For checkboxes
and radio buttons, the value 1 fills the control with the appropriate mark, and 0 removes
the mark. For scroll bars, SetControlValue redraws the scroll box where appropriate.
If the specified value is less than the minimum setting for the control,
SetControlValue sets the control to its minimum setting; if the value is greater
than the maximum setting, SetControlValue sets the control to its maximum.
When you create a control, you specify an initial setting either in the control resource or
in the value parameter of the NewControl function. To determine a control’s current
setting before changing it in response to a user’s click in that control, use the
GetControlValue function.
Control Manager
SEE ALSO
Listing 5-13 on page 5-38 illustrates the use of SetControlValue to change the setting
of a checkbox. Listing 5-16 on page 5-41 and Listing 5-20 on page 5-61 illustrate the use of
SetControlValue to change the setting of a scroll bar.
SetControlMinimum 5
To change the minimum setting of a control and redraw its indicator or scroll box
accordingly, you can use the SetControlMinimum procedure. The
SetControlMinimum procedure is also available as the SetCtlMin procedure.
theControl A handle to the control whose minimum setting you wish to change.
minValue The new minimum setting.
DESCRIPTION
The SetControlMinimum procedure changes the contrlMin field of the control record
to the setting you specify in the minValue parameter and redraws its indicator
or scroll box to reflect its new range.
When you create a control, you specify an initial minimum setting either in the control
resource or in the min parameter of the NewControl function. To determine a control’s
current minimum setting, use the GetControlMinimum function.
SetControlMaximum 5
To change the maximum setting of a control and redraw its indicator or scroll
box accordingly, you can use the SetControlMaximum procedure. The
SetControlMaximum procedure is also available as the SetCtlMax procedure.
theControl A handle to the control whose maximum setting you wish to change.
maxValue The new maximum setting.
DESCRIPTION
The SetControlMaximum procedure changes the contrlMax field of the control record
to the setting you specify in the maxValue parameter and redraws its indicator
or scroll box to reflect its new range.
Control Manager
When you create a control, you specify an initial maximum setting either in the control
resource or in the max parameter of the NewControl function. To determine a control’s
current maximum setting, use the GetControlMaximum function.
When you set the maximum setting of a scroll bar equal to its minimum setting, the
control definition function makes the scroll bar inactive; when you make the maximum
setting exceed the minimum, the control definition function makes the scroll bar active
again.
SEE ALSO
Listing 5-16 on page 5-41 illustrates the use of SetControlMaximum to specify the
maximum setting for a scroll bar.
SetControlTitle 5
To change the title of a control and redraw the control accordingly, use the
SetControlTitle procedure. The SetControlTitle procedure is also available as
the SetCTitle procedure.
DESCRIPTION
The SetControlTitle procedure changes the contrlTitle field of the control record
to the given string and redraws the control, using the system font for the
control title.
The Control Manager allows multiple lines of text in the titles of buttons, checkboxes, and
radio buttons. When specifying a multiple-line title, separate the lines with the ASCII
character code $0D (carriage return). If the control is a button, each line is horizontally
centered, and the font leading is inserted between lines. (The height of each line is equal
to the distance from the ascent line to the descent line plus the leading of the font used.
Be sure to make the total height of the rectangle greater than the number of lines times
this height.) If the control is a checkbox or a radio button, the text is justified as
appropriate for the user’s current script system, and the checkbox or button is vertically
centered within its rectangle.
When you create a control, you specify an initial title either in the control resource or in
the title parameter of the NewControl function. To determine a control’s current title,
use the GetControlTitle procedure.
Control Manager
HideControl 5
To make a control invisible, before adjusting its size and location, for example, use the
HideControl procedure.
DESCRIPTION
The HideControl procedure makes the specified control invisible by changing the value
of the contrlVis field of the control record and removing the control from the screen.
To fill the region previously occupied by the control, HideControl uses the background
pattern of the window’s graphics port. It also adds the control’s rectangle to the
window’s update region, so that anything else that was previously obscured by the
control will reappear on the screen. If the control is already invisible, HideControl has
no effect.
To make the control visible again, you can use the ShowControl procedure.
SPECIAL CONSIDERATIONS
The MoveControl and SizeControl procedures both call HideControl and
ShowControl automatically. However, so that the control will not blink on the screen
when you make both of these calls, you should use HideControl to make the control
invisible until you are finished manipulating it, and then use ShowControl.
SEE ALSO
Listing 5-14 on page 5-39 illustrates the use of HideControl before adjusting scroll bar
settings and locations.
MoveControl 5
To move a control within its window, you can use the MoveControl procedure.
Control Manager
DESCRIPTION
The MoveControl procedure moves the control to the new location specified by the h
and v parameters, using them to change the rectangle specified in the contrlRect field
of the control’s control record. When the control is visible, MoveControl first hides it
and then redraws it at its new location.
For example, if the user resizes a document window that contains a scroll bar, your
application can use MoveControl to move the scroll bar to its new location.
SEE ALSO
Listing 5-24 on page 5-67 illustrates the use of MoveControl to change the location of a
scroll bar.
SizeControl 5
DESCRIPTION
The SizeControl procedure changes the rectangle specified in the contrlRect field of
the control’s control record. The lower-right corner of the rectangle is adjusted so
that it has the width and height specified by the w and h parameters; the position of the
upper-left corner is not changed. If the control is currently visible, it’s first hidden and
then redrawn in its new size. The SizeControl procedure uses HideControl, which
changes the window’s update region.
SEE ALSO
Listing 5-24 on page 5-67 illustrates the use of SizeControl to change the size of a scroll
bar.
HiliteControl 5
If you need to change the highlighting of a control, you can use the HiliteControl
procedure.
Control Manager
DESCRIPTION
The HiliteControl procedure calls the control definition function to redraw the
control with the highlighting specified in the hiliteState parameter. The
HiliteControl procedure uses the value in this parameter to change the value
of the contrlHilite field of the control’s control record.
Except for scroll bars (which you should hide using the HideControl procedure), you
should use HiliteControl to make all controls inactive when their windows are not
frontmost. The TrackControl function automatically uses the HiliteControl
procedure as appropriate; when you use TrackControl, you don’t need to call
HiliteControl.
SPECIAL CONSIDERATIONS
The value 254 should not be passed in the hiliteState parameter; this value is
reserved for future use.
SEE ALSO
The chapter “Dialog Manager” in this book provides several examples of the use of
HiliteControl.
DragControl 5
If you need to draw and move an outline of a control or its indicator (such as the scroll
box of a scroll bar) while the user drags it, you can use the DragControl procedure.
Control Manager
CONST
noConstraint = 0; {no constraint}
hAxisOnly = 1; {drag along horizontal axis only}
vAxisOnly = 2; {drag along vertical axis only}
DESCRIPTION
The DragControl procedure moves a dotted outline of the control around the screen,
following the movements of the cursor until the user releases the mouse button. When
the user releases the mouse button, DragControl calls MoveControl. In turn,
MoveControl moves the control to the location to which the user dragged it.
The TrackControl function automatically uses the DragControl procedure as
appropriate; when you use TrackControl, you don’t need to call DragControl.
The startPt, limitRect, slopRect, and axis parameters have the same meaning as
for the Window Manager function DragGrayRgn.
SPECIAL CONSIDERATIONS
Before tracking the cursor, DragControl calls the control definition function. If you
define your own control definition function, you can specify custom dragging behavior.
ASSEMBLY-LANGUAGE INFORMATION
Like TrackControl, DragControl invokes the Window Manager function
DragGrayRgn, so you can use the global variables DragHook and DragPattern.
SEE ALSO
For information about creating your own control definition functions, see “Defining Your
Own Control Definition Function” beginning on page 5-109. See the description of the
DragGrayRgn function in the chapter “Window Manager” in this book for a more
complete discussion of the startPt, limitRect, slopRect, and axis parameters,
which are used identically in the DragControl function.
Control Manager
SetControlColor 5
To draw a control using colors other than the default colors used by system software, you
can use the SetControlColor procedure. The SetControlColor procedure is also
available as the SetCtlColor procedure.
DESCRIPTION
The SetControlColor procedure changes the color table for the specified control. If the
control currently has no auxiliary control record, SetControlColor creates one that
includes the control color table record specified in the parameter newColorTable and
adds the auxiliary control record to the head of the auxiliary control list. If there
is already an auxiliary record for the control, SetControlColor replaces its color
table with the contents of the control color table record specified in the parameter
newColorTable.
To use nonstandard colors for a control, you must create a control color table, either by
creating a color control table record and calling SetControlColor or by creating a
control color table resource. Generally, you use SetControlColor when you create
a control using NewControl and want to use nonstandard colors for it or when you
change any control’s colors after you’ve created it. When you want to use nonstandard
colors for those controls you create in a control ('CNTL') resource, you should create a
control color table ('cctb') resource with the same resource ID as the control resource.
A control whose colors you set with SetControlColor should initially be invisible.
After using SetControlColor to set the control’s colors, use the ShowControl
procedure to make the control visible.
SPECIAL CONSIDERATIONS
On color monitors, the Control Manager automatically draws controls so that they match
the colors of the controls used by system software. Be aware that nonstandard colors in
your controls may initially confuse your users.
When you create a control color table record, your application should not deallocate it if
another control is still using it.
Control Manager
SetControlAction 5
If you set the action procedure to Pointer(-1) when you use TrackControl, you can
use the SetControlAction procedure to set or change the action procedure. The
SetControlAction procedure is also available as the SetCtlAction procedure.
theControl A handle to the control whose action procedure you wish to change.
actionProc A pointer to an action procedure defining what action your application
takes while the user holds down the mouse button.
DESCRIPTION
The SetControlAction procedure changes the contrlAction field of the control’s
control record to point to the action procedure specified in the actionProc parameter. If
the cursor is in the specified control, TrackControl calls this action procedure
when user holds down the mouse button. You must provide the action procedure, and it
must define some action to perform repeatedly as long as the user holds down the mouse
button. (The TrackControl function always highlights and drags the control
as appropriate.)
SPECIAL CONSIDERATIONS
The value in the contrlAction field of the control’s control record is used
by TrackControl only if you set the action procedure to TrackControl to
Pointer(–1).
An action procedure is usually specified in a parameter to TrackControl; you generally
don’t need to call SetControlAction to change it.
SEE ALSO
Action procedures are described in “Defining Your Own Action Procedures” beginning
on page 5-115.
Control Manager
GetControlValue 5
DESCRIPTION
The GetControlValue function returns as its function result the specified control’s
current setting, which is stored in the contrlValue field of the control record.
When you create a control, you specify an initial setting either in the control resource or
in the value parameter of the NewControl function. You can change the setting by
using the SetControlValue procedure.
SEE ALSO
Listing 5-12 on page 5-37 and Listing 5-13 on page 5-38 illustrate the use of
GetControlValue for determining the current setting of, respectively, a pop-up
menu and a checkbox. Listing 5-16 on page 5-41, Listing 5-18 on page 5-53, and
Listing 5-20 on page 5-61 illustrate the use of this function for determining the
current setting of a scroll bar.
GetControlMinimum 5
theControl A handle to the control whose minimum value you wish to determine.
Control Manager
DESCRIPTION
The GetControlMinimum function returns as its function result the specified control’s
minimum setting, which is stored in the contrlMin field of the control record.
When you create a control, you specify an initial minimum setting either in the control
resource or in the min parameter of the NewControl function. You can change the
minimum setting by using the SetControlMinimum procedure.
GetControlMaximum 5
theControl A handle to the control whose maximum value you wish to determine.
DESCRIPTION
The GetControlMaximum function returns as its function result the specified control’s
maximum setting, which is stored in the contrlMax field of the control record.
When you create a control, you specify an initial maximum setting either in the control
resource or in the max parameter of the NewControl function. You can change the
maximum setting by using the SetControlMaximum procedure.
SEE ALSO
Listing 5-16 on page 5-41 and Listing 5-20 on page 5-61 illustrate the use of
GetControlMaximum for determining the maximum scrolling distance of a scroll bar.
GetControlTitle 5
Control Manager
DESCRIPTION
The GetControlTitle procedure returns the specified control title, which is stored in
the contrlTitle field of the control record.
When you create a control, you specify an initial title either in the control resource or in
the title parameter of the NewControl function. You can change the title by using the
SetControlTitle procedure.
GetControlReference 5
theControl A handle to the control whose current reference value you wish
to determine.
DESCRIPTION
The GetControlReference function returns as its function result the current reference
value for the specified control.
When you create a control, you specify an initial reference value, either in the control
resource or in the refCon parameter of the NewControl function. The reference value is
stored in the contrlRfCon field of the control record. You can use this field for any
purpose, and you can use the SetControlReference procedure, described next, to
change this value.
SetControlReference 5
theControl A handle to the control whose reference value you wish to change.
data The new reference value for the control.
Control Manager
DESCRIPTION
The SetControlReference procedure sets the control’s reference value to the value
you specify in the data parameter.
When you create a control, you specify an initial reference value, either in the
control resource or in the refCon parameter of the NewControl function. The
reference value is stored in the contrlRfCon field of the control record; you can
use the GetControlReference function to determine the current value. You
can use this value for any purpose.
GetControlAction 5
DESCRIPTION
The GetControlAction function returns as its function result whatever value is
stored in the contrlAction field of the control’s control record. This field specifies
the action procedure that TrackControl uses if you set its actionProc parameter to
Pointer(-1). The action procedure should define an action to take in response to the
user’s holding down the mouse button while the cursor is in the control. You can use
the SetControlAction procedure to change this action procedure.
SEE ALSO
For information about defining an action procedure, see “Defining Your Own Action
Procedures” beginning on page 5-115.
GetControlVariant 5
To determine the variation code specified in the control definition function for a
particular control, you can use the GetControlVariant function. The
GetControlVariant function is also available as the GetCVariant function.
theControl A handle to the control whose variation code you wish to determine.
Control Manager
DESCRIPTION
The GetControlVariant function returns as its function result the variation code for
the specified control.
SEE ALSO
Variation codes are described in “The Control Definition Function” on page 5-14.
GetAuxiliaryControlRecord 5
DESCRIPTION
In its acHndl parameter, the GetAuxiliaryControlRecord function returns a handle
to the auxiliary control record for the specified control. Your application typically doesn’t
need to access an auxiliary control record unless you need its acRefCon field, which
your application can use for any purpose.
The value that GetAuxiliaryControlRecord returns for a function result depends on
the control’s color control table, as described here:
■ If your application has changed the default control color table for the given control
(either by using the SetControlColor procedure or by creating its own control color
table), the function returns TRUE.
■ If your application has not changed the default control color table, the function
returns FALSE.
■ If you set the parameter theControl to NIL, the Dialog Manager ensures that
the control uses the default color table, and GetAuxiliaryControlRecord
returns TRUE.
Control Manager
Removing Controls 5
When you use the Window Manager procedures DisposeWindow and CloseWindow to
remove a window, they automatically remove all controls associated with the window
and release the memory the controls occupy.
When you no longer need a control in a window that you want to keep, you can use the
DisposeControl procedure to remove the control from the window’s control list and
release the memory it occupies. You can use the KillControls procedure to dispose of
all of a window’s controls at once.
DisposeControl 5
To remove a particular control from a window that you want to keep, use the
DisposeControl procedure.
DESCRIPTION
The DisposeControl procedure removes the specified control from the screen, deletes
it from its window’s control list, and releases the memory occupied by the control record
and any data structures associated with the control.
SPECIAL CONSIDERATIONS
The Window Manager procedures CloseWindow and DisposeWindow automatically
dispose of all controls associated with the given window.
SEE ALSO
To remove all of the controls in a window, use the KillControls procedure, described
next. The CloseWindow and DisposeWindow procedures are described in the chapter
“Window Manager” in this book.
KillControls 5
To remove all of the controls in a particular window that you want to keep, use the
KillControls procedure.
Control Manager
DESCRIPTION
The KillControls procedure disposes of all controls associated with the specified
window by calling the DisposeControl procedure for each control.
SPECIAL CONSIDERATIONS
The Window Manager procedures CloseWindow and DisposeWindow automatically
dispose of all controls associated with the given window.
SEE ALSO
The CloseWindow and DisposeWindow procedures are described in the chapter
“Window Manager” in this book.
Application-Defined Routines 5
This section describes how to create your own control definition function—declared
here as MyControl—which your application needs to provide when defining new,
nonstandard controls. This section also describes action procedures—declared here
as MyAction and MyIndicatorAction—which define additional actions to be
performed repeatedly as long as the user holds down the mouse button while the
cursor is in a control. For example, you need to define an action procedure for scrolling
through a document while the user holds down the mouse button and the cursor is
in a scroll arrow.
Control Manager
You can define your own variation codes, which various Control Manager routines pass
to your control definition function. This allows you to use one 'CDEF' resource to handle
several variations of the same general control.
The Control Manager calls the Resource Manager to access your control definition
function with the given resource ID. The Resource Manager reads your control definition
function into memory and returns a handle to it. The Control Manager stores this handle
in the contrlDefProc field of the control record. In 24-bit addressing mode, the
variation code is placed in the high-order byte of this field; in 32-bit mode, the variation
code is placed in the most significant byte of the acReserved field in the control’s
AuxCtlRec record. Later, when various Control Manager routines need to perform a
type-dependent action on the control, they call your control definition function and pass
it the variation code as a parameter.
If you create a control definition function, you can use control color table records of
any desired size and define their contents in any way you wish, except that part indices
1 through 127 are reserved for system definition. Note that in this case, you should
allocate explicit auxiliary records for every control you create.
MyControl 5
If you wish to define new, nonstandard controls for your application, you must write a
control definition function and store it in a resource file as a resource of type 'CDEF'.
Here’s how you would declare a procedure named MyControl:
varCode The variation code for this control. To derive the control definition ID for
the control, add this value to the result of 16 multiplied by the resource ID
of the 'CDEF' resource containing this function. The variation code
allows you to specify several control definition IDs within one 'CDEF'
resource, thereby defining several variations of the same basic control.
theControl A handle to the control that the operation will affect.
message A value (from the following list) that specifies which operation your
function must undertake.
Control Manager
DESCRIPTION
The Control Manager calls your control definition function under various circumstances;
the Control Manager uses the message parameter to inform your control definition
function what action it must perform. The data that the Control Manager passes in the
param parameter, the action that your control definition function must undertake, and
the function result that your control definition function returns all depend on the value
that the Control Manager passes in the message parameter. The rest of this section
describes how to respond to the various values that the Control Manager passes in the
message parameter.
Note
For the drawCntl message, the high-order word of the param
parameter may contain undefined data; therefore, evaluate only
the low-order word of this parameter. ◆
If the specified control is visible, your control definition function should draw the control
(or the part specified in the param parameter) within the control’s rectangle. If the
control is invisible (that is, if its contrlVis field is set to 0), your control definition
function does nothing.
Control Manager
When drawing the control or its part, take into account the current values of its
contrlHilite and contrlValue fields of the control’s control record.
If the part code for your control’s indicator is passed in param, assume that the indicator
hasn’t moved; the Control Manager, for example, may be calling your control definition
function so that you may simply highlight the indicator. However, when your applica-
tion calls the SetControlValue, SetControlMinimum, and SetControlMaximum
procedures, they in turn may call your control definition function to redraw the
indicator. Since these routines have no way of determining what part code you chose
for your indicator, they all pass 129 in param, meaning that you should move your
indicator. Your control definition function must detect this part code as a special case and
remove the indicator from its former location before drawing it. If your control has more
than one indicator, you should interpret 129 to mean all indicators.
When passed the value for the drawCntl constant in the message parameter, your
control definition function should always return 0 as its function result.
Control Manager
IMPORTANT
The Control Manager passes the calcCRgns constant when the 24-bit
Memory Manager is in operation. When the 32-bit Memory Manager is
in operation, the Control Manager instead passes the calcCntlRgn
constant or the calcThumbRgn constant. Your control definition
function should respond to all three constants. ▲
Control Manager
Your definition function should calculate the control’s new setting based on the
given offset and then, to reflect the new setting, redraw the control and update the
contrlValue field in the control’s control record. Your control definition function
should ignore the param parameter and return 0 as a function result.
Note that the SetControlValue, SetControlMinimum, and SetControlMaximum
procedures do not call your control definition function with the posCntl message;
instead, they pass the drawCntl message.
RECORD
limitRect,slopRect: Rect;
axis: Integer;
END;
Control Manager
■ If the user drags the indicator, your definition function must calculate the control’s
new setting (based on the pixel offset between the points where the cursor was when
the user pressed and released the mouse button while dragging the indicator) and
then, to reflect the new setting, redraw the control and update the contrlValue field
in the control’s control record. Note that, in this case, the TrackControl function
returns 0 whether or not the user changes the indicator’s position. Thus, you must
determine whether the user has changed the control’s setting, for instance, by
comparing the control’s value before and after the call to TrackControl.
Note
For the autoTrack message, the high-order word of the param
parameter may contain undefined data; therefore, evaluate only
the low-order word of this parameter. ◆
ASSEMBLY-LANGUAGE INFORMATION
The function’s entry point must be at the beginning.
SEE ALSO
The TrackControl function is described on page 5-90; creating an action procedure is
described in the next section.
Control Manager
example, if the user is working in a text document and holds down the mouse button
while the cursor is in the lower scroll arrow, your application should scroll continuously
one line at a time until the user releases the mouse button or reaches the end of
the document.
For a control part other than an indicator, you declare an action procedure that takes two
parameters: a handle to the control in which the mouse-down event occurred and an
integer that represents the part of the control in which the mouse-down event occurred.
Such an action procedure is declared as MyAction in the following section.
If the mouse-down event occurs in an indicator, your action procedure should take no
parameters, because the user may move the cursor outside the indicator while dragging
it. Such an action procedure, declared here as MyIndicatorAction, is described on
page 5-117.
Because it will be called with either zero or two parameters, according to whether the
mouse-down event occurred in an indicator or elsewhere, your action procedure can be
defined for only one case or the other. The only way to specify actions in response to all
mouse-down events in a control, regardless of whether they’re in an indicator, is to define
your own control definition function, as described in “Defining Your Own Control
Definition Function” beginning on page 5-109.
MyAction 5
Here’s how to declare an action procedure for a control part other than an indicator if you
were to name the procedure MyAction:
DESCRIPTION
Your procedure can perform any action appropriate for the control part. For example,
when a mouse-down event occurs in a scroll arrow or gray area of a scroll bar,
TrackControl calls your action procedure and passes it the part code and a handle
to the scroll bar. Your action procedure should examine the part code to determine
the part of the control in which the mouse-down event occurred. Your action
procedure should then scroll up or down a line or page as appropriate and then call
the SetControlValue procedure to change the control’s setting and redraw the
scroll box.
Control Manager
ASSEMBLY-LANGUAGE INFORMATION
If you store a pointer to a procedure in the global variable DragHook, your procedure is
called repeatedly (with no parameters) as long as the user holds down the mouse button.
The TrackControl function invokes the Window Manager function DragGrayRgn,
which calls the DragHook procedure. The DragGrayRgn function uses the pattern
stored in the global variable DragPattern for the dragged outline of the indicator.
SEE ALSO
Listing 5-19 on page 5-59 illustrates a pair of action procedures for scrolling through a
text document. As an alternative to passing a pointer to your action procedure in a
parameter to TrackControl, you can use the SetControlAction procedure to
store a pointer to the action procedure in the contrlAction field in the control record.
When you pass Pointer(–1) instead of a procedure pointer to TrackControl,
TrackControl uses the action procedure pointed to in the control record.
MyIndicatorAction 5
Here’s how to declare an action procedure for an indicator if you were to name the
procedure MyIndicatorAction:
PROCEDURE MyIndicatorAction;
DESCRIPTION
Your procedure can perform any action appropriate for the control part. For example, if
your application plays music while displaying a volume control slider, your application
should change the volume in response to the user’s action in the slider switch.
SEE ALSO
See the MyAction procedure described on page 5-116 for other considerations.
Resources 5
This section describes the control ('CNTL') resource and the control color table ('cctb')
resource. You can use the control resource to define a control and use the control color
table resource to change the default colors of a control’s parts.
Control Manager
Rectangle 8
Initial setting 2
Visibility 1
Fill 1
Maximum setting 2
Minimum setting 2
Control definition ID 2
Reference value 4
Title Variable
Control Manager
■ For pop-up menus, a combination of values instructs the Control Manager where
and how to draw the control title. Appropriate values, along with the constants
used to specify them in a Rez input file, are listed here:
■ The visibility of the control. If this element contains the value TRUE, GetNewControl
draws the control immediately, without using the application’s standard updating
mechanism for windows. If this element contains the value FALSE, the application
must use the ShowControl procedure (described on page 5-86) when it’s prepared to
display the control.
■ Fill. This should be set to 0.
■ The maximum setting for the control.
■ For controls—such as buttons—that don’t retain a setting, this value should be 1.
Control Manager
■ The control definition ID, which the Control Manager uses to determine the control
definition function for this control. “Defining Your Own Control Definition Function”
beginning on page 5-109 describes how to create control definition functions and their
corresponding control definition IDs. The following list shows the control definition ID
numbers—and the constants that represent them in Rez input files—for the standard
controls.
CONST
pushButProc = 0; {button}
checkBoxProc = 1; {checkbox}
radioButProc = 2; {radio button}
useWFont = 8; {when added to above, shows }
{ title in the window font}
scrollBarProc = 16; {scroll bar}
popupMenuProc = 1008; {pop-up menu}
popupFixedWidth = $0001; {add to popupMenuProc to }
{ use fixed-width control}
popupUseAddResMenu = $0004; {add to popupMenuProc to }
{ specify a value of type }
{ ResType in the contrlRfCon }
{ field of the control }
{ record; Menu Manager }
{ adds resources of this }
{ type to the menu}
popupUseWFont = $0008; {if added to popupMenuProc, }
{ shows title in window font}
Note
The title of a button, checkbox, radio button, or pop-up menu normally
appears in the system font, which in Roman script systems is 12-point
Chicago. Do not use a smaller font; some script systems, such as
KanjiTalk, require 12-point fonts. You should generally use the system
font in your controls; doing so will simplify localization effort. However,
if you absolutely need to display a control title in the font currently
associated with the window’s graphics port, you can add the
popupUseWFont constant to the pop-up menu control definition
ID or add the useWFont constant to the other standard control
definition IDs. ◆
■ The control’s reference value, which is set and used only by the application (except
when the application adds the popupUseAddResMenu variation code to the
popupMenuProc control definition ID, as described in “Creating a Pop-Up Menu”
beginning on page 5-25).
Control Manager
Note
Using nonstandard colors in your controls may initially confuse
your users. ◆
Generally, you use a control color table resource for a control that you define in a control
resource. To change a control’s colors, or to use nonstandard colors in a control
you create using NewControl, create a control color table record and use the
SetControlColor procedure. The control color table record is described on page 5-77;
the SetControlColor procedure is described on page 5-101.
A control color table resource is of type 'cctb'. All control color table resources must
have resource ID numbers greater than 128. Figure 5-26 on the next page shows the
format of a control color table resource. Note that DisposeControl does not delete
a control color table resource; therefore, you should make each control color table
resource purgeable.
Control Manager
Reserved 4
Reserved 2
Red component 2
Green component 2
Blue component 2
Red component 2
Green component 2
Blue component 2
You define a control color table resource by specifying these elements in a resource with
the 'cctb' resource type:
■ Reserved. Should always be set to 0.
■ Reserved. Should always be set to 0.
■ Number of control parts. For standard controls other than scroll bars, this should be
set to 3, because these controls consist of a frame, a control body, and text. For scroll
bars, this should be set to 12. A scroll bar consists of a frame, a body, and scroll box;
each part of a scroll bar has various highlight and tinge colors associated with it. To
create a control with more parts, you must create your own control definition function
(as described in “Defining Your Own Control Definition Function” beginning on
page 5-109) that recognizes additional parts.
■ First part identifier. A value or constant that identifies the control’s part to color. The
part identifiers can be listed in any order. The scroll bar control definition function
may use more than one part identifier to produce the actual colors used for each part
of the scroll bar.
CONST
cFrameColor = 0; {frame color; for scroll bars, used to produce }
{ foreground color for scroll arrows & gray area}
cBodyColor = 1; {body color; for scroll bars, used to produce }
{ colors in the scroll box}
cTextColor = 2; {text color; unused for scroll bars}
Control Manager
■ Red component. An integer that represents the intensity of the red component of
the color to use when drawing this part of the control. In this and the next two
elements, use 16-bit unsigned integers to give the intensity values of three additive
primary colors.
■ Green component. An integer that represents the intensity of the green component of
the color to use when drawing this part of the control.
■ Blue component. An integer that represents the intensity of the blue component of the
color to use when drawing this part of the control.
■ Part identifier and red, green, and blue components for the next control part. You can
list parts in any order in this resource. If the application specifies a part identifier that
cannot be found, the Control Manager uses the colors for the control’s first identifiable
part. If a part is not listed in the control color table, the Dialog Manager draws it in its
default color.
Control Manager
Pascal Summary 5
Constants 5
CONST
{control definition IDs}
pushButProc = 0; {button}
checkBoxProc = 1; {checkbox}
radioButProc = 2; {radio button}
useWFont = 8; {add to above to display control title in }
{ the window font}
scrollBarProc = 16; {scroll bar}
popupMenuProc = 1008; {pop-up menu}
popupMenuCDEFproc = popupMenuProc; {synonym for compatibility}
{part codes}
inButton = 10; {button}
inCheckBox = 11; {checkbox or radio button}
inUpButton = 20; {up arrow for a vertical scroll bar, }
{ left arrow for a horizontal scroll bar}
inDownButton = 21; {down arrow for a vertical scroll bar, }
{ right arrow for a horizontal scroll bar}
inPageUp = 22; {gray area above scroll box for a }
{ vertical scroll bar, gray area to }
{ left of scroll box for a horizontal }
{ scroll bar}
Control Manager
Control Manager
Data Types 5
ControlRecord =
PACKED RECORD
nextControl: ControlHandle; {next control}
contrlOwner: WindowPtr; {control's window}
contrlRect: Rect; {rectangle}
contrlVis: Byte; {255 if visible}
contrlHilite: Byte; {highlight state}
contrlValue: Integer; {control's current setting}
contrlMin: Integer; {control's minimum setting}
contrlMax: Integer; {control's maximum setting}
contrlDefProc: Handle; {control definition function}
contrlData: Handle; {data used by contrlDefProc}
contrlAction: ProcPtr; {action procedure}
contrlRfCon: LongInt; {control's reference value}
contrlTitle: Str255; {control's title}
END;
AuxCtlPtr = ^AuxCtlRec;
AuxCtlHandle = ^AuxCtlPtr;
AuxCtlRec =
RECORD
acNext: AuxCtlHandle; {handle to next AuxCtlRec}
acOwner: ControlHandle; {handle to this record's control}
acCTable: CCTabHandle; {handle to color table record}
acFlags: Integer; {reserved}
acReserved: LongInt; {reserved for future use}
acRefCon: LongInt; {for use by application}
END;
Control Manager
CCTabPtr = ^CtlCTab;
CCTabHandle = ^CCTabPtr;
CtlCTab =
RECORD
ccSeed: LongInt; {reserved; set to 0}
ccRider: Integer; {reserved; set to 0}
ctSize: Integer; {number of ColorSpec records in next }
{ field; 3 for standard controls}
ctTable: ARRAY[0..3] OF ColorSpec;
END;
Creating Controls
FUNCTION GetNewControl (controlID: Integer; owner: WindowPtr)
: ControlHandle;
FUNCTION NewControl (theWindow: WindowPtr; boundsRect: Rect;
title: Str255; visible: Boolean;
value: Integer; min: Integer; max: Integer;
procID: Integer; refCon: LongInt)
: ControlHandle;
Drawing Controls
{UpdateControls is also spelled as UpdtControl}
PROCEDURE ShowControl (theControl: ControlHandle);
PROCEDURE UpdateControls (theWindow: WindowPtr; updateRgn: RgnHandle);
PROCEDURE DrawControls (theWindow: WindowPtr);
PROCEDURE Draw1Control (theControl: ControlHandle);
Control Manager
Removing Controls
PROCEDURE DisposeControl (theControl: ControlHandle);
PROCEDURE KillControls (theWindow: WindowPtr);
Control Manager
Application-Defined Routines 5
C Summary 5
Constants 5
enum {
/*control definition IDs*/
pushButProc = 0, /*button*/
checkBoxProc = 1, /*checkbox*/
radioButProc = 2, /*radio button*/
useWFont = 8, /*add to above to display control */
/* title in the window font*/
scrollBarProc = 16, /*scroll bar*/
popupMenuProc = 1008, /*pop-up menu*/
Control Manager
enum {
/*part codes*/
inButton = 10, /*button*/
inCheckBox = 11, /*checkbox or radio button*/
inUpButton = 20, /*up arrow for a vertical scroll bar, */
/* left arrow for a horizontal scroll bar*/
inDownButton = 21, /*down arrow for a vertical scroll bar, */
/* right arrow for a horizontal scroll bar*/
inPageUp = 22, /*gray area above scroll box for a */
/* vertical scroll bar, gray area to */
/* left of scroll box for a horizontal */
/* scroll bar*/
inPageDown = 23, /*gray area below scroll box for a */
/* vertical scroll bar, gray area to */
/* right of scroll box for a horizontal */
/* scroll bar*/
inThumb = 129 /*scroll box (or other indicator)*/
};
enum {
/*pop-up title characteristics*/
popupTitleBold = 1 << 8, /*boldface font style*/
popupTitleItalic = 1 << 9, /*italic font style*/
popupTitleUnderline = 1 << 10, /*underline font style*/
popupTitleOutline = 1 << 11, /*outline font style*/
popupTitleShadow = 1 << 12, /*shadow font style*/
popupTitleCondense = 1 << 13, /*condensed text*/
popupTitleExtend = 1 << 14, /*extended text*/
popupTitleNoStyle = 1 << 15 /*monostyled text*/
};
enum {
/*pop-up title characteristics*/
popupTitleLeftJust = 0x00000000, /*place title left of pop-up box*/
popupTitleCenterJust = 0x00000001, /*center title over pop-up box*/
popupTitleRightJust = 0x000000FF, /*place title right of pop-up box*/
Control Manager
Data Types 5
struct ControlRecord {
struct ControlRecord **nextControl; /*next control*/
WindowPtr contrlOwner; /*control's window*/
Rect contrlRect; /*rectangle*/
unsigned char contrlVis; /*255 if visible*/
unsigned char contrlHilite; /*highlight state*/
short contrlValue; /*control's current setting*/
short contrlMin; /*control's minimum setting*/
short contrlMax; /*control's maximum setting*/
Handle contrlDefProc; /*control definition function*/
Handle contrlData; /*data used by contrlDefProc*/
ProcPtr contrlAction; /*action procedure*/
long contrlRfCon; /*control's reference value*/
Str255 contrlTitle; /*control's title*/
};
Control Manager
struct AuxCtlRec {
Handle acNext; /*handle to next AuxCtlRec*/
ControlHandle acOwner; /*handle to this record's control*/
CCTabHandle acCTable; /*handle to color table record*/
short acFlags; /*reserved*/
long acReserved; /*reserved for future use*/
long acRefCon; /*for use by application*/
};
struct CtlCTab {
long ccSeed; /*reserved; set to 0*/
short ccRider; /*reserved; set to 0*/
short ctSize; /*number of ColorSpec records in next */
/* field; 3 for standard controls*/
ColorSpec ctTable[4];
};
typedef struct CtlCTab CtlCTab;
typedef CtlCTab *CCTabPtr, **CCTabHandle;
Creating Controls
pascal ControlHandle GetNewControl
(short controlID, WindowPtr owner);
pascal ControlHandle NewControl
(WindowPtr theWindow, const Rect *boundsRect,
ConstStr255Param title, Boolean visible,
short value, short min, short max,
short procID, long refCon);
Drawing Controls
/*UpdateControls is also spelled as UpdtControl*/
pascal void ShowControl (ControlHandle theControl);
pascal void UpdateControls (WindowPtr theWindow, RgnHandle updateRgn);
pascal void DrawControls (WindowPtr theWindow);
pascal void Draw1Control (ControlHandle theControl);
Control Manager
Control Manager
Removing Controls
pascal void DisposeControl (ControlHandle theControl);
pascal void KillControls (WindowPtr theWindow);
Application-Defined Routines 5
Assembly-Language Summary 5
Data Structures 5
Control Manager
Global Variables 5
AuxCtlHead First in a linked list of auxiliary control records
AuxWinHead Contains a pointer to the linked list of auxiliary control records
DragHook Address of procedure to execute during TrackControl and DragControl
DragPattern Pattern of dragged region’s outline (8 bytes)
Figure 6-0
Listing 6-0
Table 6-0
6 Dialog Manager
Contents
Introduction to Alerts and Dialog Boxes 6-6
Types of Alerts 6-8
Types of Dialog Boxes 6-9
Modal Dialog Boxes 6-10
Movable Modal Dialog Boxes 6-11
Modeless Dialog Boxes 6-12
Items in Alert and Dialog Boxes 6-13
Events in Alert and Dialog Boxes 6-14
Alert Boxes, Dialog Boxes, and the Window Manager 6-15
About the Dialog Manager 6-16
Using the Dialog Manager 6-17
Creating Alert Sounds and Alert Boxes 6-18
Creating Dialog Boxes 6-23
Providing Items for Alert and Dialog Boxes 6-26
Item Types 6-30
Display Rectangles 6-32
Enabled and Disabled Items 6-36
Resource IDs for Items 6-36
Titles for Buttons, Checkboxes, and Radio Buttons 6-37
Text Strings for Static Text and Editable Text Items 6-40
Pop-Up Menus as Items 6-42
Keyboard Navigation Among Items 6-44
Manipulating Items 6-44
Changing Static Text 6-46
Getting Text From Editable Text Items 6-48
Adding Items to an Existing Dialog Box 6-51
Using an Application-Defined Item to Draw the Bold Outline for a
Default Button 6-56
Contents 6-1
C H A P T E R 6
6-2 Contents
C H A P T E R 6
C Summary 6-168
Constants 6-168
Data Types 6-169
Dialog Manager Routines 6-170
Application-Defined Routines 6-172
Assembly-Language Summary 6-172
Data Structures 6-172
Global Variables 6-172
Contents 6-3
C H A P T E R 6
Dialog Manager 6
This chapter describes how your application can use the Dialog Manager to alert users to
unusual situations and to solicit information from users. For example, in some situations
your application might not be able to carry out a command normally, and in other
situations the user must specify multiple parameters before your application can execute
a command. For circumstances like these, the Macintosh user interface includes these two
features:
■ alerts—including alert sounds and alert boxes—which warn the user whenever an
unusual or potentially undesirable situation occurs within your application
■ dialog boxes, which allow the user to provide additional information or to modify
settings before your application carries out a command
Read this chapter to learn how and when to implement alerts and dialog boxes. For
example, your application can use the Dialog Manager to ask the user whether to save
new or altered documents before quitting and, if the situation arises, to inform the user
that there is insufficient disk space to save the file.
Virtually all applications need to implement alerts and dialog boxes. To avoid needless
development effort, use the Dialog Manager to implement alerts and to create most
dialog boxes. It is possible, however—and sometimes desirable—to bypass the Dialog
Manager and instead use Window Manager, Control Manager, QuickDraw, and Event
Manager routines to create or respond to events in complex dialog boxes. Even if you
decide not to use the Dialog Manager, read this chapter for information about effective
human interface design and localization issues regarding dialog boxes.
To use this chapter, you should be familiar with resources, the Event Manager, the
Window Manager, and the Control Manager.
You typically use resources to specify the items you wish to display in alert boxes and
dialog boxes; for example, you specify the size, location, and appearance of a dialog
box in a dialog resource—a resource of type 'DLOG'. See the chapter “Introduction to the
Macintosh Toolbox” in this book for general information about resources; detailed
information about the Resource Manager and its routines is provided in the chapter
“Resource Manager” of Inside Macintosh: More Macintosh Toolbox.
The Dialog Manager offers routines that handle most of the events relating to alerts
and dialog boxes, but your application still needs to handle a few additional events
as described in “Writing an Event Filter Function for Alert and Modal Dialog Boxes”
beginning on page 6-86. See the chapter “Event Manager” in this book for general
information about events and event handling.
The Dialog Manager uses the Window Manager to display your alert boxes and dialog
boxes. Although the Dialog Manager uses most of the Window Manager routines
necessary to activate and update your alert and dialog boxes, your application needs
to use Window Manager routines if it creates certain types of dialog boxes—such as
modeless dialog boxes—as explained in this chapter. See the chapter “Window Manager”
in this book for general information about windows.
The Dialog Manager uses the Control Manager to create and display buttons, radio
buttons, checkboxes, and pop-up menus and to handle events in them. Generally, you
shouldn’t use any other controls—such as scroll bars—in your dialog boxes. If you need
6-5
C H A P T E R 6
Dialog Manager
to implement a more complex control, see the chapter “Control Manager” in this book.
Buttons are the only controls you should use in alert boxes.
If you include editable text items in your dialog boxes, the Dialog Manager uses TextEdit
to handle associated editing tasks. For general information on TextEdit, see the chapter
“TextEdit” in Inside Macintosh: Text.
This chapter provides a brief introduction to the concepts and functions of alerts and
dialog boxes, and then it discusses how you can
■ create and display alerts and dialog boxes
■ include controls, informative text, editable text fields, and similar items in your alert
boxes and dialog boxes
■ respond to events in your alert boxes and dialog boxes
By requiring the user to click a button, an alert box obliges the user to acknowledge the
alert box before proceeding. To assist the user who isn’t sure how to respond when an
alert box appears, your application specifies a preferred button—which invokes a
preferred action—for every alert box. The Dialog Manager draws a bold outline around
the preferred button so that it stands out from the other buttons in the alert box. The
outlined button is also the alert box’s default button; if the user presses the Return key or
Dialog Manager
the Enter key, the Dialog Manager acts as if the user had clicked this preferred button. For
example, if the user presses the Return or Enter key in response to the alert box shown in
Figure 6-1, the Dialog Manager inverts the OK button for 8 ticks and informs the Finder
that the OK button has been selected; then the Finder responds by deleting the item
contained in the Trash.
Use a dialog box when your application needs more information to carry out a com-
mand. Commands in menus normally act on only one object. If the user chooses a
command that your application cannot perform until the user supplies more informa-
tion, use a dialog box to elicit the information from the user. If a command brings up
a dialog box, indicate this to your user by placing three ellipsis points (...) after the
command’s name in the menu.
A dialog box is a special window that typically resembles a form on which the user
checks boxes and fills in blanks. Figure 6-2 shows a typical dialog box.
Although an alert typically requires only an acknowledgment to proceed from the user, a
dialog box ordinarily requires the user to supply information—for instance, by entering
text or by clicking a checkbox—necessary for completing the command. When you create
a dialog box that carries out a command, you normally provide OK and Cancel buttons.
When the user clicks the OK button, your application should perform the command
according to the information that the user supplied in the dialog box. When the user
clicks the Cancel button, your application should revoke the command and retract all of
its actions as though the user had never given the command. Instead of using an OK
button, you might use a button that describes the action to be performed; for example,
you might use a Search button in a Search command’s dialog box or a Remove button in
a Remove command’s dialog box. For simplicity, this chapter refers to the button that
performs the action described in the dialog box as the OK button. You may even provide
more than one button that performs the command, each in a slightly different way. For
example, in a Change command’s dialog box, you might include a Change Selection
button to replace only the current selection and a Change All button to replace all
occurrences throughout the entire document.
You can use any or all of the following elements in the dialog boxes you create:
■ informative or instructional text
■ rectangles in which text may be entered (initially blank or containing default text that
can be edited)
Dialog Manager
■ controls
■ graphics (icons or QuickDraw pictures)
■ other items as defined by your application
Types of Alerts 6
Every user of every application is liable to do something that the application won’t
understand or can’t cope with in a normal manner. Alerts give your application a way
to respond to these situations in a consistent manner. There are two major categories
of alerts: alert sounds and alert boxes.
The system alert sound is a sound resource stored in the System file. This sound is
played whenever system software or your application uses the Sound Manager
procedure SysBeep. The Sound control panel allows the user to select which sound
is played as the system alert sound. You can also provide your own alert sound to use
in place of the system alert sound.
Use an alert sound for errors that are both minor and immediately obvious. For example,
if the user tries to backspace past the left boundary of a text field, your application might
play the alert sound instead of displaying an alert box. Your application can base its
response on the number of consecutive times an alert condition recurs; the first time,
your application might simply play a sound, and thereafter it might present an alert box.
Your application can define different responses for each one of four alert stages.
An alert box is primarily a one-way communication from your application to the user;
the only way the user can respond is by clicking buttons. Therefore, your alert boxes
should contain buttons, but usually they should not contain editable text fields, radio
buttons, or checkboxes—items that are typically displayed in dialog boxes.
There are three standard kinds of alert boxes: note alerts, caution alerts, and stop alerts.
They are distinguished by the icons displayed in their upper-left corners.
Use a note alert to inform users of a situation that won’t have any disastrous
consequences if left as is. Usually this type of alert simply offers information, and the
user responds by clicking the OK button. Occasionally, as shown in Figure 6-3, a note
alert may ask a simple question and provide a choice of responses.
Dialog Manager
Use a caution alert to alert the user to an operation that may have undesirable results if
it’s allowed to continue. As shown in Figure 6-4, you should give the user the choice of
whether to continue the action (by clicking the OK button) or to stop the action (by
clicking the Cancel button).
Use a stop alert to inform the user that a problem or situation is so serious that the
action cannot be completed. Stop alerts, as illustrated in Figure 6-5, typically have only
a single button (OK), because all the user can do is acknowledge that the action cannot be
completed.
You can also create custom alert boxes containing in the upper-left corners either your
own icons or blank spaces. Plate 2 at the front of this book illustrates an alert box that
the SurfWriter application displays when the user chooses the About command from the
Apple menu. After reading the information in this alert box, the user clicks the OK button
to dismiss it.
Dialog Manager
IMPORTANT
Because the user must explicitly dismiss a modal dialog box before doing
anything else, you should use a modal dialog box only when it’s
essential for the user to complete an operation before performing any
other work. Fixed-position modal dialog boxes restrict the user’s
freedom of action; therefore, use them sparingly. As a rule of thumb,
use a modeless dialog box whenever possible, use a movable modal
dialog box whenever you can’t use a modeless dialog box, and use a
fixed-position modal dialog box only when you can’t implement the
dialog box as modeless or movable. ▲
A modal dialog box usually has at least two buttons: OK and Cancel. When the user
clicks the OK button, your application should perform the command according to the
information provided by the user and then remove the modal dialog box. You can give
the OK button a more descriptive title if you wish. When the user clicks the Cancel
button, your application should revoke any actions it took since displaying the modal
dialog box, and then it should remove the modal dialog box. Always label this button
“Cancel.” Your dialog boxes can have additional buttons as well; these may or may not
dismiss the dialog box.
Every dialog box you create should have a default button—that is, one whose action is
invoked when the user presses the Return or Enter key. Unless you provide your own
event filter function, the Dialog Manager treats the first item you specify in a description
of a dialog box as the default button (that is, so long as the first item is a button). You use
Dialog Manager
an event filter function, described in “Writing an Event Filter Function for Alert and
Modal Dialog Boxes” beginning on page 6-86, to supplement the Dialog Manager’s
ability to handle events; for example, an event filter function can also test for disk-
inserted events and can allow background applications to receive update events. If you
provide your own event filter function, it should test for key-down events involving the
Return and Enter keys and respond as if the default button were clicked. The default
button should invoke the preferred action, and you should try to design the preferred
action to be safe—that is, so that it doesn’t cause loss of data.
Although the Dialog Manager draws bold outlines around default buttons in alert
boxes, it does not draw bold outlines around those in dialog boxes. To indicate the
preferred action, your application should outline the default button. “Using an
Application-Defined Item to Draw the Bold Outline for a Default Button” beginning on
page 6-56 shows a method you can use to outline a button. If you don’t outline a
button in a dialog box, none should be the default button, and you must ensure in your
event filter function that pressing the Return or Enter key has no effect.
Dialog Manager
It’s important to consider whether you can use a modeless dialog box instead of a modal
or a movable modal dialog box—especially to preserve the user’s ability to perform any
task in any order.
Movable modal dialog boxes should generally respond like modal dialog boxes. Note,
however, that users should be able to switch between your application and another
application (thereby sending your application to the background) when you display a
movable modal dialog box—an action users cannot perform with modal dialog boxes.
For example, Macintosh system software uses several movable modal dialog boxes to
show that the Finder is busy with a time-consuming operation (such as file copying), yet
a user can still switch the Finder to the background.
When you display a modeless dialog box, you must allow the user to perform other
operations—such as working in document windows—without dismissing the dialog box.
When a user clicks a button in a modeless dialog box, your application should not
remove it; instead, the dialog box should remain on the desktop so that the user can
perform the command again. Because of the difficulty in revoking the last action invoked
from a modeless dialog box, it typically does not have a Cancel button, although it may
have a Stop button. A Stop button in a modeless dialog box is useful for halting long
printing or searching operations, for example.
When finished with a modeless dialog box, the user can click its close box or choose
Close from the File menu (when the dialog box is the active window). Your application
should then remove the modeless dialog box. A modeless dialog box is also dismissed
implicitly when the user chooses Quit. It’s usually helpful to the user for your application
to remember the contents of the dialog box after it’s dismissed. This way, when the user
invokes the dialog box again, even after the user closes and reopens your application,
you can restore the dialog box exactly as it was.
Dialog Manager
Button
Static
text
Your application enables or disables the items it includes in its dialog and alert boxes. An
enabled item is one for which the Dialog Manager reports user events involving that
item; for example, the Dialog Manager reports to the application when a user clicks the
enabled Cancel button shown in Figure 6-9. A disabled item is one for which the Dialog
Manager does not report events. For example, the Dialog Manager does not report to the
application when the user clicks or drags the static text item “Save this document as” in
Figure 6-9 because that item is disabled.
Don’t confuse a disabled item with an inactive control. When you don’t want the
Control Manager to display visual responses to mouse events in a control, you make
it inactive by using the Control Manager procedure HiliteControl. For example,
until the user types a filename, the Save button in Figure 6-9 is inactive. The Control
Manager displays an inactive control in a way (such as by dimming it) that shows it’s
inactive. The Dialog Manager makes no visual distinction between a disabled item and
an enabled item; the Dialog Manager simply doesn’t inform your application when the
user clicks a disabled item.
You should use HiliteControl to dim a control in dialog box whenever the user can’t
use that control. For example, Figure 6-8 shows a modeless dialog box with a dimmed
Dialog Manager
Stop button. The Stop button is dimmed because it has no effect until the user clicks the
Search button. When the user initiates the search operation by clicking the Search button,
the Stop button becomes active, and the Search button is dimmed.
You should use the Control Manager procedure HiliteControl to make the buttons
and other controls inactive in a modeless or movable modal dialog box when you
deactivate it. The HiliteControl procedure dims inactive buttons, radio buttons,
checkboxes, and pop-up menus to indicate to the user that clicking these items has no
effect while the dialog box is in the background. When you activate the dialog box again,
use HiliteControl to make the controls active again.
You store information about all dialog or alert box items in an item list resource. When
you use Dialog Manager routines to invoke alert boxes or create dialog boxes, the
Dialog Manager gets most of the descriptive information about them from resources.
The Dialog Manager calls the Resource Manager to read into memory what it needs
from the resource file.
Dialog Manager
You can also use the event filter function to test for and respond to keyboard equivalents
and more complex events—for instance, the user dragging the cursor within an
application-defined item.
For your application’s modeless and movable modal dialog boxes, you can pass events to
the IsDialogEvent function, or you can use your own event-handling code to
learn whether the events need to be handled as part of a dialog box. If they do, call
the DialogSelect function to assist you in handling them instead of calling the
ModalDialog procedure. Your application should not remove a modeless dialog box
unless the user clicks its close box or chooses Close from the File menu when the
modeless dialog box is the active window. Your application should remove a movable
modal dialog box only after the user clicks one of its enabled buttons.
Instead of using the IsDialogEvent or DialogSelect function to handle events
within modeless and movable modal dialog boxes, you can use Control Manager,
Window Manager, and TextEdit routines (such as FindWindow, BeginUpdate,
EndUpdate, FindControl, TrackControl, and TEClick) to handle these events
without the aid of the Dialog Manager.
Dialog Manager
plane of the dialog box (which, by convention, should initially be frontmost), and you
specify whether it is initially visible or invisible. If you create a dialog box that is initially
invisible—for example, if you need to set a control’s value before displaying it—you use
the Window Manager procedure ShowWindow to display the dialog box.
The Dialog Manager creates the dialog window by calling the Window Manager function
NewCWindow and then setting the window class in the window record to indicate that it’s
a dialog box. The Dialog Manager procedures for disposing of a dialog box,
CloseDialog and DisposeDialog, are analogous to the Window Manager procedures
CloseWindow and DisposeWindow.
When you create a dialog box (as described in “Creating Dialog Boxes” beginning on
page 6-23), use the window definition ID of dBoxProc for modal dialog boxes. Use
the noGrowDocProc window definition ID for modeless dialog boxes. (If your dialog
box absolutely needs a size box or scroll bars, you should use the Window Manager
to create the window instead of using the Dialog Manager.) And finally, use the
movableDBoxProc window definition ID to create movable modal dialog boxes.
The Dialog Manager provides routines for handling most events in alert boxes and dialog
boxes. For example, your application does not need to use such routines as the Window
Manager function FindWindow and the Control Manager function TrackControl to
determine when and where a mouse-down event occurs within an alert box’s buttons.
The Dialog Manager tells you which button the user clicks, and your application needs
only to respond appropriately to the click. The Dialog Manager also automatically
handles update and activate events for your alert boxes and dialog boxes. “Handling
Events in Alert and Dialog Boxes” beginning on page 6-77 describes in detail how to use
the Dialog Manager to help your application handle events.
Dialog Manager
■ whether to use the Event Manager, Window Manager, Control Manager, and TextEdit
instead of the Dialog Manager to handle events
You may, for example, want to create complex dialog boxes by using the Dialog Manager,
but then use the Event Manager, Window Manager, Control Manager, and TextEdit to
handle events inside your normal event loop. With regard to movable modal and
modeless dialog boxes, the sample code in this chapter illustrates such a hybrid
approach: it uses the Dialog Manager to create the dialog boxes, but it uses normal
event-handling code to determine an appropriate action according to which type of
window is frontmost. When a modeless or movable modal dialog box is in front, this
chapter illustrates how to take actions specific to that dialog box.
If you draw your own dialog box in a standard window without using the Dialog
Manager, you won’t be able to use Dialog Manager routines to help handle events,
but in return you’ll be able to update the window more quickly and extend its event
handling more easily. Here are some situations that tend to diminish the advantages
of using the Dialog Manager to create dialog boxes or handle events involving them:
■ The dialog box contains more than 20 items.
■ You need a multipart control, such as a scroll bar.
■ You need to move items offscreen and onscreen.
■ You need to display a moving indicator, such as a progress indicator.
■ You need to display a list in the dialog box. (For more information on lists, see the
chapter “List Manager” in Inside Macintosh: More Macintosh Toolbox.)
■ You need to display text in a font other than the system font.
■ Your application must respond to events other than mouse-down events, key-down
events inside editable text items, and a few key-down events for keyboard equivalents
when your application displays the dialog box.
If none of these situations applies to the dialog box you want to create, then you should
definitely use the Dialog Manager. If only one situation applies, you should probably use
the Dialog Manager. If two or more of these situations apply, you may find that it is better
to create and manage a standard window that operates like a dialog box instead of using
the Dialog Manager to create or manage it.
Dialog Manager
The Gestalt function is described in the chapter “Gestalt Manager” of Inside Macintosh:
Operating System Utilities.
Dialog Manager
These functions take descriptive information about the alert from an alert resource that
you provide. An alert resource has the resource type 'ALRT'. When you call one of these
functions, you pass it the resource ID of the alert resource and a pointer to an event filter
function. These functions create and display an alert box. When the user clicks a button
in an alert box, these functions return the button’s item number and close the alert box, at
which time you respond appropriately to the user’s click, as described in “Responding to
Events in Alert Boxes” beginning on page 6-81.
Here’s an example of how to create the caution alert shown in Figure 6-10.
VAR
myAlertItem: Integer;
myAlertItem := CautionAlert(kSaveAlertID, @MyEventFilter);
You should specify a pointer to an event filter function when you call the Alert,
StopAlert, CautionAlert, and NoteAlert functions. You should provide an event
filter function as a secondary event-handling loop for events that ModalDialog doesn’t
handle. In this example, a pointer to MyEventFilter is specified for the event filter
function. You can use the standard event filter function by passing NIL in this parameter.
The standard event filter function allows users to press the Return or Enter key in lieu of
clicking the default button. As described in “Writing an Event Filter Function for Alert
and Modal Dialog Boxes” beginning on page 6-86, your application should provide a
simple event filter function that also allows background applications to receive update
events. You can use the same event filter function in most or all of your alert boxes and
modal dialog boxes.
Continuing with the previous example, an application-defined constant
(kSaveAlertID) specifies the resource ID of an alert resource in a parameter to
the CautionAlert function. Listing 6-1 shows how this alert resource appears
in Rez input format. (Rez is the resource compiler provided with Apple’s Macintosh
Programmer’s Workshop [MPW], available from APDA.)
Dialog Manager
Dialog Manager
For example, a user might try to paste a graphic outside the page margins of a simple
page-layout program; the first time the user tries this, the application—using the Dialog
Manager—may simply play the system alert sound for the user. If the user repeats the
mistake, the application may play the system alert sound again. But when the user
repeats the error for the third consecutive time, the application may display an alert box
like the one shown in Figure 6-11. If the user makes the same mistake immediately after
dismissing this alert box, the alert box reappears, and it continues doing so until the user
corrects or abandons the improper action.
Figure 6-11 An alert box displayed only during the third and fourth alert stages
Listing 6-2 shows the alert resource used to specify the stop alert displayed in
Figure 6-11. Notice that the fourth alert stage is listed first, and the first alert stage is
listed last. At the third alert stage, the application displays an alert box but does not
play the system alert sound. If the user repeats the mistake a fourth consecutive time,
the application plays the system alert sound and displays the alert box as well.
The actions for each alert stage are specified by the following three pieces of information:
■ Which button is the default button—the OK button (that is, the first item in the item
list resource) or the Cancel button (that is, the second item in the item list resource).
The Dialog Manager automatically draws a bold outline around the default button,
and when the user presses the Return or Enter key, the Dialog Manager treats—or
your event filter function should treat—that keyboard event as a click in the default
Dialog Manager
button. The OK and Cancel buttons are described in detail in “Providing Items for
Alert and Dialog Boxes” beginning on page 6-26. At each alert stage, you can change
the default button, although it’s difficult to imagine a scenario where changing the
default button would be helpful to the user. In the previous example, the OK button is
the default.
■ Whether the alert box is to be displayed. If you specify the visible constant for
an alert stage, the alert box is displayed; if you specify the invisible constant, it is
not. In Listing 6-2, the alert box is not displayed the first two consecutive times the
user repeats the mistake, but it is displayed for all subsequent consecutive times.
■ Which of four possible sounds (if any) should be emitted at this stage of the alert. In
the previous example, the first, second, and fourth alert stages play a single system
alert sound, but the third stage plays no sound.
By default, the Dialog Manager uses the system alert sound. The sound1 constant, used
in Listing 6-2, tells the Dialog Manager to play the system alert sound once; you can also
specify the sound2 and sound3 constants, which cause the Dialog Manager to play the
system alert sound two and three times, respectively, each time at the same pitch and
with the same duration. The volume of the sound depends on the current speaker
volume setting, which the user can adjust in the Sound control panel. If the user has set
the speaker volume to 0, the menu bar blinks once in place of each sound that the user
would otherwise hear.
If you want the Dialog Manager to play sounds other than the system alert sound, write
your own sound procedure and then call ErrorSound and pass it a pointer to your
sound procedure. The ErrorSound procedure (described on page 6-104) makes your
sound procedure the current sound procedure. For example, you might create a sound
procedure named MyAlertSound, as shown in Listing 6-3.
For each of the four alert stages that can be reported in the soundNo parameter, your
procedure can emit any sound that you define.
Dialog Manager
As previously explained, the dimensions of the rectangle you specify in the alert resource
determine the dimensions of the alert box. You can also let the rectangle coordinates
serve as global coordinates that position the alert box, or you can let the Dialog Manager
automatically locate it for you according to three standard positions. Listing 6-2 on
page 6-21, for example, uses the alertPositionParentWindow constant to position
the alert box over the document window where the user is working. For details about
these standard positions, see “Positioning Alert and Dialog Boxes” beginning on
page 6-62.
VAR
theDialog: DialogPtr;
theDialog := GetNewDialog(kSpellCheckID, NIL, Pointer(-1));
Dialog Manager
Dialog Manager
■ a text string used for the title of a modeless or movable modal dialog box
■ as an option, a constant (either alertPositionParentWindow,
alertPositionMainScreen, or alertPositionParentWindowScreen) that
tells the Dialog Manager how to position the dialog box (available only to applications
running in System 7)
In the example, a rectangle with coordinates (62,184,216,448) specifies the dimensions of
the dialog box, and the alertPositionParentWindow constant causes the Dialog
Manager to place the dialog box just below the title bar of the user’s document window.
If you don’t supply a positioning constant, the Dialog Manager places the dialog box at
the global coordinates you specify for the dialog box’s rectangle. Positioning constants for
dialog boxes are explained in “Positioning Alert and Dialog Boxes” beginning on
page 6-62.
In the example, the dBoxProc window definition ID is used. Use the following window
definition IDs for specifying dialog box types:
In each case, the Dialog Manager uses the Window Manager to draw the appropriate
window frame. Figure 6-6 on page 6-10 shows an example of a modal dialog box drawn
with the dBoxProc window definition ID, Figure 6-7 on page 6-11 shows an example of a
movable modal dialog box drawn with the movableDBoxProc window definition ID,
and Figure 6-8 on page 6-12 illustrates a modeless dialog box drawn with the
noGrowDocProc window definition ID.
Listing 6-4 specifies the visible constant so that the dialog box is drawn immediately. If
you use the invisible constant, the dialog box is not drawn until your application uses
the Window Manager procedure ShowWindow to display the dialog box.
Use the goAway constant only with modeless dialog boxes. For modal dialog boxes and
movable modal dialog boxes, use the noGoAway constant, as shown in the example.
Notice that because the example does not make use of the reference constant, 0 (0x0) is
provided as a filler. However, you may wish to make use of this constant. For example,
your application can store a number that represents a dialog box type, or it can store
a handle to a record that maintains state information about the dialog box or other
window types, as explained in the chapter “Window Manager” in this book. You can use
the Window Manager procedure SetWRefCon at any time to change this value in the
dialog record for a dialog box, and you can use the GetWRefCon function to determine
its current value.
Listing 6-4 uses an application-defined constant that specifies the resource ID for the item
list. The next section, “Providing Items for Alert and Dialog Boxes,” describes how to
create an item list.
Dialog Manager
Supply a text string in your dialog resource when you want a modeless dialog box or a
movable modal dialog box to have a title. You can specify an empty string for a title bar
that contains no text. The example specifies the string “Spellcheck Options” for code
readability but, because the example creates a modal dialog box, no title bar is displayed.
You can let the Dialog Manager automatically locate the dialog box according
to three standard positions. Listing 6-4 on page 6-24, for example, specifies the
alertPositionParentWindow constant to position the dialog box over the
document window where the user is working. For details on these standard positions,
see “Positioning Alert and Dialog Boxes” beginning on page 6-62.
The Alert function in this example displays the alert box defined by the alert resource
represented by the kAboutBoxID resource ID. As explained in “Responding to Events in
Alert Boxes” beginning on page 6-81, the Alert function handles most user actions
while the alert box is displayed. When the user clicks any button in an alert box, Alert
removes the alert box and returns to your application the item number of the selected
button. The application-defined function MyEventFilter that is pointed to in this
example allows background applications to receive update events for their windows.
Listing 6-5 shows the resources, in Rez input format, that the Alert function uses to
display the alert box shown in Figure 6-13.
Dialog Manager
'ALRT' 128
'DITL' 128
Uses 'DITL' 128
OK button
Alert resource 'cicn' 128
Static text
Listing 6-5 Rez input for providing an alert box with items
Dialog Manager
Items are usually referred to by their positions in the item list resource. For example, the
Alert function returns 1 when the user clicks the OK button in the alert box created in
Listing 6-5. The Dialog Manager returns 1 because the OK button is the first item in the
list. (Responding to the item numbers returned by Alert and other Dialog Manager
functions is explained in “Handling Events in Alert and Dialog Boxes” beginning on
page 6-77.) Similarly, when you use a Dialog Manager routine to manipulate an item, you
specify it by its item number, an integer that corresponds to an item’s position in its item
list resource.
Dialog Manager
IMPORTANT
Item list resources should always be marked as purgeable. ▲
The Dialog Manager also calls the Resource Manager to read in any individual items
as necessary.
When you create a dialog box or an alert box, the Dialog Manager creates a dialog record.
The Dialog Manager then reads in the item list resource and stores a handle to it in the
items field of the dialog record. Because the Dialog Manager always makes a copy of the
item list resource and uses that copy, several independent dialog boxes may share
the same item list resource. As explained in “Adding Items to an Existing Dialog Box”
beginning on page 6-51, you can use the AppendDITL and ShortenDITL procedures
to modify or customize copies of a shared item list resource for use in individual
dialog boxes.
As an alternative to using a dialog resource, you can read in a dialog’s item list resource
directly and then pass a handle to it along with other information to NewDialog, which
creates the dialog box. Remember, however, that it is easier to localize your application if
you use a dialog resource and the GetNewDialog function.
An item list resource contains the following information for each item:
■ a display rectangle
■ the type of item (as described in the next section)
■ a constant (either enabled or disabled) that instructs the Dialog Manager whether
to report events for that item
■ either a text string or a resource ID, as appropriate for the type of item
The display rectangle determines the size and location of the item. Specify the display
rectangle in coordinates local to the alert or dialog box. For example, in Listing 6-5 the
first item is displayed in a rectangle specified by the coordinates (86,201,106,259), which
place the item in the lower-right corner of this alert box. More information about display
rectangles and their placement is provided in “Display Rectangles” beginning on
page 6-32.
In an item list resource, you can specify controls, text, icons, pictures, and other items that
you define. In Listing 6-5, the first item’s type is specified by the Button constant. Item
types and their constants are described in the next section.
For each item in the item list resource, you must also instruct the Dialog Manager
whether to report to your application when the item is clicked. In Listing 6-5, the first
item is enabled, because the enabled constant is specified. “Enabled and Disabled
Items” on page 6-36 explains when and how to enable items.
Depending on the type of item in the list, you usually provide a text string or a resource
ID for the item. In Listing 6-5, the string OK is specified as the button title for the first
item. “Resource IDs for Items” beginning on page 6-36 explains what titles and resources
are appropriate for the various item types.
The information that you provide in an item list resource is described more fully in the
next several sections.
Dialog Manager
Item Types 6
The following list shows the types of items you can include in alert and dialog boxes and
the constants for specifying them in a Rez input file.
Constant Description
Button A button control
CheckBox A checkbox control (use in dialog boxes only)
Control A control defined in a 'CNTL' resource file (use in dialog
boxes only)
EditText An editable text item (use in dialog boxes only)
HelpItem An invisible item that makes the Help Manager associate help
balloons with the other items defined in the item list resource
Icon An icon whose black-and-white version is stored in an 'ICON'
resource and whose color version is stored in a 'cicn' resource
with the same resource ID as the 'ICON' resource
Picture A QuickDraw picture stored in a 'PICT' resource
RadioButton A radio button control (use in dialog boxes only)
StaticText Static text; that is, text that cannot be edited
UserItem An application-defined item (use in dialog boxes only)
The chapter “Help Manager” in Inside Macintosh: More Macintosh Toolbox describes how to
create and use items of type HelpItem to provide help balloons for your alert and dialog
boxes. When you specify a help item, make it the last item in the list, as shown in Listing
6-5 on page 6-27.
The chapter “Finder Interface” in this book describes icon ('ICON') resources and color
icon ('cicn') resources. Inside Macintosh: Imaging describes 'PICT' resources.
The chapter “Control Manager” in this book describes how to create a control with
a 'CNTL' resource. Pop-up menus are easily implemented as controls. “Pop-Up Menus
as Items” beginning on page 6-42 illustrates how to include pop-up menus in your
dialog boxes.
Be aware that alert boxes should contain only buttons (which the user clicks to dismiss
the alert box), static text, icons, and pictures. If you need to present other items, you
should create a dialog box.
The first item in an alert box’s item list resource should be the OK button; if a Cancel
button is necessary, it should be the second item. The Dialog Manager provides these
constants for the first two item numbers:
CONST ok = 1;
cancel = 2;
As described in “Creating Alert Sounds and Alert Boxes” beginning on page 6-18, you
define within the alert resource whether the OK or the Cancel button is the default button
for each alert stage. The Dialog Manager automatically draws a bold outline around the
button that you specify and, if the user presses the Return key or Enter key, the Dialog
Dialog Manager
Manager responds—or your event filter function should respond—as if the default
button were clicked. (“Writing an Event Filter Function for Alert and Modal Dialog
Boxes” beginning on page 6-86 describes event filter functions.)
The Dialog Manager does not draw a bold outline around the default button for dialog
boxes. “Using an Application-Defined Item to Draw the Bold Outline for a Default
Button” beginning on page 6-56 shows how your application can outline the default
button in a dialog box. You should normally give every dialog box a default button—that
is, one whose action is invoked when the user presses the Return or Enter key. “Writing
an Event Filter Function for Alert and Modal Dialog Boxes” beginning on page 6-86
shows how to test for these key-down events and respond as if the user had clicked the
default button. If you don’t provide your own event filter function, the Dialog Manager
treats the first item in an item list resource as the default button. That is, although the
Dialog Manager doesn’t draw a bold outline around the button in a dialog box, the
Dialog Manager does return its item number to your application when the user presses
the Return or Enter key.
Don’t set a default button to perform a dangerous action—for example, one that causes
a loss of user data. If none of the possible actions is safe, don’t display a default border
around any button and provide an event filter function that ignores the Return and Enter
keys. This protects users from accidentally damaging their work by pressing Return or
Enter out of habit. However, you should try to design a safe action that the user can
invoke with a default button, such as a Save button. Figure 6-14 illustrates an alert box
that provides a default button for a safe action.
Provide a Cancel button whenever you can, and in your event filter function, map the
Command-period key combination and the Esc (Escape) key to the Cancel button.
Don’t display a bold outline around any button if you use the Return key in editable text
items, because using the same key for two different purposes confuses users and makes
the interface less predictable.
Dialog Manager
Display Rectangles 6
As previously mentioned, the display rectangle determines the location of an item within
an alert box or a dialog box. Use the alert or dialog box’s local coordinates to specify the
display rectangle.
For controls, the display rectangle becomes the control’s enclosing rectangle. To match
a control’s enclosing rectangle to its display rectangle, specify an enclosing rectangle
in the control resource that is identical to the one you specify for the display rectangle in
the item list resource. (The control resource is described in the chapter “Control
Manager” in this book.)
Note
Note that, when an item is a control defined in a control ('CNTL')
resource, the rectangle added to the update region is the rectangle
defined in the control resource, not the display rectangle defined in
the item list resource. ◆
For an editable text item, the display rectangle becomes the TextEdit destination rectangle
and its view rectangle. Word wrapping occurs within display rectangles that are large
enough to contain multiple lines of text, and the text is clipped if there’s more than will fit
in the rectangle. The Dialog Manager uses the QuickDraw procedure FrameRect to
draw a rectangle three pixels outside the display rectangle. For more detailed information
about TextEdit, see the chapter “TextEdit” in Inside Macintosh: Text.
For a static text item, the Dialog Manager draws the text within the display rectangle just
as it draws editable text items, except that the Dialog Manager doesn’t draw a frame
rectangle outside the display rectangle.
For an icon or a QuickDraw picture larger than its display rectangle, the Dialog Manager
scales the icon or picture to fit the display rectangle.
Although the procedure for an application-defined item can draw outside the item’s
display rectangle, this is not recommended, because if the Dialog Manager receives
an update event involving an area outside the display rectangle but inside the area where
you draw your application-defined item, the Dialog Manager won’t call your draw
procedure.
Note
A click anywhere in the display rectangle is considered a click in that
item. If display rectangles overlap, a click in the overlapping area
is considered a click in whichever item appears first in the item list
resource. ◆
You should display items in functional and consistent locations, both within your
application and across all applications that you develop. In alert boxes and in most dialog
boxes, place the OK button in the lower-right corner and place the Cancel
button to its left. Figure 6-15 shows the recommended location of buttons and text
in an alert box.
Dialog Manager
Figure 6-15 The consistent spacing of buttons and text in an alert box
23 23
pixels pixels
13 pixels
13 pixels
13 pixels
13 13
pixels pixels
Generally, you should use distances of 13 and 23 white pixels to separate the items in
dialog boxes and alert boxes. (When separating the default button from the window
edges and other items, don’t count the pixels that make up its bold outline.) However, be
aware that the Window Manager adds 3 white pixels inside the window frame when it
draws alert boxes and modal dialog boxes. Therefore, specify display rectangle locations
as follows when you use tools like Rez and ResEdit:
■ Place the display rectangle for the lower-right button 10 pixels from the right edge and
10 pixels from the bottom edge of the alert or modal dialog box; align the display
rectangles for other bottommost and rightmost items with this button.
■ Place the display rectangle for the upper-left icon (or similar item) 10 pixels from the
top edge and 20 pixels from the left of the alert or modal dialog box; align the display
rectangles for other topmost and leftmost items with this item. The Dialog Manager
automatically places the caution, note, and stop alert icons in this position when you
use the CautionAlert, NoteAlert, and StopAlert functions. When you use the
Alert function, you must specify the icon and the location.
■ Place the other elements in the alert or modal dialog box 13 or 23 pixels apart, as
shown in Figure 6-15.
For example, the rectangle for the alert box in Figure 6-15 has a specified height of
85 pixels. The display rectangle for the Save button has a bottom coordinate of 75, and the
display rectangle for the static text item has a top coordinate of 10. The Window Manager
adds 3 white pixels at the top of the alert box and 3 pixels at the bottom, so
the alert box contains 13 white pixels below the Save button and 13 white pixels above
the static text display rectangle. Listing 6-6 shows how the locations for these display
rectangles are specified in a Rez input file.
Dialog Manager
When specifying display rectangle locations for items in movable modal and modeless
dialog boxes, use the full distance of either 13 or 23 pixels to separate items from the
window edges. For example, if the items in Figure 6-15 were placed in a modeless dialog
box, the top coordinate of the Save button’s display rectangle should be 52 instead of 55,
and its bottom coordinate would be 72 instead of 75.
As explained in the previous section, the default button can be any button; its assign-
ment is secondary to the consistent placement of buttons. This rule keeps the OK button
and the Cancel button consistently placed. Otherwise, the buttons would keep changing
location depending on the default choice.
The Western reader’s eye tends to move from the upper-left area of the alert or dialog box
to the lower-right area. For Western versions of your software, use the upper-left area for
elements (such as the alert icon) that convey the initial impression that you want to make.
Place the buttons that a user clicks in the lower-right area.
The alignment of the items in an alert box or a dialog box may vary with localization.
Although in Roman script systems these items are generally aligned left to right, items
in Arabic or Hebrew script systems should generally be aligned right to left, because
Arabic and Hebrew are written from right to left. The TextEdit procedure TESetJust,
described in the chapter “TextEdit” in Inside Macintosh: Text, controls the alignment of
interface elements.
When line alignment is right to left, as in Hebrew and Arabic, the Control Manager
transposes checkboxes—and radio buttons—and their titles. That is, checkboxes and
radio buttons appear to the right of the text instead of to the left, as in Roman script
systems. Therefore, when you create checkboxes, radio buttons, and static text items
that need to align, make sure that their display rectangles are the same size.
The dialog box at the top of Figure 6-16 shows several checkboxes and radio buttons with
display rectangles of different sizes. The next dialog box in the figure illustrates what
happens to the alignment of these items after the Control Manager transposes
the controls with their titles.
The bottom two dialog boxes in Figure 6-16 illustrate how the Control Manager displays
properly sized items when transposing the controls with their titles.
Dialog Manager
Figure 6-16 Incorrectly and correctly sized display rectangles for alternate script systems
Dialog Manager
Constant Description
enabled Informs your application about events involving this item
disabled Doesn’t inform your application about events involving this item
Generally, you should enable only controls. In particular, you should enable buttons,
radio buttons, and checkboxes so that your application knows when they’ve been clicked.
You typically disable editable text and static text items. You normally disable editable text
items because you use the Dialog Manager function GetDialogItemText to read the
information in the items only after the user clicks the OK button. (Listing 6-12 on
page 6-49 illustrates how to use the GetDialogItemText function for this purpose.)
You should use static text items only for providing information; users don’t expect to
click them. Likewise, you typically disable icons and pictures that merely provide
information; if you use an icon or a picture as a buttonlike control to receive input,
however, you must enable it. If you create an application-defined item such as a moving
indicator to display information, you typically disable it. If you create an application-
defined item such as a buttonlike control to receive input, you must enable it.
Don’t confuse disabling an item with using the Control Manager procedure
HiliteControl to make a control inactive. When you don’t want the Control Manager
to respond to clicks in a control, you make it inactive; when you don’t want the Dialog
Manager to report clicks in a control, you make it disabled.
The Control Manager displays an inactive control in a way (dimmed, for example) that
shows it’s inactive, whereas the Dialog Manager makes no visual distinction between a
disabled item and an enabled item. Figure 6-17 shows the difference between an inactive
and an active control. The Control Manager procedure HiliteControl has been used
to dim the inactive Eject button. If a user clicks this button, the Control Manager does not
respond. However, when a user clicks the active Desktop button, the Control Manager
inverts the button for 8 ticks.
Buttons and other controls are generally enabled, and disabling them does not alter their
appearance; the enabled radio button in Figure 6-17 would appear the same if it were
disabled. Because the static text reading “Save this document as” in Figure 6-17 is not
a control, the application doesn’t need to respond clicks in the text. Therefore, the
application has disabled it; however, the static text would have the same appearance
if the application were to enable it.
Dialog Manager
Inactive control
Active control
Disabled item
Enabled item
Provide a resource ID for icons, QuickDraw pictures, and controls other than buttons,
checkboxes, and radio buttons. For an icon, provide the ID of an 'ICON' resource; for
a QuickDraw picture, the ID of a 'PICT' resource; and for a control (including a pop-
up menu), the ID of a 'CNTL' resource. In Listing 6-5 on page 6-27, the resource ID of 128
specifies which 'ICON' (and 'cicn') resources to use for the second item in the item
list resource.
For a button, checkbox, radio button, static text item, and editable text item, supply a text
string as the final element for the item in its item list resource. The next several sections
provide guidelines for the text that you should provide.
For your own application-defined items, supply neither a title nor a resource ID.
Listing 6-15 on page 6-57 shows an item list resource that includes an application-
defined item.
Dialog Manager
titles, thereby clarifying the states. Radio buttons should represent related, but not
necessarily opposite, choices. Give each radio button a title consisting of a word or a
phrase that identifies what the button does. Remember that, as described in the chapter
“Control Manager” in this book, the radio buttons in a group are mutually exclusive:
only one button in that group can be on at one time.
Whenever possible, title a button with a verb describing the action that the button
performs. A user typically reads the text in an alert box or a dialog box until it becomes
familiar and then relies on visual cues, such as button titles or positions, to respond.
Buttons such as Save, Quit, or Erase Disk allow users to identify and click the correct
button quickly. These titles are often more clear and precise than OK, Yes, and No. If the
action can’t be condensed into a word or two, OK and Cancel or Yes and No may serve
the purpose. If you use these generic titles, be sure to phrase the wording in the dialog
box so that the action the button initiates is clear. Figure 6-18 shows a dialog box with
appropriate OK and Cancel buttons.
Cancel means “dismiss this operation with no side effects.” It does not mean “I’ve read
this dialog box” or “stop what you’re doing regardless.” When users click the Cancel
button in your alert boxes, modal dialog boxes, and movable modal dialog boxes, your
application should revoke any actions it took since displaying the alert or dialog box and
then remove the box.
Your application should not remove a modeless dialog box when the user clicks a button;
rather, you should remove the dialog box when the user clicks its close box or chooses
Close from the File menu while the modeless dialog box is active.
When it is impossible to return to the state that existed before an operation began, don’t
use a Cancel button. You can use Stop or OK, which are useful in different situations. A
Stop button may leave the results of a partially complete task intact, whereas a Cancel
button always returns the application and its documents to their previous state. Use OK
for a button that closes the alert box, modal dialog box, or movable modal dialog box and
accepts any changes made while the dialog box was displayed.
Because of the difficulty in revoking the last action invoked from a modeless dialog box,
these dialog boxes typically don’t have Cancel buttons, although they may have Stop
buttons. For example, the movable modal dialog box shown in Figure 6-19 uses a Stop
Dialog Manager
button; clicking the button halts the current file copy operation but leaves intact the
copies that were previously made.
In an alert box that requires confirmation, use a button title that describes the result of
accepting the message in the alert box. For example, if an alert box asks “Revert to the
last saved version of the document,” use a Revert button rather than an OK button. Try to
use a verb in the button title; as in the Revert button in Figure 6-20, use the same verb
that you use in your alert message.
If the alert box presents the user with a situation in which no alternative actions are
available, give the box a single button that’s titled OK. You should interpret the user’s
clicking this button to mean “I’ve read the alert box.”
A modal dialog box usually cuts the user off from the task. That is, when making choices
in a modal dialog box, the user can’t see the area of the document that changes. The user
sees the changes only after dismissing the dialog box. If the changes aren’t appropriate,
then the user has to repeat the entire operation. To provide better feedback to the user,
you need to give the user a way to see what the changes will be. Therefore, any selection
made in a modal dialog box should immediately update the document contents, or you
should provide a sample area in the dialog box that reflects how the user’s selections will
change the document. In the case of immediate document updating, the OK button
means “accept this change” and the Cancel button means “undo all changes made
through this dialog box.”
The Dialog Manager displays button titles (as well as all other control titles) in the system
font. To make it easier to localize your application, you should not change
the font.
Dialog Manager
Dialog Manager
Figure 6-21 shows an example of a very poor alert message—the information is expressed
in the programmer’s vocabulary, and the user is offered no clue about
how to remedy the problem.
Figure 6-22 shows a somewhat better alert message. Although the vocabulary is less
technical, no remedy to the problem is offered.
Figure 6-23 illustrates a good alert message. The message is specific, it’s expressed in
nontechnical terms, it explains why the error occurred, and it suggests a solution to
the problem.
The best way to make an alert message understandable is to think carefully through the
error condition itself. Can the application handle this without an error? Is the message
specific enough so that the user can fix the situation? What are the recommended
solutions?
Dialog Manager
Dialog Manager
The modal dialog box shown in Figure 6-24 is created by defining a dialog resource that
describes the dialog box and by defining an item list resource that describes the dialog
items, including a control whose 'CNTL' resource uses the standard pop-up control
definition function. Listing 6-7 shows the dialog resource and item list resource for this
modal dialog box.
Listing 6-7 Rez input for a dialog resource and an item list resource for a dialog box that
includes a pop-up menu
Listing 6-8 shows the 'CNTL' and 'MENU' resources for the Speed pop-up menu shown
in Figure 6-24. Notice that the display rectangle specified for the control in the item list
resource is the same as the enclosing rectangle specified in the control resource. See the
chapter “Control Manager” in this book for a complete description of how to specify
values for a pop-up menu’s control resource.
Listing 6-8 Rez input for a control resource and a menu resource for a pop-up menu
Dialog Manager
Manipulating Items 6
In many cases, you won’t have to make any changes to alerts or dialog boxes after you
define them in your resource file. However, if you should want to modify an item, you
can use several Dialog Manager routines to do so.
Dialog Manager
For example, you can use the ParamText procedure to supply text strings (such as
document titles) to alert and dialog boxes dynamically. For most other types of item
manipulation, you must first call the GetDialogItem procedure to get the information
about the item. You then use other routines to manipulate that item. For example, you
can use the SetDialogItem procedure to change the item, or—to get a text string that
the user has entered in an editable text item after clicking the OK button—you can use
the GetDialogItemText procedure.
The Dialog Manager routines for manipulating items are summarized in the
following list.
Routine Description
AppendDITL Adds items to a dialog box.
CountDITL Counts the number of items in a dialog box.
FindDialogItem Finds an item that contains a specified point within a
dialog box.
GetAlertStage Returns the stage of the last occurrence of an alert.
GetDialogItem Returns the item type, the display rectangle, and the
control handle or application-defined procedure of a
given item in a dialog box.
GetDialogItemText Returns the text of a given editable text or static
text item.
HideDialogItem Hides the given item.
ParamText Substitutes up to four different text strings in static
text items.
ResetAlertStage Resets the stage of the last occurrence of an alert.
Dialog Manager
Routine Description
SelectDialogItemText Selects the text of an editable text item.
SetDialogItem Sets the item type and the display rectangle of an item,
or (for application-defined items) the draw procedure
of an item.
ShortenDITL Removes items from a dialog box.
ShowDialogItem Redisplays the item previously hidden by
HideDialogItem.
The next several sections describe the most frequently used of these routines. The next
section, “Changing Static Text,” explains the use of the ParamText procedure to
manipulate the text in static text items. “Getting Text From Editable Text Items”
beginning on page 6-48 describes how to use the GetDialogItemText procedure
to determine what the user types in an editable text item. Using the AppendDITL
procedure is explained in “Adding Items to an Existing Dialog Box” beginning on
page 6-51. “Using an Application-Defined Item to Draw the Bold Outline for a Default
Button” beginning on page 6-56 describes how to use SetDialogItem to install
application-defined items. For additional information about all of the previously listed
routines, see “Manipulating Items in Alert and Dialog Boxes” beginning on page 6-120
and “Handling Text in Alert and Dialog Boxes” beginning on page 6-129.
You can use the ParamText procedure to supply the names of document windows to
your alert and dialog boxes dynamically, as illustrated in the application-defined routine
MyCloseDocument shown in Listing 6-9.
Dialog Manager
Dialog Manager
IMPORTANT
To avoid recursion problems in versions of system sofware earlier than
7.1, you have to ensure that you do not include the characters ^0 through
^3 in any strings you pass to ParamText. This is why
MyCloseDocument uses another application-defined routine,
MyStringCheck, to filter these characters out of the window titles
passed to ParamText. ▲
Listing 6-10 shows a portion of an item list resource. When the application calls
CautionAlert, the Dialog Manager uses the first parameter passed previously to the
ParamText procedure to replace the characters ^0 in the static text with the title of the
document window.
Listing 6-10 Specifying where ParamText should substitute text in an alert box message
Dialog Manager
This dialog box prompts the user for two text strings: one to search for and another
to take the place of the first string. Listing 6-11 shows the item list resource for this
dialog box. The fifth item in the list is the editable text item where the user enters the text
string being sought; the sixth item is the item where the user enters the replacement
text string.
Listing 6-12 shows how the application handles a click in the Change button.
(Subsequent sections of this chapter explain how to handle events in a modeless
dialog box.)
Listing 6-12 Getting the text entered by the user in an editable text item
Dialog Manager
BEGIN
{use DialogSelect, then determine whether the event occurred }
{ in the Global Changes dialog box; if so, respond to mouse }
{ clicks as follows}
CASE itemHit OF
kChange: {user clicked the Change button}
BEGIN
GetDialogItem(myDialog, kFind, itemType,
searchStringHandle, itemRect);
GetDialogItemText(searchStringHandle, searchString);
GetDialogItem(myDialog, kReplace, itemType,
replaceStringHandle, itemRect);
GetDialogItemText(replaceStringHandle, replaceString);
{get a handle to the Stop button}
GetDialogItem(myDialog, kStop, itemType,
itemHandle, itemRect);
{make the Stop button active during the operation}
HiliteControl(ControlHandle(itemHandle), 0);
{get a handle to the Change button}
GetDialogItem(myDialog, kChange, itemType,
itemHandle, itemRect);
{make the Change button inactive during the operation}
HiliteControl(ControlHandle(itemHandle), 255);
DoReplace(searchString, replaceString);
{when the operation is complete, dim Stop and make }
{ Change active here}
END;
kStop: {user clicked the Stop button}
BEGIN
{cancel operation, then make Stop button }
{ inactive and Change button active again}
END;
END;
END;
In Listing 6-12, when the user clicks the Change button, the GetDialogItem procedure
returns a handle to the item containing the search string. Because this is a handle to an
editable text item, the application can pass the handle to the GetDialogItemText
procedure, which then returns the item’s text string in its second parameter. These two
procedures are then used to get the string in the item containing the replacement string.
These two strings are then passed to an application-defined routine that replaces all
Dialog Manager
instances of the first string with the characters of the second string. Note that when the
user clicks Change, the Control Manager procedure HiliteControl is used to make the
Stop button active and to make the Change button inactive—that is, dimmed. This
indicates that the user can use the Stop button but not the Change button while the
change operation is taking place.
Figure 6-28 illustrates an existing dialog box and a pair of items to be appended.
(0,200) (0,120)
(0,0) (0,0)
(90,0) (90,0)
Initial dialog box Items to be appended
Dialog Manager
(0,120) (0,200)
(0,0)
(90,0)
If you specify the appendDITLRight constant, AppendDITL appends the items to the
right side of the dialog box, as illustrated in Figure 6-30, by positioning the display
rectangles of the appended items relative to the upper-right coordinate of the dialog box.
The AppendDITL procedure automatically expands the dialog box to accommodate the
new dialog items.
Figure 6-30 The dialog box after items are appended to the right
(0,200) (0,320)
(0,0)
(90,0)
If you specify the appendDITLBottom constant, AppendDITL appends the items to the
bottom of the dialog box, as illustrated in Figure 6-31, by positioning the display
rectangles of the appended items relative to the lower-left coordinate of the dialog box.
The AppendDITL procedure automatically expands the dialog box to accommodate the
new dialog items.
Dialog Manager
Figure 6-31 The dialog box after items are appended to the bottom
(0,120) (0,200)
(0,0)
(90,0)
(180,0)
Figure 6-32 A dialog box with an item appended relative to an existing item
Dialog Manager
Dialog Manager
the second item list resource relative to item number 3 (the “Ignore Words in All Caps”
checkbox) in the dialog box. Listing 6-14 shows the dialog resource for the dialog box, its
regular item list resource, and the item list resource that AppendDITL adds to it.
Listing 6-14 Rez input for a dialog box and the item appended to it
The dialog resource specifies that the dialog box is invisible so that the application
can add the new item to the dialog box before displaying it. In Listing 6-13, the
DoSpellBoxWithSpanish routine uses the Window Manager procedure
ShowWindow to display the dialog box after its new item has been appended.
(“Displaying Alert and Dialog Boxes” beginning on page 6-61 describes more fully
how to display dialog boxes.)
Dialog Manager
The appended item list resource includes a help item that causes the Help Manager to
use the help resource associated with that item list resource in addition to the help
resource originally associated with the dialog box. See the chapter “Help Manager” in
Inside Macintosh: More Macintosh Toolbox for information about using the
HMScanAppendhdlg identifier in a help item.
Listing 6-13 uses the Resource Manager procedure ReleaseResource. The
AppendDITL procedure modifies the contents of the dialog box (for instance, by
enlarging it). To use an unmodified version of the dialog box at a later time, your
application needs to use ReleaseResource to release the memory occupied by the
appended item list. Otherwise, if your application calls AppendDITL to add items to that
dialog box again, the dialog box will remain modified by your previous call—for
example, it will still be longer at the bottom if you previously used the
appendDITLBottom constant.
When you can call the ShortenDITL procedure to remove items from the end of a
dialog item list, you specify a pointer to the dialog box and the number of items to
remove from the end of the item list. Note that ShortenDITL does not automatically
resize the dialog box; you can use the Window Manager procedure SizeWindow if you
need to resize the dialog box. You can use the CountDITL function to determine the
number of items in the item list resource for a dialog box.
Dialog Manager
The application-defined item is disabled because the Spell Check button, which lies
within the application-defined item, is enabled. Because the Spell Check button is listed
before the application-defined item in this item list resource, the Dialog Manager reports
when the user clicks the Spell Check button. However, note that when application-
defined items are enabled, the Dialog Manager reports their item numbers when the
user clicks them.
Note
Although the draw procedure for an application-defined item can draw
outside the item’s display rectangle, this is not recommended because
if the Dialog Manager receives an update event involving an area outside
the display rectangle but inside the area where you draw
your application-defined item, the Dialog Manager won’t call your
draw procedure. ◆
Listing 6-14 on page 6-55 shows the dialog resource for the dialog box. Notice that the
invisible constant in the dialog resource specifies that the dialog box should initially
be invisible.
You must provide a procedure that draws your application-defined item. Your draw
procedure must have two parameters: a dialog pointer and an item number from the
dialog box’s item list resource. For example, this is how you should declare the draw
procedure if you were to name it MyDrawDefaultButtonOutline:
The parameter theDialog is a pointer to the dialog box containing the application-
defined item. (If your procedure draws in more than one dialog box, this parameter tells
your procedure which dialog box to draw in.) The parameter theItem is a number
corresponding to the position of an item in the item list resource for the dialog box. (In
case the procedure draws more than one item, this parameter tells the procedure which
one to draw.)
Dialog Manager
Dialog Manager
Use the Window Manager procedure ShowWindow to display the previously invisible
dialog box. When ShowWindow is called in this example, a bold outline is drawn inside
the application-defined item and around the Spell Check button.
Listing 6-17 shows a procedure that draws a bold outline around a button of any size and
shape. This procedure can be used to draw the outline around the Spell Check button
from the previous example.
Listing 6-17 Creating a draw procedure that draws a bold outline around the default button
Dialog Manager
Listing 6-17 uses GetDialogItem to get the Spell Check button and then uses
several QuickDraw routines to draw a black outline around that button’s display
rectangle when the button is active. If the button is inactive (that is, dimmed),
MyDrawDefaultButtonOutline draws a gray outline.
Before drawing a gray outline, MyDrawDefaultButtonOutline determines whether
the dialog box uses a color graphics port. As explained in “Including Color in Your Alert
and Dialog Boxes” beginning on page 6-75, you can supply a dialog box with a color
graphics port by creating a dialog color table ('dctb') resource with the same resource
ID as the dialog resource. If the dialog box uses a color graphics port,
MyDrawDefaultButtonOutline uses the Color QuickDraw function GetGray to
return a blended gray based on the foreground and background colors. Then
Dialog Manager 6
Dialog Manager
The DialogSelect function uses the QuickDraw procedure SetPort to make the alert
or dialog box the current graphics port. The ModalDialog procedure and the functions
that create alert boxes use DialogSelect to respond to update and activate events. You
can also use DialogSelect to respond to update and activate events in your modeless
and movable modal dialog boxes. In response to update events, you can instead use the
UpdateDialog function, which also makes the dialog box the current graphics port.
In these cases, it’s generally not necessary for your application to call SetPort when
displaying, updating, or activating alert boxes and dialog boxes. See Inside Macintosh:
Imaging for more information about SetPort.
These and other related issues are explained in detail in the next several sections of
this chapter.
If your application positions alert or dialog boxes on its own, don’t use these
constants, because your code may conflict with the Dialog Manager. If you do use
these constants, use them to specify the positions of both alert boxes and dialog boxes.
The next three figures illustrate various alert boxes that might appear when the user is
working on two monitors: a 12-inch monitor (the main screen) that displays the menu bar
and a full-page monitor that displays a document window. These figures show where the
Dialog Manager places an alert box according to the position specified in
the alert resource.
Figure 6-33 shows an alert box displayed in response to an error made by the
user while working on a document; the alert resource specifies the
alertPositionParentWindow constant, which tells the Dialog Manager to
position the alert box over the frontmost window so that the window’s title bar
appears. This position is appropriate for an alert box or a dialog box that relates
directly to the frontmost window. You should always try to position alert boxes
and dialog boxes where the user is working.
Dialog Manager
Not all alert boxes or dialog boxes relate to the frontmost window. Some may relate
only to actions the user performs on the main screen. For example, Figure 6-34
illustrates an alert box displayed when the user chooses the About command from
the Apple menu. For an alert box or dialog box such as this, you should specify the
alertPositionMainScreen constant in the alert or dialog resource. Figure 6-34 shows
how the Dialog Manager centers such an alert box near the top of the main screen.
Dialog Manager
Sometimes you may need to display an alert box or a dialog box that applies neither to
the frontmost window nor to an action performed on the main screen. To catch the user’s
attention, you should position such an alert or dialog box on the screen where the user is
working. For example, if you need to alert the user that available disk space is low, you
should specify the alertPositionParentWindowScreen constant. Figure 6-35 shows
how the Dialog Manager displays such an alert box or dialog box when a document
window appears on a screen other than the main screen.
Figure 6-35 An alert box in the alert position of the document window screen
If you don’t specify a positioning constant, the Dialog Manager uses the rectangle
coordinates in your alert resource or dialog resource as global coordinates specifying
where to position your alert or dialog box. If you wish to specify the position yourself in
this manner, you should generally try to center alert and dialog boxes between the left
and right margins of the screen or the window where the user is working, whichever is
most appropriate. If you don’t use the positioning constants, you should also place the
tops of alert and dialog boxes (including the title bars of modeless and movable modal
dialog boxes) below the menu bar. You can use the GetMBarHeight function, described
in the chapter “Menu Manager” in this book, to determine the height of the menu bar.
Dialog Manager
Instead, the Event Manager continues sending your application activate events for
your windows as needed, which you typically handle in your normal event loop. (The
chapters “Event Manager” and “Window Manager” in this book explain how to
activate and deactivate windows.)
Plate 2 at the front of this book shows an alert box that an application displays when the
user chooses the About command in the Apple menu. Listing 6-18 shows an application-
defined routine, ShowMyAboutBox, that displays this alert box.
Listing 6-18 Deactivating the front window before displaying an alert box
PROCEDURE ShowMyAboutBox;
VAR
itemHit: Integer;
docWindow: WindowPtr;
event: EventRecord;
BEGIN
docWindow := FrontWindow; {get the front window}
{if there's a front window, deactivate it}
IF docWindow <> NIL THEN
DoActivate(docWindow, FALSE, event);
{then show the alert box}
itemHit := Alert(kAboutBoxID, @MyEventFilter);
END;
Figure 6-36 An alert box displayed only after the third alert stage
Dialog Manager
Listing 6-19 shows how you might use GetAlertStage to determine if such an alert
needs to be displayed before deactivating the document window.
Listing 6-19 Using GetAlertStage to determine when to deactivate the front window
PROCEDURE MyAlert;
VAR
itemHit: Integer;
alertStage: Integer;
docWindow: WindowPtr;
event: EventRecord;
BEGIN
docWindow := FrontWindow;
alertStage := GetAlertStage;
IF (alertStage >= 2) AND (docWindow <> NIL) THEN {at 3rd alert stage, }
DoActivate(docWindow, FALSE, event); { deactivate front window & }
itemHit := StopAlert(kStopAlertID, @MyEventFilter); { display alert box}
END;
So as not to create multiple versions of this dialog box whenever the user chooses the
Global Changes command, the application-defined routine DoGlobalChangesDialog,
shown in Listing 6-20, checks whether the dialog box already exists.
Dialog Manager
Listing 6-20 Ensuring that the modeless dialog box isn’t already open before creating it
In this example, a pointer to the modeless dialog box is stored in a global variable. If
the global variable does not contain a pointer, DoGlobalChangesDialog uses
GetNewDialog to create and draw the dialog box. Later, if the user decides to close the
modeless dialog box, the application merely hides it so that when the user needs it again,
DoGlobalChangesDialog can display the dialog box in the same location and with the
same text selected as when the user last used it. Hiding this dialog box is illustrated later
in Listing 6-30 on page 6-94.
If the dialog box has already been created, DoGlobalChangesDialog uses the Window
Manager procedures ShowWindow to make the dialog box visible and SelectWindow to
make it active.
Finally, DoGlobalChangesDialog uses the application-defined routine
MyAdjustMenus to adjust the menus as appropriate for the modeless dialog box.
Listing 6-34 on page 6-98 illustrates an application-defined routine,
DoActivateGlobalChangesDialog, that handles activate events for this
modeless dialog box. The DoActivateGlobalChangesDialog routine in
turn uses DialogSelect, which sets the graphics port to the modeless dialog
box whenever the user makes it active.
Dialog Manager
Dialog Manager
■ disable all of its menus except the Edit menu, as well as any inappropriate commands
in the Edit menu
■ use the Dialog Manager procedures DialogCut, DialogCopy, DialogPaste,
and DialogDelete to support the Cut, Copy, Paste, and Clear commands in editable
text items
■ provide your own code for supporting the Undo command
■ enable your application’s items in the Help menu as appropriate (system software
disables all items except the Hide Balloons/Show Balloons command)
You don’t need to do anything else for the system-handled menus—namely, Application,
Keyboard, and Help. System software handles these menus for you automatically.
The DialogCut, DialogCopy, DialogPaste, and DialogDelete procedures are
described beginning on page 6-132. Your application can test whether a dialog box is the
front window when handling mouse-down events in the Edit menu and then call these
routines as appropriate.
Figure 6-38 illustrates how an application disables all of its own menus except its Edit
menu when displaying a modal dialog box containing editable text items. Access to the
Edit menu benefits the user who instead of typing prefers copying from and pasting into
editable text items.
Dialog Manager
PROCEDURE MyAdjustMenus;
VAR
window: WindowPtr;
windowType: Integer;
menu: MenuHandle;
BEGIN
window := FrontWindow;
windowType := MyGetWindowType(window);
CASE windowType OF
kMyDocWindow: {document window is in front}
MyAdjustMenusForDocWindows;
kMyDialogWindow: {a dialog box is in front}
MyAdjustMenusForDialogs;
kDAWindow: {adjust menus accordingly for a DA window}
MyAdjustMenusForDA;
kNil: {there isn't a front window}
MyAdjustMenusNoWindows;
END; {of CASE}
DrawMenuBar; {redraw menu bar}
END;
Listing 6-22 Disabling menus for a modal dialog box with editable text items
PROCEDURE MyAdjustMenusForDialogs;
VAR
window: WindowPtr;
windowType: Integer;
myErr: OSErr;
menu: MenuHandle;
BEGIN
window := FrontWindow;
Dialog Manager
windowType := MyGetWindowType(window);
CASE windowType OF
kMyModalDialogs:
BEGIN
menu := GetMenuHandle(mApple); {get handle to Apple menu}
IF menu = NIL THEN
EXIT(MyAdjustMenusForDialogs);
DisableItem(menu, 0); {disable Apple menu to get control of menus}
myErr := HMSetMenuResID(mFile, kFileHelpID); {set up help balloons}
menu := GetMenuHandle(mFile); {get handle to File menu}
IF menu = NIL THEN
EXIT(MyAdjustMenusForDialogs);
DisableItem(menu, 0); {disable File menu}
myErr := HMSetMenuResID(mFile, kFileHelpID); {set up help balloons}
IF myErr <> NoErr THEN
EXIT(MyAdjustMenusForDialogs);
menu := GetMenuHandle(mTools); {get handle to Tools menu}
IF menu = NIL THEN
EXIT(MyAdjustMenusForDialogs);
DisableItem(menu, 0); {disable Tools menu}
myErr := HMSetMenuResID(mTools, kToolsHelpID); {help balloons}
IF myErr <> NoErr THEN
EXIT(MyAdjustMenusForDialogs);
MyAdjustEditMenuForModalDialogs;
END; {of kMyModalDialogs CASE}
kMyGlobalChangesModelessDialog:
; {adjust menus here as needed}
kMyMovableModalDialog:
; {adjust menus here as follows: }
{ disable all menus except Apple, then }
{ call MyAdjustEditMenuForModalDialogs for editable text items}
END; {of CASE}
END;
Dialog Manager
Listing 6-23 Adjusting the Edit menu for a modal dialog box
PROCEDURE MyAdjustEditMenuForModalDialogs;
VAR
window: WindowPtr;
menu: MenuHandle;
selection, undo: Boolean;
offset: LongInt;
undoText: Str255;
BEGIN
window := FrontWindow;
menu := GetMenuHandle(mEdit); {get a handle to the Edit menu}
IF menu = NIL THEN {add your own error handling}
EXIT (MyAdjustEditMenuForModalDialogs);
undo := MyIsLastActionUndoable(undoText);
IF undo THEN {if action can be undone}
BEGIN
EnableItem(menu, iUndo);
SetMenuItemText(menu, iUndo, undoText);
END
ELSE {if action can't be undone}
BEGIN
SetMenuItemText(menu, iUndo, gCantUndo);
DisableItem(menu, iUndo);
END;
selection := MySelection(window);
IF selection THEN
BEGIN {enable editing items if there's a selection}
EnableItem(menu, iCut);
EnableItem(menu, iCopy);
END
ELSE
BEGIN {disable editing items if there isn't a selection}
DisableItem(menu, iCut);
DisableItem(menu, iCopy);
END;
IF MyGetScrap(NIL, 'TEXT', offset) > 0 THEN
EnableItem(menu, iPaste) {enable if something to paste}
ELSE
DisableItem(menu, iPaste);{disable if nothing to paste}
DisableItem(menu, iSelectAll);
DisableItem(menu, iCreatePublisher);
DisableItem(menu, iSubscribeTo);
DisableItem(menu, iPubSubOptions);
END;
END;
Dialog Manager
See the chapter “Menu Manager” in this book for more information on menus and the
menu bar.
When the user dismisses the alert box or modal dialog box, the Menu Manager restores
all menus to their state prior to the appearance of the alert or modal dialog box—unless
your application handles its own menu bar access, in which case you must restore the
menus to their previous states. You can use a routine similar to MyAdjustMenus, shown
in Listing 6-21 on page 6-70, to adjust the menus appropriately according to the type of
window that becomes the frontmost window.
Dialog Manager
Dialog Manager
to your application while it is in the background (although it is possible for your applica-
tion to determine if the notification was received). If you need to solicit information from
the user, use the Notification Manager to ask the user to bring your application to the
foreground. The user can then respond to your alert box or modal dialog box. See the
chapter “Notification Manager” in Inside Macintosh: Processes for information about the
Notification Manager.
Listing 6-24 Rez input for a dialog color table resource using the system’s default colors
Dialog Manager
By using the system’s default colors, you ensure that your application’s interface is
consistent with that of the Finder and other applications. However, if you feel absolutely
compelled to break from this consistency, the Dialog Manager offers you the ability to
specify colors other than the default colors. Be aware, however, that nonstandard colors
in your alert and dialog boxes may initially confuse your users.
Also be aware that despite any changes you make, users can alter the colors of alert and
dialog boxes anyway by changing the settings in the Color control panel.
Your application can specify its own colors in an alert color table ('actb') resource with
the same resource ID as the alert resource or in a dialog color table ('dctb') resource
with the same resource ID as the dialog resource. Both of these resources have exactly the
same format as a window color table ('wctb') resource, described in the chapter
“Window Manager” in this book.
▲ WARNING
Because the behavior of color alert and dialog boxes, color items, and
color icons is unreliable on computers using system software versions
earlier than System 7, do not specify colors for these elements if you wish
to maintain backward compatibility. ▲
You don’t have to call any new routines to change the colors used in alert or dialog boxes.
When you call the GetNewDialog function, for example, the Dialog Manager
automatically attempts to load a dialog color table resource with the same resource ID
as the dialog resource.
Likewise, you can change the system default colors for controls and the color, style,
typeface, and size of text used in an alert box or a dialog box by creating an item color
table ('ictb') resource with the same resource ID as the item list resource. You don’t
have to call any routines to create color items. When you use the GetNewDialog
function, the Dialog Manager looks first for an item color table resource with the same
resource ID as that of the item list resource.
Note
If you want to provide an item color table resource for an alert box or
a dialog box, you must create an alert color table resource or a dialog
color table resource, even if the item color table resource has no actual
color information and describes only static text and editable text style
changes. You cannot use an item color table resource to set the font on
computers that do not support Color QuickDraw. Also, be aware that
changing the default system font makes your application more difficult
to localize. ◆
Even if you provide your own 'dctb', 'actb', or 'ictb' resources, you do not
need to test whether your application is running on a computer that supports Color
QuickDraw in order to use these resources.
Dialog Manager
Dialog Manager
Dialog Manager
Dialog Manager
Generally, your application should handle menu bar access when you display dialog
boxes containing editable text items. Leave your Edit menu enabled, and use the
DialogCut, DialogCopy, DialogPaste, and DialogDelete procedures to support
the Cut, Copy, Paste, and Clear commands and their keyboard equivalents. You should
also provide your own code to support the Undo command. “Adjusting Menus for
Modal Dialog Boxes” beginning on page 6-68 and “Adjusting Menus for Movable Modal
and Modeless Dialog Boxes” on page 6-73 describe how to allow users to access your Edit
menu when you display dialog boxes.
If you don’t supply your own event filter function and the user presses the Return or
Enter key while a modal dialog box is onscreen, the Dialog Manager treats the event as a
click on the default button (that is, the first item in the list) regardless of whether the
dialog box contains an editable text item. If your event filter function responds to the user
pressing Return and Enter by moving the cursor in editable text items, don’t display a
bold outline around any buttons. If your event filter function responds to the user
pressing Return and Enter as if the user clicks the default button, then you should
display a bold outline around the default button. See “Writing an Event Filter Function
for Alert and Modal Dialog Boxes” beginning on page 6-86 for an example of how to map
the Return and Enter keys to the default button in your dialog boxes.
Initially, an editable text item may contain default text or no text. You can provide default
text either by specifying a text string as the last element for that item in the item list
resource or by using the SetDialogItemText procedure, which is described on
page 6-131.
When a dialog box that contains editable text items is first displayed, the insertion
point usually appears in the first editable text item in the item list resource. You may
instead want to use the SelectDialogItemText procedure so that the dialog box
appears with text selected, or so that an insertion point or a text selection reappears if
the user makes an error while entering text. For example, the user who accidentally types
nonnumeric input when a number is required can be given the opportunity to type the
entry again. The SelectDialogItemText procedure is described in detail on
page 6-131.
By default, the Dialog Manager displays editable text items in the system font. To
maintain visual consistency across applications for your users and to make it easier to
localize your application, you should not change the font or font size.
Dialog Manager
Dialog Manager
For events inside the alert box, ModalDialog passes the event to an event filter function
before handling the event. The event filter function provides a secondary event-handling
loop for handling events that ModalDialog doesn’t handle and for overriding events
that ModalDialog would otherwise handle. You should provide a simple event filter
function for every alert box and modal dialog box in your application.
You specify a pointer to your event filter function in the second parameter to the Alert,
StopAlert, CautionAlert, and NoteAlert functions. In the MyCloseDocument
routine shown on page 6-47, a pointer to the MyEventFilter function is specified. In
most cases, you can use the same event filter function in every one of your alert and
modal dialog boxes. An example of a simple event filter function that allows background
applications to receive update events and performs the other necessary event handling is
provided in “Writing an Event Filter Function for Alert and Modal Dialog Boxes”
beginning on page 6-86.
Unless your event filter function handles the event in its own way and returns TRUE,
ModalDialog handles the event inside the alert box as follows:
■ In response to an activate or update event for the alert box, ModalDialog activates or
updates its window.
■ If the user presses the mouse button while the cursor is in a control, the Control
Manager function TrackControl tracks the mouse. If the user releases the
mouse button while the cursor is in an enabled control, Alert, StopAlert,
CautionAlert, and NoteAlert remove the alert box and return the control’s
item number. (Generally, buttons should be the only controls you use in alert boxes.)
■ If the user presses the mouse button while the cursor is in any enabled item other than
a control, Alert, StopAlert, CautionAlert, and NoteAlert remove the alert box
and return the item number. (Generally, button controls should be the only enabled
items in alert boxes.)
■ If the user presses the mouse button while the cursor is in a disabled item, or if it is
in no item, or if any other event occurs, Alert, StopAlert, CautionAlert, and
NoteAlert do nothing.
Dialog Manager
Note
Do not use ModalDialog for modeless or movable modal
dialog boxes. ◆
The code that supports the modal dialog box shown in Figure 6-40 must respond to
events in four controls: two checkboxes and two buttons.
Dialog Manager
Dialog Manager
Dialog Manager
■ If the user presses the mouse button while the cursor is in a control, ModalDialog
calls the Control Manager function TrackControl. If the user releases the mouse
button while the cursor is in an enabled control, ModalDialog returns the control’s
item number. Your application should respond appropriately; for example, Listing 6-26
uses an application-defined routine that checks the spelling of a document when the
user clicks the Spell Check button.
■ If the user presses the mouse button while the cursor is in any other enabled item in
the dialog box, ModalDialog returns the item’s number, and your application should
respond appropriately. Generally, only controls should be enabled. If your application
creates a complex control—such as one that measures how far a dial is moved—your
application must provide an event filter function to handle mouse events in that item.
■ If the user presses the mouse button while the cursor is in a disabled item or in no
item, or if any other event occurs, ModalDialog does nothing.
Writing an Event Filter Function for Alert and Modal Dialog Boxes 6
For alert and modal dialog boxes, the Dialog Manager provides a standard event filter
function that checks whether the user has pressed the Enter or Return key and, if so,
returns the item number of the default button. In early versions of Macintosh system
software, when a single application controlled the computer, the standard event filter
function for alert boxes and most modal dialog boxes was usually sufficient. However,
because the standard event filter function does not permit background applications to
receive or respond to update events, it is no longer sufficient.
Thus, your application should provide a simple event filter function that performs these
functions and also allows inactive windows to receive update events. You can use the
same event filter function in most or all of your alert and modal dialog boxes.
You can also use your event filter function to handle other events that ModalDialog
doesn’t handle—such as the Command-period key-down event, disk-inserted events,
keyboard equivalents, and mouse-down events (if necessary) for application-defined
items that you provide.
For example, the standard event filter function ignores key-down events for the
Command key. When your application allows the user to access your menus after you
display a dialog box, your event filter function should handle keyboard equivalents for
menu commands and return TRUE.
At a minimum, your event filter function should perform the following tasks:
■ return TRUE and the item number for the default button if the user presses the Return
or Enter key
■ return TRUE and the item number for the Cancel button if the user presses the Esc key
or the Command-period key combination
■ update your windows in response to update events (this also allows background
applications to receive update events) and return FALSE
■ return FALSE for all events that your event filter function doesn’t handle
You can also use the event filter function to test for and respond to keyboard equivalents
and more complex events—for instance, the user dragging the cursor in an application-
Dialog Manager
defined item. For example, if you provide an application-defined item that requires you
to measure how long the user holds down the mouse button or how far the user drags
the cursor, use the event filter function to handle events inside that item.
If it seems that you will spend time replicating much of your primary event loop in this
event filter function, you might consider handling all the events in your main event loop
instead of using the Dialog Manager’s Alert, NoteAlert, StopAlert, and
CautionAlert functions or ModalDialog procedure.
Your own event filter function should have three parameters and return a Boolean value.
For example, this is how to declare an event filter function named MyEventFilter:
After receiving an event that it does not handle, your function should return FALSE.
When your function returns FALSE, ModalDialog handles the event, which you pass
in the parameter theEvent. (Your function can also change the event to simulate a
different event and return FALSE, which passes the altered event to the Dialog Manager
for handling.) If your function does handle the event, your function should return TRUE
as a function result and, in the itemHit parameter, the number of the item that it
handled. The ModalDialog procedure and, in turn, the Alert, NoteAlert,
StopAlert, and CautionAlert functions then return this item number in their own
itemHit parameter.
Because ModalDialog calls the GetNextEvent function with a mask that excludes
disk-inserted events, your event filter function can call the Event Manager procedure
SetSystemEventMask to accept disk-inserted events. See the chapter “Event Manager”
in this book for a discussion about handling disk-inserted events.
For alert and modal dialog boxes, the Dialog Manager provides a standard event filter
function that checks whether the user has pressed the Enter or Return key and, if so,
returns the item number of the default button. Your event filter function should always
check whether the Return key or Enter key was pressed and, if so, return the item
number of the default button in the itemHit parameter and a function result of TRUE.
Your event filter function should also check whether the Esc key was pressed and, if so,
return the item number for the Cancel button in the itemHit parameter and a function
result of TRUE. Your event filter function should also respond to the Command-period
key-down event as if the user had clicked the Cancel button.
To give visual feedback indicating which item has been selected, you should invert
buttons that are activated by keyboard equivalents for all alert and dialog boxes. A
good rule of thumb is to invert a button for 8 ticks, long enough to be noticeable but
not so long as to be annoying. The Control Manager performs this action whenever
a user clicks a button, and your application should do this whenever a user presses the
keyboard equivalent of a button click.
For modal dialog boxes that contain editable text items, your application should handle
menu bar access to allow use of your Edit menu and its Cut, Copy, Paste, Clear, and
Undo commands, as explained in “Adjusting Menus for Modal Dialog Boxes” beginning
Dialog Manager
on page 6-68. Your event filter function should then test for and handle mouse-down
events in the menu bar and key-down events for keyboard equivalents of Edit menu
commands. Your application should respond to users’ choices from the Edit menu by
using the procedures DialogCut, DialogCopy, DialogPaste, and DialogDelete to
support the Cut, Copy, Paste, and Clear commands.
Listing 6-27 shows MyEventFilter, which begins by handling update events in
windows other than the alert or dialog box. (By responding to update events for your
application’s own inactive windows in this way, you allow ModalDialog to perform
a minor switch when necessary so that background applications can update their
windows, too.)
Next, MyEventFilter handles activate events. This event filter function then handles
key-down events for the Return and Enter keys as if the user had clicked the default
button, and it handles key-down events for the Esc key as if the user had clicked the
Cancel button. (See Inside Macintosh: Text for information about character codes for the
Return, Enter, and Esc keys.) Your event filter function can then include tests for other
events, such as disk-inserted events and keyboard equivalents.
Listing 6-27 A typical event filter function for alert and modal dialog boxes
Dialog Manager
To use this event filter function for an alert box, the application specifies a pointer to
MyEventFilter when it calls one of the Alert functions, as shown in Listing 6-19 on
page 6-66. To use this event filter function for a modal dialog box, the application
specifies a pointer to MyEventFilter when it calls ModalDialog, as shown in
Listing 6-26 on page 6-83.
Dialog Manager
▲ WARNING
The IsDialogEvent and DialogSelect functions are unreliable
when running in versions of system software previous to System 7. ▲
Alternatively, and probably most efficiently, your application can respond to events in
modeless and movable modal dialog boxes by first determining the type of event that
occurred and then taking the appropriate action according to which type of window is
in front. If a modeless or movable modal dialog box is in front, you can provide code
that takes any actions specific to that dialog box. You can then use the DialogSelect
function instead of the Control Manager functions FindControl and TrackControl to
handle mouse events in your dialog boxes. The DialogSelect function also handles
update events, activate events, and events in editable text items. (If your modeless or
movable modal dialog box contains editable text items, you should call DialogSelect
during null events to cause the text cursor to blink.)
If you choose to determine whether events involve movable modal or modeless dialog
boxes without the aid of the IsDialogEvent function, your application should be
prepared to handle the following mouse events:
■ clicks in the menu bar, which your application has adjusted as appropriate for the
dialog box. Be sure to use the procedures DialogCut, DialogCopy, DialogPaste,
and DialogDelete to support the Cut, Copy, Paste, and Clear commands in editable
text items in your dialog boxes.
■ clicks in the content region of an active movable modal or modeless dialog box. You
can use the DialogSelect function to aid you in handling the event.
■ clicks in the content region of an inactive modeless dialog box. In this case, your
application should make the modeless dialog box active by making it the front-
most window.
■ clicks in the content region of an inactive window whenever a movable modal or
modeless dialog box is active. For movable modal dialog boxes, your application
should emit the system alert sound, whereas for modeless dialog boxes, your
application should bring the inactive window to the front.
■ mouse-down events in the drag region (that is, the title bar) of an active movable
modal or modeless dialog box. Your application should use the Window Manager
procedure DragWindow to move the dialog box in response to the user’s actions.
■ mouse-down events in the drag region of an inactive window when a movable
modal dialog box is active. Your application should not move the inactive window
in response to the user’s actions. Instead, your application should play the system alert
sound.
■ clicks in the close box of a modeless dialog box. Your application should dispose of or
hide the modeless dialog box, whichever action is more appropriate.
Figure 6-41 shows a simple modeless dialog box with editable text items.
Listing 6-28 illustrates an application-defined procedure that handles mouse-down
events for all windows, including the modeless dialog box shown in Figure 6-41.
Dialog Manager
Figure 6-41 A modeless dialog box for which DialogSelect reports events
Dialog Manager
The DoMouseDown routine first uses the Window Manager function FindWindow to
determine approximately where the cursor is when the mouse button is pressed. When
the user presses the mouse button while the cursor is in the content area of a window,
DoMouseDown first checks whether the mouse-down event occurs in the currently active
window by comparing the window pointer returned by FindWindow with that returned
by the Window Manager function FrontWindow.
When the mouse-down event occurs in an inactive window, DoMouseDown uses another
application-defined routine, MyIsMovableModal, to check whether the active window
is a movable modal dialog box. If so, DoMouseDown plays the system alert sound.
Otherwise, DoMouseDown uses the Window Manager procedure SelectWindow
to make the selected window active. (Although not illustrated in this book, the
MyIsMovableModal routine uses the Window Manager function GetWVariant to
determine whether the variation code for the front window is movableDBoxProc. If so,
MyIsMovableModal returns TRUE.) See the chapter “Window Manager” in this book for
more information about the SelectWindow and GetWVariant routines.
As in this example, you must ensure that the movable dialog box is modal within your
application. That is, the user should not be able to switch to another of your application’s
windows while the movable modal dialog box is active. Instead, your application should
emit the system alert sound. Notice as well that when the mouse-down event occurs in
the drag region of any window, DoMouseDown checks whether the drag region belongs
to an inactive window while a movable modal dialog box is active. If it does,
DoMouseDown again plays the system alert sound. (However, by clicking other applica-
tions’ windows or by selecting other applications from the Application and Apple menus,
users should be able to switch your application to the background when you display a
movable modal dialog box—an action users cannot perform with fixed- position modal
dialog boxes.)
If a user presses the mouse button while the cursor is in the content region of the active
window, DoMouseDown calls another application-defined routine, DoContentClick,
to further handle mouse events. Listing 6-29 shows how this routine in turn uses the
DialogSelect function to handle the mouse-down event after the application
determines that it occurs in the modeless dialog box shown in Figure 6-41 on page 6-91.
Listing 6-29 Using the DialogSelect function for responding to mouse-down events
Dialog Manager
In this example, when the user clicks the Change button, DialogSelect returns its item
number. Within the user’s document, the application then performs a global search and
replace. (Listing 6-12 on page 6-49 illustrates how an application can use the
GetDialogItem and GetDialogItemText procedures for this purpose.) Generally,
only controls should be enabled in a dialog box; therefore, your application normally
responds only when DialogSelect returns TRUE after the user clicks an enabled
control. For example, if the event is an activate or update event for a dialog box,
DialogSelect activates or updates it and returns FALSE, so your application does not
need to respond to the event.
At this point, you may also want to check for and respond to any special events that you
do not wish to pass to DialogSelect or that require special processing before you pass
them to DialogSelect. You would need to do this, for example, if the dialog box needs
to respond to disk-inserted events.
IMPORTANT
When DialogSelect calls TrackControl, it does not allow you to
specify any action procedures necessary for a more complex control—
for example, a control that measures how long the user holds down
the mouse button or one that measures how far the user has moved
an indicator. For instances like this, you can create a picture or an
application-defined item that draws a control-like object; you must then
test for and respond to those events yourself before passing events to
DialogSelect. Or, you can use the Control Manager functions
FindControl and TrackControl to process the mouse events inside
the controls of your dialog box. ▲
Listing 6-28 on page 6-91 calls one of its application-defined routines, DoCloseCmd,
whenever the user clicks the close box of the active window. If the active window is a
modeless dialog box, you might find it more efficient to hide the window rather than
remove its data structures. Listing 6-30 shows how you can use the Window Manager
routine HideWindow to hide the Global Changes modeless dialog box when the user
Dialog Manager
clicks its close box. The next time the user chooses the Global Changes command, the
dialog box is already available, in the same location and with the same text selected as
when it was last used. (Listing 6-20 on page 6-67 illustrates how first to create and later
redisplay this modeless dialog box.)
PROCEDURE DoCloseCmd;
VAR
myWindow: WindowPtr;
myData: MyDocRecHnd;
windowType: Integer;
BEGIN
myWindow := FrontWindow;
windowType := MyGetWindowType(myWindow);
CASE windowType OF
kMyGlobalChangesModelessDialog:
HideWindow(myWindow);
kMySpellModelessDialog:
HideWindow(myWindow);
kMyDocWindow:
BEGIN
myData := MyDocRecHnd(GetWRefCon(myWindow));
MyCloseDocument(myData);
END; {of kMyDocWindow case}
kDAWindow:
CloseDeskAcc(WindowPeek(myWindow)^.windowKind);
END; {of CASE}
END;
Dialog Manager
Listing 6-31 illustrates how an application can check for keyboard equivalents whenever
it receives key-down events. If the user holds down the Command key while pressing
another key, the application calls another of its application-defined procedures,
DoMenuCommand, which handles keyboard equivalents for menu commands. See the
chapter “Menu Manager” in this book for an example of a DoMenuCommand procedure.
Remember that when a movable modal dialog box or a modeless dialog box is active,
your application should adjust the menus appropriately, and use the procedures
DialogCut, DialogCopy, DialogPaste, and DialogDelete to support the Cut,
Copy, Paste, and Clear commands in editable text items.
Listing 6-31 Checking for key-down events involving the Command key
After determining that a key-down event does not involve a keyboard equivalent, Listing
6-31 calls another of its own routines, MyHandleKeyDown, which is shown
in Listing 6-32.
Dialog Manager
windowType := MyGetWindowType(window);
IF windowType = kMyDocWindow THEN {key-down in doc window}
BEGIN {handle keystrokes in document window here}
END
ELSE {key-down in modeless dialog box}
MyHandleKeyDownInModeless(event, windowType);
END;
Dialog Manager
Dialog Manager
You should use the Control Manager procedure HiliteControl to make the buttons
and other controls inactive in a modeless or movable modal dialog box when you
deactivate it. The HiliteControl procedure dims inactive buttons, radio buttons,
checkboxes, and pop-up menus to indicate to the user that clicking these items has no
effect while the dialog box is in the background. When you activate a modeless or
movable modal dialog box again, you should use HiliteControl to make the controls
active again.
The application-defined DoActivateGlobalChangesDialog routine shown in Listing
6-34 illustrates how to use HiliteControl to make the Change button active when
activating a modeless dialog box and how to make the Change and Stop buttons inactive
when deactivating the dialog box.
Dialog Manager
Dialog Manager
kMyGlobalChangesModelessDialog:
BEGIN
BeginUpdate(window);
UpdateDialog(window, window^.visRgn);
EndUpdate(window);
END;
{handle cases for other window types here}
END; {of CASE}
END;
Dialog Manager 6
when the user clicks its close box. The next time the user invokes the Global Changes
command, the dialog box is already available, in the same location and with the same
text selected as when it was last used.
If you adjust the menus when you display a dialog box, be sure to return them to an
appropriate state when you close the dialog box, as described in “Adjusting Menus for
Modal Dialog Boxes” beginning on page 6-68 and “Adjusting Menus for Movable Modal
and Modeless Dialog Boxes” on page 6-73.
Data Structure 6
This section describes the dialog record. Your application doesn’t need to create or use
this record; rather, your application simply uses the appropriate Dialog Manager
routines, creates any necessary resources, and then allows the Dialog Manager to create
and use records of this data type as necessary. The dialog record is described here for
completeness only.
Dialog Manager
DialogRecord =
RECORD
window: WindowRecord; {dialog window}
items: Handle; {item list resource}
textH: TEHandle; {current editable text item}
editField: Integer; {editable text item number }
{ minus 1}
editOpen: Integer; {used internally; reserved}
aDefItem: Integer; {default button item number}
END;
Field descriptions
window The window record for the alert box or dialog box.
items A handle to the item list resource for the alert or the dialog box.
textH A handle to the current editable text item.
editField The current editable text item.
editOpen Used internally; reserved.
aDefItem The item number of the default button.
Table 6-1 Mapping between new and previous names of Dialog Manager routines
Dialog Manager
Table 6-1 Mapping between new and previous names of Dialog Manager routines (continued)
InitDialogs 6
Dialog Manager
resumeProc
A pointer to a procedure used by the System Error Handler in case a fatal
system error occurs on a system that predates MultiFinder. For System 7,
your application should set this parameter to NIL.
DESCRIPTION
Before using the Dialog Manager, you must initialize QuickDraw, the Font Manager,
the Window Manager, the Menu Manager, and TextEdit, in that order. Then, to
initialize the Dialog Manager, call InitDialogs once before all other Dialog Manager
routines. The InitDialogs procedure does the following initialization:
■ It saves the pointer passed in the resumeProc parameter. For System 7, your
application should set the resumeProc parameter to NIL.
■ It installs the system alert sound. To change the system alert sound, use the
ErrorSound procedure.
■ It passes empty strings to the ParamText procedure.
ErrorSound 6
To use your own alert sound instead of the system alert sound for signaling the user, use
the ErrorSound procedure.
DESCRIPTION
The Dialog Manager uses the system alert sound for signaling the user during various
alert stages. The system alert sound, which is a sound resource stored in the System
file, is played whenever system software or your application uses the Sound Manager
procedure SysBeep. By changing the setting in the Sound control panel, the user can
determine which sound is played. If you want to use sounds other than the system
alert sound at various alert stages, write your own sound procedure and call the
ErrorSound procedure to make it the current sound procedure.
SPECIAL CONSIDERATIONS
If you pass NIL in the soundProc parameter, the Dialog Manager neither plays sounds
nor causes the menu bar to blink, and thus the user receives no signal.
SEE ALSO
See the description of MyAlertSound on page 6-144 for a discussion of how to write
the sound procedure pointed to by the soundProc parameter. For examples of how to
incorporate sound alerts into alert stages, see Listing 6-2 on page 6-21 and Listing 6-3 on
page 6-22.
Dialog Manager
SetDialogFont 6
Although you generally should not change the font used in static and editable text items,
you can do so with the SetDialogFont procedure. The SetDialogFont procedure is
also available as the SetDAFont procedure.
fontNum A font ID number. Do not rely on font number constants. Instead, use
the Font Manager function GetFNum to find the font number to pass in
this parameter.
DESCRIPTION
For subsequently created dialog and alert boxes, SetDialogFont sets the font of the
dialog or alert box’s graphics port to the specified font. If you don’t call this procedure,
the system font is used. The SetDialogFont procedure does not affect titles of controls,
which are always displayed in the system font.
SPECIAL CONSIDERATIONS
There are a number of caveats regarding the SetDialogFont procedure.
First, the Standard File Package does not always properly calculate the position of the
standard file dialog box once this procedure has been called; for example, the standard
file dialog box may be partially obscured by a menu bar. Second, be aware that this
procedure affects all static text and editable text items in all of the alert and dialog boxes
you subsequently display. Third, SetDialogFont does not change the font for control
titles. Fourth, you can’t use SetDialogFont to change the font size or font style. Finally,
and most importantly, your application will be much easier to localize if you always use
the system font in your alert and dialog boxes and never use SetDialogFont.
SEE ALSO
See the chapter “Font Manager” in Inside Macintosh: Text for information about the
GetFNum function.
Creating Alerts 6
To create an alert—consisting of an alert sound, an alert box, or both—use one of
these functions: NoteAlert, CautionAlert, StopAlert, and Alert. The first
three functions display, respectively, the note, caution, and stop alert icons (see
Figure 6-3, Figure 6-4, and Figure 6-5) in the upper-left corner of the alert box. The Alert
function allows you to display your own icon or to have no icon at all in the upper-left
corner of your alert box.
Dialog Manager
These functions take descriptive information about the alert from an alert resource that
you provide. When you call one of these functions, you pass it the resource ID of the alert
resource and a pointer to an event filter function. These functions create a dialog record,
play an alert sound, and display an alert box according to the alert stages that you specify
in the alert resource.
You should specify a pointer to an event filter function when you call the Alert,
StopAlert, CautionAlert, and NoteAlert functions. You can use the same
event filter function in most or all of your alert and modal dialog boxes.
If you need to find out the current alert stage—for example, to ensure that your applica-
tion deactivates the frontmost window only if an alert box is to be displayed at that
stage—use the GetAlertStage function. To change the current alert stage, use the
ResetAlertStage procedure.
Your application does not dispose of alert boxes; the Dialog Manager does that for you
automatically.
Alert 6
To display an alert box (or, if appropriate for the alert stage, to play an alert sound
instead of or in addition to displaying the alert box), you can use the Alert function.
This function does not display a default icon in the upper-left corner of the alert box;
you can leave this area blank, or you can specify your own icon in the alert’s item list
resource, which in turn is specified in the alert resource.
alertID The resource ID of an alert resource. If the alert resource is missing, the
Dialog Manager returns to your application without creating the
requested alert.
filterProc
A pointer to a function that responds to events not handled by the
ModalDialog procedure.
DESCRIPTION
The Alert function creates the alert defined in the specified alert resource. The function
calls the current alert sound procedure and passes it the sound number specified in the
alert resource for the current alert stage. If no alert box is to be drawn at this stage, Alert
returns –1; otherwise, it uses the NewDialog function to create and display the alert box.
The default system window colors are used unless your application provides an alert
color table resource with the same resource ID as the alert resource.
Dialog Manager
The Alert function uses the ModalDialog procedure, which repeatedly gets and
handles most events for you. The ModalDialog procedure, in turn, gets each event by
calling the Event Manager function GetNextEvent. If the event is a mouse-down event
outside the content region of the alert box, ModalDialog emits an error sound and gets
the next event.
The Alert function continues calling ModalDialog until the user selects an enabled
control (typically a button), at which time the Alert function removes the alert box from
the screen and returns the item number of the selected control. Your application then
responds as appropriate when the user clicks this item.
For events inside the alert box, ModalDialog passes the event to an event filter function
before handling the event. The event filter function provides a secondary event-handling
loop for events that ModalDialog doesn’t handle. You specify a pointer to your event
filter function in the filterProc parameter of the Alert function.
If you set the filterProc parameter to NIL, the Dialog Manager uses the standard
event filter function, which behaves as follows:
■ If the user presses the Return or Enter key, the event filter function returns TRUE and
returns the item number for the default button.
However, your application should provide a simple event filter function that not only
replicates this behavior but also
■ returns TRUE and the item number for the Cancel button if the user presses Esc or
Command-period
■ updates your windows in response to update events (this also allows background
windows to receive update events) and returns FALSE
■ returns FALSE for all events that your event filter function doesn’t handle
You can also use the event filter function to test for and respond to keyboard equivalents.
Unless the event filter function handles the event in its own way and returns TRUE,
ModalDialog handles the event inside the alert box as follows:
■ If the user presses the mouse button while the cursor is in a control, the Control
Manager function TrackControl tracks the cursor. If the user releases the
mouse button while the cursor is in an enabled control, Alert, StopAlert,
CautionAlert, and NoteAlert remove the alert box and return the control’s
item number. (Generally, buttons should be the only controls you use in alert boxes.)
■ If the user presses the mouse button while the cursor is in any enabled item other than
a control, Alert, StopAlert, CautionAlert, and NoteAlert remove the alert box
and return the item number. (Generally, button controls should be the only enabled
items in alert boxes.)
■ If user presses the mouse button while the cursor is in a disabled item or in no item,
or if any other event occurs, Alert, StopAlert, CautionAlert, and NoteAlert
do nothing.
Dialog Manager
The Alert function uses the QuickDraw routine SetPort to make the alert box the
current graphics port. It’s not necessary for your application to call SetPort again before
displaying alert boxes, because you can’t draw into any other windows between the time
you create an alert box and the time the Dialog Manager displays it.
SPECIAL CONSIDERATIONS
If you need to display an alert box while your application is running in the background
or is otherwise invisible to the user, you should use the Notification Manager to post a
notification to the user. The Notification Manager automatically displays an alert box
containing whatever message you specify; you will not need to use the Dialog Manager
to create the alert box yourself.
Note that the Notification Manager provides a one-way communications path from
your application to the user. There is no provision for carrying information back from
the user to your application while it is in the background (although it is possible for
your application to determine if the notification was received). If you need to solicit
information from the user, use the Notification Manager to inform the user to bring
your application to the foreground, where the user can then respond to an alert box
that your application presents.
SEE ALSO
The ModalDialog procedure is described on page 6-135. See “Writing an Event Filter
Function for Alert and Modal Dialog Boxes” beginning on page 6-86 for a discussion of
how to write an event filter function. See “Creating Alert Sounds and Alert Boxes”
beginning on page 6-18 for a discussion of alerts and alert stages. See “Titles for Buttons,
Checkboxes, and Radio Buttons” beginning on page 6-37 and “Text Strings for Static Text
and Editable Text Items” beginning on page 6-40 for recommendations about button titles
and messages in alert boxes. Alert resources are described on page 6-150. Alert color table
resources are described on page 6-157. The Dialog Manager uses the system alert sound
as the error sound unless you change it by calling the ErrorSound pro- cedure,
described on page 6-104. See “Responding to Events in Alert Boxes” beginning on
page 6-81 for a discussion of how to respond to events returned by the Alert function.
See the chapter “Notification Manager” in Inside Macintosh: Processes for information
about the Notification Manager.
The NoteAlert, CautionAlert, and StopAlert functions are identical to the Alert
function, except that NoteAlert (described on page 6-110), CautionAlert (described
on page 6-111), and StopAlert (described next) display icons in the upper-left corners
of alert boxes.
Dialog Manager
StopAlert 6
To display an alert box with a stop icon in its upper-left corner (or, if appropriate for the
alert stage, to play an alert sound instead of or in addition to displaying the alert box),
use the StopAlert function.
alertID The resource ID of an alert resource. If the alert resource is missing, the
Dialog Manager returns to your application without creating the
requested alert.
filterProc
A pointer to a function that responds to events not handled by the
ModalDialog procedure. If you set this parameter to NIL, the
Dialog Manager uses the standard event filter function, which allows
users to press the Return or Enter key in lieu of clicking the default button.
However, your application should provide a simple event filter function
that also allows background applications to receive update events. Pass a
pointer to the event filter function in this parameter.
DESCRIPTION
The StopAlert function is the same as the Alert function except that, before drawing
the items in the alert box, StopAlert draws the stop icon in the upper-left corner
(within the rectangle with local coordinates [10,20,42,52]). The stop icon has the following
resource ID:
By default, the Dialog Manager uses the standard stop icon from the System file. You can
change this icon by providing your own 'ICON' resource with this resource ID number.
Use a stop alert to inform the user that a problem or situation is so serious that the action
cannot be completed. Stop alerts typically have only a single button (OK), because all the
user can do is acknowledge that the action cannot be completed.
SEE ALSO
Figure 6-5 on page 6-9 illustrates the stop icon in a typical stop alert. Except that it
includes a stop icon in the alert box, StopAlert is identical to the Alert function. See
the description of the Alert function on page 6-106 for detailed information about the
parameters and behavior of both of these functions.
Dialog Manager
NoteAlert 6
To display an alert box with a note icon in its upper-left corner (or, if appropriate for the
alert stage, to play an alert sound instead of or in addition to displaying the alert box),
use the NoteAlert function.
alertID The resource ID of an alert resource. If the alert resource is missing, the
Dialog Manager returns to your application without creating the
requested alert.
filterProc
A pointer to a function that responds to events not handled by the
ModalDialog procedure. If you set this parameter to NIL, the
Dialog Manager uses the standard event filter function, which allows
users to press the Return or Enter key in lieu of clicking the default button.
However, your application should provide a simple event filter function
that also allows background applications to receive update events. Pass a
pointer to the event filter function in this parameter.
DESCRIPTION
The NoteAlert function is the same as the Alert function except that, before drawing
the items in the alert box, NoteAlert draws the note icon in the upper-left corner
(within the rectangle with local coordinates [10,20,42,52]). The note icon has the following
resource ID:
By default, the Dialog Manager uses the standard note icon from the System file. You can
change this icon by providing your own 'ICON' resource with this resource ID number.
Use a note alert to inform users of a minor mistake that won’t have any disastrous
consequences if left as is. Usually this type of alert simply offers information, and the
user responds by clicking an OK button. Occasionally, a note alert may ask a simple
question and provide a choice of responses.
SEE ALSO
Figure 6-3 on page 6-8 illustrates the note icon in a typical note alert. Except that it
includes a note icon in the alert box, NoteAlert is identical to the Alert function. See
the description of the Alert function on page 6-106 for detailed information about the
parameters and behavior of both of these functions.
Dialog Manager
CautionAlert 6
To display an alert box with a caution icon in its upper-left corner (or, if appropriate for
the alert stage, to play an alert sound instead of or in addition to displaying the alert
box), use the CautionAlert function.
alertID The resource ID of an alert resource. If the alert resource is missing, the
Dialog Manager returns to your application without creating the
requested alert.
filterProc
A pointer to a function that responds to events not handled by the
ModalDialog procedure. If you set this parameter to NIL, the
Dialog Manager uses the standard event filter function, which allows
users to press the Return or Enter key in lieu of clicking the default button.
However, your application should provide a simple event filter function
that also allows background applications to receive update events. Pass a
pointer to the event filter function in this parameter.
DESCRIPTION
The CautionAlert function is the same as the Alert function except that, before
drawing the items in the alert box, CautionAlert draws the caution icon in the
upper-left corner (within the rectangle with local coordinates [10,20,42,52]). The caution
icon has the following resource ID:
By default, the Dialog Manager uses the standard caution icon from the System file.
You can change this icon by providing your own 'ICON' resource with this resource
ID number.
Use a caution alert to alert the user of an operation that may have undesirable results if
it’s allowed to continue. Give the user the choice of continuing the action (by clicking an
OK button) or stopping it (by clicking a Cancel button).
SEE ALSO
Figure 6-4 on page 6-9 illustrates the caution icon in a typical caution alert. Except
that it includes a caution icon in the alert box, CautionAlert is identical to the
Alert function. See the description of the Alert function on page 6-106 for detailed
information about the parameters and behavior of both of these functions.
Dialog Manager
GetAlertStage 6
To determine the stage of the last occurrence of an alert, use the GetAlertStage
function. The GetAlertStage function is also available as the GetAlrtStage function.
DESCRIPTION
The GetAlertStage function returns a number from 0 to 3 as the stage of the last
occurrence of an alert. For example, you can use the GetAlertStage function to
ensure that your application deactivates the active window only if an alert box is to be
displayed at that stage.
ASSEMBLY-LANGUAGE INFORMATION
The global variable ACount contains this number. In addition, the global variable
ANumber contains the resource ID of the alert resource of the last alert that occurred.
SEE ALSO
Listing 6-19 on page 6-66 illustrates how to use GetAlertStage to determine whether
to deactivate a window for the current alert stage. Listing 6-2 on page 6-21 illustrates how
to use an alert resource to specify different alert responses according to different alert
stages.
ResetAlertStage 6
To reset the current alert stage to the first alert stage, use the ResetAlertStage
procedure. The ResetAlertStage procedure is also available as the ResetAlrtStage
procedure.
PROCEDURE ResetAlertStage;
DESCRIPTION
The ResetAlertStage procedure resets every alert to a first-stage alert.
SEE ALSO
Listing 6-2 on page 6-21 illustrates how to use an alert resource to specify different alert
responses according to different alert stages.
Dialog Manager
GetNewDialog 6
To create a dialog box from a description in a dialog resource, use the GetNewDialog
function.
DESCRIPTION
The GetNewDialog function creates a dialog record from the information in the dialog
resource and returns a pointer to it. You can use this pointer with Window Manager or
QuickDraw routines to manipulate the dialog box. If the dialog resource specifies that the
dialog box should be visible, the dialog box is displayed. If the dialog resource specifies
that the dialog box should initially be invisible, use the Window Manager procedure
ShowWindow to display the dialog box.
Dialog Manager
If you supply a dialog color table resource with the same resource ID as the dialog
resource, GetNewDialog uses the NewColorDialog function and returns a pointer
to a color graphics port. If no dialog color table resource is present, GetNewDialog
uses NewDialog to return a pointer to a black-and-white graphics port, although
system software draws the window frame using the system’s default colors.
The dStorage and behind parameters of GetNewDialog have the same meaning as
they do in the Window Manager function GetNewWindow. Always set the behind
parameter to Pointer(-1) to bring the dialog box to the front.
The dialog resource contains the resource ID of the dialog box’s item list resource. After
calling the Resource Manager to read the item list resource into memory (if it’s not
already in memory), GetNewDialog makes a copy of the item list resource and uses that
copy; thus you may have several dialog boxes with identical items.
If you provide a dialog color table resource, GetNewDialog copies it before passing it to
the Window Manager routine SetWinColor unless the number-of-entries element of the
dialog color table resource is set to –1, in which case the default window colors are used
instead. The GetNewDialog function makes the copy so that the dialog color table
resource can be purged without affecting the dialog box.
SPECIAL CONSIDERATIONS
The GetNewDialog function doesn’t release the memory occupied by the resources.
Therefore, your application should mark all resources used for a dialog box as purgeable.
If either the dialog resource or the item list resource can’t be read, the function result is
NIL; your application should test to ensure that NIL is not returned before performing
any more operations with the dialog box or its items.
For modal dialog boxes, the Dialog Manager function ModalDialog traps all events.
This prevents your event loop from receiving activate events for your windows. Thus,
if one of your application’s windows is active when you use GetNewDialog to create
a modal dialog box, you must explicitly deactivate that window before displaying the
modal dialog box.
If you ever need to display a dialog box while your application is running in the back-
ground or is otherwise invisible to the user, you should use the Notification Manager to
post a notification to the user. The Notification Manager automatically displays an alert
box containing whatever message you specify; you do not use the Dialog Manager to
create the alert box yourself.
Note that the Notification Manager provides a one-way communications path from
your application to the user. There is no provision for carrying information back from
the user to your application while it is in the background (although it is possible for
your application to determine if the notification was received). If you need to solicit
information from the user, use the Notification Manager to inform the user to bring
your application to the foreground, where the user can then respond to the dialog box
that your application presents.
The GetNewDialog function uses either NewDialog or NewColorDialog, each of
which generates an update event for the entire window contents. Thus, with the
Dialog Manager
exception of controls, items aren’t drawn immediately. The Dialog Manager calls the
Control Manager to draw controls, and the Control Manager draws them immediately. So
the controls won’t be drawn twice, the Dialog Manager calls the Window Manager
procedure ValidRect for the enclosing rectangle of each control. If you find that there is
too great a lag between the drawing of controls and the drawing of other items, try
making the dialog box initially invisible and then calling the Window Manager
procedure ShowWindow to show it.
SEE ALSO
See “Creating Dialog Boxes” beginning on page 6-23 and “Displaying Alert and Dialog
Boxes” beginning on page 6-61 for discussions and examples of how to use
GetNewDialog.
The GetNewWindow and ShowWindow procedures are described in the chapter “Window
Manager” of this book. The Notification Manager is described in the
chapter “Notification Manager” in Inside Macintosh: Processes.
“Adjusting Menus for Modal Dialog Boxes” beginning on page 6-68 and “Adjusting
Menus for Movable Modal and Modeless Dialog Boxes” on page 6-73 discuss menu
adjustment when your application displays dialog boxes. See “Titles for Buttons,
Checkboxes, and Radio Buttons” beginning on page 6-37 and “Text Strings for Static Text
and Editable Text Items” beginning on page 6-40 for recommendations about messages
and control titles in dialog boxes.
NewColorDialog 6
To create a dialog box, you can use the NewColorDialog function, which returns a
pointer to a color graphics port. Generally, you should instead use GetNewDialog to
create a dialog box, because GetNewDialog takes information about the dialog box from
a dialog resource in a resource file. (Like window resources, dialog resources isolate de-
scriptive information from your application code for ease of modification or translation
to other languages.) The NewColorDialog function is also available as the
NewCDialog function.
dStorage A pointer to the memory for the dialog record. If you set this parameter to
NIL for modal dialog boxes and movable modal dialog boxes, the Dialog
Manager allocates memory for them on your application heap. For a
modeless dialog box, however, you should allocate your own memory
as you would for a window—otherwise, your heap could become
fragmented.
Dialog Manager
boundsRect
A rectangle, given in global coordinates, that determines the size and
position of the dialog box; these coordinates specify the upper-left and
lower-right corners of the dialog box.
title A text string used for the title of a modeless or movable modal dialog
box. You can specify an empty string (not NIL) for a title bar that contains
no text.
visible A flag that specifies whether the dialog box should be drawn on the screen
immediately. If you set this parameter to FALSE, the dialog box is not
drawn until your application uses the Window Manager procedure
ShowWindow to display it.
procID The window definition ID for the type of dialog box. Use the dBoxProc
constant to specify modal dialog boxes, the noGrowDocProc constant to
specify modeless dialog boxes, and the movableDBoxProc constant to
specify movable modal dialog boxes.
behind A pointer to the window behind which the dialog box is to be placed on
the desktop. Always set this parameter to the window pointer
Pointer(-1) to bring the dialog box in front of all other windows.
goAwayFlag
A flag to specify whether a modeless dialog box should have a close box
in its title bar when the dialog box is active. If you set this parameter to
TRUE, the dialog window has a close box in its title bar when the window
is active; only modeless dialog boxes should have close boxes.
refCon A value that the Dialog Manager uses to set the refCon field of the dialog
box’s window record. Your application may store any value here for any
purpose. For example, your application can store a number that represents
a dialog box type, or it can store a handle to a record that maintains state
information about the dialog box. You
can use the Window Manager procedure SetWRefCon at any time to
change this value in the dialog record for a dialog box, and you can use
the GetWRefCon function to determine its current value.
items A handle to an item list resource for the dialog box. You can get the handle
by calling the Resource Manager function GetResource to read the item
list resource into memory. Use the Memory Manager procedure
HNoPurge to make the handle unpurgeable while you use it or use the
Operating System utility function HandToHand to make a copy of the
handle and use the copy.
DESCRIPTION
The NewColorDialog function creates a dialog box as specified by its parameters
and returns a pointer to a color graphics port for the new dialog box. The first eight
parameters (dStorage through refCon) are passed to the Window Manager function
NewCWindow, which creates the dialog box. You can use this pointer with Window
Manager or QuickDraw routines to manipulate the dialog box.
The Dialog Manager uses the default window colors for the dialog box. By using the
system’s default colors, you ensure that your application’s interface is consistent with
Dialog Manager
that of the Finder and other applications. However, if you absolutely feel compelled to
break from this consistency, you can use the Window Manager procedure SetWinColor
to use your own dialog color table resource that specifies colors other than the default
colors. Be aware, however, that nonstandard colors in your alert and dialog boxes may
initially confuse your users.
The Window Manager creates an auxiliary window record for the color dialog box. You
can access this record with the Window Manager function GetAuxWin. (The
dialogCItemhandle field of the auxiliary window record points to the dialog box’s
item color table resource.) If the dialog box’s content color isn’t white, it’s a good idea
to call NewColorDialog with the visible flag set to FALSE. After the color table
and color item list resource are installed, use the Window Manager procedure
ShowWindow to display the dialog box if it’s the frontmost window. If the dialog box
is a modeless dialog box that is not in front, use the Window Manager procedure
ShowHide to display it.
When specifying the size and position of the dialog box in the boundsRect parameter,
you should generally try to center dialog boxes between the left and right margins of the
screen or the window where the user is working, whichever is more appropriate. Also
ensure that the tops of dialog boxes (including the title bars of modeless and movable
modal dialog boxes) lie below the menu bar when you position them on the main screen.
You can use the Menu Manager function GetMBarHeight to determine the height of
the menu bar.
SPECIAL CONSIDERATIONS
For modal dialog boxes, the Dialog Manager function ModalDialog traps all events.
This prevents your event loop from receiving activate events for your windows. Thus, if
one of your application’s windows is active when you use NewColorDialog to create
a modal dialog box, you must explicitly deactivate that window before displaying the
modal dialog box.
If you ever need to display a dialog box while your application is running in the back-
ground or is otherwise invisible to the user, you should use the Notification Manager
to post a notification to the user. The Notification Manager automatically displays an
alert box containing whatever message you specify; you do not need to use the Dialog
Manager to create the alert box yourself.
Note that the Notification Manager provides a one-way communications path from
your application to the user. There is no provision for carrying information back from
the user to your application while it is in the background (although it is possible for
your application to determine if the notification was received). If you need to solicit
information from the user, use the Notification Manager to inform the user to bring
your application to the foreground, where the user can then respond to the dialog box
that your application presents.
The NewColorDialog function generates an update event for the entire window
contents. Thus, with the exception of controls, items aren’t drawn immediately. The
Dialog Manager calls the Control Manager to draw controls, and the Control Manager
draws them immediately. So that the controls won’t be drawn twice, the Dialog Manager
Dialog Manager
calls the Window Manager procedure ValidRect for the enclosing rectangle of each
control. If you find that there is too great a lag between the drawing of controls and the
drawing of other items, try making the dialog box initially invisible and then calling the
Window Manager procedure ShowWindow to show it.
SEE ALSO
Window Manager routines are described in the chapter “Window Manager” in this book.
The Notification Manager is described in the chapter “Notification Manager” in Inside
Macintosh: Processes. See Inside Macintosh: Memory for a description of HNoPurge. See
Inside Macintosh: Operating System Utilities for a description of HandToHand.
“Adjusting Menus for Modal Dialog Boxes” beginning on page 6-68 and “Adjusting
Menus for Movable Modal and Modeless Dialog Boxes” on page 6-73 discuss menu bar
adjustment when your application displays dialog boxes. See “Titles for Buttons,
Checkboxes, and Radio Buttons” beginning on page 6-37 and “Text Strings for Static Text
and Editable Text Items” beginning on page 6-40 for recommendations about messages
and control titles in dialog boxes. The GetResource function is described in the chapter
“Resource Manager” of Inside Macintosh: More Macintosh Toolbox.
NewDialog 6
To create a dialog box, you can use the NewDialog function, which returns a pointer to a
black-and-white graphics port (although system software draws the window frame of the
dialog box using the system’s default window colors). Generally, you should instead use
GetNewDialog to create a dialog box; GetNewDialog takes information about the
dialog from a dialog resource in a resource file. (Like window resources, dialog resources
isolate descriptive information from your application code for ease of modification or
translation to other languages.)
The NewDialog function is identical to the NewColorDialog function, except that
NewDialog returns a pointer to a black-and-white graphics port. See the discussion
of NewColorDialog on page 6-115 for descriptions of the parameters that you also
pass to NewDialog.
DESCRIPTION
The NewDialog function creates a dialog box as specified by its parameters and returns a
pointer to a black-and-white graphics port for the new dialog box. The first eight
parameters (dStorage through refCon) are passed to the Window Manager function
NewWindow, which creates the dialog box.
Dialog Manager
When specifying the size and position of the dialog box in the boundsRect parameter,
you should generally try to center dialog boxes between the left and right margins of the
screen or the window where the user is working, whichever is more appropriate. Also
ensure that the tops of dialog boxes (including the title bars of modeless and movable
modal dialog boxes) lie below the menu bar when you position them on the main screen.
You can use the Menu Manager function GetMBarHeight to determine the height of the
menu bar.
SEE ALSO
If you use a dialog color table resource to change the default window colors, use the
NewColorDialog function, which returns a pointer to a color graphics port. See the
description of NewColorDialog on page 6-115 for additional information common to
both the NewDialog and NewColorDialog functions.
CloseDialog 6
To dismiss a dialog box for whose dialog record you allocated memory, use the
CloseDialog procedure.
DESCRIPTION
The CloseDialog procedure removes a dialog box from the screen and deletes it from
the window list. The CloseDialog procedure releases the memory occupied by
■ the data structures associated with the dialog box (such as its structure, content, and
update regions)
■ all the items in the dialog box (except for pictures and icons, which might be shared by
other resources) and any data structures associated with them
Generally, you should provide memory for the dialog record of modeless dialog boxes
when you create them. (You can let the Dialog Manager provide memory for modal and
movable modal dialog boxes.) You should then use CloseDialog to close a modeless
dialog box when the user clicks the close box or chooses Close from the File menu.
Because CloseDialog does not dispose of the dialog resource or the item list
resource, it is important to make these resources purgeable. Unlike GetNewDialog,
NewColorDialog does not use a copy of the item list resource. Thus, if you
use NewColorDialog to create a dialog box, you may want to use CloseDialog to
keep the item list resource in memory even if you didn’t supply a pointer to the memory.
Dialog Manager
SEE ALSO
If you let the Dialog Manager allocate memory for the dialog box (by passing NIL in the
dStorage parameter to the GetNewDialog, NewColorDialog, or NewDialog
function), use the DisposeDialog procedure, described next, instead of CloseDialog.
DisposeDialog 6
To dismiss a dialog box for which the Dialog Manager supplies memory, use the
DisposeDialog procedure. The DisposeDialog procedure is also available
as the DisposDialog procedure.
DESCRIPTION
The DisposeDialog procedure calls the CloseDialog procedure and, in addition,
releases the memory occupied by the dialog box’s item list resource and the dialog
record. Call DisposeDialog when you’re done with a dialog box if you pass NIL in
the dStorage parameter to GetNewDialog, NewColorDialog, or NewDialog.
Generally, your application should not allocate memory for the dialog records of modal
dialog boxes or movable modal dialog boxes. In these cases your application should use
DisposeDialog when the user clicks the OK or Cancel button.
SEE ALSO
If you allocate memory for the dialog box (for example, by passing a pointer in the
dStorage parameter to the GetNewDialog, NewColorDialog, or NewDialog
function), use CloseDialog, described on page 6-119, instead of DisposeDialog.
Dialog Manager
You can dynamically add items to and remove items from a dialog box by using the
AppendDITL and ShortenDITL procedures. These procedures are especially useful
if you share a single item list resource among multiple dialog boxes, because you can
then use AppendDITL or ShortenDITL to add or remove items as appropriate for
individual dialog boxes. You typically make such dialog boxes invisible, use the
AppendDITL and ShortenDITL procedures as appropriate, then make the dialog
boxes visible by using the Window Manager procedure ShowWindow.
GetDialogItem 6
To get a handle to an item so that you can manipulate it (for example, to determine its
current value, to change it, or to install a pointer to a draw procedure for an
application-defined item), use the GetDialogItem procedure. The GetDialogItem
procedure is also available as the GetDItem procedure.
CONST
ctrlItem = 4; {add this constant to the next }
{ four constants}
btnCtrl = 0; {standard button control}
chkCtrl = 1; {standard checkbox control}
radCtrl = 2; {standard radio button}
resCtrl = 3; {control defined in a 'CNTL'}
helpItem = 1; {help balloons}
statText = 8; {static text}
editText = 16; {editable text}
iconItem = 32; {icon}
picItem = 64; {QuickDraw picture}
userItem = 0; {application-defined item}
itemDisable = 128; {add to any of the above to }
{ disable it}
Dialog Manager
DESCRIPTION
The GetDialogItem procedure returns in its parameters the following information
about the item numbered itemNo in the item list resource of the specified dialog box:
in the itemType parameter, the item type; in the item parameter, a handle to the item
(or, for application-defined draw procedures, the procedure pointer); and in the box
parameter, the display rectangle for the item.
For most item manipulation, first use the GetDialogItem procedure to get the informa-
tion about the item. You can then use other routines, such as GetDialogItemText and
SetDialogItem, to determine and change the value of that item.
SEE ALSO
Listing 6-12 on page 6-49 illustrates the use of GetDialogItem in conjunction with
GetDialogItemText to retrieve the text entered by a user in an editable text item.
Listing 6-16 on page 6-58 illustrates the use of GetDialogItem in conjunction with
SetDialogItem to install the draw procedure for an application-defined item into
a dialog box. Listing 6-26 on page 6-83 illustrates the use of GetDialogItem to
determine the current value of a checkbox in a dialog box.
SetDialogItem 6
After using the GetDialogItem procedure to get a handle to an item from a dialog box,
use the SetDialogItem procedure to set or change the item. The SetDialogItem
procedure is also available as the SetDItem procedure.
Dialog Manager
DESCRIPTION
The SetDialogItem procedure sets the item specified by the itemNo parameter for the
specified dialog box. This procedure installs the item without drawing it; typically you
create an invisible dialog box, use SetDialogItem, then use the Window Manager
procedure ShowWindow to draw the dialog box and its items.
SEE ALSO
Listing 6-16 on page 6-58 illustrates how to use SetDialogItem to install an
application-defined draw procedure. The ShowWindow procedure is described in the
chapter “Window Manager” of this book.
HideDialogItem 6
Although you should rarely need to do so, you can make an item in a dialog box invisible
by using the HideDialogItem procedure. The HideDialogItem procedure is also
available as the HideDItem procedure.
DESCRIPTION
The HideDialogItem procedure hides the item specified by itemNo by giving it a
display rectangle that’s off the screen. Specifically, if the left coordinate of the item’s
display rectangle is less than 8192 (hexadecimal $2000), HideDialogItem adds 16,384
(hexadecimal $4000) to both the left and right coordinates of the rectangle. If the item is
already hidden (that is, if the left coordinate is greater than 8192), HideDialogItem
does nothing. To redisplay an item that’s been hidden by HideDialogItem, you can use
the ShowDialogItem procedure.
Dialog Manager
SPECIAL CONSIDERATIONS
If your application needs to display a number of dialog boxes that are similar except for
one or two items, it’s generally easier to modify the common elements using the
AppendDITL and ShortenDITL procedures than to use the HideDialogItem and
ShowDialogItem procedures.
The rectangle for a static text item must always be at least as wide as the first character of
the text.
You generally shouldn’t use HideDialogItem to make an editable text item invisible,
because as the user presses the Tab key, the Dialog Manager attempts to move the cursor
to the hidden editable text item, where the user’s subsequent keystrokes will be placed.
ShowDialogItem 6
To redisplay an item that has been hidden by the HideDialogItem procedure, use the
ShowDialogItem procedure. The ShowDialogItem procedure is also available as the
ShowDItem procedure.
DESCRIPTION
The ShowDialogItem procedure redisplays the item specified in itemNo by restoring
the display rectangle the item had prior to the HideDialogItem call. Specifically, if
the left coordinate of the item’s display rectangle is greater than 8192, ShowDialogItem
subtracts 16,384 from both the left and right coordinates of the rectangle. If the item
is already visible (that is, if the left coordinate is less than 8192), ShowDialogItem
does nothing.
The ShowDialogItem procedure adds the rectangle that contained the item to the
update region so that it will be drawn. Note that if the item is a control you define in a
control ('CNTL') resource, the rectangle added to the update region is the rectangle
defined in the control resource, not the display rectangle defined in the item list resource.
If the item is an editable text item, ShowDialogItem activates it by calling the TextEdit
procedure TEActivate.
Dialog Manager
FindDialogItem 6
To determine the item number of an item at a particular location in a dialog box, use the
FindDialogItem function. The FindDialogItem function is also available as the
FindDItem function.
DESCRIPTION
If the point specified in the parameter thePt lies within an item, FindDialogItem
returns a number corresponding to the position of that item in the dialog box’s item list
resource. If the point doesn’t lie within the item’s rectangle, FindDialogItem returns
–1. If items overlap, FindDialogItem returns the item number of the first item, in the
item list resource, containing the point.
This function is useful for changing the cursor when it’s over a particular item.
The FindDialogItem function returns 0 for the first item in the item list resource,
1 for the second, and so on. To get the proper item number before calling the
GetDialogItem or SetDialogItem procedure, add 1 to FindDialogItem’s
function result, as shown here:
Note that FindDialogItem returns the item number of disabled items as well as
enabled items.
AppendDITL 6
To add items to an existing dialog box while your application is running, use the
AppendDITL procedure.
theDialog A pointer to a dialog record. This is the dialog record to which you will
add the item list resource specified in the parameter theDITL.
theDITL A handle to the item list resource whose items you want to append to the
dialog box.
Dialog Manager
theMethod The manner in which you want the new items to be displayed in the
existing dialog box. You can pass a negative value to offset the appended
items from a particular item in the existing dialog box. You can also pass
any of these constants:
CONST
overlayDITL = 0; {overlay existing items}
appendDITLRight = 1; {append at right}
appendDITLBottom = 2; {append at bottom}
DESCRIPTION
The AppendDITL procedure adds the items in the item list resource specified in the
parameter theDITL to the items of a dialog box. This procedure is especially useful if
several dialog boxes share a single item list resource, because you can use AppendDITL
to add items that are appropriate for individual dialog boxes. Your application can use
the Resource Manager function GetResource to get a handle to the item list resource
whose items you wish to add.
In the parameter theMethod, you specify how to append the new items, as follows:
■ If you use the overlayDITL constant, AppendDITL superimposes the appended
items over the dialog box. That is, AppendDITL interprets the coordinates of the
display rectangles for the appended items (as specified in their item list resource) as
local coordinates within the dialog box.
■ If you use the appendDITLRight constant, AppendDITL appends the items to the
right of the dialog box by positioning the display rectangles of the appended items
relative to the upper-right coordinate of the dialog box. The AppendDITL procedure
automatically expands the dialog box to accommodate the new dialog items.
■ If you use the appendDITLBottom constant, AppendDITL appends the items to the
bottom of the dialog box by positioning the display rectangles of the appended items
relative to the lower-left coordinate of the dialog box. The AppendDITL procedure
automatically expands the dialog box to accommodate the new dialog items.
■ You can also append a list of items relative to an existing item by passing a negative
number in the parameter theMethod. The absolute value of this number is
interpreted as the item in the dialog box relative to which the new items are to be
positioned. For example, if you pass –2, the display rectangles of the appended
items are offset relative to the upper-left corner of item number 2 in the dialog box.
You typically create an invisible dialog box, call the AppendDITL procedure, then make
the dialog box visible by using the Window Manager procedure ShowWindow.
SPECIAL CONSIDERATIONS
The AppendDITL procedure modifies the contents of the dialog box (for instance, by
enlarging it). To use an unmodified version of the dialog box at a later time, your
application should use the Resource Manager procedure ReleaseResource to release
the memory occupied by the appended item list resource. Otherwise, if your application
calls AppendDITL to add items to that dialog box again, the dialog box remains
Dialog Manager
modified by your previous call—for example, it will still be longer at the bottom if you
previously used the appendDITLBottom constant.
The AppendDITL procedure is available in System 7 and in earlier versions of the
Communications Toolbox. Before calling AppendDITL, you should make sure that it
is available by using the Gestalt function with the gestaltDITLExtAttr selector.
Test the bit indicated by the gestaltDITLExtPresent constant in the response
parameter. If the bit is set, then AppendDITL is available.
SEE ALSO
Listing 6-13 on page 6-54 and Listing 6-14 on page 6-55 illustrate a typical use
of AppendDITL. Figure 6-29 on page 6-52 shows the result of using the
overlayDITL constant, Figure 6-30 on page 6-52 shows the result of using the
appendDITLRight constant, Figure 6-31 on page 6-53 shows the result of using
the appendDITLBottom constant, and Figure 6-32 on page 6-53 shows the result
of using a negative number in the parameter theMethod.
The chapter “Resource Manager” in Inside Macintosh: More Macintosh Toolbox describes the
GetResource and ReleaseResource routines. The Gestalt function is described in
the chapter “Gestalt Manager” of Inside Macintosh: Operating System Utilities. See the
chapter “Window Manager” in this book for information about ShowWindow.
ShortenDITL 6
To remove items from an existing dialog box while your application is running, use the
ShortenDITL procedure.
DESCRIPTION
The ShortenDITL procedure removes the specified number of items from the dialog
box. This procedure is especially useful if several dialog boxes share a single item list
resource, because you can use ShortenDITL to remove items as necessary for individual
dialog boxes.
You typically create an invisible dialog box, call the ShortenDITL procedure, then make
the dialog box visible by using the Window Manager procedure ShowWindow. Note that
ShortenDITL does not automatically resize the dialog box; you can use
the Window Manager procedure SizeWindow if you need to resize the dialog box.
Dialog Manager
SPECIAL CONSIDERATIONS
SEE ALSO
You can use the CountDITL function, described next, to determine the number of items
in the dialog box’s item list resource. See the chapter “Window Manager” in this book
for information on the ShowWindow and SizeWindow procedures. The Gestalt
function is described in the chapter “Gestalt Manager” in Inside Macintosh: Operating
System Utilities.
CountDITL 6
You can determine the number of items in a dialog box by using the CountDITL
function.
DESCRIPTION
The CountDITL function returns the number of current items in a dialog box. You
typically use CountDITL in conjunction with ShortenDITL to remove items from a
dialog box.
SPECIAL CONSIDERATIONS
The CountDITL function is available in System 7 and in earlier versions of the Commu-
nications Toolbox. Before calling CountDITL, you should make sure that it is available
by using the Gestalt function with the gestaltDITLExtAttr selector. Test the bit
indicated by the gestaltDITLExtPresent constant in the response parameter. If the
bit is set, then CountDITL is available.
SEE ALSO
The Gestalt function is described in the chapter “Gestalt Manager” in Inside Macintosh:
Operating System Utilities.
Dialog Manager
ParamText 6
To substitute text strings in the static text items of your alert or dialog boxes while your
application is running, use the ParamText procedure.
param0 A text string to substitute for the special string ^0 in the static text items of
all subsequently created alert and dialog boxes.
param1 A text string to substitute for the special string ^1 in the static text items of
all subsequently created alert and dialog boxes.
param2 A text string to substitute for the special string ^2 in the static text items of
all subsequently created alert and dialog boxes.
param3 A text string to substitute for the special string ^3 in the static text items of
all subsequently created alert and dialog boxes.
DESCRIPTION
The ParamText procedure replaces the special strings ^0 through ^3 in the static text
items of all subsequently created alert and dialog boxes with the text strings you pass as
parameters. Pass empty strings (not NIL) for parameters not used.
SPECIAL CONSIDERATIONS
The strings used in ParamText are stored in the low-memory global variable
DAStrings, which specifies a set of string handles used by the Dialog Manager.
Dialog Manager
If the user launches a desk accessory in your application’s partition and the desk
accessory calls ParamText, it may change the text in your application’s dialog box.
You should be very careful about using ParamText in modeless dialog boxes. If a
modeless dialog box using ParamText is onscreen and you display another dialog box
or alert box that also uses ParamText, both boxes will be affected by the latest call
to ParamText.
The strings you pass in the parameters to ParamText cannot contain the special strings
^0 through ^3, or else the procedure will enter an endless loop of substitutions in
versions of system software earlier than 7.1.
Note that you should try to store text strings in resource files to facilitate translation into
other languages; therefore, ParamText is best used for supplying text strings, such as
document names, that the user specifies. To avoid problems with grammar and sentence
structure when you localize your application, you should use ParamText to supply only
one text string per screen message.
SEE ALSO
Listing 6-9 on page 6-47 and Listing 6-10 on page 6-48 show an example of how you can
use ParamText to supply the title of the user’s current document to your alert and
dialog boxes. If you need to supply a default text string to an editable text item while
your application is running, use SetDialogItemText. The SetDialogItemText
procedure also allows you to set or change the entire text string for a static text item.
GetDialogItemText 6
After using the GetDialogItem procedure to get a handle to an editable text item or a
static text item in a dialog box, you can use the GetDialogItemText procedure to get
the text string contained in that item. The GetDialogItemText procedure is also
available as the GetIText procedure.
item A handle to an editable text item or a static text item in a dialog box.
text The text contained within the item.
DESCRIPTION
The GetDialogItemText procedure returns, in the text parameter, the text of the
given editable text or static text item.
SPECIAL CONSIDERATIONS
If the user types more than 255 characters in an editable text item, GetDialogItemText
returns only the first 255.
Dialog Manager
SEE ALSO
Listing 6-12 on page 6-49 illustrates how to use GetDialogItemText to retrieve
the text that a user types into an editable text item.
SetDialogItemText 6
After using the GetDialogItem procedure to get a handle to an editable text item or
a static text item in a dialog box, you can use the SetDialogItemText procedure to
display a particular text string in that item. The SetDialogItemText procedure is also
available as the SetIText procedure.
item A handle to an editable text item or a static text item in a dialog box.
text The text to display in the item.
DESCRIPTION
The SetDialogItemText procedure places the specified text in the specified item and
draws the item. This procedure is useful for supplying a default text string—such as a
document name—for an editable text item while your application is running.
SPECIAL CONSIDERATIONS
All strings should be stored in resource files to ease translation into other languages.
SEE ALSO
For static text items, the ParamText procedure, described on page 6-129, is useful when
you need to determine and provide only a portion of a text string while your application
is running.
SelectDialogItemText 6
To select and highlight text contained in an editable text item, use the
SelectDialogItemText procedure. The SelectDialogItemText procedure
is also available as the SelIText procedure.
Dialog Manager
DESCRIPTION
If the item in the itemNo parameter is an editable text item that contains text, the
SelectDialogItemText procedure sets the text selection range to extend from
the character position specified in the strtSel parameter up to but not including the
character position specified in the endSel parameter. The selection range is highlighted
unless strtSel equals endSel, in which case a blinking vertical bar is displayed to
indicate an insertion point at that position. If the editable text item doesn’t contain text,
SelectDialogItemText displays the insertion point.
You can select the entire text by specifying the number 0 in the strtSel parameter and
the number 32767 in the endSel parameter.
For example, if the user makes an unacceptable entry in the editable text item, your
application can display an alert box reporting the problem and then use
SelectDialogItemText to select the entire text so it can be replaced by a new
entry. Without this procedure, the user would have to select the item before making
the new entry.
SEE ALSO
For details about text selection range and character position, see the chapter “TextEdit” in
Inside Macintosh: Text.
DialogCut 6
When a dialog box containing an editable text item is active, use the DialogCut
procedure to handle the Cut editing command. The DialogCut procedure is also
available as the DlgCut procedure.
DESCRIPTION
The DialogCut procedure checks whether the dialog box has any editable text items
and, if so, applies the TextEdit procedure TECut to the selected text. Your application
should test whether a dialog box is the frontmost window when handling mouse-down
events in the Edit menu and then call this routine when appropriate.
Dialog Manager
SEE ALSO
For more information about allowing access to your menus when your application
displays dialog boxes, see “Adjusting Menus for Modal Dialog Boxes” beginning on
page 6-68 and “Adjusting Menus for Movable Modal and Modeless Dialog Boxes” on
page 6-73. The TECut procedure is described in the chapter “TextEdit” in Inside
Macintosh: Text.
DialogCopy 6
When a dialog box containing an editable text item is active, use the DialogCopy
procedure to handle the Copy editing command. The DialogCopy procedure is also
available as the DlgCopy procedure.
DESCRIPTION
The DialogCopy procedure checks whether the dialog box has any editable text items
and, if so, applies the TextEdit procedure TECopy to the selected text. Your application
should test whether a dialog box is the frontmost window when handling mouse-down
events in the Edit menu and then call this routine when appropriate.
SEE ALSO
For more information about allowing access to your menus when your application
displays dialog boxes, see “Adjusting Menus for Modal Dialog Boxes” beginning on
page 6-68 and “Adjusting Menus for Movable Modal and Modeless Dialog Boxes” on
page 6-73. The TECopy procedure is described in the chapter “TextEdit” in Inside
Macintosh: Text.
DialogPaste 6
When a dialog box containing an editable text item is active, use the DialogPaste
procedure to handle the Paste editing command. The DialogPaste procedure is also
available as the DlgPaste procedure.
Dialog Manager
DESCRIPTION
The DialogPaste procedure checks whether the dialog box has any editable text
items and, if so, applies the TextEdit procedure TEPaste to the selected editable text
item. Your application should test whether a dialog box is the frontmost window
when handling mouse-down events in the Edit menu and then call this routine when
appropriate.
SEE ALSO
For more information about allowing access to your menus when your application
displays dialog boxes, see “Adjusting Menus for Modal Dialog Boxes” beginning on
page 6-68 and “Adjusting Menus for Movable Modal and Modeless Dialog Boxes” on
page 6-73. The TEPaste procedure is described in the chapter “TextEdit” in Inside
Macintosh: Text.
DialogDelete 6
When a dialog box containing an editable text item is active, use the DialogDelete
procedure to handle the Clear editing command. The DialogDelete procedure is also
available as the DlgDelete procedure.
DESCRIPTION
The DialogDelete procedure checks whether the dialog box has any editable text items
and, if so, applies the TextEdit procedure TEDelete to the selected text. Your application
should test whether a dialog box is the frontmost window when handling mouse-down
events in the Edit menu and then call this routine when appropriate.
SEE ALSO
For more information about allowing access to your menus when your application
displays dialog boxes, see “Adjusting Menus for Modal Dialog Boxes” beginning on
page 6-68 and “Adjusting Menus for Movable Modal and Modeless Dialog Boxes” on
page 6-73. The TEDelete procedure is described in the chapter “TextEdit” in Inside
Macintosh: Text.
Dialog Manager
ModalDialog 6
To handle events when you display a modal dialog box, use the ModalDialog
procedure.
filterProc
A pointer to an event filter function.
itemHit A number representing the position of the selected item in the item list
resource for the active modal dialog box.
DESCRIPTION
Call the ModalDialog procedure immediately after displaying a modal dialog box. The
ModalDialog procedure assumes that a modal dialog box is displayed as the current
port, and ModalDialog repeatedly handles events inside that port until an event
involving an enabled dialog box item—such as a click in a radio button, for example—
occurs. If the event is a mouse-down event outside the content region of the dialog box,
ModalDialog emits the system alert sound and gets the next event. After receiving an
event involving an enabled item, ModalDialog returns its item number in the itemHit
parameter. Your application should then do whatever is appropriate in response to an
event in that item. Your application should continue calling ModalDialog until the user
selects the OK or Cancel button.
Dialog Manager
For events inside the dialog box, ModalDialog passes the event to the event filter
function pointed to in the filterProc parameter before handling the event. When the
event filter returns FALSE, ModalDialog handles the event. If the event filter function
handles the event, the event filter function returns TRUE, and ModalDialog performs no
more event handling.
If you set the filterProc parameter to NIL, the standard event filter function is
executed. The standard event filter function returns TRUE and causes ModalDialog to
return item number 1, which is the number of the default button, when the user presses
the Return key or the Enter key. However, your application should provide a simple
event filter function that
■ returns TRUE and the item number for the default button if the user presses the Return
or Enter key
■ returns TRUE and the item number for the Cancel button if the user presses the Esc key
or the Command-period key combination
■ updates your windows in response to update events (this allows background
applications to receive update events) and return FALSE
■ returns FALSE for all events that your event filter function doesn’t handle
You can use the same event filter function in most or all of your alert and modal
dialog boxes.
You can also use the event filter function specified in the filterProc parameter to test
for and respond to keyboard equivalents and more complex events—for instance, the
user dragging the cursor within an application-defined item.
To handle events, ModalDialog calls the IsDialogEvent function. If the result of
IsDialogEvent is TRUE, then ModalDialog calls the DialogSelect function to
handle the event. Unless the event filter function returns TRUE, ModalDialog handles
the event as follows:
■ In response to an activate or update event for the dialog box, ModalDialog activates
or updates its window.
■ If the user presses the mouse button while the cursor is in an editable text item,
ModalDialog responds to the mouse activity as appropriate—that is, either by
displaying an insertion point or by selecting text. If a key-down event occurs and
there’s an editable text item, ModalDialog uses TextEdit to handle text entry and
editing automatically. If the editable text item is enabled, ModalDialog returns its
item number after it receives either the mouse-down or key-down event. Normally,
editable text items are disabled, and you use the GetDialogItemText procedure to
read the information in the items only after the user clicks the OK button.
■ If the user presses the mouse button while the cursor is in a control, ModalDialog
calls the Control Manager function TrackControl. If the user releases the mouse
button while the cursor is in an enabled control, ModalDialog returns the control’s
item number. Your application should respond appropriately—for example, by
performing a command after the user clicks the OK button.
Dialog Manager
■ If the user presses the mouse button while the cursor is in any other enabled item in
the dialog box, ModalDialog returns the item’s number, and your application should
respond appropriately. Generally, only controls should be enabled. If your application
creates a control more complex than a button, radio button, or checkbox, your
application must handle events inside that item with your event filter function.
■ If the user presses the mouse button while the cursor is in a disabled item or in no
item, or if any other event occurs, ModalDialog does nothing.
SPECIAL CONSIDERATIONS
Do not use ModalDialog for movable modal dialog boxes (that is, those created with
the movableDBoxProc window definition ID) or for modeless dialog boxes (that is,
those created with the noGrowDocProc window definition ID). If you want the Dialog
Manager to assist you in handling events for movable modal and modeless dialog boxes,
use the IsDialogEvent and DialogSelect functions instead.
The ModalDialog procedure calls the Event Manager function GetNextEvent with a
mask that excludes disk-inserted events. To receive disk-inserted events, your event filter
function can call the Event Manager procedure SetSystemEventMask.
When ModalDialog calls TrackControl, it does not allow you to specify the action
procedure necessary for anything more complex than a button, radio button, or checkbox.
If you need a more complex control (for example, one that measures how long the user
holds down the mouse button or how far the user has moved an indicator), you can
create your own control, a picture, or an application-defined item that draws a control-
like object in your dialog box. You must then provide an event filter function that
appropriately handles events in that item.
SEE ALSO
Listing 6-26 on page 6-83 illustrates the use of ModalDialog. “Responding to Events in
Editable Text Items” beginning on page 6-79 describes how ModalDialog uses TextEdit
to handle text entry and editing in editable text items. The IsDialogEvent and
DialogSelect functions (which your application may use instead of ModalDialog for
modeless and movable modal dialog boxes) are described on page 6-138 and page 6-139,
respectively. See the description of MyEventFilter on page 6-145 for information about
the event filter function your application should specify in the filterProc parameter.
The GetNextEvent and SetSystemEventMask routines are described in the chapter
“Event Manager” in this book. See that chapter as well for a discussion of disk-inserted
events. See “Responding to Events in Controls” on page 6-78 for a description of how
your application should respond to events inside of controls; the TrackControl
function is fully described in the chapter “Control Manager” in this book. Also see that
chapter for information about creating your own nonstandard controls. TextEdit is
described in the chapter “TextEdit” of Inside Macintosh: Text.
Dialog Manager
IsDialogEvent 6
To determine whether a modeless dialog box or a movable modal dialog box is active
when an event occurs, you can use the IsDialogEvent function.
DESCRIPTION
If any event, including a null event, occurs when your dialog box is active,
IsDialogEvent returns TRUE; otherwise, it returns FALSE. When IsDialogEvent
returns FALSE, pass the event to the rest of your event-handling code. When
IsDialogEvent returns TRUE, pass the event to DialogSelect after testing for the
events that DialogSelect does not handle.
A dialog record includes a window record. When you use the GetNewDialog,
NewDialog, or NewColorDialog function to create a dialog box, the Dialog Manager
sets the windowKind field in the window record to dialogKind. To determine whether
the active window is a dialog box, IsDialogEvent checks the windowKind field.
Before passing the event to DialogSelect, you should perform the following tests
whenever IsDialogEvent returns TRUE:
■ Check whether the event is a key-down event for the Return, Enter, Esc, or
Command-period keystrokes. When the user presses the Return or Enter key, your
application should respond as if the user had clicked the default button; when the user
presses Esc or Command-period, your application should respond as if the user had
clicked the Cancel button. Use the Control Manager procedure HiliteControl to
highlight the applicable button for 8 ticks.
■ At this point, you may also want to check for and respond to any special events that
you do not wish to pass to DialogSelect or that require special processing before
you pass them to DialogSelect. You would need to do this, for example, if the
dialog box needs to respond to disk-inserted events.
■ Check whether the event is an update event for a window other than the dialog box
and, if it is, update your window.
■ For complex items that you create, such as pictures or application-defined items that
emulate complex controls, test for and respond to mouse events inside those items as
appropriate. When DialogSelect calls TrackControl, it does not allow you to
specify the action procedure necessary for anything more complex than a button, radio
button, or checkbox. If you need a more complex control (for example, one that
measures how long the user holds down the mouse button or how far the user has
moved an indicator), you can create your own control or a picture or an
application-defined item that draws a control-like object in your dialog box. You must
then test for and respond to those events yourself.
Dialog Manager
If your application uses IsDialogEvent to help handle events when you display a
movable modal dialog box, perform the following additional tests before passing events
to DialogSelect:
■ Test for mouse-down events in the title bar of the movable modal dialog box and
respond by dragging the dialog box accordingly.
■ Test for and respond to mouse-down events in the Apple menu and, if the movable
modal dialog box includes editable text items, in the Edit menu. (You should disable
all other menus when you display a movable modal dialog box.)
■ Play the system alert sound for every other mouse-down event outside the movable
modal dialog box.
SPECIAL CONSIDERATIONS
Both IsDialogEvent and DialogSelect are unreliable when running in versions of
system software earlier than System 7. You shouldn’t use these routines if you expect
your application to run in earlier versions of system software.
SEE ALSO
The WaitNextEvent function is described in the chapter “Event Manager” in this book.
See Inside Macintosh: Sound for a description of the SysBeep procedure. The
FrontWindow function is described in the chapter “Window Manager” in this book.
DialogSelect 6
After determining that an event related to an active modeless dialog box or an active
movable modal dialog box has occurred, you can use the DialogSelect function to
handle most of the events inside the dialog box.
DESCRIPTION
The DialogSelect function handles most of the events relating to a dialog box. If the
event is an activate or update event for a dialog box, DialogSelect activates or
updates it and returns FALSE. If the event involves an enabled item, DialogSelect
Dialog Manager
returns a function result of TRUE. In its itemHit parameter, it returns the item number of
the item selected by the user. In the parameter theDialog, it returns a pointer to
the dialog record for the dialog box where the event occurred. In all other cases, the
DialogSelect function returns FALSE. When DialogSelect returns TRUE, do
whatever is appropriate as a response to the event involving that item in that particular
dialog box; when it returns FALSE, do nothing.
Generally, only controls should be enabled in a dialog box; therefore your application
should normally respond only when DialogSelect returns TRUE after the user clicks
an enabled control, such as the OK button.
The DialogSelect function first obtains a pointer to the window containing the event.
For update and activate events, the event record contains the window pointer. For other
types of events, DialogSelect calls the Window Manager function FrontWindow.
The Dialog Manager then makes this window the current graphics port by calling the
QuickDraw procedure SetPort. Then DialogSelect prepares to handle the event by
setting up text information if there are any editable text items in the active dialog box.
If the event is an update event for a dialog box, DialogSelect calls the Window
Manager procedure BeginUpdate, the Dialog Manager procedure DrawDialog,
and then the Window Manager procedure EndUpdate. When an item is a control
defined in a control ('CNTL') resource, the rectangle added to the update region is the
rectangle defined in the control resource, not the display rectangle defined in the item
list resource.
The DialogSelect function handles the event as follows:
■ In response to an activate or update event for the dialog box, DialogSelect activates
or updates its window and returns FALSE.
■ If a key-down event or an auto-key event occurs and there’s an editable text item
in the dialog box, DialogSelect uses TextEdit to handle text entry and editing,
and DialogSelect returns TRUE for a function result. In its itemHit parameter,
DialogSelect returns the item number.
■ If a key-down event or an auto-key event occurs and there’s no editable text item in
the dialog box, DialogSelect returns FALSE.
■ If the user presses the mouse button while the cursor is in an editable text item,
DialogSelect responds to the mouse activity as appropriate—that is, either by
displaying an insertion point or by selecting text. If the editable text item is disabled,
DialogSelect returns FALSE. If the editable text item is enabled, DialogSelect
returns TRUE and in its itemHit parameter returns the item number. Normally,
editable text items are disabled, and you use the GetDialogItemText function to
read the information in the items only after the OK button is clicked.
■ If the user presses the mouse button while the cursor is in a control, DialogSelect
calls the Control Manager function TrackControl. If the user releases the mouse
button while the cursor is in an enabled control, DialogSelect returns TRUE for a
function result and in its itemHit parameter returns the control’s item number. Your
application should respond appropriately—for example, by performing a command
after the user clicks the OK button.
Dialog Manager
■ If the user presses the mouse button while the cursor is in any other enabled item in
the dialog box, DialogSelect returns TRUE for a function result and in its itemHit
parameter returns the item’s number. Generally, only controls should be enabled. If
your application creates a complex control—such as one that measures how far a dial
is moved—your application must handle mouse events in that item before passing the
event to DialogSelect.
■ If the user presses the mouse button while the cursor is in a disabled item, or if it is in
no item, or if any other event occurs, DialogSelect does nothing.
■ If the event isn’t one that DialogSelect specifically checks for (if it’s a null event, for
example), and if there’s an editable text item in the dialog box, DialogSelect calls
the TextEdit procedure TEIdle to make the insertion point blink.
SPECIAL CONSIDERATIONS
Because DialogSelect handles only mouse-down events in a dialog box and key-down
events in a dialog box’s editable text items, you should handle other events
as appropriate before passing them to DialogSelect. Likewise, when DialogSelect
calls TrackControl, it does not allow you to specify any action procedure necessary for
anything more complex than a button, radio button, or checkbox. If you need a more
complex control (for example, one that measures how long the user holds down the
mouse button or how far the user has moved an indicator), you can create your own
control or a picture or an application-defined item that draws a control-like object in your
dialog box. You must then test for and respond to those events yourself.
Within dialog boxes, use the procedures DialogCut, DialogCopy, DialogPaste, and
DialogDelete to support Cut, Copy, Paste, and Clear commands in editable text boxes.
The DialogSelect function is unreliable when running in versions of system software
earlier than System 7. You shouldn’t use this routine if you expect your application to run
under earlier versions of system software.
SEE ALSO
Listing 6-25 on page 6-79 illustrates the use of DialogSelect to make the cursor blink
in editable text items during null events; Listing 6-29 on page 6-92 illustrates the use of
DialogSelect to handle mouse events in a modeless dialog box; Listing 6-33 on
page 6-96 illustrates the use of DialogSelect to handle key-down events in editable
text items; Listing 6-34 on page 6-98 illustrates the use of DialogSelect to handle
activate events in a modeless dialog box.
Dialog Manager
DrawDialog 6
If you don’t use any other Dialog Manager routines for handling events in a dialog box,
you can use the DrawDialog procedure to draw its entire contents.
DESCRIPTION
The DrawDialog procedure draws the entire contents of the specified dialog box. The
DrawDialog procedure draws all dialog items, calls the Control Manager procedure
DrawControls to draw all controls, and calls the TextEdit procedure TEUpdate to
update all static and editable text items and to draw their display rectangles. The
DrawDialog procedure also calls the application-defined items’ draw procedures if
the items’ rectangles are within the update region.
The DialogSelect, ModalDialog, Alert, StopAlert, NoteAlert, and
CautionAlert routines use DrawDialog automatically. If you use GetNewDialog
to create a dialog box but don’t use any of these other Dialog Manager routines when
handling events in the dialog box, you can use DrawDialog to redraw the contents of
the dialog box when it’s visible. If the dialog box is invisible, first use the Window
Manager procedure ShowWindow and then use DrawDialog.
SEE ALSO
See the chapters “Window Manager” and “Event Manager” in this book for more
information on update and activate events for windows. The DrawControls procedure
is described in the chapter “Control Manager” in this book. The TEUpdate procedure is
described in the chapter “TextEdit” in Inside Macintosh: Text.
UpdateDialog 6
You can use the UpdateDialog procedure to redraw the update region of a
specified dialog box. The UpdateDialog procedure is also available as the UpdtDialog
procedure.
Dialog Manager
DESCRIPTION
The UpdateDialog procedure redraws only the region in a dialog box specified in the
updateRgn parameter. Because the DialogSelect, ModalDialog, Alert,
StopAlert, NoteAlert, and CautionAlert routines automatically call DrawDialog
to handle update events in your alert and dialog boxes, your application might never
need to use UpdateDialog.
Instead of drawing the entire contents of the specified dialog box, UpdateDialog draws
only the items in the specified update region. You can use UpdateDialog in response to
an update event, and you should usually bracket it by calls to the Window Manager
procedures BeginUpdate and EndUpdate. The UpdateDialog procedure uses the
QuickDraw procedure SetPort to make the dialog box the current graphics port. For
drawing controls, UpdateDialog uses the Control Manager procedure
UpdateControls, which is faster than the DrawControls procedure.
SEE ALSO
Listing 6-35 on page 6-99 illustrates the use of UpdateDialog to respond to update
events in a modeless dialog box. See the chapter “Window Manager” in this book for
more information on update and activate events for windows. The UpdateControls
procedure is described in the chapter “Control Manager” in this book.
Application-Defined Routines 6
If you supply an application-defined item in a dialog box, you must provide a draw
procedure for the Dialog Manager to use when displaying the item; that procedure is
referred to in this section as MyItem. If you want the Dialog Manager to play sounds
other than the system alert sound, you must provide your own sound procedure, referred
to in this section as MyAlertSound. To supplement the Dialog Manager’s ability to
handle events in the Macintosh multitasking environment, you should provide an event
filter function that the Dialog Manager calls whenever it displays alert boxes and modal
dialog boxes. This function is referred to as MyEventFilter.
MyItem 6
To draw your own application-defined item in a dialog box, provide a draw procedure
that takes two parameters: a window pointer to the dialog box and an item number from
the dialog box’s item list resource. For example, this is how you should declare the
procedure if you were to name it MyItem:
theWindow A pointer to the dialog record for the dialog box containing an
application-defined item. If your procedure can draw in more than
one dialog box, this parameter tells your procedure which one to
draw in.
Dialog Manager
DESCRIPTION
The Dialog Manager calls your procedure to draw an application-defined item at the time
you display the specified dialog box. When calling your draw procedure, the Dialog
Manager sets the current port to the dialog box’s graphics port. Normally, you create an
invisible dialog box and then use the Window Manager procedure ShowWindow to
display the dialog box.
Before you display the dialog box, use the SetDialogItem procedure to install this
procedure in the dialog record. Before using SetDialogItem, you must first use the
GetDialogItem procedure to obtain a handle to an item of type userItem.
If you enable the application-defined item that you draw with this procedure, the
ModalDialog procedure and the DialogSelect function return the item’s number
when the user clicks that item. If your application needs to respond to a user action more
complex than this (for example, if your application needs to measure how long the user
holds down the mouse or how far the user drags the cursor), your application must track
the cursor itself. If you use ModalDialog, your event filter function must handle events
inside the item; if you use DialogSelect, your application must handle events inside
the item before handing events to DialogSelect.
SEE ALSO
Listing 6-17 on page 6-59 illustrates a procedure that draws a bold outline around
a button of any size and shape; Listing 6-16 on page 6-58 shows the use of
GetDialogItem and SetDialogItem to install this draw procedure in a dialog
record. The ShowWindow procedure is described in the chapter “Window Manager”
in this book.
MyAlertSound 6
If you want the Dialog Manager to play sounds other than the system alert sound, write
your own sound procedure and call the ErrorSound procedure to make it the current
sound procedure. For example, you can declare a sound procedure named
MyAlertSound, as shown here:
Dialog Manager
DESCRIPTION
For each of the four alert stages that can be reported in the soundNo parameter, your
procedure can emit any sound that you define. When the Dialog Manager calls your
procedure, it passes 0 as the sound number for alert sounds specified by the silent
constant in the alert resource. The Dialog Manager passes 1 for sounds specified by the
sound1 constant, 2 for sounds specified by the sound2 constant, and 3 for sounds
specified by the sound3 constant.
SPECIAL CONSIDERATIONS
When the Dialog Manager detects a click outside an alert box or a modal dialog box, it
uses the Sound Manager procedure SysBeep to play the system alert sound. By
changing settings in the Sound control panel, the user can select which sound to play as
the system alert sound. For consistency with system software and other Macintosh
applications, your sound procedure should call SysBeep whenever your sound
procedure receives sound number 1 (which you can represent with the sound1 constant).
SEE ALSO
Listing 6-3 on page 6-22 illustrates how to use MyAlertSound. The SysBeep procedure
is described in Inside Macintosh: Sound.
MyEventFilter 6
To supplement the Dialog Manager’s ability to handle events, your application should
provide an event filter function that the Dialog Manager calls when it displays alert boxes
and modal dialog boxes. Your event filter function should have three parameters and
return a Boolean value. For example, this is how you would declare it if you were to
name it MyEventFilter:
theDialog A pointer to a dialog record for an alert box or a modal dialog box.
theEvent An event record returned by an Event Manager function such as
WaitNextEvent.
itemHit A number corresponding to the position of an item in the item list
resource for the alert or modal dialog box.
Dialog Manager
DESCRIPTION
After receiving an event that it does not handle, your function should return FALSE.
When your function returns FALSE, ModalDialog handles the event, which you pass
in the parameter theEvent. (Your function can also change the event to simulate a
different event and return FALSE, which passes the event to the Dialog Manager for
handling.) If your function does handle the event, your function should return TRUE
as a function result, and in the itemHit parameter return the number of the item
that it handled. The ModalDialog procedure and, in turn, the Alert, NoteAlert,
StopAlert, and CautionAlert functions then return this item number in their own
itemHit parameters.
Your event filter function should perform the following tasks:
■ return TRUE and the item number for the default button if the user presses Return
or Enter
■ return TRUE and the item number for the Cancel button if the user presses Esc or
Command-period
■ update your windows in response to update events (this allows background
applications to receive update events) and return FALSE
■ return FALSE for all events that your event filter function doesn’t handle
You can also use the event filter function to test for and respond to keyboard equivalents
and more complex events—for instance, the user dragging the cursor in an application-
defined item. For example, if you provide an application-defined item that requires you
to measure how long the user holds down the mouse button or how far the user drags
the cursor, use the event filter function to handle events inside that item.
The ModalDialog procedure calls the Event Manager function GetNextEvent with a
mask that excludes disk-inserted events; to receive disk-inserted events, your event filter
function can call the Event Manager procedure SetSystemEventMask.
You can use the same event filter function in most or all of your alert and modal
dialog boxes.
For alert and modal dialog boxes, the Dialog Manager provides a standard event filter
function that checks whether the user has pressed the Enter or Return key and, if so,
returns the item number of the default button. Your event filter function should always
check whether the Return key or Enter key was pressed and, if so, return the number of
the default button in the itemHit parameter and a function result of TRUE.
In all alert and dialog boxes, any buttons that are activated by key sequences should
invert to indicate which item has been selected. Use the Control Manager procedure
HiliteControl to invert a button for 8 ticks, long enough to be noticeable but not so
long as to be annoying. The Control Manager performs this action whenever users click a
button, and your application should do this whenever the user presses the keyboard
equivalent of a button click.
Dialog Manager
For modal dialog boxes that contain editable text items, your application should handle
menu bar access to allow use of your Edit menu and its Cut, Copy, Paste, Clear, and
Undo commands. Your event filter function should then test for and handle clicks
in your Edit menu and keyboard equivalents for the appropriate commands in your
Edit menu. Your application should respond by using the procedures DialogCut,
DialogCopy, DialogPaste, and DialogDelete to support the Cut, Copy, Paste, and
Clear commands.
For an alert box, you specify a pointer to your event filter function in a parameter that
you pass to the Alert, StopAlert, CautionAlert, and NoteAlert functions. For a
modal dialog box, specify a pointer to your event filter function in a parameter that you
pass to the ModalDialog procedure.
SEE ALSO
Listing 6-27 on page 6-88 illustrates an event filter function. The functions
GetNextEvent and SetSystemEventMask are described in the chapter
“Event Manager” in this book.
Resources 6
This section describes resources used by the Dialog Manager for displaying alerts and
dialog boxes. These resources are
■ the dialog ('DLOG') resource, which specifies the window type, display rectangle, and
item list resource for a dialog box
■ the alert ('ALRT') resource, which specifies alert sounds, a display rectangle, and an
item list resource for an alert box
■ the item list ('DITL') resource, which specifies the items—such as buttons and static
text—to display in an alert box or a dialog box
■ the dialog color table ('dctb') resource, which lets you supply a color graphics port
for a dialog box and also use colors other than the default colors in a dialog box
■ the alert color table ('actb') resource, which lets you use colors other than the
default colors in an alert box
■ the item color table ('ictb') resource, which lets you change the default colors,
typeface, font style, and font size of items in an alert box or a dialog box
This section describes the structures of these resources after they are compiled by the Rez
resource compiler, available from APDA. If you are interested in creating the Rez input
files for these resources, see “Using the Dialog Manager” beginning on page 6-17 for
detailed information.
Dialog Manager
Rectangle 8
Window definition ID 2
Visibility 1
Reserved 1
Close box specification 1
Reserved 1
Reference constant 4
Item list ID 2
Alignment byte 0 or 1
Dialog box position 2
Dialog Manager
■ If the integer 4 appears here (as specified in the Rez input file by the
noGrowDocProc window definition ID), the Dialog Manager displays a
modeless dialog box.
■ If the integer 5 appears here (as specified in the Rez input file by the
movableDBoxProc window definition ID), the Dialog Manager displays
a movable modal dialog box.
These types of dialog boxes are illustrated in Figure 6-6 on page 6-10, Figure 6-8 on
page 6-12, and Figure 6-7 on page 6-11, respectively.
■ Visibility. If this is set to a value of 1 (as specified by the visible constant in the Rez
input file), the Dialog Manager displays this dialog box as soon as you call the
GetNewDialog function. If this is set to a value of 0 (as specified by the invisible
constant in the Rez input file), the Dialog Manager does not display this dialog box
until you call the Window Manager procedure ShowWindow.
■ Close box specification. This specifies whether to draw a close box. Normally, this is
set to a value of 1 (as specified by the goAway constant in the Rez input file) only for a
modeless dialog box to specify a close box in its title bar. Otherwise, this is set to a
value of 0 (as specified by the noGoAway constant in the Rez input file).
■ Reference constant. This contains any value that an application stores here. For
example, an application can store a number that represents a dialog box type, or
it can store a handle to a record that maintains state information about the dialog
box or other window types. An application can use the Window Manager procedure
SetWRefCon at any time to change this value in the dialog record for a dialog box,
and you can use the GetWRefCon function to determine its current value.
■ Item list resource ID. The ID of the item list resource that specifies the items—such as
buttons and static text—to display in the dialog box.
■ Window title. This is a Pascal string displayed in the dialog box’s title bar only when
the dialog box is modeless.
■ Alignment byte. This is an extra byte added if necessary to make the previous Pascal
string end on a word boundary.
■ Dialog box position. This specifies the position of the dialog box on the screen. (If your
application positions dialog boxes on its own, don’t use these constants, because your
code may conflict with the Dialog Manager.)
■ If 0x0000 appears here (as specified by the noAutoCenter constant in the Rez
input file), the Dialog Manager positions this dialog box according to the global
coordinates specified in the rectangle element of this resource.
■ If 0xB00A appears here (as specified by the alertPositionParentWindow
constant in the Rez input file), the Dialog Manager positions the dialog box over the
frontmost window so that the window’s title bar appears. This is illustrated in
Figure 6-33 on page 6-63.
■ If 0x300A appears here (as specified by the alertPositionMainScreen constant
in the Rez input file), the Dialog Manager centers the dialog box near the top of the
main screen. This is illustrated in Figure 6-34 on page 6-63.
■ If 0x700A appears here (as specified in the Rez input file by the
alertPositionParentWindowScreen constant), the Dialog Manager
positions the dialog box on the screen where the user is currently working.
This is illustrated in Figure 6-35 on page 6-64.
Dialog Manager
Rectangle 8
Dialog Manager
■ If the second bit is set, the Dialog Manager displays the alert box at this stage. If the
second bit is not set, the Dialog Manager doesn’t display the alert box at this stage.
■ If neither of the next 2 bits is set, the Dialog Manager plays no alert sound at this
stage. If bit 3 is set and bit 4 is not set, the Dialog Manager plays the first alert
sound—by default, the system alert sound. If bit 3 is not set and bit 4 is set, the
Dialog Manager plays the second alert sound; by default, it plays the system alert
sound twice. If both bit 3 and bit 4 are set, the Dialog Manager plays the third alert
sound; by default, it plays the system alert sound three times. By defining your own
alert sound (described on page 6-144) and calling the ErrorSound procedure
(described on page 6-104) to make it the current sound procedure, you can specify
your own alert sounds.
■ Third-stage alert information. This specifies the response when the user repeats the
action that invokes this alert three consecutive times. The Dialog Manager interprets
these 4 bits in the manner described for the fourth-stage alert.
■ Second-stage alert information. This specifies the response when the user repeats the
action that invokes this alert two consecutive times. The Dialog Manager interprets
these 4 bits in the manner described for the fourth-stage alert.
■ First-stage alert information. This specifies the response for the first time that the user
performs the action that invokes this alert. The Dialog Manager interprets these 4 bits
in the manner described for the fourth-stage alert.
■ Alert box position. This specifies the position of the alert box on the screen. (If your
application positions alert boxes on its own, don’t use these constants, because your
code may conflict with the Dialog Manager.)
■ If 0x0000 appears here (as specified by the noAutoCenter constant in the Rez
input file), the Dialog Manager positions this alert box according to the global
coordinates specified in the rectangle element of this resource.
■ If 0xB00A appears here (as specified by the alertPositionParentWindow
constant in the Rez input file), the Dialog Manager positions the alert box over the
frontmost window so that the window’s title bar appears. This is illustrated in
Figure 6-33 on page 6-63.
■ If 0x300A appears here (as specified by the alertPositionMainScreen constant
in the Rez input file), the Dialog Manager centers the alert box near the top of the
main screen. This is illustrated in Figure 6-34 on page 6-63.
■ If 0x700A appears here (as specified in the Rez input file by the
alertPositionParentWindowScreen constant), the Dialog Manager
positions the alert box on the screen where the user is currently working.
This is illustrated in Figure 6-35 on page 6-64.
Dialog Manager
For an alert box, you specify the resource ID of the item list resource in an alert
resource (described beginning on page 6-150). For a dialog box that you create with
the GetNewDialog function, you specify the resource ID of the item list resource in a
dialog resource (described beginning on page 6-148). For a dialog box that you create
with either the NewColorDialog function (described on page 6-115) or the NewDialog
function (described on page 6-118), you use the Resource Manager function
GetResource to read the item list resource into memory and to provide a handle to
the item list resource in memory.
The format of a Rez input file for an item list resource differs from its compiled output
format. This section describes the structure of a Rez-compiled item list resource. If you
are concerned only with creating an item list resource, see “Providing Items for Alert and
Dialog Boxes” beginning on page 6-26.
Figure 6-44 shows the format of a compiled item list resource.
The compiled version of an item list resource contains the following elements:
■ Item count minus 1. This value is 1 less than the total number of items defined in
this resource.
■ A variable number of items.
The format of each item depends on its type. Figure 6-45 shows the format of an item
defined to be a button, a checkbox, a radio button, a static text item, or an editable
text item.
The compiled version of a button, checkbox, radio button, static text item, or editable text
item consists of the following elements:
■ Reserved. The Dialog Manager uses the element for storage.
■ Display rectangle. This determines the size and location of the item in the alert box or
dialog box. The display rectangle is specified in coordinates local to the alert box
or dialog box; these coordinates specify the upper-left and lower-right corners of
the item.
Dialog Manager
Figure 6-45 Structure of compiled button, checkbox, radio button, static text, and editable
text items
Reserved 4
Display rectangle 8
Text 1 to 256
Alignment byte 0 or 1
■ Enable flag. This specifies whether the item is enabled or disabled. If this bit is set,
the item is enabled and the Dialog Manager reports to your application whenever
mouse-down events occur inside this item.
■ Item type.
■ If this bit string is set to 4 (as specified in the Rez input file by the Button constant),
then the item is a button.
■ If this bit string is set to 5 (as specified in the Rez input file by the CheckBox
constant), then the item is a checkbox.
■ If this bit string is set to 6 (as specified in the Rez input file by the RadioButton
constant), then the item is a radio button.
■ If this bit string is set to 8 (as specified in the Rez input file by the StaticText
constant), then the item is static text.
■ If this bit string is set to 16 (as specified in the Rez input file by the EditText
constant), then the item is editable text.
■ Text. This specifies the text that appears in the item. This element consists of a length
byte and as many as 255 additional bytes for the text. (“Titles for Buttons, Checkboxes,
and Radio Buttons” beginning on page 6-37 and “Text Strings for Static Text and
Editable Text Items” beginning on page 6-40 contain recommendations about appro-
priate text in items.)
■ For a button, checkbox, or radio button, this is the title for that control.
■ For an editable text item, this can be an empty string (in which case the editable text
item contains no text), or it can be a string that appears as the default string in the
editable text item.
■ Alignment byte. This is added if necessary to make the previous text string end on a
word boundary.
Dialog Manager
Figure 6-46 shows the format for an element defined to be a control, an icon, or a
picture item.
Reserved 4
Display rectangle 8
The compiled version of a control, an icon, or a picture item consists of the following
elements:
■ Reserved. The Dialog Manager uses the element for storage.
■ Display rectangle. This determines the size and location of the item in the alert box
or dialog box. The display rectangle is specified in coordinates local to the alert or
dialog box.
■ Enable flag. This specifies whether the item is enabled or disabled. If this bit is set, the
item is enabled and the Dialog Manager reports to your application whenever
mouse-down events occur inside this item.
■ Item type.
■ If this 7-bit string is set to 7 (as specified in the Rez input file by the Control
constant), then the item is a button.
■ If this is set to 32 (as specified in the Rez input file by the Icon constant), then the
item is an icon.
■ If this is set to 64 (as specified in the Rez input file by the Picture constant), then
the item is a QuickDraw picture.
■ Resource ID.
■ For a control item, this is the resource ID of a 'CTRL' resource.
■ For an icon item, this is the resource ID of an 'ICON' resource and, optionally, a
'cicn' resource
■ For a picture item, this is the resource ID of a 'PICT' resource.
Dialog Manager
Reserved 4
Display rectangle 8
Reserved 4
Reserved 8
Resource ID 2
Item number 2
(HMScanAppendhdlg only)
Dialog Manager
Dialog Manager
■ When you need to produce a blended gray color for outlining the inactive (that is,
dimmed) default button, you must create a dialog color table ('dctb') resource with
the same resource ID as the dialog resource.
“Using an Application-Defined Item to Draw the Bold Outline for a Default Button”
beginning on page 6-56 explains how to create a draw routine that outlines the default
button of a dialog box. If you deactivate a dialog box, you should dim its buttons and use
gray to draw the outline for the default button. Because GetNewDialog and NewDialog
supply black-and-white graphics ports for dialog boxes, you can create a dialog color
table resource for the dialog box to force the Dialog Manager to supply a color graphics
port. Then you can use a blended gray color for the outline for the default button. (The
NewColorDialog function supplies a color graphics port.)
Even when you create a dialog color table resource for drawing a gray outline, you
should not change the system’s default colors. If you feel absolutely compelled to use
nonstandard colors, you can use the Dialog Manager to specify colors other than the
default colors. Your application can specify its own colors for a dialog box by creating a
dialog color table ('dctb') resource with the same resource ID as the dialog resource
(described beginning on page 6-148). You don’t have to call any new routines to change
the colors used in dialog boxes. When you call the GetNewDialog function, for example,
the Dialog Manager automatically attempts to load a dialog color table resource with the
same resource ID as the dialog resource.
Be aware, however, that nonstandard colors in your dialog boxes may initially confuse
your users. Also be aware that despite any changes you may make, users can alter the
colors of dialog boxes anyway by changing settings in the Color control panel.
▲ WARNING
Because the behavior of color alert and dialog boxes, color items, and
color icons is unreliable on computers using system software versions
earlier than System 7, do not create these color elements if you wish to
maintain backward compatibility. ▲
A dialog color table resource has exactly the same format as a window color table (that is,
a resource of type 'wctb'), which is described in the chapter “Window Manager” of this
book.
If the dialog box’s content color isn’t white, specify the invisible constant in the dialog
resource. Use the Window Manager procedure ShowWindow to display the dialog box
when it’s the frontmost window. If the dialog box is a modeless dialog box that is not in
front, use the Window Manager procedure ShowHide to display it.
Dialog Manager
If you feel absolutely compelled to use nonstandard colors, you can use the Dialog
Manager to specify colors other than the default colors. Your application can specify its
own colors for an alert box by creating an alert color table ('actb') resource with the
same resource ID as the alert resource (described beginning on page 6-150). You don’t
have to call any new routines to change the colors used in alert or dialog boxes. When
you call the Alert function, for example, the Dialog Manager automatically attempts to
load an alert color table resource with the same resource ID as the alert resource.
Be aware, however, that nonstandard colors in your alert boxes may initially confuse
your users. Also be aware that despite any changes you may make, users can alter the
colors of dialog boxes anyway by changing settings in the Color control panel.
▲ WARNING
Because the behavior of color alert and dialog boxes, color items, and
color icons is unreliable on computers using system software versions
earlier than System 7, do not create these color elements if you wish to
maintain backward compatibility. ▲
An alert color table resource has exactly the same format as a window color table
('wctb') resource, which is described in the chapter “Window Manager” of this book.
Note
The Dialog Manager displays the typeface, font style, and font size you
specify only on color monitors. ◆
Your application can specify these by creating an item color table ('ictb') resource with
the same resource ID as the dialog or alert box’s item list resource , and then providing a
dialog color table resource for a dialog box or an alert color table resource for an alert
box. You don’t have to call any new routines to change the colors, typefaces, font styles,
or font sizes used in dialog boxes. When you call the GetNewDialog function, for
example, the Dialog Manager automatically attempts to load an item color table resource
with the same resource ID as the item list resource.
Note
To make it easier to localize your application for other script
systems, you should not change the font. Do not use a smaller font,
such as 9-point Geneva; some script systems, such as KanjiTalk,
require 12-point fonts. ◆
Also, be aware that nonstandard colors for items in your dialog and alert boxes may
initially confuse your users.
Dialog Manager
▲ WARNING
Because the behavior of color alert and dialog boxes, color items, and
color icons is unreliable on computers using system software versions
earlier than System 7, do not create these color elements if you wish to
maintain backward compatibility. ▲
If you want to provide an item color table resource for an alert box or a dialog box, you
must create an alert color table resource or a dialog color table resource, even if the item
color table resource has no actual color information and describes only static text and
editable text style changes.
An item color table resource is a resource of type 'ictb'. All item color table resources
must have resource ID numbers greater than 128.
There is no Rez template available for creating item color table resources. When
you compile an item color table resource, it should follow the format illustrated in
Figure 6-49.
Item data 2
First item
Item offset 2
Item data 2
Last item
Item offset 2
First
control color table or (Variable)
text style table
Last
control color table or (Variable)
font style table
Dialog Manager
You define an item color table resource for a dialog box or an alert box by specifying
these elements in a resource with the 'ictb' resource type:
■ Items. These consist of a variable number of items, corresponding to those in an item
list resource with the same resource ID as this item color table resource.
■ Control color tables and text style tables.
■ A control color table defines the colors used in a control. Several controls can share
the same control color table.
■ A text style table defines the font family, font style, font size, and color of text in an
editable text item or a static text item. Several editable text and static text items can
share the same text style table.
■ Optionally, a list of font families. If you use any text style tables, you generally
conclude the item color table resource with a list of text strings, each of which specifies
a font family. Although you may specify font numbers instead of font names, it’s much
more reliable to specify names, because system software may renumber these fonts as
they are installed and removed. For every editable text item and static text item listed
at the top of the item color table resource, specify a font family at the bottom of the
resource.
The information contained in an element depends on the type of item it describes:
■ Item data. This contains information about how this item is described in the rest of this
resource.
■ For a control, this is the length (in bytes) of its control color table.
■ For a static text item or an editable text item, the bits of this element determine
which elements of the text style table to use and are interpreted as follows:
Bit Meaning
0 Change the font family.
1 Change the typeface.
2 Change the font size.
3 Change the font foreground color.
4 Add the font size.
13 Change the font background color.
14 Change the font mode.
15 The font element is an offset to the name.
■ Item offset. The number of bytes from the beginning of the resource to either the
control color table or the text style table that describes this item.
When both the item data and item offset elements are set to 0, then the control or text
item is drawn with the default colors, typeface, font size, and font style. Even if only the
first few items of the dialog box have color style information, there must be room for all
of the items actually in the box (with the item data and item offset elements of the unused
entries set to 0).
Dialog Manager
For controls, the colors are described by a color table identical to a 'cctb' resource used
by the Control Manager. Multiple controls can use the same color table. If the resource
sets both the item data and the item offset element to 0, then the system’s default colors
are used for the control. The format of a control color table is illustrated in Figure 6-50.
Reserved 4
Reserved 2
Red component 2
Green component 2
Blue component 2
Red component 2
Green component 2
Blue component 2
Dialog Manager
■ Part identifier. This is a value that identifies a part of the first control. The following
list shows the values and constants they represent for the standard controls other than
scroll bars. For information on the part identifiers for a scroll bar, see the description of
the control color table resource in the chapter “The Control Manager” in this book.
They can be listed in any order in the control color table.
■ Red component. This is an integer that represents the intensity of the red component
of the color to use when drawing this control part.
■ Green component. This is an integer that represents the intensity of the green
component of the color to use when drawing this control part.
■ Blue component. This is an integer that represents the intensity of the blue component
of the color to use when drawing this control part.
■ Part identifier, and the red, green, and blue color components for the next control part.
Specify color components for every part of this control whose color you want to
change. If a part is not listed in the control color table, the Dialog Manager draws it in
its default color.
Figure 6-51 shows the format of a text style table.
Typeface 2
Font style 2
Font size 2
Mode 2
Dialog Manager
The text style table must be 20 bytes long, as shown in Figure 6-51. Multiple editable text
and static text items can use the same text style record. To display text in the standard
typeface, color, font size, and font style, set the item data and item offset elements for the
item to 0. Allocate space for all fields in the text style table, even if they are not used.
A text style table consists of the following elements (see Inside Macintosh: Text for a
discussion of font families, font style, and point sizes):
■ Typeface. This is the name of the font family to use. If bit 15 in the item data element is
set to 1, then this element contains an offset (in bytes) to a font name element at the
end of the resource. If bit 0 in the item data element is set to 1, then this element
contains the number of a font family. If bit 0 in the item data element is set to 0, this
element is set to 0, and the system default font is used.
■ Font style. This is the font style to use. If bit 1 in the item data element is set to 1, then
this element uses the bits of the low-order byte to describe which styles to apply to the
text. If all bits in the low-order byte are set to 0, the plain font style is used. The bit
numbers and the styles they represent are
Bit
value Style
0 Bold
1 Italic
2 Underline
3 Outline
4 Shadow
5 Condensed
6 Extended
■ Font size. This is the point size of the font. If bit 2 in the item data element is set to 1,
this element contains a value representing a point size. If bit 4 in the item data element
is set to 1, this element contains a value to add to the current point size of the text. If
bit 0 in the item data element is set to 0, this element is set to 0, and the system font
size (12) is used.
■ Text red color. If bit 3 in the item data element is set to 1, this element contains an
integer that represents the intensity of the red component of the color to use when
drawing the text.
■ Text green color. If bit 3 in the item data element is set to 1, this element contains an
integer that represents the intensity of the green component of the color to use when
drawing the text.
■ Text blue color. If bit 3 in the item data element is set to 1, this element contains an
integer that represents the intensity of the blue component of the color to use when
drawing the text.
■ Background red color. If bit 13 in the item data element is set to 1, this element
contains an integer that represents the intensity of the red component of the color
to use when drawing the background behind the text.
Dialog Manager
■ Background green color. If bit 13 in the item data element is set to 1, this element
contains an integer that represents the intensity of the green component of the color
to use when drawing the background behind the text.
■ Background blue color. If bit 13 in the item data element is set to 1, this element
contains an integer that represents the intensity of the blue component of the color
to use when drawing the background behind the text.
■ Mode. If bit 14 in the item data element is set to 1, this element contains an integer that
represents how characters are placed in the bit image. The values that the Dialog
Manager interprets and the constants that represent them are listed here. See Inside
Macintosh: Imaging for a discussion of source transfer modes.
Constant Value
scrOr 1
srcXor 2
srcBic 3
Dialog Manager
Pascal Summary 6
Constants 6
CONST
{checking for AppendDITL, ShortenDITL, CountDITL using Gestalt function}
gestaltDITLExtAttr = 'ditl'; {Gestalt selector for AppendDITL, etc.}
gestaltDITLExtPresent = 0; {if this bit's set, then AppendDITL, }
{ ShortenDITL, & CountDITL are available}
Dialog Manager
Data Types 6
DITLMethod = Integer;
Creating Alerts
{some routines have 2 spellings--see Table 6-1 for the alternate spellings}
FUNCTION Alert (alertID: Integer; filterProc:
ModalFilterProcPtr): Integer;
FUNCTION StopAlert (alertID: Integer; filterProc:
ModalFilterProcPtr): Integer;
FUNCTION NoteAlert (alertID: Integer; filterProc:
ModalFilterProcPtr): Integer;
FUNCTION CautionAlert (alertID: Integer; filterProc:
ModalFilterProcPtr): Integer;
FUNCTION GetAlertStage : Integer;
PROCEDURE ResetAlertStage;
Dialog Manager
Dialog Manager
Application-Defined Routines 6
C Summary 6
Constants 6
enum {
/*checking for AppendDITL, ShortenDITL, CountDITL using Gestalt function*/
#define gestaltDITLExtAttr 'ditl' /*Gestalt selector*/
gestaltDITLExtPresent = 0 /*if this bit's set, then AppendDITL, */
/* ShortenDITL, & CountDITL are available*/
};
enum {
/*item types for GetDItem, SetDItem*/
ctrlItem = 4, /*add this constant to the next four constants*/
btnCtrl = 0, /*standard button control*/
chkCtrl = 1, /*standard checkbox control*/
radCtrl = 2, /*standard radio button*/
resCtrl = 3, /*control defined in a control resource*/
statText = 8, /*static text*/
editText = 16, /*editable text*/
iconItem = 32, /*icon*/
Dialog Manager
enum {
/*constants used for theMethod parameter in AppendDITL*/
overlayDITL = 0, /*overlay existing items*/
appendDITLRight = 1, /*append at right*/
appendDITLBottom = 2 /*append at bottom*/
};
enum {
/*constants for procID parameter of NewDialog, NewColorDialog*/
dBoxProc = 1, /*modal dialog box*/
noGrowDocProc = 4, /*modeless dialog box*/
movableDBoxProc = 5 /*movable modal dialog box*/
};
Data Types 6
struct DialogRecord{
WindowRecord window; /*dialog window*/
Handle items; /*item list resource*/
TEHandle textH; /*current editable text item*/
short editField; /*editable text item number minus 1*/
short editOpen; /*used internally*/
short aDefItem; /*default button item number*/
};
Dialog Manager
Creating Alerts
/*some routines have 2 spellings--see Table 6-1 for the alternate spellings*/
pascal short Alert (short alertID, ModalFilterProcPtr filterProc);
pascal short StopAlert (short alertID, ModalFilterProcPtr filterProc);
pascal short NoteAlert (short alertID, ModalFilterProcPtr filterProc);
pascal short CautionAlert (short alertID, ModalFilterProcPtr filterProc);
#define GetAlertStage() (* (short*) 0x0A9A);
pascal void ResetAlertStage (void);
Dialog Manager
Dialog Manager
Application-Defined Routines 6
pascal void MyItem (WindowPtr theWindow, short itemNo);
pascal void MyAlertSound (short soundNo);
pascal Boolean MyEventFilter (DialogPtr theDialog, *EventRecord theEvent,
*short itemHit);
Assembly-Language Summary 6
Data Structures 6
Global Variables 6
DAStrings Handles to text strings specified with the ParamText procedure
DABeeper Address of current sound procedure
DlgFont Font number for text in dialog boxes and alert boxes
ACount Alert stage number (0 through 3) of the last alert
ANumber Resource ID of last alert
ResumeProc Address of resume procedure (should not be used in System 7)
Figure 7-0
Listing 7-0
Table 7-0
7 Finder Interface
Contents
Introduction to the Finder Interface 7-3
About the Finder Interface 7-6
Using the Finder Interface 7-6
Giving a Signature to Your Application and a Creator and a
File Type to Your Documents 7-8
Creating Icons for the Finder 7-11
Creating Customized Document Icons 7-17
Creating File Reference Resources 7-18
Creating a Bundle Resource 7-20
How and When the Finder Launches Your Application 7-25
Displaying Messages When the Finder Can’t Find Your Application 7-27
Providing Version Resources 7-31
Using Finder Information in the Catalog File 7-32
Supporting Stationery Pads 7-34
Distributing Fonts, Sounds, and Other Movable Resources 7-36
Providing Balloon Help for Nondocument Icons 7-38
Using Aliases 7-39
Using the System Folder and Its Related Directories 7-41
The Desktop Database 7-45
Finder Interface Reference 7-46
Data Structures 7-46
File Information Record 7-47
Extended File Information Record 7-49
Directory Information Record 7-50
Extended Directory Information Record 7-50
Routines 7-51
Resolving Alias Files 7-51
Finding Directories 7-53
Contents 7-1
C H A P T E R 7
Resources 7-56
The Signature Resource 7-57
The Icon List Resource 7-57
The Small Icon List Resource 7-58
The Large 4-Bit Color Icon Resource 7-59
The Small 4-Bit Color Icon Resource 7-60
The Large 8-Bit Color Icon Resource 7-61
The Small 8-Bit Color Icon Resource 7-62
The Icon Resource 7-63
The Color Icon Resource 7-64
The File Reference Resource 7-64
The Bundle Resource 7-65
The Missing-Application Name String 7-68
The Application-Missing Message String 7-68
The Version Resource 7-69
Summary of the Finder Interface 7-71
Pascal Summary 7-71
Constants 7-71
Data Types 7-73
Routines 7-74
C Summary 7-74
Constants 7-74
Data Types 7-76
Routines 7-77
Assembly-Language Summary 7-77
Data Structures 7-77
Result Codes 7-78
7-2 Contents
C H A P T E R 7
Finder Interface 7
The Finder is an application that works with the system software to keep track of files
and manage the user’s desktop display. This chapter describes the programming
interface your application should use to interact with the Finder.
To use this chapter, you should be familiar with the Resource Manager. See the chapter
“Introduction to the Macintosh Toolbox” in this book for general information about
resources; detailed information about the Resource Manager and its routines is provided
in the chapter “Resource Manager” in Inside Macintosh: More Macintosh Toolbox. Virtually
all software intended for Macintosh computers must use the Finder-related resources
described in this chapter.
Read this chapter to learn how to
■ set up the resources the Finder needs to display and start up your application
■ set up the resources the Finder uses to display information about other files related to
your application
■ check or change Finder-related information stored in a volume’s catalog file
■ support stationery pads
■ use the directories generally organized within the System Folder
This chapter does not explain how to use Apple events to communicate with the Finder.
When a user opens or prints a file from the Finder, the Finder sends information to your
application so that it can open or print the file. In System 7, applications that support
high-level events receive this information through the required Apple events.
Refer to Inside Macintosh: Interapplication Communication for instructions on how
your application should respond to these required Apple events that the Finder sends
to your application: Open Application, Open Documents, Print Documents, and Quit
Application. In addition, your application can use another set of Apple events—called
Finder events—to request services from the Finder. For example, your application can ask
the Finder to perform such operations as launching another application on your behalf.
Refer to Inside Macintosh: Interapplication Communication for more details.
Finder Interface
To distinguish your product for the user, you should design your own icons for all the
files associated with your application. For each file type that your application uses or
creates, you should define large, small, black-and-white, and 4-bit and 8-bit color icons—
each in a separate resource. Your application can then use another resource, called a
bundle resource, to assign these icons to all your files of a particular type. For example,
the document icon representing Some Memo in Figure 7-1 is the icon that the SurfWriter
application assigns to all text files that it creates. When double-clicking the icon for Some
Memo, the user asks the Finder to launch the SurfWriter application, which in turn
responds by opening the document Some Memo in a window.
Stationery pads are files that a user creates to serve as templates for other documents.
Editions are special files that contain data to be shared among applications. Query
documents contain commands and data in a format appropriate for a database or other
data source. If your application supports any of these document types, you can create
icons for the Finder that distinguish the stationery pads, editions, and query documents
that users create with your application. For example, Plate 4 at the front of this book
shows customized stationery pad and edition icons used for documents created with the
SurfWriter application. (Editions are described in Inside Macintosh: Interapplication
Communication. Query documents are described in Inside Macintosh: Communications.)
You might also like your application to create customized icons for documents on the
desktop. Or, if instead of producing an application, you produce and distribute
information documents (such as database files, stationery pads, query documents, clip art
libraries, or dictionaries) to be used by other applications, you can also provide
customized icons for the Finder that distinguish your documents.
Macintosh users have access to online assistance in the form of help balloons. You can
customize the help balloon that the Finder displays for your application icon. For
example, Figure 7-2 shows a customized help balloon for the SurfWriter application icon.
Finder Interface
When appropriate, the Finder starts up your application and uses Apple events to tell
your application what documents to open or print. To perform these tasks, the Finder
relies on information you provide through resources. When the user creates or installs a
file, the File Manager (described in Inside Macintosh: Files) initially stores some of this
information in the volume’s catalog file. (The catalog file is a special file, located on a
volume, that contains information about the hierarchical organization of files and folders
on that volume.)
The Finder extracts from the catalog file the information you provide in your resources
and, for quick access to your resource information, the Finder uses that information to
build either a desktop database for all volumes over 2 MB or a Desktop file for volumes
under 2 MB. (The desktop database is a Finder-maintained database of icons, file types,
applications, version data, and comments; the Desktop file is a resource file in which the
Finder stores this information for volumes under 2 MB.)
You can even specify resources that identify your application when the user tries to open
a document and your application is missing. For example, if a user tries to open a
document named Instructions and the SurfWriter application is missing from the user’s
computer system, the Finder displays the alert box in Figure 7-3.
The System Folder is a directory that contains the software that Macintosh computers
use to start up. The System Folder includes a set of folders for storing related files. Your
application may use several of these folders for storing its files. For example, you may
want to use the Preferences folder to store preferences files that your application needs
when starting up.
Finder Interface
Finder Interface
Note
Supply a missing-application name string resource for documents
that you intend for users to open with your application; supply an
application-missing message string resource for documents (such
as preferences files) that your application uses but that users
shouldn’t open. You supply only one of these resources in a document—
never both. ◆
Your application can also make use of these resources:
■ version resources, so that users can easily find out the version of your application and,
if applicable, the version of your application’s superset of files
■ a help resource, which the Finder uses to display your customized Balloon Help
message for your application, control panel, system extension, or desk accessory icon
If you sell or distribute data in the form of a document to be used by other applications,
you can assist users by providing
■ an appropriate file type to allow users to open your document from the Finder by
dragging its icon to an application icon or by choosing the Open command from the
File menu within an application
■ the resources describing an icon family to represent your document to the user
■ a missing-application name string resource or an application-missing message string
resource, so the Finder can assist users who try to open or print your documents from
the Finder
■ version resources, so that users can easily find out the version of your document and,
if your document file is one of a larger collection of files, the version of the entire
superset of files
A catalog file exists on every volume to maintain relationships between the files and
directories on that volume. (A volume is any storage medium formatted to contain files.)
Although it’s used mostly by the File Manager, the catalog file also contains information
used by the Finder. You can always check the information in the catalog file. In particular,
you may want to check the file type or creator for a file, or you may want to check or set
one of the Finder flags for a document. When opening a document, your application
should check a Finder flag to determine if the document is a stationery pad, and, if it is,
your application should copy the document’s contents into a new document and open
the new document in an untitled window.
Your application might wish to use the folders located in the System Folder. Those you’re
most likely to want to access are Preferences, Temporary Items, and Trash. For example,
you might wish to check for the existence of a user’s configuration file in Preferences,
create a temporary file in Temporary Items, or—if your application runs out of storage
when trying to save a file—check how much storage is taken by items in the Trash
directory and report this to the user. You can use the FindFolder function to get the
path information you need to gain access to these system-related directories.
Finder Interface
In System 7, users can create Finder objects called aliases to aid them in organizing their
files. Ordinarily, when the user wants to open or print files, your application does not
need to be concerned with whether they are aliases because the Finder resolves aliases
before passing them to your application. However, if your application bypasses the
Finder (or the Standard File Package, which is described in Inside Macintosh: Files) when
manipulating documents, it should check for and resolve aliases itself by using the Alias
Manager function ResolveAliasFile.
The rest of this chapter describes in detail how to use these Finder features in your
application.
Note
There is no need to register your own resource types because they’re
usually used in only your own applications or documents. ◆
You must include in your resource file a special resource that has your application’s
signature as its resource type. By convention, the signature resource has a resource ID
number of 0. The signature resource typically contains a string that specifies the name,
version number, and release date of your application. If you do not provide specific
version information through a version resource (described in “Providing Version
Resources” beginning on page 7-31), the Finder displays the string stored in the signature
resource when the user selects your application and chooses Get Info from
the File menu.
Listing 7-1 illustrates a signature resource in Rez input format. (Rez is the resource
compiler provided with Apple’s Macintosh Programmer’s Workshop [MPW], available
from APDA.)
Note
The signature resource alone is not sufficient to establish your
application’s signature. You must also supply a bundle resource,
described in “Creating a Bundle Resource” beginning on page 7-20. ◆
Finder Interface
Whenever your application creates a document, it assigns the document a creator and
a file type. Typically, as described in “Using Finder Information in the Catalog File”
beginning on page 7-32, your application sets its signature as the document’s creator.
When a user double-clicks a document or selects it and chooses Open or Print from the
Finder’s File menu, the Finder reads the creator field of that file to find the document’s
creator. The Finder then searches for an application with a signature by that name. When
it finds that application, the Finder launches it.
If the document’s creator is your application’s signature, for example, the Finder calls the
Process Manager to start your application. The Finder then passes to your application the
information it needs to open or print the document; since the introduction of
System 7, the Finder has used Apple events to pass this information to your application.
Inside Macintosh: Interapplication Communication describes how your application processes
the required Apple events to open or print files.
As described in “Using Finder Information in the Catalog File” beginning on page 7-32,
your application typically assigns a file type to a document when it creates one. The file
type can be a type especially defined for your application, or it can be one of the existing
general types, such as those listed here.
Finder Interface
Note
Apple reserves the use of all signatures and file types whose names
contain only lowercase and nonalphabetic characters. Your signature and
the file types created especially for your application must each contain at
least one uppercase character. Since the system software
never displays signatures and file types to users, signatures and file
types can consist of character combinations that might otherwise be
incomprehensible to anyone but you. ◆
Like signatures, file types must be registered with Apple. Your application must have a
file type of 'APPL'. The creator field of your application file should contain its own
signature. Most programming environments provide a simple tool for setting the creator
field of your application file.
Your application can create documents of any type, and it can specify any application
as the creator. You could write a utility application, for example, that creates a new
document by opening one text file and appending onto it another text file. The applica-
tion would give the new document the same creator as the first original text file so
that the Finder can call on that application when the user wants to open or print the
new document.
Assign the standard file type 'TEXT' to files that consist of only text—that is, a stream of
characters with return characters at the ends of paragraphs. Most word processors allow
the user to create text-only files. A document of file type 'TEXT' can be opened or
printed by any application that accepts such file types. Your application can still assign its
own signature as the file’s creator so that the Finder can call on it to open or print the file
when appropriate.
Users can also open a document created by your application—as well as a document of a
file type supported by your application—by selecting its icon and dragging it to your
application’s icon. Because the document’s file type is stored in the catalog file and the
Finder stores a list of your application’s supported file types in the desktop database, the
Finder can determine whether to launch your application. If the document’s file type is
supported by your application, the Finder launches your application and passes it the
name of the document. (These topics are detailed in subsequent sections of this chapter.)
For example, if your application is a page-layout program, it might create documents of
its own file type while also supporting documents of 'TEXT' and 'PICT' file types. A
user can launch your application by dragging a document of any of these file types to
your application icon.
Your application also relies on file types to determine which files to let the user open
when your application is running. When your application calls the Standard File Package
to open a file, your application supplies either a list of the file types that your application
can open or a filter function for those types. The open file dialog box then displays only
files of the specified types. (See Inside Macintosh: Files for details.)
Finder Interface
Finder Interface
Before creating icon families for your files, you should begin by designing a graphic
element that all of your icon families can share and that can help the users quickly
identify the files associated with your product. Figure 7-4, for example, illustrates how
a company uses the image of a wave in all of its application icons; these icons represent
the SurfWriter text-editing application, the SurfPainter graphics application, and the
SurfDB database application. As illustrated in Plate 4 at the front of this book, the wave
element is also included in icons representing the documents, stationery pads, and
editions that users create with these applications.
Figure 7-4 Large black-and-white application icons for a company’s product line
If you do not design your own icons, the Finder uses a set of its own default application
and document icons for display. Figure 7-5 shows the Finder’s default large black-and-
white icons.
Finder Interface
Note
Desk accessories, displayed by default with the icon shown in
Figure 7-5, were designed for early versions of Macintosh system
software that did not support cooperative multitasking. Desk
accessories and applications are much more alike in their appearance
and behavior in System 7. Because there are no longer any compelling
reasons for creating desk accessories, you should generally write a
small application instead of a desk accessory if you wish to create
a small or simple program. ◆
If you don’t want the Finder to display the default icons for your application or
documents, you must at least define an icon list ('ICN#') resource for each icon.
The term icon list has become a bit of a misnomer, because you can define only two
images in the icon list resource: a 32-by-32 pixel black-and-white icon and its mask.
To define color and 16-by-16 pixel icons for a file, you create additional resources, as
described later in this section. (If you don’t define color versions of your icons, the Finder
displays the black-and-white icon defined in your icon list resource on all displays, and if
you don’t define 16-by-16 pixel icons, the Finder algorithmically reduces the 32-by-32
pixel icon to half size when needed.)
An icon list resource defines one icon. It contains two icon descriptions: the actual icon
for display and an all-black mask that shows the area covered by the icon. The Finder
uses the mask to crop the icon’s outline into whatever background color or pattern is on
the desktop. The Finder then draws the icon into this shape. Therefore, it’s important that
the mask be exactly the same shape as the icon. The mask also defines the area that users
need to click to select the icon. Therefore, it’s best not to have any holes in the mask;
otherwise, users may have trouble selecting your icon.
Figure 7-6 illustrates a black-and-white icon and its mask for an application. The area
around the pencil just underneath the wave creates a problem with this sample icon and
its mask: like a hole in a mask, it creates two small areas within the middle of the icon
that the user cannot select with the cursor.
Finder Interface
An icon list resource is defined to be an array of two items of type String[128]; each
bit in the first array represents a pixel in the 32-by-32 pixel icon, and each bit in the
second array represents a pixel in the 32-by-32 pixel mask. Typically, you use a high-level
tool such as the ResEdit application, which is available through APDA, to create your
icon list resources. Figure 7-7 shows how the icon list resource for the icon in Figure 7-6
was created using the ResEdit icon editor. When you are satisfied with the appearance of
your icons, you can use the DeRez decompiler to convert your icon list resources into Rez
input.
Listing 7-2 is a partial listing of the icon list resource’s Rez input that describes the
application icon shown in Figure 7-7; Listing 7-2 also shows partial listings for the icon
list resources used for the icons that represent the documents created by the application.
This listing and those that follow in this chapter use Rez input format to help you
understand the format of the resources and see how they work together.
Finder Interface
You can also define a small (16-by-16 pixel) version of your icon in a small icon list
resource (that is, in a resource of resource type 'ics#'). On black-and-white monitors,
the Finder displays the small icon in windows when the user chooses by Small Icon
from the View menu. On black-and-white monitors, the small icon also appears in the
Application menu after the user launches your application and in the Apple menu if
the user places your application or an alias to it in the Apple Menu Items folder. (Alias
files and the Apple Menu Items folder are described, respectively, in “Using Aliases”
beginning on page 7-39 and “Using the System Folder and Its Related Directories”
beginning on page 7-41.)
You should also define color versions of both large and small icons by using several
resource types. The resource for each icon variation has the same resource ID as the icon
list resource that defines the large black-and-white icon. For example, if the resource ID
number of your application icon’s icon list resource is 128, its small icon list resource
should have a resource ID number of 128; and the following resources should also have
resource IDs of 128: the large 4-bit color icon resource, the small 4-bit color icon resource,
the large 8-bit color icon resource, and the small 8-bit color icon resource.
Don’t define masks for the resources that define color icons. The large 4-bit color icon
resource and large 8-bit color icon resource use the black-and-white icon mask defined in
their companion icon list resource, and the small 4-bit color icon resource and small 8-bit
color icon resource use the black-and-white icon mask defined in their companion
'ics#' resource. Because of this, the outline shapes of your color icons should exactly
match those defined in your 'ICN#' and 'ics#' resources.
ResEdit 2.1 includes an icon family editor to help you easily manage the creation of these
related resources. See the ResEdit Reference for details.
See Macintosh Human Interface Guidelines for information about the most effective use of
color and shape for your icons. It is generally best that you first create the black-and-
white icons in the icon list resource and small icon list resource and then add color to
them using the resources that define color icons. Don’t alter the shapes of your icons
among these resources; otherwise, the masks defined in the icon list resource and the
small icon list resource won’t match these shapes. Choose your colors from the 36
recommended icon colors in the system palette. (If you use ResEdit 2.1, these colors
appear in a palette when you choose Apple Icon Colors from the Color menu.) Note that
you cannot specify your own color table for these resources.
For more information about color palettes, see Inside Macintosh: Imaging. Although the
Palette Manager allows you to define a palette for the system to use when it needs to
define the color environment, you should rely on the system palette colors for your icons.
Finder Interface
Users may often use the Finder when your application is not running, and the user can
switch to another application when your application is running. Relying on the system
palette gives your icons a more consistent look in the Finder regardless of what the active
application is. Also, because users can change the desktop color and pattern, your
application gives users more control over their work environment if your icons rely on
the system palette. Users can always alter your color definitions by selecting an icon and
choosing a color from the Label menu. The Finder then blends the chosen color into those
of the selected icon. To restore the original colors, users must choose None from the Label
menu.
If your application creates documents, it should also define at least two additional icon
families: one to be displayed for documents created by your application and another
to be displayed when the user creates a stationery pad from one of your applica-
tion’s documents. (“Supporting Stationery Pads” beginning on page 7-34 describes
stationery pads.)
If your application creates other variations of its documents, you can assist your users
by providing different icons for the different documents. For example, TeachText has
separate icon families to distinguish its read-only and graphics documents.
If your application supports data sharing through the Edition Manager, your application
should also define an icon family for editions. The Edition Manager (described in Inside
Macintosh: Interapplication Communication) allows users to share and automatically update
data from numerous documents and applications. For example, a user might want to
capture sales figures and totals from within a spreadsheet and then include this
information in a word-processing document that summarizes sales for a given month. If
both the spreadsheet and word-processing applications support the Edition Manager, the
user begins by selecting data within the spreadsheet document and creating a publisher.
The spreadsheet application then writes a copy of that data to a separate file, called an
edition. The edition is represented by an icon; by default, it appears as the edition icon
shown in Figure 7-5 on page 7-12. If the user opens a word-processing document and
creates a subscriber to the spreadsheet document’s edition, the word-processing
application then incorporates the desired sales figures and totals from the spreadsheet
document’s edition into the document.
If you design your application to create editions, consider creating an icon that uniquely
identifies your editions and that associates them with your application’s documents. The
file type for your edition containers should be 'edtt' (for text-oriented data), 'edtp'
(for graphics-oriented data), or 'edts' (for sound-oriented data); and the creator, of
course, should be the signature of your application.
If your Macintosh application is a database program or serves as a source for data (as
a spreadsheet program often does), you might wish to create query documents so that
other Macintosh applications can gain access to that data through the Data Access
Manager; in this case, your application should also define an icon family for its query
documents. (See Inside Macintosh: Communications for information on sharing data in
this manner.)
Plate 4 at the front of this book shows the large color icons for the various documents that
the sample SurfWriter application creates: text documents, stationery pads,
and editions.
Finder Interface
Defining icon resources is not enough to display your icons. In addition, you must follow
one of two sets of procedures:
■ If you are an application developer, you must define file reference resources and a
bundle resource for your application, as described in “Creating File Reference
Resources” beginning on page 7-18 and “Creating a Bundle Resource” beginning on
page 7-20.
■ If you are an information provider or a database developer—that is, if you provide
documents that are used by other applications—you don’t need to create file reference
resources or a bundle resource to provide document icons on Macintosh computers
running System 7. You can instead create customized icons for your documents as
described in the following section.
Note
Although an application can assign icons to it all of its documents by
associating their icons with the documents’ file types in a bundle
resource (as explained in “Creating File Reference Resources” beginning
on page 7-18 and “Creating a Bundle Resource” beginning on page 7-20),
a customized icon can represent only one specific file—that file that has
an icon list resource with a resource ID of –16455 in its resource fork. ◆
Users of System 7 are able to customize individual icons. By selecting a file and choosing
Get Info from the File menu, the user sees the information window for that file. The
user can then select the icon displayed in the upper-left corner of the information
window and use the Paste command in the Edit menu to replace it with a picture from
the Clipboard. The Finder creates a family of icons based on the user’s customized
icon, assigns a resource ID number of –16455 to each resource in the icon family, stores
these resources in the resource fork of the file that the icon represents, and sets the
hasCustomIcon bit in the file’s Finder flags field. (Finder flags are described in detail
in “File Information Record” beginning on page 7-47.)
Your application can use the same strategy to provide customized icons for the
documents that it creates. For example, a drawing application might create miniature
versions of the illustrations contained within its documents and use those for the
documents’ icons.
If you are a database developer who creates and distributes query documents that
support the Data Access Manager, you can also use this strategy to create icons that
identify your database’s query documents. Similarly, if instead of producing an
application you produce and distribute information (such as database files, stationery
pads, clip art libraries, or dictionaries) to be used by other applications, you might want
to provide icons that distinguish your documents.
Finder Interface
To make the Finder display customized icons for a document, you must create—at least—
an icon list resource with resource ID –16455 and store it in the document’s resource
fork. (To create this while your application is running, your application can call the
AddResource procedure, described in the chapter “Resource Manager” in Inside
Macintosh: More Macintosh Toolbox.) You can use the following constant in place of
the ID number:
If you provide only an icon list resource, the Finder uses a black-and-white icon on all
screen displays and automatically reduces it when a small version of the icon is required.
To create color versions and to define a small version of the icon, create an entire icon
family as described in “Creating Icons for the Finder” beginning on page 7-11.
After creating resources for icons using the kCustomIconResource constant as their
IDs, you must set the hasCustomIcon bit in the file’s Finder flags field. To prevent users
from changing these icons, set the nameLocked bit in the file’s Finder flags field. (Most
development environments provide tools for setting these bits. “Using Finder
Information in the Catalog File” beginning on page 7-32 describes how to determine
and set these Finder flags.)
Finder Interface
If you provide your own icon for the stationery pads that users create from your
application’s documents, create a file reference resource for your stationery pads.
Assign this file reference resource a file type in the following manner: use the file type
of the document upon which the stationery pad is based, but replace the first letter of
the original document’s file type with a lowercase s. As with other file reference
resources, you map this to an icon list resource in the bundle resource. (This convention
necessitates that you make the names of your documents’ file types unique in their last
three letters.)
For example, in Listing 7-3, the 'sEXT' file type assigned within the file reference
resource is used for stationery pads created from documents of the 'TEXT' file type. In
this case, when the isStationery bit (described in “Using Finder Information in the
Catalog File” beginning on page 7-32) is set on a document of file type 'TEXT', the
Finder looks in the SurfWriter application’s bundle ('BNDL') resource to determine what
icon is mapped to documents of type 'sEXT'. The Finder then displays the document
using the stationery pad icon shown in Plate 4 at the front of this book.
Finder Interface
When the user drags a document icon to your application icon, the Finder checks a list
that it maintains of your file reference resources. If the document’s file type appears in
this list, the Finder launches your application with a request to open that document.
If your application supports file types for which it doesn’t provide icons, you can still
define file reference resources for them, and then users can launch your application by
dragging these document icons to your application icon. For example, the file reference
resource with resource ID 212 in Listing 7-3 on page 7-19 is created so that the Finder
launches the SurfWriter application when users drag TeachText read-only documents to
the SurfWriter application icon. Since these documents have TeachText as their creator,
the Finder displays the icon that the TeachText application defines for them in its own
bundle resource.
By supporting the Open Documents event, you can also specify disks, folders, and a pair
of wildcard file types in your file reference resources so that users can launch your
application by dragging their icons to your application icon. As explained in Inside
Macintosh: Interapplication Communication, the Open Documents event is one of the four
required Apple events. After the Finder uses the Process Manager to launch an
application that supports high-level events, the Finder sends your application an Open
Documents event, which includes a list of alias records for objects that the application
should open.
Because alias records can specify volumes and directories as well as files, an Open
Documents event gives you the opportunity to handle cases in which users drag disk
or folder icons to your application. (Alias records are described in “Using Aliases”
beginning on page 7-39.) Create a file reference resource and specify 'disk' as the
file type to allow users to drag hard disk and floppy disk icons to your application icon.
Create a file reference resource and specify 'fold' as the file type to allow users to
drag folder icons to your application icon.
You can create a file reference resource that specifies '****' as the file type to allow
users to drag all file types—including applications, system extensions, documents, and so
on, but not including disks or folders—to your application icon. If you create three file
reference resources that specify 'disk', 'fold', and '****' as their file types and if
your application supports the Open Documents event, you effectively allow users to
launch your application by dragging any icon to your application icon. It is up to your
application to open disks, folders, or all possible file types in a manner appropriate to the
needs of the user.
Finder Interface
■ the assignment, for compatibility reasons, of local IDs to file reference resource IDs
(For consistency, these can be the same local IDs that are assigned inside the file
reference resources, but they don’t have to be—they only need to be unique for every
file reference resource.)
When the Finder first displays your application on the user’s desktop, it checks the
catalog file (described in detail in “Using Finder Information in the Catalog File”
beginning on page 7-32) to see if your application has a bundle resource. If it doesn’t,
the Finder displays the default icons shown in Figure 7-5 on page 7-12. If your
application has a bundle resource, the Finder installs the information from the bundle
resource and all its bundled resources into either the desktop database for a hard disk
or into the Desktop file for a floppy disk and uses this information to display icons for the
file types associated with your application.
You must assign local IDs to your icon list resources within your bundle resource. Make
sure that for all your file types with icons, these local IDs match the local IDs you
assigned inside their corresponding file reference resources. In the Desktop file on floppy
disks (and on hard disks running earlier versions of system software), the Finder
renumbers the resource IDs that you’ve assigned to your resources to avoid conflicts with
the resources of other applications. Therefore, the bundle resource has to rely on these
local IDs to map icon list resources to their file reference resources; that is, the bundle
resource uses the local ID you assign to an icon list resource to map it to the file reference
resource that has specified the same local ID.
For example, the file reference resource with resource ID 208 in Listing 7-3 on page 7-19
shows that the file type 'APPL' (the SurfWriter application file) is assigned a local ID
of 0. In the bundle resource shown in Listing 7-4, you see that local ID 0 is assigned to the
icon list resource with resource ID 128. This maps the icon defined by this resource (see
Figure 7-7 on page 7-14) to the SurfWriter application file. Listing 7-4 shows
the bundle resource for the icons and file reference resources defined in Listing 7-2 on
page 7-14 and in Listing 7-3 on page 7-19.
Finder Interface
In Listing 7-4, notice that you also assign local IDs to file reference resources inside the
bundle resource. This assignment is superfluous because the Finder doesn’t map these
local IDs to any other resources. The local ID assignment for file reference resources
inside the bundle resource was implemented for the earliest versions of Macintosh
system software, and it remains this way today to maintain backward compatibility. For
compatibility with the format of the bundle resource, assign local IDs to file reference
resource IDs. You may number them any way you like, except that each local ID in this
particular list must be unique.
Of all the icon resource types that make up an icon family, you need to list only the icon
list resource in the bundle resource. The Finder automatically recognizes and loads all the
other members of the icon family—provided that you have given them the same resource
IDs that you have assigned to your icon list resource.
If the user drags documents created by other applications to your application icon, and
if you have created file reference resources for these documents’ file types, the Finder
launches your application and passes it the names of the documents. You should create
file reference resources for all file types that your application supports. Do not provide
icon resources for file types created by other applications because the Finder won’t use
them, but will instead use the icon resources defined by the documents’ creators. Though
the local IDs of such a file reference resource are superfluous in the file reference resource
and at the bottom of the bundle resource, the resource formats require that you provide
local IDs in both.
For example, notice in Listing 7-3 on page 7-19 that the file reference resource with
resource ID 212 is assigned a local ID of 4, but that no icon list resource is assigned to
local ID 4 in the bundle resource in Listing 7-4 on page 7-21. This file reference resource,
which specifies a file type of 'ttro', was created in Listing 7-3 to make the Finder
launch the SurfWriter application when users drag TeachText read-only documents to the
SurfWriter application icon. No icon mapping is made for this file type in the SurfWriter
application’s bundle resource because the Finder displays the icons defined for it by the
TeachText application. The file reference resource with resource ID 212 is assigned to local
ID 14 in the bundle resource in Listing 7-4 because the format of the resource requires a
local ID for all associated file reference resources.
You alert the Finder that your application has a bundle resource by setting a bit in the
file’s Finder flags field. (Most development environments provide a simple tool for
setting the bundle bit. “Using Finder Information in the Catalog File” beginning on
page 7-32 describes Finder flags.)
Finder Interface
Figure 7-8 illustrates how the bundle resource created in Listing 7-4 uses local IDs to map
icon list resources to file reference resources. This figure illustrates two main concepts:
first, that one bundle resource ties together all the icon resources and file reference
resources for your application and all of its documents; and second, that the icon
resources and their associated file reference resources are mapped together by
local IDs.
Figure 7-8 Linking icon list resources and file reference resources in a bundle resource
Resource ID
209
File type ’TEXT’
Resource ID Local ID
129 129 1 163 1
Resource ID
210
File type ’sEXT’
Resource ID Local ID
130 130 2 164 2
Resource ID
211
File type ’edtt’
Resource ID Local ID
131 131 3 165 3
Finder Interface
In Figure 7-8, the application file’s icon list resource has resource ID 128 while its file
reference resource has resource ID 208. For easier code maintenance, you should
probably assign the same resource ID to a file’s file reference resource that you assign
to its icon list resource. However, because the Finder renumbers these whenever it
adds them to a Desktop file on floppy disks, you must map them by using local IDs. In
Figure 7-8, the application file’s icon list resource is assigned local ID 0. This maps the
icon to the file type described by the file reference resource with local ID 0—in this case,
the file reference resource with resource ID 208.
The general steps you must take to provide icons for applications and documents are
enumerated here and assume that you are using a tool, such as ResEdit, that allows you
to open and edit several resources simultaneously. (Remember that these resources must
have resource IDs of 128 or greater.)
To provide your application with icon families for itself and for its documents, follow
these steps:
1. Design a graphic element that all of your icon families can share in common and that
can help users quickly identify the files associated with your product.
2. Create an icon list ('ICN#') resource for your application file.
3. Create the other members of the icon family of the application file—resources of types
'ics#', 'icl8', 'icl4', 'ics8', and 'ics4'—and give each of these the same
resource ID as the icon list resource.
4. Create a bundle ('BNDL') resource.
5. Within the bundle resource, list the resource ID number of the application file’s icon
list resource and assign it a local ID of 0.
6. Create a file reference resource for the application file.
7. Within the file reference resource, assign the application a file type of 'APPL' and
assign it a local ID of 0.
8. Within the bundle resource, list the resource ID number of the file reference resource
for the application file and assign it a unique local ID—for example, 0 to maintain
consistency with the local ID assigned in the file reference resource.
9. Create another icon family—consisting of resources of types 'ICN#', 'ics#',
'icl8', 'icl4', 'ics8', and 'ics4'—to represent one type of document that your
application creates.
10. Within the application’s bundle resource, list the resource ID number of the
document’s icon list resource and assign it a local ID of 1.
11. Create a file reference resource for the document.
12. Within the file reference resource for the document, assign it a file type (for example,
'TEXT' or 'edtt') and assign it a local ID of 1.
13. Within the bundle resource, list the resource ID number of the file reference resource
for the document and assign it a unique local ID—for example, 1 to maintain
consistency with the local ID assigned in the file reference resource.
14. Assigning unique local IDs for every type of document your application creates, repeat
steps 9 through 13.
Finder Interface
15. If your application supports file types of other applications, define file reference
resources for them, but do not create icon resources for them.
16. Create a signature resource (as described in “Giving a Signature to Your Application
and a Creator and a File Type to Your Documents” beginning on page 7-8) with
resource ID 0.
17. Set the file’s hasBundle bit and clear the hasBeenInited bit in the file’s Finder
flags. (Finder flags are described in “Using Finder Information in the Catalog File”
beginning on page 7-32.)
18. Save and close all of the resources. (When you restart your Macintosh computer, your
application should appear with its own icon. If you later alter any of your icons, clear
the hasBeenInited bit and rebuild your desktop database by pressing Command-
Option when restarting.)
Finder Interface
signature resource as the creator of its documents. The Finder searches for the applica-
tion whose signature matches each document’s creator. If the document’s creator matches
your application’s signature, the Finder calls the Process Manager, launches your
application, and then passes your application the name of the selected document
or selected multiple documents in an Open Documents or a Print Documents event.
Your application should then open the documents in titled windows or print them, as
appropriate. (See Inside Macintosh: Files for detailed information about opening
documents; see Inside Macintosh: Imaging for detailed information about printing them.)
If the user tries to open documents created by your application and your application is
missing, the Finder displays an alert box telling the user that your application is missing.
The Finder displays the name of your application in this alert box if you provide your
documents with a missing-application name string resource, as described in “Displaying
Messages When the Finder Can’t Find Your Application” beginning on page 7-27.
Sometimes when your application is already running, the user might double-click a
document created by your application. In this case, the Finder sends your application
the Open Documents event.
The user can also request the Finder to launch your application by dragging one icon or
several icons to your application’s icon. The Finder determines whether to launch your
application by comparing the document’s file type (which is stored in the catalog file)
against the list of your application’s supported file types. The Finder compiles this list
from the file reference resources you create for your application; the Finder stores this
list in the desktop database. If the document’s file type appears in the file reference
resource list for your application, the Finder calls the Process Manager, launches your
application, and passes it the name of the selected document or selected multiple
documents in an Open Documents event. Your application should then open the
documents in titled windows.
You can also specify disks, folders, and a wildcard file type for all other files in your file
reference resources so that users can launch your application by dragging their icons to
your application icon, in which case the Finder launches your application and sends it an
Open Documents event. An Open Documents event includes a list of alias records for ob-
jects that the application should open. It is up to your application to open disks, folders,
or all possible file types in a manner appropriate to the needs of the user. (Alias records
are described in “Using Aliases” beginning on page 7-39.)
To support stationery, your application should specify the isStationeryAware
constant in its 'SIZE' resource and always check the isStationery bit of a document
passed to it by the Finder. If the isStationery bit is set for a file that the user wants to
open, your application should copy the stationery pad’s contents into a new document
and open the document in an untitled window. This is described in “Supporting
Stationery Pads” beginning on page 7-34.
In System 7, users can create aliases, which are objects that represent other files,
directories, or volumes. If the user opens an alias that represents a document created by
your application, the Finder resolves the alias for you; that is, it passes your application
the name and location of the document itself, not the alias.
Finder Interface
Before displaying the default message shown in Figure 7-9, the Finder looks in the
document for one of two special 'STR ' resources with resource ID numbers of –16396
and –16397: the missing-application name string and the application-missing message
string, respectively. If the Finder can’t find the document’s creator on any mounted
volume, it looks first for the application-missing message string resource. Provide an
application-missing message string resource if you do not intend for users to open the
file. The message should explain why the file can’t be opened. If the Finder does not find
an application-missing message string resource, it looks for the missing-application name
string resource. Provide a missing-application name string resource if you intend for us-
ers to open the file. The missing-application name string should be your application’s
name; the Finder displays it in an alert box to inform the user that your application is
needed.
Supply either the application-missing message string resource or the missing-application
name string resource; don’t supply both. Supply an application-missing message string
resource for documents (such as a preferences file) that your application uses but that
users should not open; supply a missing-application name string resource for documents
that you intend for users to open with your application.
Your missing-application name string resource (an 'STR ' resource with a resource ID
number of –16396) should contain the name of your application. Listing 7-5 on the next
page shows a missing-application name string resource for the SurfWriter application.
Finder Interface
You can store this resource in the resource fork of your application. When your applica-
tion saves a document for the first time, it should copy the missing-application name
string resource from your application’s resource fork to the resource fork of the newly
created document. Listing 7-6 shows a fragment of an application-defined function called
DoSaveAsCmd, which the application calls when the user chooses the Save As command
from the File menu. (For a description of the File Manager routines used here to create,
open, and save the resource file, see Inside Macintosh: Files.)
Listing 7-6 Storing a missing-application name string resource in the resource fork of
a document
VAR
myData: MyDocRecHnd; {handle to document record}
myErr: OSErr;
myFile: Integer; {file reference number}
Listing 7-7 shows the application-defined function DoCopyResource, which copies the
missing-application name string resource from the application’s resource fork into the
newly created document’s resource fork. (For a description of the Resource Manager
routines used here to set, open, and write the resource file, see the chapter “Resource
Manager” in Inside Macintosh: More Macintosh Toolbox.)
Finder Interface
Listing 7-7 Copying the missing-application name string resource into the resource fork of
a document
BEGIN
UseResFile(source); {set the source resource file}
myHandle := GetResource(theType, theID); {open the source}
IF myHandle <> NIL THEN
BEGIN
GetResInfo(myHandle, myID, myType, myName); {get resource }
{ name}
DetachResource(myHandle); {detach resource}
UseResFile(dest); {set the destination resource file}
AddResource(myHandle, theType, theID, myName);
IF ResError = noErr THEN
WriteResource(myHandle); {write resource data}
END;
DoCopyResource := ResError; {return result code}
END;
If a user tries to open or print one of the application’s documents when the application is
not present, the Finder specifies the application’s name in the alert box, as illustrated in
Figure 7-10.
Your application-missing message string resource (an 'STR ' resource with a
resource ID number of –16397) should explain why the user cannot open or print a
document. Use this resource for files—such as your application’s preferences file—
that are not intended to be opened or printed by the user. Register a signature (as
explained in “Giving a Signature to Your Application and a Creator and a File Type to
Your Documents” beginning on page 7-8) that is different from the signature of your
Finder Interface
application and set this signature as the creator of files that you don’t want your users to
open. This ensures that the Finder displays your message instead of launching your
application when the user double-clicks these documents.
Listing 7-8 illustrates an application-missing string resource that explains why a user
cannot open a preferences file.
Note that if your application creates documents of file type 'TEXT' or 'PICT', if
the TeachText application is available, and if your application is missing when the
user tries to open these documents from the Finder, the Finder always displays the
alert box shown in Figure 7-12. For these file types, the Finder displays this alert box even
if you provide missing-application name string resource or application-missing message
string resource.
Figure 7-12 The application-unavailable alert box for 'TEXT' and 'PICT' documents
Finder Interface
■ Prerelease revision level. This number specifies the version if the software is still
prerelease.
■ Region code. This identifies the script system for which this version of the software is
intended. See the chapter “Script Manager” in Inside Macintosh: Text for information
about the values represented by the various region codes that can be specified here.
■ Version number. This string identifies the version number of the software. When the
user opens the Views control panel, clicks the Show version box, and then chooses any
command from the View menu other than by Icon or by Small Icon, the Finder
window containing this application displays this string.
Finder Interface
■ Version message. This string identifies the version number and either a company
copyright for a file or a product name for a superset of files. When the user selects this
file and chooses the Get Info command, the Finder displays this string in the
information window as follows:
■ For a version resource with a resource ID number of 1, this string is displayed in the
version field of the information window.
■ For a version resource with a resource ID number of 2, this string is displayed
beneath the file’s name next to the file’s icon at the top of the information window.
Listing 7-9 illustrates the version resources for a graphics application and for the
document-processing system of which it is a part. Notice that the paint program is
version 1.0 while the set of files that compose the entire document-processing system
is version 2.0.
Figure 7-13 illustrates how the Finder displays the information from these resources in its
information window.
You can store version resources in any kind of file, not just an application. If your
application does not contain a version resource with a resource ID number of 1, the
Finder displays the string from your signature resource as the version information
in the information window for your application.
Finder Interface
The Finder manipulates the fields in the file information, directory information, and
extended directory information records; your application shouldn’t have to directly check
or set any of these fields.
Normally, your application sets the file type and the creator information in fields of the
file’s file information record when your application creates a new file; for example, the
File Manager function FSpCreate (described in Inside Macintosh: Files) takes a creator
and a file type as parameters. The Finder manipulates the other fields in the file
information record, which is shown here:
TYPE FInfo =
RECORD
fdType: OSType; {file type}
fdCreator: OSType; {file creator}
fdFlags: Integer; {Finder flags}
fdLocation: Point; {file's location in window}
fdFldr: Integer; {directory that contains file}
END;
After you have created a file, you can use the File Manager function FSpGetFInfo to
return the file information record, then change the fdType and fdCreator fields by
using the File Manager function FSpSetFInfo.
Finder Interface
You can check the information in this record by calling the File Manager function
FSpGetFInfo or PBGetCatInfo. In particular, you may want to check the file type
or creator for a file, or you may want to check or set one of your document’s Finder flags.
See “File Information Record” beginning on page 7-47 for a list of all the Finder flags. The
only Finder flags you might ever want to set are described here:
■ isInvisible. This flag specifies that a file is invisible from the Finder and from the
Standard File Package dialog boxes. Making a file invisible is generally not
recommended. Not even temporary files need to be invisible because the Temporary
Items folder into which they should be written is invisible. The Temporary Items
folder is described in “Using the System Folder and Its Related Directories” beginning
on page 7-41.
■ hasBundle. This flag specifies that a file has a bundle resource that associates the file
with your own icons. When the Finder displays or manipulates a file, it checks the
file’s hasBundle bit (also called the bundle bit). If that bit is not set, the Finder
displays a default icon for that file type. If the hasBundle bit is set, the Finder checks
the hasBeenInited bit. If the hasBeenInited bit is set, the Finder uses the
information in the desktop database to display that file’s icon. If the hasBeenInited
bit is not set, the Finder installs the information from the bundle resource in the
desktop database and sets the hasBeenInited bit. Most development environments
provide a simple tool for setting the bundle bit when you create your application.
■ nameLocked. This flag specifies that a file cannot be renamed from the Finder and
that the file cannot have customized icons assigned to it by users.
■ isStationery. This flag specifies that a file is a stationery pad. To support
stationery pads, your application should check this bit for every document passed to it
by either the Finder or the Standard File Package. (The File Manager functions
StandardGetFile and CustomGetFile return this flag in the sfFlags field of the
standard file reply record.) If the isStationery bit is set for a file that a user wants
to open, your application should copy the template’s contents into a new document
and open the document in an untitled window. Stationery pads are described in the
next section.
■ isShared. This flag specifies that a file is an application that multiple users on a
network can execute simultaneously.
■ hasCustomIcon. This flag specifies that a file has a customized icon. “Creating
Customized Document Icons” beginning on page 7-17 explains how users or your
application can use customized icons.
Finder Interface
When the user opens a stationery pad from the Finder, the Finder first checks your
application’s size resource to see if your application supports stationery. The 'SIZE'
resource tells the Finder and the Process Manager which features your application
supports and how much memory to allocate when it starts up your application.
Listing 7-10 illustrates a size resource.
Notice that the twelfth field, isStationeryAware, tells the Finder that this application
supports stationery pads.
If the isStationeryAware bit is not set in the size resource, the Finder creates a
new document from the template and prompts the user for a name. The Finder then
starts up your application as usual, passing it the name of the new document.
If the isStationeryAware bit is set, as shown in Listing 7-10, the Finder informs your
application that the user has opened a document and passes your application the name of
the stationery pad.
To support stationery, your application should
■ specify the isStationeryAware constant in its size resource
■ always check the isStationery bit of a document before opening it
Listing 7-11 on page 7-36 illustrates a simple function that takes a file system specification
record and returns TRUE or FALSE, indicating whether the file is a stationery document
or not.
Finder Interface
Finder Interface
icon. The Finder puts font resources in the Fonts folder, and it puts the other resources
in the System file. The user can determine which fonts are currently installed by double-
clicking the System Folder to open it and then double-clicking the Fonts folder. By
double-clicking the System file so that it opens like a folder, the user can see which other
movable resources are installed. (For a description of the new organization of the System
Folder, see “Using the System Folder and Its Related Directories” beginning on
page 7-41.)
To make one of these resources visible on the screen, assign it one of the special file types
defined by the Finder for movable resources. The following list shows the resources that
can be moved, their assigned file types, and their icons:
Large black-
Resource File type and-white icon
Font 'ffil'
Sound 'sfil'
Note
You or your users can give customized icons to these file types (as
described in “Creating Customized Document Icons” beginning on
page 7-17) as long as the files are not installed in the System file
or in a suitcase file. As soon as users install them in the System file or
in a suitcase file, the Finder displays them using the icons shown in
the previous list. Font and TrueType font movable resources retain
their custom icons when installed in the Fonts folder. ◆
The user can still store fonts (as well as desk accessories) in files that have suitcase icons,
which is how they were distributed for installation or saved by the user using the
Font/DA Mover in versions of system software that preceded System 7. A suitcase file
that holds desk accessories is of type 'DFIL', and a suitcase file that holds fonts is of
type 'FFIL'. All suitcase files have a creator of 'DMOV'.
Finder Interface
In your documentation, tell users to install fonts, sounds, or script system resource
collections by dragging their icons to the System Folder icon. A dialog box appears
asking the user to verify that the resource should be installed in either the Fonts folder
or the System file. The user clicks OK to accept the installation. The user also has the
option to click Cancel to prevent the installation.
Note
If users drag icons to the open System Folder window instead of to the
System Folder icon, the Finder copies or moves the files into the System
Folder directory instead of installing them into either the Fonts folder or
the System file. ◆
Figure 7-14 Default and customized help balloons for application icons
Listing 7-12 shows a Finder help override resource and its associated 'STR ' resource,
which are used for the customized help balloon shown in Figure 7-14.
Note
You cannot override the default help balloon that the Finder uses
for document icons. ◆
The chapter “Help Manager” in Inside Macintosh: More Macintosh Toolbox describes in
detail how to provide Balloon Help for your application icon and for other elements of
your application.
Finder Interface
Listing 7-12 Rez input for a help balloon resource for an application icon
Using Aliases 7
The Finder allows the user to create multiple icons to represent a single document or
other desktop object (such as a disk, a folder, or the Trash). One of the icons represents
the actual file; the others are aliases that point to the file. An alias is an object that
represents some other file, directory, or volume. An alias looks like the icon of its target,
but its name is displayed in a different style. The style depends on the system script; for
Roman and most other scripts, alias names are displayed in italic.
To the user, the icons of the actual file and its aliases are functionally identical. Aliases
give the user more flexibility in organizing files and offer a convenient way to store a
local copy of a large or dynamic file that resides on a file server.
Ordinarily, when the user wants to open or print files, your application does not need to
be concerned with whether they are aliases because both the Finder and the Standard File
Package resolve aliases before passing them to your application. If the user opens an alias
that represents a document created by your application, the Finder passes your
application the name and location of the document itself, not the alias. Similarly, when
the user opens an alias from within your application, the Standard File Package passes
your application the name of the target document.
If your application opens a file or a directory without going through the Finder or the
Standard File Package (if, for example, it uses preference files or dictionary files), your
application should always call the ResolveAliasFile function just before opening
the file.
As a Finder object, the alias depicts a file called the alias file, which contains a record that
points to the file, directory, or volume represented by the icon. Alias files are created and
managed by the user through the Finder.
Although your application shouldn’t create alias files or change users’ aliases, your
application can create and use its own alias records for storing identifying information
about files or directories. An alias record is a data structure that identifies a file, folder, or
volume. Whenever your application needs to store file or directory information, you can
record the location and other identifying information in an alias record. The next time
your application needs the file or directory, you can use the Alias Manager to locate it,
even if the user has renamed it, copied it, restored it from backup, or moved it. You can
Finder Interface
also use alias records to identify objects on other volumes, including AppleShare
volumes. See the chapter “Alias Manager” in Inside Macintosh: Files for details about
creating and managing information in alias records.
An alias file contains an alias record, stored as a resource of type 'alis', that points to
the target of the alias. (The alias target is the file, directory, or volume described by the
alias record.) The alias file might also contain the target object’s icon descriptions. The
Finder identifies an alias file by setting the isAlias bit in the file’s Finder flags field (see
“File Information Record” beginning on page 7-47 for a description of Finder flags).
An alias file that represents a document typically has the same type and creator as the file
it represents. However, many Finder objects—such as disks, folders, and the Trash—do
not have file types. Instead, alias files for these objects are assigned special file
types, called alias types. Here are the alias types for those objects for which users can
create aliases:
(The Extensions, Preferences, Apple Menu Items, Control Panels, Startup Items, and
PrintMonitor Documents folders are described in “Using the System Folder and Its
Related Directories” beginning on page 7-41.)
Finder Interface
When opening a file without going through the Finder or the Standard File Package,
you call ResolveAliasFile immediately before opening the file. (The
ResolveAliasFile function is described in detail on page 7-52.) In Listing 7-13,
the customized open function MyOpen ensures that the file to be opened is the target
file and then opens the data fork with the File Manager function FSpOpenDF.
Note
If users drag icons to the open System Folder window instead of to
the System Folder icon, the Finder copies or moves the files into the
System Folder directory instead of copying or moving them to the proper
subdirectories. ◆
Finder Interface
Figure 7-15 shows a user’s view of the new directory organization typically found within
the System Folder.
Additional related directories are located at the root directory. Notice the Trash window.
It shows the contents of the Trash directory, which is represented to the user by the Trash
icon. The Trash directory exists at the root level of the volume. A Macintosh sharing files
among users in a network environment maintains separate Trash subdirectories within a
shared Trash directory. That is, the server creates a separate, uniquely named Trash
subdirectory for every user who opens a volume on a Macintosh server and drags an
object to the Trash icon. All Trash subdirectories within a shared Trash directory are
invisible to users. On the desktop, the user sees only the Trash icon of the local Macintosh
computer. When the user double-clicks the Trash icon, a window reveals the names of
only those files that the user has thrown away; no distinction is made to the user as to
which computers any of these files originated on.
At the root level of the volume, the Finder also maintains a Temporary Items folder
and a Desktop Folder, both of which are invisible to the user and so don’t appear
in Figure 7-15.
Figure 7-15 illustrates the folder organization typically found on single-user systems. Of
all the related directories shown, your application is likely to use only the Preferences
folder and the Temporary Items folder. However, you cannot be certain of the location of
these or any of the other system-related directories. In the future, these system-related
directories may not be located in the System Folder or in the root directory.
You can use the FindFolder function (described on page 7-54) to get the path
information to these directories. Of these directories, the only ones you are ever likely
to need are Preferences, Temporary Items, and Trash. For example, you might wish to
check for the existence of a user’s configuration file in Preferences, create a temporary file
in Temporary Items, or—if your application runs out of storage when trying to save
a file—check how much storage is taken by items in the Trash directory and report this to
the user.
Finder Interface
Your application may freely use these two directories for storing and locating
important files:
■ Preferences, located in the System Folder, holds preferences files to record local
configuration settings. Your application can store its preferences file in this directory.
The active Finder Preferences file is always stored in the Preferences folder. Do not use
the Preferences folder to hold information that is to be shared by users on more than
one Macintosh computer on a network. Ensure that your application can always
operate even if its preferences file has been deleted.
■ Temporary Items, located at the root level of the volume, holds temporary files created
by applications. The Temporary Items folder is invisible to the user. Your application
can place its temporary files in this directory. A temporary file should exist only as
long as your application needs to keep it open. As soon as your application closes the
file, your application should remove the temporary file. You should also ensure that
you are assigning a unique name to your temporary file so that you don’t write over
another application’s file.
It’s important to bear in mind a few rules about storing your application’s files. First,
don’t store any files at the top level of the System Folder. Use the Preferences directory
or one of the other directories described in the following list.
Second, use the FindFolder function to locate or put files in the right place. Don’t
assume files are on the same volume as your application; they could be on a different
local volume, or on a remote volume on the network.
Third, don’t store any files that multiple users may need to access, such as dictionaries
and format converters, in the Preferences directory or in any of the directories located in
the System Folder. Remember that the files in the System Folder are generally accessible
only to the person who starts up from the System file in that System Folder.
There are additional directories that either the user or the Finder uses for storing and
locating important files; these directories are described here. Generally, your application
should not store files in these directories.
■ Apple Menu Items, located in the System Folder, holds the standard desk accessories
plus any other desk accessories, applications, files, folders, or aliases that the user
wants to display in the Apple menu. Only the user and the Installer should put things
into the Apple Menu Items folder.
■ Control Panels, located in the System Folder, holds control panels. The Apple Menu
Items folder holds an alias to the Control Panels folder so that the user can also reach
the control panels through the Apple menu. Only the user and the Installer should put
things into the Control Panels folder.
■ Desktop Folder, which is invisible to users, is located at the root level of the volume.
The Desktop Folder stores information about the icons that appear on the desktop area
of the screen. The user controls the contents of the Desktop Folder by arranging icons
on the screen. What appears on the screen to the user is the union of the contents of
Desktop Folders for all mounted volumes.
■ Extensions, located in the System Folder, holds extensions—that is, code that is not
part of the basic system software but that provides system-level services, such as
printer drivers and system extensions. Files of type 'INIT', previously called startup
documents, and of type 'appe', also known as background-only applications, are
Finder Interface
routed by the Finder to this folder. Files of type 'scri' (system extensions for
script systems) are also routed to this folder. Only the user and the Installer should put
files into the Extensions folder.
■ Fonts, located in the System Folder on computers using system software version 7.1 or
later, holds fonts. Only the user and the Installer should put fonts into the Fonts folder.
■ PrintMonitor Documents, located in the System Folder, holds spooled docu-
ments waiting to be printed. Only the printing software uses the PrintMonitor
Documents folder.
■ Rescued Items from volume name, located in the Trash directory, is a directory created
by the Finder at system startup, restart, or shutdown only when the Finder finds items
in the Temporary Items folder. Since applications should remove their temporary files
when they close them, the existence of a file in a Temporary Items folder indicates a
system crash. When the Finder discovers a file in the Temporary Items folder, the
Finder creates a Rescued Items from volume name directory that is named for the
volume on which the Temporary Items folder exists. For example, the Finder creates a
directory called Rescued Items from Loma Prieta when a file is discovered in the
Temporary Items folder on a volume named Loma Prieta. The Finder then moves the
temporary file to that directory so that users can examine the file in case they want to
recreate their work up to the time of the system crash. When a user empties the Trash,
all Rescued Items folders disappear. Only the Finder should put anything into
Rescued Items directories.
■ Startup Items, located in the System Folder, holds applications and desk accessories
(or their aliases) that the user wants started up every time the Finder starts up.
Only the user should put things into the Startup Items folder. Note that there is a
distinction between startup applications that users put in the Startup Items folder
and system extensions of file type 'INIT' (previously called startup documents),
which are typically installed in the Extensions folder.
■ System file, located in the System Folder, contains the basic system software plus
some system resources, such as sound and keyboard resources. The System file
behaves like a folder in this regard: although it looks like a suitcase icon, double-
clicking it opens a window that reveals movable resource files (such as sounds,
keyboard layouts, and script system resource collections) stored in the System file.
(“Distributing Fonts, Sounds, and Other Movable Resources” beginning on page 7-36
describes the resources that can be moved into the System file.) Only the user and the
Installer should put resources into the System file.
■ Trash, located at the root level of a volume, holds items that the user moves to the
Trash icon. After opening the Trash icon, the user sees the collection of all items that he
or she has moved to the Trash icon—that is, the union of all appropriate Trash
directories from all mounted volumes. A Macintosh set up to share files among users
in a network environment maintains separate Trash subdirectories for remote users
within its shared Trash directory. That is, the server creates a separate, uniquely named
Trash subdirectory for every remote user who opens a volume on a Macintosh file
server and drags an object to the Trash icon. All Trash subdirectories and the shared
Trash directory are invisible to users. The Finder empties a Trash directory (or, in the
case of a file server, a Trash subdirectory) only when the user of that directory chooses
the Empty Trash command.
Finder Interface
Although the names of the visible system-related folders vary on different international
systems, the invisible directories Temporary Items and Desktop Folder keep these names
on all systems. System software assigns unique names for invisible Trash subdirectories.
Generally, you should store application-specific files in the folder with your application,
not in any of these system-related directories. Your application may want to provide
users with a mechanism to specify a directory in which to look for auxiliary files. For
example, you could design a customized version of the open file dialog box that allows
users to specify a path to locations where files are stored. This technique may be useful
for finding files that are shared by several applications. It’s also possible to track the
location of files by using the Alias Manager. For details, see the chapter “Alias Manager”
in Inside Macintosh: Files.
When you design your application, it’s important to consider the user’s view of the tools
that you provide. In most cases you’ll want to build your application so that the user
deals with one icon that represents the entire set of abilities your application provides.
This scheme simplifies the user’s world by restricting the complexity of installing and
maintaining your product. If you provide optional tools—such as a dictionary and
thesaurus—that have their own icons, it’s a good idea to allow these tools to work from
any location in the file system rather than relying on their storage somewhere in the
System Folder.
Finder Interface
The Finder maintains a desktop database for each volume with a capacity greater than
2 MB. For most volumes, such as hard disks, the database is stored on the volume itself.
For read-only volumes—such as some compact discs—that don’t contain their own
desktop database, the Desktop Manager creates it and stores it in the System Folder of
the startup drive.
For compatibility with older versions of system software, the Finder keeps the informa-
tion for ejectable volumes with a capacity smaller than 2 MB in a resource file instead of a
database.
Data Structures 7
A catalog file exists on every volume to maintain relationships between the files and
directories on that volume. (A volume is any storage medium formatted to contain files.)
Although it’s used mostly by the File Manager, the catalog file also contains information
used by the Finder. The information for files is listed in file information records and
extended file information records; the information for directories is listed in directory
information records and extended directory information records.
Normally, your application sets the file type and the creator information in fields of a file
information record when your application creates a new file. (For a complete discussion
of the File Manager and the functions available for creating files, see Inside Macintosh:
Files.) The Finder manipulates the other fields in the file information record. You can
check the information in this record by calling the File Manager function FSpGetFInfo
or PBGetCatInfo. In particular, you may want to check the file type or creator for a file,
or you may want to check or set one of your document’s Finder flags.
The Finder manipulates the fields in the extended file information, directory informa-
tion, and extended directory information records; your application shouldn’t have to
directly check or set any of these fields. These data structures are described here for
completeness.
Finder Interface
TYPE FInfo =
RECORD
fdType: OSType; {file type}
fdCreator: OSType; {file creator}
fdFlags: Integer; {Finder flags}
fdLocation: Point; {file's location in window}
fdFldr: Integer; {window that contains file}
END;
Field descriptions
fdType File type. For a discussion of file types, see “Giving a Signature to
Your Application and a Creator and a File Type to Your Documents”
beginning on page 7-8.
fdCreator The signature of the application that created the file. For a discussion
about creators, see “Giving a Signature to Your Application and a
Creator and a File Type to Your Documents” beginning on page 7-8.
fdFlags Finder flags. There are only a few flags that your application might
ever need to set; these are described in “Using Finder Information in
the Catalog File” beginning on page 7-32. All of the Finder flags are
listed here for completeness.
Bit
Flag name number Description
isAlias 15 For a file, this bit indicates that the file
is an alias file. For directories, this bit is
reserved—in which case, set to 0.
isInvisible 14 The file or directory is invisible from the
Finder and from the Standard File Package
dialog boxes.
hasBundle 13 For a file, this bit indicates that the file
contains a bundle resource. For directories,
this bit is reserved—in which case, set to 0.
nameLocked 12 The file or directory can’t be renamed from
the Finder, and the icon cannot be changed.
isStationery 11 For a file, this bit indicates that the file is a
stationery pad. For directories, this bit is
reserved—in which case, set to 0.
hasCustomIcon 10 The file or directory contains a
customized icon.
Finder Interface
Bit
Flag name number Description
Reserved 9 Reserved; set to 0.
hasBeenInited 8 The Finder has recorded information from
the file’s bundle resource into the desktop
database and given the file or folder a
position on the desktop.
hasNoINITS 7 The file contains no 'INIT' resources; set to
0. Reserved for directories; set to 0.
isShared 6 The file is an application that can be
executed by multiple users simultaneously.
Defined only for applications; otherwise, set
to 0.
requiresSwitchLaunch 5 Unused and reserved in System 7; set to 0.
colorReserved 4 Unused and reserved in System 7; set to 0.
color 1–3 Three bits of color coding.
isOnDesk 0 Unused and reserved in System 7; set to 0.
CONST
fHasBundle = 8192; {set if file has a bundle }
{ resource}
fInvisible = 16384; {set if icon is invisible}
kIsOnDesk = $1; {unused and reserved in }
{ System 7}
kColor = $E; {three bits of color }
{ coding}
kIsShared = $40; {file can be executed by }
{ multiple users }
{ simultaneously}
kHasBeenInited
= $100; {file info is in desktop }
{ database}
kHasCustomIcon
= $400; {file or directory has a }
{ customized icon}
kIsStationery
= $800; {file is a stationery pad}
kNameLocked = $1000; {file or directory can't }
{ be renamed from Finder, }
{ and icon can't be }
{ changed}
kHasBundle = $2000; {file has bundle resource}
kIsInvisible= $4000; {file or directory is }
{ invisible from Finder & }
Finder Interface
TYPE FXInfo =
RECORD
fdIconID: Integer; {icon ID}
fdUnused: ARRAY[1..3] OF Integer;
{unused but reserved 6 bytes}
fdScript: SignedByte; {script flag and code}
fdXFlags: SignedByte; {reserved}
fdComment: Integer; {comment ID}
fdPutAway: LongInt; {home directory ID}
END;
Field descriptions
fdIconID An ID number for the file’s icon; the numbers that identify icons are
assigned by the Finder.
fdUnused Reserved.
fdScript The script system for displaying the file’s name. Ordinarily, the
Finder (and the Standard File Package) displays the names of all
desktop objects in the system script, which depends on the
region-specific configuration of the system. The high bit of the byte
in the fdScript field is set by default to 0, which causes the Finder
to display the filename in the current system script. If the high bit is
set to 1, the Finder (and the Standard File Package) displays the
filename and directory name in the script whose code is recorded in
the remaining 7 bits.
fdXFlags Reserved.
fdComment An ID number for the comment that is displayed in the information
window when the user selects a file and chooses the Get Info
command from the File menu. The numbers that identify comments
are assigned by the Finder.
fdPutAway If the user moves the file onto the desktop, the directory ID of the
folder from which the user moves the file.
Finder Interface
TYPE DInfo =
RECORD
frRect: Rect; {folder's window rectangle}
frFlags: Integer; {flags}
frLocation: Point; {folder's location in window}
frView: Integer; {folder's view}
END;
Field descriptions
frRect The rectangle for the window that the Finder displays when the user
opens the folder.
frFlags Reserved.
frLocation Location of the folder in the parent window.
frView The manner in which folders are displayed; this is set by the user
with commands from the View menu of the Finder.
TYPE DXInfo =
RECORD
frScroll: Point; {scroll position}
frOpenChain: LongInt; {directory ID chain of open }
{ folders}
frScript: SignedByte; {script flag and code}
frXFlags: SignedByte; {reserved}
frComment: Integer; {comment ID}
frPutAway: LongInt; {home directory ID}
END;
Field descriptions
frScroll Scroll position within the Finder window. The Finder does not
necessarily save this position immediately upon user action.
Finder Interface
frOpenChain Chain of directory IDs for open folders. The Finder numbers
directory IDs. The Finder does not necessarily save this information
immediately upon user action.
frScript The script system for displaying the folder’s name. Ordinarily, the
Finder (and the Standard File Package) displays the names of all
desktop objects in the current system script, which depends on the
region-specific configuration of the system. The high bit of the byte
in the fdScript field is set by default to 0, which causes the Finder
to display the folder’s name in the current system script. If the high
bit is set to 1, the Finder (and the Standard File Package) displays the
filename and directory name in the script whose code is recorded in
the remaining 7 bits. However, as of system software version 7.1, the
Window Manager and Dialog Manager do not support multiple
simultaneous scripts, so the system script is always used for
displaying filenames and directory names in dialog boxes, window
titles, and other user interface elements used by the Finder.
Therefore, until the system software’s script capability is fully
implemented, you should treat this field as reserved.
frXFlags Reserved.
frComment An ID number for the comment that is displayed in the information
window when the user selects a folder and chooses the Get Info
command from the File menu. The numbers that identify comments
are assigned by the Finder.
frPutAway If the user moves the folder onto the desktop, the directory ID of the
folder from which the user moves it.
Routines 7
This section describes the routines your application can use to resolve alias files if it
bypasses the Finder when manipulating documents and to find system-related folders
if your application needs to determine where they are located.
Finder Interface
ResolveAliasFile 7
If your application bypasses the Finder when manipulating documents, it should check
for and resolve aliases itself by using the ResolveAliasFile function.
theSpec A file system specification record for the file or directory you plan to open.
resolveAliasChains
A Boolean value. Set this parameter to TRUE if you want
ResolveAliasFile to resolve all aliases in a chain, stopping only when
it reaches the target file. Set this parameter to FALSE if you want to resolve
only one alias file, even if the target is another alias file.
targetIsFolder
A return parameter only. The ResolveAliasFile function returns TRUE
in this parameter if the file specification record in the parameter theSpec
points to a directory or a volume; otherwise, ResolveAliasFile returns
FALSE in this parameter.
wasAliased
A return parameter only. The ResolveAliasFile function returns TRUE
in this parameter if the file specification record in the parameter theSpec
points to an alias; otherwise, ResolveAliasFile returns FALSE in this
parameter.
DESCRIPTION
The ResolveAliasFile function returns in the parameter theSpec the name and
location of the target file that you initially pass in the parameter theSpec.
The ResolveAliasFile function first checks the catalog file for the file or directory
specified in the parameter theSpec to determine whether it is an alias and whether it is
a file or a directory. If the object is not an alias, ResolveAliasFile leaves theSpec
unchanged, sets the targetIsFolder parameter to TRUE for a directory or volume and
FALSE for a file, sets wasAliased to FALSE, and returns noErr. If the object is an alias,
ResolveAliasFile resolves it, places the target in the parameter theSpec, and sets
the wasAliased flag to TRUE.
When ResolveAliasFile finds the specified volume and parent directory but fails to
find the target file or directory in that location, ResolveAliasFile returns a result code
of fnfErr and fills in the parameter theSpec with a complete file system specification
record describing the target (that is, its volume reference number, parent directory ID,
and filename or folder name). The file system specification record is valid, although the
Finder Interface
object it describes does not exist. This information is intended as a “hint” that lets you
explore possible solutions to the resolution failure. You can, for example, use the file
system specification record to create a replacement for a missing file with the File
Manager function FSpCreate.
If ResolveAliasFile receives an error code while resolving an alias, it leaves the input
parameters as they are and exits, returning an error code. In addition to any of these
result codes, ResolveAliasFile can also return any Resource Manager or File
Manager errors.
SPECIAL CONSIDERATIONS
Before calling the ResolveAliasFile function, you should make sure that it is
available by using the Gestalt function with the gestaltAliasMgrAttr selector.
RESULT CODES
noErr 0 No error
nsvErr –35 Volume not found
fnfErr –43 Target not found, but volume and parent directory
found, and theSpec parameter contains a valid
file system specification record
dirNFErr –120 Parent directory not found
SEE ALSO
Finding Directories 7
You can use the FindFolder function to get the path information you need to gain
access to the system-related directories described in “Using the System Folder and Its
Related Directories” beginning on page 7-41. Those you’re most likely to want to access
are Preferences, Temporary Items, and Trash. For example, you might wish to check for
the existence of a user’s configuration file in Preferences, create a temporary file in
Temporary Items, or—if your application runs out of disk storage when trying to save a
file—check how much disk storage is taken by items in the Trash directory and report
this to the user.
Finder Interface
FindFolder 7
To get the path information to gain access to the system-related directories, use the
FindFolder function.
vRefNum The volume reference number (or the constant kOnSystemDisk for the
startup disk) of the volume on which you want to locate a directory.
folderType
A four-character folder type, or a constant that represents the type, for the
directory you want to find. The constants and the four-character folder
types they represent are listed here:
CONST
kAppleMenuFolderType
= 'amnu'; {Apple Menu Items}
kControlPanelFolderType
= 'ctrl'; {Control Panels}
kDesktopFolderType = 'desk'; {Desktop Folder}
kExtensionFolderType
= 'extn'; {Extensions}
kFontsFolderType = 'font'; {Fonts folder}
kPreferencesFolderType
= 'pref'; {Preferences}
kPrintMonitorDocsFolderType
= 'prnt'; {PrintMonitor }
{ Documents}
kStartupFolderType = 'strt'; {Startup Items}
kSystemFolderType = 'macs'; {System Folder}
kTemporaryFolderType
= 'temp'; {Temporary Items}
kTrashFolderType = 'trsh'; {single-user Trash}
kWhereToEmptyTrashFolderType
= 'empt'; {shared Trash on net}
createFolder
Pass the constant kCreateFolder in this parameter to create a directory
if it does not already exist; otherwise, pass the constant
kDontCreateFolder.
Finder Interface
foundVRefNum
The volume reference number, returned by FindFolder, for the volume
containing the directory you specify in the folderType parameter.
foundDirID
The directory ID number, returned by FindFolder, for the directory you
specify in the folderType parameter.
DESCRIPTION
For the folder type on the particular volume (specified, respectively, in the folderType
and vRefNum parameters), the FindFolder function returns the directory’s volume
reference number in the foundVRefNum parameter and its directory ID in the
foundDirID parameter.
The specified folder used for a given volume might be located on a different volume in
future versions of system software; therefore, do not assume the volume that you
specify in vRefNum and the volume returned in foundVRefNum will be the same.
Specify a volume reference number (or the constant kOnSystemDisk for the startup
disk) in the vRefNum parameter.
Specify a four-character folder type—or the constant that represents it—in the
folderType parameter. Use the kTrashFolderType constant to locate the current
user’s Trash directory for a given volume—even one located on a file server. On a file
server, you can use the kWhereToEmptyTrashFolderType constant to locate the
parent directory of all logged-on users’ Trash subdirectories.
Use the constant kCreateFolder in the createFolder parameter to tell FindFolder
to create a directory if it does not already exist; otherwise, use the constant
kDontCreateFolder. Directories inside the System Folder are created only if the
System Folder directory exists. The FindFolder function will not create a System Folder
directory even if you specify the kCreateFolder constant in the createFolder
parameter.
The FindFolder function returns a nonzero result code if the folder isn’t found,
and it can also return other file system errors reported by the File Manager or
Memory Manager.
SPECIAL CONSIDERATIONS
The Finder identifies the subdirectories of the System Folder, and their folder types, in a
resource of type 'fld#' located in the System file. Do not modify or rely on the contents
of the 'fld#' resource in the System file; use only the FindFolder function to find the
appropriate directories.
To determine the availability of the FindFolder function, use the Gestalt function
with the Gestalt selector gestaltFindFolderAttr. Test the bit field indicated by the
gestaltFindFolderPresent constant in the response parameter. If the bit is set, then
the FindFolder function is present.
Finder Interface
RESULT CODES
noErr 0 No error
fnfErr –43 Type not found in 'fld#' resource, or disk doesn’t have
System Folder support or System Folder in volume
header, or disk does not have desktop database support
for Desktop Folder—in all cases, folder not found
dupFNErr –48 File found instead of folder
SEE ALSO
The system-related directories located by the FindFolder function are described in
“Using the System Folder and Its Related Directories” beginning on page 7-41.
Resources 7
This section describes the resources you supply for your files so that the Finder can use
your files and relay information about them to your users. These resources are
■ the signature resource—defined using a string ('STR ') resource—which the Finder
uses to identify and start up your application when a user double-clicks documents
created by your application
■ the set of resources (icon list resource, small icon list resource, large 4-bit color icon
resource, small 4-bit color icon resource, large 8-bit color icon resource, and small 8-bit
color icon resource) that visually represent your application and any documents it
creates, and two related resources, the icon ('ICON') resource and the color icon
('cicn') resource
■ the file reference ('FREF') resource, which links icons with the files types they
represent and which allows users to launch your application by dragging document
icons to your application icon
■ a bundle ('BNDL') resource, which groups together your application’s signature, icon
list resource, and file reference resources
■ a missing-application name string—that is, a string ('STR ') resource—for your
application’s documents in order to display the name of your application if the user
tries to open or print a document created by your application when your application is
missing
■ an application-missing message string—that is, a string ('STR ') resource—in your
application’s documents in order to explain why the user can’t open or print certain
documents used by your application
■ the version ('vers') resource, so that users can easily find out the version of a file
and, if applicable, the version of the superset of files to which the single file belongs
For information about using the 'SIZE' resource to support stationery pads, see
“Supporting Stationery Pads” beginning on page 7-34.
This section describes the structures of these resources after they are compiled by the Rez
resource compiler, available from APDA. If you are interested in creating the Rez input
files for these resources, see instead “Using the Finder Interface” beginning on page 7-6
for detailed information.
Finder Interface
Figure 7-16 Structure of a signature resource compiled as a string ('STR ') resource
Finder Interface
An icon list resource is defined to be an array of two items of type String[128]; each
bit in the first array represents a pixel in the 32-by-32 pixel icon, and each bit in the
second array represents a pixel in the 32-by-32 pixel mask. You can use a high-level tool
such as the ResEdit application, which is available through APDA, to create icon list
resources. You can then use the DeRez decompiler to convert your icon list resources into
Rez input when necessary. See “Creating Icons for the Finder” beginning on page 7-11 for
additional information about creating icon list resources and other resources for
representing files to users.
An icon list resource defines one icon, which the Finder uses to display the file it
represents. If you examine the compiled version of an icon list resource, as represented in
Figure 7-17, you find that it contains the following elements:
■ The 32-by-32 pixel black-and-white icon.
■ The 32-by-32 pixel black icon mask, which shows the area covered by the black-and-
white icon and any 32-by-32 pixel color versions of the icon. The Finder uses the mask
to crop the icon’s outline into whatever background color or pattern is on the desktop.
The Finder then draws the black-and-white icon specified in this resource—or the
color icons specified in large 4-bit color icon resources or large 8-bit color icon
resources—into this shape.
To create 16-by-16 pixel and color versions of the icon defined in an icon list resource
(thereby supplying an entire icon family), your application must also create the following
resources: a small icon list resource, a large 4-bit color icon resource, a small 4-bit color
icon resource, a large 8-bit color icon resource, and a small 8-bit color icon resource. Their
compiled formats are described in the next several sections; guidelines for creating them
are provided in “Creating Icons for the Finder” beginning on page 7-11.
Finder Interface
When the user chooses by Small Icon from the View menu, the Finder displays the
small black-and-white icon specified in this resource in windows if either the user has a
black-and-white monitor or the application has not defined any resources for color icons;
otherwise, a color version of the icon is displayed. Similarly, the small black-and-white
icon or its color version appears in the Application menu after the user launches the
application and in the Apple menu if the user places the application or an alias to it in the
Apple Menu Items folder.
A small icon list resource is defined to be an array of two items of type String[32];
each bit in the first array represents a pixel in the 16-by-16 pixel icon, and each bit in the
second array represents a pixel in the 16-by-16 pixel mask. You can use a high-level tool
such as the ResEdit application to create small icon list resources. You can then use the
DeRez decompiler to convert your small icon list resources into Rez input when
necessary. See “Creating Icons for the Finder” beginning on page 7-11 for information
about creating small icon list resources and other resources for representing files to users.
A small icon list resource defines one icon, which the Finder uses to display the file it
represents. If you examine the compiled version of a small icon list resource, as
represented in Figure 7-18, you find that it contains the following elements:
■ The 16-by-16 pixel black-and-white icon for display on the desktop.
■ The 16-by-16 pixel black icon mask, which shows the area covered by the icon. The
Finder uses the mask to crop the icon’s outline into whatever background color or
pattern is on the desktop. The Finder then draws the black-and-white icon specified
in this resource—or the color icons specified in the small 4-bit color icon resource or
the small 8-bit color icon resource—into this shape.
The format for the compiled icon list resource is described on page 7-57; the format
for the compiled small 4-bit color icon resource is described on page 7-60; and the
format for the compiled small 8-bit color icon resource is described on page 7-62.
Finder Interface
resource ID as the icon list resource that represents the file that the large 4-bit color icon
resource also represents.
When the user chooses by Icon from the View menu, the Finder displays the large 4-bit
color icon specified in this resource in windows if the user has a monitor displaying
4 bits of color data per pixel. Similarly, the large 4-bit color icon appears in the
Application menu after the user launches the application and in the Apple menu if the
user places the application or an alias to it in the Apple Menu Items folder.
A large 4-bit color icon resource is defined to be of type String[512]; every 4 bits in the
string represent a pixel in the 32-by-32 pixel icon. You can use a high-level tool such as
the ResEdit application to create large 4-bit color icon resources. You can then use the
DeRez decompiler to convert your large 4-bit color icon resources into Rez input when
necessary. See “Creating Icons for the Finder” beginning on page 7-11 for information
about creating resources for visually representing files.
A large 4-bit color icon resource defines one icon, which the Finder uses to display the file
it represents. If you examine the compiled version of a large 4-bit color icon resource, as
represented in Figure 7-18, you find that it contains only the 32-by-32 pixel 4-bit color
icon for display by the Finder. This resource does not specify a mask for the icon; instead,
the Finder uses the mask specified for the icon list resource with the same resource ID
number as this resource.
Figure 7-19 Structure of a compiled large 4-bit color icon ('icl4') resource
The format for the compiled icon list resource is described on page 7-57.
Finder Interface
A small 4-bit color icon resource is defined to be of type String[128]; every 4 bits in
the string represent a pixel in the 16-by-16 pixel icon. You can use a high-level tool such
as the ResEdit application to create small 4-bit color icon resources. You can then use the
DeRez decompiler to convert your small 4-bit color icon resources into Rez input when
necessary. See “Creating Icons for the Finder” beginning on page 7-11 for information
about creating resources for representing files to users.
A small 4-bit color icon resource defines one icon, which the Finder uses to display the
file it represents. If you examine the compiled version of a small 4-bit color icon resource,
as represented in Figure 7-18, you find that it contains only the 16-by-16 pixel 4-bit color
icon for display by the Finder. This resource does not specify a mask for the icon; instead,
the Finder uses the mask specified for the small icon list resource with the same resource
ID number as this resource.
Figure 7-20 Structure of a compiled small 4-bit color icon ('ics4') resource
The format for the compiled icon list resource is described on page 7-57. The format for
the compiled small icon list resource is described on page 7-58.
Finder Interface
A large 8-bit color icon resource defines one icon, which the Finder uses to display the file
it represents. If you examine the compiled version of a large 8-bit color icon resource, as
represented in Figure 7-21, you find that it contains only the 32-by-32 pixel 8-bit color
icon for display by the Finder. This resource does not specify a mask for the icon; instead,
the Finder uses the mask specified for the icon list resource with the same resource ID
number as this resource.
The format for the compiled icon list resource is described on page 7-57.
Figure 7-21 Structure of a compiled large 8-bit color icon ('icl8') resource
Finder Interface
Figure 7-22 Structure of a compiled small 8-bit color icon ('ics8') resource
The format for the compiled icon list resource is described on page 7-57. The format for
the compiled small icon list resource is described on page 7-58.
Finder Interface
Finder Interface
This section describes the structure of a file reference resource after it is compiled by the
Rez resource compiler. The format of a Rez input file for a file reference resource differs
from its compiled output form. If you are concerned only with creating a file reference
resource, see “Creating File Reference Resources” beginning on page 7-18.
If you examine a compiled version of a file reference resource, as illustrated in
Figure 7-24, you find that it contains the following elements:
■ File type. This is the four-character code that identifies the type of file represented by
this resource. File types are described in “Giving a Signature to Your Application and a
Creator and a File Type to Your Documents” beginning on page 7-8.
■ Local ID. The Finder uses this number to map the file type specified in this resource
to an icon list resource that is assigned the same local ID in the bundle resource. The
icon list resource is described on page 7-57; the bundle resource is described in the
next section.
■ Empty string. This element should always contain an empty Pascal string.
File type 2
Empty string 1
Finder Interface
Application signature 4
Finder Interface
Figure 7-26 Mapping local IDs to icon list resource IDs in a bundle resource
■ Local ID–to–icon list resource ID mapping pairs for the rest of the icons representing
file types for an application.
Figure 7-27 illustrates the remainder of a bundle resource, which assigns local IDs to
file reference resource IDs. This assignment is superfluous because the Finder doesn’t
map these local IDs to any other resources. This ID assignment was implemented for
the earliest versions of Macintosh system software, and it remains this way today to
maintain backward compatibility.
Figure 7-27 Structure of superfluous local ID mapping for file reference resources in a
bundle resource
Finder Interface
If you examine the compiled portion of the remainder of a bundle resource, you find that
it contains the following elements:
■ Resource type. This element should always specify the resource type 'FREF' (that is, a
file reference resource).
■ Count of all the file reference resources representing file types for an application.
This is the number of local ID–to–file reference resource mapping pairs in the rest of
this resource.
■ Local ID for a file reference resource. The local ID can be any integer so long as no
other file reference resource is given that same local ID within this resource.
■ Resource ID for the file reference resource assigned a local ID in the preceding field.
■ Local ID–to–file reference resource ID mapping pairs for the rest of the file reference
resources that represent file types with application-supplied icons.
Finder Interface
'STR ', it must have a resource ID number of –16397, and it must be made purgeable.
The string resource should contain a message that explains why the user cannot open or
print the document, as explained in “Displaying Messages When the Finder Can’t Find
Your Application” beginning on page 7-27.
If you examine a compiled application-missing message string, as illustrated in
Figure 7-29, you find that it consists entirely of a Pascal string that explains why the
user cannot open the document. The Finder displays this string in an alert box if the user
tries to open or print a document that is given a special creator that is not used as a
signature by any application file. (File creators and application signatures are explained
in “Giving a Signature to Your Application and a Creator and a File Type to Your
Documents” beginning on page 7-8.)
Finder Interface
■ Development stage. The values that can appear in this field, as well as the constants
that can be used to specify them in a Rez input file, are the following:
■ Prerelease revision level. This number specifies the version if the software is
still prerelease.
■ Region code. This identifies the script system for which this version of the software is
intended. See the chapter “Script Manager” in Inside Macintosh: Text for information
about the values represented by the various region codes that can be specified here.
■ Version number. This Pascal string identifies the version number of the software.
When the user opens the Views control panel, clicks the Show version box, and then
chooses any command from the View menu other than by Icon or by Small Icon, the
Finder window containing this application displays this string.
■ Version message. This Pascal string identifies the version number and either a
company copyright for a file or a product name for a superset of files. When the
user selects this file and chooses the Get Info command, the Finder displays this
string in the information window as follows:
■ For a version resource with a resource ID number of 1, this string is displayed in the
version field of the information window.
■ For a version resource with a resource ID number of 2, this string is displayed
beneath the file’s name next to the file’s icon at the top of the information window.
Finder Interface
Pascal Summary 7
Constants 7
Finder Interface
{for FindFolder}
kOnSystemDisk = $8000; {use vRefNum for the }
{ boot disk}
kCreateFolder = TRUE; {create folder if it }
{ doesn't exist}
kDontCreateFolder = FALSE; {don't create folder}
Finder Interface
Data Types 7
FXInfo =
RECORD
fdIconID: Integer; {icon ID}
fdUnused: ARRAY[1..3] OF Integer;
{unused but reserved 6 bytes}
fdScript: SignedByte; {script flag and code}
fdXFlags: SignedByte; {reserved}
fdComment: Integer; {comment ID}
fdPutAway: LongInt; {home directory ID}
END;
DInfo =
RECORD
frRect: Rect; {folder's window rectangle}
frFlags: Integer; {flags}
frLocation: Point; {folder's location in window}
frView: Integer; {folder's view}
END;
DXInfo =
RECORD
frScroll: Point; {scroll position}
frOpenChain: LongInt; {dir ID chain of open folders}
frScript: SignedByte; {script flag and code}
frXFlags: SignedByte; {reserved}
frComment: Integer; {comment ID}
frPutAway: LongInt; {directory ID}
END;
Finder Interface
Routines 7
Finding Directories
FUNCTION FindFolder (vRefNum: Integer; folderType: OSType;
createFolder: Boolean;
VAR foundVRefNum: Integer;
VAR foundDirID: LongInt): OSErr;
C Summary 7
Constants 7
enum {
/*Gestalt selectors*/
#define gestaltFindFolderAttr 'fold' /*selector for FindFolder*/
/*Finder flags*/
#define kIsOnDesk 0x1 /*unused and reserved in */
/* System 7*/
#define kColor 0xE /*3 bits of color coding*/
#define kIsShared 0x40 /*file can be executed by */
/* multiple users */
/* simultaneously*/
#define kHasBeenInited 0x100 /*file info is in desktop */
/* database*/
#define kHasCustomIcon 0x400 /*file or directory has a */
/* customized icon*/
Finder Interface
enum {
/*for Finder flags*/
fHasBundle = 8192, /*set if file has 'BNDL'*/
fInvisible = 16384 /*set if icon is invisible*/
};
enum {
/*for FindFolder*/
kOnSystemDisk = 0x8000 /*use vRefNum for the */
/* boot disk*/
#define kCreateFolder true /*create folder if it */
/* doesn't exist*/
#define kDontCreateFolder false /*don't create folder*/
Finder Interface
Data Types 7
struct FXInfo {
short fdIconID; /*icon ID*/
short fdUnused[3]; /*unused but reserved 6 bytes*/
char fdScript; /*script flag and code*/
char fdXFlags; /*reserved*/
short fdComment; /*comment ID*/
long fdPutAway; /*home directory ID*/
};
Finder Interface
struct DInfo {
Rect frRect; /*folder's window rectangle*/
unsigned short frFlags; /*flags*/
Point frLocation; /*folder's location in window*/
short frView; /*folder's view*/
};
struct DXInfo {
Point frScroll; /*scroll position*/
long frOpenChain; /*directory ID chain of open folders*/
char frScript; /*script flag and code*/
char frXFlags; /*reserved*/
short frComment; /*comment ID*/
long frPutAway; /*directory ID*/
};
Routines 7
Finding Directories
pascal OSErr FindFolder (short vRefNum, OSType folderType,
Boolean createFolder, short *foundVRefNum,
long *foundDirID);
Assembly-Language Summary 7
Data Structures 7
Finder Interface
Result Codes 7
noErr 0 No error
nsvErr –35 Volume not found
fnfErr –43 For FindFolder: Type not found in 'fld#' resource, or disk doesn’t have
System Folder support or System Folder in volume header, or disk does not
have desktop database support for Desktop Folder—in all cases, folder not
found
For ResolveAliasFile: Target not found, but volume and parent
directory found and theSpec parameter contains a valid file system
specification record
dupFNErr –48 File found instead of folder
dirNFErr –120 Parent directory not found
action procedure A procedure that performs an alert resource A resource (of type 'ALRT') that
action in response to the user holding the mouse specifies alert sounds, a display rectangle, and an
button down while the cursor is in a control. item list for an alert box.
activate event A type of event that indicates alert sound An audible signal from the
that a window is becoming active or inactive. Macintosh speaker that warns the user of an
Each activate event specifies the window unusual or a potentially undesirable situation
to be changed and the direction of the change occurring within an application. An alert sound
(that is, whether it’s becoming active or becoming may or may not be accompanied by an alert box.
inactive).
alias An object that represents another file,
active control A control in which the Control directory, or volume.
Manager responds to a user’s mouse actions by
alias file A file that contains a record that points
providing visual feedback.
to another file, directory, or volume. An alias file
active window The frontmost window on the is displayed by the Finder as an alias.
desktop, the one in which the user is currently
alias record A data structure created by the
working. The active window is designated by
Alias Manager to identify a file, directory,
racing stripes in the title bar, active controls, and
or volume.
highlighted selections.
alias target The file, directory, or volume
A5 world An area of memory in an applica-
described by the alias record.
tion’s partition that contains the QuickDraw
gloabl variables, the application global variables, Apple event A high-level event whose structure
the application parameters, and the jump table— and interpretation are determined by the Apple
all of which are accessed through the A5 register. Event Interprocess Messaging Protocol.
alert An alert sound, an alert box, or both. Apple Menu Items folder A directory located
Alerts warn the user of an unusual or a in the System Folder for storing desk accessories,
potentially undesirable situation occurring within applications, folders, and aliases that the
an application. See also alert box and user wants to display in and access from the
alert sound. Apple menu.
alert box A window that an application displays application heap An area of memory in
on the screen to warn the user or to report an the application heap zone in which memory is
error to the user. An alert box typically consists of dynamically allocated and released on demand.
text describing the situation and buttons that The heap contains the application’s 'CODE'
require the user to acknowledge or rectify the segment 1, data structures, resource map, and
problem. An alert box may or may not be other code segments as needed.
accompanied by an alert sound. See also caution
application partition A partition of memory
alert, note alert, and stop alert.
reserved for use by an application. The applica-
alert color table resource A resource (of type tion partition consists of free space, the
'actb') that lets an application display an alert application heap, the application’s stack, and
box using colors other than the system’s default the application’s A5 world.
window colors.
GL-1
G L O S S A RY
auto-key event An event indicating that a (indicated by an X inside the box) or off. When
key is still down after a certain amount of time the user clicks a checkbox, the application
has elapsed. reverses its setting. See also radio button.
auxiliary window record A data structure that close box The small white box on the left side of
the Window Manager uses to tie together a list of the title bar of an active window. Clicking it closes
windows and their corresponding window color the window.
information tables.
close region The area occupied by a window’s
background process A process that isn’t close box. See also close box.
currently interacting with the user. Compare
Command-key equivalent Refers specifically to
foreground process.
a keyboard equivalent that the user invokes by
bundle bit A flag in a file’s Finder information holding down the Command key and pressing
record that informs the Finder that a bundle another key (other than a modifier key) at the
('BNDL') resource exists for the file. A file’s same time.
Finder information record is stored in a volume’s
content region The part of a window in which
catalog file. The Finder uses the information
the contents of a document, the size box, and
in the bundle resource to associate icons with
the window controls (including the scroll bars)
the file.
are displayed.
button A control that appears on the screen as a
context The information about a process
rounded rectangle with a title centered inside.
maintained by the Process Manager. This
When the user clicks a button, the application
information includes the current state of the
performs the action described by the button’s
process, the address and size of its partition, its
title. Button actions are usually performed
type, its creator, a copy of its low-memory global
instantaneously. Examples include completing
variables, information about its 'SIZE' resource,
operations defined by a dialog box and
and a process serial number.
acknowledging an error message in an alert box.
control An onscreen object that the user can
catalog file A special file, located on a volume,
manipulate with the mouse. By manipulating a
that contains information about the hierarchical
control, the user can take an immediate action or
organization of files and folders on that volume.
change a setting to modify a future action.
caution alert An alert box that warns the user of
control color table In an item color table
an operation that may have undesirable results if
resource, a specification for the colors used to
it’s allowed to continue. A caution alert gives the
draw the various parts of a control.
user the choice of continuing the action (by
clicking the OK button) or stopping the action (by control definition function A function that
clicking the Cancel button). A caution alert is defines the appearance and behavior of a control.
identified by an icon bearing an exclamation A control definition function, for example, draws
point in the upper-left corner of the alert box. See the control. See also standard control definition
also note alert and stop alert. functions.
character code A value that represents a control definition ID A number passed to
particular character. The character code that is control-creation routines to indicate the type of
generated depends on the virtual key code and control. It consists of the control definition
the state of the modifier keys. In the Roman script function’s resource ID and a variation code.
system, character codes are specified in
control list A series of entries pointing to the
the extended version of ASCII (the American
descriptions of the controls associated with
Standard Code for Information Interchange).
the window.
checkbox A control that appears onscreen as a
small square with an accompanying title. A
checkbox displays one of two settings: on
GL-2
G L O S S A RY
Control Manager A collection of routines that the default button in dialog boxes. The default
applications use to create and manipulate button should invoke the preferred action, which,
controls, especially those in windows. whenever possible, should be a “safe” action—
that is, one that doesn’t cause loss of data.
Control Panels folder A directory located in the
System Folder for storing control panels, which desktop The working environment displayed
allow users to modify the work environment of on the Macintosh computer: the gray background
their Macintosh computer. area on the screen.
control record A data structure of type desktop database A Finder-maintained
ControlRecord, which the Control Manager database of icons, file types, applications, version
uses to store all the information it needs for its data, and comments for all volumes over 2 MB.
operations on a control. Compare Desktop file.
current menu list A data structure that contains Desktop file A resource file in which the Finder
handles to the menu records of all menus in the stores icons, file types, applications, version data,
current menu bar and the menu records of any and comments for all volumes less than 2 MB.
submenus or pop-up menus that an application Compare desktop database.
inserts into the list.
Desktop Folder A directory, located at the root
current process The process that is currently level of each volume, used by the Finder for
executing and whose A5 world is valid; this storing information about the icons that appear
process can be in the background or the on the desktop area of the screen. The Desktop
foreground. Folder is invisible to the user. What the user sees
onscreen is the union of the contents of Desktop
cursor Any 256-bit image, defined by a 16-by-16
Folders for all mounted volumes.
bit square. The mouse driver displays the current
cursor and maps the movement dial A control, similar to a scroll bar, that
of the mouse to relative locations on the screen graphically represents the ranges of values that
as the user moves the mouse. a user can set or that simply displays the value,
magnitude, or position of something, typically in
custom alert box An alert box whose upper-left
some pseudo-analog form.
corner contains blank space or displays an icon
other than those used by caution alerts, stop dialog box A window that an application
alerts, or note alerts. displays on the screen to solicit information
from the user before the application carries
customized icon An icon created by the user or
out the user’s command. See also modal dialog
by an application and stored with a resource ID of
box, modeless dialog box, and movable modal
–16455 in the resource fork of a file. A file with a
dialog box.
customized icon has the hasCustomIcon bit set
in its Finder flags field. dialog color table resource A resource (of type
'dctb') that lets an application display a dialog
data fork The part of a file that contains data
box using colors other than the system’s default
accessed using the File Manager. The data usually
window colors.
corresponds to data entered by the user; the
application creating a file can store and interpret Dialog Manager A collection of routines that
the data in the data fork in whatever manner is applications use to implement alerts and dialog
appropriate. boxes.
default button In an alert box or a dialog box, dialog record A data structure of type
the button whose action is invoked when the user DialogRecord that the Dialog Manager
presses the Return key or the Enter key. The uses to create dialog boxes and alerts.
Dialog Manager automatically draws a bold
dialog resource A resource (of type 'DLOG')
outline around the default button in alert boxes;
that specifies the window type, display rectangle,
applications should draw a bold outline around
and item list for a dialog box.
GL-3
G L O S S A RY
disabled item In an alert box or a dialog box, an notice of changes in the processing status of
item for which the Dialog Manager does the application, and to communicate with
not report user events. An example of a disabled other applications.
item is static text, which typically does not
event mask An integer with one bit position for
respond to clicks.
each event type. You specify an event mask as a
disk-inserted event An event indicating that a parameter to Event Manager routines to specify
disk has been inserted into a disk drive. the event types you want your application to
receive, thereby disabling (or “masking out”) the
display rectangle A rectangle that defines the
events you are not interested in receiving.
size and location of an item in an alert box or a
dialog box. The display rectangle is specified in event record A data structure of type
an item list and uses coordinates local to the alert EventRecord that your application uses when
box or dialog box. retrieving information about an event. The Event
Manager returns, in an event record, information
divider A gray line used in menus to separate
about what type of event occurred (a mouse click
groups of menu items.
or keypress, for example) and additional informa-
document window A window in which the user tion associated with the event.
enters text, draws graphics, or otherwise enters or
Extensions folder A directory located in the
manipulates data.
System Folder for storing system extension files
drag region The area occupied by a window’s such as printer and network drivers and files of
title bar, except for the close box and zoom box. types 'INIT', 'scri', and 'appe'.
The user can move a window on the desktop by
file A named, ordered sequence of bytes stored
dragging the drag region.
on a Macintosh volume, divided into a data fork
edition The data written to an edition container and a resource fork.
by a publisher. A publisher writes data to an
Finder An application that works with the
edition whenever a user saves a document that
system software to keep track of files and manage
contains a publisher, and subscribers in other
the user’s desktop display.
documents may read the data from the edition
whenever it is updated. Fonts folder A directory located in the System
Folder for storing fonts.
enabled item In an alert box or a dialog box, an
item for which the Dialog Manager reports user foreground process The process currently
events. For example, the Dialog Manager reports interacting with the user; it appears to the user as
clicks in an enabled OK button. the active application. The foreground process
displays its menu bar, and its windows are in
event The means by which the Event Manager
front of the windows of other applications.
communicates information about user actions,
Compare background process.
changes in the processing status of the
application, and other occurrences that require a frame The part of a window drawn
response from the application. automatically by the Window Manager, namely,
the title bar, including the close box and zoom
event filter function An application-defined
box, and the window’s outline.
routine that supplements the Dialog Manager’s
ability to handle events—for example, an event global coordinate system The coordinate
filter function can test for disk-inserted events system that represents all potential QuickDraw
and can allow background applications to receive drawing space. The origin of the global
update events. coordinate system—that is, the point (0,0)—
is at the upper-left corner of the main screen.
Event Manager The collection of routines that
Compare local coordinate system.
an application can use to receive information
about actions performed by the user, to receive
GL-4
G L O S S A RY
graphics port A complete, individual drawing (16-by-16 pixel) icons, each with a mask, and each
environment with an independent coordinate available in three different versions of color: black
system. Each window is drawn in a graphics port. and white, 4 bits of color data per pixel, and 8 bits
of color data per pixel.
gray area The area within a scroll bar, excluding
the scroll arrows and the scroll box. When the inactive control A control that has no meaning
user clicks the gray area of a scroll bar, the or effect in the current context—for example, the
application moves the displayed area of the scroll bars in an empty window. The Control
document by an entire window less one line (or Manager dims inactive controls or otherwise
column, row, or character). visually indicates their inactive state.
gray region A region that represents all inactive window A window in which the user
available desktop area—that is, a collection is not working.
of rounded-corner rectangles representing
indicator A moving part in a dial or slider
the display areas of all monitors available to
control. A user moves an indicator to set a value,
a computer.
and an application moves it to indicate the
grow image An outline of a window’s new current setting of the control. In a scroll bar, the
frame, drawn on the screen while the user is scroll box is the indicator.
resizing the window with the size box.
item color table resource A resource (of type
help balloon A rounded-rectangle window that 'ictb') that an application can use to display an
contains explanatory information for the user. alert box or a dialog box with items using a
With tips pointing at the objects they annotate, typeface, font style, font size, or colors other
help balloons look like bubbles used for dialog in than the system’s default font and colors. (For
comic strips. Help balloons are turned on by the an application to use a nonstandard typeface, font
user from the Help menu; when Balloon Help style, or font size, the user must have a
assistance is on, a help balloon appears whenever color monitor.)
the user moves the cursor over an area that is
item list A resource (of type 'DITL') that
associated with it.
specifies the items—such as buttons and static
hierarchical menu A menu to which a submenu text—to display in an alert box or a dialog box.
is attached.
item number An integer that identifies an item
high-level event An event sent from one in either a menu or a dialog box. Menu items
application to another requesting transfer of are assigned item numbers starting with 1 for
information or performance of some action. the first menu item in the menu, 2 for the second
menu item in the menu, and so on, up to the
high-level event queue A separate queue that
number of the last menu item in the menu.
the Event Manager maintains to store high-level
Dialog items are assigned numbers that
events transmitted to an application. The Event
correspond to the item’s position in its item list.
Manager maintains a high-level event queue for
For example, the first item listed in a dialog item
each open application capable of receiving
list is item number 1.
high-level events.
keyboard equivalent A keyboard combination
hot spot A point that the mouse driver uses to
of one or more modifier keys and another key
align the cursor with the mouse location.
that invokes a corresponding menu command
icon An image that represents an object, a when pressed by the user.
concept, or a message.
key-down event An event indicating that the
icon family The set of icons that represent an user pressed a key on the keyboard.
object—such as an application or a document—
key-up event An event indicating that the user
displayed by the Finder. An entire icon family
released a key on the keyboard.
consists of large (32-by-32 pixel) and small
GL-5
G L O S S A RY
local coordinate system The coordinate system application’s menu bar and defines default colors
defined by the port rectangle of a graphics port. for its menu titles, menu items, and background
When the Window Manager creates a window, it color of menus.
places the origin of the local coordinate system at
menu bar resource A resource (of type 'MBAR')
the upper-left corner of the window’s port
that specifies the order and resource ID of each
rectangle. Compare global coordinate system.
menu in a menu bar.
location name An identifier for the network
menu color entry record A data structure of
location of the computer on which a PPC port
type MCEntry that defines the colors for an
resides. A location name consists of an object
application’s menu bar, menus, or menu items.
string, a type string, and a zone.
The first two fields of a menu color entry record,
low-level event The type of event returned by mctID and mctItem, define whether the entry
the Event Manager to report very low level is a menu bar entry, a menu title entry, or a menu
hardware and software occurrences. Low-level item entry.
events report actions by the user, changes in
menu color information table An array of
windows on the screen, and that the Event
menu color entry records, maintained by the
Manager has no other events to report. Compare
Menu Manager, that define the standard color
high-level event, operating-system event.
for the menu bar, titles of menus, text and
major switch A change of the foreground characteristics of menu items, and background
process. The Process Manager switches the color of a displayed menu. If you do not add
context of the foreground process with the context any entries to this table, the Menu Manager
of a background process (including the A5 worlds draws your menus using the default colors, black
and low-memory global variables) and brings the on white.
background process to the front, sending the
menu color information table resource A
previous foreground process to the background.
resource (of type 'mctb') that specifies the colors
See also context.
for an application’s menu bar, menus,
menu A user interface element you can use in and menu items.
your application to allow the user to view or
menu definition procedure A procedure that
choose an item from a list of choices and
performs all the drawing of menu items within
commands that your application provides.
a specific menu. This procedure, in conjunction
See also hierarchical menu, pop-up menu,
with the menu bar definition function, defines the
pull-down menu, and submenu.
general appearance and behavior of menus.
menu bar A white rectangle that is tall enough
menu ID A number that you assign to a menu
to display menu titles in the height of the system
in your application. Each menu in your applica-
font and system font size, and with a black lower
tion must have a unique menu ID.
border that is one pixel tall. The menu bar extends
across the top of the startup screen and contains menu item In a menu, a rectangle with text and
the title of each available pull-down menu. other characteristics identifying a command that
the user can choose.
menu bar definition function A function that
draws the menu bar and performs most of the menu item entry A menu color entry record
drawing activities related to the display of menus that contains nonzero values in both the mctID
when the user moves the cursor between menus. and mctItem fields. A menu item entry defines
This function, in conjunction with the menu colors for the mark, text, and keyboard equivalent
definition procedure, defines the general of items in a specific menu. It also defines the
appearance and behavior of menus. default background color of a menu.
menu bar entry A menu color entry record that
contains 0 in both the mctID and mctItem fields.
A menu bar entry defines the color for an
GL-6
G L O S S A RY
menu list A data structure that contains handles mouse-moved event An event indicating that
to the menu records of one or more menus the cursor is outside of a specified region.
(although a menu list can be empty). Compare
mouse-up event An event indicating that the
current menu list.
user released the mouse button.
Menu Manager The collection of routines that
movable modal dialog box A modal dialog box
an application can use to create, display, and
that has a title bar (with no close box) by which
manage its menus.
the user can drag the dialog box. See also dialog
menu record A data structure of type box, modal dialog box, and modeless dialog box.
MenuInfo that the Menu Manager uses to
note alert An alert box that informs users of a
maintain information about a menu.
minor mistake that won’t have any disastrous
menu resource A resource (of type 'MENU') consequences if left as is. Usually a note alert
that specifies the menu title and the individual simply offers information, and the user responds
characteristics of items in a menu. by clicking the OK button. A note alert is
identified by an icon bearing a face and a
menu title entry A menu color entry record that
cartoonlike dialog balloon in the upper-left corner
contains a nonzero value in the mctID
of the alert box. See also caution alert and stop
field and contains 0 in the mctItem field. A menu
alert.
title entry defines colors for the title,
items, and background color of a specific menu. It null event An event indicating that no events of
also defines the default menu bar color. the requested types exist in the application’s
event stream.
minimum partition size The actual partition
size limit below which an application cannot run. offset point The point in a region whose
horizontal and vertical offsets from the upper-left
minor switch A change in the context of a
corner of the region’s enclosing rectangle are the
process. The Process Manager switches the
same as the offsets of a specified point. The
context of a process to give time to a background
DrayGrayRgn function uses an offset point to
process without bringing the background process
limit the motion of a region and to calculate the
to the front.
distance a region has moved.
modal dialog box A dialog box that puts the
operating-system event An event returned by
user in the state or “mode” of being able to work
the Event Manager to communicate information
only inside the dialog box. A modal dialog box
about changes in the operating status of
resembles an alert box. The user cannot move a
applications (suspend and resume events) and to
modal dialog box and can dismiss it only by
report that the user has moved the cursor outside
clicking its buttons. See also modeless dialog box
of an area specified by the application (mouse-
and movable modal dialog box.
moved events). Compare low-level event,
modeless dialog box A dialog box that looks high-level event.
like a document window without a size box or
Operating System Event Manager The
scroll bars. The user can move a modeless dialog
collection of low-level routines that manage the
box, make it inactive and active again, and close it
Operating System event queue.
like any document window. See also modal
dialog box and movable modal dialog box. Operating System event queue A queue that
the Operating System Event Manager creates and
modifier keys The Shift, Option, Command,
maintains. The Operating System Event Manager
Control, and Caps Lock keys.
detects and reports low-level hardware-related
mouse-down event An event indicating that the events such as mouse clicks, keypresses, and disk
user pressed the mouse button. insertions and places these events in the
Operating System event queue.
mouse location The location of the cursor at the
time the event occurred.
GL-7
G L O S S A RY
part code An integer from 1 through 253 that radio button A control that appears onscreen as
stands for a particular part of a control. The a small circle. A radio button displays one of two
FindControl and TrackControl functions settings: on (indicated by a black dot inside the
return a part code to indicate the location of the circle) or off. A radio button is always a part of a
cursor when the user presses the mouse button. group of related radio buttons in which only one
button can be on at a time. When the user clicks
pop-up menu A menu that appears elsewhere
an unmarked radio button, the application turns
than the menu bar. The Control Manager provides
that button on and turns the other buttons in its
a control definition function for applications to
group off.
use when implementing pop-
up menus. Rescued Items from volume name folder A
directory located in the Trash directory and
port name A unique identifier for a particular
created by the Finder at system startup, restart, or
application on a computer, used for the purposes
shutdown only when it finds items in the
of communication between applications. A port
Temporary Items folder, usually after a system
name consists of a name string, a type string, and
crash. The Rescued Items from volume name folder
a script code.
is named for the volume on which the Temporary
port rectangle An entry in the graphics port Items folder exists. When a user empties the
data structure, described in Inside Macintosh: Trash, all Rescued Items folders disappear.
Imaging. Ordinarily, the port rectangle represents
resource Any data stored according to a defined
the area of a graphics port available for
structure in a resource fork of a file; the data in a
drawing—that is, the content region of a window.
resource is interpreted according to its resource
Preferences folder A directory located in the type.
System Folder for holding files that record users’
resource fork The part of a file that contains the
configuration settings for applications on a
files’ resources. A resource fork consists of a
particular Macintosh computer.
resource map and resources.
preferred partition size The partition size at
resource ID A number that identifies a specific
which an application can run most effectively. The
resource of a given resource type.
Operating System attempts to secure this
partition size upon launch of the application. resource type A sequence of four characters that
uniquely identifies a specific type of resource.
PrintMonitor Documents folder A directory
located in the System Folder for storing spooled resume event An event indicating that an
documents waiting to be printed. application has been switched back into the
foreground and can resume interacting with
process An open application or, in some cases,
the user.
an open desk accessory. (Only desk accessories
that are not opened in the context of another return receipt A high-level event that indicates
application are considered processes.) whether the other application accepted the
high-level event sent to it by your application.
process serial number A number assigned by
the Process Manager to identify a particular scroll arrow An arrow at either end of a scroll
instance of an application during a single boot bar. When the user clicks a scroll arrow, the
of the local machine. application moves a document or list one line
(or some similar measure) in the direction of the
pull-down menu A menu that is identified by a
arrow. When the user holds the mouse button
menu title (a word or an icon) in the menu bar.
down while the cursor is over a scroll arrow,
query document A file of file type 'qery' the application moves the document or list
containing commands and data in a format continuously in the direction of the arrow.
appropriate for a database or other data source.
An application uses high-level Data Access
Manager routines to open a query document.
GL-8
G L O S S A RY
scroll bar A control with which the user can standard state The size and location that
change the portion of a document displayed an application deems the most convenient for
within a window. A scroll bar is a light gray a window.
rectangle with scroll arrows at each end.
Startup Items folder A directory located in the
Windows can have a horizontal scroll bar, a
System Folder for storing applications and desk
vertical scroll bar, or both. A vertical scroll bar lies
accessories that the user wants started up every
along the right side of a window. A horizontal
time the Finder starts up.
scroll bar runs along the bottom of
a window. Inside the scroll bar is a rectangle stationery pad A document that a user creates
called the scroll box. The rest of the scroll bar to serve as a template for other documents. The
is called the gray area. The user can move Finder tags a document as a stationery pad by
through a document by manipulating the parts setting the isStationery bit in the Finder
of the scroll bar. flags field of the file’s file information record.
An application that is asked to open a stationery
scroll box A box that slides up and down or
pad should copy the template’s contents into a
back and forth across a scroll bar. The position of
new document and open the document in an
the scroll box in a scroll bar indicates the position
untitled window.
of the window contents relative to the entire
document. When the user drags the scroll box, the stop alert An alert box that informs the user of a
application displays a different portion of problem or situation so serious that the user’s
the document. desired action cannot be completed. Stop alerts
typically have only a single button (OK), because
signature A resource whose type is defined by a
all the user can do is acknowledge that the action
four-character sequence that uniquely identifies
cannot be completed. A stop alert is identified by
an application to the Finder. A signature is located
an icon of an upraised hand in the upper-left
in an application’s resource fork.
corner of the alert box. See also caution alert and
size box A box in the lower-right corner of note alert.
windows that can be resized. Dragging the size
structure region The entire screen area occupied
box resizes the window.
by a window, including both the window frame
size region The area occupied by a window’s and the content region.
size box. See also size box.
submenu A menu that is attached to
size resource A resource (of type 'SIZE') that another menu.
specifies the operating characteristics, minimum
suspend event An event indicating that the
partition size, and preferred partition size of
execution of your application is about to be
an application.
suspended as the result of a major switch.
slider A control, such as a scroll bar, that The application is suspended at the application’s
graphically represent the ranges of values that next call to WaitNextEvent or EventAvail.
a user can set or that simply displays the value,
system alert sound A sound resource that is
magnitude, or position of something, typically
stored in the System file and played whenever
in some pseudo-analog form.
system software or an application uses the Sound
standard control definition functions Three Manager procedure SysBeep. With the Sound
control definition functions, stored as 'CDEF' control panel, the user can select which sound
resources in the System file. The 'CDEF' resource to use.
with resource ID 0 defines the look and behavior
System file A file, located in the System Folder,
of buttons, checkboxes, and radio buttons; the
that contains the basic system software plus some
'CDEF' resource with resource ID 1 defines the
system resources, such as sound and keyboard
look and behavior of scroll bars; and the 'CDEF'
resources.The System file behaves like a folder in
resource with resource ID 63 defines the look and
this regard: although it looks like a suitcase icon,
behavior of pop-up menus.
GL-9
G L O S S A RY
double-clicking it opens a window that reveals user state The size and location that the user has
movable resource files (such as sounds, keyboard established for a window.
layouts, and script system resource collections)
variation code A number that selects among
stored in the System file.
variations supported by a single window
System Folder A directory containing the defintion function or control definition function.
software that Macintosh computers use to start The variation code is stored in the low-order 4
up. The System Folder includes a set of folders for bits of the window definition ID or control
storing related files, such as preferences files that definition ID. See also control definition
an application might need when starting up. function, control definition ID, window
definition function, and window definition ID.
Temporary Items folder A directory located at
the root level of a volume for storing temporary virtual key code A value that represents the key
buffer files created by applications. The pressed or released by the user; this value is
Temporary Items folder is invisible to the user. always the same for a specific physical key on a
keyboard. Compare character code.
text style table In an item color table resource, a
specification for the typeface, font style, font size, visible region The part of a window’s graphics
and color of text in an editable text item or a static port that’s actually visible on the screen—that is,
text item. the part that’s not covered by other windows.
title bar The bar at the top of a window that window An area on the screen that displays
displays the window name, contains the close and information, including user documents as well
zoom boxes, and indicates whether the window is as communications such as alert boxes and dialog
active. boxes. The user can open or close a window;
move it around on the desktop; and sometimes
Toolbox Event Manager See Event Manager.
change its size, scroll through it, and edit its
Trash folder A directory at the root level of a contents.
volume for storing files that the user has moved
window color table The data structure in which
to the Trash icon. After opening the Trash icon,
the Window Manager stores the colors
the user sees the collection of all items that the
to be used for drawing a window’s frame and
user has moved to the Trash icon—that is, the
for highlighting selected text.
union of appropriate Trash directories from
all mounted volumes. A Macintosh computer window definition function A function that
set up to share files among users in a network defines the general appearance and behavior of a
environment maintains separate Trash window. The Window Manager calls the window
subdirectories for remote users within its shared definition function to draw the window’s frame,
Trash directory. The Finder empties a Trash determine what region of the window the cursor
directory (or, in the case of a file server, a Trash is in, draw the window’s size box, draw the
subdirectory) only when the user of that directory window’s zoom box, move and resize the
chooses the Empty Trash command. window, and calculate the window’s structure
and content regions.
update event An event indicating that the
contents of a window need updating. window definition ID An integer that specifies
the resource ID of a window definition function in
update region A region maintained by the
the upper 12 bits and an optional variation code
Window Manager that includes the parts of a
in the lower 4 bits. When creating a new window,
window’s content region that need updating.
your application supplies a window definition ID
The Event Manager generates update events
either as a field in the 'WIND' resource or as a
as necessary, based on the contents of the
parameter to the NewWindow or NewCWindow
update region, telling your application to update
function.
a window.
GL-10
G L O S S A RY
GL-11
Index
IN-1
I N D E X
'ALRT' resource type. See alert resources arrows, in scroll bars. See scroll arrows
altDBoxProc window type 4-9 '****' file type 7-20
'amnu' folder type 7-54 AtMenuBottom global variable 3-151
ANumber global variable 6-172 auto-key events 2-38
'appe' file type 7-44 auto-key threshold rate 2-38
AppendDITL procedure 6-54, 6-125 to 6-127 A/UX and cancel events 2-46
AppendMenu procedure 3-64 to 3-67, 3-124 to 3-125 AuxCtlRec data type 5-76 to 5-77, 5-107
AppendResMenu procedure 3-20, 3-68 to 3-70, 3-128 to auxiliary control records 5-76 to 5-77, 5-107
3-129 auxiliary window record 4-21, 4-73 to 4-74
Apple Event Interprocess Messaging Protocol AuxWinRec data type 4-73 to 4-74
(AEIMP) 2-13, 2-67
Apple events
and the Finder 7-25 to 7-26
application sending to itself 3-71 B
as high-level events 2-67 to 2-69
defined 2-13 background applications, and Extensions folder 7-44
handling 2-78 background processes 2-4
Open Documents event 7-20 Balloon Help online assistance, for icons 7-38.See also
sending 2-78 help balloons
in response to menu commands 3-71 BeginUpdate procedure 4-50, 4-106 to 4-107
Apple menu 3-20 BeginUpdate procedure 2-47
About command 3-21 to 3-22, 3-45 'BNDL' resource type 7-20 to 7-25, 7-65 to 7-68
accessing from dialog boxes 6-68 to 6-73 BringToFront procedure 4-90
adding items to 3-68 to 3-69 bundle bit 7-34
creating 3-43 to 3-44 bundle resources 7-20 to 7-25, 7-45, 7-65 to 7-68
handling 3-80 to 3-81 Button function 2-108
Apple Menu Items folder buttons
adding items from, to Apple menu 3-20 to 3-21 active 5-11 to 5-13
alias type for 7-40 control definition ID for 5-14
defined 7-43 creating, in windows 5-17 to 5-20
finding 7-54 default 6-10 to 6-11, 6-22, 6-30 to 6-31, 6-56 to 6-61
'APPL' file type 7-10 defined 5-5
application-defined items events in 5-31 to 5-37, 6-78
creating 6-56 to 6-61 inactive 5-11 to 5-13
specifying in alert or dialog boxes 6-29 to 6-30, 6-155 part code for 5-32
application heap 2-32 specifying in alert or dialog boxes 6-29 to 6-30, 6-153
application icons. See also icon families titles for 6-37 to 6-39
creating 7-10 to 7-17
default 7-12
Application menu 3-33
accessing from alert and dialog boxes 6-68 to 6-69 C
Hide Others command 3-33
application-missing message string resources 7-27 to CalcMenuSize procedure 3-143, 5-28
7-30, 7-68 to 7-69 CalcVisBehind procedure 4-119
applications CalcVis procedure 4-119
alias type for 7-40 canBackground flag 2-117
in Apple Menu Items folder 7-43 cancel events 2-46 to 2-47
creating icons for 7-11 to 7-17 Can’t Undo command (Edit menu) 3-24, 3-25
default icon for 7-12 Caps Lock key 2-20
launching from the Finder 7-25 to 7-26 caret, time between blinks of 2-113
sharing 2-68 catalog files
signatures for 7-8 to 7-10 defined 7-5
switching between 2-5 Finder information in 7-32 to 7-34, 7-46 to 7-51
application-unavailable alert box messages 7-27 to 7-30 CautionAlert function 6-111
arrow cursor 2-63 caution alerts
creating with the CautionAlert function 6-111
defined 6-9
IN-2
I N D E X
'cctb' resource type 5-121 to 5-123 ColorSpec data type 4-72, 5-78 to 5-79
'CDEF' resource type 5-14, 5-109 to 5-115 color window records 4-65 to 4-68
character codes 2-40 Command key 2-20
checkboxes Command-key equivalents. See keyboard equivalents
active 5-11 to 5-13 Command-Shift-number key sequences 2-39, 2-86
changing setting and display of 5-38 to 5-39 content region
control definition ID for 5-14 defined 4-6, 4-12
defined 5-5 to 5-6 drawing 4-39 to 4-40
events in 6-78 updating 4-40 to 4-41, 4-48 to 4-50
in windows 5-31 to 5-32, 5-38 to 5-39 context of a process, switching 2-15 to 2-16
inactive 5-11 to 5-13 control color table records 5-77 to 5-80
part code for 5-32 control color table resources 5-121 to 5-123
specifying in alert or dialog boxes 6-29 to 6-30, 6-153 control color tables 6-160 to 6-162
CheckItem procedure 3-61 to 3-62, 3-136 control definition functions
CheckUpdate function 4-116 custom 5-109 to 5-115
'cicn' resource type 7-64 defined 5-14
specifying a menu item’s 3-62, 3-154 for pop-up menus 5-14, 5-36
Clear command (Edit menu) 3-25, 6-69 standard 5-14
ClearMenuBar procedure 3-110 control definition IDs
ClipAbove procedure 4-116 to 4-117 defined 5-14
Clipboard 3-24 for buttons 5-14
converting data to and from 2-58 to 2-60 for checkboxes 5-14
Hide Clipboard command (Edit menu) 3-25 for custom controls 5-109 to 5-110
Show Clipboard command (Edit menu) 3-25 for pop-up menus 5-14
close box 4-6 for radio buttons 5-14
Close command (File menu) 3-23 for scroll bars 5-14
CloseDialog procedure 6-119 to 6-120 specifying 5-18, 5-19, 5-25, 5-83 to 5-84, 5-120
close region 4-12 Control key 2-20
CloseWindow procedure 4-60, 4-104 to 4-105 control list 4-14
closing windows 4-60 to 4-62 Control Manager 5-3 to ??
routines for 4-103 to 4-106 application-defined routines for 5-109 to 5-117
'CNTL' resource type data structures in 5-72 to 5-80
example of 5-18, 5-21, 5-23, 5-26 and Dialog Manager 5-3, 5-5, 5-16, 5-29, 5-31, 6-78
Rez input format for 5-18 to 5-24, 5-25 to 5-28 and Event Manager 5-3
Rez output format for 5-118 to 5-121 and List Manager 5-3
Color control panel 4-20, 4-65 localization guidelines 5-15, 5-19 to 5-20, 5-85, 5-120
color flag 7-48 and Resource Manager 5-3
color graphics ports 4-20 resources for 5-117 to 5-123. See also control color
color icon resources 3-46, 3-62, 7-64 tables; control definition functions; control
color icons 7-11, 7-13 to 7-16 resources;
Color QuickDraw routines in 5-80 to 5-117
checking for user interface guidelines 5-5 to 5-13, 5-52 to 5-53
when creating a window 4-77 and Window Manager 5-3
when zooming windows 4-54 control panels installing and removing 7-41
and color window records 4-65 Control Panels folder
coordinate systems in 4-17 to 4-18 alias type for 7-40
creating color windows 4-20 to 4-21 defined 7-43
and the Window Manager port 4-74 finding 7-54
colorReserved flag 7-48 ControlRecord data type 5-73 to 5-75
colors control records 5-73 to 5-75
in alert boxes and dialog boxes 6-156 to 6-164 control resources
in controls 5-5 example of 5-18, 5-21, 5-23, 5-26
Label menu commands for 7-16 Rez input format for 5-18 to 5-24, 5-25 to 5-28
in menus 3-46, 3-62, 3-98 to 3-102 Rez output format for 5-118 to 5-121
in windows 4-20 to 4-21
IN-3
I N D E X
controls creators
action procedures for 5-91, 5-102, 5-115 to 5-117 assigning 7-33 to 7-34, 7-47 to 7-49
activating 5-13 defined 7-9 to 7-10
active 5-11 to 5-13, 6-13 CtlCTab data type 5-77 to 5-80
colors in 5-5, 5-101, 5-121 to 5-123 'ctrl' folder type 7-54
control definition IDs for 5-18, 5-19, 5-25, 5-83 to current menu list 3-40
5-84, 5-120 current process 2-28
custom. See custom controls cursor
defined 5-3 adjusting 2-65 to 2-67
dragging 5-35, 5-99 to 5-100, 5-114 to 5-115 arrow 2-63
drawing 5-17, 5-85 to 5-88 cross 2-63
events in 5-88 to 5-93, 6-78 I-beam 2-63
highlight states 5-35, 5-98 to 5-99 plus 2-63
inactive 5-13, 6-13, 6-74 setting the appearance of 2-62
in alert and dialog boxes 6-29 to 6-30, 6-154 wristwatch 2-63
indicators. See indicators, in controls custom alert boxes
invisible 5-18, 5-19, 5-25, 5-83, 5-97, 5-119 creating with the Alert function 6-106 to 6-108
in windows 4-14 to 4-15, 4-23, 5-82 defined 6-9
mouse events in 5-11 to 5-13, 5-30 to 5-70 custom controls 5-11, 5-109 to 5-115
moving 5-65 to 5-70, 5-97 to 5-98 customized icons 7-17 to 7-18
part codes for 5-31 to 5-32 Cut command (Edit menu) 3-25, 6-69
pop-up menus 6-42 to 6-44 CWindowPeek data type 4-65
rectangles for 5-18 to 5-19, 5-22 to 5-23, 5-25 to 5-26, CWindowPtr data type 4-65
5-82, 5-118.See also display rectangles 5-26 CWindowRecord data type 4-65 to 4-68
reference values for
changing 5-105 to 5-106
determining 5-105
specifying 5-18, 5-25, 5-84, 5-120 D
removing 5-108 to 5-109
resizing 5-65 to 5-70, 5-98 DABeeper global variable 6-172
resources for. See control resources DAStrings global variable 6-172
settings of data forks 1-11
changing 5-11, 5-37 to 5-43, 5-61, 5-65 to 5-70, 5-93 dBoxProc window type 4-9
to 5-102 dBoxProc window type 2-16, 6-25
determining 5-37 to 5-43, 5-102 to 5-107 'dctb' resource type 6-156 to 6-157
specifying initial 5-18 to 5-19, 5-21 to 5-23, 5-25 to default buttons 6-10 to 6-11, 6-22, 6-30 to 6-31, 6-56 to
5-28, 5-83, 5-118 to 5-119 6-61
standard 5-4, 5-15 to 5-28, 5-81 to 5-85 DeleteMCEntries procedure 3-147
text in 5-18, 5-19 to 5-20, 5-25 DeleteMenuItem procedure 3-127 to 3-128
titles of DeleteMenu procedure 3-109 to 3-110
changing 5-96 DelMCEntries procedure. See DeleteMCEntries
determining 5-104 to 5-105 procedure
specifying 5-18, 5-19 to 5-20, 5-25, 5-83, 5-85, 5-120, DelMenuItem procedure. See DeleteMenuItem
5-121 procedure
types of 5-4 to 5-13. See also buttons; checkboxes; desk accessories
custom controls; pop-up menus; radio buttons; handling events in 2-36, 2-87, 2-95
scroll bars and System 7 7-13
updating 5-29 to 5-30 desk accessory resource. See 'DRVR' resource type
visible 5-18, 5-19, 5-25, 5-83, 5-119 'desk' folder type 7-54
cooperative multitasking 2-10 DeskHook global variable 4-75
coordinate systems 4-17 to 4-18 DeskPattern global variable 4-113
Copy command (Edit menu) 3-25, 6-69 desktop 7-3
CountDITL function 6-128 desktop database 7-5, 7-45 to 7-46
CountMItems function 3-81, 3-141 Desktop file 7-5
Create Publisher command (Edit menu) 3-25 Desktop Folder
defined 7-43
finding 7-54
IN-4
I N D E X
IN-5
I N D E X
Draw1Control procedure 5-88 Event Manager 2-3 to 2-132. See also Operating
DrawControls procedure 5-87 to 5-88 System Event Manager
DrawDialog procedure 6-142 application-defined routine for 2-114 to 2-115
DrawGrowIcon procedure 4-12, 4-39, 4-86 to 4-87 and Control Manager 5-3
DrawMenuBar procedure 3-51, 3-58, 3-113 data structures in 2-78 to 2-83
DrawNew procedure 4-117 initializing 2-17
'drop' alias type 7-40 and MultiFinder 2-7
drop folder, alias type for 7-40 and the PPC Toolbox 2-7, 2-13
'DRVR' resource type 3-20, 3-68, 3-129, 3-130 and the Process Manager 2-5
DXInfo data type 7-50 to 7-51 routines in 2-84 to 2-113
and the Scrap Manager 2-60
testing for features 2-17
event masks
E defined 2-22, 2-85
setting 2-26 to 2-29
editable text items event messages 2-19, 2-80
events in 6-79 to 6-80 event queue. See also high-level event queue;
getting text from 6-48 to 6-51, 6-130 to 6-131 Operating System event queue
highlighting default text in 6-131 to 6-132 scanning for a cancel event 2-46
setting text in 6-131, 6-153 structure of 2-83
specifying in dialog boxes 6-29 to 6-30, 6-153 EventRecord data type 2-79 to 2-81
Edition Manager 2-14 event records 2-79 to 2-81
editions defined 2-4
creating icons for 7-16 and event loops 2-25
defined 7-4 for high-level events 2-68, 2-69
Edit menu 3-24 to 3-26 events
accessing from alert and dialog boxes 6-68 to 6-73 activate 2-8, 2-50 to 2-55, 4-50 to 4-53
adjusting 3-75 to 3-76 in alert boxes 2-29 to 2-30, 6-81 to 6-82, 6-86 to 6-89,
Can’t Undo command 3-25 6-135
Clear command 3-25, 6-69 Apple. See Apple events
Copy command 3-25, 6-69 auto-key 2-8, 2-38
Create Publisher command 3-25 in buttons in windows 5-31 to 5-37
Cut command 3-25, 6-69 cancel 2-46 to 2-47
Hide Clipboard command 3-25 in checkboxes in windows 5-38 to 5-39
Paste command 3-25, 6-69 Command-period 2-46
Publisher Options command 3-25 in controls 5-11 to 5-13, 5-30 to 5-70, 5-88 to 5-93, 6-78
Select All command 3-25 defined 2-4
Show Clipboard command 3-25 in desk accessories 2-36
Subscriber Options command 3-25 in dialog boxes 2-29 to 2-30, 6-77 to 6-100, 6-135 to
Subscribe To command 3-25 6-143
Undo command 3-25, 6-69 disk-inserted 2-8, 2-55 to 2-56
8-bit color icons 7-11 in editable text items 6-79 to 6-80
'empt' folder type 7-54 filter function for, in alert and dialog boxes 6-86 to
enabled constant 3-7 6-89, 6-145 to 6-147
enabled items 6-13 first click in an inactive window 4-42
EnableItem procedure 3-58 to 3-59, 3-131 getting information about 2-18 to 2-21
EndUpdate procedure 4-50, 4-107 in gray areas of scroll bars 5-57 to 5-61
EndUpdate procedure 2-47, 2-49 handling 2-26
EraseRect procedure 4-103 high-level. See high-level events
ErrorSound procedure 6-104 interacting with the user from the background 2-12
EventAvail function 2-21, 2-88 to 2-89 keyboard 2-8, 2-38 to 2-45
event classes 2-68 key-down 2-38
event filter functions 6-86 to 6-89, 6-145 to 6-147 key-up 2-38, 2-39
event IDs 2-68 low-level 2-8 to 2-9
event loops 2-24 to 2-25 masking out 2-27
IN-6
I N D E X
IN-7
I N D E X
IN-8
I N D E X
IN-9
I N D E X
IN-10
I N D E X
IN-11
I N D E X
IN-12
I N D E X
Menu Manager 3-5 to 3-167 missing-application name string resources 7-27 to 7-30,
application-defined routines for 3-148 to 3-151 7-68
data structures in 3-95 to 3-102 modal dialog boxes
data structures maintained by 3-40 to 3-41 accessing menus from 6-68 to 6-73
and Dialog Manager 6-68 to 6-73 closing 6-100 to 6-101
initializing 3-103 to 3-104 creating 6-23 to 6-26, 6-113 to 6-119
localization guidelines 3-10, 3-16 to 3-18, 3-43 defined 6-10 to 6-11
routines in 3-102 to 3-147 displaying 6-61, 6-62 to 6-75
routines names, mapping of 3-102 event filter function for 6-86 to 6-89, 6-145 to 6-147
testing for availability 3-42 events in 6-82 to 6-86, 6-135 to 6-137
user interface guidelines 3-5 to 3-38 window types for 4-9
menu records 3-40, 3-95 to 3-97 ModalDialog procedure 6-84, 6-135 to 6-137
menu resource 3-151 to 3-154 and menus 3-86
'MENU' resource type 3-42 to 3-48, 3-152 to 3-154 and disk-inserted events 2-56
menus. See also Apple menu; Application menu; Edit modeless dialog boxes
menu; File menu; Font menu; Help menu; accessing menus from 6-68 to 6-73
Keyboard menu; Size menu; Style menu closing 6-100 to 6-101
accessing from alert and dialog boxes 3-84 to 3-86, creating 6-23 to 6-26, 6-113 to 6-119
6-68 to 6-73 defined 6-12
adding items to 3-64 to 3-70 displaying 6-61 to 6-67
adjusting items in 3-73 to 3-76 events in 6-89 to 6-100, 6-138 to 6-141
Apple. See Applemenu titles for 6-25
Application. See Application menu window types for 4-10
color 3-11 modifier keys 2-20 to 2-21, 2-81, 3-77
creating 3-42 to 3-57, 3-105 to 3-108 mounted folder, alias type for 7-40
hierarchical 3-53 to 3-56 mouse
pop-up 3-56 to 3-57, 5-25 to 5-28, 6-42 to 6-44 determining location of 2-108
pull-down 3-42 to 3-56 getting information about 2-108
disabling for alert and dialog boxes 6-68 to 6-73 mouse-down events
disposing of 3-112, 3-140 in alert boxes 6-78, 6-81 to 6-82
Edit. See Edit menu in controls 5-11 to 5-13, 5-30 to 5-70
File. See File menu in desk accessories 2-87, 2-95
Font. See Font menu in dialog boxes 6-78 to 6-80, 6-82 to 6-94
grouping items in 3-14 to 3-16 handling 2-33 to 2-38
Help. See ; Help menu in windows 4-42 to 4-45
help balloons for 3-31 in the menu bar 3-72 to 3-73
hierarchical 3-6, 3-38, 3-53 to 3-56 mouse driver 2-62
items in. See menu items mouse-moved events 2-23, 2-62 to 2-67, 2-86
Keyboard. See Keyboard menu mouse region 2-23, 2-64 to 2-67
keyboard equivalents for 3-16 to 3-19, 3-154 mouse-up events 2-33
localizing 3-10 in alert boxes 6-78, 6-81 to 6-82
menu ID 3-152 in controls 5-11 to 5-13, 5-30 to 5-70
pop-up. See pop-up menus in dialog boxes 6-78 to 6-80, 6-82 to 6-94
pull-down 3-6, 3-42 movableDBoxProc window type 4-9
resource ID 3-44, 3-153 movableDBoxProc window type 3-85, 6-25
Size. See Size menu movable modal dialog boxes
Style. See Style menu accessing menus from 6-68 to 6-73
submenus 3-6, 3-53 to 3-56 closing 6-100 to 6-101
system-handled 3-19 creating 6-23 to 6-26, 6-113 to 6-119
titles of 3-7, 3-10 defined 6-11 to 6-12
types of 3-6 displaying 6-61, 6-62
MenuSelect function 3-8, 3-70, 3-72, 3-73, 3-78 to 3-79, events in 6-89 to 6-100, 6-138 to 6-141
3-115 to 3-117 titles for 6-25
message string resources 7-27 to 7-30 window types for 4-9
minor switches 2-16 movable resources 7-36 to 7-38
IN-13
I N D E X
MoveControl procedure 5-67 to 5-70, 5-97 to 5-98 Operating System event queue
MoveWindow procedure 4-95 to 4-96 defined 2-6
MultiFinder 2-7 flushing events from 2-93
MyAction procedure 5-116 to 5-117 operating-system events
MyAlertSound procedure 6-144 to 6-145 defined 2-10 to 2-12
MyControl function 5-110 to 5-115 handling 2-58 to 2-67
MyEventFilter function 6-145 to 6-147 Option key 2-20
MyIndicatorAction procedure 5-117 OSEventAvail function 2-98 to 2-99
MyItem procedure 6-143 to 6-144 Other command (Size menu) 3-28 to 3-29, 3-82 to 3-84
N P
nameLocked flag 7-18, 7-34 page regions, in scroll bars. See gray areas
name string resources for applications 7-27 to 7-30 Page Setup command (File menu) 3-23
networks, using shared Trash directories on 7-44 PaintBehind procedure 4-118 to 4-119
NewCDialog function. See NewColorDialog function PaintOne procedure 4-118
NewColorDialog function 6-115 to 6-118 PaintWhite global variable 4-118, 4-119
New command (File menu) 3-23 Palette Manager, and system color tables 4-21
NewControl function 5-82 to 5-85 ParamText procedure 6-47, 6-129 to 6-130
NewCWindow function 4-79 to 4-82 part codes 5-31 to 5-32
NewDialog function 6-118 to 6-119 partitions
NewMenu function 3-105 to 3-106 sizes of 2-30, 2-115
NewWindow function 4-82 to 4-85 Paste command (Edit menu)
noGrowDocProc window type 4-10 and dialog boxes 6-69
noGrowDocProc window type 6-25 and information windows 7-17
NoteAlert function 6-110 introduced 3-25
note alerts PBGetCatInfo function 7-34, 7-49
creating with the NoteAlert function 6-110 PBMountVol function 2-55
defined 6-8 pCDeskPat parameter-RAM bit flag 4-113
Notification Manager, and operating-system pictures, in alert or dialog boxes 6-29 to 6-30, 6-154
events 2-12 PinRect function 4-99
null events plainDBoxProc window type 4-9
defined 2-9 pop-up menus 3-33 to 3-38
and event masking 2-28 action procedure for 5-36 to 5-37
handling 2-57 active 5-11 to 5-13
control definition function for 3-33, 3-34 to 3-36, 5-14
control definition ID for 5-14
creating 3-56 to 3-57, 5-25 to 5-28
O defined 3-6, 5-6 to 5-7
events in, in windows 5-31 to 5-37
OldContent global variable 4-117 inactive 5-11 to 5-13
OldStructure global variable 4-117 in dialog boxes 6-42 to 6-44
onlyBackground flag 2-117 testing for availability 3-42
Open command (File menu) 3-23 type-in fields 3-37
OpenDeskAcc function 3-21, 3-80 to 3-81 variation codes for 5-27 to 5-28
Open Documents events 7-20, 7-25 to 7-26 PopUpMenuSelect function 3-57, 3-120 to 3-121
opening popupPrivateData data type 5-77
applications, from the Finder 7-25 to 7-26 port names 2-75
disks 7-20 and receiving high-level events 2-73
documents 7-25 to 7-26 converting to process serial numbers 2-105
folders 7-20 port rectangle 4-18, 4-101, 4-103
Operating System Event Manager 2-3, 2-7. See also of Window Manager port 4-75
Event Manager PostEvent function 2-104 to 2-105
IN-14
I N D E X
IN-15
I N D E X
IN-16
I N D E X
IN-17
I N D E X
SetControlMaximum procedure 5-41 to 5-43, 5-70, 5-95 ShowDItem procedure. See ShowDialogItem
to 5-96 procedure
SetControlMinimum procedure 5-95 ShowHide procedure 4-89 to 4-90
SetControlReference procedure 5-105 to 5-106 ShowWindow procedure 4-88
SetControlTitle procedure 5-96 ShowWindow procedure 6-61
SetControlValue procedure 5-38 to 5-39, 5-42 to 5-43, 'SICN' resource type, specifying a menu item’s 3-62,
5-44, 5-61, 5-94 to 5-95 3-154
SetCRefCon procedure. See SetControlReference signature resources 7-8 to 7-10
procedure signatures
SetCTitle procedure. See SetControlTitle in bundle resources 7-20
procedure as creators 7-9
SetCtlAction procedure. See SetControlAction defined 7-8
procedure registering 7-8 to 7-10
SetCtlColor procedure. See SetControlColor 16-by-16 pixel icons (small) 7-11, 7-15
procedure size box 4-6
SetCtlMax procedure. See SetControlMaximum SizeControl procedure 5-67 to 5-70, 5-98
procedure Size menu 3-27 to 3-29, 3-82
SetCtlMin procedure. See SetControlMinimum handling 3-82 to 3-84
procedure Other command 3-28 to 3-29
SetDAFont procedure. See SetDialogFont size region 4-12
procedure size resources 2-115 to 2-119, 7-35
SetDeskCPat procedure 4-112 to 4-113 'SIZE' resource type 2-115 to 2-119, 7-35
SetDialogFont procedure 6-105 creating 2-30 to 2-32
SetDialogItem procedure 6-122 to 6-123 defined 2-30 to 2-32, 2-115 to 2-119
SetDialogItemText procedure 6-131 flags, defined 2-116 to 2-119
SetDItem procedure. See SetDialogItem procedure and null events 2-9, 2-57
SetEventMask procedure 2-99 to 2-100 sample Rez input 2-31
SetItemCmd procedure 3-139 to 3-140 scheduling option flags 2-16
SetItemIcon procedure 3-62 to 3-64, 3-137 to 3-138 setting flags for high-level events 2-68
SetItemMark procedure 3-61 to 3-62, 3-135 to 3-136 setting flags of 2-9, 2-11, 2-16, 2-51
SetItem procedure. See SetMenuItemText SizeWindow procedure 4-60, 4-101
procedure sleep value 2-22
SetItemStyle procedure 3-60, 3-134 slider controls 5-11
SetIText procedure. See SetDialogItemText small 8-bit color icon resources
procedure Rez output format for 7-62 to 7-63
SetMCEntries procedure 3-146 to 3-147 creating 7-11, 7-24
SetMCInfo procedure 3-52, 3-144 small 4-bit color icon resources
SetMenuBar procedure 3-50 to 3-51, 3-112 to 3-113 creating 7-11, 7-24
SetMenuFlash procedure 3-142 Rez output format for 7-60 to 7-61
SetMenuItemText procedure 3-59 to 3-60, 3-133 small icon list resources
SetOrigin procedure 5-44 to 5-45, 5-63 to 5-64 creating 7-11, 7-15, 7-24
SetPort procedure 6-62 Rez output format for 7-58 to 7-59
SetWinColor procedure 4-114 to 4-115 small icons (16-by-16 pixel)
SetWindowPic procedure 4-110 resource IDs for 7-15
SetWRefCon procedure 4-111 resources for 7-10
SetWTitle procedure 4-85 sound resources
'sfil' file type 7-37 icon for 7-37 to 7-38
shared folder, alias type for 7-40 installing and removing 7-41
Shift key 2-20 'srvr' alias type 7-40
ShortenDITL procedure 6-127 to 6-128 stack, size of 2-32
Show Balloons command (Help menu) 6-68 standard control definition function 5-14
Show Clipboard command (Edit menu) 3-25 standard file dialog boxes, and disk-inserted
ShowControl procedure 5-39 to 5-40, 5-66 to 5-67, events 2-55
5-86 Standard File Package and disk-inserted events 2-55 to
ShowDialogItem procedure 6-124 2-56
IN-18
I N D E X
IN-19
I N D E X
IN-20
I N D E X
IN-21