Important: The information in this document is obsolete and should not be used for new development.
Writing a Desk Accessory
Desk accessories are small applications designed like device drivers. Desk accessories typically provide a user interface with a window and a menu, perform some limited function, and are opened from the Apple menu. The Chooser is an example of a desk accessory.Desk accessories were originally created for the Macintosh because they offered two distinct advantages over applications. They provided both a limited degree of multitasking and a primitive form of interapplication communication. However, modern Macintosh applications enjoy far more sophisticated versions of these capabilities. Users can even open applications from the Apple menu. For these reasons, you would be better served by writing a small application than by writing a desk accessory.
Control panels have largely replaced desk accessories as a user interface for device drivers. In addition to providing a more consistent and extensible interface, control panels can include an initialization (
'INIT'
) resource to load and execute your device driver at system startup. For more information about control panels, see the chapter "Control Panels" in Inside Macintosh: More Macintosh Toolbox.If you're certain you need to write a desk accessory, you should read this section. You might also want to read the chapters "Event Manager," "Window Manager," "Dialog Manager," and "Menu Manager" in Inside Macintosh: Macintosh Toolbox Essentials.
How Desk Accessories Work
When the user opens a desk accessory (or when an application calls theOpenDeskAcc
function), the system performs a major context switch, loads the desk accessory into the system heap, and calls the desk accessory driver open routine. The desk accessory can respond by creating its window and menu.When events occur, the Event Manager directs them to the desk accessory by calling its driver control routine. The Event Manager handles switching between applications and desk accessories in the system heap.
When the user closes the desk accessory (by closing its window or choosing Quit from its menu) or an application closes the desk accessory (by calling the
CloseDeskAcc
function), the desk accessory disposes of its window and any other data structures associated with it.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, although it still translates them into control requests. For details, see the chapter "Event Manager" in Inside Macintosh: Macintosh Toolbox Essentials.
Creating a Driver Resource for a Desk Accessory
You create a desk accessory by creating a driver resource and storing it in a resource file, as described in "Creating a Driver Resource," beginning on page 1-24. Typically, you store your desk accessory driver resource in a file of type'dfil'
, which the user places in the Apple Menu Items folder.Three fields of the driver resource header are of particular importance to desk accessories:
All desk accessories must implement open, close, and control routines. Your desk accessory can implement a prime and status routine if needed.
- The
drvrEMask
field. This field contains an event mask specifying which events your desk accessory can handle. If your desk accessory has a window, you should include keyboard, activate, update, and mouse-down events, but you should not include mouse-up events. When an event occurs, the Event Manager checks this field to determine whether the desk accessory can handle the type of event and, if so, calls the desk accessory driver control routine. See the chapter "Event Manager" in Inside Macintosh: Macintosh Toolbox Essentials for more information about events and event masks.- The
drvrMenu
field. This field contains the menu ID of your desk accessory's menu, if it has one, or any one of its menus, if it has more than one. Otherwise, it contains 0. A desk accessory menu ID must be negative and must be different from the menu ID for other desk accessories.- The
drvrDelay
field and thedNeedTime
flag of thedrvrFlags
field. Desk accessories sometimes need to perform certain actions periodically. For example, a clock desk accessory might change the time it displays every second. If your desk accessory needs to perform a periodic action, set thedNeedTime
flag and use thedrvrDelay
field to indicate how often the action should occur. "Creating a Driver Resource," beginning on page 1-24, describes these fields in more detail.
Opening and Closing a Desk Accessory
When the user chooses an item from the Apple menu, the foreground application calls theOpenDeskAcc
function, which determines whether the item is a desk accessory, application, or document, and schedules it for execution. Applications call theCloseDeskAcc
function if the user chooses the Close menu item from the File menu when the foreground window does not belong to the application. These functions are described in "Device Manager Reference," beginning on page 1-53.Opening a desk accessory is similar to launching an application. In your desk accessory driver open routine, you should do the following:
If your driver open routine is unable to complete its tasks (because of insufficient memory, for example), you should modify the code so it doesn't respond to events, and display an alert indicating failure.
- Create the desk accessory's window. You can do this with the Dialog Manager function
GetNewDialog
orNewDialog
. You should specify that the window be invisible because theOpenDeskAcc
function will display it. You should set thewindowKind
field of thewindowRecord
structure to the desk accessory's driver reference number, which you can find in the device control entry. You should also store a copy of the window pointer in thedCtlWindow
field of the device control entry.- Allocate private storage as you would for any device driver.
- Create any menus needed by your desk accessory. You are responsible for adding your menus to the menu bar. See the chapter "Menu Manager" in Inside Macintosh: Macintosh Toolbox Essentials for more details.
As for all drivers, your close routine should undo the actions taken by the open routine, dispose of the desk accessory's window and private storage, clear the window pointer in the device control entry, and remove any menus that were added to the menu bar.
Responding to Events
When the Event Manager determines an event has occurred that your desk accessory should handle, it checks thedrvrEMask
field of the driver header and, if that field indicates your desk accessory handles the event type, it passes the event to your desk accessory by calling your driver control routine.The Event Manager passes one of nine values in the
csCode
field to indicate the action to take:
Constant name Value Meaning accEvent 64 Handle a given event accRun 65 Time for periodic action accCursor 66 Change cursor shape if appropriate accMenu 67 Handle a given menu item accUndo 68 Handle the Undo command accCut 70 Handle the Cut command accCopy 71 Handle the Copy command accPaste 72 Handle the Paste command accClear 73 Handle the Clear command Along with the
accEvent
message, the Event Manager sends a pointer to an event record in thecsParam
field. Your desk accessory can respond to the event in whatever way is appropriate. For example, when your desk accessory becomes active, it might install its menu in the menu bar.
The Event Manager periodically sends the
- Note
- If your desk accessory window is a modeless dialog box and you are calling the Dialog Manager function
IsDialogEvent
in response to the event, you should set thewindowKind
field of your window record to 2 before you callIsDialogEvent
. Setting this field to 2 allows the Dialog Manager to recognize and handle the event properly. You should restore the original value of thewindowKind
field before returning from your control routine.accRun
message if your desk accessory has requested time for background processing. To request this service, you set thedNeedTime
flag in thedrvrFlags
field of your desk accessory driver header. See "Writing Control and Status Routines," beginning on page 1-34, for more information.The
accCursor
message makes it possible to change the shape of the cursor when it is inside your desk accessory window and your desk accessory window is active. Your control routine should check whether the mouse location is in your window and, if so, should set the cursor appropriately by calling the QuickDraw functionInitCursor
.If your desk accessory window is a dialog box, you should respond to the
accCursor
message by generating a null event (storing the event code for a null event in an event record) and passing it to the Dialog Manager functionDialogSelect
. This allows the Dialog Manager to blink the insertion point ineditText
items.When the Event Manager sends an
accMenu
message, it provides the menu ID followed by the menu item number in thecsParam
field. You should take the appropriate action and then call the Menu Manager functionHiliteMenu
with a value of 0 for themenuID
parameter to remove the highlighting from the menu bar.You should respond to the last five messages,
accUndo
throughaccClear
, by processing the corresponding editing command in the desk accessory window, if appropriate. The chapter "Scrap Manager" in Inside Macintosh: More Macintosh Toolbox contains information about cutting and pasting.Your desk accessory routines should restore the current resource file and graphics port if it changes either one.
Subtopics
- How Desk Accessories Work
- Creating a Driver Resource for a Desk Accessory
- Opening and Closing a Desk Accessory
- Responding to Events