Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Macintosh Toolbox Essentials /
Chapter 6 - Dialog Manager / Using the Dialog Manager


Using an Application-Defined Item to Draw the Bold Outline
for a Default Button

You can define your own type of item for dialog boxes. You might wish, for example,
to display a clock with the current time in a dialog box. You can also use application- defined items to draw a bold outline around the default button in a dialog box.

You should not use application-defined items in an alert box because they add unnecessary programming complications. If you need an application-defined item,
use a dialog box instead.

To define your own item, include an item of type UserItem in your item list resource;
it should have a display rectangle, but no text and no resource ID associated with
it. The dialog resource that uses this item list resource must specify the invisible constant. This makes the dialog box invisible while you install a draw procedure for your application-defined item. After installing the procedure that draws the application- defined item, you display the dialog box by using the Window Manager procedure ShowWindow.

For example, Figure 6-32 on page 6-48 illustrates a dialog box that outlines the default button (Spell Check). To outline the button, the application must add an item of type UserItem to the item list resource for that dialog box.

So that an application-defined drawing procedure can draw a border around the Spell Check button, the item list resource in Listing 6-15 specifies a larger display rectangle for the application-defined item than for the Spell Check button.

Listing 6-15 Rez input for an application-defined item in an item list

resource 'DITL' (kSpellCheckDITL, purgeable) {
   /*ITEM NO. 1: OK button--the default*/
   {  {123, 170, 144, 254}, Button {enabled,"Spell Check"},
   /*ITEMs 2-5 go here: Cancel button, two checkboxes, and static text*/
   /*ITEM NO. 6: application-defined item*/
      {115, 164, 152, 260},   /*6th item*/
      UserItem {              /*draw procedure for item draws an outline*/
            disabled,         /*1st item lies inside this--1st is enabled*/ 
      }
   }
};
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-49 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:

PROCEDURE MyDrawDefaultButtonOutline (theDialog: DialogPtr; 
                                       theItem: Integer);
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.)

To install this draw procedure, use the GetDialogItem and SetDialogItem procedures. Use GetDialogItem to return a handle to the application-defined item specified in the item list resource. Then use SetDialogItem to replace this handle
with a pointer to your draw procedure. When calling your draw procedure, the Dialog Manager sets the current port to the dialog box's graphics port. The Dialog Manager then calls your procedure to draw the application-defined item as necessary--for instance, when you display the dialog box and whenever the Dialog Manager receives an update event for the dialog box.

Listing 6-16 illustrates how to install the procedure that draws a bold outline. In this listing, GetDialogItem gets a handle to the application-defined item (which is
the sixth item in the item list resource from Listing 6-15). The procedure pointer @MyDrawDefaultButtonOutline, which is coerced to a handle, is then passed
to SetDialogItem, which sets the draw procedure into the dialog record.

Listing 6-16 Installing the draw procedure for an application-defined item

FUNCTION DisplayMyDialog (VAR theDialog: DialogPtr): OSErr;
VAR
   itemType:      Integer;
   itemHandle:    Handle;
   itemRect:      Rect;
   docWindow:     WindowPtr;
   event:      EventRecord;
BEGIN
   {begin by creating an invisible dialog box}
   theDialog := GetNewDialog(kSpellCheckID, NIL, Pointer(-1));
   IF theDialog <> NIL THEN
   BEGIN
      {get a handle to the application-defined item (i.e., userItem)}
      GetDialogItem(theDialog, kUserItem, itemType, itemHandle, itemRect);
      {install the drawing procedure for the application-defined item}
      SetDialogItem(theDialog, kUserItem, itemType, 
                    Handle(@MyDrawDefaultButtonOutline), itemRect);
      docWindow := FrontWindow;     {get the front window}
         {if there's a front window, deactivate it}
      IF docWindow <> NIL THEN 
         DoActivate(docWindow, FALSE, event);
      ShowWindow(theDialog);     {display the dialog box}
      MyAdjustMenus;             {adjust menus as needed}
      DisplayMyDialog := kSuccess;
   END
   ELSE DisplayMyDialog := kFailed;
   {call ModalDialog and handle events in dialog box here}
END;
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

PROCEDURE MyDrawDefaultButtonOutline(theDialog: DialogPtr; theItem: Integer);
CONST
   kButtonFrameInset =  -4;
   kButtonFrameSize =   3;
   kCntrActivate =      0;
VAR
   itemType:      Integer;    {returned item type}
   itemRect:      Rect;       {returned display rectangle}
   itemHandle:    Handle;     {returned item handle}
   curPen:        PenState;
   buttonOval:    Integer;
   fgSaveColor:   RGBColor;
   bgColor:       RGBColor;
   newfgColor:    RGBColor;
   newGray:       Boolean;
   oldPort:       WindowPtr;
   isColor:       Boolean;
   targetDevice:  GDHandle;
BEGIN
   {get the default button & draw a bold border around it}
   GetDialogItem(theDialog, kDefaultButton, itemType, itemHandle, itemRect);
   GetPort(oldPort);
   SetPort(ControlHandle(itemHandle)^^.contrlOwner);
   GetPenState(curPen);
   PenNormal;
   InsetRect(itemRect, kButtonFrameInset, kButtonFrameInset);
   FrameRoundRect(itemRect, 16, 16);
   buttonOval := (itemRect.bottom - itemRect.top) DIV 2 + 2;
   IF ((CGrafPtr(ControlHandle(itemHandle)^^.contrlOwner)^.portVersion) =
       kIsColorPort) THEN
      isColor := TRUE
   ELSE
      isColor := FALSE;
   IF (ControlHandle(itemHandle)^^.contrlHilite <> kCntrlActivate) THEN
   BEGIN    {control is dimmed, so draw gray default button outline}
      newGray := FALSE;
      IF isColor THEN
      BEGIN
         GetBackColor(bgColor);
         GetForeColor(fgSaveColor);
         newfgColor := fgSaveColor;
            {get the device on which this dialog box is displayed}
         targetDevice := 
                MyGetDeviceFromRect(ControlHandle(itemHandle)^^.contrlRect);
            {use the gray defined by the display device}
         newGray := GetGray(targetDevice, bgColor, newfgColor);
      END;
      IF newGray THEN
         RGBForeColor(newfgColor)
      ELSE
         PenPat(gray);
      PenSize(kButtonFrameSize, kButtonFrameSize);
      FrameRoundRect(itemRect, buttonOval, buttonOval);
      IF isColor THEN
         RGBForeColor(fgSaveColor);
   END
   ELSE  {control is active, so draw default button outline in black}
   BEGIN
      PenPat(black);
      PenSize(kButtonFrameSize, kButtonFrameSize);
      FrameRoundRect(itemRect, buttonOval, buttonOval);
   END;
   SetPenState(curPen);
   SetPort(oldPort);
END;
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 MyDrawDefaultButtonOutline uses this gray for outlining the dimmed default button. Otherwise, MyDrawDefaultButtonOutline uses the QuickDraw procedure PenPat to draw a gray outline on black-and-white monitors.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
11 JUL 1996