|
对每一个我们要加载的窗体,我们在switch语句中增加case语句来初始化窗体并设置对应的事件处理。 现在是为我们在上一章中分配的内存在做一些工作的时候了。尽管当应用进程从内存卸下时我们的文本句柄将被释放,我们最好还是在PilotMain()末尾显式卸载它,因为关闭窗体不再释放其内的文本句柄。 // CH.4 Deallocate memory MemHandleFree( htext ); // CH.2 We're done return( 0 ); 程序的整洁性是与应用进程是否崩溃的相关的重要因素。当你的程序变得越来越复杂,你的程序代码到处搬动时,有序地分配和释放内存将为你免去应用程序崩溃之灾,为你节约大量时间。 处理Options菜单 我们将按惯例选择菜单项来获得About窗体。因为所有的菜单ID都是唯一的,你仅需在现有的菜单时间处理中为Contacts添加一些代码: // CH.3 Erase the menu status from the display MenuEraseStatus( NULL ); // CH.4 Handle options menu if( event->data.menu.itemID == OptionsAboutContacts ) { // CH.4 Pop up the About form as a Dialog FrmPopupForm( AboutForm ); return( true ); } // CH.3 Handle graffiti help if( event->data.menu.itemID == EditGraffitiHelp ) { // CH.3 Pop up the graffiti reference based on // the graffiti state SysGraffitiReferenceDialog( referenceDefault ); return( true ); } 在调用MenuEraseStatus()之后在MenuEventHandler()中增加的代码将正常运转。你检查新选择项的ID,然后调用FrmPopusForm()。FrmPopusForm()与FrmGotoForm()相似,除了旧的窗体从不关闭。这在About窗体中是恰当的,因为我们知道我们将从About窗体中返回到Contact Detail窗体中。除此之外没有别的路径。 这意味着我们不需要作我们在上一章所做的通用的窗体变换工作。尽管如此,我们最好加上窗体变换代码,这样我们不必担心在加入窗体时使Contact Detail窗体的行为变乱。 注意:在这里我们在处理代码中原本为了处理edit菜单的options菜单。这是怎么回事?原来,Contructor(构造器)给所有菜单的所有菜单项赋予唯一的ID号。因此,没必要单独处理某一组菜单项。 为About窗体加入一个事件处理 每一个窗体应有它自己的时间处理,因此我们为新的About窗体添加一个事件处理。首先,为About窗体的事件处理函数添加一个函数原型,称之为aboutHandleEvent()。代码如下: // CH.3 Prototypes for our event handler functions static Boolean contactDetailHandleEvent( EventPtr event ); static Boolean aboutHandleEvent( EventPtr event ); static Boolean menuEventHandler( EventPtr event ); 然后,在处理frmLoadEvent的事件循环中加入代码。这段代码将对About窗体初始化并以FrmDispatchEvent()为目标加入事件处理函数。 // CH.4 Initialize our form switch( event.data.frmLoad.formID ) { // CH.4 Contact Detail form case ContactDetailForm: form = FrmInitForm( ContactDetailForm ); FrmSetEventHandler( form, contactDetailHandleEvent ); break; // CH.4 About form case AboutForm: form = FrmInitForm( AboutForm ); FrmSetEventHandler( form, aboutHandleEvent ); break; } 剩下的所有的事就是加入时间处理函数aboutHandleEvent()。 // CH.4 Our About form event handler function static Boolean aboutHandleEvent( EventPtr event ) { FormPtr form; // CH.4 A pointer to our form structure // CH.4 Get our form pointer form = FrmGetActiveForm(); // CH.4 Respond to the Open event if( event->eType == frmOpenEvent ) { // CH.4 Draw the form FrmDrawForm( form ); } // CH.4 Return to the calling form if( event->eType == ctlSelectEvent ) { FrmReturnToForm( 0 ); // CH.4 Always return true in this case return( true ); } 事件处理函数对frmOpenEvent应答以唯一的显示窗体基本调用:FrmDrawForm()。它也像我们的第一个Hello应用程序一样应答ctlSelectEvent,除了在这一次,它不发送告警,而是调用FrmReturnToForm()。FrmReturnToForm()函数使About窗体被消灭,该窗体的调用窗体(在这里是Contact Detail窗体)被重激活。 注意:在返回调用窗体时返回true是十分重要的。原因是否则Palm OS试图全面处理cltSelectEvent事件,处理工作包括处理在调用FrmReturnToForm中被你消灭的结构。为了避免这些内存恶作剧,在FrmReturnToForm之后总是返回true, 这样窗体会立即消失。 调试 又回到调试了。你的Contact窗体看起来和工作起来和以前一样。当你从Options菜单选择对应项时,你的About窗体会弹出。当你按下它的OK按钮时,窗体返回Contact Detail窗体。Contact Detail窗体含有一个包含原有的Edit菜单和新的Options菜单。About窗体没有菜单条因为我们没有定义它。 如同以前一样,程序在PilotMain()开始执行,按照它通常的路径走下去。当frmLoadEvent 事件被处理时,它初始化Contact Detail窗体的事件处理函数。之后,frmOpenEvent事件被发送到Contact Detail窗体的事件处理函数。在那里,事件被处理,窗体被画出,各个域如以前一样被设置。然后程序等在那里等待事件的发生。 Contact Detail 窗体处于等待输入状态 接下来讲什么? 在下一章中,我们将继续考察更多的基于Palm设备的控件。 源代码 下面是新版本的Contacts.c的所有代码。 // CH.2 The super-include for PalmOS #include // CH.3 Our resource file #include "Contacts_res.h" // CH.3 Prototypes for our event handler functions static Boolean contactDetailHandleEvent( EventPtr event ); static Boolean aboutHandleEvent( EventPtr event ); static Boolean menuEventHandler( EventPtr event ); // CH.3 Our field memory handle static Handle htext; // CH.3 Handle to the text in our edit field #define HTEXT_SIZE 81 // CH.3 Size of our edit field // CH.4 Constants for ROM revision #define ROM_VERSION_2 0x02003000 #define ROM_VERSION_MIN ROM_VERSION_2 // CH.2 The main entry point DWord PilotMain( Word cmd, Ptr, Word ) { DWord romVersion; // CH.4 ROM version FormPtr form; // CH.2 A pointer to our form structure Handle hsrc; // CH.3 Handle to the string resource CharPtr psrc; // CH.3 Points to the text in the resource CharPtr ptext; // CH.3 Points to the text in the edit field EventType event; // CH.2 Our event structure Word error; // CH.3 Error word // CH.4 Get the ROM version romVersion = 0; FtrGet( sysFtrCreator, sysFtrNumROMVersion, &romVersion ); // CH.4 If we are below our minimum acceptable ROM revision if( romVersion < ROM_VERSION_MIN ) { // CH.4 Display the alert FrmAlert( LowROMVersionErrorAlert ); // CH.4 PalmOS 1.0 will continuously re-launch this app // unless we switch to another safe one if( romVersion < ROM_VERSION_2 ) { AppLaunchWithCommand( sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL ); } return( 0 ); } // CH.2 If this is not a normal launch, don't launch if( cmd != sysAppLaunchCmdNormalLaunch ) return( 0 ); // CH.3 Get the initialization string resource handle hsrc = DmGetResource( strRsc, FieldInitString ); // CH.3 Lock the resource, get the pointer psrc = MemHandleLock( hsrc ); // CH.3 Allocate our field chunk htext = MemHandleNew( HTEXT_SIZE ); if( htext == NULL ) return( 0 ); // CH.3 Lock the memory, get the pointer ptext = MemHandleLock( htext ); // CH.3 Initialize it StrCopy( ptext, psrc ); // CH.3 Unlock the field's memory MemHandleUnlock( htext ); // CH.3 Unlock the resource's memory MemHandleUnlock( hsrc ); // CH.3 Release the string resource DmReleaseResource( hsrc ); // CH.4 Go to our starting page FrmGotoForm( ContactDetailForm ); // CH.2 Our event loop do |
| Palm Powered设备上的增强型音频 编写Palm J2ME红外线“聊天”程序 PALM开发教程-… PALM开发教程-… PALM开发教程-… PALM开发教程-… PALM开发教程-… Palm OS上发送和&… Palm OS上常用编&… Palm OS上如何利&… |
| 文章评论 | |||