.
Home    |    Palm Games   |  Tech SupportTable of Contents   |   About Us    |    Email Us  
Palm Programming
Palm Programming HomepageHello WorldEmail Us
.
Support
Palm    |    Windows   |    Unix
Your first palm program - Hello World Line by Line
Line by Line Analysis

Color code used:
light blue = variables, constants, and subroutines names chosen by the programmer
light green = C reserved words, Palm API calls, and all else NOT chosen by the programmer

#include <PalmOS.h>
This include file is from the Palm SDK and contains the needed reference materials for us to use the Palm API and its defined constants.  There are other include files you will need for more complex programs that will be discussed elsewhere.

#include "HelloWorld_resource.h"
This include file is created by your IDE (unless you are making them up manually - a monumental task that should only be attempted when you are extremely bored) and contains the constants that refer to the resources you have created for your program.  These resources include forms and thier contents (buttons, fields, etc), alert boxes, bitmaps, and strings.  This file does not include the actual bitmaps or forms, it only contains definitions for thier names.  You may click here for an example of the resource.h file.

static int
StartApplication(void);
static Boolean
ApplicationHandleEvent(EventPtr event);
static void
EventLoop(void);
static void
StopApplication(void);
UInt32 PilotMain(UInt16
cmd, void *cmdPBP, UInt16 launchFlags);
Boolean
frmMainHandleEvent(EventPtr event);
In the six lines above we are prototyping all the procedures below.  We don't need to prototype all your procedures, only those that are called before they are defined,  but it is a good habit.

Now we declare any global variables we need - This program uses only one, flagProgramExit that we will use to control program termination
Boolean flagProgramExit=false;

static int
StartApplication (void)
{
   FrmGotoForm(
frmMain);
The only purpose of our StartApplication routine is to open frmMain.  It uses the Palm API call FrmGotoForm() to open our initial form.  This is only generating an event to open the form, not actually doing the opening.  The form will be opened as soon as the event handler is called and pulls the request we have made off the event queue.
   return 0;
}

