Palm OS开发常见问题和技巧

  1. 判断当前focus是否为field
index=FrmGetFocus(form); if(index= =noFocus) return(false);
field=FrmGetObjectPtr(form,index);
  1. FrmDoDialog()使用方法:
FrmInitForm
FrmDrawForm set form controls
FrmDoDialog
read form controls
FrmDeleteForm 

注意:FrmDoDialog()无法获得frmOpenEvent。

  1. 测试控件类型:
switch (FrmGetObjectType(pForm, index)) { 
   case frmControlObj: 
   case frmFieldObj: 
   case frmScrollBarObj: 
   default:
}
  1. 在程序里使用标准的edit menu:

If your form has a menubar that consists of just the "Edit" menu, you can specify menu ID 10000 at form creation time. If your form has a menubar with several menus, you should specify your Edit menu like this, using PilRC notation:

PULLDOWN "Edit"
BEGIN
    MENUITEM "Undo" ID 10000 "U"
    MENUITEM "Cut" ID 10001 "X"
    MENUITEM "Copy" ID 10002 "C"
    MENUITEM "Paste" ID 10003 "U"
    MENUITEM "Select All" ID 10004 "S"
    MENUITEM "-" ID 10005
    MENUITEM "Keyboard" ID 10006 "K"
    MENUITEM "Grafitti Help" ID 10007 "G"
END

If you're using Constructor, just create an Edit menu with ID 10000, and the IDs for the items will be provided for you. http://www.palmoswerks.com/2001/11/16

  1. Push button的使用

GroupID若为0则与普通button一样,若GroupID不为0则同组内保证只有一个被选中。 FrmSetControlGroupSelection给push button赋值。

  1. 关于PrefGetAppPreferences

PrefGetAppPreferences要判断返回结果是否为noPreferenceFound

  1. 给文本框(Field)赋值
static void SetFieldText(FormType *form, FieldType *field, Char* value){
    MemHandle newTextH;
    MemHandle oldTextH;
    Char *text;
    newTextH = MemHandleNew(20);
    text = MemHandleLock(newTextH);
    StrCopy(text, value);
    MemHandleUnlock(newTextH);
    oldTextH = FldGetTextHandle(field);
    FldSetTextHandle(field, newTextH);
    if (oldTextH)  
        MemHandleFree(oldTextH);
    if(FrmVisible(form))
        FldDrawField(field);
}
  1. 关于CtlGetLabel()

如果需要CtlGetLabel(),则在CtlSetLabel()时不应立即释放Char*参数,否则CtlGetLabel()得到的将是乱内容。

This function stores the newLabel pointer in the control's data structure. It doesn't make a copy of the string that is passed in. Therefore, if you use CtlSetLabel, you must manage the string yourself. You must ensure that it persists for as long as it is being displayed (that is, for as long as the control is displayed or until you call CtlSetLabel with a new string), and you must free the string after it is no longer in use (typically after the form containing the control is freed). If you never use CtlSetLabel, you do not need to worry about freeing a control's label.

  1. 关于HideState()

HideState()返回代码之一是statXXX而非sysXXX,Palm SDK参考有误。

  1. 最好不要使用全局变量,用Feature代替之。

  2. Simulator没有截屏的快捷键,用Alt+PrintScr代替之。

  3. 让modal dialog全屏的方法

FormType* pOriForm = FrmGetActiveForm();
pForm = FrmInitForm(KeyboardForm);
FrmSetActiveForm(pForm);//Must
FrmSetEventHandler(pForm, KeyboardFormHandleEvent);

formWinH = FrmGetWindowHandle(pForm);
WinSetConstraintsSize(formWinH, 160, 160, 160, 240, 240, 240);
FrmSetDIAPolicyAttr(pForm, frmDIAPolicyCustom);
PINSetInputTriggerState(pinInputTriggerDisabled);
PINSetInputAreaState(pinInputAreaClosed);
SysSetOrientation(sysOrientationLandscape);
StatHide();
  1. 关于RepeatingButton

RepeatingButton响应CtlRepeatEvent而非CtlSelectEvent

  1. Palm simulator与电脑同步

可参考这个网址:http://duchaoqian.blogbus.com/logs/538520.html,注意电话号码用"00"

  1. 多行文本框

Multi-line的text改变内容后要FldRecalculateField(textField, false);否则换行可能不正确。

  1. 关于下拉列表

要产生popSelectEvent,在ctlSelectEvent里一定让handled=false

  1. 关于debug

遇到不知原因的死机等错误,最有效的解决办法是排除法,用if(false){...}不断缩小范围直到找到导致错误的代码。 按下按钮后,若模拟器不是崩溃而是没有反应,很可能是程序陷入了死循环。

  1. JPilotDB的使用方法

JPilotDB提供的lib文件太大,有4M多(因为包含了很多UI和相关lib),如果只是用于在Java里处理.pdb文件完全不需要它的全部内容,精简后的大小为96K,点击下载

代码范例:创建一个.pdb文件

try {
  //Construct the database
    PilotDBSchema schema = new PilotDBSchema();
    PilotDBDatabase database = new PilotDBDatabase("DB Name", "TypeID", "Creator", schema);
    for (int i = 0; i < 10; i++) {
        PilotDBRecord record = database.createRecord();
      record.setRecordData(new byte[]{});//set contents of the record
    }
    //Write to file
    FileOutputStream fos = new FileOutputStream("c:/test.pdb");
    database.write(fos);
    fos.close();
} catch (IOException e) {
    e.printStackTrace();
} catch (PalmDbException e) {
    e.printStackTrace();
}

代码范例:读取一个.pdb文件

try {
    //Read database from file
    FileInputStream fis = new FileInputStream("c:/test.pdb");
    PilotDBDatabase database = new PilotDBDatabase(fis);
    fis.close();
    //Read records of the database
    int recCount = database.getRecordCount();
    for (int i = 0; i < recCount; i++) {
        Record record = database.getRecord(i);
        byte[] bytes = record.getRecordData();
        //deal with the record
    }
} catch (IOException e) {
    e.printStackTrace();
} catch (PalmDbException e) {
    e.printStackTrace();
}

 19. 用程序控制退出当前运行的程序

EvtEnqueueKey (vchrLaunch, 0, commandKeyMask);
  1. Simulator里使用五维方向键(5-Way Navigator):
  • [Alt] + [Enter] = Select
  • [Alt] + [Left Arrow] = Left
  • [Alt] + [Right Arrow] = Right
  • [Alt] + [Up Arrow] = Up
  • [Alt] + [Down Arrow] = Down
  1. 关于Gadget。帮助文档里的例子可能比较旧了,回调(Callback)函数里的第一个参数FormGadgetType类型应改为FormGadgetTypeInCallback类型。此外,第三个void*类型的参数不能直接paramP->eType,要先转换为确定类型才能使用,例如在formGadgetHandleEventCmd里要先EventType* pToEvent = (EventType*) paramP;,然后才可以用 pToEvent->eType来判断事件类型。

  2. 在PODS里使用Palm OS Glue Library,除了在.c文件头部加上#include <PalmOSGlue.h>;外,还要设置这个project的linker配置,否则会提示"Undefined reference"。配置的方法祥见这里。摘抄如下:

    For managed make 68K projects, go to the project properties, and in the C/C++ Build panel, choose PRC-Tools Palm OS 68K Linker/General. Click the "New..." button in the Additional Libraries area, and enter this text into the dialog: -lPalmOSGlue; For a standard make 68K project based on the PalmSource template, in the file "makefile", modify the line for ADDITIONAL_LINK_LIBRARIES to read: ADDITIONAL_LINK_LIBRARIES = -lPalmOSGlue

  3. 判断Form里的对象是否可见:用FrmGlueGetObjectUsable()方法,注意要先加载Glue库。

  4. 根据新闻组里的言论以及自己的试验,FrmReturnToFrom(0)在Debug ROM里很可能有bug,会导致Simulator因内存问题崩溃。

  5. 若两个数据库的TypeID和CreatorID都相同,Palm将视其为同一数据库的两个版本,因此若要枚举出它们,DmGetNextDatabaseByTypeCreator()的第五个参数必须为false(有些应用可能恰恰不需要枚举出每个版本,而只需要最新版本,则应使用true)。

  6. 虽然数据库都是在内存里,但打开一个数据库的开销还是不能忽视,DmOpenDatabase()执行50次的时间大约有0.1秒。

  7. Palm SDK没有提供画圆的函数,可以用画圆角矩形的方法代替,让圆角的半径等于矩形边长一半即可。

  8. 关于使用表格控件的方法,这篇文章介绍的很详细,建议参考:http://www.mit.jyu.fi/~mweber/teaching/docs/palmos/book/ch08.htm

