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

📄 mtmengine.cpp

📁 symbian 2rd 备忘录
💻 CPP
字号:
#include "MtmEngine.h"


// SYSTEM FILES
#include <f32file.h>        // TParsePtrC
#include <mmsclient.h>      // CMmsClientMtm
#include <mtclreg.h>        // CClientMtmRegistry 
#include <mtmdef.h>         // KMsvMessagePartBody 
#include <smsclnt.h>        // CSmsClientMtm
#include <smscmds.h>        // ESmsMtmCommandScheduleCopy
#include <smuthdr.h>        // CSmsHeader
#include <smutset.h>        // CSmsSettings
#include <txtrich.h>        // CRichText
#include <eikenv.h>
#include <stringloader.h>
//#include <infoman.rsg>

const TInt KMessageAddressLength 	= 32;
const TInt KMessageBodySize 		= 256;
const TInt KListInfoLength			= 512;

CMtmEngine* CMtmEngine::NewL(MMtmsEngineObserver& aObserver)
{
	CMtmEngine* self = new(ELeave) CMtmEngine(aObserver);
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop();
	return self;
}
CMtmEngine::CMtmEngine(MMtmsEngineObserver& aObserver)
:CActive(0),
m_Observer(aObserver),
m_pIdArray(NULL),
m_SmsId(KMsvNullIndexEntryId)
{
	
}
void CMtmEngine::ConstructL()
{
	CActiveScheduler::Add(this);
	// m_pEntrySelection encapsulates an array of entry IDs
	m_pEntrySelection = new(ELeave) CMsvEntrySelection;
	// Represents a channel of communication between a client thread (Client-side MTM, User
	// Interface MTM, or message client application) and the Message Server thread. 
	// Session is opened asynchorously. CreateMtmClientL() is called afterwards.
	// Another possibility is use OpenSyncL which is synchronous.
	m_pSession = CMsvSession::OpenAsyncL(*this);
}

void CMtmEngine::CreateMtmClientL()
{
	  // Client-side MTM registry. 
	m_pClientMtmReg = CClientMtmRegistry::NewL(*m_pSession);

	// Get the SMS Mtm client from the registry
	m_pSmsMtm = static_cast<CSmsClientMtm*>(m_pClientMtmReg->NewMtmL(KUidMsgTypeSMS));
}
CMtmEngine::~CMtmEngine()
{
	Cancel();
	delete m_pMsvOper;
	delete m_pEntrySelection;
	delete m_pSmsMtm;
	delete m_pClientMtmReg;
	delete m_pSession;
	if(m_pIdArray)
	{
		m_pIdArray->Reset();
		delete m_pIdArray;
		m_pIdArray = NULL;
	}
}
void CMtmEngine::DoCancel()
{
	if(m_pMsvOper)
	{
		m_pMsvOper->Cancel();
		delete m_pMsvOper;
		m_pMsvOper = NULL;
	}
}

