📄 contacts.c
字号:
else
// CH.7 Date/time #2 is later
if( lDiff < 0 )
sortResult = -1;
else
// CH.7 They are equal
sortResult = 0;
}
break;
// 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;
}
// CH.7 We're done
return( sortResult );
}
// CH.8 Draw our list of choices using a table object
static void drawTable( void )
{
FormPtr form;
TablePtr table;
Int column;
Int count;
// CH.8 Get the form pointer
form = FrmGetActiveForm();
// CH.8 Get the table pointer
table = getObject( form, ContactListTableTable );
// CH.8 For all columns
for( column = 0; column < TABLE_NUM_COLUMNS; column++ )
{
// CH.8 Set the draw routine
TblSetCustomDrawProcedure( table, column, drawCell );
// CH.8 Make the column visible
TblSetColumnUsable( table, column, true );
}
// CH.8 Initialize the table styles
for( count = 0; count < TABLE_NUM_ROWS; count++ )
{
// CH.9 If there is data
if( tableIndex[count] != 0xffff )
{
// CH.8 Show the row
TblSetRowUsable( table, count, true );
// CH.8 Set the cell styles
for( column = 0; column < TABLE_NUM_COLUMNS; column++ )
TblSetItemStyle( table, count, column, customTableItem );
}
else
// CH.8 Hide unused rows if any
TblSetRowUsable( table, count, false );
}
// CH.8 Draw the table
TblDrawTable( table );
// CH.8 We're done
return;
}
// CH.8 The custom drawing routine for a table cell
static void drawCell( VoidPtr table, Word row, Word column,
RectanglePtr bounds )
{
Int record;
CharPtr precord;
Char string[DB_FIRST_NAME_SIZE + DB_LAST_NAME_SIZE];
SWord width;
SWord len;
Boolean noFit;
// CH.9 Calculate our record
record = tableIndex[row];
// CH.8 Get our record
hrecord = DmQueryRecord( contactsDB, record );
precord = MemHandleLock( hrecord );
// CH.8 Get the date and time
MemMove( &dateTime, precord + DB_DATE_TIME_START,
sizeof( dateTime ) );
// CH.8 Switch on the column
switch( column )
{
// CH.8 Handle dates
case TABLE_COLUMN_DATE:
{
if( dateTime.year != NO_DATE )
{
DateToAscii( dateTime.month, dateTime.day,
dateTime.year,
(DateFormatType)PrefGetPreference(
prefDateFormat ), string );
}
else
StrCopy( string, "-" );
}
break;
// CH.8 Handle times
case TABLE_COLUMN_TIME:
{
if( dateTime.hour != NO_TIME )
{
TimeToAscii( dateTime.hour, dateTime.minute,
(TimeFormatType)PrefGetPreference(
prefTimeFormat ), string );
}
else
StrCopy( string, "-" );
}
break;
// CH.8 Handle names
case TABLE_COLUMN_NAME:
{
StrCopy( string, precord + DB_FIRST_NAME_START );
StrCat( string, " " );
StrCat( string, precord + DB_LAST_NAME_START );
}
break;
}
// CH.8 Unlock the record
MemHandleUnlock( hrecord );
// CH.8 Set the text mode
WinSetUnderlineMode( noUnderline );
FntSetFont( stdFont );
// CH.8 Truncate the string if necessary
width = bounds->extent.x;
len = StrLen( string );
noFit = false;
FntCharsInWidth( string, &width, &len, &noFit );
// CH.8 Draw the cell
WinEraseRectangle( bounds, 0 );
WinDrawChars( string, len, bounds->topLeft.x, bounds->topLeft.y );
// CH.8 We're done
return;
}
// CH.9 Initialize the row information by finding the right records
static void initIndexes( void )
{
FormPtr form;
Int count;
UInt index = cursor;
ControlPtr downArrow;
ControlPtr upArrow;
UInt numRecsInCategory;
// CH.9 Get the current form
form = FrmGetActiveForm();
// CH.9 For each table row
for( count = 0; count < TABLE_NUM_ROWS; count++ )
{
// CH.9 Find the next matching record
if( DmSeekRecordInCategory( contactsDB, &index, 0,
dmSeekForward, listCat ) )
{
// CH.9 No more records. Fill the rest of the array with
// 0xffff
for( ; count < TABLE_NUM_ROWS; count++ )
tableIndex[count] = 0xffff;
break;
}
// CH.9 Put the index number in the array
tableIndex[count] = index;
index++;
}
// CH.9 Set the cursor to a known category record
cursor = tableIndex[0];
// CH.8 Get pointers to the arrow buttons
upArrow = getObject( form, ContactListRecordUpRepeating );
downArrow = getObject( form, ContactListRecordDownRepeating );
// CH.8 Update the arrow buttons and scrollbars
numRecsInCategory = DmNumRecordsInCategory( contactsDB, listCat );
if( numRecsInCategory > TABLE_NUM_ROWS )
{
UInt position = DmPositionInCategory( contactsDB, cursor,
listCat );
// CH.8 Show the up arrow
if( position > 0 )
{
CtlSetLabel( upArrow, BLACK_UP_ARROW );
CtlSetEnabled( upArrow, true );
}
else
{
CtlSetLabel( upArrow, GRAY_UP_ARROW );
CtlSetEnabled( upArrow, false );
}
CtlShowControl( upArrow );
// CH.8 Show the down arrow
if( position >= numRecsInCategory - TABLE_NUM_ROWS )
{
CtlSetLabel( downArrow, GRAY_DOWN_ARROW );
CtlSetEnabled( downArrow, false );
}
else
{
CtlSetLabel( downArrow, BLACK_DOWN_ARROW );
CtlSetEnabled( downArrow, true );
}
CtlShowControl( downArrow );
// CH.9 Show the scrollbar
SclSetScrollBar( getObject( form,
ContactListScrollbarScrollBar ), position, 0,
numRecsInCategory - TABLE_NUM_ROWS, TABLE_NUM_ROWS );
}
else
{
// CH.8 Hide the arrows
CtlHideControl( upArrow );
CtlHideControl( downArrow );
// CH.8 Hide the scrollbar
SclSetScrollBar( getObject( form,
ContactListScrollbarScrollBar ), 0, 0, 0, 0 );
}
// CH.9 We're done
return;
}
// CH.9 Scroll a certain number of records in the current category
static void scrollIndexes( Int amount )
{
FormPtr form;
UInt count;
UInt index;
ControlPtr downArrow;
ControlPtr upArrow;
UInt numRecsInCategory;
// CH.9 Get the current form
form = FrmGetActiveForm();
// CH.9 Get pointers to the arrow buttons
upArrow = getObject( form, ContactListRecordUpRepeating );
downArrow = getObject( form, ContactListRecordDownRepeating );
// CH.9 If we're scrolling down
if( amount > 0 )
{
// CH.9 While there is still an amount to scroll
while( amount-- )
{
// CH.9 Get a new index after the last one
index = tableIndex[TABLE_NUM_ROWS - 1];
if( DmSeekRecordInCategory( contactsDB, &index, 1,
dmSeekForward, listCat ) )
{
// CH.9 No more records. We're done scrolling
CtlSetLabel( downArrow, GRAY_DOWN_ARROW );
CtlSetEnabled( downArrow, false );
return;
}
// CH.9 Move current indexes up one
for( count = 0; count < TABLE_NUM_ROWS - 1; count++ )
tableIndex[count] = tableIndex[count + 1];
// CH.9 Put the index number in the array
tableIndex[count] = index;
}
// CH.9 Disable the down arrow if needed
if( DmSeekRecordInCategory( contactsDB, &index, 1,
dmSeekForward, listCat ) )
{
CtlSetLabel( downArrow, GRAY_DOWN_ARROW );
CtlSetEnabled( downArrow, false );
}
// CH.9 Enable the up arrow
CtlSetLabel( upArrow, BLACK_UP_ARROW );
CtlSetEnabled( upArrow, true );
}
else
// CH.9 If we're scrolling up
if( amount < 0 )
{
// CH.9 While there is still an amount to scroll
while( amount++ )
{
// CH.9 Get a new index before the first one
index = tableIndex[0];
if( DmSeekRecordInCategory( contactsDB, &index, 1,
dmSeekBackward, listCat ) )
{
// CH.9 No more records. We're done scrolling
CtlSetLabel( upArrow, GRAY_UP_ARROW );
CtlSetEnabled( upArrow, false );
return;
}
// CH.9 Move current indexes down one
for( count = TABLE_NUM_ROWS - 1; count > 0; count-- )
tableIndex[count] = tableIndex[count - 1];
// CH.9 Put the index number in the array
tableIndex[count] = index;
}
// CH.9 Disable the up arrow if needed
if( DmSeekRecordInCategory( contactsDB, &index, 1,
dmSeekBackward, listCat ) )
{
CtlSetLabel( upArrow, GRAY_UP_ARROW );
CtlSetEnabled( upArrow, false );
}
// CH.9 Enable the down arrow
CtlSetLabel( downArrow, BLACK_DOWN_ARROW );
CtlSetEnabled( downArrow, true );
}
// CH.9 Set the cursor
cursor = tableIndex[0];
// CH.9 Set the scrollbar
numRecsInCategory = DmNumRecordsInCategory( contactsDB, listCat );
SclSetScrollBar( getObject( form,
ContactListScrollbarScrollBar ), DmPositionInCategory(
contactsDB, cursor, listCat ), 0,
numRecords - TABLE_NUM_ROWS, TABLE_NUM_ROWS );
// CH.9 We're done
return;
}
// CH.9 Find a particular index
static UInt findIndex( UInt scrollValue )
{
UInt index = 0;
// CH.9 Seek from zero to the scrollvalue
DmSeekRecordInCategory( contactsDB, &index, scrollValue,
dmSeekForward, listCat );
// We're done
return( index );
}
// CH.9 Find something in our records
static void find( Ptr params )
{
FindParamsPtr findParams = (FindParamsPtr)params; // CH.9 Params
DmOpenRef contactsDB; // CH.9 Our local database ptr
UInt numRecords; // CH.9 Number of records in the db
LocalID dbID; // CH.9 Local ID of the database
UInt cardNum; // CH.9 Card number
UInt cursor; // CH.9 The current record
VoidHand hrecord; // CH.9 Handle to the record
CharPtr precord; // CH.9 Pointer to the record
DateTimeType dateTime; // CH.9 Date and time in this record
Char textRecord[dateStringLength + 1 + // CH.9 We
timeStringLength + 1 + // build
DB_FIRST_NAME_SIZE + // text
DB_LAST_NAME_SIZE + // record here
DB_PHONE_NUMBER_SIZE];
Char lcText[dateStringLength + 1 + // CH.9 Copy
timeStringLength + 1 + // lower
DB_FIRST_NAME_SIZE + // case
DB_LAST_NAME_SIZE + // text here
DB_PHONE_NUMBER_SIZE];
Word offset; // CH.9 Offset of the match
RectangleType bounds; // CH.9 Bounding rect for text
SWord width; // CH.9 Width of the bounds rect
SWord len; // CH.9 Text length
Boolean noFit; // CH.9 Does it fit
// CH.9 Draw a title for our find items
// CH.9 If there's no more room, return
if( (FindDrawHeader( findParams, "Contacts" )) == true )
return;
// CH.9 Open the database for reading
if( (contactsDB = DmOpenDatabaseByTypeCreator( 'ctct', 'PPGU',
dmModeReadOnly )) == NULL )
return;
// CH.9 Find out how many records we have
numRecords = DmNumRecords( contactsDB );
// CH.9 Get the ID and card number
DmOpenDatabaseInfo( contactsDB, &dbID, NULL, NULL, &cardNum, NULL);
// CH.9 For each record
for( cursor = findParams->recordNum; cursor < numRecords; cursor++ )
{
// CH.9 Get the record
hrecord = DmQueryRecord( contactsDB, cursor );
precord = MemHandleLock( hrecord );
// CH.9 Get the date and time
MemMove( &dateTime, precord + DB_DATE_TIME_START,
sizeof( dateTime ) );
// CH.9 Start over
*textRecord = '\0';
// CH.9 Add the date string if any
if( dateTime.year != NO_DATE )
{
DateToAscii( dateTime.month, dateTime.day,
dateTime.year,
(DateFormatType)PrefGetPreference(
prefDateFormat ), textRecord );
StrCat( textRecord, " " );
}
// CH.9 Add the time string if any
if( dateTime.hour != NO_TIME )
{
TimeToAscii( dateTime.hour, dateTime.minute,
(TimeFormatType)PrefGetPreference(
prefTimeFormat ), textRecord +
StrLen( textRecord ) );
StrCat( textRecord, " " );
}
// CH.9 Append the first name
StrCat( textRecord, precord + DB_FIRST_NAME_START );
StrCat( textRecord, " " );
// CH.9 Append the last name
StrCat( textRecord, precord + DB_LAST_NAME_START );
StrCat( textRecord, " " );
// CH.9 Append the phone number
StrCat( textRecord, precord + DB_PHONE_NUMBER_START );
// CH.9 Unlock the record
MemHandleUnlock( hrecord );
// CH.9 Copy and convert to lower case
StrToLower( lcText, textRecord );
// CH.9 If there's no match, move on
if( (FindStrInStr( lcText, findParams->strToFind,
&offset )) == false )
continue;
// CH.9 Send it to find
// CH.9 If there's no more room, return
if( (FindSaveMatch( findParams, cursor, offset, 0,
NULL, cardNum, dbID )) == true )
break;
// CH.9 Get the rectangle for our line of text
FindGetLineBounds( findParams, &bounds );
// CH.9 Truncate the string if necessary
width = bounds.extent.x;
len = StrLen( textRecord );
noFit = false;
FntCharsInWidth( textRecord, &width, &len, &noFit );
// CH.9 Draw the text
WinEraseRectangle( &bounds, 0 );
WinDrawChars( textRecord, len, bounds.topLeft.x,
bounds.topLeft.y );
// We used a line in the find dialog
(findParams->lineNumber)++;
}
// CH.9 Close the database
DmCloseDatabase( contactsDB );
// CH.9 We're done
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -