📄 simplesms.c
字号:
}
/****************************************************************/
/* HandlePhoneLibraryEvent */
/**
* This function handles all Phone specific events.
*
* \param cmdPBP IN Pointer to a structure that is associated with the launch code.
* \param launchFlags IN Value providing extra information about the launch.
*
* \retval UInt32 - Result of launch
*
****************************************************************/
static UInt32
HandlePhoneLibraryEvent(MemPtr cmdPBP, UInt16 launchFlags)
{
PhnEventPtr eventP = (PhnEventPtr)cmdPBP;
UInt32 flags;
Err error = 0;
UInt32 locked = 0;
launchFlags = launchFlags; // Prevent compiler warning of unused var
switch (eventP->eventType)
{
case phnEvtSegmentInd:
case phnEvtMessageInd:
// a message has been received
DisplayMessage (eventP->data.params.id);
// Tell the Phone Library that we handled the event and no
// other app needs to know about this.
eventP->acknowledge = true;
HsAttrGet(hsAttrKeyboardLocked, 0, &locked);
if (locked)
HsAttrSet(hsAttrKeyboardLocked, 0, 0);
break;
case phnEvtMessageStat:
// a message status has changed
switch (eventP->data.params.newStatus)
{
case kSending:
// this is an expected status, do nothing
break;
case kSent:
// ok, did we successfully send the message?
error = PhnLibGetFlags (smsLibRef, eventP->data.params.id, &flags);
if (error)
return error;
if ((flags & kFailed) == 0)
FrmAlert (resAlertSuccessfulTransfer);
else
FrmAlert (resAlertUnsuccessfulTransfer);
break;
default:
break;
}
eventP->acknowledge = true;
break;
default:
break;
}
return error;
}
/****************************************************************/
/* LoadPhoneLibrary */
/**
* Get a libRef to the Phone library
*
* \param libRefP OUT Pointer to library reference ID to return. If NULL,
* library isn't loaded and an error is returned.
* \param libLoadedP INOUT Pointer to boolean indicating whether the library
* had to be loaded or not. If the value is true on
* entry, it will be left as true, even if the library
* was found already loaded - this allows reuse of the
* same boolean indicating load status throughout the
* application. This routine NEVER sets this parameter
* to false.
*
* \retval none
*
****************************************************************/
static Err
LoadPhoneLibrary(UInt16* libRefP, Boolean* libLoadedP)
{
Err error = 0;
error = HsGetPhoneLibrary(libRefP);
if (error) return error;
error = PhnLibOpen(*libRefP);
if (error) return error;
*libLoadedP = true;
return error;
}
/****************************************************************/
/* SMSRegister */
/**
* This routine registers this application with the SMS library.
*
* \param bReg IN true to register; false to unregister
*
* \retval none
*
****************************************************************/
static Err
SMSRegister (Boolean bReg)
{
Boolean libLoaded = smsLibLoaded;
Err error = 0;
UInt16 libRef = smsLibRef;
if (!libLoaded)
error = LoadPhoneLibrary (&libRef, &libLoaded);
if (!error)
{
// Register this application with the Phone library so it will receive the appropriate events
error = PhnLibRegister (libRef, appFileCreator, bReg ? phnServiceSMS : 0);
if (libLoaded)
(void)PhnLibClose (libRef);
}
// Register NBS Notification
{
UInt16 cardNo;
LocalID dbID;
DmSearchStateType searchState;
DmGetNextDatabaseByTypeCreator(true, &searchState, sysFileTApplication,
appFileCreator, true, &cardNo, &dbID);
if ( bReg)
{
error = SysNotifyRegister (cardNo, dbID, phnNBSEvent, NULL, sysNotifyNormalPriority, NULL);
if (error == sysNotifyErrDuplicateEntry) // Already registered
error = 0; // This is OK. Clear this error
}
else
error = SysNotifyUnregister (cardNo, dbID, phnNBSEvent,sysNotifyNormalPriority);
}
return error;
}
/****************************************************************/
/* SendTheMessage */
/**
* This routine will send the message
*
* \retval none
*
****************************************************************/
static void
SendTheMessage(void)
{
UInt32 msgID = 0;
PhnAddressList addList;
PhnAddressHandle addressH;
Err error = 0;
DmOpenRef smsRefNum = 0; // CDMA workaround
// verify the Phone is powered
if (!PhnLibModulePowered (smsLibRef))
{
FrmAlert (resAlertPhoneNotReady);
return;
}
// verify the Phone is on the network
if (!PhnLibRegistered (smsLibRef))
{
FrmAlert (resAlertNotRegistered);
return;
}
smsRefNum = PhnLibGetDBRef(smsLibRef); // CDMA workaround
// get the values from the fields into the globals
// check if there is no address input. if not, do not send SMS and return. Modified by TaoC
if (CopyFromFieldsToGlobal() == 1)
{
FrmAlert (resAlertNoAddressInput);
return ;
}
// now, create the new message
msgID = PhnLibNewMessage (smsLibRef, kMTOutgoing);
if (!msgID)
goto SendMessage_CloseAndRelease;
// the the owner of this new message to this application
PhnLibSetOwner (smsLibRef, msgID, appFileCreator);
// fill in the text of this message
PhnLibSetText (smsLibRef, msgID, smsPrefs.message, (short) StrLen(smsPrefs.message));
// fill in the address
addList = PhnLibNewAddressList (smsLibRef);
if (!addList)
goto SendMessage_CloseAndRelease;
addressH = PhnLibNewAddress (smsLibRef, smsPrefs.address, phnLibUnknownID);
if (!addressH)
goto SendMessage_CloseAndRelease;
PhnLibAddAddress (smsLibRef, addList, addressH);
MemHandleFree (addressH);
PhnLibSetAddresses (smsLibRef, msgID, addList);
// PhnLibDisposeAddressList (smsLibRef, addList);
// and fire the message off!
error = PhnLibSendMessage (smsLibRef, msgID, true);
SendMessage_CloseAndRelease:
PhnLibReleaseDBRef(smsLibRef, smsRefNum); // CDMA workaround
}
/****************************************************************/
/* DisplayMessage */
/**
* This routine displays information about the given message
*
* \param messageID IN The message to display
*
* \retval none
*
****************************************************************/
static void
DisplayMessage(UInt32 messageID)
{
PhnAddressList addList;
PhnAddressHandle addressH;
MemHandle messageH;
char* addressP;
char* messageP;
Err error = 0;
DmOpenRef smsRefNum = 0; // CDMA workaround
// we cannot use the global smsLibRef,
// because this can be called when the application is not running
UInt16 localSmsLibRef;
Boolean localSmsLibLoaded;
char errMsg[10];
UInt16 msgIndex;
//Initialize some values
localSmsLibLoaded = false;
localSmsLibRef = 0;
error = LoadPhoneLibrary (&localSmsLibRef, &localSmsLibLoaded);
if (error)
{
StrIToA(errMsg, error);
FrmCustomAlert (resAlertPhoneLibrary, "Can't Load the Phone Library", errMsg, NULL);
return;
}
smsRefNum = PhnLibGetDBRef(localSmsLibRef); // CDMA workaround
// get the address list
error = PhnLibGetAddresses (localSmsLibRef, messageID, &addList);
if (error)
goto DisplayMessage_CloseAndRelease;
// now get the first entry from the list
error = PhnLibGetNth (localSmsLibRef, addList, 1, &addressH);
if (error)
goto DisplayMessage_CloseAndRelease;
// now get the actual address
addressP = PhnLibGetField (localSmsLibRef, addressH, phnAddrFldPhone);
// and get the message text
error = PhnLibGetText (localSmsLibRef, messageID, &messageH);
if (error)
goto DisplayMessage_CloseAndRelease;
messageP = MemHandleLock (messageH);
// display the incoming message alert
FrmCustomAlert (resAlertIncomingMessage, addressP, messageP, NULL);
// and clean up
if (addressP)
MemPtrFree (addressP);
if (messageH)
{
MemHandleUnlock (messageH);
MemHandleFree (messageH);
}
if (!DmFindRecordByID(smsRefNum, messageID, &msgIndex))
{
DmRemoveRecord(smsRefNum, msgIndex); // CDMA workaround
}
else
{
FrmCustomAlert(resAlertIncomingMessage, "000000", "Record not found!", NULL);
}
DisplayMessage_CloseAndRelease:
PhnLibReleaseDBRef(localSmsLibRef, smsRefNum); // CDMA workaround
// unload if necessary
if (localSmsLibLoaded)
(void)PhnLibClose (localSmsLibRef);
}
/****************************************************************/
/* TurnOnOptionLock */
/**
* Turn on the option lock on keyboard enabled devices.
*
* \param none
*
* \retval none
*
****************************************************************/
static void
TurnOnOptionLock (void)
{
// See if we are on a keyboard device and enable the option-lock
UInt16 err;
UInt32 keyboardType;
// See if we have a keyboard
err = FtrGet (hsFtrCreator, hsFtrIDTypeOfKeyboard, &keyboardType);
if (!err && (keyboardType & hsFtrValKeyboardQwerty))
HsGrfSetStateExt (false, // capsLock
false, // numLock
true, // optLock
false, // upperShift
false, // optShift
false); // autoShift
}
/****************************************************************/
/* GetObjectPtr */
/**
* This routine returns a pointer to an object in the current form.
*
* \param formId IN ID of the form to display
*
* \retval void* - Pointer to the object
*
****************************************************************/
static void*
GetObjectPtr (UInt16 objectID)
{
FormPtr frmP;
frmP = FrmGetActiveForm ();
return FrmGetObjectPtr (frmP, FrmGetObjectIndex(frmP, objectID));
}
/****************************************************************/
/* CopyFromGlobalsToFields */
/**
* This routine will copy the text strings from the global prefs into
* the text fields on the main form
*
* \param none
*
* \retval none
*
****************************************************************/
static void
CopyFromGlobalToFields (void)
{
Err error = 0;
FieldPtr fld;
MemHandle h, oldH;
PhnAddressHandle addressH;
CharPtr addressP;
UInt32 phnType;
HsAttrGet(hsAttrPhoneType, 0, &phnType);
// Fill in the fields from the prefs
fld = GetObjectPtr (resFieldAddress);
h = MemHandleNew (StrLen(smsPrefs.address) + 1);
if (!h)
return;
StrCopy (MemHandleLock (h), smsPrefs.address);
MemHandleUnlock (h);
oldH = FldGetTextHandle (fld);
FldSetTextHandle (fld, h);
FldDrawField (fld);
if (oldH)
MemHandleFree (oldH);
fld = GetObjectPtr (resFieldMessage);
h = MemHandleNew (StrLen (smsPrefs.message) + 1);
if (!h)
return;
StrCopy (MemHandleLock (h), smsPrefs.message);
MemHandleUnlock (h);
oldH = FldGetTextHandle (fld);
FldSetTextHandle (fld, h);
FldDrawField (fld);
if (oldH)
MemHandleFree (oldH);
if (phnType == hsAttrPhoneTypeGSM)
{
// fill in the service center from the Phone library
fld = GetObjectPtr (resFieldServiceCenter);
error = PhnLibGetServiceCentreAddress (smsLibRef, &addressH);
if (!error && addressH)
{
addressP = PhnLibGetField (smsLibRef, addressH, phnAddrFldPhone);
h = MemHandleNew (serviceCenterSize);
if (!h)
{
MemHandleFree (addressH);
MemPtrFree (addressP);
return;
}
StrCopy (MemHandleLock (h), addressP);
MemHandleUnlock (h);
oldH = FldGetTextHandle (fld);
FldSetTextHandle (fld, h);
FldDrawField (fld);
if (oldH)
MemHandleFree (oldH);
// clean up
MemHandleFree (addressH);
MemPtrFree (addressP);
}
}
}
/****************************************************************/
/* CopyFromFieldsToGlobal */
/**
* This routine will copy the text strings from the text
* fields on the main form into the global prefs.
*
* \param none
*
* \retval none - rev.1
* 0: success - rev.2
* 1: no address input added by TaoC
*
****************************************************************/
static UInt32
CopyFromFieldsToGlobal (void)
{
FieldPtr fld;
char* s;
UInt16 len = 0;
// Get the pref values from the fields
fld = GetObjectPtr(resFieldAddress);
s = FldGetTextPtr(fld);
if (s)
{
// check if user has enter an address. if not, then do not send SMS. Added by TaoC
len = StrLen(s);
if ( len > 0)
// copy contents of address field into prefs
StrCopy(smsPrefs.address, s);
else
return 1 ;
}
fld = GetObjectPtr(resFieldMessage);
s = FldGetTextPtr(fld);
if (s)
{
// copy contents of message field into prefs
StrCopy(smsPrefs.message, s);
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -