⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contacts.c

📁 CD_《Palm OS编程实践》
💻 C
📖 第 1 页 / 共 4 页
字号:
			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 + -