Objective
To design, write, compile and test forms and the piece of code
that handles user interaction.
Concepts
Creating labelz, buttonz, fieldz...
If you're used to developing windowed apps for PC, Mac or any other
platform, then designing your first Palm form shouldn't be a problem.
PilRC User Manual is the doc to refer
to, should you need more details. Basically, you will "write"
the .rcp file using your favorite text editor, compile it, link
it to the compiled source code of your app, and get a beautiful
.prc file that you can hotsync to your device or run on POSE.
Positioning items on a form may use either absolute
values (like 50, 100) or relative values
(like CENTER, PREVBOTTOM+2). I'd suggest that relative mode be used
as much as possible because it's more flexible and makes updates
easier.
Writing the .rcp file
Here's the big picture.
Define all the IDs of your controls, buttons, etc in a .h file,
which will be #included in both your .rcp and .c files. This .h
makes sure that the app and the form(s) use the same
resource IDs
In your editor, create the .rcp file, include the .h, and give
your form the following structure:
FORM ID Form1 AT (2 2 156 156) USABLE MODAL
HELPID Help1
BEGIN
TITLE "Forms 1/4 (Modal)"
LABEL "This is a label"
AUTOID AT (CENTER 20) FONT 1
BUTTON "Next" ID Next
AT (CENTER PREVBOTTOM+10 AUTO AUTO) FRAME
BUTTON "Exit" ID Exit AT (CENTER@120 PREVTOP
AUTO AUTO)
END
This says that we want a form with just one label, a Next button
and Exit button. Labels do not communicate
with the app, so we don't assign them any ID, neither do we mention
them in the .h file. On the other hand, buttons
may send events to our app, or our app may want to change
a button's setting. That's why buttons, controls, etc. will be assigned
IDs in our .h file.
Writing code that handles form and control events
Here's the overview of who can send what event, and what should
be done. Variable "e" is our event.
Sender |
Event |
Meaning |
Action |
Form manager |
frmLoadEvent |
Form has been loaded |
FrmSetActiveForm(FrmInitForm(e.data.frmLoad.formID)) |
Form manager |
frmOpenEvent |
Form has been opened |
FrmDrawForm(...) |
Control |
ctlSelectEvent |
User tapped control |
if (e.data.ctlSelect.controlID == Next)
...
if (e.data.ctlSelect.controlID == Exit)
... |
Control |
ctlRepeatEvent |
User tapped control and maintained stylus
on control |
if (e.data.ctlRepeat.controlID == Form3Minus)
...
if (e.data.ctlRepeat.controlID == Form3Plus)
... |
This handler is part of the "endless" loop started in
PilotMain.
Exercise
Download the ZIP file.
In this app, not all controls will generate event. For the sake
of simplicity, those controls will not have IDs.
In forms.h:
- add ID Next (value 9001)
- add ID Exit (value 9002)
In forms.rcp:
- in Form1, assign value Forms 1/4 (Modal)
to TITLE
- give a position of CENTER 20 to
the first label
- give a position of CENTER@50 PREVBOTTOM+10
and a size of AUTO AUTO to "Next"
button
- define Exit button as follows: BUTTON "Exit"
ID Exit AT (CENTER@120 PREVTOP AUTO AUTO)
- in Form2, add a PUSHBUTTON "2nd" ID 2012
AT (CENTER@80 PREVTOP AUTO AUTO) GROUP 1
- add the first checkbox: CHECKBOX "Unchecked"
ID 2021 AT (CENTER@50 PREVBOTTOM+2 AUTO AUTO)
- in Form3, add a POPUPTRIGGER "Continent"
ID 2040 AT (CENTER@40 PREVBOTTOM+2 AUTO AUTO)
- add a popup list like this: LIST "Europe"
"America" "Asia" "Africa" "Oceania" ID 2041 AT (PREVLEFT PREVTOP
52 1) VISIBLEITEMS 3 NONUSABLE
- link this popuptrigger to its list: POPUPLIST
ID 2040 2041
- add a list like LIST "English" "Spanish"
"German" "French" ID 2042 AT (CENTER@120 PREVTOP 52 1) VISIBLEITEMS
2
- add a REPEATBUTTON "-" ID Form3Minus AT
(CENTER@50 PREVBOTTOM+2 AUTO AUTO) that the user will use
to decrement a value
- add a field to hold the value: FIELD ID
Form3Count AT (CENTER@80 PREVTOP 24 AUTO) NONEDITABLE UNDERLINED
MAXCHARS 4
- insert a superb image: FORMBITMAP AT (80-(32/2)
PREVBOTTOM+2) BITMAP Bitmap
- in Form4, add a TABLE Table AT (CENTER
PREVBOTTOM+4 80 90) ROWS 8 COLUMNS 2 COLUMNWIDTHS 20 60
- lastly, in Alert1, add a MESSAGE "Nothin'
special :)\n"
In forms.c:
- include the .h
- in UpdateCount, add this block of code to update and refresh
the counter:
frm = FrmGetActiveForm();
obj = FrmGetObjectIndex(frm, Form3Count);
fld = (FieldPtr)FrmGetObjectPtr(FrmGetActiveForm(), obj);
h = (VoidHand)FldGetTextHandle(fld);
if( h == NULL )
{
h = MemHandleNew (FldGetMaxChars(fld)+10);
ErrFatalDisplayIf( !h, "No Memory");
}
p = (CharPtr) MemHandleLock (h);
StrIToA(p, cnt);
MemHandleUnlock (h);
FldSetTextHandle (fld, (Handle)h);
FldDrawField(fld);
- in UpdateTable, add TblSetRowUsable(table,
i, true);
- in PilotMain, handle the "Next" event with this code:
if (e.data.ctlSelect.controlID == Next)
{
if (f < FormLast)
FrmGotoForm(++f);
}
- handle "+" button as follows:
if (e.data.ctlRepeat.controlID == Form3Plus)
{
if (cnt < MAX_COUNT)
UpdateCount(+1);
}
- set active form with a call to FrmSetActiveForm(FrmInitForm(e.data.frmLoad.formID));
- draw it: FrmDrawForm(pfrm);
- close the forms when you leave the app: FrmCloseAllForms();
Make the app and test it!
Solution
Here's the ZIP file.
And here's how the app should like:
Next topic
|