搬家前链接:https://www.cnblogs.com/bjzhanghao/archive/2008/04/14/1152995.html

四种方法修改Palm Simulator使用的ROM

第一次运行Palm OS Garnet Simulator时,模拟器会提示你选择一个ROM文件,但这之后想换其他ROM文件时该怎么做呢?以下四种方法都可以实现:

  1. 在模拟器运行文件(palmsim.exe)所在目录找到palmsim.ini文件,修改里面的ROM项;
  2. 运行模拟器时加-rom参数;
  3. 启动模拟器时按住shift键,模拟器会像第一次运行一样提示你选择一个ROM文件;
  4. 在windows文件管理器里直接把ROM文件拖到palmsim.exe图标上启动。

来自Palm OS Tools Documentation。

Palm OS Developer Suite的安装和使用

终于买了一个掌上电脑,我又开始关注Palm开发了。Palm上虽然可以安装Java虚拟机,但据我所知绝大多数用户受里的Palm并没有安装,让他们为了用你的一个小软件而装虚拟机不太现实,因此只能用C/C++了。大学里学的C语言一直没有实际应用过,所以经过这么多年也和没学差不多,最近通过看wj给我的书,对C语言又有了重新的认识。不过C语言是面向过程的,我在Java里积累的经验似乎帮不上什么忙,边走边看吧。我在“Palm开发”这个分类里记录学习过程,这是第一篇,先介绍一下PODS的使用方法。

如果不熟悉Palm,可以先通过这篇文章了解一下Palm公司的历史和产品。没有掌上电脑也可以开发Palm应用,你可以在模拟器上运行和调试,但我相信把自己编写的应用程序拿在手里的感觉一定不错。

Palm OS Developer Suite(PODS)是PalmSource提供的基于Eclipse的Palm应用程序开发工具,它包含了编译工具、调试工具、模拟器、资源编辑工具和Palm SDK等等,可以在这个地址下载。虽然很多人都使用CodeWarrier开发Palm应用程序,但PODS毕竟是PalmSource官方推出的开发工具,从最初的1.0到现在的1.2版本看来,支持得也不错,加上它是基于我们熟悉的Eclipse平台,更重要的一点它是免费的,所以我还是选择了PODS。当然,用什么工具只能在一定程度上影响开发速度,熟练以后工具间的差别就不那么明显了。

我目前收集到的Palm开发资料主要有这几部分:首先是PalmSource网站上提供的不少pdf文档,对入门者比较有用的是“Palm OS Companion”和“Palm OS Reference”这两份,还有一个“UI Guideline”在设计窗体之前可以看看;另一个是PalmOS的开发者新闻组(news.palmos.com),比较活跃,到现在已经有超过10万个post了;最后就是纸版的图书,我找到的比较新的中文书籍是《PalmOS编程宝典(第二版)》,网上可以找到该书第一版的英文电子版,决定购买以前可以先看一下。

