Palmphi

Share the joy
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Palmphi is a Windows desktop tool for visual design and PalmOS code generation.
The main features are

  • WYSIWYG.
  • Visual design
  • Object inspector for controls and forms, like many visual IDEs (Delphi, Visual Basic,…).
  • Class browser with help, so you get instantly information about each method.
  • Code autocompletion, just type the name of an object and after pressing '.' you get all methods and properties for this object.
  • The programming language is C, but you can use some predefined objects.
  • The source code is preprocessed to allow a further level of abstraction, adding pseudo-objects that can be accessed through properties and methods.

Besides, you don’t have to bother anymore with the installation of the individual components (pilrc, prctools, …) for the environment as I have developed also an installer.

 

FAQ – Palmphi

General

What is the latest version of Palmphi and where can I get it ?

You can get the latest version by clicking to the link “Product URL” in the About box in Palmphi. At this page you can see under the logo the current version.

Can I be notified when new versions of Palmphi are available ?

Not for every single version, as currently there are around five new versions every week. Though you can suscribe the mailing list of yahoo and select “mail me only for special notices”, every time I consider having made a big step in the development I will post a special notice to yahoo.

Is there a mailing list for Palmphi?

Better yet! there is a Yahoo Group. Use it as mailing list to post your questions and share code and experiences.

How much costs Palmphi ?

Nothing. It is freeware. You shouldn’t make money with it without sharing a part with me though, but this is up to you.

Where comes this strange name from?

Well you probably guessed where the part “Palm” comes from. The second part “phi” comes from my favorite language “Delphi” which I consider the best one for small applications like this and which inspired me to do something similar for the Palm.

Where can I get help ?

To get started with Palmphi use the tutorials. To know more about what you can do with each object use the Class browser. You can take a look at the samples too. Finally, if you have a question post it to the yahoo group or send me a mail.

Will Palmphi ever support xxxxx?

I don’t know. I am a complete beginner with PalmOS development. If you want Palmphi to do something you will have to teach me first how it works with C + Palm SDK.

Is Palmphi compatible with OS x.x ?

I own a Palm m100 and I can say for sure that Palmphi works fine with it. For other OS I didn’t try. I have tested many applications with the simulator provided by Palm and have improved many compatibility issues. So unless you do something special it should work everything. Feedback at this issue is, of course, welcome.

I can’t see any colors with programs created with Palmphi !

If you want colors, you will have to dive into the Palm API as I don’t have color and I don’t know how to use it. If you learn how it works, I would appreciate if you tell me how I can implement it in Palmphi for other users.

I am interested in the source code, can you send it to me ?

Yes, download it from the Files section. If you change anything and want other people to use your change you may consider sending your modifications back to me.

What are your future plans for Palmphi?

I have stopped inplementing more functionality, now I am trying to make it as stable and bug-free as possible. Every feedback is welcome.

After I have something stable I will probably inprove the parser, add new classes or automatize frequently used tasks (like allowing to link components that work together)

Could you please implement this cool feature?

Sure!, send it to me. I can’t promise you anything, but I will surely take it into account.

Programming language

Is this C or C++?

This is C. Sometimes it looks like C++. Specially when you use a method for one of the visual objects. But these is just like a #define, before the program is compiled every object and method is substituted to plain C.

Why not use C++ ?

C++ is very nice, but it uses the memory too generously for a Palm Device. Also there is no easy way to create properties and I wanted to have writable properties for every object, so I can write Edit1.Enabled=0;

Can I create a class with Palmphi ?

Not yet. You can add the class to the file parser.c . The format shouldn’t be difficult to understand. But you can have member functions and member properties but no member variables. In the future this might change.

How is the program compiled ?

– A header file is created with the resources of the program
– A C file is created containing :

  • Needed header files (as #include)
  • Definitions for the dimensions of each object
  • Declarations of all the events which are defined
  • Definition of all the TGadget private structs
  • StartApplication function which calls Application.OnStart (if any) and initializes all the fonts whose AutoInit is true
  • StopApplication function which calls Application.OnTerminate (if any)
  • A definition of needed temporary storage variables for TTable’s, TListbox’es and TScrollBox’es
  • An event handler for each TForm which calls all defined events. The handler does also following :
  • Translates the coordinates of the pen and calls each OnPenDown / OnPenUp / OnPenMove with the coordinates relative to the left/upper corner of the component
  • Calls the OnPaint events of all components which need to repaint
  • Reserves memory to store strings needed by tables with AutoInit=True upon frmOpenEvent
  • Reserves List handles for each TListBox
  • Initializes the tables with the default types and values (if AutoInit=True)
  • Initializes TEdit’s with the default values
  • Frees reserved memory on frmCloseEvent
  • A global event handler for the whole Application
  • EventLoop function which fetches and dispatch all the events
  • A PilotMain function which launches the application
  • Each of the .c files of the project appended.
  • Appropiate directives are also included, so you get the right line and filename when an error occurrs.

– This C file is parsed completely and “translated” to plain C
– A makefile is created
– A new cygwin.bat is created, which mountes your project directory accessible to cygwin.
– A script file is created to run makefile on your project.
– Output data of the compiler is processed and showed to you
– Temporary files are deleted.

Isn’t this process a bit slow ?

Probably, but who cares? Computers now are fast enough to process this, I use an Athlon 900 Mhz and compiling the second time (after everything is in the cache) won’t take over 2 secs.

Where is the resulting .prc?

The resulting prc file is in your project directory. You can synchronize normally to your palm or use an emulator.

Is there an emulator ?

If you are a serious developer you will probably want to use a palm emulator. There is one at the Palm site working very well. You can just drag and drop the prc files to the emulator and you can see in seconds if your program does what you want or only what you told it to do. I don’t distribute any emulator nor roms, so don’t bother asking me.

This version of cygwin/prctools/palmsdk you have is very old !

I found this version to work perfectly for what I need. You don’t have to use it necessarily, every version new or old of each product should work as well.

Why is not the API function XXXXX in Palmphi ?

Every API function is in Palmphi, as Palmphi is just a front-end to the API. So if you have, let’s say, a TEdit and you want to use the function FldScrollField just use it ! TEdit is an alias for FieldPtr so you can write FldScrollField(Edit1,2,up);

Other questions

I get a message, that my version is old and have to update, what is this?

For each new version there is about one month buffer for use time. After this month you are prompted to update. You still can use the program normally, but each time you start it you will get the prompt. I will make this buffer bigger and bigger as the version becomes more stable.

The project directory is full of files, what do they mean?

Your source code is stored in the .c files. The resource information (Forms, Objects, etc) are stored in the .pprj file. The rest are temporary files created by the compiler and parser. In particular you may want to take a look to the .c file which has the same name as the project, this file contains the plain C code ready to be compiled.

My question is not here. What now?

Send me a mail. I normally answer in less than one day.

 

Translating Palmphi into your language


Most of the strings in Palmphi are contained in the file help.txt. This help supports now HTML tags and some parts are completely in HTML format.

The main file (“help.txt”) following structure :

# comments
# comments
LANGUAGE Spanish
Title1
=>Explanation
Title2=>Explanation
=>(Can have more than one line)
.
.
.
TitleN
=>ExplanationINCLUDE moreHelp.txtLANGUAGE French
Title1=>Explanation in french for Title2
=>This explanation contains <b>bold</b> and <i>italic</i> html tags
Title2
=>Explanation in french for Title2
.
.
.
TitleN
=>Explanation in french for TitleN
TitleHTML
=><h4> TitleHTML </h4>
=>This is a full HTML code<br>
=>You need to specifify tag Br <br>
=>at the end of each paragraph.
LANGUAGE German.
.
same for each language
.
.<< Add additional languages here >>LANGUAGE EnglishTitleA =>Explanation in english for TitleA
Title2
=>Explanation in english for Title2
TitleA2
=>Explanation in english for TitleA2
Title1
=>Explanation in english for Title1
INCLUDE PalmApi.txt



INCLUDE has the same functionality as ‘#include’ in C. PalmApi.txt is included at the end of help.txt

Palmphi loads strings as follows: Given a keyword (let’s say “Title1”) it looks first in your default language, if it founds the string, the explanation is displayed (explanation is composed of all the lines following the entry title which begin with “=>”). In this case Title1 exists in every language, so it would always be localized for every language.

If a given string is not found in the default language then it is load from the english part of the file.

When Palmphi loads a help text, it treats the code as HTML if the first line begins with <H4>. If this is not the case, each line gets a “<BR>” appended.

Adding a new language

To add a new language simply add the line “LANGUAGE <language_name>” before the definition of the english language. Then add all the sections you want to translate. The entries you don’t add will appear in english.

Adding entries to a language

If you are already using your local language and you find some texts still appearing in english, is probably due to new help items which aren’t still translated. You can open the help file and search this string, once you find it copy the whole entry to your languages section and translate the entry. After restarting Palmphi you should get the new text translated.

Modifying entries

After modifying anything you will have to restart Palmphi in order to see the updated data.

Format of the entries

There are some predefined formats for the entry titles :

  • Line ends with “()” : Function which are displayed in the class browser
  • Line ends with “:” : This is a string resource used in the program
  • Line ends with “=”: A property
  • Line ends with “>>”: An example (displayed under the html help in the class browser)
  • ExtraGroups: This topic contains all the extra API-sections. Each section has following format:
    • %s1:%s2 where %s1 is the name of the section and %s2 the name of the topic containing the functions of this section

 

Palmphi & CPDB

To use CPDB in your Palmphi application follow these steps (Palmphi 1.43b or newer is required) :

1. At the top of the first source code window write :

#include “CPDBSTD.h”
CPDB_USELIB

2. In the handler for TApplication.OnStart write :
CPDB_OPENLIB
3. In the handler for TApplication..AfterDestroy write :
CPDB_CLOSELIB

Done!

After doing this the minimum program should look like this :

#include “CPDBSTD.h”
CPDB_USELIBEVENT pdb_reader_OnStart(EventPtr event)
{
CPDB_OPENLIB
}EVENT pdb_reader_AfterDestroy(EventPtr event)
{
CPDB_CLOSELIB
}

You will need the file CPDBSTD.h in your project directory. If you are planning to use CPDB in several projects, you may consider copying it to the include directory in cygwin (($CYGWIN)/m68k-palmos/include and using

#include <CPDBSTD.h>
CPDB_USELIB

instead.

1. A brief Tutorial : Your first Application


Install the application

To install the application you only need to copy the exe file (palmphi.exe) to any directory in your harddrive. The file “parser.c” must be copied into the same directory. An explanation about what this file does, can be found here:

parser.c

Before a program is compiled, Palmphi parses every source code and makes some substitutions and add some functions depending on what you wrote. For example : It can be so easy as Form1.Show() becomes FrmGotoForm(_Form1) or as difficult as Label3.Caption=”hello” where the label is deleted and created again with the new text. This parsing is made according a master file called parser.c

Following lines can be found in the file edit.ppc (a file included by parser.c). These here are only examples, the real file can differ from this one. You can also change this file to add new methods or pseudo-classes if you want. Be warned though that an error on this file can mean that the program is not usable or that your code will behave different. I would appreciate that you send me modified versions of this file, if you find your modifications useful for other people.

You may be asking your self, why not use C++ to make this and get full C++ classes?. The two key reasons for me have been the following:
– C produces smaller executables than C++
– C++ doesn’t allow lvalues. (I know with a little effort you can simulate this, but is anyway not as easy as here)

Think of this parser.c as a class library definition, it allows to write programs at a level somewhat higher than plain C sometimes like C++ or Object Pascal.

Let’s start with an example. The code :

  • Edit1.Text=”Hello World”;

Will be parsed according to the part of “parser.c” which defines a TEdit class (I assume, that Edit1 is a TEdit). This part is marked in red in following code:

  • class TEdit=FieldPtr {
    char* Text_() return FldGetTextPtr(THIS);
    char* Text() return $$##$$Edit_TextS(THIS);
    void Copy() FldCopy(THIS);
    void Paste() FldPaste(THIS);
    void Cut() FldCut(THIS);
    void Delete(PAR1,PAR2) FldDelete(THIS,PAR1,PAR2);
    void Draw() FldDrawField(THIS);
    void Empty() FldEraseField(THIS);
    int SelStart() return $$##$$Edit_SelStart(THIS);
    int SelLength() return $$##$$Edit_SelLength(THIS);
    void SetFocus() FldGrabFocus(THIS);
    int Visible() return $$##$$Edit_Visible(THIS);
    int Width() return THIS_width;
    int Top() return THIS_top;
    int Left() return THIS_left;
    int Height() return THIS_height;
    char Enabled() return CtlEnabled(THIS);
    lvalues:
    Enabled CtlSetEnabled(THIS,RVALUE);
    Text $$##$$Edit_SetText(THIS,RVALUE);
    SelStart FldSetSelection(THIS,RVALUE,RVALUE);
    SelLength Edit_SetSelLength(THIS,RVALUE);
    Visible $$##$$Assign_Visible(_THIS,PARENTFORM,RVALUE);
    }

This “$$##$$” means that the following function must be add for the program to be successfully compiled. The parser will get in this case the function Edit_SetText, because in our code Text is a lvalue. Edit_SetText will automatically added to the generated code.

The parser would search for a line “Function Edit_SetText” in parser.c and included files. Once it finds it, it would add all following lines until the line which contains a “}”.

The values RVALUE and THIS are automatically substituted with the right part of the assignation and the object used respectively. The portion $$##$$ is, of course, also removed in the resulting parsed program. So that means we get following code:

  • Edit_SetText(Edit1,”Hello World”);

Edit1 is automatically defined as a FieldPtr if you have added Edit1 as a TEdit on the Form. This is defined at the very first line of the class :

  • class TEdit=FieldPtr {

You can also use such definitions. So it is also possible to do following :

  • TEdit TmpEdit;
    if (val)
    TmpEdit=Edit1;
    else
    TmpEdit=Edit2;
    TmpEdit.Text=”Hello”;

You can use the property Text at the other part of the assignation. So following code is allowed:

  • Edit1.Text=Edit2.Text;

This would be changed in :

  • Edit_SetText(Edit1,Edit_TextS(Edit2));

 

REMEMBER to configure the application for the first time use. Go to Tools|Settings and specify where the root directory of your cygwin installation is. The file “cygwin.bat” can be found there.

Create the Project

First select File| New Project.
Click on the button next to the project name field. Create a directory called “test”. In the directory write “test” as Project name.
As Application Name, write “FirstPalmphi”
As Application ID, write “TST1”

Press OK

Change property values
Now you see the Main Form. Its default name is Form1. The title is also “Form1”. Change the title!. Press F11. Select in the ComboBox of the object inspector the component “Form1”. Change the value for the property Caption. Write “My first app”. Press Enter.

Insert new components
Now insert a Label component (Press the button with the word LABEL under the components in the object inspector, and then click anywhere on to the Form1). Change the caption of the label to something like “Enter your name :”.

NOTE: You can switch any time between Object inspector – Editor with F11. With Shift-F12 you switch between Form and Source file

Insert a new TEdit component. You can see which component corresponds to each button by leaving the mouse cursor over the button for a while. The name of the corresponding component appears.

The new just inserted TEdit is called Edit2. Now make it underlined :go to the object inspector, click on the property value of underlined, now double click the value “False” to change it into “True”, to allow entering data, change the property MaxChars to 10. Make the TEdit big enough to hold a name. Just click on one of the small rectangles and drag.

Now insert a Button. Place it under the Edit2. Change its caption to “OK”. If you followed the right order, your button name is “Button3”.

Now we need a new Form – our greeting form -. Click on the first Component Button (the TForm button). Change the properties of the Form to make it smaller. Or drag it smaller if you prefer. Width and Height should be around 120. Top and Left around 20. Change the caption to an empty string (the title disappears). Change both Modal and SaveBehind to “true”

Now drop a TEdit onto Form2. Make it multiline and big enough to contain more than one line.

Write the code
Now is time to go back to Form1. Press Shift F12 and on the Tab go to Form1.c, now press again Shift – F12. We’ve got our interface. Now we have to write some code.

Double click on out “OK” button. You are now in the code window. Write there :

  • StrCopy(swp,Edit2.Text);
    Form2.PopUp();
  • Declare swp as a Char array;
    It should look like :
  • Char swp[20];
    EVENT Button3_OnClick(EventPtr event)
    {
    Form2.PopUp();
    }

A swap area (swp) must be used to comunicate between forms, because with PalmOS it is not assured that your pointers are not changed between events.

Now switch back to Form2. And press Shift-F12 to got back to the Form. Select Form2 and go to the Events Tab. Locate the Event “OnOpen” and double click it.
You will be directed again to the source window. Write there :

  • Char tmp[50];
    sprintf(tmp,”Hello %s\nHow are you?”,swp);
    Edit4.Text=tmp;

If we want to be able to go back to the previous Form, we have to insert a new button and following code for the OnClick event :

Form2.Back();

Now we are done. Press F9.

You get in the project directory following files : “test.c”,”test.rcp” and “test.mak”.
With a right configured prc-tools and cygwin environment, go to the directory and type :
make -f test.mak

And that’s all. You get a prc file with your program.

More methods for the different components can be found in parser.c. You can define new methods and write them there.

Menu tutorial

1st StepPress the TMenu button.
By pressing this button you create always a new TMenu unless the selected component is already a TMenu. In this case the selected TMenu will be edited.
2nd Step
The menu editing form appears. If you created a new TMenu, everything is empty.The table on the left is the preview of what the menu will be.
The fields on the right are the information related to the selected menu item. You use this fields to change and enter information.You can insert a new item in the current menu column by pressing insert item.
To insert a new menu column, press insert column.To delete an item select it and press “delete”. If you delete all items in a column, the column disappears.
To edit/insert the event associated to an item, double click the cell representing this item.
2a Step
This is an example how you could build a menu.To insert a separator just use “-” as caption.Note that the item Exit has the Accel “x”, it appears in red on the right side of the cell.Note that the assigned name must be unique if you plan to assign an event to the menu. By default a name is built using the valid characters of the caption.
3rd Step
Get sure you assign your menu to the form, where you want to have it.
Ready!And here is the aspect of the selected menu on the palm.
Adding an OnClick eventTo insert a new event double click the item in the table view. For example to add a new event for the menu item “Open” make a double click on point 1. Next time you open the menu editor, you can see that Palmphi has filled the input field “2” for you.Alternatively, if you already have an event handler for this option you can write it in the input field on point 2. Then you can double click on the menu option and Palmphi brings you to the existing event handler.
Adding an acceleratorAn accelerator is a shortcut you can enter with the graffiti keyboard which launches the same command on the menu.To add an accelerator position the cursor onto the option which you want to add an accel. for and insert a letter into the input field “Accel” (marked with the “2”).
Visually, you can see the new accelerator in the table view (here marked with the “1”).Now each time you write / and x in your palm, the event for “Open” will be executed.

Tutorial 4: Tables (TTable)

TTable is a component to assist in the creation of tables on the Palm Pilot. Tables are a way to show structured information without having to care for the coordinates of each element on it. Palm tables are very powerful and have many features, with the class TTable you will be able to use much of them, for more advanced features you will have to access directly the API, remember that as with every component in Palmphi, TTable is just an alias for a pointer to a table (TablePtr).

1. Creating a table

You create a table just like you would do for any other component. Before changing any property a table looks like this :

You can change some properties of the table with the object inspector, but you can change them all by double clicking on it.

This is the table editor. Here you can :
1: Change the amount of columns of the table
2: Change the amount of rows of the table
3: Change the type of the column. If the property AutoInit of the Table is set to true, the table is automatically initialized when the form is open. Following types are now allowed :

  • TCheckBox: Like a normal checkbox
  • TIntLabel: A label which displays only integer values
  • TStrLabel: A label which displays alphanumeric values
  • TDateLabel: A label to display dates
  • TEdit: An editable area in the table

4: Here you can specify the initial value of this cell. If the property AutoInit of the Table is set to true, the cells automatically initialized with their initial values.

5. Here you can see how to access programmatically to this cell.

To change th width of a column, place the mouse over the first row between the arrows (or to the right of the last arrow) and drag to the desired width..

I will use following table for this example :

To abandon the dialog saving the changes press OK on this dialog. Now the table looks like this :

You can now press f9 without writing a single line code and take a look at the compiled program on the palm :

As you see, each cell works as expected. The TEdit seems to have some problems with the selection, but I think that is the default behavior, you have to use one edit on each column to avoid this problem, until I figure out something better (ideas are welcomed).

Now we will be accessing this date from the program. First we will add a button for each cell to copy the contents to a TEdit. For me it looks now so:

We add also a TEdit under the TTable and I will call it MyEdit. Change the MaxChars properties to 25, so we can change it and make it underlined so we can see, where it is.

We write following code for each button (just double click on the button to get to the source editor) :

EVENT Button2_OnClick(EventPtr event)
{
if(Table1.Checked(0,0))
MyEdit.Text="Checked";
else
MyEdit.Text="not Checked";
}

EVENT Button3_OnClick(EventPtr event)
{
Char str[20];
sprintf(str,”%d”,Table1.IntValue(0,1)); // I use this to convert an integer to a string.
MyEdit.Text=str;
}

EVENT Button4_OnClick(EventPtr event)
{
Char str[20];
sprintf(str,”%d-%d-%d”,Table1.ExtractYear(0,2),Table1.ExtractMonth(0,2),Table1.ExtractDay(0,2));
MyEdit.Text=str;
}

EVENT Button5_OnClick(EventPtr event)
{
MyEdit.Text=Table1.TextValue(0,3);
}

You can now run again the program and see what happens when you press the buttons beside the table. It is not very exciting though, as we cannot change the values of the table and always the same value will be copied.

So now, add another button under the TEdit, call it “copyBtn”.

EVENT CopyBtn_OnClick(EventPtr event)
{
Char *str=MyEdit.Text;
if(StrLen(str)>1) {
Char CopyTo=str[0];
if (CopyTo>='1' && CopyTo<='4') {
switch (CopyTo) {
case '4':
Table1.TextValue(0,3)=&str[1];
break;
case '3':
Table1.SetDateValue(0,2,1,2,1903);
break;
case '2':
Table1.IntValue(0,1)=StrToInt(&str[1]);
Table1.Erase(); // Erase the table from the form
Table1.Draw();
break;
case '1':
Table1.Checked(0,0)=str[1]=='C';
Table1.Draw();
break;
}
}
}
}

Now you can run the program and write in to the TEdit something like that :
1C -> To check the checkbox
1N -> To delete the check mark
4Hello -> To write hello to the fourth row
21234 -> To write the value 1234 to the intlabel cell

For the date I write just a fixed value to the cell, well it is not that I am too lazy to decode the string into a date (no no), it is just to keep it simple.

Well I hope, now you know how to access the individual cells of a table. You can learn more taking a look directly to the file parser.c to the section where the table is defined, or seeing the help part on the table editor.

You can download this project, with the prc here.
If you have any questions you can just send an email.
Tutorial 5a: Fonts

1. Using existing fonts

Using fonts with Palmphi is very easy.
If you have a .pfn file already you can simply create a new TFont component pressing the button on the object inspector :

and changing the property File :

To change this property press either cursor-right or click with the mouse over the marked area. Then select the pfn file and press ok. You can also insert directly the name of the file.

You can either initialize the font yourself or let Palmphi do it. By default the property Autoload is true, this means that the Font will be automatically loaded and will be available during the whole life of the program. If you set this property to False you have to write in your program : Font7.Init(); before you attempt to use it.

Whether autoloaded or not, you have now this font available at each control which support fonts : TLabel, TEdit, TButton, TChechbox, TComboBox and TListBox.
Each of these components has a property “Font”. This is a pop-down list which contains the default fonts and now a new one called Font7 or the name you chose for it. The name of the font is followed by the Id of the font (Font7 128), you won’t need this id though.

2. Creating custom fonts

Anyway, probably you won’t have any pfn files and after you looked for them in internet you are a bit disappointed, they are difficult to find. Still there is another possibility, you can create them.

Create a new TFont or use the last created one (as I will do). This time, press the button “Edit font” in the object inspector :


Now the font editor appears and you could edit the individual characters of the font. We don’t have any, so instead a blank area appears “This character is not defined. Press “create” to define one”. Well, you can press Create and edit one by one all the characters you may need. You can leave as much characters undefined as you want, but remember that you can’t use undefined characters in your application. Empty characters are ok, but undefined characters will at least freeze your PalmOS.

There is a more comfortable way to get your characters … Use import from system. A new dialog appears with options, which characters and from which font. For now we will just press Ok in this dialog. Now you are again in the font editor. But now you have a font imported from system.

The buttons in the font editor are self-explanatory. You have two buttons “+”,”-” on the selected row and selected column, they add/delete the Row/column. By deleting/adding a new column you change the width of the character. To change the width of all characters use the button “Change height”. You have hotkeys for this add/del row/col buttons, they appear as a hint when you leave the mouse over them. The buttons “Create” and “Delete” define/ undefine an individual character. If you haven’t defined any character, by creating the first you will be prompted for a height.

You can use “Copy” and “Paste” to copy a character to the clipboard and paste it to another character.

By pressing onto the character number, you are prompted for a new location, so you can easily jump from character 21 to character 233 without clicking on the button “Next character” x times. You can also use PgDn and PgUp to go to next/previous character.

When you are tired of editing you can press Ok to save your changes to the file specified in the “File” property. If you didn’t specify any (as I did) a new file will be created with the name of the font. By pressing Cancel you won’t save anything.

The MemoPad application with Palmphi

In this tutorial we will try to recreate the functionality of the MemoPad standard application provided with each Palm.
I will assume that this is not your first program with Palmphi and that you have already tried some tutorials and know what I mean when I say form, object inspector, etc.

To follow this tutorial please get at least the version 1.10

Step 1. The main list

First, create a new TForm and change the caption to ‘Memo list’. Try to recreate the layout of the original MemoPad. Use 10 VisibleItems in the listbox. Add also a “New” button under the list to allow the user insert new memos. When ready go to the File menu and save the form as “FrmMemoList.c”. The name of the Form changes accordingly.

Define a global variable (I know you don’t like it, but for this example is easier so) for the memo :

TPalmDB MemoDB;

Place it before anything else on the first form (A global variable on the top of the first form is visible for all forms).

Now we have to open the database when starting the program. Go to the event list of the FrmMemoList and double click on the value of OnOpen.

To change the items of the list at runtime, we need to assign a comma delimited list of options to the Items property of the TListBox. So we will need a holder for the items. Declare this on the top of the list:

Char Memos[500]=””;

500 bytes should be enough to contain all the headers of the memos. You can use more if you want. You can allocate it dynamically if you are for elegancy instead of for easiness.

We’ll need a temporary holder for each Title :

Char Title[50];

Now open the database using what you learnt on Tutorial 3:

MemoDB.OpenRW(‘memo’);

Now we iterate every record to extract the title, which is the first line of the memo. A line ends always with the character 0xA. So following code should do it :

Int16 size=MemoDB.RecordSize(i); // Get the memo size
Char *cut,TmpStr[35];
MemoDB.Read(i,Title,50); // We read the first 50 characters of the memo
cut=StrChr(Title,10); // We look for the end of the line
if (cut) *cut=0; // If found, we set the end of the string at this point
if (size>28) // For too long lines we cut at the 28th character
Title[28]=0;
if (StrLen(Memos)>0) StrCat(Memos,”,”); // We append a comma to delimite the last item from this one
sprintf(TmpStr,”%d. %s”,i+1,Title); // We create a header, which is the number of the record and the title
StrCat(Memos,TmpStr); // We append what we got to our Memo items string

The iteration occurs by looping from 0 to MemoDB.RecordCount()-1

After we are ready we assign the result to the TListBox :

ListBox6.Items=Memos;

And we redraw the list to show the changes :

ListBox6.Draw();

NOTES

As you probably guessed, if the title of the memo contains a comma it will be interpreted as an item separator, to avoid this, you should replace the commas :
for(j=0;j<StrLen(Title);j++)
if (Title[j]==',') Title[j]=' ';


So the code could look like this after writing everything :

EVENT FrmMemoList_OnOpen(EventPtr event)
{
Char Memos[500]="";
Char Title[50];
Int16 i,j;
MemoDB.OpenRW('memo');
for(i=0;i<MemoDB.RecordCount();i++)
{
Int16 size=MemoDB.RecordSize(i);
Char *cut,TmpStr[35];
MemoDB.Read(i,Title,50);
cut=StrChr(Title,10);
if (cut) *cut=0;
if (size>28)
Title[28]=0;
for(j=0;j<StrLen(Title);j++)
if (Title[j]==',') Title[j]=' ';
if (StrLen(Memos)>0) StrCat(Memos,",");
sprintf(TmpStr,"%d. %s",i+1,Title);
StrCat(Memos,TmpStr);
}
ListBox6.Items=Memos;
ListBox6.Draw();
}

You can now run the application and see that all the memos are listed in your new program.

Step 2. The Memo contents

Now we need another form to show the contents of a memo.

Press the “new form” button labelled as frm in the object inspector. Save this form as FrmMemoContents.c

This Form must have SaveBehind property set to true, as we want to come back and forth showing memos and coming back to the list. Add a new TEdit component with MultiLine and Underlined set to True. Make it long enough to be able to display several lines.

Add a button to come back to the first form, label it “Done”. This button should call FrmMemoContents.Back() to go back to the first form.
On the first form clicking on a item in the list (OnClick event) will call FrmMemoContents.PopUp()

Create again a global variable to hold the value of the clicked item. Name it SelectedItem and before opening the FrmMemoContents TForm assign the selected item to this variable:
SelectedItem=ListBox6.ItemIndex();

You shouldn’t use member functions of controls in one form from another form, hence we use a temporary global variable to do this.

Loading the contents

You’ve done this before … remember loading the titles? This is easier, because we don’t have to process the contents, just display them. Just do following :

Char MemoContents[2048];
MemoDB.Read(SelectedItem,MemoContents,2048);
Edit8.Text=MemoContents;

Once again, you could make it better, by reserving the necessary memory for the record instead of reserving the maximum size (2048). Dynamic memory is handled with MemPtrNew and MemPtrFree.

Edit8 is the TEdit in the second TForm. For your program the numeration can vary.

If you run now the program, you should be able to see the contents of each memo by clicking on the list.

Step 3. Saving changes

I recommend you backing up your data if you have something important before continuing

As with the standard MemoPad, we want to get our changes saved when pressing “Done”. To do this we just have to change the record size of the current memo to fit the new length of the TEdit. This can be done so :
MemoDB.RecordSize(SelectedItem)=Edit8.Length();
Now the record is prepared to hold the new data. The function Modify uses the same parameters as Read. And this would look like this :
MemoDB.Modify(SelectedItem,Edit8.Text(),Edit8.Length());

If you add this to lines before the call to Back your changes will be saved when you press “Done”

You can now run the program and see if the data is saved when pressing done.

Step 4. Button new

Now we have to add the last functionality. Creating a new memo when pressing “New” button.

There are many ways to do this. I will just set SelectedItem to the number of records and check in the second form for this value. You could as well use another value or a flag.

So the code for pressing the new button would be :
SelectedItem=MemoDB.RecordCount();
FrmMemoContents.PopUp();

When opening the second form, we shouldn’t try to load a record which does not exist :
Char MemoContents[2048];
if(SelectedItem==MemoDB.RecordCount()) {
Edit8.Text="";
} else {
MemoDB.Read(SelectedItem,MemoContents,2048);
Edit8.Text=MemoContents;
}

Similarly, when pressing the button “Done” we shouldn’t try to call Modify on an unexistent record :
if(SelectedItem==MemoDB.RecordCount()) {
MemoDB.Insert(SelectedItem,Edit8.Text(),StrLen(Edit8.Text()));
} else {
MemoDB.RecordSize(SelectedItem)=Edit8.Length();
MemoDB.Modify(SelectedItem,Edit8.Text(),Edit8.Length());
}
FrmMemoContents.Back();

I don’t know why StrLen(Edit8.Text()) is not the same as Edit8.Length(). I just tried it and FldGetTextLength didn’t return the right value. If anyone knows why please tell me …

Anyway, now we have a full working memo. The full listing of the project can you see here :


EVENT ListBox6_OnClick(EventPtr event)
{
SelectedItem=ListBox6.ItemIndex();
FrmMemoContents.PopUp();
}
EVENT FrmMemoList_OnOpen(EventPtr event)
{
Char Memos[500]=””;
Char Title[50];
Int16 i,j;
MemoDB.OpenRW(‘memo’);
for(i=0;i<MemoDB.RecordCount();i++)
{
Int16 size=MemoDB.RecordSize(i);
Char *cut,TmpStr[35];
MemoDB.Read(i,Title,50);
cut=StrChr(Title,10);
if (cut) *cut=0;
if (size>28)
Title[28]=0;
for(j=0;j<StrLen(Title);j++)
if (Title[j]==’,’) Title[j]=’ ‘;
if (StrLen(Memos)>0) StrCat(Memos,”,”);
sprintf(TmpStr,”%d. %s”,i+1,Title);
StrCat(Memos,TmpStr);
}
ListBox6.Items=Memos;
ListBox6.Draw();
}EVENT Button7_OnClick(EventPtr event)
{
SelectedItem=MemoDB.RecordCount();
FrmMemoContents.PopUp();
}
EVENT Button10_OnClick(EventPtr event)
{
if(SelectedItem==MemoDB.RecordCount()) {
MemoDB.Insert(SelectedItem,Edit8.Text(),StrLen(Edit8.Text()));
} else {
MemoDB.RecordSize(SelectedItem)=Edit8.Length();
MemoDB.Modify(SelectedItem,Edit8.Text(),Edit8.Length());
}
FrmMemoContents.Back();
}
EVENT FrmMemoContents_OnOpen(EventPtr event)
{
Char MemoContents[2048];
if(SelectedItem==MemoDB.RecordCount()) {
Edit8.Text=””;
} else {
MemoDB.Read(SelectedItem,MemoContents,2048);
Edit8.Text=MemoContents;
}
}

Step 5. Scrolling (thanks Bill McAllister for the idea)

You may have noticed than looking the memos without a scroll bar is not very comfortable.
From the version 1.10 there is a possibility to link easily a TScrollBar and a TEdit. Simply create a TScrollBar and place it next to the TEdit.
Then write in the OnOpen event :

ScrollBar9.GetValuesFrom(Edit8);

This method initializes the values of the ScrollBar according the length and page size of the TEdit

And now in the OnScroll event of the ScrollBar write following :

Edit8.ScrollFrom(ScrollBar9);

This gets the values of the TScrollBar and scrolls the TEdit consequently.

UPDATE

From version 1.11 you have the possibility to update the TScrollBar indicator each time the user press a key (or introduces a character through graffiti). The code would look like this :

EVENT FrmMemoContents_OnKeyPress(WChar chr,UInt16 Modifiers)
{
if (FrmMemoContents.FocusedControl()==Edit8) {
ScrollBar9.GetValuesFrom(Edit8);
}
}

 


 

Palmphi – CYGWIN

 

Environment Installation

If you haven’t installed cygwin yet, or you have problems with you current version, then read following information.
I have build an installer for cygwin, prctools, PilRC and PalmSDK. Install it, only if you don’t have any other versions or if you don’t mind loosing the ones you have.

  • PilRC (GPL) is being developed by :
(c) 1997-1999 Wes Cherry   wesc@technosis.com
(c) 2000-2002 Aaron Ardiri aaron@ardiri.com
      • palm SDK license can be read after the installation at : ($CYGWIN)\Palmdev\Palm OS SDK Licenses. Before using the software, you should read this license.
      • cygwin (GPL) ‘s homepage can be reached at http://www.cygwin.com/

Steps for installing the software are:
1. Download my installation at the end of this page (You need to download all the four files, Total : 11 Mb) (remember, that I have developed only the installer)
2. Copy all four files to the same directory and execute cygwin.exe
3. When the self-extractor is launched, select a directory to unpack the files which is accessible by old DOS programs (e.g. C:\inst) and execute the program install.exe there.
3. Select a destination for the file “cygwin.bat”, this is where the whole installation is unpacked. Normal directories are C:\CYGWIN or D:\CYGWIN, other should work too. DON’T select C:\Program Files\Cygwin, because “Program Files” won’t be accessible by these unpack utilities. And don’t select C:\cygwin.bat if you don’t want to get zillions of files in your root directory.
4. Wait until the installation is over and answer “yes” to the question if it should perform a test.
5. You can safely delete the installation directory if everything run ok.

As the main program is changing very often, this installer is intended only for the environment. The main program must be downloaded separately.

Troubleshooting
If you have any problem check following :
– Do you have more than one copy of cygwin, in your system? Try deleting the old one. Delete also with the registry editor the path : HKEY_LOCAL_USER\Cygnus Software\cygwin
– Do you have enough free space? with less than 70 Mb don’t even try it !
– If you have deactivated 8.3 filename format mirroring, then you have to copy the installation files to a directory, which is accessible with 8.3 format names. (e.g. c:\inst)
– The test script can be manually executed. It resides on ($CYGWIN) directory. Try executing it manually and seeing what happens.