📄 msg1.cpp
字号:
//
// Msg1.cpp - Msg1 example
//
// Copyright (C) UIQ Technology AB, 2007
//
// This material is provided "as is" without any warranty to its performance or functionality.
// In no event shall UIQ Technology be liable for any damages whatsoever arising out of the
// use or inabilty to use this material.
//
#include "Msg1.h"
#include "Msg1.hrh"
#include <Msg1.rsg>
#include <QikViewBase.h>
#include <QikCommand.h>
#include <QikListBoxModel.h>
#include <QikListBox.h>
#include <MQikListBoxData.h>
#include <eikstart.h>
#include <Msvstd.h>
#include <Msvids.h>
#include <Msvapi.h>
#include <Mtclreg.h>
#include <Mtclreg.h>
#include <SmsClnt.h>
#include <Smut.h>
#include <Smuthdr.h>
#include <txtrich.h>
#include <Smscmds.h>
//////////////////////////////////////////////////////////////////////////////
// The application Uid here MUST match UID3 defined in the MMP file
// This is a development UID and must NOT be used in production type software
const TUid KAppSpecificUid={0xEDEAD014};
// internal secondary view id, must be unique amongst this applications views
const TUid KUidListView={0x00000001};
// views within applications are fully identified by the app Uid and secondary view id
#define KViewIdListView TVwsViewId(KAppSpecificUid,KUidListView)
//////////////////////////////////////////////////////////////////////////////////
class CLogText : public CBase
{
public:
// new methods
~CLogText();
void ConstructL();
TInt Count();
const TDesC& At(const TInt aIndex);
void LogText(const TDesC& aBuf);
void ResetText();
protected:
CArrayFixFlat<HBufC*>* iText;
};
CLogText::~CLogText()
{
ResetText();
delete(iText);
}
void CLogText::ConstructL()
{
iText=new(ELeave)CArrayFixFlat<HBufC*>(32);
}
TInt CLogText::Count()
// Report number of logged messages
{
return(iText->Count());
}
const TDesC& CLogText::At(const TInt aIndex)
// report 'n'th text message
{
return(*iText->At(aIndex));
}
void CLogText::ResetText()
{
TInt count=Count();
for (TInt i=0;i<count;i++)
delete(iText->At(i));
iText->Reset();
}
void CLogText::LogText(const TDesC& aBuf)
{ // add new text item to front of the list
TRAPD(err,
TBuf<128>bb;
if (aBuf.Length()>120)
bb=aBuf.Left(120);
else
bb=aBuf;
HBufC* q=bb.AllocLC();
iText->InsertL(0,q); // at front of list
CleanupStack::Pop(q);
if (iText->Count()>100)
{ // restrict to last 100 log msgs
delete(iText->At(100));
iText->Delete(100);
}
);
}
//////////////////////////////////////////////////////////////////////////////////
class MMsgEngineObserver
{
public:
virtual void LogInfo(const TDesC& aBuf)=0;
};
//////////////////////////////////////////////////////////////////////////////////
const TInt KMaxSmsMessageSize=160; // Max number of 7-bit GSM chars in an SMS msg
const TInt KMaxTelephoneNumber=32; // max length of a telephone number
enum TMessageEngineSmsSendState
{
ESmsSendIdle,
ESmsSendCreateMessage,
ESmsSendMoveMessageToOutBox,
ESmsSendTransmittingMessage
};
class CMessageEngine : public CActive, public MMsvSessionObserver
{
protected:
// from MMsvSessionObserver
void HandleSessionEventL(TMsvSessionEvent aEvent,TAny* aArg1,TAny* aArg2,TAny* aArg3);
void DoCancel();
void RunL();
// new methods
void DeleteOperation();
void MsgCreationCompleteL(const TMsvId aId);
public:
// new methods
~CMessageEngine();
CMessageEngine(MMsgEngineObserver* aObserver);
void ConstructL();
TBool StartSendText(const TDesC& aMessageBody,const TDesC& aSmsAddress);
protected:
MMsgEngineObserver* iObserver;
CMsvSession* iMessageServer;
CClientMtmRegistry* iMtmRegistry;
TMessageEngineSmsSendState iState;
CMsvEntrySelection* iSendSelection; // list of IDs of msgs to send
CMsvEntry* iMsvEntry;
CMsvOperation* iOperation;
CBaseMtm* iMtm;
TBuf<KMaxSmsMessageSize> iMessageBody; // actual msg body to send
TBuf<KMaxTelephoneNumber> iDestinationAddress; // where were sending it to
};
CMessageEngine::~CMessageEngine()
{
Cancel();
delete(iOperation);
delete(iMsvEntry);
delete(iSendSelection);
delete(iMtm);
delete(iMtmRegistry);
delete(iMessageServer);
}
CMessageEngine::CMessageEngine(MMsgEngineObserver* aObserver) :
CActive(CActive::EPriorityStandard),iObserver(aObserver)
{
CActiveScheduler::Add(this);
}
void CMessageEngine::HandleSessionEventL(
//
// Called back by the message server when things happen
//
TMsvSessionEvent aEvent,
TAny* aArg1,
TAny* aArg2,
TAny* aArg3)
{
TBuf<128>bb;
_LIT(KHandleEventL,"HandleEventL:%d");
bb.Format(KHandleEventL,aEvent);
iObserver->LogInfo(bb);
// an example of the kind of information being provided. Here we extract the information as
// defined by the EMsvEntriesMoved enum in MSVAPI.H
if (aEvent==EMsvEntriesMoved)
{
// arg2 is the TMsvId of the new parent
TMsvId* entryId=static_cast<TMsvId*>(aArg2);
if (*entryId==KMsvSentEntryId)
{ // items have been moved to the Sent items folder
// aArg1 is a CMsvEntrySelection (list of entries that have been moved)
CMsvEntrySelection* selection=static_cast<CMsvEntrySelection*>(aArg1);
TBuf<128>bb;
TInt count=selection->Count();
_LIT(KMovedToSentFolder,"%d moved to sent folder");
bb.Format(KMovedToSentFolder,count);
iObserver->LogInfo(bb);
for (TInt i=0;i<count;i++)
{
_LIT(KMovedId,"Moved Id %d");
bb.Format(KMovedId,selection->At(i));
iObserver->LogInfo(bb);
}
}
}
}
void CMessageEngine::ConstructL()
{
// obtain an IPC connection to the meesage sever process
iMessageServer=CMsvSession::OpenSyncL(*this);
// we need a client side CClientMtmRegistry to obtain MTM objects
iMtmRegistry=CClientMtmRegistry::NewL(*iMessageServer);
// required to send SMS entries
iSendSelection=new(ELeave)CMsvEntrySelection();
// the one CMsvEntry we should endevour to reuse
iMsvEntry=CMsvEntry::NewL(*iMessageServer,KMsvGlobalInBoxIndexEntryId,TMsvSelectionOrdering());
TBuf<256>bb;
// Scan the inbox looking for SMS messages.
CMsvEntrySelection* inboxEntries=iMsvEntry->ChildrenWithMtmL(KUidMsgTypeSMS);
CleanupStack::PushL(inboxEntries);
TInt count=inboxEntries->Count();
// display number of SMS entries we have been informed exist
_LIT(KSMSEntries,"%d SMS entries");
bb.Format(KSMSEntries,count);
iObserver->LogInfo(bb);
/*
Whilst totally valid + works, it is undesriable to create a CMsvEntry for every entry.
// display who each SMS from + the content as an example of acessing these items
for (TInt i=0;i<count;i++)
{
CMsvEntry* qq=iMessageServer->GetEntryL(inboxEntries->At(i));
TMsvEntry msvEntry=qq->Entry();
delete(qq);
// demonstrate its an SMS msg thats arrived
if (msvEntry.iMtm!=KUidMsgTypeSMS)
continue;
// obtain some info about the SMS in the Inbox
CSmsClientMtm* smsMtm=static_cast<CSmsClientMtm*>(iMtmRegistry->NewMtmL(KUidMsgTypeSMS));
CleanupStack::PushL(smsMtm);
smsMtm->SwitchCurrentEntryL(inboxEntries->At(i));
smsMtm->LoadMessageL();
// we can look at the SMS header to see who its from
CSmsHeader& smsHdr=smsMtm->SmsHeader();
TPtrC msgFrom(smsHdr.FromAddress());
_LIT(KSMSFrom,"SMS from: %S");
bb.Format(KSMSFrom,&msgFrom);
iObserver->LogInfo(bb);
// we can look at the body to see the content
TPtrC msgBody(smsMtm->Body().Read(0));
_LIT(KSMSBody,"SMS body: %S");
bb.Format(KSMSBody,&msgBody);
iObserver->LogInfo(bb);
CleanupStack::PopAndDestroy(smsMtm);
}
CleanupStack::PopAndDestroy(inboxEntries);
*/
// demonstrates how you should go about reusing the CMsvEntry
CSmsClientMtm* smsMtm=static_cast<CSmsClientMtm*>(iMtmRegistry->NewMtmL(KUidMsgTypeSMS));
CleanupStack::PushL(smsMtm);
for (TInt i=0;i<count;i++)
{
iMsvEntry->SetEntryL(inboxEntries->At(i));
const TMsvEntry& tEntry=iMsvEntry->Entry();
// demonstrate its an SMS msg thats arrived
if (tEntry.iMtm!=KUidMsgTypeSMS)
continue;
// type should be KUidMsvMessageEntry, iServiceId will be KMsvLocalServiceIndexEntryId
_LIT(KTypeServiceId,"Type: %d, ServiceId %d");
bb.Format(KTypeServiceId,tEntry.iType.iUid,tEntry.iServiceId);
iObserver->LogInfo(bb);
// obtain some info about the SMS in the Inbox
smsMtm->SwitchCurrentEntryL(inboxEntries->At(i));
smsMtm->LoadMessageL();
// we can look at the SMS header to see who its from
CSmsHeader& smsHdr=smsMtm->SmsHeader();
TPtrC msgFrom(smsHdr.FromAddress());
_LIT(KSMSfrom,"SMS from: %S");
bb.Format(KSMSfrom,&msgFrom);
iObserver->LogInfo(bb);
// we can look at the body to see the content
TPtrC msgBody(smsMtm->Body().Read(0));
_LIT(KSMSbody,"SMS body: %S");
if (msgBody.Length()>200)
{ // ensure we cant overflow our buffer in the example code
TPtrC xx=msgBody.Left(200);
bb.Format(KSMSbody,&xx);
}
else
bb.Format(KSMSbody,&msgBody);
iObserver->LogInfo(bb);
}
// tidy up
CleanupStack::PopAndDestroy(smsMtm);
CleanupStack::PopAndDestroy(inboxEntries);
// alternativly we can reduce above 2 PopAndDestroys to
// CleanupStack::PopAndDestroy(2); // smsMtm, inboxEntries
}
void CMessageEngine::DeleteOperation()
// Tidy up the worker objects
{
delete(iOperation);
iOperation=NULL;
}
TBool CMessageEngine::StartSendText(
//
// Create the msg to send, start sending it
//
const TDesC& aMessageBody,
const TDesC& aSmsAddress)
{
if (IsActive())
return(EFalse); // we cant send the info just yet, were busy doing previous request
// Reset list of Ids of messages we wish to send - as were creating a new one
DeleteOperation();
iSendSelection->Reset();
// save the message body and target address
iMessageBody=aMessageBody;
iDestinationAddress=aSmsAddress;
// Setup a blank sms message in the message server. The created SMS has no body or
// destination telephone number at this stage.
TMsvEntry newEntry; // An entry in the Message Server index
newEntry.iServiceId=KMsvLocalServiceIndexEntryId; // ID of local service (containing the standard folders)
newEntry.iRelatedId=0;
newEntry.iType=KUidMsvMessageEntry; // the type of the entry: a message
newEntry.iMtm=KUidMsgTypeSMS; // its an SMS msg
newEntry.iDate.UniversalTime();
newEntry.iSize=0;
newEntry.iError=0;
newEntry.iBioType=0;
newEntry.iMtmData1=0;
newEntry.iMtmData2=0;
newEntry.iMtmData3=0;
newEntry.SetInPreparation(ETrue); // this message is in preparation
TRAPD(err,
// represents an entry we are manipulating. By setting to the Draft folder we will create
// the new entry in Drafts...
iMsvEntry->SetEntryL(KMsvDraftEntryIdValue);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -