TweetFollow Us on Twitter

MACINTOSH C
MACINTOSH C: A Hobbyist's Guide To Programming the Mac OS in C
Version 2.3

© 2000 K. J. Bricknell

Go to Contents

(Chapter 7)

INTRODUCTION TO CONTROLS

A link to the associated demonstration program listings is at the bottom of this page



Introduction

Prior to the introduction of Mac OS 8 and the Appearance Manager, the system software provided for only a limited range of controls (specifically, buttons, checkboxes, radio buttons, pop-up menus, and scroll bars) and the creation and handling of these desktop objects was relatively simple and straightforward. Mac OS 8 and the Appearance Manager, however, ushered in a very wide range of additional controls, extended the capabilities of the old controls, and provided a generally richer control environment. The result is that the subject of controls is now considerably more involved; accordingly, this chapter constitutes an introduction to controls only and addresses only the more basic controls. All but one of the remaining controls will be addressed at Chapter 14 - More on Controls. The remaining control (the list box control) will be addressed at Chapter 20 - Lists and Custom List Definition Functions.

You can use the Control Manager to create and manage controls. An alternative method is to use the Dialog Manager to more easily create and manage controls in dialog boxes and alert boxes. In this latter case, the Dialog Manager works with the Control Manager behind the scenes. The creation and handling of controls in dialog boxes and alert boxes will be addressed at Chapter 8 - Dialogs and Alerts and in the demonstration program associated with Chapter 14 - More on Controls. The creation and handling areas of this chapter are limited to the use of the Control Manager to create and handle controls in document windows.

Every control you create must be associated with a particular window. All the controls for a window are stored in a control list, a handle to which is stored in the controlList field of the window's window structure.

Standard Controls

The term standard controls refers to controls whose control definition functions (see below) are provided by the system software. The term custom controls refers to controls that you provide yourself via a custom control definition function.

Historical Note

Prior to the introduction of Mac OS 8 and the Appearance Manager. It was often necessary to provide your own custom controls (for example, slider controls). However, the large range of controls now provided by the system software means that it is all but inconceivable that you will ever need to create a custom control. A further consideration is the matter of Appearance-compliance. All of the new and revised controls provided by the system are Appearance-compliant. A non-Appearance-compliant custom control will create visual disharmony on the desktop, a situation much to be avoided.

Available Appearance-Compliant Standard Controls

The complete range of available standard controls, all of which are Appearance-compliant, is as follows. . (Those control types and variants which existed prior to the introduction of Mac OS 8 and the Appearance Manager, and which have been revised so as to be Appearance-compliant, appear in light blue. Those control types and variants introduced with Mac OS 8 and the Appearance Manager appear in black. Those additional types and variants introduced with Mac OS 8.5 appear in dark blue.)

Control Description Variants
Push button A control that appears on the screen as a rounded rectangle with a title centred inside. When the user clicks a push button, the application performs the action described by the button's title. Button actions are usually performed instantaneously. Examples include completing operations defined by a dialog box and acknowledging an error message in an alert box. With title only.
With colour icon to left of title.
With colour icon to right of title.
Checkbox A control that appears onscreen as a small square with an accompanying title. A checkbox displays one of three settings: on (indicated by a checkmark inside the box), off, or mixed (indicated by a dash inside the box). Non-auto-toggling.
Auto-toggling
Radio button A control that appears onscreen as a small circle. A radio button displays one of three settings: on (indicated by a black dot inside the circle), off, or mixed (indicated by a dash inside the circle). A radio button is always a part of a group of related radio buttons in which only one button can be on at a time. Non-auto-toggling.
Auto-toggling
Scroll bar A control with which the user can change the portion of a document displayed within a window. A scroll bar is a light gray rectangle with scroll arrows at each end. Windows can have a horizontal scroll bar, a vertical scroll bar, or both. A vertical scroll bar lies along the right side of a window. A horizontal scroll bar runs along the bottom of a window. Inside the scroll bar is a rectangle called the scroll box. The rest of the scroll bar is called the gray area. The user can move through a document by manipulating the parts of the scroll bar. Without live feedback.
With live feedback.
Pop-up menu button A control that is used to display a menu elsewhere than in the menu bar. Fixed width.
Variable width.
Add resource.
Use window font.
Bevel button A button containing a self-descriptive icon, picture, text, or any combination of the three, that performs an action when pressed. With small bevel.
With normal bevel.
With large bevel.
The above with a pop-up menu either to the right or below.
Slider A control that displays a range of values, magnitudes, or positions. A horizontally- and vertically-mobile indicator is used to increase or decrease the value. Without live feedback.
With live feedback.
With tick marks.
With directional indicator.
With non-directional indicator.
Disclosure triangle A triangular control governing how items are displayed in a list. The disclosure triangle can point in two directions: right and down. When the disclosure triangle points to the right, one item is displayed in the list. When the arrow points downward, the original item and its subitems are displayed in the list. Right-facing.
Left-facing.
Right-facing, auto-tracking.
Left-facing, auto-tracking.
Progress indicator A control indicating that a lengthy operation is occurring. Two types of progress indicators can be used: an indeterminate progress indicator reveals that an operation is occurring but does not indicate its duration; a determinate progress indicator displays how much of the operation has been completed. (One variant only. However, the progress indicator can be made determinate or non-determinate via a call to SetControlData.)
Little arrows Up- and down-arrows accompanying a text box that contains a value, such as a date. Clicking the up arrow increases the value displayed. Clicking the down arrow decreases the value displayed. (One variant only.)
Asynchronous (or chasing) arrows A control which indicates through a simple animation that a background process is in progress. (One variant only.)
Tab A control that appears as a row of folder tabs on top of a pane. It allows multiple panes to appear in the same window. Normal.
Small.
Separator line A control that draws a vertical or horizontal line used to visually separate groups of controls. (One variant only.)
Primary group box A control that consists of a rectangular two-pixel-wide frame which may or may not contain a title. It is used to provide a well-defined area in a dialog box into which text, pictures, icons or other controls can be embedded. With text title.
With checkbox title.
With pop-up menu button title.
Secondary group box A control that consists of a rectangular one-pixel-wide frame which may or may not contain a title. It is used to provide a well-defined area in a dialog box into which text, pictures, icons or other controls can be embedded. With text title.
With checkbox title.
With pop-up menu button title.
Image well A control that is used to display non-text visual content on a white background surrounded by a rectangular frame. Without auto-tracking.
With auto-tracking.
Pop-up arrow A control that simply draws the pop-up glyph. Large, right-facing.
Large, left-facing.
Large, up-facing.
Large, down-facing.
Small, right-facing.
Small, left-facing.
Small, up-facing.
Small, down-facing.
Placard A rectangular control used as an information display. (One variant only.)
Clock A control that combines the features of little arrows and an edit text field into a control which displays a date and/or time. Displays hours, minutes.
Displays hours, minutes, seconds.
Displays date, month, year.
Displays month, year.
User pane A general purpose control which can be used as the root control for a window and as an embedder control in which other controls may be embedded. It can also be used to hook in callback functions for drawing, hit testing, etc. (One variant only.)
Edit text A control that appears as a rectangular box in which the user enters text to provide information to an application. For windows.
For dialog boxes.
For passwords.
Inline input.
Static text A control that displays static (unchangeable by the user) text labels in a window. (One variant only.)
Picture A control used to display pictures. Tracking.
Non-tracking.
Icon A control used to display icons. Tracking.
Non-tracking.
Icon suite, tracking.
Icon suite, non-tracking.
All icon types, tracking.
All icon types, non-tracking.
Window header A control that runs along the top of a window's content region and provides information about the window's contents. Window header.
Window list view header.
List box A control that combines a rectangular frame, scroll bar(s), and a scrolling list. Non-autosizing.
Autosizing.
Radio Group A control that implements a radio button group. (One variant only.)
Scrolling text box A control that implements a scrolling text box. Non-auto-scrolling.
Auto-scrolling.

Definition of the Term "Controls"

Prior to the introduction of Mac OS 8 and the Appearance Manager, a control was defined as an "on-screen objects which the user can manipulate to cause an immediate action or to change settings to modify a future action". Given this previous definition, the question arises as to why such objects as, for example, separator lines and window headers are now implemented as controls. On the surface, it may appear that these objects are purely visual entities.

Part of the answer to that question has to do with the matter of Appearance-compliance. For example, using the provided separator line "control" to draw separator lines will ensure that those lines are drawn with the correct appearance, in both the activated and deactivated modes, regardless of which Appearance theme has been chosen by the user.

Another part of the answer has to do with the concept of embedding (see below). The window header control, for example, is not just the visual entity it might at first appear to be; it is actually a control in which other controls may be embedded. (As will be seen, the ability to embed other controls is a powerful new feature of some of the new controls.)

Since many of the new controls are not really controls "which the user can manipulate", a more accurate blanket definition might now be "any element of the user interface that is implemented by a control definition function" (see below).

Controls Addressed in This Chapter

Of the controls listed above, only those which might be termed the basic controls (push buttons, checkboxes, radio buttons, scroll bars, and pop-up menu buttons), together with primary group boxes (text title variant) and user panes, will be addressed in this chapter and its associated demonstration programs. These controls, with the exception of the user pane (which is invisible), are illustrated at Fig 1.

(Basic controls and primary group box)

The Control Definition Function

A control definition function (CDEF) determines the appearance and behaviour of a control. Various Control Manager functions call a control's CDEF when they need to perform some control-related action. CDEFs are stored as resources of type 'CDEF'.

Just as a window definition function can describe variations of the same basic window, a CDEF can use a variation code to describe variations of the same control. You specify a particular control with a control definition ID, which is an integer containing the resource ID of the in the upper 12 bits and the variation code in the lower four bits.

The control definition ID is arrived at by multiplying the resource ID by 16 and adding the variation code. The following shows the control definition IDs for the standard controls and variants addressed in this chapter and its associated demonstration programs, together with the derivation of those IDs. (Those variants introduced with Mac OS 8.5 are shown in dark blue.)

CDEF
Resource ID
Variation
Code
Control Definition ID
(Value)
Control Definition ID
(Constant)
23 0 23 * 16 + 0 = 368 kControlPushButtonProc
23 4 23 * 16 + 4 = 374 kControlPushButLeftIconProc
23 5 23 * 16 + 5 = 375 kControlPushButRightIconProc
23 1 23 * 16 + 1 = 369 kControlCheckBoxProc
23 3 23 * 16 + 3 = 371 kControlCheckBoxAutoToggleProc
23 2 23 * 16 + 2 = 370 kControlRadioButtonProc
23 4 23 * 16 + 3 = 372 kControlRadioAutoToggleButtonProc
24 0 24 * 16 + 0 = 384 kControlScrollBarProc
24 2 24 * 16 + 2 = 386 kControlScrollBarLiveProc
25 0 25 * 16 + 0 = 400 kControlPopupButtonProc
25 1 25 * 16 + 1 = 401 kControlPopupButtonProc +
kControlPopupFixedWidthVariant
25 2 25 * 16 + 2 = 402 kControlPopupButtonProc +
kControlPopupVariableWidthVariant
25 4 25 * 16 + 4 = 404 kControlPopupButtonProc +
kControlPopupUseAddResMenuVariant
25 8 25 * 16 + 8 = 408 kControlPopupButtonProc +
kControlPopupUseWFontVariant
10 0 10 * 16 + 0 = 160 kControlGroupBoxTextTitleProc
16 0 16 * 16 + 0 = 256 kControlUserPaneProc

Historical Note

With regard to the basic controls, these are the resource IDs and variation codes of the new Appearance-compliant CDEFs first issued with Mac OS 8 and the Appearance Manager. The old CDEFs have resource IDs of 0 (button, checkbox, radio button), 1 (scroll bar), and 63 (pop-up menu), and remain in the System file. The new definition functions are located in the Appearance extension.

Note that the one CDEF caters for both horizontal and vertical scroll bars. The CDEF determines whether a scroll bar is vertical or horizontal from the rectangle you specify when you create the control.

The Basic Controls, Primary Group Boxes (Text Title Variant), and User Panes

Push Buttons

You normally use push buttons in alert boxes and dialog boxes. Push buttons typically allow the user to perform actions instantaneously, for example, completing the actions in a dialog box or acknowledging an error in an alert box. In every window or dialog box in which you display push buttons, you should designate one push button as the default push button, that is, the push button the user is most likely to click. (In modal and movable modal alert boxes, the Dialog Manager automatically outlines the default push button (see the default push button at Fig 1); however, your application must outline the push button in modeless dialog boxes.) Your application should respond to key-down events involving the Enter and Return keys as if the user had clicked the default push button.

Checkboxes

Checkboxes are typically used in dialog boxes so that the user can supply additional information necessary for completing a command. Checkboxes provide alternative choices and act like toggle switches, turning a setting on or off. Each checkbox has a title, which should reflect two clearly opposite states. If you cannot devise a title which clearly implies two opposite states, you might be better off providing two radio buttons.

Non-Auto-Toggling Variant

When the non-auto-toggling variant is being used, and when the user clicks a checkbox in the off state, your application should call SetControlValue to set the control to the on state and place a checkmark in the box (see Fig 1). When the user again clicks the checkbox, your application should call SetControlValue to set the control to the off state and remove the checkmark from the box.

SetControlValue may also be used to place a dash in the box to indicate that the control is in the mixed state (see Fig 1). The mixed state is a special state which indicates that a selected range of items has some in the on state and some in the off state. For example, a text formatting checkbox for bold text would be in the mixed state if a text selection contained both bold and non-bold text.

Historical Note

The mixed state was introduced with Mac OS 8 and the Appearance Manager.

Auto-Toggling Variant

When the auto-toggling variant is being used, checkboxes automatically changes between their various states (on, off, and mixed) in response to user actions. Your application need only call the function GetControl32BitValue to get the checkbox's new state. There is no need to programmatically change the control's value after tracking successfully.

Historical Note

The auto-toggling variant was introduced with Mac OS 8.5.

Radio Buttons

Like checkboxes, radio buttons retain and display an on or off setting and are typically used inside dialog boxes. Radio buttons represent choices that are related but not necessarily opposite. The user can have only one radio button setting in effect at one time; in other words, radio buttons within a group are mutually exclusive.

A group of radio buttons must comprise at least two radio buttons. Each group must have a label which identifies the kind of choices the group offers and each button must have a title identifying what the radio button does. If you need to display more than seven items, or if the items change as the context changes, you should use a pop-up menu button instead.

Non-Auto-Toggling Variant

When the non-auto-toggling variant is being used, and when the user clicks a radio button in the off state, your application should call SetControlValue to:

  • Set that control to the on state and place a black dot in its circle (see Fig 1).

  • Set the previously "on" button in the group to the off state and remove the black dot from its circle.
SetControlValue may also be used to place a dash in the circle to indicate that the control is in the mixed state (see Fig 1). The mixed state is a special state which shows that a selected range has a variety of items in the on state. For example, a set of radio buttons for selecting font size might have buttons representing 10- and 12-point sizes. If a passage of text with both 10- and 12-point text was selected, both the 10 and 12 buttons would appear in the mixed state.

Historical Note

The mixed state was introduced with Mac OS 8 and the Appearance Manager.

Auto-Toggling Variant

When the auto-toggling variant introduced with Mac OS 8.5 is being used, radio buttons automatically change between their various states (on, off, and mixed) in response to user actions. Your application need only call the function GetControl32BitValue to get the radio button's new state. There is no need to programmatically change the control's value after tracking successfully. P>

Historical Note

The auto-toggling variant was introduced with Mac OS 8.5.

Scroll Bars

Scroll bars change the portion of a document that the user can view within a document's window. A scroll bar is a light gray rectangle with scroll arrows at each end. Inside the scroll bar is a scroll box. The rest of the scroll box is called the gray area. If the user drags the scroll box, clicks a scroll arrow or clicks in the gray region, your application scrolls the document accordingly.

As previously stated, the CDEF for scroll bars supports two variants. The only difference between the two variants is that one supports live feedback and the other does not. In the case of scroll bars, live feedback (a generic term) may be used to perform live scrolling of a document in a window. Live scrolling means that, when the user attempts to drag the scroll box, the scroll box moves and the document scrolls as the user moves the mouse. (Without live scrolling, only a ghosted image of the scroll box moves. In addition, the document is only scrolled, and the scroll box proper is only redrawn at its new location, when the user releases the mouse button.)

Historical Note

The live feedback capability was introduced with Mac OS 8 and the Appearance Manager.

Scroll Arrows and Gray Area

When the scroll arrows are clicked, your application should move the scroll box the appropriate distance in the direction of the arrow being clicked and scroll the window contents accordingly. Each click should move the window contents one unit in the chosen direction. (In a text document, a unit would typically be one line of text.)

When the gray area is clicked above the scroll box, your application should move the document up so that the bottom line of the previous view is at the top of the new view, and it should move the scroll box accordingly. A similar, but downward movement, should occur when the user clicks in the gray area below the scroll box.

Scroll Box

Live Feedback Variant Not Used. When the live feedback variant is not being used, and when the user drags the scroll box, the Control Manager redraws the scroll box proper in its new position, and sets the control's value accordingly, when the user releases the mouse button. You must then ascertain the position (that is, the value) of the control box and, using this value, display the appropriate portion of the document.

Live Feedback Variant Used. When the live feedback variant is being used, and when the user drags the scroll box, the Control Manager continually redraws the scroll box, and continually returns the control's position (that is, its value) as the scroll box moves. Once again, your application uses this value to display the appropriate portion of the document.

Proportional Scroll Boxes

A proportional scroll box is one whose height (vertical scroll bars) or width (horizontal scroll bars) varies in relation to the height/width of the scroll bar so as to visually represent the proportion of the document visible in the window.

