PALM开发教程-第九章 分类和查找 |
| 作者:palmheart 来源:palmheart.net 发布时间:2005-12-21 3:36:55 |
|
会对此处理。我经常使用这个空间保存优先权(preferences)或数据库中全局变量。例如,可以使用它来存储数据库结构,由此可以使用代码处理不同类型的数据库。 小技巧 注意我们在这里细致定义了卡号,而不是只指定卡号为0。尽管卡号为0的卡在Palm Compting的设备上一般都能正常工作,但对一些第三方的硬件,特别是Handspring Visor和TRGpro,他们有一块以上的内存卡,为了支持更宽的Palm内存单元,正确的处理卡号在程序中也就变得很重要了。 如果我们没有找到已创建分类的应用程序信息块,就回到开头新建一个。 // CH.9 If there is no application info block, create one if( appInfoID == 0 ) { // CH.9 Allocate an application info block if( (hAppInfo = DmNewHandle( contactsDB, sizeof( AppInfoType ) )) == NULL ) errorExit( MemoryErrorAlert ); // CH.9 Translate the handle to a local ID appInfoID = MemHandleToLocalID( hAppInfo ); // CH.9 Set the application info block DmSetDatabaseInfo( cardNum, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &appInfoID, NULL, NULL, NULL ); // CH.9 Translate the local ID to a pointer pAppInfo = MemLocalIDToLockedPtr( appInfoID, cardNum ); // CH.9 Clear it DmSet( pAppInfo, 0, sizeof( AppInfoType ), 0 ); // CH.9 Initialize the categories CategoryInitialize( pAppInfo, CategoryLabelsAppInfoStr ); // CH.9 Unlock the application info block MemPtrUnlock( pAppInfo ); } 当调用Palm OS的函数CategoryInitialize()时,Palm OS自动地初始化分类。你需将在Constructor中创建的App Info String List ID号传给此函数。保证所使用的字符串就是上一部分中所定义的。如果不是,上面的分类就不会显示或者显示一些垃圾,但CategoryInitialize()的也不会返回错误。 小技巧 你可以在应用程序信息模块中保存任何东西。如果已保存了分类,你只需在应用程序信息模块扩展分类结构,然后添加你想保存的数据就可以了。不过应用程序信息模块中添加的数据必须符合分类结构形式。 对Contact Detail Form的支持 当我们浏览记录时,Contact Detail窗体应正确的显示每一条记录所在的分类,当我们翻动记录时。它也应该允许我们把分类设置为一个记录。 不像常规的弹出触发按纽(Pop-up Trigger),为了使用分类管理器(Category Manager)来处理事件,必须捕捉分类弹出触发按纽的初始值来触发ctlSelectEvent事件,然后使用Palm OS的函数CategorySelect()完成其他所有的工作。我们让事件返回true,来防止Palm OS在一般情况下对一个弹出触发按纽所做的操作(试图弹出一个列表框)。在这里,列表框的创建、弹出和关闭都是通过调用CategorySelect()来完成。 在程序的开始处,我们定义三个变量。变量detailCat代表在Contact Detail窗体中的显示当前记录的分类。ListCat代表Contact List窗体当前的分类。第三个变量talbeIndex,是为浏览特定分类中的记录而定义的,在下一部分中将做详细的解释。 // CH.9 Category variables static Word listCat = dmAllCategories; // CH.9 The current category ID static Word detailCat; // CH.9 Category ID for details static UInt tableIndex[TABLE_NUM_ROWS]; // CH.9 Record indexes for rows 在contactDetailHandleEvent()事件的顶部,需要分配内存来保存分类的名称: Char catName[dmCategoryLength]; // CH.9 Category name 下面是支持分类弹出触发按纽和列表框的代码,将之添加到ctlSelectEvent()事件中: // CH.9 Catch a tap on the category trigger case ContactDetailCategoryPopupPopTrigger: { UInt recAttrs; // CH.9 The record attribs // CH.9 Palm OS will present the popup list for us. CategorySelect( contactsDB, form, ContactDetailCategoryPopupPopTrigger, ContactDetailCategoryListList, false, &detailCat, catName, 1, 0 ); // CH.9 Get the record attributes DmRecordInfo( contactsDB, cursor, &recAttrs, NULL, NULL ); // CH.9 Put in the category bits recAttrs &= ~dmRecAttrCategoryMask; recAttrs |= detailCat; // CH.9 Set the record attributes DmSetRecordInfo( contactsDB, cursor, &recAttrs, NULL ); } // CH.9 Set fields and return true in this case setFields(); return( true ); } 在这里,CategorySelect()几乎完成了所有的困难工作,包括创建和管理列表框和可能要编辑的列表框条目。注意CategorySelect()中的第五个参数为False,这个参数提示CategorySelect()我们是使用列表框选择分类而不是对列表框的条目进行排序。这使CategorySelect()去掉了列表框中的All选项。 CategorySelect()中的第八个参数值(catName后面的一个)是1,提示CategorySelect()防止第一个分类Unfiled被修改。使用这种方式,就可以使很多分类不被修改。 你可以使用最后一个参数指定一个字符串作为分类编辑对话框的标题,来替代原来的Edit Categories。在所有例子中,迄今为止,我认为这个缺省的标题是最好的,所以我总是把它设为0。 注意: Palm OS1.0有它自己版本的CategorySelect()—— CategorySelectV10()。如果你对支持原来的Pilot1000到5000单元有兴趣,就需要使用这个命令。 在调用CategorySelect()后,我们在当前记录的属性位上设置分类的值。首先DmRecordInfo()获取属性位,在做一些位运算后,通过DmRecordInfo()为属性设置新值。在事件处理过程中要做的就是这些。 在newRecord()函数中,我们为创建的每一个记录初始化其分 类。在函数的顶部,需要定义一个变量临时保存记录属性。 UInt recAttrs; // CH.9 The record's attributes 在函数的末尾,和在事件处理函数中一样,我们获得并设置记录的属性。如果在Contact List中我们选择的分类是All,我们就不知道将这个记录到底该放在哪一个分类中,这时我们就把分类设置为Unfiled。如果Contact List上面有一个具体的分类,那么就把记录放在这个分类中。 // Ch.9 Get the record attribute bits DmRecordInfo( contactsDB, cursor, &recAttrs, NULL, NULL ); // C |
| [] [返回上一页] [打 印] |
|
文章评论 |
