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

📄 smssendhandler.cpp

📁 在s60 v3版本中的发送短信的示例
💻 CPP
字号:
/* Copyright (c) 2001, Nokia Mobile Phones. All rights reserved */

#include <msvids.h>
#include <mtclreg.h>
#include <mtclbase.h>
//#include <comabs.h>
#include <txtrich.h>
#include <smsclnt.h>
#include <smuthdr.h>
#include <smutset.h>
#include <smscmds.h>
#include "SmsSendHandler.h"
#include "MsvObserver.h"
#include <charconv.h> 	 // CCnvCharacterSetConverter
#include <eikenv.h>

//#include <MuiuMsvSingleOpWatcher.h>

// this is the content of the message
// _LIT(KSMSText, "Example SMS");

CSmsSendHandler* CSmsSendHandler::NewL(MMsvObserver& aObserver)
    {
    CSmsSendHandler* self = CSmsSendHandler::NewLC(aObserver);
    CleanupStack::Pop();
    return self;
    }

    
CSmsSendHandler* CSmsSendHandler::NewLC(MMsvObserver& aObserver)
    {
    CSmsSendHandler* self = new (ELeave) CSmsSendHandler(aObserver);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }


CSmsSendHandler::CSmsSendHandler( MMsvObserver& aObserver ) 
    : CMsvHandler(aObserver), iPhase(EIdle)
    {
    }

CSmsSendHandler::~CSmsSendHandler()
    {
    // No implementation required
    }


TBool CSmsSendHandler::IsIdle()
    {
    if (CMsvHandler::IsIdle() && (iPhase == EIdle))
        {
        return ETrue;
        }
    else
        {
        return EFalse;
        }
    }

void CSmsSendHandler::ConstructL()
    {
    CMsvHandler::ConstructL();
    }


// from CActive
void CSmsSendHandler::RunL()
    {
    ASSERT(iOperation);

    // Mtm's should always return KErrNone and clients should rely on other means
    // to check on operation progress
    User::LeaveIfError(iStatus.Int());

    // Determine the current operations progress
    // Note : This class is only appropriate to Locally acting operations
    //        such as Create, Move, Delete.
    //        For the CBaseMtm::InvokeAsyncFunctionL, used to schedule the messange for sending,
    //        no status is available as this is not a local operation, so we use the fact
    //        that sent messages are moved to the 'Sent' folder which we can detect using
    //        the HandleSessionEventL
    TMsvLocalOperationProgress progress;
    TUid mtmUid = iOperation->Mtm();
    if (mtmUid == KUidMsvLocalServiceMtm)
        {
        progress = McliUtils::GetLocalProgressL(*iOperation);
        User::LeaveIfError(progress.iError);
        }
    else
        {
        // The request to schedule the message is the only non-local operation
        // we request from this example
        if (iPhase != EWaitingForScheduled)
            {
            // User::Panic(KSms, ESmsStateError);
            }
        }

    delete iOperation;
    iOperation = NULL;

    switch (iPhase)
        {
        case EWaitingForCreate:
            iObserver.HandleStatusChange(MMsvObserver::ECreated);
            SetMtmEntryL(progress.iId);
            if (InitializeMessageL())
                {
                // if ( MoveMessageEntryL(KMsvGlobalOutBoxIndexEntryId) )
				if ( MoveMessageEntryL(KMsvGlobalInBoxIndexEntryId) )
                    {
                    iPhase = EWaitingForMove;
                    }
                else
                    {
                    iPhase = EIdle;
                    }
                }
            else
                {
                iPhase = EIdle;
                }
            break;

        case EWaitingForMove:
            {
            // iObserver.HandleStatusChange(MMsvObserver::EMovedToOutBox);
            iObserver.HandleStatusChange(MMsvObserver::EMovedToInbox);
            // We must create an entry selection for message copies 
            // (although now we only have one message in selection)
            CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
            CleanupStack::PushL(selection);

            selection->AppendL(progress.iId);

            // schedule the sending with the active scheduler
            SetScheduledSendingStateL(*selection);

            CleanupStack::PopAndDestroy(selection);
            iPhase = EWaitingForScheduled;
            break;
            }

        case EWaitingForScheduled:
            {
            const TMsvEntry& msvEntry = iMtm->Entry().Entry();
            TInt state = msvEntry.SendingState();
            if (state != KMsvSendStateScheduled)
                {
                iObserver.HandleError(MMsvObserver::EScheduleFailed);
                iPhase = EIdle;
                }
            else
                {
                iObserver.HandleStatusChange(MMsvObserver::EScheduledForSend);
                iPhase = EWaitingForSent;
                }
            break;
            }

        case EWaitingForDeleted:
            iObserver.HandleStatusChange(MMsvObserver::EDeleted);
            iPhase = EIdle;
            break;

        case EWaitingForSent:  // We handle this in HandleSessionEventL
        case EIdle:            // Shouldn't get triggered in this state
        default:
            ASSERT(EFalse);
        }

    }

void CSmsSendHandler::CreateNewMessageL()
    {
    TMsvEntry newEntry;              						// This represents an entry in the Message Server index
    newEntry.iMtm = KUidMsgTypeSMS;                         // message type is SMS
    newEntry.iType = KUidMsvMessageEntry;                   // this defines the type of the entry: message 
    newEntry.iServiceId = KMsvLocalServiceIndexEntryId;     // ID of local service (containing the standard folders)
    newEntry.iDate.HomeTime();                              // set the date of the entry to home time
	newEntry.iDate.UniversalTime();
    newEntry.SetInPreparation(ETrue);                       // a flag that this message is in preparation

    // - CMsvEntry accesses and acts upon a particular Message Server entry.
    // - NewL() does not create a new entry, but simply a new object to access an existing entry.
    // - It takes in as parameters the client's message server session,
    //   ID of the entry to access and initial sorting order of the children of the entry. 
    CMsvEntry* entry = CMsvEntry::NewL(*iSession, KMsvDraftEntryIdValue, TMsvSelectionOrdering());
    CleanupStack::PushL(entry);

    iOperation = entry->CreateL(newEntry, iStatus);
    CleanupStack::PopAndDestroy(entry);

    // The RunL of this class will trigger when the server completes the request
    SetActive();
    iPhase = EWaitingForCreate;

    }

void CSmsSendHandler::SendToL(const TDesC& aRecipient, const TDesC& aText )
    {
    iRecipientsTelNum = aRecipient;
	iText = aText;
    CreateNewMessageL();
    }


TBool CSmsSendHandler::SetupSmsHeaderL()
    {
    if (iMtm)
        {
        // To handle the sms specifics we start using SmsMtm
        CSmsClientMtm* smsMtm = static_cast<CSmsClientMtm*>(iMtm);
        // 
        smsMtm->RestoreServiceAndSettingsL();

        // CSmsHeader encapsulates data specific for sms messages,
        // like service center number and options for sending.
        CSmsHeader&   header          = smsMtm->SmsHeader();
        CSmsSettings& serviceSettings = smsMtm->ServiceSettings();
		
		// Added by XiaoGuo
		serviceSettings.SetCharacterSet( TSmsDataCodingScheme::ESmsAlphabetUCS2 );

        CSmsSettings* sendOptions = CSmsSettings::NewL();
        CleanupStack::PushL(sendOptions);
        sendOptions->CopyL(serviceSettings); // restore existing settings

        // set send options
        sendOptions->SetDelivery(ESmsDeliveryImmediately);      // set to be delivered immediately
        header.SetSmsSettingsL(*sendOptions);

        CleanupStack::PopAndDestroy(sendOptions);
    
        // let's check if there's a service centre address
        if (header.Message().ServiceCenterAddress().Length() == 0)
            {
			if ( serviceSettings.ServiceCenterCount() != 0 )
				{
				// set sc address to default. 
				CSmsServiceCenter& sc = serviceSettings.
					GetServiceCenter(  serviceSettings.DefaultServiceCenter() );
				header.Message().SetServiceCenterAddressL( sc.Address() );
				}
			else
				{
				// here there could be a dialog in which user can add sc number
				iObserver.HandleError(MMsvObserver::ENoServiceCentre);
				return EFalse;
				}
            }
        return ETrue;
        }
    else
        {
        return EFalse;
        }
    }

#include <aknutils.h> 
const TUint KSmsEdUnicodeLFSupportedByBasicPhones = 0x000A;
void CSmsSendHandler::PopulateMessageL(TMsvEntry& aMsvEntry)
    {
    ASSERT(iMtm);

    // We get the message body from Mtm and insert a bodytext
    CRichText& mtmBody = iMtm->Body();
    mtmBody.Reset();

	mtmBody.InsertL( 0, iText );    

    // set iRecipientTelNum into the Details of the entry
    aMsvEntry.iDetails.Set(iRecipientsTelNum);  // set recipient info in details
    aMsvEntry.SetInPreparation(EFalse);         

    aMsvEntry.SetSendingState( KMsvSendStateWaiting );   
    aMsvEntry.iDate.HomeTime(); 
	aMsvEntry.iDate.UniversalTime();
    }


TBool CSmsSendHandler::InitializeMessageL()
    {
    ASSERT(iMtm);

    TMsvEntry msvEntry = (iMtm->Entry()).Entry();

    PopulateMessageL(msvEntry);

    // Set SMS specific Mtm fields
    if (!SetupSmsHeaderL())
        {
        return EFalse;
        }

    // Add our recipient to the list, takes in two TDesCs, first is real address and second is an alias
    // works also without the alias parameter.
    iMtm->AddAddresseeL( iRecipientsTelNum, msvEntry.iDetails );
    
    // save message
    CMsvEntry& entry = iMtm->Entry();
    entry.ChangeL( msvEntry );            // commit index changes
    iMtm->SaveMessageL();                 // commit message to message server

    return ETrue;
    }

TBool CSmsSendHandler::MoveMessageEntryL( TMsvId aTarget )
    {
    ASSERT( iMtm );
 
	TMsvEntry msvEntry( (iMtm->Entry()).Entry() );

	if ( msvEntry.Parent() != aTarget )
        {
        TMsvSelectionOrdering sort;
        sort.SetShowInvisibleEntries(ETrue);    // we want to also handle the invisible entries
        // Take a handle to the parent entry
        CMsvEntry* parentEntry = CMsvEntry::NewL(iMtm->Session(), msvEntry.Parent(), sort);
        CleanupStack::PushL(parentEntry);

        // Move original from the parent to the new location
        iOperation = parentEntry->MoveL(msvEntry.Id(), aTarget, iStatus);

        CleanupStack::PopAndDestroy(parentEntry);
        SetActive();

        return ETrue;
		}

    return EFalse;
    }


void CSmsSendHandler::SetScheduledSendingStateL(CMsvEntrySelection& aSelection)
    {
    ASSERT(iMtm);

    // Add entry to task scheduler
    TBuf8<1> dummyParams;
    // invoking async schedule copy command on our mtm
    iOperation = iMtm->InvokeAsyncFunctionL(
                        ESmsMtmCommandScheduleCopy,
						// ESmsMtmCommandScheduleMove,
                        aSelection,
                        dummyParams,
                        iStatus);
    SetActive();
    }


void CSmsSendHandler::HandleChangedEntryL(TMsvId aEntryId)
    {
    // if we've no Mtm then we can't be in the middle of sending a message
    if (iMtm)
        {
        // Compare the entry supplied with our current context (the message
        // we have been dealing with)
        TMsvEntry msvEntry((iMtm->Entry()).Entry());
        if (msvEntry.Id() == aEntryId)
            {
#if 0
            if (msvEntry.SendingState() == KMsvSendStateSent)
                {
                iPhase = EWaitingForDeleted;
                iObserver.HandleStatusChange(MMsvObserver::ESent);
                DeleteEntryL(msvEntry);
                }
            else if (msvEntry.SendingState() == KMsvSendStateFailed)
                {
                iPhase = EIdle;
                iObserver.HandleError(MMsvObserver::ESendFailed);
                }
#endif
            }
        }
    }


void CSmsSendHandler::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* /*aArg2*/, TAny* /*aArg3*/)
    {
    switch (aEvent)
        {
        case EMsvEntriesChanged:
            {
            // Find out what happened to the message we scheduled for sending
            if (iPhase == EWaitingForSent)
                {
                // We take the moved entries into a selection
                CMsvEntrySelection* entries = static_cast<CMsvEntrySelection*>(aArg1);

                 //Process each created entry, one at a time.
                for(TInt i = 0; i < entries->Count(); i++)
                    {
                    HandleChangedEntryL(entries->At(i));       
                    }
				iPhase = EIdle;
                }
            }
            break;

            // This event tells us that the session has been opened
        case EMsvServerReady:
            CompleteConstructL();       // Construct the mtm registry
            break;

        case EMsvCloseSession:
            // Handle close session
            iSession->CloseMessageServer();
            break;

        case EMsvServerTerminated:
            // Handle server terminated
            iSession->CloseMessageServer();
            break;

        case EMsvGeneralError:
        case EMsvServerFailedToStart:
            // A major problem has occurred
            iObserver.HandleError(MMsvObserver::EFatalServerError);
            break;

        default:
            // All other events are ignored
            break;
        }
    }

⌨️ 快捷键说明

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