Previous Book Contents Book Index Next

Inside Macintosh: Programmer's Guide to MacApp / Part 1 - MacApp Theory and Architecture
Chapter 8 - Displaying, Manipulating, and Printing Data

Dialog Boxes and Controls

A dialog box is a special type of window used in Macintosh applications to display information and receive input from the user. A control is a user interface item, such as a radio button or checkbox, that commonly appears in a dialog box.

In MacApp, a dialog box is just another type of window, containing its own hierarchy of views. MacApp supplies the TDialogView class for building a dialog box, as well as a number of view classes to represent Macintosh Control Manager controls, such as buttons and checkboxes. The TDialogView class automatically creates a TDialogBehavior object to supply dialog-box behavior. The dialog behavior object works with the dialog view to validate view data when the dialog box is closed.

MacApp also provides a behavior class that supports tabbing between fields. This behavior works in any window but is most commonly used in dialog boxes. The tabbing support allows a data-entry view to validate its data when a user tabs to another field. Tabbing is described in "Tabbing Between Views," beginning on page 243.

As with other windows in MacApp, you can use a view resource to define a window and view hierarchy for a dialog box. You can then create the window with NewTemplateWindow and display it as either a modal or modeless dialog box.

Modal Versus Modeless Dialog Boxes

A modal dialog box is one that, once opened, does not allow a user to perform any other program task until the dialog has been dismissed. A modeless dialog box is one that does not interfere with other program operations--for example, it may be open in the background while a user works in a different window. Modal and modeless dialog boxes may be similar in appearance--for example, both may contain buttons and text-entry fields, have a title bar, and be movable.

A modal dialog box usually has one or more buttons that serve as dismissers, such as an OK button and a Cancel button. The user clicks the OK button to dismiss the dialog and accept its action. The user clicks the cancel button to dismiss the dialog without accepting any changes. If the user types Command-period or presses the Escape key, the result is the same as clicking the Cancel button--that is, the dialog is dismissed without any changes.

A modeless dialog box may also include buttons, but is commonly dismissed by clicking its close box.

The default button is indicated by a 3-pixel black border. Pressing the Return key specifies the same action as clicking the default button and normally dismisses the dialog box. Depending on the function performed by the dialog, the default button may be the OK button, the Cancel button, or another button.

Creating a Dialog Box

MacApp uses the TDialogView class for both modal and modeless dialog boxes. TDialogView is not a large or complicated class. Its main contributions are to supply fields that identify the default and cancel views in a dialog box and to call the SetDialogItems method of its window from its DoPostCreate method. The SetDialogItems method creates a TDialogBehavior object and adds it to the window's behavior list. When you construct a view hierarchy for a dialog box, you use a TDialogView object as the superview for the dialog box's control-item views.

You typically define a subclass of TDialogView to

If you override the DoPostCreate method in a subclass of TDialogView, your version should call Inherited, which calls the window's SetDialogItems method to create a dialog behavior for the view. If your DoPostCreate method doesn't call Inherited, it should either call its window's SetDialogItems method, or supply its window with a dialog behavior directly.

Displaying a Modal Dialog

The TDialogBehavior class handles certain tasks that are most commonly required of a modal dialog, including

The PoseModally method sets the behavior's fModal field to TRUE and processes events in its own event loop until the dialog box is dismissed. You can use a view-editing program to define any control item in the dialog window as a dismisser. When PoseModally processes an event from a dismisser control, it terminates its event loop and returns control to the caller. The return value of PoseModally is the ID of the item that caused the dismissal.

When you call PoseModally to display a dialog window modally, you must call the window's Close method after the dialog box is dismissed.

Adding Controls to Dialog Boxes

Most of the items in a dialog box are controls such as buttons, checkboxes, and text-entry fields. MacApp defines the TControl class, a descendant of TView, for creating these kinds of items. Each control object has these properties:

Control View Classes

MacApp defines subclasses of TControl to support standard control items:

Implements a Control Manager button
Implements a Control Manager checkbox
Implements a Control Manager radio button
Implements a Control Manager scroll bar
Subclass of TScrollBar that is associated with one or more TScroller view objects
Provides a label for a group of controls; understands an mRadioHit message from a subview and therefore can respond to a mouse click on a radio button by turning off all other radio buttons in the cluster
Displays an icon; can operate as a button, if desired
Displays a picture; can operate as a button, if desired
Implements a pop-up menu
Implements a static text item that can serve as a basic form of button if enabled, but whose text cannot be edited
Implements a text item that can be edited
Implements a view to accept and validate numeric data
You can read more about these classes in the MacApp Class and Method Reference.

Control Object Events

When a user clicks in a control view, MacApp calls the control view object's DoEvent method. The interface to this method is defined as follows:

virtual void DoEvent(EventNumber eventNumber,
                  TEventHandler* source,
                  TEvent* event  );
The eventNumber parameter is the ID of the event. Constants for control object event numbers are defined in the UMacAppGlobals unit. Some examples are

const EventNumber mOKHit = 1; // Click OK button.
const EventNumber mCancelHit = 2;// Click Cancel button.
const EventNumber mButtonHit = 3;// Click any button.
const EventNumber mCheckBoxHit = 4;// Click checkbox.
Table 19-1 contains a more complete listing of these event constants, and Chapter 19, "Working With Dialog Boxes and Controls," provides recipes for processing the specified events.

Tabbing Between Views

MacApp provides the TMultiWindowTabber behavior class to support tabbing between views. It supports tabbing within any view, not just views based on TDialogView. The TMultiWindowTabber class is called multiwindow because it operates correctly in an environment with multiple windows open, including any number of floating windows. Multiwindow does not refer to support for tabbing between views in multiple windows, because that is not a standard feature of the Macintosh user interface.

The IApplication method creates an instance of TMultiWindowTabber and adds it to the application object's behavior list. You don't need to create your own tabber behavior objects--the application's tabber object will support correct tabbing in your dialog views or other views.

Tabbing is accomplished by iterating over a view's list of subviews, looking for the current target and the next subview that wants to become the target object. The order of tabbing depends on the order of the subviews in the list.

The TMultiWindowTabber class descends from the TTabber class. TTabber is an abstract behavior class that intercepts the Tab key and calls its own Tab method. The Tab method calls FindTargets, which does nothing in TTabber but is overridden in TMultiWindowTabber. If you need specialized tab handling, you can define your own subclass of either TTabber or TMultiWindowTabber.

MacApp also provides the TLetterTabber class for tabbing between the mailer view and the main content view of a document with an attached mailer. TLetterTabber is described in "PowerTalk Mailers," beginning on page 192.

Validating Dialog-Box Data

If your application uses a dialog box for data entry, you may need to validate data when the user attempts to move from one entry field to another or when the user attempts to close the dialog box.

Validating Data When a User Changes Fields in a Dialog Box

When a user attempts to change the field in a dialog box by tabbing or by clicking the mouse, MacApp calls BecomeTarget, a method of TEventHandler, to set the new target object. Data validation occurs as part of the process of setting a new target object.

The BecomeTarget method calls the ResignTarget method of the current target object. For a TEditText view or a TNumberText view, this results in a call to the view's GetValidationError method, which validates the current data.

If the data in the field is invalid, GetValidationError returns a nonzero value. For a TEditText view or a TNumberText view, this results in a call to the view's ValidationFailed method, which notifies the user of the invalid data.

To clarify the previous discussion, some method calls were omitted.
When you define a subclass of MacApp's TEditText or TNumberText classes, you can override GetValidationError to do special checking and override ValidationFailed to put up the desired error alert.

Validating Data When a User Accepts Changes to a Dialog Box

When a user accepts changes to a modal data-entry dialog box, usually by clicking the OK button, the TDialogBehavior object's Dismiss method is called. This method calls the dialog view's IsHierarchyValid method.

The IsHierarchyValid method calls the IsValid method for each subview in the hierarchy. The IsValid method in turn calls GetValidationError, which is described in the previous section. Thus each control view in the dialog's view hierarchy has a chance to validate its data. If GetValidationError returns a nonzero value, IsValid calls ValidationFailed, which is also described in the previous section.

Good program design calls for a minimum of modal dialogs, and your application may often use a modeless dialog for data entry. To validate data when a user closes a modeless dialog, you can subclass TDialogView and override the Close method to call IsHierarchyValid directly, as shown in this code fragment from the DemoDialogs sample application:

void TMonthlyDialog::Close()// Override.
   // Give text-entry fields a chance to validate their data.
   if (this->IsHierarchyValid())
      // Store validated data. (Not shown.)
      // Perform other closing tasks.
      // Silent failure--don't close dialog box.
      Failure(noErr, 0);
When IsHierarchyValid returns FALSE, the dialog field with the invalid data has already displayed an error message, if appropriate, telling the user why the data is invalid. The call to Failure ensures that the modeless dialog box is not closed. MacApp's failure handling is described in Chapter 3, "Core Technologies."

Previous Book Contents Book Index Next

© Apple Computer, Inc.
25 JUL 1996