contacts.c

来自「CD_《Palm OS编程实践》」· C语言 代码 · 共 1,566 行 · 第 1/3 页

C
1,566
字号
						
						// CH.6 Increase tens of minutes
						case EnterTimeMinuteTensPushButton:
						{
							// CH.6 Increment minutes
							dateTime.minute += 10;
							
							// CH.6 If it was 5X, roll over
							if( dateTime.minute > 59 )
								dateTime.minute -= 60;
						}
						break;
						
						// CH.6 Increase minutes
						case EnterTimeMinuteOnesPushButton:
						{
							// CH.6 Increment minutes
							dateTime.minute++;
							
							// CH.6 If it is zero, subtract ten
							if( (dateTime.minute % 10) == 0 )
								dateTime.minute -= 10;
						}
						break;
					}
					
					// Revise the controls
					setTimeControls();
				}
				break;
				
				// CH.6 Down button
				case EnterTimeTimeDownRepeating:
				{
					
					// CH.6 If there's no time, do nothing
					if( dateTime.hour == NO_TIME )
						break;
					
					// CH.6 Based on what push button is selected
					switch( timeSelect )
					{
						// CH.6 Decrease hours
						case EnterTimeHoursPushButton:
						{
							// CH.6 Decrement hours
							dateTime.hour--;
							
							// CH.6 If it was 12 AM, make it 11 AM
							if( dateTime.hour == -1 )
								dateTime.hour = 11;
								
							// CH.6 If it was 12 PM, make it 11 PM
							if( dateTime.hour == 11 )
								dateTime.hour = 23;
						}
						break;
						
						// CH.6 Decrease tens of minutes
						case EnterTimeMinuteTensPushButton:
						{
							// CH.6 Decrement minutes
							dateTime.minute -= 10;
							
							// CH.6 If it was 0X, roll over
							if( dateTime.minute < 0 )
								dateTime.minute += 60;
						}
						break;
						
						// CH.6 Decrease minutes
						case EnterTimeMinuteOnesPushButton:
						{
							// CH.6 Decrement minutes
							dateTime.minute--;
							
							// CH.6 If it is 9, add ten
							if( (dateTime.minute % 10) == 9 )
								dateTime.minute += 10;
								
							// CH.6 If less than zero, make it 9
							if( dateTime.minute < 0 )
								dateTime.minute = 9;
						}
						break;
					}
					
					// CH.6 Revise the controls
					setTimeControls();
				}
				break;
								
				// CH.6 AM button
				case EnterTimeAMPushButton:
				{
					// CH.6 If no time was set
					if( dateTime.hour == NO_TIME )
					{
						// CH.6 Set the time to 12 AM
						dateTime.hour = 0;
						dateTime.minute = 0;
						
						// CH.6 Set the controls
						setTimeControls();
					}	
					
					// CH.6 If it is PM
					if( dateTime.hour > 11 )
					{
						// CH.6 Change to AM
						dateTime.hour -= 12;
						
						// CH.6 Set the controls
						setTimeControls();
					}
				}
				break;
				
				// CH.6 PM button
				case EnterTimePMPushButton:
				{
					// CH.6 If no time was set
					if( dateTime.hour == NO_TIME )
					{
						// CH.6 Set the time to 12 PM
						dateTime.hour = 12;
						dateTime.minute = 0;
						
						// CH.6 Set the controls
						setTimeControls();
					}	
					
					// CH.6 If it is AM
					if( dateTime.hour < 12 )
					{
						// CH.6 Change to PM
						dateTime.hour += 12;
						
						// CH.6 Set the controls
						setTimeControls();
					}
				}
				break;
				
				// CH.6 No Time checkbox
				case EnterTimeNoTimeCheckbox:
				{
					// CH.6 If we are unchecking the box
					if( dateTime.hour == NO_TIME )
					{
						// CH.6 Set the time to 12 PM
						dateTime.hour = 12;
						dateTime.minute = 0;
						
						// CH.6 Set the controls
						setTimeControls();

						// CH.6 Set the new selection
						timeSelect = EnterTimeHoursPushButton;
						CtlSetValue( getObject( form, timeSelect ),
								true );
					}
					
					else
					// CH.6 If we are checking the box
						dateTime.hour = NO_TIME;
					
					// CH.6 Set the controls
					setTimeControls();
				}
				break;
				
				// CH.6 Cancel button
				case EnterTimeCancelButton:
				{
					// CH.6 Restore time
					dateTime = oldTime;
					
					// CH.6 Return to calling form
					FrmReturnToForm( 0 );
				}
				// CH.6 Always return true
				return( true );
					
				// CH.6 OK button
				case EnterTimeOKButton:
				{
					VoidPtr	precord;	// CH.6 Points to the record
			
					// CH.6 Lock it down
					precord = MemHandleLock( hrecord );
					
					// CH.6 Write the date time field
					DmWrite( precord, DB_DATE_TIME_START, &dateTime,
							sizeof( DateTimeType ) );
				
					// CH.6 Unlock the record
					MemHandleUnlock( hrecord );
					
					// CH.6 Mark the record dirty
					isDirty = true;
			
					// CH.6 Return to the Contact Details form
					FrmReturnToForm( 0 );

					// CH.6 Update the field
					setTimeTrigger();
				}
				// CH.6 Always return true
				return( true );
			}
		}
		break;
	}
	
	// CH.6 We're done
	return( false );
}
		