void CMtmEngine::RunL()
{
	m_Observer.HandleMessageSentL(iStatus.Int());	
}
TMsvEntry CMtmEngine::CreateSMSMessageL(const TDesC& aAddress,const TDesC& aMessage)
{
	// Set SMS parameters 设置短信参数
	TMsvEntry indexEntry;
	indexEntry.iDate.HomeTime();
	indexEntry.SetInPreparation(EFalse);
	// This is an SMS message
	indexEntry.iMtm = KUidMsgTypeSMS;
	indexEntry.iType = KUidMsvMessageEntry;
	// Gets the ID of the current SMS service 取得当前的短信服务编号
	indexEntry.iServiceId = m_pSmsMtm->ServiceId();

	// Create entry to drafts
	m_pSmsMtm->SwitchCurrentEntryL(KMsvDraftEntryId);

	// Creates a new child entry owned by the context synchronously //同步
	m_pSmsMtm->Entry().CreateL(indexEntry);

	// Set the MTM's active context to the new message
	m_SmsId = indexEntry.Id();
	m_pSmsMtm->SwitchCurrentEntryL(m_SmsId);

	// modify by tommy
	CSmsHeader& header = m_pSmsMtm->SmsHeader();
	CSmsSettings* sendOptions = CSmsSettings::NewL();
	CleanupStack::PushL(sendOptions);
	sendOptions->CopyL(m_pSmsMtm->ServiceSettings()); //restore existing settings
	// set send options
	sendOptions->SetDelivery(ESmsDeliveryImmediately); // set to be deliverred immediately 立即发送
	// here we modified the character set
	sendOptions->SetCharacterSet(TSmsDataCodingScheme::ESmsAlphabetUCS2);
	// end
	header.SetSmsSettingsL(*sendOptions);
	CleanupStack::PopAndDestroy(sendOptions);

	// Add message body. Body is set twice because index entry keeps a copy
	// of some summary information. Index entry and full stored entry
	// must be in sync.
	CRichText& body = m_pSmsMtm->Body();
	body.Reset();
	body.InsertL(0,aMessage);
	indexEntry.iDescription.Set(aMessage);

	// Add destination address (recipient). Copy address also to the index entry
	m_pSmsMtm->AddAddresseeL(aAddress);
	indexEntry.iDetails.Set(aAddress);

	// commit changes because index entry is only a local variable
	m_pSmsMtm->Entry().ChangeL(indexEntry);

	// Save full message data to the store
	m_pSmsMtm->SaveMessageL();

	return indexEntry;

}
TBool CMtmEngine::ValidateCreatedSMS()
{
	
    TMsvPartList partsToBeChecked = KMsvMessagePartBody | KMsvMessagePartRecipient |
        KMsvMessagePartOriginator | KMsvMessagePartDate;
	
	// ValidateMessage return KErrNone if message is valid.
    TMsvPartList failedParts = m_pSmsMtm->ValidateMessage(partsToBeChecked);
    
	if (failedParts == KMsvMessagePartNone)
	{
		return ETrue;
	}
	else 
	{
		return EFalse;
	}
}
void CMtmEngine::SendSMSL()
{
	// Changes the entry on which later actions are performed to the entry with the 
	// specified TMsvId. 
    m_pSmsMtm->SwitchCurrentEntryL(m_SmsId);
	
    // Load the created message
    m_pSmsMtm->LoadMessageL();
	
    // Gets the current SMS service settings
    CSmsSettings& serviceSettings = m_pSmsMtm->ServiceSettings();
	
	// Gets the number of service centre addresses stored in this object.
    const TInt numSCAddresses = serviceSettings.NumSCAddresses();
    
	// There should always be a service center number
	if (numSCAddresses > 0)
	{
        CSmsNumber*	serviceCentreNumber = NULL;
		
        // get the service center number
        if ((serviceSettings.DefaultSC() >= 0)  &&  (serviceSettings.DefaultSC() < numSCAddresses))
            serviceCentreNumber = &(serviceSettings.SCAddress(serviceSettings.DefaultSC()));
        else
            serviceCentreNumber = &(serviceSettings.SCAddress(0));
		
        m_pSmsMtm->SmsHeader().SetServiceCenterAddressL(serviceCentreNumber->Address());
	}
	else 
	{
		// Leave if there is no service center number
		User::Leave(0);
	}
	
    m_pSmsMtm->SaveMessageL();
	
    // Index entry must be Updated  索引条目必须更新
    TMsvEntry indexEntry = m_pSmsMtm->Entry().Entry();
	// Set in-preparation flag
    indexEntry.SetInPreparation(EFalse);
	// Sets the sending state
    indexEntry.SetSendingState(KMsvSendStateWaiting);
    m_pSmsMtm->Entry().ChangeL(indexEntry);
	
    // Time to send the message
    Cancel(); // prepare iMsvOper for use
	m_pEntrySelection->Reset();
	m_pEntrySelection->AppendL(m_SmsId);
	
    TBuf8<1> dummyParam;
	// There is also InvokeSyncFunctionL which is synchronous.
	m_pMsvOper = m_pSmsMtm->InvokeAsyncFunctionL(ESmsMtmCommandScheduleCopy, *m_pEntrySelection, dummyParam, iStatus);
    SetActive();
}
void CMtmEngine::GetFolderSMSMessageInformation(TMsvId aFolderID, CDesCArrayFlat*& aMobile, CDesCArrayFlat*& aMessage)
{
	m_pSmsMtm->SwitchCurrentEntryL( aFolderID );
	CMsvEntry& entry = m_pSmsMtm->Entry();
	
	// Remember to delete this entry after no longer needed!
	// Only intrested in messages. Filter out service etries.
	CMsvEntrySelection* entries = entry.ChildrenWithMtmL(KUidMsgTypeSMS);
	
	TBuf<2> sTmp;
	//	CDesCArrayFlat* arrayRead = new (ELeave) CDesCArrayFlat(10);
	//	CDesCArrayFlat* arrayAddr = new (ELeave) CDesCArrayFlat(10);
	//	CDesCArrayFlat* arrayMsgBody = new (ELeave) CDesCArrayFlat(10);
	
	if(m_pIdArray)
	{
		m_pIdArray->Reset();
		delete m_pIdArray;
	}
	m_pIdArray = new (ELeave) RArray<TMsvId>;
	
	for (TInt i = entries->Count()-1; i >= 0; i-- ) 
	{
		//		TBuf<KMessageBodySize> body;
		//		TBuf<KMessageAddressLength> address;
		
		m_pIdArray->Append((*entries)[i]);
		
		//of message.
		m_pSmsMtm->SwitchCurrentEntryL( (*entries)[i] );
		aMessage->AppendL(m_pSmsMtm->Entry().Entry().iDescription);
		//of mobile
		m_pSmsMtm->SwitchCurrentEntryL( (*entries)[i] );	
		m_pSmsMtm->LoadMessageL();
		// 		CSmsHeader&	header = iSmsMtm->SmsHeader();
		// 		aMobile->AppendL(header.FromAddress());
		aMobile->AppendL(m_pSmsMtm->Entry().Entry().iDetails );
	}
	
	// Delete entries. This is your responsibility.
	entries->Reset();
	delete entries;
	entries = 0;
	
	//	aIsRead		= arrayRead;
	//	aMobile		= arrayAddr; // address array
//	aMessage	= arrayMsgBody; // msg body array
}
void CMtmEngine::MoveToFolderL(TInt aIndex,TMsvId aFolder)
{
	MoveToFolderL((*m_pIdArray)[aIndex], aFolder);
}
void CMtmEngine::MoveToFolderL(TMsvId aMessageId,TMsvId aFolder)
{
	m_pSmsMtm->SwitchCurrentEntryL( aMessageId );
	TMsvSelectionOrdering selection;
	selection.SetShowInvisibleEntries(ETrue);
	CMsvEntry* parentEntry = CMsvEntry::NewL( m_pSmsMtm->Session(), 
		m_pSmsMtm->Entry().Entry().Parent(), selection );
	CleanupStack::PushL(parentEntry);
	// Move the message
	parentEntry->MoveL( aMessageId, aFolder );
	CleanupStack::PopAndDestroy(); // parentEntry
}
void CMtmEngine::DeleteMessageL(TInt aCurrent)
{
	DeleteMessageL((*m_pIdArray)[aCurrent]);
	m_pIdArray->Remove(aCurrent);
}
void CMtmEngine::DeleteMessageL(TMsvId aMessageId )
{
	m_pSmsMtm->SwitchCurrentEntryL( aMessageId );
	TMsvId parent = m_pSmsMtm->Entry().Entry().Parent();
	
	m_pSmsMtm->SwitchCurrentEntryL( parent );
	m_pSmsMtm->Entry().DeleteL( aMessageId );
}