PODS的安装很简单:运行你下载的安装文件就可以了(PODS没有Linux的版本,它带的模拟器也是运行在Windows里的,所以我暂时还是要用回Windows了),可能需要你的机器里事先装有JRE。安装以后在“开始”菜单里会出现PODS组,其中有两个模拟器(Simulator,注意和Emulator的区别),开发OS5及以下应用程序用Garnet Simulator,开发OS6应用程序用Cobalt Simulator,所以我们一般用前者,它的样子见图1。

file
图1 Garnet模拟器

如果你用过Eclipse,对PODS的界面也不会感到陌生,基本上PODS就是在Eclipse里加了个透视图(Perspective)和一些向导,PODS 1.2版本带的Eclipse是3.0.1版本,显得有点过时了(也许可以把PODS那部分拿出来放在新版本Eclipse和CDT里,不知道能不能兼容),图2是PODS的运行界面。

file
图2 PODS的运行界面

环境看得差不多了,现在试着创建第一个Palm应用程序吧。在新建向导里创建“Managed Make 68K C/C++ Project”,如图3。这种应用程序可以运行在各个版本的Palm上,具有最好的兼容性。

file
图3 创建Palm应用程序

按下一步按钮,给项目起个名字“hello”,见图4。

file
图4 给项目起名

按下一步按钮,这里要指定你的应用程序的一些属性,对普通应用程序来说,大部分可以不动,只有“Creator ID”这一项必须改为其他值。按正规的流程,我们首先要在palmos网站上注册自己唯一的ID,然后把这个ID填在这里,目的是避免应用程序间的冲突。因为现在只是试验,随便改成“HELL”就可以了,见图5。

file
图5 修改Creator ID

按下一步按钮,在这一步里PODS提供了一些代码模板,这样可以不用从零开始写每个程序。我们选择“Sample Application”这一项,见图6,这样在向导结束后我们会得到一个很简单的应用程序。

file
图6 选择一个模板

现在直接按Finish按钮结束向导,这时要稍等一会儿,PODS在生成必要的代码和编译它们。简单来看一下生成的代码,主要的程序文件是src目录下的AppMain.c文件,注意它的入口方法不是main()而是PilotMain(),这个文件里的内容以后的帖子里会说明;在rsc目录下生成了名为AppResources.xrd的文件,这是一个资源文件,如果你在PODS里双击它,会打开Palm OS资源编辑器,见图7,在资源编辑器里你可以编辑窗体、定义菜单、定义图标、定义字符串等等。

file
图7 Palm OS资源编辑器

怎样在模拟器里运行这个应用程序呢?首先确认你已经启动了Garnet模拟器;然后在PODS里选择菜单“Run->Run...”,这将弹出一个对话框。在对话框左边选中“Palm OS Application”,然后按下面的New按钮,在“Palm OS Application”下面会出现一个新的节点(运行项);选中这个节点,在对话框右半部分把它的名称改为和项目名一样的“hello”,并确认“Files to install”框里只勾选了hello项目;点击Target属性页,在Device下拉列表里选择“Palm OS Garnet Simulator 5.4”,这个设置很重要,不要忽略。

现在运行项已经配置好了,见图8,按下对话框右下方的Run按钮即可运行程序。注意,以上这个过程对一个项目只需要配置一次就够了,再需要运行可以在PODS的工具栏里直接按Run下拉按钮。

file
图8 为hello项目配置运行项

我们第一个应用程序在模拟器上运行的界面如图9所示。

file
图9 第一个应用程序

你可能已经注意到了,在项目的Debug目录下已经生成了hello.prc文件,这个文件可以直接在Palm设备上运行(方法和安装其他软件一样,通过同步,或者复制到扩展卡上,等等),图10是我们的hello项目在真正的Palm上运行的样子。

file
图10 运行在Palm T|X上的hello项目

搬家前链接:https://www.cnblogs.com/bjzhanghao/archive/2006/06/09/421821.html