Before calling the ApplicationHandleEvent() we have already called the systems event handler and determined that the system did not handle the event.  
static Boolean
ApplicationHandleEvent(EventPtr event)
{
   UInt16
formID//  used to hold a forms id number
   FormPtr
form// used to hold a pointer to a form
   Boolean
handled=false;
The handled variable  is used for returning a true false value to the EventLoop informing it whether or not we have taken care of this event.  If we have not, the eventloop will be able to pass it to another handler, or, in this case, destroy the event if unused..

When we pull an event off the event queue, first we come here, to the ApplicationHandleEvent routine, to see if we can process the event ourselves, before passing it on to the system to see if it can handle the event.
the eType will tell us if it is a form loading (the frmLoadEvent) or a menu being called up.  There are several types of events, all of which will be discussed in the
Concepts and Strategies section.

   switch (
event->eType)
   {
      case frmLoadEvent:
        
formID=event->data.frmLoad.formID;   //  Here we find out which form is loading - its ID number is stored in
                                                                                   the event object's data section.

        
form=FrmInitForm(formID);                  //  We initialize the form
         FrmSetActiveForm(
form);                      //  and make it active

Next, based upon which form is loading we will want to set the event handling routine for the form to the procedure we have written.  This will allow us to be notified of button presses and other activities on our form, as well as containing the API call to do the actual displaying of the form (which at this point is still invisible to the user)

         switch (
formID)
         {
            case
frmMain:
               FrmSetEventHandler(
form,(FormEventHandlerPtr) frmMainHandleEvent// setting the event handler
               break;
            default:
               break;
         }
        
handled=true;  // set the handled flag to true - this will be returned to the EventLoop (the calling routine) to tell it that this event has been taken care of.
         break;
      default:
         break;
   }
   return
handled;
}

The EventLoop is the main body of the program.
static void
EventLoop(void)
{
   UInt16
error// a variable to store API call error results in
   EventType
event// a variable to store the current event (the one we pull of the event queue)
   do
   {
      EvtGetEvent(&
event,evtWaitForever);
The Palm API call EvtGetEvent() is used to grab an event off the queue - it will wait for the next event if there is none in the queue.  The constant evtWaitForever may be used to wait an indefinate period of time, or an integer may be used to wait that number of clock ticks (about 100 per second).  The program is paused at this line while waiting for an event.  Events may be pen taps on the screen, pressing of the hard buttons, opening the menu or a form, or pressing a button.  Choosing the Home Icon in the graffiti writing area will generate a program termination event.  (Events will be discussed in detail in the Concepts and Strategies section.)

      if (!SysHandleEvent(&
event))  //  The system gets first crack at an event to see if it can take care of it.
      {
          if (!
ApplicationHandleEvent(&event)) //  Then the application handler we have written gets it
               FrmDispatchEvent(&
event);  //  and if the event is still not taken care of our form handler gets it.
      }
   }
   while (
event.eType != appStopEvent && !flagProgramExit);
The EventLoop continues until an appStopEvent is detected, or if our global variable flagProgramExit is equal to true.  An AppStop event will be generated by a user pressing the home button in the graffiti writing area.   The flagProgramExit is set in the frmMainEventHandler routine when the user presses the close button on our form.
}

static void
StopApplication(void)
{
  FrmCloseAllForms(); 
The only cleanup we need to do for this program is close all forms (using the Palm API call FrmCloseAllForms()).  Other cleanup needed for more sophisticated programs will be discussed in Concepts and Strategies.
}

PilotMain MUST exist.  It is launched by the Palm operating system when your program is started.
UInt32 PilotMain(UInt16
cmd, void *cmdPBP, UInt16 launchFlags)
{
   int
error;

   if (
cmd == sysAppLaunchCmdNormalLaunch)
There are several types of launch commands.  The only one your program MUST handle is sysAppLaunchCmdNormalLaunch - which simply means your program is being asked to start normally.
   {
     
error=StartApplication();
      if (
error)
         return
error;
The three lines above call our StartApplication() routine (which loads our initial form) and exits if there was an error.

     
EventLoop();
The event loop does all our main processing, and continues to pull and process user and system events until program termination.

    
StopApplication();
The StopApplication() routine closes all forms and cleans up any locked memory.  This prevents memory leaks (which means that a small or large amount of memory is no longer able to be used by the system each time the program is run, eventually crashing the system)  Our HelloWorld application only has one form for us to close, and has no locked memory to worry about.  More detail will be given in Concepts and Strategies.
   }
}

When our form (frmMain) is active, our form event handler is used (as directed by our ApplicationEventHandler) to attempt to handle any event that the system event handler, and the application event handler, did not process.

Boolean
frmMainHandleEvent(EventPtr event)
{
   FormPtr
form;
   Boolean
handled=false;

   switch (
event->eType)
   {

The first type of event we must deal with is the frmOpenEvent, this is the section I mentioned earlier where the form is actually displayed to the user (with FrmDrawForm()), the frmOpenEvent is generated whenever we open a form (as we did in StartApplication()).

      case frmOpenEvent:
        
form=FrmGetActiveForm();
         FrmDrawForm(
form);
       
handled=true;
         break;
The second (and final) form event we must handle is the pressing of the close button.  The only thing we need to do in this case is set our global variable flagProgramExit to true, and the EventLoop will terminate.  Realize that this flag variable is of our own creation, not part of the Palm API in any way, and that we are simply using it at the end of the EventLoop's while statement.  (See the EventLoop procedure above, and our usage of flagProgramExit in the test statement if this is not clear)
      case ctlSelectEvent:
         if (
event->data.ctlEnter.controlID == cmdClose)
         {
          
flagProgramExit=true;
           break;
         }
      default:
         break;
   }
}

// HelloWorld for Palm example END
// =======================================================================


The actual "Hello World" message is part of our form design (created in our drag and drop IDE).
By displaying the frmMain form (the only form used in our program), we are displaying the "Hello World" message.
Before reading this page, you should look over the Hello World Overview