Newsgroup: it.comp.lang.delphi
Titolo: IdMessage e Multi-thread

Ciao a tutti!
Ho sviluppato una piccola applicazione con la quale invio delle email
tramite i componenti IdSMTP e IdMessage di Indy... Avrei la necessità
di fare un invio simultaneo dei messaggi attraverso vari threads.
L'unico problema che non riesco a risolvere è questo: devo copiare i
valori del messaggio IdMessage dal thread principale ai vari threads.
Ho cercate di farlo, causando errori, nel seguente modo:
__fastcall ThreadInviaEmail::ThreadInviaEmail(bool
CreateSuspended,AnsiString sorgCont,int start,int fine,AnsiString
dnsAddr,TIdMessage *Message)
        : TThread(CreateSuspended)
{
IdMessage1 = new TIdMessage(NULL);
IdMessage1->From->Name =  Message->From->Name;
IdMessage1->From->Address =  Message->From->Address;
IdMessage1->ReplyTo->EMailAddresses =
Message->ReplyTo->EMailAddresses;
IdMessage1->Subject =  Message->Subject;
IdMessage1->MessageParts = Message->MessageParts;
IdMessage1->Body = Message->Body;
IdMessage1->ContentType = Message->ContentType;
IdMessage1->ExtraHeaders->Assign(Message->ExtraHeaders);
IdMessage1->Recipients->EMailAddresses =
Message->Recipients->EMailAddresses;
}
Avete qualche idea su come passare i parametri all'IdMessage nel modo
corretto? Ne sarei molto grato!
Mille grazie!

valori del messaggio IdMessage dal thread principale ai vari threads.
A parte che non capisco perché devi copiare l'oggetto IdMessage (la
spedizione simultanea dell *stesso* messaggio è già prevista dai
componenti Indy), io ti dico di passare al secondo thread i dati che
devono comporre un nuovo messaggio e far sì che esso si preoccupi di
istanziare il proprio TIdMessage.

Passare al secondo thread i dati che devono comporre un nuovo messaggio
e far sì che esso si preoccupi di istanziare il proprio TIdMessage è
difficoltoso, perchè il messaggio è composto da allegati ed immagini,
i quali non sono riuscito a passarli...
Ecco come facevo, nel thread principale, a creare il messaggio:
- Il testo del messaggio lo creo con:
theText1 = new TIdText(IdMessage1->MessageParts, slBody);
e lo assegno con:
IdMessage1->Body->Assign(slBody);
- Le immagini allegate le inserisco con:
theImage = new TIdAttachment(IdMessage1->MessageParts,
OpenDialog1->FileName );
- Gli allegati li inserisco con:
allegato = new TIdAttachment(IdMessage1->MessageParts,
OpenDialog1->FileName );
- Domanda: come faccio a fare tutto questo nel thread secondario?? Gli
passo i puntatori theText1, theImage e allegato?? Non credo basti
questo...

i quali non sono riuscito a passarli...
Che vuol dire "non sono riuscito a passarli" ? 
Fosse anche che da un thread all'altro devi passare una carovana di
elefanti, chiudi tutto in un record allocato dinamicamente e passi il
puntatore con PostThreadMessage.  Piů semplice di cosě.
Nulla di difficoltoso.

"non sono riuscito a passarli" significa che non sono riuscito a
passare ai threads tutti i parametri del messaggio, il quale non è
composto solo da testo ma anche di allegati ed immagini... risolverei
ogni problema se potessi passare per valore l'oggetto IdMessage, così
avrei una copia identica dell' IdMessage che c'è nel thread
principale.
Grazie ma non ho mai usato PostThreadMessage, quindi non saprei da dove
iniziare per passare i parametri ai threads...
Comunque sono riuscito a passare, uno per volta come vedi sopra, tutti
i parametri necessari tranne IdMessage1->MessageParts, che ho cercato
di passare con:
IdMessage1->MessageParts->Assign(Message->MessageParts);
Viene visualizzato il seguente errore: Project raised exception class
EIdCanNotCreateMessagePart with message 'TIdMessagePart can not be
created. Use descendant classes.'
Come posso fare? Avete in mente qualcosa per risolvere questo errore o
per passare per copia l'intero oggetto IdMessage?

per passare per copia l'intero oggetto IdMessage?
Passare i singoli parametri.

Passare i singoli parametri... facile a dirsi ma difficile a farsi,
almeno per me... altrimenti non avrei postato questo problema.
Ripeto che sono risucito a passare tutti i parametri eccetto
IdMessage1->MessageParts, il quale non riesco a crearlo col codice che
ho utilizzato:
IdMessage1->MessageParts->Assign(Message->MessageParts);
Quindi cerco di risolvere il problema passando al secondo thread i dati
che devono comporre il messaggio e far sì che esso si preoccupi di
istanziare il proprio TIdMessage.
- Con messaggi HTML senza allegati ed immagini incorporate non ci sono
problemi... avendo un vettore di threads, ho fatto così:
VettInviaEmail1[i]->email_slBody->Add(frmMain->EditMessaggio->Text);
email_theText1 = new
TIdText(VettInviaEmail1[i]->IdMessage1->MessageParts,
VettInviaEmail1[i]->email_slBody);
if (frmMain->ComboBoxTipoInvio->Text == "HTML" )
    email_theText1->ContentType = "text/html";
else if (frmMain->ComboBoxTipoInvio->Text == "Testo" )
    email_theText1->ContentType = "text/plain";
email_theText2 = new
TIdText(VettInviaEmail1[i]->IdMessage1->MessageParts,NULL);
email_theText2->ContentType = "text/plain";
email_theText2->Body->Text = "";
VettInviaEmail1[i]->IdMessage1->Body->Assign(VettInviaEmail1[i]->email_slBody);
VettInviaEmail1[i]->IdMessage1->ContentType = "multipart/mixed";
- Quando invece ho messaggi HTML con allegati ed immagini incorporate
non riesco ad inserirli nel messaggio, perchè li inserivo tramite
funzioni che facevano riferimento all' IdMessage del thread principale
come questa:
theImage = new TIdAttachment(IdMessage1->MessageParts,
OpenDialog1->FileName );
- A questo punto vedo che, almeno per quanto riguarda
IdMessage1->MessageParts, ci sono parecchi problemi nel passare i
parametri uno per volta... non c'è qualche modo per copiare in blocco
IdMessage1->MessageParts nel secondo thread?? Come già detto, con
Assign() non sono riuscito.

almeno per me... altrimenti non avrei postato questo problema.
E' difficile capire che cosa ci sia di difficile, se non lo spieghi.
Dal canto mio, non capisco che cosa ci sia di così complicato:
un'email è un composto di più elementi base, tutti qui.  Sia che essa
sia in "plain text" o HTML, hai sempre degli elementi da cui partire.
Così come componi 1 messaggio a partire da questi elementi, ne componi
n.  Sul serio, non so davvero capire qual è la tua difficoltà.

 ha scritto nel messaggio 
news:1142768176.4...@i39g2000cwa.googlegroups.com...
Passare i singoli parametri... facile a dirsi ma difficile a farsi,
almeno per me... altrimenti non avrei postato questo problema.
Scusa, non ho letto tutto il thread, forse ti dirņ una banalitą.
Tu vuoi replicare un intero messaggio?
Facile.
idMessage.SaveToStream
idMessage.LoadFromStream
oppure i corrispettivi ToFile.
Puņ esserti utile?

suggerimento che ti ho dato ci sta dentro. :-)
Sì ma, a che serve? la spedizione dello stesso messaggio a destinatari
multipli è previsto di serie dai componenti Indy.  Perché reinventare
la ruota?

 la ruota?
Non sapevo ci fosse qualche altro componente del genere. :)
In alcuni casi ho utilizzato i soliti indirizzi multipli sulla lista dei 
destinatari, oppure su cc o su bcc, ma non sapevo ci fosse qualcosa d'altro.
Ma ho anche avuto tempo fa l'esigenza di spedire a piů persone, spedendo ad 
ognuno di loro lo stesso messaggio personalizzato nella parte finale del 
corpo con alcuni loro dati, senza utilizzare indirizzi multipli o il campo 
bcc, ed ho fatto inviare tanti messaggi quanti erano i destinatari. Certo, 
la velocitŕ per le mie cose non mi interessa, quindi ho preferito aspettare 
durante l'invio un minuto in piů, piuttosto che scrivere codice per una ora 
in piů.
Spero comunque Carmelo non stia scrivendo un software spammatore! Mi 
pentirei di avergli consigliato quei due metodi. :)))

destinatari, oppure su cc o su bcc, ma non sapevo ci fosse qualcosa d'altro.
Si sta parlando *proprio* dei componenti Indy.

 Si sta parlando *proprio* dei componenti Indy.
Appunto: di componenti indy ce n'è un fracco. Credevo parlassi di qualche 
componente indy idMultiMessageQualcosa che facesse ciò che voleva fare 
Carmelo.
Intuisco allora che ti riferivi alle liste di destinatari del idMessage.
Non va bene. Oltre al fatto che molti server smtp negano l'invio quando 
metti più di un tot di destinatari, per chi riceve la mail dà una immagine 
poco professionale dell'azienda che invia messaggi nascondendo i destinatari 
o addirittura ne nega palesemente la privacy inserendoli in massa nei campi 
visibili a tutti.
Per non dire che ci sono utenti come me che segano direttamente dal server i 
messaggi con destinatari eliminati (bcc).
Poi è chiaro che tutto si basa su ciò che effettivamente Carmelo debba fare. 
Se non ha troppe pretese mette i destinatari, quanti più possibile, in bcc e 
via. 

Non posso mettere i destinatari su Bcc, proprio per una questione di
privacy ed anche per una questione di limiti imposti da alcuni server
di posta... La soluzione migliore credo proprio sia quella tua GDG. Ho
provato ad usare IdMessage.SaveToFile() e questo metodo funziona quasi
su tutto. Dico quasi perchè ho ancora il problrma di prima, cioè non
riesco a mandare gli allegati. Ho fatto un test nel seguente modo:
1) Ho inviato un messaggio html senza allegati e tutto è andato bene.
2) Ho inviato un messaggio con un allegato ed il destinatario non
riceve l'allegato. Ho aperto il messaggio ricevuto e contiene
effettivamente quello che contiene il file su cui ho salvato i dati con
IdMessage.SaveToFile().
3) Ho inviato un messaggio con un allegato dal thread principale ed uno
da un thread secondario, ed ho confrontato i messaggi ricevuti.
Risultato: non sono identici, ci sono delle differenze, forse a causa
delle quali non viene mostrato l'allegato al destinatario. Ho comunque
notato che gli allegati sono codificati col MIME in entrambi i messaggi
ma solo in quello mandato dal thread principale vengono mostrati...
Come posso fare??

Carmelo:
 Ho provato ad usare IdMessage.SaveToFile() e questo metodo funziona quasi
su tutto. Dico quasi perchč ho ancora il problrma di prima, cioč non
riesco a mandare gli allegati.
Con il LoadFromStream e SaveToStream mi ci son costruito un server smtp. Mi 
pare strano che non ti funziona.
Sei sicuro che inviando il messaggio principale, quello da dove poi generi 
tutti gli altri, l'allegato arriva normalmente?
Se non imposti un po' di campi e parti nell'idMessage, tra antivirus attuali 
e blocco degli allegati nel mailer, l'allegato c'č, ma non si vede.
Prova a scoprire inviando a te stesso.
Ti assicuro che i due metodi funzionano alla perfezione e salvano e caricano 
*interamente* il messaggio.

Sono sicurissimo che col thread principale arrivi perfettamente.
Infatti fino ad ora ho potuto mandare i messaggi solo col thread
principale, con quello secondario invece sto avendo problemi...
Spiego megli quello che ho fatto:
- Dal thread principale
IdMessage1->SaveToFile(progDir+"idmessage.dat");
- Dal thread secondario
IdMessage1->LoadFromFile(progDir+"idmessage.dat");
//qui inizia un ciclo col quale spedisco agli indirizzi presenti sulla
mia lista di spedizione
IdMessage1->Recipients->EMailAddresses = str;
IdSMTP1->Send(IdMessage1);
Ripeto che il messaggio arriva perfettamente tranne gli allegati, i
quali sono codificati all'interno del messaggio in MIME ma non sono
visualizzati. Credo che il motivo siano delle piccole differenze nel
messaggio inviato dal thread principale rispetto al thread secondario.
Se mi mandi il tuo indirizzo email Giuseppe ti mostrerò in dettaglio
come sono fatti i due messaggi...
Grazie

Il mio indirizzo è semplice.
Prendi l'attuale e scambi il dominio "giuseppe" col nome utente "digrande" 
tale che risulterà
giuseppe chiocciola digrande punto it
Se mi mandi come prova uno di questi messaggi fallo sia con il messaggio 
originale sia col duplicato.
Eventualmente poi ti scrivo cosa specificare nei campi necessari e come 
aggiungere l'allegato.
Ciao 

carmelo ha scritto:

Ciao,
  non ho seguito tutta la discussione, a onor del vero, comunque, visto 
che dici che i messaggi arrivano mi sembra che tu abbia risolto la parte 
relativa alla comunicazione tra i thread, quindi salto anche l'eventuale 
discussione relativa alle sezioni critiche (TCriticalSection) etc. e 
rispondo su questo ultimo punto chiedendoti se hai impostato 
correttamente tutte le proprieta' del messaggio: io, infatti, ho da poco 
avuto l'esigenza di inviare dei messaggi con contenuto di tipo text/html 
ed ho dovuto quindi impostare a questo valore la proprieta' 
"TIdMessage.ContentType" (: string), che di default vale "text/plain".
Non vorrei avere preso troppo semplicemente il problema, ma prova a dare 
un'occhiata e fammi sapere.
Ciao,
baba.

Grazie per la risposta baba, ma non è questo il problema.
Ricapitolando, ecco in sintesi cosa succede:
Col thread principale riesco ad inviare perfettamente i messaggi anche
se hanno allegati. Il problema si presenta quando li devo inviare da
threads secondari, ai quali devo "passare" il messaggio usato dal
thread principale. Tutto funziona e viene passato correttamente tranne
la parte che riguarda gli allegati, anche usando
IdMessage1.SaveToFile() e LoadFromFile...
Non so proprio come fare, perchè una soluzione sarebbe creare in ogni
thread un nuovo messaggio basandosi su parametri passati dal thread
principale. Ma dal thread principale sono riuscito a passare tutto
tranne IdMessage1->MessageParts che, guarda caso, mi serve proprio per
gli allegati !!
Finora ho avuto quindi sempre lo stesso problema, sia usando
SaveToFile() sia passando i parametri uno per volta, gli allegati non
sono riuscito a mandarli dai threads secondari.
Controllando i messaggi mandati dai threads secondari, caricati in ogni
thread con LoadFromFile, mi sono accorto che in questo caso gli
allegati erano presenti nel messaggio e codificati in MIME, ma non
venivano visualizzati dal client di posta.

carmelo ha scritto:

Ok, non avevo capito bene.
Io procederei ad isolare il codice del thread secondario, esaminarlo e 
appurare che tutti i dati necessari alla corretta creazione ed 
inizializzazione dell'oggetto TIdMessage siano presenti ed essa avvenga 
correttamente.
Nel tuo caso, spezzerei il problema in due parti: prenderei il file di 
testo prodotto dal thread principale che contiene i messaggi da spedire 
(salvati con "SaveToFile", giusto?).
Poi farei un progettino di test con cui verificherei che il thread 
secondario crei il messaggio a partire da tale file di testo (con 
LoadFromFile, giusto?), che la spedizione del messaggio avvenga e questo 
sia poi leggibile dal client.
Se tutto va, significa che c'e' qualche problema di sincronismo tra i 
thread. Mi spiego. Se il principale non ha finito di scrivere tutti i 
dati tramite la SaveToFIle e il secondario se li va a leggere, e' molto 
probabile che il TIdMessage che si crea sia "sporco".
In questo caso dovresti utilizzare un oggetto TCriticalSection che ti 
permetta di sincronizzare in modo sicuro le operazioni di 
scrittura/lettura tra i thread.
Cosa ne dici?
Fammi sapere,
baba.

Giuseppe credo di aver risolto grazie ad un amico del forum
riksoft.com
. Invece di passare l'IdMessage per copia o di salvarlo su
un file con SaveToFile(), ho passato l'IdMessage tramite puntatore.
Siccome l'accesso simultaneo è solo in lettura, non ci sono problemi!
Adesso il mio problema è un altro. Siccome sto facendo un piccolo
server smtp, ho problemi ad inviare le email ad alcuni server i quali
richiedono autenticazione. Con alcuni server smtp ho questo problema:
viene visualizzato il messaggio di errore "Use
SMTP AUTH".
Le proprietà che ho settato sono:
IdSMTP1->ReadTimeout = 13000;
IdSMTP1->Port = 25;
IdSMTP1->Host = mailserver;
IdSMTP1->HeloName = mailserver;
Questo errore mi capita solo su alcuni server smtp. Come posso fare?
Immagino che bisognerebbe avere NomeUtente e Password per inviare a
questi siti... ma così non può funzionare il mio server smtp, perchè
non posso sapere che login usare...
Grazie mille in anticipo!!

 
Ma hai provato con il suggerimento che ti ho dato nella mia risposta di 
stamattina???
Ciao,
baba.

Baba, ho letto il tuo suggerimento e credo che tu abbia ragione... ma
come faccio a sapere quale login usare? scrivo letteralmente quello che
hai scritto tu? :-) funziona?

 hai scritto tu? :-) funziona?
Ascolta, io ho sempre usato server SMTP che non richiedono login.
Se tu hai necessita' di usarne uno che richiede autenticazione, bene, il 
tuo prvider di servizi SMTP *deve* averti fornito i parametri per la 
connessione.
Non so se hai presente, ad esempio, "libero". Quando ti registri ti 
danno l'indirizzo (o nome) del server POP3 (o IMAP) e del server SMTP
e, per il POP3 (o IMAP) ti forniscono login e password. Solitamente, 
ripeto, questo non e' richiesto per il SMTP.
Fai una prova: imposta, per la proprieta' "Host" dell'oggetto TIdSmtp il 
server "
smtp.libero.it
", commenta tutti i parametri relativi alle 
credenziali e all'autenticazione e fammi sapere se sei riuscito a spedire.
Ciao,
baba.

Questo lo so benissimo baba... forse non mi sono spiegato bene...
Sto realizzando un piccolo server smtp, il quale per inviare le email
deve contattare i server smtp dei destinatari delle email. Ok? Il
problema è che ci sono alcuni server smtp che non mi permettono di
inviare attraverso di essi senza autenticazione.
Ad esempio io ho un indirizzo con libero ed uno con tiscali. Quando
devo inviare una email al mio indirizzo tiscali, il mio server smtp si
collega a quello di tiscali ed invia senza alcun problema l'email al
mio indirizzo. Quando invece devo inviare a quello di libero, viene
visualizzato il messaggio di errore il quale mi dice che devo
autenticarmi.
Ora, nel caso in cui io debba contattare il mio stesso indirizzo non ci
sono problemi perchè dispongo ovviamente di Nome e Passord, ma siccome
questo programma vorrei che fosse un server smtp, non deve aver bisogno
di Nome e Password... Vorrei che funzionasse come se fosse un server
smtp. Se ad esempio io sono abbonato a tiscali e voglio inviare una
email col mio indirizzo tiscali ad un amico su libero, se la vedrà il
server smtp di tiscali a contattare quello di libero... e lo stesso
dovrebbe fare il programma... forse questo non è possibile perchè
dovrei far parte di una lista "trusted" ??

Ah dimenticavo di fornire questo strano particolare: provando ad
inviare un messaggio sul mio indirizzo 
libero.it
, anche se si verifica
il messaggio di errore auth il messaggio arriva a destinazione...

SI baba così funziona, lo so. Ti pregherei di leggere la mia nuova
discussione: Server Smtp
Li sto iniziando la discussione su come "creare" un server smtp
Ciao :-)

Credo di aver scoperto la causa principale del problema!
E' vero che alcuni server non permettono il relay, però mi sono
accorto che la maggior parte delle volte il problem era dovuto al fatto
che passavo l'IdMessage come puntatore agli altri threads...
Pensavamo di poter passare l'IdMessage per puntatore perchè tanto
l'accesso era solo in lettura... ma non è così! Infatti ogni
messaggio da inviare è QUASI uguale agli altri, cambia il
destinatario! Il codice che ho usato per impostare il destinatario è:
IdMessage1->Recipients->EMailAddresses =
frmMain->CheckListBoxInvio->Items->Strings[i];
Quindi, se mentre un certo thread sta inviando un'altro thread cambia
il destinatario, si genera l'errore! Perchè per quel destinatario non
è più valido IdSMTP1->HeloName settato prima...
Sembrerebbe proprio necessario il passaggio per valore... che però mi
ha causato i problemi che ho elencato prima su
http://www.riksoft.com/forum/topic.asp?TOPIC_ID=2149&whichpage=1
Come posso fare??

Non ho più avuto risposte... non avreste un'idea su come risolvere
questo problema? Spero di essere stato più chiaro stavolta nello
spiegare cosa dovrebbe fare la mia applicazione e quali sono i
problemi. Finora non sono proprio riuscito a risolvere. Adesso che ho
risolto il problema dei dati "sporchi" riguardo il destinatario, il
problema principale è l'efficienza: l'IdMessage resta bloccato, da una
TCriticalSection, durante l'invio del messaggio. Quindi ogni thread lo
tiene bloccato e non permette agli altri di procedere in modo
indipendente. La soluzione pensavo che fosse clonare l'IdMessage in
ogni thread, ma non ci sono riuscito.
Spero nel vostro aiuto! Grazie!

Se non ho cpito male stai cercando di fare come le mail in list
Grazie dell'attenzione.
A presto.
 
Massimiliano Monti
Cellulare: 0039 - 335 - 8477278
Mail: 
massimili...@matia.it
--- posted by geoForum on 
http://www.delphiedintorni.it

Jano78, si è una cosa simile

Che ne pensate dell'efficienza?? Usando il metodo della
TCriticalSection per bloccare assegnare il destinatario all'IdMessage,
si tiene bloccato l'IdMessage fino a quando l'invio è completato...
Credo che la strada migliore sarebbe quella di rendere ogni thread
indipendente dagli altri, ma non ci sono riuscito. Ho provato a fare
una cosa simile salvando su file con IdMessage->SaveToFile(), per poi
caricare in ogni thread il contenuto con IdMessage->LoadFromFile().
Purtroppo però questo metodo mi ha causato dei problemi con gli
allegati...
Avete qualche idea o suggerimento??
Grazie per l'attenzione!

Ti invio questo codice che ho scritto io e poi ti spiego come fare la
mail in list.
//La unit SendMail è freeware e si scarica comodamente da
http://www.scalabium.com/mapimail.htm
unit uInivaMail;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
  Dialogs, StdCtrls, Mapi, dxCntner, dxEditor, dxExEdtr, dxEdLib;
type
  TfInviaMail = class(TForm)
    Label1: TLabel;
    bInvia: TButton;
    eOggetto: TEdit;
    eIndirizzo: TEdit;
    Label2: TLabel;
    eBody: TdxMemo;
    Label3: TLabel;
    Label4: TLabel;
    eAllegato: TEdit;
    bAllega: TButton;
    OpenDialog1: TOpenDialog;
    cbAnteprima: TCheckBox;
    procedure bInviaClick(Sender: TObject);
    procedure OpenDialog1CanClose(Sender: TObject; var CanClose:
Boolean);
    procedure bAllegaClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  fInviaMail: TfInviaMail;
implementation
uses SendMail;
{$R *.dfm}
procedure TfInviaMail.bInviaClick(Sender: TObject);
begin
  with TMAPIMail.Create(Self) do
      try
        Subject := eOggetto.Text;
        Body := eBody.Text;
        Recipients.Add(eIndirizzo.Text);
        Attachments.Add(eAllegato.Text);
        if cbAnteprima.Checked then
        begin
          EditDialog := True; //Prima di mandare il messaggio apre
outlook express.
        end;
        if not cbAnteprima.Checked then
        begin
          EditDialog := False; //Manda il messaggio senza aprire
outlook express.
        end;
        Send
      finally
        Free
      end;
      eOggetto.Clear;
      eBody.Clear;
      eAllegato.Clear;
      eIndirizzo.Clear;
end;
procedure TfInviaMail.OpenDialog1CanClose(Sender: TObject;
  var CanClose: Boolean);
begin
  eAllegato.Text:=OpenDialog1.FileName;
end;
procedure TfInviaMail.bAllegaClick(Sender: TObject);
begin
  OpenDialog1.Execute;
end;
end.
Per fare la mail in list, se usi un database devi fare così
      qRubrica.First;
      while not qRubrica.Eof do
      begin
        with TMAPIMail.Create(Self) do
           try
             Subject:=eOggetto.Text;
             Body:=eBody.Text;
             Recipients.Add(qRubricaEMAIL.AsString);
             Attachments.Add(eAllegato.Text);
             EditDialog:=False;
             Send
           finally
             Free
           end;
        qRubrica.Next;
      end;
Così a me funziona.

Grazie per le preziose informazioni!
Ma tu riesci a far funzionare questo programma col multi-threading,
potendo cioè inviare le email attraverso più threads?? Perchè questo
è il mio problema. L'invio "normale" attraverso il thread principale
(cioè attraverso il Form) avviene perfettamente senza alcun problema.
I problemi quindi nascono solo quando vorrei "clonare" l'IdMessage su
ogni thread secondario, in modo da poter avere threads indipendenti ed
inviare velocemente attraverso molti threads...

Se tu usi la query di una rubrica sei praticamente a posto.
Nel senso che outlook express invierà lo stesso messaggio tante volte 
quanti sono i contatti presenti nella rubrica.
Non dovresti avere problemi.
Se mi telefoni però posso spiegartelo meglio.
Detto per iscritto è un casino per me.
Se non hai problemi a chiamarmi fallo anche ora.
Se vuoi ti invio un programmino che ti fa vedere quello che intendo.
Ma se no chiamami che ti spiego cosa fare.
Io abitualmente preferisco il telefono alle mail.
Il mio cellulare è 335 - 8477278


Non ho capito bene cosa sono i Multi-thread.
Comunque io con un form solo e un ciclo sulla query in cui ho la 
rubrica, può anche essere una tabella senza bisogno di una query,
io usol la query perchè ho un programma con molte più form e per inviare 
le mail ho creato un form apposito che mi consente a sconda di un flag 
su un check box (spero sia corretto il termine) di inviare o la mail 
singorlarmente in modo che uso la rubrica dei miei clienti oppure se ho 
necessità di inviare la stessa mail a più clienti senza ovviamente far 
vedere a chi lo inviata, uso un ciclo e il programma manda attraverso 
outlook express quante mail voglio.
Ho cercato per giorni una cosa del genere e finalmente l'ho trovata, non 
è di mia invenzione la unit che serve per inviare la mail con outlook 
express.
Mio è il programma che usa quella unit in un ciclo.
Tra l'altro, posso allegare quanti file voglio.
Nella mail invio i dati della mia azienda, il nome del mio cliente il 
testo del messaggio.
Bada che nel messaggio se uso la mail list cambia sempre il nome del 
cliente.
Resta uguale solo il testo del messaggio e l'allegato o allegati che 
invio.
Per cui problema risolto almeno per me.
Ripeto l'invito se mi chiami te lo spiego meglio.
