Palm OS开发常见问题和技巧
1. 判断当前focus是否为field
index=FrmGetFocus(form); if(index= =noFocus) return(false); field=FrmGetObjectPtr(form,index);
2. FrmDoDialog()使用方法:
FrmInitForm FrmDrawForm set form controls FrmDoDialog read form controls FrmDeleteForm
注意:FrmDoDialog()无法获得frmOpenEvent。
3. 测试控件类型:
switch (FrmGetObjectType(pForm, index)) { case frmControlObj: case frmFieldObj: case frmScrollBarObj: default: }
4. 在程序里使用标准的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
5. Push button的使用
GroupID若为0则与普通button一样,若GroupID不为0则同组内保证只有一个被选中。 FrmSetControlGroupSelection给push button赋值。
6. 关于PrefGetAppPreferences
PrefGetAppPreferences要判断返回结果是否为noPreferenceFound
7. 给文本框(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); }
8. 关于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. ”
9. 关于HideState()
HideState()返回代码之一是statXXX而非sysXXX,Palm SDK参考有误。
10. 最好不要使用全局变量,用Feature代替之。
11. Simulator没有截屏的快捷键,用Alt+PrintScr代替之。
12. 让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();
13. 关于RepeatingButton
RepeatingButton响应CtlRepeatEvent而非CtlSelectEvent
14. Palm simulator与电脑同步
可参考这个网址:http://duchaoqian.blogbus.com/logs/538520.html,注意电话号码用"00"
15. 多行文本框
Multi-line的text改变内容后要FldRecalculateField(textField, false);否则换行可能不正确。
16. 关于下拉列表
要产生popSelectEvent,在ctlSelectEvent里一定让handled=false
17. 关于debug
遇到不知原因的死机等错误,最有效的解决办法是排除法,用if(false){...}不断缩小范围直到找到导致错误的代码。 按下按钮后,若模拟器不是崩溃而是没有反应,很可能是程序陷入了死循环。
18. 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);
20. Simulator里使用五维方向键(5-Way Navigator):
- [Alt] + [Enter] = Select
- [Alt] + [Left Arrow] = Left
- [Alt] + [Right Arrow] = Right
- [Alt] + [Up Arrow] = Up
- [Alt] + [Down Arrow] = Down
21. 关于Gadget。帮助文档里的例子可能比较旧了,回调(Callback)函数里的第一个参数FormGadgetType*类型应改为FormGadgetTypeInCallback*类型。此外,第三个void*类型的参数不能直接paramP->eType,要先转换为确定类型才能使用,例如在formGadgetHandleEventCmd里要先EventType* pToEvent = (EventType*) paramP;,然后才可以用pToEvent->eType来判断事件类型。
22. 在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
”
23. 判断Form里的对象是否可见:用FrmGlueGetObjectUsable()方法,注意要先加载Glue库。
24. 根据新闻组里的言论以及自己的试验,FrmReturnToFrom(0)在Debug ROM里很可能有bug,会导致Simulator因内存问题崩溃。
25. 若两个数据库的TypeID和CreatorID都相同,Palm将视其为同一数据库的两个版本,因此若要枚举出它们,DmGetNextDatabaseByTypeCreator()的第五个参数必须为false(有些应用可能恰恰不需要枚举出每个版本,而只需要最新版本,则应使用true)。
26. 虽然数据库都是在内存里,但打开一个数据库的开销还是不能忽视,DmOpenDatabase()执行50次的时间大约有0.1秒。
27. Palm SDK没有提供画圆的函数,可以用画圆角矩形的方法代替,让圆角的半径等于矩形边长一半即可。
28. 关于使用表格控件的方法,这篇文章介绍的很详细,建议参考:http://www.mit.jyu.fi/~mweber/teaching/docs/palmos/book/ch08.htm