PALM开发教程-第七章 列表框和排序 |
| 作者:palmheart 来源:palmheart.net 发布时间:2005-12-21 3:33:26 |
|
,将List ID设置为刚创建的弹出列表框的ID; 3. 在对Contact List窗体修改完毕,其图如下所示。单击窗体编辑器右上角的X按钮关闭,选择File | Save 保存所做修改。 对Contacts.c内容的添加 首先,在文件头添加排序所必需的变量和常量: // CH.7 The sort order variable and constants static Int sortBy; // CH.7 NOTE: These items match the popup list entries! #define SORTBY_DATE_TIME 0 #define SORTBY_FIRST_NAME 1 #define SORTBY_LAST_NAME 2 变量sortBy表示在三个排序标准中的当前值。三个常量代表了弹出列表框中的三个排序标准,注意使它们和列表框的每个选项相对应。 排序的初始化 为了建立排序标准,必须添加代码来处理popSelectEvent事件,此事件在弹出列表框的列表选项被选中时触发。下面的代码是如何根据所选项进行排序: case popSelectEvent: { // CH.7 If there is no change, we're done if( sortBy == event->data.popSelect.selection ) return( true ); // CH.7 Modify sort order variable sortBy = event->data.popSelect.selection; // CH.7 Sort the contact database by the new criteria DmQuickSort( contactsDB, (DmComparF*)sortFunc, sortBy ); // CH.7 Rebuild the list buildList(); } break; 首先,在排序标准没有改变时,避免重复排序。然后保存排序标准,因为在Contact Detail窗体中当有新记录或修改记录后,排序发生了改变,这时又用到了排序标准。最后调用函数DmQuickSort(),此函数将排序标准sortBy传递给函数sortFunc()。在数据库排序完成后,绘制列表框显示。 下面我们研究一下函数sortFunc()。这个函数可以比较前后两个条目的大小,在将数据库中的两条记录比较后,函数返回一个整数。如果此数大于零,则第一个记录排在前面;如果小于零则第二条记录排在前面;如果为零则说明两记录相同。 // CH.7 This function is called by Palm OS to sort records static Int sortFunc( CharPtr precord1, CharPtr precord2, Int sortBy ) { Int sortResult; // CH.7 Switch based on sort criteria switch( sortBy ) { // CH.7 Sort by date and time case SORTBY_DATE_TIME: { DateTimePtr pdateTime1; DateTimePtr pdateTime2; Long lDiff; pdateTime1 = (DateTimePtr)(precord1 + DB_DATE_TIME_START); pdateTime2 = (DateTimePtr)(precord2 + DB_DATE_TIME_START); // CH.7 Compare the dates and times lDiff = (Long)(TimDateTimeToSeconds( pdateTime1 ) / 60 ) - (Long)(TimDateTimeToSeconds( pdateTime2 ) / 60 ); // CH.7 Date/time #1 is later if( lDiff > 0 ) sortResult = 1; else // CH.7 Date/time #2 is later if( lDiff < 0 ) sortResult = -1; else // CH.7 They are equal sortResult = 0; } break; 代码中首先将时间和日期从所选记录中抽出,然后将其转换成秒进行比较。在这个算法中会将无日期的记录放在列表框的顶部,而将无时间的记录放在相同日期的最底部。由于所转换的秒值有可能超过16位整值,所以我们采用32位长整数来进行比较,相应的设置变量sortResult为16位。 // CH.7 Sort by first name case SORTBY_FIRST_NAME: { sortResult = StrCompare( precord1 + DB_FIRST_NAME_START, precord2 + DB_FIRST_NAME_START ); } break; // CH.7 Sort by last name case SORTBY_LAST_NAME: { sortResult = StrCompare( precord1 + DB_LAST_NAME_START, precord2 + DB_LAST_NAME_START ); } break; 调用函数StrCompare()为first name和last name 排序,此函数定义在Developing Palm OS 3.0 Applications Part II:Sytem Management中。它和ANSI C的函数strcmp()十分相似,直接给Palm OS返回一个整值。 排序的记录写入列表框 在移动到另一个记录或退出Contact Detail窗体时,函数getField()都要被调用,因此应该在此函数中添加代码,来保证在添加新记录或修改记录后重新排序。 为达到要求,这些代码应添加在记录内存已被释放但“脏(dirty)”位还没有清除的位置。 // CH.5 If the record has been modified if( isDirty ) { CharPtr precord; // CH.5 Points to the DB record // CH.7 Detach the record from the database DmDetachRecord( contactsDB, cursor, &hrecord ); // CH.5 Lock the record precord = MemHandleLock( hrecord ); // CH.5 Get the text for the First Name field getText( getObject( form, ContactDetailFirstNameField ), precord, DB_FIRST_NAME_START ); // CH.5 Get the text for the Last Name field getText( getObject( form, ContactDetailLastNameField ), precord, DB_LAST_NAME_START ); // CH.5 Get the text for the Phone Number field getText( getObject( form, ContactDetailPhoneNumberField ), precord, DB_PHONE_NUMBER_START ); // CH.7 Find the proper position cursor = DmFindSortPosition( contactsDB, precord, NULL, (DmComparF*)sortFunc, sortBy ); // CH.5 Unlock the record MemHandleUnlock( hrecord ); // CH.7 Reattach the record DmAttachRecord( contactsDB, &cursor, hrecord, NULL ); } 既然只是在记录被改变时重新排序,因此可以先使用isDirty位来判断记录是否已被修改。然后将“脏”的记录从数据库中临时分离出来并将之锁定,最后调用函数DmFindSortPosition()决定应该在列表框的什么地方插入。此函数的前提示列表已经有了正确的排序,由于我们一次只改变或添加一条记录,因此可以满足要求。最后解锁该记录并将之插入到数据库的新位置。 调试 分别在popSelectEvent事件的顶部、函数sortBy()的顶部、函数getField()的if语句的开始处设置断点。检查程序是否能正常运行。下面是一些功能的测试: l 用三个排序标准分别排序,看数据库是否能根据各个标准正确的排序; l 向数据库中添加一个记录,看其是否能排在正确的位置; l 修改一个现存记录,看其是否能排在正确的位置。 下一步做什么 下一章我们将添加更多新的控件,例如表和浏览栏。这一章我们使用列表框显示程序的记 |
| [] [返回上一页] [打 印] |
|
文章评论 |
