Saturday, August 1, 1998

Programming controls in PalmOS

How does the OS keep track of controls?

Listing A (at http://www.component-net.com/pp-extras/control1.html) shows a section of the include file CONTROL.H. This is the structure the OS uses to keep track of the controls.

This structure shows the general capabilities of the controls, and shows the common functionality between the controls. There's little difference between a checkbox and a button for example; visually, they do a bit different when they're tapped, but the structure defining them is nearly the same.

Let's look at the pieces of the ControlType structure.

The first element, id, is the ID number assigned by you when you design the form, either in Constructor or PilRC's script.

The RectangleType structure, bounds, contains an upper-left corner coordinate (0,0 is the top left) and a width and height (160, 160 would be the full screen). We'll deal with RectangleTypes a lot; they show up in lots of APIs. It's used here to set the position and size of the control.

The CharPtr, text, points to the text label for the control.

The ControlAttrType, attr, contains the control's attributes, whether the control is usable or not, enabled or not, etc.

The ControlAttrStyle, style, says what type of control it is, a button, checkbox, etc.

FontID specifies which font to use to draw the control's text label.

Finally, group contains a group id number if that particular control is part of a group. You might have two buttons to select "Fahrenheit" or "Celsius" in an application. By making the two pushbuttons a group the OS's pushbutton-handling routines should know to only allow one button to be on at a time. When you press Fahrenheit, it will turn off Celsius, and vice-versa. Unfortunately, the group indicator appears to be useless; the program must turn off other buttons itself if it wants to enforce the "only one at a time" rule. I haven't bothered with grouping buttons. When I wish to do such things, I just do it by knowing the range of the control IDs.

Actually, having the application do this is more flexible. You might want to allow multiple selections in a pushbutton bar, or only allow certain combinations.

When an application manipulates a control, changing the text on a button for example, it uses one of the PalmOS APIs to do so. Looking at last month's utility routines, the ChangeButtonText routine calls the CtlSetLabel API to change a button's text. These APIs take a pointer to the ControlType structure so they know which control to change. The ControlPtr data type is defined as a pointer to a ControlType. Because we frequently need to refer to a control by a ControlPtr (pointer to its data structure), it's easier to use last month's GetObjectPointer routine; the example programs from Palm define do this. In fact, I took this routine directly from those examples.

How do we work with controls in our program?

As I mentioned, the OS handles most of the work with the controls. So what do we do when we're working with the controls? How do we know when they change, or when a user selects them?