TBool CMtmEngine::GetMessageL(TMsvId aMessageId,TDes& aMessage)
{
	m_pSmsMtm->SwitchCurrentEntryL( aMessageId );
	
	if ( m_pSmsMtm->Entry().HasStoreL() ) 
	{
		// SMS message is stored inside Messaging store.
		CMsvStore* store = m_pSmsMtm->Entry().ReadStoreL();
		CleanupStack::PushL(store);
		
		if (store->HasBodyTextL())
		{
			CRichText* richText = CRichText::NewL(
				CEikonEnv::Static()->SystemParaFormatLayerL(),
				CEikonEnv::Static()->SystemCharFormatLayerL());
			richText->Reset();
			CleanupStack::PushL(richText);
			
			// Get the SMS body text.
			store->RestoreBodyTextL(*richText);
			const TInt length = richText->DocumentLength();
			TBuf<KMessageBodySize> message;
			
			// Check length because message is read to limited size TBuf.
			if ( length >= KMessageBodySize ) 
			{
				message.Append( richText->Read(0, KMessageBodySize -1) );
			}
			else 
			{
				message.Append( richText->Read(0, length) );
			}
			
			aMessage.Append( message );
			
			CleanupStack::PopAndDestroy(richText);
		}
		CleanupStack::PopAndDestroy(store);
	}
	else
	{
		return EFalse;
	}
	
	return ETrue;
}
void CMtmEngine::GetMessageAddressL(TMsvId aMessageId,TDes& aAddress)
{
	m_pSmsMtm->SwitchCurrentEntryL( aMessageId );	
	
	// Remember to load before using the SmsHeader
	m_pSmsMtm->LoadMessageL();
	
// 	 	CSmsHeader&	header = m_pSmsMtm->SmsHeader();
// 	
// 		aAddress.Append( header.FromAddress() );
	// Other possibility is this: (It's little bit faster than the previous one).
	aAddress.Append( m_pSmsMtm->Entry().Entry().iDetails );
}
TBool CMtmEngine::GetMessageIndexBodyTextL(TMsvId aMessageId,TDes& aMessage)
{
	m_pSmsMtm->SwitchCurrentEntryL( aMessageId );
	aMessage.Append(m_pSmsMtm->Entry().Entry().iDescription );
	return ETrue;
}
RArray<TMsvId>* CMtmEngine::GetMessageIds()
{
	return m_pIdArray;
}	
void CMtmEngine::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3)
{
	switch (aEvent)
	{
        // This event tells us that the session has been opened
	case EMsvServerReady:
		CreateMtmClientL();
		break;
	default:
		// do nothing
		break;
	}
}

⌨️ 快捷键说明

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