Under Mac OS 8.5 and later, if the user selects Smart Scrolling on in the Options tab in the Appearance control panel, your application's scroll boxes will appear as proportional scroll boxes provided that you pass the size of the view area, in whatever units the scroll bar uses, to the function SetControlViewSize. The system automatically handles resizing the scroll box once your application supplies this information.

Historical Note

Proportional scroll boxes were introduced with Mac OS 8.5.

The following functions, introduced with Mac OS 8.5, are relevant to proportional scroll boxes:

Function Description
GetControlViewSize Obtains the size of the content to which a control's size is proportioned.
SetControlViewSize Informs the Control Manager of the size of the content to which a control's size is proportioned.

Pop-Up Menu Buttons

Pop-up menu buttons provide the user with a simple way to choose from a list of choices. As an alternative to a group of radio buttons, a pop-up menu button is useful for specifying a group of settings or values that number five or more, or whose settings or values might change. Like the items in a group of radio buttons, the items in a pop-up menu button's menu should be mutually exclusive.

Primary Group Boxes (Text Title Variant)

A primary group box (text title variant) is a control that consists of a rectangular two-pixel-wide frame which may or may not contain a title. Group boxes are used to associate, isolate, and distinguish groups of related controls, such as a group of radio buttons.

The primary group box is an embedder control (see below), meaning that you can embed other controls, such as radio buttons, checkboxes, and pop-up menu buttons, within it.

User Panes

The user pane is unique amongst the family of controls in that it has no visual representation. It has two main uses:

  • Like the primary group box, it can be used as an embedder control, that is, other controls may be embedded within it.

  • It provides a way to hook in application-defined functions, known as user pane functions, which perform actions such as drawing, hit testing, etc.

Activating, Deactivating, Hiding, and Showing Controls

Activating and Deactivating Controls

A control can be either active or inactive. Whenever it is inappropriate for your application to respond to a mouse-down event in a control, you should make it inactive. The Control Manager continues to display inactive controls so that they remain visible, but in a dimmed state which indicates their inactive status to the user. The Control Manager displays inactive basic controls and inactive primary group boxes as shown at Fig 2.

(basic controls and primary group box in inactive mode)

Activating and Deactivating Controls Other Than Scroll Bars

You use ActivateControl and DeactivateControl to make push buttons, checkboxes, radio buttons, pop-up menu buttons and primary group boxes active and inactive. You should make these controls inactive when:

  • They are not relevant to the current context.

  • The window in which they reside is not the active window.
Your application can ascertain whether a control is currently active or inactive using IsControlActive.

Historical Note

Prior to Mac OS 8 and the Appearance Manager, the HiliteControl function was used for this purpose. HiliteControl has other uses for which it may still be used; however it should not now be used to activate and deactivate controls.

Activating and Deactivating Scroll Bars

Scroll bars become irrelevant to the current context when the document being displayed is smaller than the window in which it is being displayed. To make a scroll bar inactive in this case, you typically use SetControlMaximum to make the scroll bar's maximum value (see below) equal to its minimum value (see below), which causes the Control Manager to automatically make the scroll bar inactive and display it in the inactive state. To make the scroll bar active again, SetControlMaximum should be used to set its maximum value larger than its minimum value.

Hiding and Showing Controls

HideControl may be used to hide a control. HideControl erases a control by filling its enclosing rectangle with the owning window's background pattern.

ShowControl may be used to show a control. ShowControl makes the control visible and immediately draws the control within its window without using your window's standard updating mechanism.

SetControlVisibility may be used to both hide and show a control. With regard to showing a control, this function differs from ShowControl in that the option is available to "show" the control without redrawing it immediately.

Your application can ascertain whether a control is currently hidden or visible using IsControlVisible.

Historical Note

SetControlVisibility and IsControlVisible were introduced with Mac OS 8 and the Appearance Manager.

Visual Feedback From the Basic Controls

In response to a mouse-down event in a basic control, your application should call either TrackControl or HandleControlClick. These functions provide visual feedback when a mouse-down occurs in an active control by:

  • Displaying push buttons, checkboxes and radio buttons in their pressed mode.

  • Displaying and highlighting the items in pop-up menu buttons.

  • Highlighting the scroll arrows in scroll bars.

  • Moving the scroll box (live feedback variant of the scroll bar CDEF being used) or moving a ghosted image of the scroll box (live feedback variant not being used) when the user drags it.

Historical Note

HandleControlClick was introduced with Mac OS 8 and the Appearance Manager. It is identical to TrackControl except that it allows modifier keys to be passed in its third parameter. Some of the new controls, such as edit text fields and list boxes, require the ability for modifier keys to be passed in. If you use HandleControlClick with controls for which modifier keys are irrelevant, simply pass 0 in the inModifiers parameter.

Embedding Controls

In addition to providing a large number of additional control types, Mac OS 8 and the Appearance Manager introduced a richer environment for controls. The innovation of specific relevance to this chapter is control embedding. As previously stated, this involves the embedding of a control (or, more usually, a group of controls) in another control.

The Root Control

To embed controls in a window, you must first create a root control for that window. The root control, which is implemented as a user pane control, is the container for all other window controls and is at the base of what is known as the embedding hierarchy. In document windows, you create the root control by calling CreateRootControl. The root control may be retrieved by calling GetRootControl.

Once you have created a root control, new controls will be automatically embedded in the root control when they are created. One advantage of such embedding is that, when you wish to activate and deactivate all of the window's controls on window activation and deactivation, you can do so by simply activating and deactivating the root control. (If the root control did not exist, you would have to activate and deactivate all of the window's controls individually.) You can also hide and show all of the window's control by simply hiding and showing the root control.

Other Embedders

Certain other controls also have embedding capability. One such embedder control is the primary group box. This means that you can embed, say, a group of radio buttons in a primary group box (which would, in turn, be already automatically embedded in the root control), an arrangement which is illustrated conceptually at Fig 3. By acting on the group box alone, you can then activate, deactivate, hide, show, and move all four controls as a group.

(Root control and embedded controls)

EmbedControl may be used to embed a control in another (embedder) control. However, where the control to be embedded is visually contained by the embedder, as is the case with the radio buttons in Fig 3, AutoEmbedControl would be more appropriate.

Other Advantages of Embedding

Drawing Order

As controls are created by your application, they are added to the head of the window's control list. When those controls are drawn in the absence of an embedding hierarchy, the Control Manager starts from the top of the control list, drawing the controls in the opposite order to the order in which it they were created.

In the example at Fig 3, assume that there is no embedding hierarchy and that the radio buttons are created after the group box. This means that the group box will be drawn after the radio buttons, thus obscuring the radio buttons. An embedding hierarchy, however, enforces drawing order by drawing the embedding control before its embedded controls regardless of which is created first.

Hit Testing

Hit-testing is the process of testing whether a control is under the cursor at the time of a mouse-down event, and of identifying that control. For situations where controls are visually contained by other controls, an embedding hierarchy enforces orderly hit-testing by forcing an "inside-out" hit test aimed at determining the most deeply nested control that is hit by the mouse.

Latency

Latency pertains to the ability of the Control Manager to remember the activation and visibility status of an embedded control when its embedder is cycled between activated and deactivated, or between visible and hidden.

For example, assume that the radio button labelled White at Fig 3 has been separately deactivated by the application. When the primary group box is deactivated, the two remaining radio buttons will also be deactivated. When the primary group box is again enabled, the Control Manager remembers that the radio button labelled white was previously deactivated, and ensures that it remains in that mode.

Getting and Setting Control Data

Another refinement introduced with Mac OS 8 and the Appearance Manager was read and write access to the various attributes of a control. Essentially, this is a mechanism that allows the outside world to access a control's specialised data without exposing how that data is stored. It allows you to easily set and get control fonts, tell the push button CDEF to draw the default outline around a default push button, and many other useful things.

Each piece of information that a particular CDEF allows access to is referenced by a tag, which is a constant that is meaningful to the CDEF and which represents the data in question. Each tagged piece of data can be of any data type, such as a menu handle or a structure.

Control data tag constants are passed in the third parameter of the getter and setter functions SetControlData and GetControlData. The control data tag constants relevant to the basic controls are as follows:

Control Data Tag Constant Meaning and Data Type Returned or Set
kControlPushButtonDefaultTag Tells Appearance-compliant push buttons whether to draw a default ring, or returns whether the Appearance Manager has drawn a default ring, for the push button.

Data type returned or set: Boolean

kControlPushButtonCancelTag Gets or sets whether a given push button in a dialog or alert should be drawn with the appearance-specific adornments for a Cancel button.

Data type returned or set: Boolean. Default is false.

kControlPopupButtonMenuHandleTag Gets or sets the menu handle for a pop-up menu.

Data type returned or set: MenuHandle

kControlPopupButtonMenuIDTag Gets or sets the menu ID for a pop-up menu button.

Data type returned or set: SInt16

kControlPopupButtonExtraHeightTag Gets or sets the amount of extra white space in a pop-up menu button.

Data type returned or set: SInt16. Default is 0.

