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 + -
显示快捷键?