Click here to Skip to main content
15,868,164 members
Articles / Mobile Apps

Your first Palm app - covering GUI components, alerts and forms.

Rate me:
Please Sign up or sign in to vote.
4.50/5 (5 votes)
5 Nov 2002CPOL7 min read 135.4K   213   27   31
Building on previous articles, we develop a simple application and discuss some of the components available for Palm GUI.

Sample Image - Palm.jpg

Welcome to this, my second article on Palm development. In the meantime I see Jason Henderson has submitted an article on Palm, and I'm certainly presuming to build off his article as well as my own. In particular, my previous article does not cover the vagaries of the Palm event loops, so this time I will presume that you're familiar with them from reading Jason's excellent article.

In this article we will develop our first form based application, and explore some of the GUI components available to us. More complex components such as tables and lists will be covered separately at a later date.

Forms and Alerts

As has been previously mentioned: the Palm regards what we would call a window to be a form. What the Windows world would call a MessageBox is known as an alert. The library which handles these things is the forms library, and therefore the functions found within it are all prefixed by Frm. This is actually incredibly helpful when using the help index provided with your compiler. We do cheat a little in this example to minimise the amount of code required, but where we do this I will be sure to point it out to you.

The project provided with this article is for the Falch.net developer studio IDE, because that is what I use. It uses the PilRC resource compiler, and GCC. Therefore if you're using these things directly, you're unlikely to have any trouble. If you are using CodeWarrior I am not sure if it can work with textbased resources. If not, I am afraid you will have to create them within your compiler.

PilotMain

Traditionally a Palm application has specific points of operation. Generally speaking, the PilotMain will in part look something like this.

Err error;
switch (cmd) 
{ 
	case sysAppLaunchCmdNormalLaunch: 
		// Application start 
		error = StartApplication(); 
		if (error) 
			return error; 
		// Maintain event loop 
		EventLoop(); 
		// Stop application 
		StopApplication(); 
		break; 
}

The Err type in one which is often seen in that it is returned by great many functions, and the API also provides constants for predefined return values. When an application receives a normal launch command, it's typical for initialisation to occur within a function called StartApplication, the main event loop to be a function called EventLoop, and then for clean up to occur within a function called StopApplication. The StartApplication function simply calls FrmGotoForm in order to initialise our main form, and the EventLoop is boilerplate code which looks like this:

static void EventLoop(void) 
{ 
	Err error; 
	EventType event; 
	// Main event loop 
	do 
	{ // Get next event 
		EvtGetEvent(&event, evtWaitForever); 
		// Handle event 
		if (!SysHandleEvent(&event)) 
		{ 
			if (!MenuHandleEvent(0, &event,	&error)) 
			{ 
				if (!ApplicationHandleEvent(&event)) 
					FrmDispatchEvent(&event); 
			} 
		} 
	} while (event.eType != appStopEvent); 
}

This is the core message pump for the application, and it gives first the system, then our menu, and finally our application the opportunity to handle an event. Should all these functions return false, then the event is sent to our own event handler for that specific form. The Palm is strictly a single threaded environment, and so if any other applications started, the appStopEvent event is sent, our event loop terminates, and our program ends.

Controls

Once we have created a form within our IDE, we need to populate it. The Palm has a number of UI controls that you will be familiar with, and a few that are not so similar to the ones offered by the Windows environment.

LabelsA label is basically a static text control. Naturally we can programmatically set its value, however it does not open itself for editing by the end user.
FieldsA field is an edit control, where the user is able to enter text. It may be multi-line, or single, it can be underlined, and it may be limited to accept only numbers. The one in the demo application is single line, and underlined so that you can see where it is.
SliderThe Palm offers a horizontal slider for setting values within a range.
ScrollbarAlthough some input controls offer scrollbars automatically, it's also possible to set up a scroll bar and respond to it manually.
CheckboxJust like in Windows, a checkbox control contains text to explain its purpose, and a box within which a checkmark is toggled by clicking on it.
ButtonIt is almost obvious that a GUI will offer buttons which can be pressed in order to trigger desired actions.
SelectorTriggerA selectorTrigger works a little like a button. Both buttons and selectorTriggers can display an image rather than text.
PushButtonA pushbutton is a button that stays down when it is pressed. These are typically presented in a sequence, so the user can visibly select from a list of options.
PopupTriggerA little like a combobox, a pop-up trigger has text and an arrow. Pressing the arrow brings up a list of options, and selecting an option changes the text on the trigger.
GraffitiStateIndicatorWhen entering text using the graffiti system, there are a couple of notations which instead of entering text, notify the Palm of the nature of text to follow. This component simply provides graphical information regarding the state of the graffiti system.

These are the controls which will appear on our form for this example, but this does not represent an exhaustive list. In particular, lists and tables will be covered in a future article.

Responding to GUI events

Our main event handler, ApplicationHandleEvent, handles a number of things, including setting the event handler function for our form. The code which does this is as follows:

// Application event loop 
switch (event->eType)
{ 
	case frmLoadEvent: //Handle form load events 
		formID = event->data.frmLoad.formID; 
		form = FrmInitForm(formID); 
		FrmSetActiveForm(form); 
		
		switch (formID) 
		{ 
			case frmMain: // Set event handler for frmMain 
				FrmSetEventHandler(form, (FormEventHandlerPtr)frmMain_HandleEvent); 
				break;
			default: 
				break; 
		} 
		handled = true; 
		break; 
	default: 
		break;
}

As a result of this, the frmMain_HandleEvent function is the function which is called by events which have been rejected by the system, the menu, and this main event loop. Within the handle event function, we must handle the frmOpenEvent event, with some code such as this:

switch (event->eType) 
{
	case frmOpenEvent: // Repaint form on open 
		form = FrmGetActiveForm(); 
		FrmDrawForm(form); 
		handled = true; 
		break;

This code simply makes sure our form is drawn, a bit like a Windows paint event. To respond to controls, we need to add something like this:

case ctlSelectEvent: 
	switch (event->data.ctlSelect.controlID) 
	{ 
		case btnAlert: 
			FrmAlert(altHelloWorld); 
			break; 
		case trgr: 
			ShowSecondForm(); 
			break; 
	} 
	break;

In this case, I have named our button btnAlert, defined an alert called HelloWorld, and so when the button is pressed, our alert is shown. Alerts can also be very useful for debugging, with the FrmCustomAlert being able to show a dialog with information that we pass in. This function takes the id of an alert, and three string values, which then replace the values ^1, ^2 and ^3 within the text of the alert. Note the title is not parsed, only the body. It is necessary to pass an empty string rather than null for unwanted values with this function.

Our selection trigger is named trgr, and it serves to show a second form, which merely has a button on it. We show this form modally, and pressing any button automatically will close it, so no code is needed. Rather than add more code to this example, we cheat and use the same event loop for this form as for our main form. The ShowSecondForm function looks like this:

void ShowSecondForm() 
{ 
	// Create form 
	FormPtr frm = FrmInitForm(frmSecond); 
	// Cheat - use our event handler, as it won't be called upon to do anything anyhow 
	FrmSetEventHandler(frm, frmMain_HandleEvent); 
	// Show as a dialog - this returns the ID of the button pressed, 
	// just like windows, but in this case we don't care 
	FrmDoDialog(frm); 
	// Clean up 
	FrmDeleteForm(frm); 
}

Finally, we need some code to set up our popup. We actually do this entirely within the resource file, although it can be done programatically. We need to associate the popup with a list, and populate that list. In PilRC, it looks like this:

POPUPTRIGGER "Select" ID popup AT (11 61 42 11) 
POPUPLIST ID popup popList 
LIST "Ozzy" "Sharon" "Aimee" "Kelly" "Jack" ID popList AT (11 61 44 0) NONUSABLE DISABLED FONT 0

I've set up a list that contains the names of the Osbourne family, positioned it at the same location as the trigger, with 0 height so that it will work it out itself, and made it invisible. The POPUPLIST item simply links the trigger to the list.

Conclusion

Well, I hope you find this information useful. We've covered a fair bit of ground, in a fairly whirlwind manner. Next up we will talk about databases, and how to persist information to the Palm, then we will be in a position to discuss lists and tables. Once we have that basic information under our belt, we can start to build a real application. I welcome any feedback, there are areas I am being vague because I do not want to favour one IDE. If however the information is hard to follow as a result, I will make changes, although they will of necessity favour the IDE I am using.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Australia Australia
Programming computers ( self taught ) since about 1984 when I bought my first Apple ][. Was working on a GUI library to interface Win32 to Python, and writing graphics filters in my spare time, and then building n-tiered apps using asp, atl and asp.net in my job at Dytech. After 4 years there, I've started working from home, at first for Code Project and now for a vet telemedicine company. I owned part of a company that sells client education software in the vet market, but we sold that and I worked for the owners for five years before leaving to get away from the travel, and spend more time with my family. I now work for a company here in Hobart, doing all sorts of Microsoft based stuff in C++ and C#, with a lot of T-SQL in the mix.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey20-Feb-12 19:46
professionalManoj Kumar Choubey20-Feb-12 19:46 
GeneralEvent Queue Pin
kalm16-Dec-02 4:51
kalm16-Dec-02 4:51 
GeneralPalm Apps Pin
Alex Gusev11-Dec-02 2:08
Alex Gusev11-Dec-02 2:08 
GeneralRe: Palm Apps Pin
Christian Graus11-Dec-02 9:51
protectorChristian Graus11-Dec-02 9:51 
GeneralRe: Palm Apps Pin
Alex Gusev11-Dec-02 11:42
Alex Gusev11-Dec-02 11:42 
GeneralRe: Palm Apps Pin
ting66814-Nov-04 20:25
ting66814-Nov-04 20:25 
GeneralRe: Palm Apps Pin
Christian Graus15-Nov-04 8:46
protectorChristian Graus15-Nov-04 8:46 
Generalassigning Alert Buttons to Hard buttons Pin
ShanKonduru27-Nov-02 2:00
ShanKonduru27-Nov-02 2:00 
GeneralRe: assigning Alert Buttons to Hard buttons Pin
Christian Graus27-Nov-02 9:42
protectorChristian Graus27-Nov-02 9:42 
GeneralCool article CG! Pin
Amit Dey5-Nov-02 9:46
Amit Dey5-Nov-02 9:46 
GeneralRe: Cool article CG! Pin
Christian Graus5-Nov-02 10:07
protectorChristian Graus5-Nov-02 10:07 
GeneralOooh, Another one!! Pin
Jamie Nordmeyer5-Nov-02 4:51
Jamie Nordmeyer5-Nov-02 4:51 
GeneralRe: Oooh, Another one!! Pin
Joao Vaz5-Nov-02 5:56
Joao Vaz5-Nov-02 5:56 
GeneralRe: Oooh, Another one!! Pin
Jason Henderson5-Nov-02 6:23
Jason Henderson5-Nov-02 6:23 
GeneralRe: Oooh, Another one!! Pin
Joao Vaz5-Nov-02 6:43
Joao Vaz5-Nov-02 6:43 
GeneralRe: Oooh, Another one!! Pin
Christian Graus5-Nov-02 9:14
protectorChristian Graus5-Nov-02 9:14 
GeneralRe: Oooh, Another one!! Pin
Joao Vaz5-Nov-02 14:18
Joao Vaz5-Nov-02 14:18 
GeneralRe: Oooh, Another one!! Pin
Christian Graus5-Nov-02 14:27
protectorChristian Graus5-Nov-02 14:27 
GeneralRe: Oooh, Another one!! Pin
Joao Vaz5-Nov-02 14:32
Joao Vaz5-Nov-02 14:32 
GeneralRe: Oooh, Another one!! Pin
Christian Graus5-Nov-02 14:42
protectorChristian Graus5-Nov-02 14:42 
GeneralRe: Oooh, Another one!! Pin
Joao Vaz5-Nov-02 14:50
Joao Vaz5-Nov-02 14:50 
GeneralRe: Oooh, Another one!! Pin
Christian Graus5-Nov-02 15:07
protectorChristian Graus5-Nov-02 15:07 
GeneralRe: Oooh, Another one!! Pin
Joao Vaz5-Nov-02 15:08
Joao Vaz5-Nov-02 15:08 
GeneralRe: Oooh, Another one!! Pin
Christian Graus5-Nov-02 15:18
protectorChristian Graus5-Nov-02 15:18 
GeneralRe: Oooh, Another one!! Pin
Joao Vaz5-Nov-02 15:17
Joao Vaz5-Nov-02 15:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.