Important: The information in this document is obsolete and should not be used for new development.
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 namedMyControl:
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
messageparameter.DESCRIPTION
The Control Manager calls your control definition function under various circumstances; the Control Manager uses themessageparameter to inform your control definition function what action it must perform. The data that the Control Manager passes in theparamparameter, 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 themessageparameter. The rest of this section describes how to respond to the various values that the Control Manager passes in themessageparameter.Drawing the Control or Its Part
When the Control Manager passes the value for thedrawCntlconstant in themessageparameter, the low word in theparamparameter has one of the following values:
- the value 0, indicating the entire control
- the value 129, signifying an indicator that must be moved
- any other value, indicating a part code for the control (Don't use part code 128, which is reserved for future use, or part code 129, which the Control Manager uses to signify an indicator that must be moved.)
If the specified control is visible, your control definition function should draw the control (or the part specified in the
- Note
- For the
drawCntlmessage, the high-order word of theparamparameter may contain undefined data; therefore, evaluate only
the low-order word of this parameter.![]()
paramparameter) within the control's rectangle. If the control is invisible (that is, if itscontrlVisfield 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
contrlHiliteandcontrlValuefields 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 theSetControlValue,SetControlMinimum, andSetControlMaximumprocedures, 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 inparam, 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
drawCntlconstant in themessageparameter, 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, theFindControlfunction sends the value for thetestCntlconstant in themessageparameter. In this case, theparamparameter specifies a point (in coordinates local to the control's window) as follows:
When passed the value for the
- The point's vertical coordinate is contained in the high-order word of the long integer.
- The point's horizontal coordinate is contained in the low-order word.
testCntlconstant in themessageparameter, 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 thecalcCRgnsconstant in themessageparameter, 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 theparamparameter; it is this region that you calculate. If the high-order bit ofparamis 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
calcCntlRgnconstant in themessageparameter, your control definition function should calculate the region passed in theparamparameter for the specified control. When the Control Manager passes the value for thecalcThumbRgnconstant, calculate the region occupied by the indicator.When passed the values for the
calcCRgns,calcCntlRgn, andcalcThumbRgnconstants, 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
calcCRgnsconstant when the 24-bit Memory Manager is in operation. When the 32-bit Memory Manager is in operation, the Control Manager instead passes thecalcCntlRgnconstant or thecalcThumbRgnconstant. 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 passesinitCntlin themessageparameter 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 storePointer(-1)in thecontrlActionfield of the control's control record. Then, in a call toTrackControlfor this control, you would passPointer(-1)in theactionProcparameter ofTrackControl.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
contrlDatafield of the new control record.When passed the value for the
initCntlconstant in themessageparameter, your control definition function should ignore theparamparameter and return 0 as a
function result.Performing Any Additional Disposal Actions
TheDisposeControlprocedure passesdispCntlin themessageparameter 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 thecontrlDatafield of the control's control record.When passed the value for the
dispCntlconstant in themessageparameter, your control definition function should ignore theparamparameter and return 0 as a
function result.Moving the Indicator
When a mouse-up event occurs in the indicator of a control, theTrackControlfunction calls your control definition function and passesposCntlin themessageparameter. In this case, theparamparameter 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
- The point's vertical offset is contained in the high-order word of the
paramparameter.- The point's horizontal offset is contained in the low-order word.
given offset and then, to reflect the new setting, redraw the control and update thecontrlValuefield in the control's control record. Your control definition function should ignore theparamparameter and return 0 as a function result.Note that the
SetControlValue,SetControlMinimum, andSetControlMaximumprocedures do not call your control definition function with theposCntlmessage; instead, they pass thedrawCntlmessage.Calculating Parameters for Dragging the Indicator
When the Control Manager passes the value forthumbCntlin themessageparameter, your control definition function should respond by calculating values (analogous to
thelimitRect,slopRect, andaxisparameters ofDragControl) that constrain
how the indicator is dragged. Theparamparameter contains a pointer to the following data structure:
RECORD limitRect,slopRect: Rect; axis: Integer; END;On entry, the fieldparam^.limitRect.topLeftcontains 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 byparam; they're analogous to the similarly named parameters to the Window Manager functionDragGrayRgn.Performing Custom Dragging
The Control Manager passesdragCntlin themessageparameter to give your control definition function the opportunity to specify its own method for dragging a control (or its indicator).The
paramparameter 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
- A value of 0 means the user is dragging the entire control.
- Any nonzero value means the user is dragging only the indicator.
DragControlto drag the control or the Window Manager functionDragGrayRgnto 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:
- If the user drags the entire control, your definition function should use the
MoveControlprocedure to reposition the control to its new location after the user releases the mouse button.- If the user drags the indicator, your definition function must calculate the control's new setting (based on the pixel offset between the points where the cursor was when the user pressed and released the mouse button while dragging the indicator) and then, to reflect the new setting, redraw the control and update the
contrlValuefield in the control's control record. Note that, in this case, theTrackControlfunction returns 0 whether or not the user changes the indicator's position. Thus, you must determine whether the user has changed the control's setting, for instance, by comparing the control's value before and after the call toTrackControl.
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 theinitCntlmessage by storingPointer(-1)in thecontrlActionfield of the control's control record. (As previously explained, the Control Manager sends theinitCntlmessage to your control definition function after initializing
the fields of a new control record.) Then, when your application passesPointer(-1)
in theactionProcparameter to theTrackControlfunction,TrackControl
calls your control definition function with theautoTrackmessage. Theparamparameter 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
autoTrackmessage, the high-order word of theparamparameter 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
TheTrackControlfunction is described on page 5-84; creating an action procedure is described in the next section.