Sending e-mail from code
| Thu, 2005-04-28 07:20 | |
|
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. : 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*/) { } |
|






:
Forum posts: 5
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