Sending e-mail from code

Login to reply to this topic.
Thu, 2005-04-28 07:20
Joined: 2004-11-29
Forum posts: 9
Hello everybody,

   I wonder if someone achieved success to send e-mail from code. I made search in this forum and many internet resources and found only a lot of similar questions w/o answers.
   What I got as a result is e-mail in Messaging software Outbox with queued status. I may select this message and then send it with menu. The question is how to perform sending automatically from code.  Huh:

I paste my code below for your attention:
Code:
// CMsvSession
#include "AppConst.h"
#include "msgservice.h"

CSendSynchMail* CSendSynchMail::NewL()
{
CSendSynchMail* obj = new(ELeave) CSendSynchMail;
CleanupStack::PushL(obj);
obj->ConstructL();
CleanupStack::Pop();
return obj;
}

CSendSynchMail::CSendSynchMail()
{
}

void CSendSynchMail::ConstructL()
{
// connect to MTM server
iSession = CMsvSession::OpenSyncL(*this);
CleanupStack::PushL(iSession);

// create MTM registry
iMtmRegistry = CClientMtmRegistry::NewL(*iSession);
CleanupStack::PushL(iMtmRegistry);

// create smtp MTM
iMtm = static_cast<CSmtpClientMtm*>(iMtmRegistry->NewMtmL(KUidMsgTypeSMTP));
CleanupStack::PushL(iMtm);

// find service
iServiceId = FindServiceByTypeL(KUidMsgTypeSMTP);
if( iServiceId==KMsvRootIndexEntryId )
User::Leave(KErrNotFound);

// Ui registry
iUiRegistry = CMtmUiRegistry::NewL(*iSession);
CleanupStack::PushL(iUiRegistry);
iMtmUi = iUiRegistry->NewMtmUiL( *iMtm );

CleanupStack::Pop(4);
}

CSendSynchMail::~CSendSynchMail()
{
delete iMtmUi;
delete iUiRegistry;
delete iMtm;
delete iMtmRegistry;
delete iSession;
}

TMsvId CSendSynchMail::FindServiceByTypeL(TUid aServiceType)
{
// select the root index to start the search
CMsvEntry* currentEntry = iSession->GetEntryL(KMsvRootIndexEntryId);
CleanupStack::PushL(currentEntry);

TMsvId rc = KMsvRootIndexEntryId;
TInt count = currentEntry->Count();

{
TBuf<100> msg; msg.Format(_L("%d: services count"), count);
Log(msg);
}

// loop for every child entry of the root index
for(TInt i = 0; i<count; i++)
{
const TMsvEntry& child = (*currentEntry)[i];

{
TBuf<100> msg; msg.Format(_L("%x: service enum"), child.iMtm.iUid);
Log(msg);
}

// is the current child the same type as the type we are lookingfor ?
if( child.iMtm==aServiceType )
{
rc = child.Id();
break;
}
}//for
CleanupStack::PopAndDestroy(currentEntry);
return rc;
}

void CSendSynchMail::SendMailL(const TDesC& aAddress)
{
Log(_L("CSendSynchMail::SendMailL() begin"));

CMsvEntry* rentry = CMsvEntry::NewL(*iSession, KMsvGlobalOutBoxIndexEntryId ,TMsvSelectionOrdering());
CleanupStack::PushL(rentry);
rentry->AddObserverL(*this);
Log(_L("CSendSynchMail::SendMailL() 0"));

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

// asynch wait object
CMsvOperationWait* wait = CMsvOperationWait::NewLC();
CleanupStack::PushL(wait);
Log(_L("CSendSynchMail::SendMailL() 1"));

wait->Start();
Log(_L("CSendSynchMail::SendMailL() 2"));

// create new entry
iOperation = rentry->CreateL(newEntry, wait->iStatus);
CleanupStack::PushL(iOperation);
Log(_L("CSendSynchMail::SendMailL() 3"));

CActiveScheduler::Start(); // wait for complette
TMsvLocalOperationProgress prog = McliUtils::GetLocalProgressL(*iOperation);
{
TBuf<100> msg; msg.Format(_L("%d - error!"), prog.iError);
Log(msg);
}
User::LeaveIfError(prog.iError);
Log(_L("CSendSynchMail::SendMailL() 3.0"));
CleanupStack::PopAndDestroy(); // iOperation
Log(_L("CSendSynchMail::SendMailL() 3.1"));
CleanupStack::PopAndDestroy(); // wait
Log(_L("CSendSynchMail::SendMailL() 3.2"));
//CleanupStack::PopAndDestroy(); // entry
//entry = NULL;

Log(_L("CSendSynchMail::SendMailL() 4"));

CMsvEntry* entry = iSession->GetEntryL(prog.iId);
CleanupStack::PushL(entry);
Log(_L("CSendSynchMail::SendMailL() 5"));

// switch to global
iMtm->SetCurrentEntryL(entry);
//iMtm->SwitchCurrentEntryL(KMsvGlobalOutBoxIndexEntryId);
Log(_L("CSendSynchMail::SendMailL() 6"));
//iMtm->LoadMessageL();

// create new message
//iMtm->CreateMessageL(iServiceId);
//Log(_L("CSendSynchMail::SendMailL() 7"));

CImSmtpSettings* set = new(ELeave) CImSmtpSettings();
CleanupStack::PushL(set);
Log(_L("CSendSynchMail::SendMailL() 8"));
set->CopyL(iMtm->Settings());
iMtm->AddAddresseeL(aAddress);
iMtm->SetSubjectL(_L("this is subject"));
set->SetSendMessageOption(ESendMessageImmediately);
iMtm->SetSettingsL(*set);
Log(_L("CSendSynchMail::SendMailL() 9"));
entry->Entry().SetInPreparation(EFalse);
entry->Entry().SetScheduled(ETrue);
entry->Entry().SetSendingState(KMsvSendStateWaiting);
iMtm->SaveMessageL();
CleanupStack::PopAndDestroy(); // set

// switch context
//iMtm->SwitchCurrentEntryL(KMsvGlobalOutBoxIndexEntryId);
Log(_L("CSendSynchMail::SendMailL() 10"));
CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
CleanupStack::PushL(selection);
selection->AppendL(prog.iId);
{
TBuf<100> msg; msg.Format(_L("%x: smtp service!"), iServiceId);
Log(msg);
}

wait = CMsvOperationWait::NewLC();
CleanupStack::PushL(wait);
Log(_L("CSendSynchMail::SendMailL() 11"));
wait->Start();

CMsvEntry* service_entry = iSession->GetEntryL(iServiceId);
CleanupStack::PushL(service_entry);

// switch context
//iMtm->SwitchCurrentEntryL(entry->Entry().Parent());
Log(_L("CSendSynchMail::SendMailL() 11.0"));
iMtm->SetCurrentEntryL(service_entry);
Log(_L("CSendSynchMail::SendMailL() 11.1"));
iOperation = iMtmUi->CopyToL(*selection, wait->iStatus);
CleanupStack::PushL(iOperation);
Log(_L("CSendSynchMail::SendMailL() 12"));

CActiveScheduler::Start(); // wait for complette
prog = McliUtils::GetLocalProgressL(*iOperation);
User::LeaveIfError(prog.iError);
Log(_L("CSendSynchMail::SendMailL() 13"));

CleanupStack::PopAndDestroy(4+1); // iOperation, wait, selection, entry

Log(_L("CSendSynchMail::SendMailL() end"));
}

void CSendSynchMail::HandleEntryEventL(TMsvEntryEvent aEvent, TAny* aArg1, TAny* /*aArg2*/, TAny* /*aArg3*/)
{
switch( aEvent )
{
case EMsvNewChildren:
{
Log(_L("new children!!!"));
CMsvEntrySelection* selection = (CMsvEntrySelection*)aArg1;
/*iNewChild = */(*selection)[0];
}
break;

default:
break;
}
}

void CSendSynchMail::HandleSessionEventL(TMsvSessionEvent /*aEvent*/, TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
{

}


Fri, 2005-06-24 10:53
Joined: 2005-06-24
Forum posts: 5
Re: Sending e-mail from code
Some suggestion/comments on ur code:

This is ur ConstruL:

void CSendSynchMail::ConstructL()
{
   // connect to MTM server
   iSession = CMsvSession::OpenSyncL(*this);
   CleanupStack::PushL(iSession);
   
   // create MTM registry
   iMtmRegistry = CClientMtmRegistry::NewL(*iSession);
   CleanupStack::PushL(iMtmRegistry);
   
   // create smtp MTM
   iMtm = static_cast<CSmtpClientMtm*>(iMtmRegistry->NewMtmL(KUidMsgTypeSMTP));
   CleanupStack::PushL(iMtm);
   
   // find service
   iServiceId = FindServiceByTypeL(KUidMsgTypeSMTP);
   if( iServiceId==KMsvRootIndexEntryId )
      User::Leave(KErrNotFound);
   
   // Ui registry
   iUiRegistry = CMtmUiRegistry::NewL(*iSession);
   CleanupStack::PushL(iUiRegistry);
   iMtmUi = iUiRegistry->NewMtmUiL( *iMtm );
   
   CleanupStack::Pop(4);
}

Never ever write such code in Program as,

ur destructer is like this:

CSendSynchMail::~CSendSynchMail()
{
   delete iMtmUi;
   delete iUiRegistry;
   delete iMtm;
   delete iMtmRegistry;
   delete iSession;
}

Suppose that, ur ConstructL leaves in between. lets say some where after after "CleanupStack::PushL(iSession);"
So, TRAP down the line will take care of deleting everything those items that are in CleanupStack, and obviously ur iSession is one among them.
Now in ur destructer, again u r deleting iSession, in which case, you are doing double deletion and your appln will PANIC.

So, never Push Members Variables to Cleanup Stack, if you are deleting them in destructer.

Regards
Girish

Girish Shetty

  • Login to reply to this topic.