• Aucun résultat trouvé

Basic Theory and Structure

Dans le document TURBO THE (Page 128-131)

Let's start off by. looking at the overall format of a desk accessory, much as we looked at the overall format of a Mac application back in Chapter 9. Here's how your source file might be laid out:

program ThisDeskAcc;

{$D PasDeskAcc}

{$U-}

uses <whatever units>;

procedure Open(var Device: dCtlEntry); forward;

procedure Control(var Device: dCtlEntry; Param: LongInt; Code: Integer);

forward;

procedure Close{var Device: dCtIEntry);

forward

{ Global constants and data types } { Support procedures and functions } { Body of Open, Control, and Close procedures } begin end.

The Open, Control, and Close procedures must be the first three procedures declared in the desk accessory program. They may have other names, but they must be declared in the above order and with the above parameter lists.

• Open This procedure is called when the desk accessory is launched. It should do all the initialization: windows, menus, and so on.

• Control This procedure is called each time the system wants the desk acces-sory to do something: respond to an event or handle a timer update, for ex-ample.

• Close This procedure is called when the desk accessory is shut down. It closes up and disposes of the various items: windows, menus, and so on.

One easy solution to ensuring that these routines are the first three is to declare them all forward at the start of your program, then have their bodies located later on. That allows them to call one another, and also allows them to share other procedures and functions located between their declarations and their implementations.

As you can see, the desk accessory structure is not unlike that of a standard Mac application,. with procedures for initialization, event-handling, and cleanup.

Unlike an application, though, a desk accessory has no main body; instead, the operating system makes all the appropriate calls to these routines. More accu-rately, the current application-be it the FINDER or some other program-makes the appropriate calls.

Remember the discussion on supporting desk accessories back in Chapter 9?

When a desk accessory (DA) is selected from the Apple menu, the application currently running launches it by calling OpenDeskAcc, which instructs the oper-ating system (OS) to load that DA into memory and then call its Open procedure.

When the application calls System Task-as it should in its main loop and, for that matter, any other persistent loop-the operating system can then check to see if it needs to call the DA's Control procedure. Finally, when the application calls C loseDeskAcc, the OS issues the call to the DA's Close procedure, then purges it from memory. Likewise, when the application itself is finished, the OS issues calls to the Close procedure on any DAs still running (though it is possible to write a DA that continues to run after you exit an application).

108 Turbo Pascal for the Macintosh

Like an application, a desk accessory needs to handle most of the usual events-mouse down, key down, auto key, activate, update-and may have to provide support for windows, dialogs, and menus. As you might suspect, how-ever, there are significant differences in event handling between desk accessories and applications. There are three major differences. First, many events do not have to be handled by the desk accessory at all, since the application takes care of them. For example, the mouse-down event in a DA usually just has to do with an in-content event. Other events, such as the drag bar and Close box"are handled by the application.

Second, other events are predigested by the operating system. Instead of han-dling the in-menu-bar version of the rrwuseDown event, the DA receives a code from the OS telling it that a menu item has been selected, along with the menu and item values.

This is taken one step further with editing commands: When an application calls SystemEdit, passing to it a value in the set [1,3,4,5,6] (which correspond to the commands Undo, Cut, Copy, Paste, and Clear, respectively), the operating system calls the Control procedure with that specific information, so that the DA already knows which command has been selected.

Third, a desk accessory has to respond to certain events that an application doesn't. For example, a DA can tell the operating system that it needs to be called periodically, such as once per second .. The OS then issues those periodic calls-in addition to whatever other events might occur-telling the DA this is its periodic timed event, and the DA should do whatever it needs to. For exam-ple, it may have been told to update a clock.

A desk accessory differs from an application in other ways as well. Perhaps the most significant is in the area of global variables: A DA doesn't have any. You can declare global constants, global data types, and global procedures and functions (in addition to Open, Control, and Close), but not global variables. This could be quite a hindrance, if there were no way around it. But, as you might guess, there is a workaround. The operating system passes the same data structure-a record of type dCtlEntry-to all three routines. One of the fields in that record, dCtlStorage, can be used as a handle (a double pointer, remember?) to a chunk of memory that holds whatever «global" data you need to be passed from Open to Control to Close, or that you need to be preserved between calls to Control.

The fact that a desk accessory cannot have global variables also means that a DA may not use any units that depend upon global variables. In,particular, this means that the PaslnOut, PasConsole, and PasPrinter units cannot be used by a DA, since these units declare and use global variables (such as the Input and Output files). The QuickDraw unit also declares global variables (thePort and arrow, for example), but as an exception to the rule, you may use QuickDraw as long as you don't refer to any of those variables in your DA.

Other differences and limitations exist. A desk accessory has to fit into a single segment, which restricts it to 32K. (Inside Macintosh suggests an 8K limit, but this is due to historical reasons, namely. the limited memory on the earliest Macs.) In addition, a DA shouldn't have more than one menu and one window for itself, although again exceptions are possible.

A comment on desk accessory design: A desk accessory is, by nature, mode-less. It runs concurrently with whatever application happens to be going on at the time, and you can usually switch back and forth between them. By the usual event handling, a DA can tell when it has been activated or deactivated, that is, when its window has been made the active one. Your design needs to accommo-date this and to make sure (as far as is possible) that your DA doesn't seriously interfere with whatever application might be running at the time.

Dans le document TURBO THE (Page 128-131)