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 5 - Control Manager / Control Manager Reference
Application-Defined Routines / Defining Your Own Control Definition Function


MyControl

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:

FUNCTION MyControl (varCode: Integer; theControl: ControlHandle;
                     message: Integer; param: LongInt): LongInt;
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.
         CONST drawCntl       = 0;  {draw the control or its part}
               testCntl       = 1;  {test where mouse button }
                                    { is pressed}
               calcCRgns      = 2;  {calculate region for }
                                    { control or indicator in }
                                    { 24-bit systems}
               initCntl       = 3;  {peform any additional }
                                    { control initialization}

               dispCntl       = 4;  {perform any additional }
                                    { disposal actions}
               posCntl        = 5;  {move indicator and }
                                    { update its setting}
               thumbCntl      = 6;  {calculate parameters for }
                                    { dragging indicator}
               dragCntl       = 7;  {perform any custom dragging }
                                    { of control or its indicator}
               autoTrack      = 8;  {execute action procedure }
                                    { specified by your function}
               calcCntlRgn    = 10; {calculate region for control}
               calcThumbRgn   = 11; {calculate region for }
                                    { indicator}
param
A value whose meaning depends on the operation specified in the message parameter.
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.

Drawing the Control or Its Part

When the Control Manager passes the value for the drawCntl constant in the message parameter, the low word in the param parameter has one of the following values:

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.

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 application 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.

Testing Where the Mouse-Down Event Occurs

To request your control definition function to determine whether a specified point is
in a visible control, the FindControl function sends the value for the testCntl constant in the message parameter. In this case, the param parameter specifies a point (in coordinates local to the control's window) as follows:

When passed the value for the testCntl constant in the message parameter, your control definition function should return the part code of the part that contains the specified point; it should return 0 if the point is outside the control or if the control
is inactive.

Calculating the Control and Indicator Regions

When the Control Manager passes the value for the calcCRgns constant in the message parameter, your control definition function should calculate the region occupied by either the control or its indicator. The Control Manager passes a QuickDraw region handle in the param parameter; it is this region that you calculate. If the high-order bit of param is set, the region requested is that of the control's indicator; otherwise, the region requested is that of the entire control. Your control definition function should clear the high bit of the region handle before calculating the region.

When the Control Manager passes the value for the calcCntlRgn constant in the message parameter, your control definition function should calculate the region passed in the param parameter for the specified control. When the Control Manager passes the value for the calcThumbRgn constant, calculate the region occupied by the indicator.

When passed the values for the calcCRgns, calcCntlRgn, and calcThumbRgn constants, your control definition function should always return 0, and it should express the region in the local coordinate system of the control's window.

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.

Performing Any Additional Initialization

After initializing fields of a control record as appropriate when creating a new control, the Control Manager passes initCntl in the message parameter to give your control definition function the opportunity to perform any type-specific initialization you may require. For example, if you implement the control's action procedure in its control definition function, you'll need to store Pointer(-1) in the contrlAction field of the control's control record. Then, in a call to TrackControl for this control, you would pass Pointer(-1) in the actionProc parameter of TrackControl.

The standard control definition function for scroll bars allocates space for a region to hold the scroll box and stores the region handle in the contrlData field of the new control record.

When passed the value for the initCntl constant in the message parameter, your control definition function should ignore the param parameter and return 0 as a
function result.

Performing Any Additional Disposal Actions

The DisposeControl procedure passes dispCntl in the message parameter to give your control definition function the opportunity to carry out any additional actions when disposing of a control. For example, the standard definition function for scroll bars releases the memory occupied by the scroll box region, whose handle is kept in the contrlData field of the control's control record.

When passed the value for the dispCntl constant in the message parameter, your control definition function should ignore the param parameter and return 0 as a
function result.

Moving the Indicator

When a mouse-up event occurs in the indicator of a control, the TrackControl function calls your control definition function and passes posCntl in the message parameter. In this case, the param parameter contains a point (in coordinates local to the control's window) that specifies the vertical and horizontal offset, in pixels, by which your control definition function should move the indicator from its current position. Typically, this is the offset between the points where the cursor was when the user pressed and released the mouse button while dragging the indicator. The offset point is specified as follows:

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.

Calculating Parameters for Dragging the Indicator

When the Control Manager passes the value for thumbCntl in the message parameter, your control definition function should respond by calculating values (analogous to
the limitRect, slopRect, and axis parameters of DragControl) that constrain
how the indicator is dragged. The param parameter contains a pointer to the following data structure:

RECORD
   limitRect,slopRect:  Rect;
   axis:                Integer;
END;
On entry, the field param^.limitRect.topLeft contains the point where the mouse-down event first occurred. Your definition function should store the appropriate values into the fields of the record pointed to by param; they're analogous to the similarly named parameters to the Window Manager function DragGrayRgn.

Performing Custom Dragging

The Control Manager passes dragCntl in the message parameter to give your control definition function the opportunity to specify its own method for dragging a control (or its indicator).

The param parameter specifies whether the user is dragging an indicator or the
whole control:

If you want to use the Control Manager's default method of dragging (which is to call DragControl to drag the control or the Window Manager function DragGrayRgn to drag its indicator), return 0 as the function result for your control definition function.

If your control definition function returns any nonzero result, the Control Manager does not drag your control, and instead your control definition function must drag the specified control (or its indicator) to follow the cursor until the user releases the mouse button, as follows:

Executing an Action Procedure

You can design a control whose action procedure is specified by your control definition function. When you create the control, your control definition function must first respond to the initCntl message by storing Pointer(-1) in the contrlAction field of the control's control record. (As previously explained, the Control Manager sends the initCntl message to your control definition function after initializing
the fields of a new control record.) Then, when your application passes Pointer(-1)
in the actionProc parameter to the TrackControl function, TrackControl
calls your control definition function with the autoTrack message. The param parameter specifies the part code of the part where the mouse-down event occurs.
Your control definition function should then use this information to respond as an action procedure would.

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-84; creating an action procedure is described in the next section.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
11 JUL 1996