zcj1122 2003-7-25 08:46
我的DA小程序~~:)
自己学palm编程有一段时间了,因为我以前也没写过什么程序,所一直不敢动手写。
自己倒是写了不少Hello Word这样的没什么用的程序,总觉得能写出来一个有点使用价值的程序是件很神秘的事 有点害怕,不敢动手。不过“palm是我的理想”是唯一一个能让我有点感动的操作系统,所以在放暑假之前我为自己订了一个目标:要在暑假里写出一个有点用的小程序。当时我看上的dumm 的 Ak_Utils我觉得这个程序很好(应该是容易写:redface: ),后来又由eCool 的 Cool DA 这更让我下了写一个同类程序练练手的决心~~~经过我的观察,发现大家很喜欢这种程序:小巧、实用,可是大家对这两个程序又有点遗憾:都没有控制红外和蓝牙的功能,所以我决定在我写的程序里加上红外开关,对于蓝牙,由于我的机子是T650没法调试,所以我没敢把蓝牙开关加进去(要是那位好心人给我提供一个带蓝牙的机子,我一定把蓝牙开关加进去~~~~:lovu: )由于我是第一次写程序~~界面做得不好还请大家多多包涵~,由于DA的资料不好找,我就稍微的说说写这个DA的过程,在这里,我要感谢dumm PilotMian atsea eCool各位大哥的帮助~~真心的说声~~谢谢~~:F:
[img]http://www.tompda.com/bbsimgx/tompda_44835_sss.jpg[/img]
zcj1122 编辑于 2003-7-25 1:26:07
zcj1122 2003-7-25 08:47
刚开始的时候,找了半天找到一个介绍DA的网站,全是英文,看了半天知道了DA程序的入口函数不是PilotMain,是在 code 1000的地方;DA不能有全局变量;可是在CW里怎么设置我还是不会~~多亏了atsea 和eCool 两位大哥耐心的给我说了设置方法如图:
[img]http://www.tompda.com/bbsimgx/tompda_44833_Debug.jpg[/img]
zcj1122 编辑于 2003-7-25 0:55:04
zcj1122 2003-7-25 08:49
设置好这些后,用CW新建一个C项目,把它在xxx . c 文件中的代码除了#include语句外,全删掉,剩下就~~拿出咱得copy and paste神功~~把程序的框架搭起来(copy 我后面附的代码就行啦~~)框架和标准的c程序差不多,无非入口函数、事件循环、GetObjectPtr()这些,其实DA程序只要把编译的项目设置好后,和写一般的程序区别不大
zcj1122 2003-7-25 08:53
这是入口函数:一个struct: typedef struct{Boolean beamONOFF;} BeamStatePrefereces;
void da_main()
{
FormPtr form;
BeamStatePrefereces *beamP;
ExgSocketType socket;
UInt16 valueLen;
beamP=MemPtrNew(sizeof(BeamStatePrefereces));
MemSet(&socket,sizeof(ExgSocketType),0);
form=FrmInitForm(HelloForm);
FrmSetActiveForm(form);
GetBeam(beamP,&socket);//[color=blue]取得红外的状态[/color]
//[color=red]这儿为什么不能调用DrawTime()??,调用了后from退出时field不会消失
[/color]
FrmDrawForm(form);
DrawTime();//读时间,并显示
DrawRAM();//读内存的大小,并显示
DrawBattery();//读电量,并显示
GetCardState();//读扩展卡信息,并显示
event_loop(beamP);//事件循环函数
//[color=blue]设置红外的状态[/color]
ExgControl(&socket,irSetScanningMode,&(beamP-beaONOFF),&valueLen);
FrmEraseForm(form);
FrmDeleteForm(form);
MemPtrFree(beamP);
}
在这里请注意event_loop(beamP);因为DA程序不能有全局变量,所以要在主函数中建立一个struct变量,在需要这个变量的函数之间传递他的指针来修改这个变量。这里我有点不清楚,就是为什么不能在FrmDrawForm(form);之前调用DrawXXX()函数,我觉得既然field属于这个form,那么在后来的FrmEraseForm(form);应该把这个field给删除了呀,为什么不是这样呢??
zcj1122 2003-7-25 08:56
static void event_loop(BeamStatePrefereces *beamP)
{
EventType event;
Boolean done = false;
UInt16 error;
do {
EvtGetEvent(&event, TimePeriod);
if (SysHandleEvent(&event))
continue;
if (MenuHandleEvent(NULL, &event, &error))
continue;
done = handle_event(&event, beamP);//[color=red]beamP被当作全区变量在需要的函数之间传递[/color]
FrmHandleEvent(FrmGetActiveForm(),&event);
} while (!done);
}
没什么好说的,只有一点EvtGetEvent(&event, TimePeriod); TimePeriod是我设置的超时值为一秒,让form每个一秒更新一次。
zcj1122 2003-7-25 08:58
static Boolean handle_event(EventType * eventP,BeamStatePrefereces *beamP)
{
FormType *form;
RectangleType bounds;
Boolean done=false;
Boolean handle=false;
switch(eventP->eType){
case appStopEvent:
EvtAddEventToQueue(eventP);
done=true;
handle=true;
break;
case nilEvent://[color=red]每当超过一秒,就会有这个事件发生,在这里更新各种信息
[/color]
DrawTime();
DrawBattery();
handle=true;
break;
//下面的是判断使用者是不是要退出程序
case penDownEvent:
form=FrmGetActiveForm();
FrmGetFormBounds(form,&bounds);
if(IsOutside(&bounds,eventP->screenX,eventP->screenY))
done=true; //如果done=true则退出程序
handle=true;
break;
// 更新beam的信息
case popSelectEvent:
if(eventP->data.popSelect.listID==Beam_LS){
if(eventP->data.popSelect.selection==1)
beamP->beamONOFF=false;//选了OFF
else
beamP->beamONOFF=true;
}
break;
}
return done;
}
zcj1122 2003-7-25 08:59
剩下的DrawXXX()程序我就不贴在这儿了,因为无非就是分配内存、调用系统函数、获得信息、格式化成字符串、更新field信息,释放内存。我还有点不明白的地方:一开始我曾经想过用Preferecens代替全局变量,结果不起任何作用;也想过用FtrPtrNew(),可是一用就crash~~,请问这是~~为什么~~~为什么~~~~为什么~~~~为什么~~为什么~~~~!!
:em14: :cry:
另外小小的问一声:斑竹大人,可以加点原创分吗?:F:
zcj1122 编辑于 2003-7-25 1:33:25
zcj1122 2003-7-25 09:01
完整的源程序:
[img]http://www.tompda.com/bbs/img/addon.gif[/img][url=http://www.tompda.com/bbs/download.asp?id=tompda_44838_Hello.rar]tompda_44838_Hello.rar[/url]
redgear 2003-7-25 09:12
好厉害!谢谢你!提个小意见:扩展卡小数点后面的位数是不是太多了点?:D:
zcj1122 2003-7-25 09:17
哈哈~~
要是嫌我可以减几位呀~~不过我觉得这样仔细点:F:
中国门牙 2003-7-25 12:09
感谢中~~~~~ :D:
继续加油吧~~~~~
中国门牙 编辑于 2003-7-25 4:09:34
bigyu 2003-7-25 17:13
zcj1122
很不错哦~继续加油啊!
zcj1122 2003-7-25 17:24
谢谢大家的支持~~:F:
eCool 2003-7-25 17:36
[quote]zcj1122 写道:
剩下的DrawXXX()程序我就不贴在这儿了,因为无非就是分配内存、调用系统函数、获得信息、格式化成字符串、更新field信息,释放内存。我还有点不明白的地方:一开始我曾经想过用Preferecens代替全局变量,结果不起任何作用;也想过用FtrPtrNew(),可是一用就crash~~,请问这是~~为什么~~~为什么~~~~为什么~~~~为什么~~为什么~~~~!!
:em14: :cry:
另外小小的问一声:斑竹大人,可以加点原创分吗?:F:[/quote]
[color=blue]Preferences的问题:[/color]
应该是可以的,看看你的程序有没有问题?
[color=blue]FtrPtrNew()的问题:[/color]
因为FtrPtrNew()分配的空间是在Heap空间或者Stack空间(如果heap有足够多,优先使用heap的空间),而da程序由于不能使用heap空间(这个就是为什么da不能使用全局变量的原因),所以如果FtrPtrNew()分配的Heap空间就会crash了,而用MemPtrNew()分配的是stack空间,就行。
[color=red]另:关于field不删除的原因(偶认为):[/color]
因为你的Form设置了Save behind属性,如果在FrmDrawForm()之前使用DrawTime(),而FrmDrawForm()会将当前Form占用的空间保存下来(这样就把时间的field占用的空间也保存了下来),所以当程序退出时恢复屏幕的时候,就出现了时间field.
:F:
eCool 编辑于 2003-7-25 9:52:41
atsea 2003-7-25 17:36
不错!!看来你很刻苦呀,深夜还在做程序:X:。
atsea 2003-7-25 17:42
[quote]zcj1122 写道:
在这里请注意event_loop(beamP);因为DA程序不能有全局变量,所以要在主函数中建立一个struct变量,在需要这个变量的函数之间传递他的指针来修改这个变量。这里我有点不清楚,就是为什么不能在FrmDrawForm(form);之前调用DrawXXX()函数,我觉得既然field属于这个form,那么在后来的FrmEraseForm(form);应该把这个field给删除了呀,为什么不是这样呢??
[/quote]
在Palm OS reference 的FrmDrawForm函数说明中有这么一段话:
If 3.5 New Feature Set is present, FrmDrawForm erases the form's window before performing any drawing. Thus, it is especially important to do any custom drawing after this function call on Palm OS 3.5 and higher.
大意是FrmDrawForm在画操作之前擦除了From的Window,因此任何定制的画操作应该在FrmDrwaForm之后进行。
zcj1122 2003-7-25 17:43
谢谢atsea和eCool的解答~~不过我有点不明白的是:一个程序不是可以有多个Preferences的吗~只要他们的creatid不同就行了~~
zcj1122 编辑于 2003-7-25 9:43:36
eCool 2003-7-25 17:54
[quote]zcj1122 写道:
谢谢atsea和eCool的解答~~不过我有点不明白的是:一个程序不是可以有多个Preferences的吗~只要他们的creatid不同就行了~~
[/quote]
sorry,开始说错了,da是可以用Preferences,:H: ,也许你的代码有问题吧?:?:
zcj1122 2003-7-25 18:03
哦~~我说呢~~:8::X:
无声 2003-7-28 17:07
支持你!继续努力!