Pour les 2 ou 3 personnes que ça va interesser vu le succès mondial de mes sources sur les mails avec Indy :(
90% des mails ne posent pas de problème ... Par contre, pour les autres 10% il faut s' accrocher:
- embedded images :
http://www.delphifr.com/codes/MAILS-AVEC-INDY10-CONTENTTYPE-CONTENTID-PARENTPART_45372.aspx
- des attachments qui contiennent un mail?!
etc ...
Bref, tous ces problèmes viennent souvent des mails qui sont envoyés par OutLook bien souvent à cause d' un forward d' un forward d' un forward...
Cette source vient dans l' esprit de celle-ci et est d' ailleurs reprise ici afin que celle-ci regroupe toutes les possibilités:
http://www.delphifr.com/codes/MAILS-AVEC-INDY-FAIRE-POURQUOI-LORSQUE-ANEXE-NE_44335.aspx
Le fait est que multipart/related MessageParts contiennent elles mêmes plusieurs parties de mails.
La fontion EXTRACT_MAIL_EMBEDDED_IN_TEXT(IdTexto: TIdText); permet de récupérer les parties contenues.
Je vous conseille aussi de regarder ma source:
MAILS AVEC INDY10, RÉSOLUTION DU PROBLÈME LORSQUE CHARSET = UTF-8
http://www.delphifr.com/codes/MAILS-AVEC-INDY10-RESOLUTION-PROBLEME-LORSQUE-CHARSET-UTF_43582
Source / Exemple :
Mensagem est de type TIdMessage
IndMsg est l' indice du message que l' on veut récupérer
IdPOP31 est un compo de type TIdPOP3 qui est sur la form FrmPreview
IdMsg est un compo de type TIdMessage qui est sur la form FrmPreview
procedure PREVIEW_MAIL;
var
TOT_MSG, M: Integer;
_Ok: Boolean;
begin
FrmPreview := TFrmPreview.Create(nil);
with FrmPreview do
begin
try
_Ok := false;
RETexto.Lines.Clear; // RichEdit qui contiendra le Body du mail au format Texte
REHtml.Lines.Clear; // RichEdit qui contiendra le Body du mail au format Html
LBAnexos.Items.Clear; // ListBox avec les noms des anexes
IdPOP31.Host := xxx;
IdPOP31.Port := xxx;
IdPOP31.Username := xxx;
IdPOP31.Password := xxx;
IdPOP31.Connect;
TOT_MSG := IdPOP31.CheckMessages; // Nombre de messages
MemUID.Lines.Clear; // memo avec les UID, qui est une valeur unique pour chaque message
IdPOP31.UIDL(MemUID.Lines, -1); // Récupérer les UID des messages ...
IdMsg.Clear;
IdPOP31.Retrieve(IndMsg, IdMsg);
IDMESSAGE_EXTRACT_INFO(IdMsg);
_Ok := true;
finally
if IdPOP31.Connected
then IdPOP31.Disconnect; // Fermer la conexion
if LBAnexos.Items.Count = 0
then LBAnexos.Items.Add('(Aucun anexe)');
if _Ok
then Caption := ' Preview mail'
else Caption := ' Error Preview mail !!!';
ShowModal;
end;
end;
FrmPreview.Release;
end;
end;
// Fonction qui permet de récupérer le Body et les anexes :
procedure TFrmPreview.IDMESSAGE_EXTRACT_INFO(Mensagem: TIdMessage);
var
_a: Integer;
DuplicatedBody: Boolean;
procedure EXTRACT_MAIL_EMBEDDED_IN_TEXT(IdTexto: TIdText);
var
aTmpStream: TMemoryStream;
aTmpIdMsg: TIdMessage;
begin
aTmpStream := TMemoryStream.Create;
aTmpIdMsg := TIdMessage.Create(self);
try
IdTexto.Body.SaveToStream(aTmpStream);
aTmpStream.Position := 0; // Revenir au début des données du Stream ...
aTmpIdMsg.Clear;
aTmpIdMsg.LoadFromStream(aTmpStream);
IDMESSAGE_EXTRACT_INFO(aTmpIdMsg);
finally
FreeAndNil(aTmpStream);
aTmpIdMsg.Free;
end;
end;
procedure OPEN_MAIL_EMBEDDED_IN_ATTACHMENT(Anexo: TIdAttachment);
var
aTmpStream: TMemoryStream;
aTmpIdMsg: TIdMessage;
begin
aTmpStream := TMemoryStream.Create;
aTmpIdMsg := TIdMessage.Create(self);
try
Anexo.SaveToStream(aTmpStream);
aTmpStream.Position := 0; // Revenir au début des données du Stream ...
aTmpIdMsg.Clear;
aTmpIdMsg.LoadFromStream(aTmpStream);
IDMESSAGE_EXTRACT_INFO(aTmpIdMsg); // On rapelle la fonction pou y retirer les infos ...
finally
FreeAndNil(aTmpStream);
aTmpIdMsg.Free;
end;
end;
begin
DuplicatedBody := False;
for _a := 0 to Mensagem.MessageParts.Count - 1 do
begin
if (Mensagem.MessageParts.Items[_a] is TIdText) // Texte ...
then begin
try
if Mensagem.Body = TIdText(Mensagem.MessageParts.Items[_a]).Body
then DuplicatedBody := True;
if TIdText(Mensagem.MessageParts.Items[_a]).ContentType = 'multipart/related' // il y aura des parties dans cette partie de mail !
then begin
EXTRACT_MAIL_EMBEDDED_IN_TEXT(TIdText(Mensagem.MessageParts.Items[_a]));
end
else
if TIdText(Mensagem.MessageParts.Items[_a]).ContentType = 'text/html'
then REHtml.Lines.AddStrings(TIdText(Mensagem.MessageParts.Items[_a]).Body) // text/html
else RETexto.Lines.AddStrings(TIdText(Mensagem.MessageParts.Items[_a]).Body); // text/plain e outros ...
except
end;
end
else begin
if TIdAttachment(Mensagem.MessageParts.Items[_a]).FileName <> '' // Pas de nom pour l' anexe!!!
then begin
LBAnexos.Items.Add('<' + TIdAttachment(Mensagem.MessageParts.Items[_a]).FileName + '>');
Activez cette ligne si vous voulez faire le download de l' anexe:
//
TIdAttachment(Mensagem.MessageParts.Items[_a]).SaveToFile('c:\_output\'
+ TIdAttachment(Mensagem.MessageParts.Items[_a]).FileName);
end
else
OPEN_MAIL_EMBEDDED_IN_ATTACHMENT(TIdAttachment(Mensagem.MessageParts.Items[_a]));
end;
end;
if Pos('This is a multi-part message in MIME format.', Mensagem.Body.Text) = 0
then
if not DuplicatedBody
then RETexto.Lines.AddStrings(Mensagem.Body);
end;
Conclusion :
Bem c' est pas très propre comme solution mais ça a le mérite de fonctionner.
Tout le monde sait que les compos de mails Indy auraient besoin d' être complètement refaits mais y a t-il quelqu'un d' assez courageux pour le faire?
Moi? Je ne suis pas un héros ... (clin d' oeil à Daniel Balavoine sniff)
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.