If the attachment didn't go through, here is the source:
----------------------------------------------------------------------------
-----------
#include <PalmOS.h>
#include "ScrollPageRsc.h"
#define appFileCreator 'SCPG'
#define appName "ScrollPage"
#define appVersionNum 0x01
#define appPrefID 0x00
#define appPrefVersionNum 0x01
#define CONTROL_BASE 7000
#define LABEL_BASE 8000
void * GetObjectPtr(UInt16 objectID);
void StrXCopy(char* dst, char* src, UInt16 n);
Boolean StrWCopy(char* dst, char* src, Int16 stringWidth);
char msglabel[256];
char* cArr1[] = {"David Webb", "Ronald Reagan", "Jim Belushi", "Michael
Jackson", "Tom Jones", "Sarah Gellar", "John Doe", "Alicia Silverstone",
"Ben Stiller", "Owen Wilson", "Snoop Dogg", "Fred Williamson"};
char* cArr2[] = {"111 Main St.", "222 Main St.", "333 Main St.", "444
Main St. Laurel MD 20723", "555 Main St.", "6666 Main St.", "777 Main St.",
"888 Main St.", "999 Main St.", "000 Main St.", "1212 Main St.", "1313 Main
St."};
char* cArr3[] = {"Laurel", "Odenton", "Crofton", "Glen Burnie",
"Baltimore", "Jamestown", "Parkville", "Perry Hall", "Lutherville", "Bowie",
"Washington", "Greenbelt"};
/*********************************************************************
* Internal Functions
*********************************************************************/
static Boolean MainFormHandleEvent(EventType * eventP)
{
FormType* frmP = FrmGetActiveForm();
Boolean handled = false;
UInt16 numEntries, curIndex, iPos, objIndex, objID,
objType, numObjects, i, ScrollHeight;
Int16 x, y, scrLines, yPos;
RectangleType rP;
ControlPtr ControlP;
FormLabelType* labelP;
const UInt16 MAX_ENTRIES_PAGE = 5, LINE_HEIGHT = 12, FORM_TOP =
20, LINES_PER_ENTRY = 2, NUM_LABELS = 3, NUM_CONTROLS = 1;
ScrollHeight = MAX_ENTRIES_PAGE * LINE_HEIGHT * LINES_PER_ENTRY;
switch (eventP->eType)
{
case frmOpenEvent:
//
****************************************************************************
**************************
// Display the dynamic controls
//
****************************************************************************
**************************
iPos = 0;
numEntries = 12;
// Loop through all entries
for (iPos=0; iPos < numEntries; iPos++) {
yPos = FORM_TOP + (LINE_HEIGHT * LINES_PER_ENTRY * iPos);
// Display a checkbox
ControlP = CtlNewControl ((void **) &frmP, CONTROL_BASE +
(NUM_CONTROLS * iPos) + 0, checkboxCtl, "", 1, yPos - 1, 11, 10, stdFont, 1,
true);
if (ControlP && iPos + 1 > MAX_ENTRIES_PAGE)
CtlHideControl (ControlP);
// Display a Button
ControlP = CtlNewControl ((void **) &frmP, CONTROL_BASE +
(NUM_CONTROLS * iPos) + 1, buttonCtl , "xxx", 115, yPos + 1, 30, 8, stdFont,
0, true);
if (ControlP && iPos + 1 > MAX_ENTRIES_PAGE)
CtlHideControl (ControlP);
// Display labels.
StrWCopy(msglabel, cArr1[iPos], 100); // Truncate label to
max width in pixels
labelP = FrmNewLabel ((FormType **) &frmP, LABEL_BASE +
(NUM_LABELS * iPos) + 0, msglabel, 14, yPos, stdFont);
if (labelP && iPos + 1 > MAX_ENTRIES_PAGE)
FrmHideObject (frmP, FrmGetObjectIndex(frmP, LABEL_BASE
+ (NUM_LABELS * iPos) + 0));
StrWCopy(msglabel, cArr2[iPos], 75);
labelP = FrmNewLabel ((FormType **) &frmP, LABEL_BASE +
(NUM_LABELS * iPos) + 1, msglabel, 14, yPos + LINE_HEIGHT, stdFont);
if (labelP && iPos + 1 > MAX_ENTRIES_PAGE)
FrmHideObject (frmP, FrmGetObjectIndex(frmP, LABEL_BASE
+ (NUM_LABELS * iPos) + 1));
StrWCopy(msglabel, cArr3[iPos], 60);
labelP = FrmNewLabel ((FormType **) &frmP, LABEL_BASE +
(NUM_LABELS * iPos) + 2, msglabel, 90, yPos + LINE_HEIGHT, stdFont);
if (labelP && iPos + 1 > MAX_ENTRIES_PAGE)
FrmHideObject (frmP, FrmGetObjectIndex(frmP, LABEL_BASE
+ (NUM_LABELS * iPos) + 2));
}
if (iPos > MAX_ENTRIES_PAGE) {
// Position and set scroll bar properties
rP.topLeft.x = 153;
rP.topLeft.y = FORM_TOP;
rP.extent.x = 7;
rP.extent.y = ScrollHeight;
FrmSetObjectBounds (frmP, FrmGetObjectIndex(frmP,
MainEntryScrollBar), &rP);
SclSetScrollBar (GetObjectPtr(MainEntryScrollBar), 0, 0,
(numEntries * LINES_PER_ENTRY) - (MAX_ENTRIES_PAGE * LINES_PER_ENTRY),
(MAX_ENTRIES_PAGE * LINES_PER_ENTRY));
} else
FrmHideObject (frmP, FrmGetObjectIndex(frmP,
MainEntryScrollBar));
FrmDrawForm(frmP);
handled = true;
break;
case sclRepeatEvent:
//
****************************************************************************
**************************
// Scroll the form
//
****************************************************************************
**************************
scrLines = (eventP->data.sclRepeat.newValue -
eventP->data.sclRepeat.value);
if (scrLines == 0)
break;
WinSetDrawWindow (WinGetDisplayWindow());
// Loop through all objects on the form
numObjects = FrmGetNumberOfObjects(frmP);
for (i = 0; i < numObjects; i++) {
// Count forward through the objects or backwards depending
on if scrolling up or down - display issue
objIndex = (scrLines > 0) ? i : numObjects - i - 1;
objType = FrmGetObjectType (frmP, objIndex);
objID = FrmGetObjectId (frmP, objIndex);
FrmGetObjectBounds (frmP, objIndex, &rP);
x = rP.topLeft.x;
y = rP.topLeft.y;
// Grow the bounds by one pixel to cover control frames
rP.topLeft.x --;
rP.topLeft.y --;
rP.extent.x += 2;
rP.extent.y += 2;
// Set the new y position
yPos = y - (LINE_HEIGHT * scrLines);
// Check to make sure the control is one of the dynamic
controls
if ((objType == frmLabelObj && objID >= LABEL_BASE && objID
< LABEL_BASE + 1000) ||
(objType == frmControlObj && objID >= CONTROL_BASE &&
objID < CONTROL_BASE + 1000)) {
// Labels and Controls aren't erasing when moved, so
explicitly erase them
if (y > FORM_TOP - 2 && y < ScrollHeight + FORM_TOP - 2)
WinEraseRectangle (&rP, 0);
// Move the control to yPos and check to see if it needs
shown or hidden
if (yPos < FORM_TOP - 2 || yPos > ScrollHeight +
FORM_TOP - 2) {
FrmHideObject (frmP, objIndex);
FrmSetObjectPosition (frmP, objIndex, x, yPos);
} else {
FrmSetObjectPosition (frmP, objIndex, x, yPos);
FrmShowObject (frmP, objIndex);
}
}
}
case ctlSelectEvent:
// Catch any button clicks and set the index/line number
if (eventP->data.ctlSelect.controlID >= CONTROL_BASE &&
eventP->data.ctlSelect.controlID < CONTROL_BASE + 1000){
curIndex = ((eventP->data.ctlSelect.controlID - 1 -
CONTROL_BASE) / NUM_CONTROLS);
}
}
return handled;
}
/***************************************************************************
***********************
* FUNCTION: StrWCopy
*
* DESCRIPTION: Copies as many characters as will fit in the pixel width
****************************************************************************
**********************/
Boolean StrWCopy(char* dst, char* src, Int16 stringWidth)
{
Int16 stringLength;
Boolean fitWithinWidth;
stringLength = StrLen(src);
FntCharsInWidth(src, &stringWidth, &stringLength, &fitWithinWidth);
StrXCopy(dst, src, stringLength);
return fitWithinWidth;
}
/***************************************************************************
***********************
* FUNCTION: StrXCopy
*
* DESCRIPTION: Replacement for StrNCopy since it doesn't null terminate
dst.
****************************************************************************
**********************/
void StrXCopy(char* dst, char* src, UInt16 n)
{
UInt16 i = 0;
for (i = 0; i < n; i++) {
dst[i] = src[i];
if (src[i] == NULL)
break;
}
dst[i] = NULL;
}
void * GetObjectPtr(UInt16 objectID)
{
FormType * frmP;
frmP = FrmGetActiveForm();
return FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID));
}
static Boolean AppHandleEvent(EventType * eventP)
{
UInt16 formId;
FormType * frmP;
if (eventP->eType == frmLoadEvent)
{
/* Load the form resource. */
formId = eventP->data.frmLoad.formID;
frmP = FrmInitForm(formId);
FrmSetActiveForm(frmP);
switch (formId)
{
case MainForm:
FrmSetEventHandler(frmP, MainFormHandleEvent);
break;
default:
break;
}
return true;
}
return false;
}
static void AppEventLoop(void)
{
UInt16 error;
EventType event;
do {
/* change timeout if you need periodic nilEvents */
EvtGetEvent(&event, evtWaitForever);
if (! SysHandleEvent(&event))
{
if (! MenuHandleEvent(0, &event, &error))
{
if (! AppHandleEvent(&event))
{
FrmDispatchEvent(&event);
}
}
}
} while (event.eType != appStopEvent);
}
static Err AppStart(void)
{
return errNone;
}
static void AppStop(void)
{
/* Close all the open forms. */
FrmCloseAllForms();
}
/* all code from here to end of file should use no global variables */
#pragma warn_a5_access on
static UInt32 Test5PalmMain(
UInt16 cmd,
MemPtr /*cmdPBP*/,
UInt16 launchFlags)
{
Err error;
switch (cmd)
{
case sysAppLaunchCmdNormalLaunch:
error = AppStart();
if (error)
return error;
FrmGotoForm(MainForm);
AppEventLoop();
AppStop();
break;
default:
break;
}
return errNone;
}
UInt32 PilotMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
return Test5PalmMain(cmd, cmdPBP, launchFlags);
}
#pragma warn_a5_access reset
--
For information on using the Palm Developer Forums, or to unsubscribe, please see
http://www.palmos.com/dev/support/forums/