// CH.7 Our Contact List form event handler function
static Boolean contactListHandleEvent( EventPtr event )
{
	FormPtr	form;		// CH.7 A form structure pointer

	// CH.7 Get our form pointer
	form = FrmGetActiveForm();

	// CH.7 Parse events 
	switch( event->eType )
	{
		// CH.7 Form open event
		case frmOpenEvent:
		{
			// CH.7 Draw the form	
			FrmDrawForm( form );
			
			// CH.8 Populate and draw the table
			drawTable();			
		}
		break;
	
		// CH.7 Respond to a list selection
		case tblSelectEvent:
		{
			// CH.7 Set the database cursor to the selected contact
			cursor += event->data.tblSelect.row;
			
			// CH.7 Go to contact details
			FrmGotoForm( ContactDetailForm );
		}
		break;
		
		// CH.7 Respond to a menu event
		case menuEvent:
			return( menuEventHandler( event ) );

		// CH.7 Respond to the popup trigger
		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.8 Rebuild the table
			drawTable();
		}
		break;
		
		// CH.8 Respond to arrows
		case ctlRepeatEvent:
		{
			switch( event->data.ctlRepeat.controlID )
			{
				// CH.8 Up arrow
				case ContactListRecordUpRepeating:
					if( cursor > 0 )
						cursor--;
				break;
				
				// CH.8 Down arrow
				case ContactListRecordDownRepeating:
					if( (numRecords > TABLE_NUM_ROWS) &&
							(cursor < numRecords - TABLE_NUM_ROWS) )
						cursor++;
				break;
			}
			
			// CH.8 Now refresh the table
			drawTable();
		}
		return( true );
		
		// CH.8 Respond to up and down arrow hard keys
		case keyDownEvent:
		{
			switch( event->data.keyDown.chr )
			{
				// CH.8 Up arrow hard key
				case pageUpChr:
					if( cursor > TABLE_NUM_ROWS - 1 )
						cursor -= TABLE_NUM_ROWS - 1;
					else
						cursor = 0;
				break;
				
				// CH.8 Down arrow hard key
				case pageDownChr:
					if( (numRecords > 2 * TABLE_NUM_ROWS - 1) &&
							(cursor < numRecords -
							2 * TABLE_NUM_ROWS - 1) )
						cursor += TABLE_NUM_ROWS - 1;
					else
						cursor = numRecords - TABLE_NUM_ROWS;
				break;
			}
			
			// CH.8 Now refresh the table
			drawTable();
		}
		break;
		
		// CH.8 Respond to scrollbar events
		case sclRepeatEvent:
			cursor = event->data.sclExit.newValue;
			drawTable();
		break;
		
	}	// CH.7 End of the event switch statement
	
	// CH.7 We're done
	return( false );
}

// CH.3 Handle menu events
Boolean menuEventHandler( EventPtr event )
{
	FormPtr		form;		// CH.3 A pointer to our form structure
	Word		index;		// CH.3 A general purpose control index
	FieldPtr	field;		// CH.3 Used for manipulating fields

	// CH.3 Get our form pointer
	form = FrmGetActiveForm();

	// 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 );
	}

	// CH.3 Get the index of our field
	index = FrmGetFocus( form );
			
	// CH.3 If there is no field selected, we're done
	if( index == noFocus )
		return( false );
			
	// CH.3 Get the pointer of our field
	field = FrmGetObjectPtr( form, index );
			
	// CH.3 Do the edit command
	switch( event->data.menu.itemID )
	{
		// CH.3 Undo
		case EditUndo:
			FldUndo( field );
		break;
		
		// CH.3 Cut
		case EditCut:
			FldCut( field );
		break;
				
		// CH.3 Copy
		case EditCopy:
			FldCopy( field );
		break;
			
		// CH.3 Paste
		case EditPaste:
			FldPaste( field );
		break;
				
		// CH.3 Select All
		case EditSelectAll:
		{
			// CH.3 Get the length of the string in the field
			Word length = FldGetTextLength( field );
				
			// CH.3 Sound an error if appropriate
			if( length == 0 )
			{
				SndPlaySystemSound( sndError );
				return( false );
			}
			
			// CH.3 Select the whole string
			FldSetSelection( field, 0, length );					
		}
		break;
				
		// CH.3 Bring up the keyboard tool
		case EditKeyboard:
			SysKeyboardDialogV10();
		break;
	}
	
	// CH.3 We're done	
	return( true );
}

// CH.5 This function creates and initializes a new record
static void newRecord( void )
{
	VoidPtr		precord;	// CH.5 Pointer to the record
	
	// CH.7 Create the database record and get a handle to it
	if( (hrecord = DmNewRecord( contactsDB, &cursor,
			DB_RECORD_SIZE )) == NULL )
		errorExit( MemoryErrorAlert );
	
	// CH.5 Lock down the record to modify it
	precord = MemHandleLock( hrecord );
	
	// CH.5 Clear the record
	DmSet( precord, 0, DB_RECORD_SIZE, 0 );
	
	// CH.6 Initialize the date and time
	MemSet( &dateTime, sizeof( dateTime ), 0 );
	dateTime.year = NO_DATE;
	dateTime.hour = NO_TIME;
	DmWrite( precord, DB_DATE_TIME_START, &dateTime,
			sizeof( DateTimeType ) );
	
	// CH.5 Unlock the record
	MemHandleUnlock( hrecord );
	
	// CH.5 Clear the busy bit and set the dirty bit
	DmReleaseRecord( contactsDB, cursor, true );
	
	// CH.5 Increment the total record count
	numRecords++;

	// CH.5 Set the dirty bit
	isDirty = true;
	
	// CH.5 We're done
	return;
}

// CH.5 A time saver: Gets object pointers based on their ID
static VoidPtr getObject( FormPtr form, Word objectID )
{
	Word	index;	// CH.5 The object index
	
	// CH.5 Get the index
	index = FrmGetObjectIndex( form, objectID );
	
	// CH.5 Return the pointer
	return( FrmGetObjectPtr( form, index ) );
}

// CH.5 Gets the current database record and displays it
// in the detail fields
static void setFields( void )
{
	FormPtr		form;		// CH.5 The contact detail form
	CharPtr		precord;	// CH.5 A record pointer
	Word		index;		// CH.5 The object index
	
	// CH.5 Get the contact detail form pointer
	form = FrmGetActiveForm();
		
	// CH.5 Get the current record
	hrecord = DmQueryRecord( contactsDB, cursor );
		
	// CH.6 Initialize the date and time variable
	precord = MemHandleLock( hrecord );
	MemMove( &dateTime, precord + DB_DATE_TIME_START,
			sizeof( dateTime ) );

	// CH.6 Initialize the date control
	setDateTrigger();
		
	// CH.6 Initialize the time control
	setTimeTrigger();
	
	// CH.5 Set the text for the First Name field
	setText( getObject( form, ContactDetailFirstNameField ),
			precord + DB_FIRST_NAME_START );
		
	// CH.5 Set the text for the Last Name field
	setText( getObject( form, ContactDetailLastNameField ),
			precord + DB_LAST_NAME_START );
		
	// CH.5 Set the text for the Phone Number field
	setText( getObject( form, ContactDetailPhoneNumberField ),
			precord + DB_PHONE_NUMBER_START );
	MemHandleUnlock( hrecord );

	// CH.5 If the record is already dirty, it's new, so set focus
	if( isDirty )
	{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?