kControlGroupBoxTitleRectTag Get the rectangle that contains the title of a group box (and any associated control, such as a checkbox).

Data type returned or set: Rect

Historical Note

Calling SetControlData with the kControlPushButtonDefaultTag tag constant greatly simplifies the task of drawing the default ring around the default push button. Prior to Mac OS 8 and the Appearance Manager, your application had to provide its own function to do this.

kControlPushButtonCancelTag, kControlPopupButtonExtraHeightTag, and kControlGroupBoxTitleRectTag were introduced with Mac OS 8.5.

The Control Structure

The Control Manager stores information about a control in a control structure. A control structure is defined by the data type ControlRecord:

     struct ControlRecord 
     {
       ControlHandle     nextControl;   // Next Control.
       WindowPtr         contrlOwner;   // Control's window.
       Rect              contrlRect;    // Rectangle.
       UInt8             contrlVis;     // 255 if visible, else 0.
       UInt8             contrlHilite;  // Highlight state.
       SInt16            contrlValue;   // Current setting.
       SInt16            contrlMin;     // Minimum Setting.
       SInt16            contrlMax;     // Maximum setting.
       Handle            contrlDefProc; // Control definition function.
       Handle            contrlData;    // Data used by contrlDefProc.
       ControlActionUPP  contrlAction;  // Action function.
       SInt32            contrlRfCon;   // Reference constant.
       Str255            contrlTitle;   // Title.
     };
     typedef struct ControlRecord ControlRecord;
     typedef ControlRecord *ControlPtr;
     typedef ControlPtr *ControlHandle;

Creating Your Application's Basic Controls

You typically create controls from resources of type 'CNTL', though you can create controls programmatically using the function NewControl.

'CNTL' Resources

When creating resources with Resorcerer, it is advisable that you refer to a diagram and description of the structure of the resource and relate that to the various items in the Resorcerer editing windows. Accordingly, the following describes the structure of the 'CNTL' resource.

Structure of a Compiled 'CNTL' Resource

Fig 4 shows the structure of a compiled 'CNTL' resource and how it "feeds" the control structure.

('CNTL' resource)

The following describes the main fields of the 'CNTL' resource:

Field Description
INITIAL RECTANGLE The rectangle, specified in coordinates local to the window, that encloses the control and thus determines its size and location.
INITIAL VALUE The initial value for the control. (See Values for Controls, below).
VISIBILITY The visibility of the control. If this field contains the value true, GetNewControl draws the control immediately, without using the application's standard updating mechanism for windows. If this field contains false, the application may use ShowControl when it is prepared to display the control.
MAXIMUM VALUE The maximum value of the control. (See Values for Controls, below).
MINIMUM VALUE The minimum value for the control. (See Values for Controls, below).
CONTROL DEFINITION ID The control definition ID, which the Control Manager uses to determine the CDEF for the control. (See The Control Definition Function, above).
REFERENCE VALUE The control's reference value, which is set up and used only by the application (except when the control is the add resource variant of the pop-up menu button, in which case this field is used to specify the resource type).
TITLE For controls that need a title, the string for that title. For controls that do not need or do not use titles, an empty string.

Values For Controls

The following lists the initial, minimum, and maximum value settings for the basic controls and the primary group box:

Control Initial Value Minimum Value Maximum Value
Push button 0 0 1
Checkbox 0 (initially off), or
1 (initially on), or
2 (initially in mixed state).
0 1, or 2 if mixed state checkboxes are to be used.
Radio button 0 (initially off), or
1 (initially on), or
2 (initially in mixed state).
0 1, or 2 if mixed state radio buttons are to be used.
Scroll bar Whatever initial value is appropriate (between the minimum and maximum settings). Whatever minimum value is appropriate. (See Creating Scroll Bars, below.) The value must be between -32768 and 32768. Whatever maximum value is appropriate. (See Creating Scroll Bars, below.) The value must be between -32768 and 32768.

When the maximum setting is equal to the minimum setting, the CDEF makes the scroll bar inactive. When the maximum setting is greater than the minimum setting, the CDEF makes the scroll bar active.

Pop-up menu button A combination of values which instructs the Control Manager how to draw the control's title. (See Pop-up Menu Button Title Style Constants, below.) Resource ID of the 'MENU' resource. Width (in pixels) of the title. (See Pop-up Menu Button Title Width, below.)
Primary group box Ignored if the group box is the text title variant. Ignored if the group box is the text title variant. Ignored if the group box is the text title variant.

Note that the title of each of the three value fields is somewhat of a misnomer in the case of the pop-up menu button.

Creating 'CNTL' Resources Using Resorcerer

Fig 5 shows a 'CNTL' resource being created with Resorcerer.

(Creating a 'CNTL' resource)

Creating Controls

GetNewControl and NewControl are used to create new controls in a document window. You typically use GetNewControl, which takes a 'CNTL' resource ID and a pointer to the window, creates a control structure from the information in the resource, adds the control structure to the control list for your window, and returns a handle to the control.

If the 'CNTL' resource specifies that a control is initially visible, the Control Manager uses the CDEF to draw the control. (The Control Manager draws the control immediately and does not wait for the window updating mechanism.) If the 'CNTL' resource specifies that the control is to be initially invisible, ShowControl may be used to draw the control when required.

Note that when you use the Dialog Manager to implement push buttons, radio buttons, checkboxes or pop-up menu buttons in alert boxes or dialog boxes, Dialog Manager functions automatically use Control Manager functions to create the controls for you.

Creating Scroll Bars

The 'CNTL' resource for scroll bars should specify whether the live-feedback variant or the non-live-feedback variant is required. Within the 'CNTL' resource, you typically make the scroll bar invisible, set the initial, minimum and maximum settings to 0 and supply an empty string for the title.

After you create the window, use GetNewControl to create the scroll bar. Then use MoveControl, SizeControl, SetControlMaximum and SetControlValue to adjust the size, location and value settings. (For example, for a window displaying a text document, you would typically calculate the number of lines of text and set the vertical scroll bar's maximum value according to the line count and the window's current height. You would set the control's value according to the part of the document to be initially displayed.) Finally, use ShowControl to display the control bar.

Most applications allow the user to change the size of windows, add information to the document and remove information from the document. It is therefore necessary, in your window handling code, to calculate a changing maximum setting based on the document's current size and its window's current size. For new documents which have no content to scroll, assign an initial value of 0 as the maximum setting (which will, as previously stated, make the scroll bars inactive). Thereafter, your window-handling code should set and maintain the maximum setting.

By convention, a scroll bar for a document window is 16 pixels wide; accordingly, there should be a sixteen-pixel difference between the left and right coordinates of a vertical scroll bar's rectangle and between the top and bottom coordinates of a horizontal scroll bar. (If you do not specify a 16-pixel width, the Control Manager scales the scroll bar to fit the width you specify.) A standard scroll bar for a document window should be at least 48 pixels long to allow room for the scroll arrows and scroll box.

The Control Manager draws one-pixel lines for the rectangle enclosing the scroll bar. As shown at Fig 6, the outside lines of the scroll bar should overlap the inside lines of the window frame.

(Correct overlap of scroll bar)

The following calculations determine the rectangle for a vertical scroll bar for a document window:

Do not include the title bar area in these calculations.

Coordinate Calculation
Top Combined height of any items above the scroll bar - 1.
Left Width of window - 15.
Bottom Height of window - 14.
Right Width of window + 1.

The following calculations determine the rectangle for a horizontal scroll bar for a document window.

Coordinate Calculation
Top Height of window - 15.
Left Combined width of any items to the left of the scroll bar - 1.
Bottom Height of window + 1.
Right Width of window - 14.

The top coordinate of a vertical scroll bar and the left coordinate of a horizontal scroll bar is -1 unless your application uses part of the window's typical scroll bar area for displaying information or specifying additional controls.

Just as the maximum settings change when the user resizes a document's window, so too do the scroll bar's coordinate locations change when the user resizes the window. The initial maximum settings and location, as specified in the 'CNTL' resource, must therefore be changed dynamically by the application as required. Typically, this is achieved by storing handles to each scroll bar in an application-defined document structure associated with the window and then using Control Manager functions to change control settings.

Scroll Bars in Utility Windows. You can also use scroll bars in utility windows (see Fig 7). Size boxes in utility windows are 11-by-11 pixels, and the standard Appearance-compliant scroll bar can be made to fit into this space.

(Scroll bars in utility window)

Pop-up Menu Buttons

Pop-up Menu Button Title Style Constants

The constants and values for the initial value for pop-up menu buttons are as follows:

Constant Value Meaning
popupTitleBold 0x0100 Boldface font style
popupTitleItalic 0x0200 Italic font style
popupTitleUnderline 0x0400 Underline font style
popupTitleOutline 0x0800 Outline font style
popupTitleShadow 0x1000 Shadow font style
popupTitleCondense 0x2000 Condensed text
popupTitleExtend 0x4000 Extended text
popupTitleNoStyle 0x0800 Monostyle text

Pop-up Menu Button Title Width

Fig 8 shows the relationship between the title width and the enclosing rectangle of a pop-up menu box.

(Pop-up menu title width)

Menu Width Adjustment

If the base variant or the variable width variant is being used, and whenever the pop-up menu button is redrawn, the CDEF calls CalcMenuSize to calculate the size of the menu associated with the control. If the sum of the width of the title, the longest item in the menu, the arrows, and a small amount of "white space" is less than the width of the control rectangle, the width of the pop-up button will be reduced for drawing purposes (see Fig 7). If the calculated width is greater than the width of the control rectangle, the longer menu items will be truncated with an added ellipsis so that the drawn pop-up will not exceed the width of the control rectangle.

Menu Items and Control Values

When it creates the control, GetNewControl assigns the item number of the first menu item to the contrlValue field of the control structure and sets the contrlMax field to the number of items in the pop-up menu button. When the user chooses a different menu item, the Control Manager changes the contrlValue field to that item number.

Adding Resource Names as Items

If the add resource variant of the pop-up menu button is being used, the Control Manager coerces the value in the control structure's contrlRfCon field to the type ResType and then uses AppendResMenu to add items of that type. For example, if you specify FONT in the ResType item in the Resorcerer 'CNTL' resource editing window, the CDEF appends a list of fonts installed in the system to the menu specified at the 'MENU' ID item. Note that, after the control has been created, your application can use the contrlRfCon field for whatever purpose it requires.

Setting the Font of a Control's Title

You can set the font of any control's title independently of the system font or window font.

Historical Note

Prior to Mac OS 8 and the Appearance Manager, your only choices were the system font and, if the control had a variant that used it (as did the pop-up menu control), the window font.

To set the font of a control's title, you pass a pointer to a control font style structure in the inStyle parameter of the function SetControlFontStyle.

Control Font Style Structure

     struct ControlFontStyleRec 
     {
       SInt16    flags;
       SInt16    font;
       SInt16    size;
       SInt16    style;
       SInt16    mode;
       SInt16    just;
       RGBColor  foreColor;
       RGBColor  backColor;
     };
     typedef struct ControlFontStyleRec ControlFontStyleRec;
     typedef ControlFontStyleRec *ControlFontStylePtr;

Field Descriptions

flags A signed 16-bit integer specifying which fields of the structure should be applied to the control (see Control Font Style Flag Constants, below). If none of the flags in the flags field of the structure are set, the control uses the system font unless the control variant kControlUsesOwningWindowsFontVariant has been specified, in which case the control uses the window font.
font If the kControlUseFontMask bit is set, this field will contain an integer indicating the ID of the font family to use. If this bit is not set, then the system default font is used. A meta font constant can be specified instead (see Meta Font Constants, below).
size If the kControlUseSizeMask bit is set, this field will contain an integer representing the point size of the text. If the kControlAddSizeMask bit is set, this value will represent the size to add to the current point size of the text. A meta font constant can be specified instead (see Meta Font Constants, below).
style If the kControlUseStyleMask bit is set, this field will contain an integer specifying which styles to apply to the text. If all bits are clear, the plain font style is used. The bit numbers and the styles they represent are as follows:

Bit Value Style
0 Bold
1 Italic
2 Underline
3 Outline
4 Shadow
5 Condensed
6 Extended

mode If the kControlUseModeMask bit is set, this field will contain an integer specifying how characters are drawn in the bit image. (See Chapter 12 - Drawing With QuickDraw for a discussion of transfer modes.)
just If the kControlUseJustMask bit is set, this field will contain an integer specifying text justification (left, right, centered, or system script direction).
foreColor If the kControlUseForeColorMask bit is set, this field will contain an RGB (red-green-blue) colour to use when drawing the text.
backColor If the kControlUseBackColorMask bit is set, this element will contain an RGB (red-green-blue) colour to use when drawing the background behind the text. (Note that, in certain text modes, background colour is ignored.)

Control Font Style Flag Constants

You can pass one or more of the following control font style flag constants in the flags field of the control font style structure to specify those fields of the structure that are be applied to the control. (The constant shown in dark blue was introduced with Mac OS 8.5.) If none of the flags in of the flags field are set, the control uses the system font unless a control with a variant that uses the window font has been specified.

Constant Value Meaning
kControlUseFontMask 0x0001 The font field of the control font style structure is applied to the control.
kControlUseFaceMask 0x0002 The style field of the control font style structure is applied to the control.

This flag is ignored if you specify a meta font value (see Meta Font Constants, below).

kControlUseSizeMask 0x0004 The size field of the control font style structure is applied to the control.

This flag is ignored if you specify a meta font value (see Meta Font Constants, below).

kControlUseForeColorMask 0x0008 The foreColor field of the control font style structure is applied to the control.

This flag only applies to static text controls.

kControlUseBackColorMask 0x0010 The backColor field of the control font style structure is applied to the control.

This flag only applies to static text controls.

kControlUseModeMask 0x0020 The text mode specified in the mode field of the control font style structure is applied to the control.
kControlUseJustMask 0x0040 The just field of the control font style structure is applied to the control.
kControlUseAllMask 0x00FF All flags in this mask will be set except kControlUseAddFontSizeMask.
kControlUseAddFontSizeMask 0x0100 The Dialog Manager will add a specified font size to the size field of the control font style structure.

This flag is ignored if you specify a meta font value (see Meta Font Constants, below.

KControlAddToMetaFontMask 0x0200 The control may use a meta font while also adding other attributes to the font.

Meta Font Constants

You can use the following meta font constants in the font field of the control font style structure to specify the style, size, and font family of a control's font. You should use these meta font constants whenever possible because the system font can change, depending upon the current theme. If none of these constants are specified, the control uses the system font unless a control with a variant that uses the window font has been specified.

Constant Value Meaning In Roman Script System
kControlFontBigSystemFont 0x0001 Use the system font. (For the Roman script system, this is Charcoal 12.)
kControlFontSmallSystemFont 0x0002 Use the small system font. (For the Roman script system, this is Geneva 10.)
kControlFontSmallBoldSystemFont 0x0004 Use the small emphasised system font. (For the Roman script system, this is Geneva 10.)

Another advantage of using these meta font constants is that you can be sure of getting the correct font on a Macintosh using a different script system, such as kanji.

Updating, Moving, and Removing Controls

Updating Controls

When your application receives an update event for a window containing controls, it should call UpdateControls between the BeginUpdate and EndUpdate calls in its updating function.

Note that when you use the Dialog Manager to implement push buttons, radio buttons, checkboxes or pop-up menu buttons in alert boxes or dialog boxes, Dialog Manager functions automatically use Control Manager functions to update the controls for you.

Moving Controls

You can change the position of a control using MoveControl, which erases the control, offsets the control's control rectangle, and redraws it at the specified new location

Removing Controls

When you no longer need a control in a window that you wish to keep, you use DisposeControl to remove it from the screen, delete it from the window's control list, and release the control structure and associated data structures from memory. KillControls will dispose of all of a window's controls at once.

Handling Mouse Events in Controls

Overview

For mouse events in controls, you usually perform the following tasks:

  • Use FindWindow to determine the window in which the mouse-down event occurred.

  • If the mouse-down event occurred in the content region of the active window, use FindControl to determine whether the event occurred in a control and, if so, which control.

  • Call TrackControl or HandleControlClick to handle user interaction with the control as long as the user holds the mouse button down. The actionProc parameter passed to TrackControl, or the inAction parameter passed to HandleControlClick, should be as follows:

    • NULL for push buttons, checkboxes and radio buttons.

    • For scroll arrows and gray areas of scroll bars, a pointer which invokes an application-defined action function which, in turn, causes the document to scroll as long as the user holds the mouse button down.

    • For the scroll box of scroll bars:

      • NULL if the non-live-feedback variant is being used.

      • If the live-feedback variant is being used, a pointer which invokes an application-defined action function which, in turn, causes the document to scroll while the scroll box is being dragged.

    • (ControlActionUPP) -1 for pop-up menu buttons. This causes TrackControl and HandleControlClick to use the action function defined within the pop-up CDEF, a pointer to which is stored in the contrlAction field of the control structure.

    For source code that only needs to be compiled as 680x0 code, the pointer which invokes the application-defined action function need only be a procedure pointer, that is, the address of the action function. For source code that needs to be compiled as PowerPC code, or as both PowerPC code and 680x0 code, the pointer must be a Universal Procedure Pointer (UPP).

    Note that, as an alternative to passing these pointers in the actionProc parameter of TrackControl, or the inAction parameter of HandleControlClick, you can preset the action function by passing the pointer in the actionProc parameter of SetControlAction. (Ordinarily, you would call SetControlAction immediately after the control is created. SetControlAction stores the pointer in the contrlAction field of the control structure.) In this case, you must pass (ControlActionUPP) -1 in the actionProc and inAction parameters of TrackControl and HandleControlClick.

  • When TrackControl or HandleControlClick reports that the user has released the mouse button with the cursor in a control, respond appropriately, that is:

    • Perform the task identified by the push button title if the cursor is over a push button.

    • Toggle the value of the checkbox when the cursor is over a checkbox. (The Control Manager then redraws or removes the checkmark, as appropriate.)

    • Turn on the radio button, and turn off all other radio buttons in the group, when the cursor is over an active radio button.

    • Show more of the document in the direction of the scroll arrow when the cursor is over the scroll arrow or gray area of a scroll bar, and move the scroll box accordingly.

    • If the non-live-feedback scroll bar variant is being used, and when the cursor is over the scroll box, determine where the user has dragged the scroll box, and then display the corresponding portion of the document.

    • Use the new setting chosen by the user when the cursor is over a pop-up menu button.

Determining a Mouse-Down Event in a Control

When the mouse-down event occurs in a visible, active control, FindControl returns a handle to that control as well as a control part code identifying that control's part. (When the mouse-down occurs in an invisible or inactive control, or when the cursor is not in a control, FindControl sets the control handle to NULL and returns 0 as its control part code.)

Historical Note

A new function similar to FindControl was introduced with Mac OS 8 and the Appearance Manager. This new function (FindControlUnderMouse) will return a handle to the control even if no part was hit and can determine whether a mouse-down event has occurred even if the control is deactivated, whereas FindControl will not.

A control part code is an integer from 1 to 255. Part codes are assigned to a control by its CDEF. The CDEFs for the basic controls define the following part codes:

Constant Value Meaning
kControlNoPart 0 Event did not occur in any control.

Also unhighlights any highlighted part of the control when passed to the HiliteControl function.

kControlLabelPart 1 Event occurred in the label of a pop-up menu button.
kControlMenuPart 2 Event occurred in the menu of a pop-up menu button.
kControlButtonPart 10 Event occurred in a push button.
kControlCheckBoxPart 11 Event occurred in a checkbox.
kControlRadioButtonPart 12 Event occurred in a radio button.
kControlUpButtonPart 20 Event occurred in the up (or left )scroll arrow of a scroll bar.
kControlDownButtonPart 21 Event occurred in the down (or right) button of a scroll bar.
kControlPageUpPart 22 Event occurred in the page-up part of a scroll bar.
kControlPageDownPart 23 Event occurred in the page-down part of a scroll bar.
kControlIndicatorPart 129 Event occurred in the scroll box of a scroll bar.

Tracking the Cursor in a Control

After calling FindControl to determine that the user pressed the mouse button while the cursor was in a control, you should call TrackControl or HandleControlClick to follow and respond to the user's movements.

You can also use an action function to undertake additional actions as long as the user holds the mouse button down. Typically, action functions are used to continuously scroll the window's contents while the cursor is on a scroll arrow or gray area of a scroll bar, or in the scroll box of a live-feedback scroll bar. (As previously stated, you pass a pointer to this action function in the actionProc parameter of TrackControl or the inAction parameter of HandleControlClick).

TrackControl and HandleControlClick return the control's control part code if the user releases the mouse button while the cursor is still inside the control part, or kControlNoPart (0) if the cursor is outside the control part when the button is released. Your application should then respond appropriately.

Determining and Changing Control Settings

When the user clicks a control, your application often needs to determine the current setting and other values of that control. When the user clicks a checkbox, for example, your application must determine whether the box is checked before it can decide whether to clear or draw a checkmark inside the checkbox.

Applications must adjust some controls in response to events other than mouse events in the controls themselves. For example, when the user resizes a window, your application must use MoveControl and SizeControl to move and resize the scroll bars appropriately.

Your application can use the following functions to get and set control values. (Those appearing on in dark blue were introduced with Mac OS 8.5.)

Function Description
GetControlValue Obtains the current value of a control.
SetControlValue Changes the current value of a control.
GetControlMinimum Obtains the minimum value of a control.
SetControlMinimum Changes the minimum value of a control.
GetControlMaximium Obtains the maximum value of a control.
SetControlMaximium Changes the maximum value of a control.
GetControl32BitValue Obtains the current value of a control.
SetControl32BitValue Changes the current value of a control.
GetControl32BitMinimum Obtains the minimum value of a control.
SetControl32BitMinimum Changes the minimum value of a control.
GetControl32BitMaximum Obtains the maximum value of a control.
SetControl32BitMaximum Changes the maximum value of a control.

Moving and Resizing Scroll Bars

Your application must be able to size and move scroll bars dynamically in response to the user resizing your windows. The steps involved are:

  • Resize the window.

  • Use HideControl to make each scroll bar invisible.

  • Use MoveControl to move the scroll bars to the appropriate edges of the window.

  • Use SizeControl to lengthen or shorten each scroll bar as appropriate.

  • Recalculate the maximum settings for the scroll bars and use SetControlMaximum and SetControlValue to update the settings and to redraw the scroll boxes appropriately.

  • Use ShowControl to make each scroll bar visible at its new location.
Each of the functions involved require a handle to the relevant scroll bar control. When your application creates a window, it should store handles for each scroll bar in an application-defined document structure associated with that window.

Scrolling Operations With Scroll Bars

Scrolling Basics

Spatial Relationships - Document, Window, and Scroll Bar

Spatial relationships between a document and a window, and their representation in a scroll bar, are shown at Fig 9.

(Spatial relationships)

Distance and Direction to Scroll

When the user scrolls a document using scroll bars, your application must first determine the distance and direction to scroll. The distance to scroll is as follows:

  • When the user drags the scroll box to a new location, your application should scroll a corresponding distance in the document.

  • When the user clicks on a scroll arrow, your application must determine an appropriate amount to scroll. Word processor applications typically scroll one line of text vertically, and horizontally by the average character width. Graphics applications typically scroll to display an entire object.

  • When the user clicks in the gray area, your application must determine an appropriate amount to scroll. Typically, applications scroll by a distance of just less than the height or width of the window.
The direction to scroll is determined by whether the scrolling distance is expressed as a positive or negative number. For example, when the user scrolls from the beginning of a document to a line 200 pixels down, the scrolling distance is -200 pixels on the vertical scroll bar.

Scrolling the Pixels

With the distance and direction to scroll determined, the next step is to scroll the pixels displayed in the window by that distance and in that direction. Typically, ScrollRect is used for that purpose.

Moving the Scroll Box

If the user did not effect the scroll using the scroll box, the scroll box must then be repositioned using SetControlValue.

Updating the Window

The final step is to either call a function which generates an update event or directly call your application's update function. Your application's update function should call UpdateControls (to update the scroll bars) and redraw the appropriate part of the document in the window.

Scrolling Example

Half the complexity of scrolling lays in ensuring that that part of the document which is displayed in the window correlates with the scroll bar control value, and vice versa, at all times.

Consider the left-top of Fig 10, which illustrates the situation where the user has just opened an existing document. The document consists of 35 lines of monostyled text and the line height throughout is 10 pixels. The document is, therefore, 350 pixels long. When the user opens the document, the window origin is identical to the upper-left point of the document's space, that is, both are at (0,0).

In this example, the window displays 15 lines of text, which amounts to 150 pixels. Hence the maximum setting for the scroll bar is equivalent to 200 pixels down in the document. (As shown at Fig 9, a vertical scroll bar's maximum setting equates to the length of the document minus the height of the window.)

Now assume that the user drags the scroll box about halfway down the vertical scroll bar. Because the user wishes to scroll down, your application must move the text of the document up. Moving a document up in response to a user's request to scroll down requires a negative scrolling value.

Your application, using GetControlValue, determines that the scroll bar's control value is 100 and that it must therefore move the document up by 100 pixels. It then uses ScrollRect to shift the bits displayed in the window by a distance of -100 pixels (that is, 10 lines of text). As shown at the top-right of Fig 10, five lines from the bottom of the previous window display now appear at the top of the window. Your application adds the rest of the window to an update region for later updating.

(Scrolling a document)

Note that ScrollRect does not change the coordinate system of the window; instead it moves the bits in the window to new coordinates that are still in the window's local coordinate system. (For the purposes of updating the window, you can think of this as changing the coordinates of the entire document, as is illustrated at the right-top of Fig 10.) In terms of the window's local coordinate system, then, the upper left corner of the document is now at (-100,0).

To facilitate updating of the window, SetOrigin must now be used to change the local coordinate system of the window so that the application can treat the upper left corner of the document as again lying at (0,0). This restoration of the document's original coordinate space makes it easier for the application to determine which lines of the document to draw in the update region of the window. (See bottom-left of Fig 10.)

Your application should now update the window by drawing lines 16 to 24, which it stores in its document structure as beginning at (160,0) and ending at (250,0).

Finally, because the Window and Control Managers always assume that the window's upper-left point is at (0,0) when they draw in the window, the window origin cannot be left at (100,0). Accordingly, the application must use SetOrigin to reset it to (0,0) after performing its own drawing, (See bottom-right of Fig 10.)

To summarise:

  • The user dragged the scroll box about half way down the vertical scroll bar. The application determined that this distance amounted to a scroll of -100 pixels.

  • The application passed this distance to ScrollRect, which shifted the bits in the window 100 pixels upwards and created an update region in the vacated area of the window.

  • The application passed the vertical scroll bar's current setting (100) in a parameter to SetOrigin so that the document's local coordinates were used when the update region of the window was redrawn. This changed the window's origin to (100,0).

  • The application drew the text in the update region.

  • The application reset the window's origin to (0,0)

Alternative to SetOrigin

There are alternatives to the SetOrigin methodology. SetOrigin simply helps you to offset the window's origin by the scroll bar's current settings when you update the window so that you can locate objects in a document using a coordinate system where the upper-left corner of the document is always at (0,0).

As an alternative to this approach, your application can leave the upper-left corner of the window at (0,0) and instead offset the items in your document, using OffsetRect, by an amount equal to the scroll bar's settings.

Scrolling a TextEdit Document and Scrolling Using the List Manager

TextEdit is a collection of functions and data structures which you can use to provide your application with basic text editing capabilities. Chapter 19 - Text and TextEdit addresses, amongst other things, the scrolling of TextEdit documents.

For scrolling lists of graphic or textual information, your application can use the List Manager to implement scroll bars. (See Chapter 20 - Lists and Custom List Definition Functions.)



Main Control Manager Constants, Data Types and Functions Relevant to the Basic Controls, Primary Group Box (Text Title Variant) and User Panes

In the following:

  • The constants, data types, and functions introduced with Mac OS 8 and the Appearance Manager are shown in light blue.

  • The constants and functions introduced with Mac OS 8.5 are shown in dark blue.

  • Those older constants, data types and functions affected by the introduction of Mac OS 8 and the Appearance Manager, but which may still be used in certain circumstances, are shown in red.

Constants

Control Definition IDs

  
kControlPushButtonProc            = 368
kControlPushButLeftIconProc       = 374
kControlPushButRightIconProc      = 375
kControlCheckBoxProc              = 369
kControlCheckBoxAutoToggleProc    = 371
kControlRadioButtonProc           = 370
kControlRadioButtonAutoToggleProc = 372
kControlScrollBarProc             = 384
kControlScrollBarLiveProc         = 386
kControlPopupButtonProc           = 400
kControlGroupBoxTextTitleProc     = 160
kControlUserPaneProc              = 256

Pop-up Menu Button Variation Codes

kControlPopupFixedWidthVariant     = 1 << 0
kControlPopupVariableWidthVariant  = 1 << 1
kControlPopupUseAddResMenuVariant  = 1 << 2
kControlPopupUseWFontVariant       = 1 << 3

Pop-up Title Characteristics

popupTitleBold        = 1 << 8
popupTitleItalic      = 1 << 9
popupTitleUnderline   = 1 << 10
popupTitleOutline     = 1 << 11
popupTitleShadow      = 1 << 12
popupTitleCondense    = 1 << 13
popupTitleExtend      = 1 << 14
popupTitleNoStyle     = 1 << 15

Control Variants

kControlNoVariant                     = 0
kControlUsesOwningWindowsFontVariant  = 1 << 3

Control Part Codes

kControlNoPart          = 0
kControlLabelPart       = 1
kControlMenuPart        = 2
kControlButtonPart      = 10
kControlCheckBoxPart    = 11
kControlRadioButtonPart = 11
kControlUpButtonPart    = 20
kControlDownButtonPart  = 21
kControlPageUpPart      = 22
kControlPageDownPart    = 23
kControlIndicatorPart   = 129
kControlDisabledPart    = 254
kControlInactivePart    = 255

Checkbox Value Constants

kControlCheckBoxUncheckedValue  = 0,
kControlCheckBoxCheckedValue    = 1,
kControlCheckBoxMixedValue      = 2

Radio Button Value Constants

kControlRadioButtonUncheckedValue  = 0,
kControlRadioButtonCheckedValue    = 1,
kControlRadioButtonMixedValue      = 2

Control Data Tag Constants

kControlPushButtonDefaultTag      = FOUR_CHAR_CODE('dflt')
kControlPushButtonCancelTag       = FOUR_CHAR_CODE('cncl')
kControlPopupButtonMenuHandleTag  = FOUR_CHAR_CODE('mhan')
kControlPopupButtonMenuIDTag      = FOUR_CHAR_CODE('mnid')
kControlPopupButtonExtraHeightTag = FOUR_CHAR_CODE('exht')
kControlGroupBoxTitleRectTag      = FOUR_CHAR_CODE('trec')

Control Font Style Flag Constants

kControlUseFontMask       = 0x0001
kControlUseFaceMask       = 0x0002
kControlUseSizeMask       = 0x0004
kControlUseForeColorMask  = 0x0008
kControlUseBackColorMask  = 0x0010
kControlUseModeMask       = 0x0020
kControlUseJustMask       = 0x0040
kControlUseAllMask        = 0x00FF
kControlAddFontSizeMask   = 0x0100
kControlAddToMetaFontMask = 0x0200

Meta Font Constants

kControlFontBigSystemFont        = -1
kControlFontSmallSystemFont      = -2
kControlFontSmallBoldSystemFont  = -3

Data Types

typedef SInt16 ControlPartCode;

Control Structure

struct ControlRecord 
{
  ControlHandle     nextControl;   // Next Control.
  WindowPtr         contrlOwner;   // Control's window.
  Rect              contrlRect;    // Rectangle.
  UInt8             contrlVis;     // 255 if visible, else 0.
  UInt8             contrlHilite;  // Highlight state.
  SInt16            contrlValue;   // Current setting.
  SInt16            contrlMin;     // Minimum Setting.
  SInt16            contrlMax;     // Maximum setting.
  Handle            contrlDefProc; // Control definition function.
  Handle            contrlData;    // Data used by contrlDefProc.
  ControlActionUPP  contrlAction;  // Action function.
  SInt32            contrlRfCon;   // Reference constant.
  Str255            contrlTitle;   // Title.
};
typedef struct ControlRecord ControlRecord;
typedef ControlRecord *ControlPtr;
typedef ControlPtr *ControlHandle;

Control Font Style Structure

struct ControlFontStyleRec 
{
  SInt16    flags;
  SInt16    font;
  SInt16    size;
  SInt16    style;
  SInt16    mode;
  SInt16    just;
  RGBColor  foreColor;
  RGBColor  backColor;
};
typedef struct ControlFontStyleRec ControlFontStyleRec;
typedef ControlFontStyleRec *ControlFontStylePtr;

Functions

Creating and Removing Controls

ControlHandle  NewControl(WindowPtr owningWindow,const Rect *boundsRect,
               ConstStr255Param title,Boolean initiallyVisible,SInt16 initialValue,
               SInt16 minimumValue,SInt16 maximumValue,SInt16 procID,
               SInt32 controlReference);
ControlHandle  GetNewControl(SInt16 controlID,WindowPtr owner);
void           DisposeControl(ControlHandle theControl);
void           KillControls(WindowPtr theWindow);

Embedding Controls

OSErr  CreateRootControl(WindowPtr inWindow,ControlHandle * outControl);
OSErr  GetRootControl(WindowPtr inWindow,ControlHandle * outControl);
OSErr  EmbedControl(ControlHandle inControl,ControlHandle inContainer);
OSErr  AutoEmbedControl(ControlHandle inControl,WindowPtr inWindow);
OSErr  CountSubControl(ControlHandle inControl,SInt16 * outNumChildren);
OSErr  GetIndexedSubControl(ControlHandle inControl,SInt16 inIndex,
       ControlHandle * outSubControl);
OSErr  GetSuperControl(ControlHandle inControl,ControlHandle * outParent);
OSErr  SetControlSupervisor(ControlHandle inControl,ControlHandle inBoss);
OSErr  DumpControlHierarchy(WindowPtr inWindow,const FSSpec *inDumpFile);

Displaying and Manipulating Controls

void     MoveControl(ControlHandle theControl,SInt16 h,SInt16 v);
void     SizeControl(ControlHandle theControl,SInt16 w,SInt16 h);
void     UpdateControls(WindowPtr theWindow,RgnHandle updateRgn);
void     DrawControls(WindowPtr theWindow);
void     DrawOneControl(ControlHandle theControl);
void     DrawControlInCurrentPort(ControlHandle inControl);
Boolean  IsControlActive (ControlHandle inControl);
OSErr    ActivateControl (ControlHandle inControl);
OSErr    DeactivateControl(ControlHandle inControl);
Boolean  IsControlVisible(ControlHandle inControl);
void     HideControl(ControlHandle theControl);
void     ShowControl(ControlHandle theControl);
OSErr    SetControlVisibility (ControlHandle inControl,Boolean inIsVisible,
         Boolean inDoDraw);
OSErr    SendControlMessage(ControlHandle inControl,SInt16 inMessage,SInt32 inParam);
void     DragControl(ControlHandle theControl,Point startPt,const Rect *limitRect,
         const Rect *slopRect,DragConstraint axis);
void     HiliteControl(ControlHandle theControl,ControlPartCode hiliteState);
SInt32   GetControlViewSize(ControlHandle theControl);
Void     SetControlViewSize(ControlHandle theControl,SInt32 newViewSize);

Handling Events in Controls

ControlPartCode  FindControl(Point thePoint,WindowPtr theWindow,
                 ControlHandle *theControl);
ControlHandle    FindControlUnderMouse(Point inWhere,WindowPtr inWindow,SInt16 *outPart); 
ControlPartCode  TrackControl(ControlHandle theControl,Point thePoint,
                 ControlActionUPP  actionProc);
Sint16           HandleControlClick(ControlHandle inControl,Point inWhere,
                 SInt16 inModifiers,  ControlActionUPP nAction);
ControlPartCode  TestControl(ControlHandle theControl, PointthePt);

Accessing and Changing Control Settings and Data

SInt16            GetControlValue(ControlHandle theControl);
void              SetControlValue(ControlHandle theControl,SInt16 theValue);
SInt16            GetControlMinimum(ControlHandle theControl);
void              SetControlMinimum(ControlHandle theControl,SInt16 newMinimum);
SInt16            GetControlMaximum(ControlHandle theControl);
void              SetControlMaximum(ControlHandle theControl,SInt16 newMaximum);
SInt32            GetControl32BitValue(ControlHandle theControl);
void              SetControl32BitValue(ControlHandle theControl,SInt32 newValue);
SInt32            GetControl32BitMaximum(ControlHandle theControl);
Void              SetControl32BitMaximum(ControlHandle theControl,SInt32 newMaximum);
SInt32            GetControl32BitMinimum(ControlHandle theControl);
Void              SetControl32BitMinimum(ControlHandle theControl,SInt32 newMinimum);
void              GetControlTitle(ControlHandle theControl,Str255 title);
void              SetControlTitle(ControlHandle theControl,ConstStr255Param title);
SInt32            GetControlReference(ControlHandle theControl);
void              SetControlReference(ControlHandle theControl,SInt32 data);
ControlActionUPP  GetControlAction(ControlHandle theControl);
void              SetControlAction(ControlHandle theControl,
                  ControlActionUPP actionProc);
SInt16            GetControlVariant(ControlHandle theControl);
OSErr             SetControlData(ControlHandle inControl,ControlPartCode inPart,
                  ResType inTagName,Size inSize,Ptr inData);
OSErr             GetControlData (ControlHandle inControl,ControlPartCode inPart,
                  ResType inTagName,Size inBufferSize,Ptr inBuffer,
                  Size *outActualSize);
OSErr             GetControlDataSize(ControlHandle inControl,ControlPartCode inPart,
                  ResType inTagName,Size *outMaxSize);
OSErr             SetControlVisibility(ControlHandle inControl,Boolean inIsVisible,
                  Boolean inDoDraw);

Setting the Control Font Style

OSErr   SetControlFontStyle  (ControlHandle inControl,
        const ControlFontStyleRec *inStyle)

Go to Demo

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Whitethorn Games combines two completely...
If you have ever gone fishing then you know that it is a lesson in patience, sitting around waiting for a bite that may never come. Well, that's because you have been doing it wrong, since as Whitehorn Games now demonstrates in new release Skate... | Read more »
Call of Duty Warzone is a Waiting Simula...
It's always fun when a splashy multiplayer game comes to mobile because they are few and far between, so I was excited to see the notification about Call of Duty: Warzone Mobile (finally) launching last week and wanted to try it out. As someone who... | Read more »
Albion Online introduces some massive ne...
Sandbox Interactive has announced an upcoming update to its flagship MMORPG Albion Online, containing massive updates to its existing guild Vs guild systems. Someone clearly rewatched the Helms Deep battle in Lord of the Rings and spent the next... | Read more »
Chucklefish announces launch date of the...
Chucklefish, the indie London-based team we probably all know from developing Terraria or their stint publishing Stardew Valley, has revealed the mobile release date for roguelike deck-builder Wildfrost. Developed by Gaziter and Deadpan Games, the... | Read more »
Netmarble opens pre-registration for act...
It has been close to three years since Netmarble announced they would be adapting the smash series Solo Leveling into a video game, and at last, they have announced the opening of pre-orders for Solo Leveling: Arise. [Read more] | Read more »
PUBG Mobile celebrates sixth anniversary...
For the past six years, PUBG Mobile has been one of the most popular shooters you can play in the palm of your hand, and Krafton is celebrating this milestone and many years of ups by teaming up with hit music man JVKE to create a special song for... | Read more »
ASTRA: Knights of Veda refuse to pump th...
In perhaps the most recent example of being incredibly eager, ASTRA: Knights of Veda has dropped its second collaboration with South Korean boyband Seventeen, named so as it consists of exactly thirteen members and a video collaboration with Lee... | Read more »
Collect all your cats and caterpillars a...
If you are growing tired of trying to build a town with your phone by using it as a tiny, ineffectual shover then fear no longer, as Independent Arts Software has announced the upcoming release of Construction Simulator 4, from the critically... | Read more »
Backbone complete its lineup of 2nd Gene...
With all the ports of big AAA games that have been coming to mobile, it is becoming more convenient than ever to own a good controller, and to help with this Backbone has announced the completion of their 2nd generation product lineup with their... | Read more »
Zenless Zone Zero opens entries for its...
miHoYo, aka HoYoverse, has become such a big name in mobile gaming that it's hard to believe that arguably their flagship title, Genshin Impact, is only three and a half years old. Now, they continue the road to the next title in their world, with... | Read more »

Price Scanner via MacPrices.net

B&H has Apple’s 13-inch M2 MacBook Airs o...
B&H Photo has 13″ MacBook Airs with M2 CPUs and 256GB of storage in stock and on sale for up to $150 off Apple’s new MSRP, starting at only $849. Free 1-2 day delivery is available to most US... Read more
M2 Mac minis on sale for $100-$200 off MSRP,...
B&H Photo has Apple’s M2-powered Mac minis back in stock and on sale today for $100-$200 off MSRP. Free 1-2 day shipping is available for most US addresses: – Mac mini M2/256GB SSD: $499, save $... Read more
Mac Studios with M2 Max and M2 Ultra CPUs on...
B&H Photo has standard-configuration Mac Studios with Apple’s M2 Max & Ultra CPUs in stock today and on Easter sale for $200 off MSRP. Their prices are the lowest available for these models... Read more
Deal Alert! B&H Photo has Apple’s 14-inch...
B&H Photo has new Gray and Black 14″ M3, M3 Pro, and M3 Max MacBook Pros on sale for $200-$300 off MSRP, starting at only $1399. B&H offers free 1-2 day delivery to most US addresses: – 14″ 8... Read more
Department Of Justice Sets Sights On Apple In...
NEWS – The ball has finally dropped on the big Apple. The ball (metaphorically speaking) — an antitrust lawsuit filed in the U.S. on March 21 by the Department of Justice (DOJ) — came down following... Read more
New 13-inch M3 MacBook Air on sale for $999,...
Amazon has Apple’s new 13″ M3 MacBook Air on sale for $100 off MSRP for the first time, now just $999 shipped. Shipping is free: – 13″ MacBook Air (8GB RAM/256GB SSD/Space Gray): $999 $100 off MSRP... Read more
Amazon has Apple’s 9th-generation WiFi iPads...
Amazon has Apple’s 9th generation 10.2″ WiFi iPads on sale for $80-$100 off MSRP, starting only $249. Their prices are the lowest available for new iPads anywhere: – 10″ 64GB WiFi iPad (Space Gray or... Read more
Discounted 14-inch M3 MacBook Pros with 16GB...
Apple retailer Expercom has 14″ MacBook Pros with M3 CPUs and 16GB of standard memory discounted by up to $120 off Apple’s MSRP: – 14″ M3 MacBook Pro (16GB RAM/256GB SSD): $1691.06 $108 off MSRP – 14... Read more
Clearance 15-inch M2 MacBook Airs on sale for...
B&H Photo has Apple’s 15″ MacBook Airs with M2 CPUs (8GB RAM/256GB SSD) in stock today and on clearance sale for $999 in all four colors. Free 1-2 delivery is available to most US addresses.... Read more
Clearance 13-inch M1 MacBook Airs drop to onl...
B&H has Apple’s base 13″ M1 MacBook Air (Space Gray, Silver, & Gold) in stock and on clearance sale today for $300 off MSRP, only $699. Free 1-2 day shipping is available to most addresses in... Read more

Jobs Board

Medical Assistant - Surgical Oncology- *Apple...
Medical Assistant - Surgical Oncology- Apple Hill Location: WellSpan Medical Group, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Apply Read more
Omnichannel Associate - *Apple* Blossom Mal...
Omnichannel Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Mall Read more
Operations Associate - *Apple* Blossom Mall...
Operations Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Business Analyst | *Apple* Pay - Banco Popu...
Business Analyst | Apple PayApply now " Apply now + Apply Now + Start applying with LinkedIn Start + Please wait Date:Mar 19, 2024 Location: San Juan-Cupey, PR Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.