Problème avec Idmessage.MessageParts pièces jointes [Résolu]

cs_sagitarius 46 Messages postés samedi 26 août 2017Date d'inscription 4 avril 2018 Dernière intervention - 26 août 2017 à 20:14 - Dernière réponse : cs_sagitarius 46 Messages postés samedi 26 août 2017Date d'inscription 4 avril 2018 Dernière intervention
- 3 sept. 2017 à 21:37
Bonjour,
J'ai un problème pour afficher mes fichier joints des e-mails reçus.

j'arrive à afficher tous mes mails dans mon ListviewMail
(ListViewMail: TListView)

Lorsque je sélectionne une ligne dans mon TListView, j'aimerais afficher le nom du fichier joint et la taille de celui-ci dans mon label2.

voici mon code:
Uses IdAttachmentFile ;

procedure TForm1.ListViewMailSelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
var
  Index, j: Integer;
begin
for j := 0 to Pred(Idmessage.MessageParts.Count)-1 do <== (message d'erreur lorsque je ferme le programme)
  begin
  if Idmessage.MessageParts.Items[j] is TIdAttachmentFile then
      begin
      Item := ListView1.Items.Add;
      Item.Caption := Idmessage.MessageParts.Items[j].ContentType;
      Item.SubItems.Add(TIdAttachmentFile(Idmessage.MessageParts.Items[j]).ContentType);
  //TIdAttachmentFile(Idmessage.MessageParts.Items[j]).Filename;
      label2.Caption:= 'Pièce(s) Jointe(s):'+TIdAttachmentFile(Idmessage.MessageParts.Items[j]).Filename;
      end;
  end;
end;

En vous remercient d'avance
cordialement
Afficher la suite 

11 réponses

Répondre au sujet
Cirec 4217 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 3 avril 2018 Dernière intervention - 26 août 2017 à 23:31
0
Utile
3
Bonjour,

soit tu fais
for j := 0 to Pred(Idmessage.MessageParts.Count) do

ou
for j := 0 to Idmessage.MessageParts.Count-1 do

mais pas les deux
cs_sagitarius 46 Messages postés samedi 26 août 2017Date d'inscription 4 avril 2018 Dernière intervention - 27 août 2017 à 00:23
Bonjour Cirec,
Merci de m'avoir répondu,
Le problème est toujous le même, avec l'une ou l'autre des boucles For.
Je pense que le prolème vient que je n'arrie pas à afficher si il y à un fichier joint avec le mail dans mon ListViewMail (ListViewMail: TListView).
voici le code pour récupérer les mails:

if (IdPOP3.CheckMessages >= 1) then
begin
     for intIndex := 1 to IdPOP3.CheckMessages do
      begin
         Application.ProcessMessages;
         IdMessage.Clear;
         IdPOP3.RetrieveHeader(intIndex, IdMessage);
         itm := ListViewMail.Items.Add;
         ListViewMail.Checkboxes:= true;
         itm.SubItems.Add(IntToStr(Ord(IdMessage.Priority)));
         itm.SubItems.Add(IdMessage.From.Address);
         itm.SubItems.Add(IdMessage.Subject);
         itm.SubItems.Add(formatdatetime('dd/mm/yyyy à hh:mm',IdMessage.Date));
         itm.SubItems.Add(IntToStr(IdPOP3.RetrieveMsgSize(intIndex))+' Ko');
         itm.SubItems.Add(IdMessage. ?????  (le fichier joint) + (Taille fichier joint); = je sais pas faire

je me suis apparçu, que je n'ai pas le fichier " IdAttachmentFile.pas" (???),
mais, il faut que je le déclare dans Uses avec les composants
Uses
Windows, Messages, SysUtils, Variants,.....IdAttachmentFile;

Désolé de mes questions, mais je débute depuis peu
En vous remercient d'avance
Cordialement
Cirec 4217 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 3 avril 2018 Dernière intervention > cs_sagitarius 46 Messages postés samedi 26 août 2017Date d'inscription 4 avril 2018 Dernière intervention - 27 août 2017 à 12:52
re,
j'ai l'impression que tu cherches à utiliser un code pour Indy10 sous Indy9
pourquoi je dis ça ?
parce que
je me suis aperçu, que je n'ai pas le fichier " IdAttachmentFile.pas" (???)

IdAttachmentFile.pas appartient à Indy10

as-tu déjà vu ce tuto ?

Cordialement,
@+
cs_sagitarius 46 Messages postés samedi 26 août 2017Date d'inscription 4 avril 2018 Dernière intervention > Cirec 4217 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 3 avril 2018 Dernière intervention - 27 août 2017 à 13:34
Bonjour Cirec,
Merci pour la réponse,
oui, j'ai l'exemple du tuto en plusieurs partie que j'ai eu sur le net.
les liens de téléchargement ne fonctionnent plus, j'ai une page d'erreur.

IdAttachment , IdText, IdAttachmentFile, bien sont déclarés dans:
Uses windows.....
puis, j'ai eu ce code:

Comment récupérer les pièces jointes d'un mail ?
Pour cela, il vous faut deux composants : TIdPop3 et TIdMessage. Et il vous faut rajouter dans la clause uses de votre unité : IdAttachment et IdText.
Dans l'exemple ci-dessous, on va lister tous les mails et sauvegarder leur contenu sur le disque dur.
Var 
  i ,j : integer; 
begin 
  // On se connecte au compte mail si ce n'est pas déjà fait 
  if not IdPop3.connected then 
    idPop3.connect; 
  
  // On va boucler du premier au dernier message sur le compte 
  for i := 1 to idPop3.CheckMessages do 
  begin 
    // On récupère le message complet 
    idPop3.Retrieve(i,IdMessage); 
  
    // Si on a plusieurs parties dans le mail alors on a une pièce jointe  
    if IdMessage.MessageParts.Count > 0 then 
      for j := 0 to IdMessage.MessageParts.count -1 do 
      begin 
        // Est-ce une partie texte du mail ? 
        if IdMessage.MessageParts.Items[j] is TIdText then 
        begin 
          // A vous de traiter comme bon vous semble cette partie du mail  
          Showmessage(TIdText(IdMessage.MessageParts.Items *** [j]).Body.text); // Par exemple           
        end; 
  
        // Est-ce une pièce jointe ? 
         if IdMessage1.MessageParts.Items[j] is TIdAttachment then 
           With TIdAttachment(IdMessage1.MessageParts.Items[j]) do 
             if not FileExists('C:\Users\C:\Users\xxx\xxx\xxxx\' + FileName) then 
                 // On sauvegarde le fichier 
                 SaveTofile('C:\Users\xxx\xxx\xxxx\' + Filename); 
      end; // for j 
   end; // for i 
end;



*
      • Showmessage fonctionne bien, ... mais pas le reste

donc, après avoir passé toute la nuit, pour chercher une solution que je n'ai toujours pas ... lol
je n'ai vu que ce type de code sur le net
si, j'ai les fichiers , mais * .dcu*, pas les fichiers *.pas*

C:\Program Files\Borland\BDS\3.0\lib\Indy10\IdAttachment.dcu
C:\Program Files\Borland\Delphi2005\Setup Files\Install\program files\Borland\BDS\3.0\lib\Indy10\IdAttachment.dcu

C:\Program Files\Borland\BDS\3.0\lib\Indy10\IdText.dcu
C:\Program Files\Borland\Delphi2005\Setup Files\Install\program files\Borland\BDS\3.0\lib\Indy10\IdText.dcu

et j'ai bien la version INDY 10

quelle est la différenceente les deux INDY ????

merci d'avance, bonne journée
cordialement
Commenter la réponse de Cirec
Cirec 4217 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 3 avril 2018 Dernière intervention - 27 août 2017 à 17:13
0
Utile
Bon,
j'ai repris ton code, je l'ai testé et après de toutes petites modifications
il fonctionne parfaitement
  // On va boucler du premier au dernier message sur le compte
  for i := 1 to idPop31.CheckMessages do
  begin
    // on vide le contenu de IdMessage avant relever un nouveau message
    IdMessage1.Clear;
    // On récupère le message complet
    idPop31.Retrieve(i,IdMessage1);

    // Si on a plusieurs parties dans le mail alors on a une pièce jointe
    if IdMessage1.MessageParts.Count > 0 then
      for j := 0 to IdMessage1.MessageParts.count -1 do
      begin
        // Est-ce une partie texte du mail ?
        if IdMessage1.MessageParts.Items[j] is TIdText then
        begin
          // évite d'afficher un message vide
          if TIdText(IdMessage1.MessageParts.Items[j]).Body.text <> EmptyStr then
          // A vous de traiter comme bon vous semble cette partie du mail
            Showmessage(TIdText(IdMessage1.MessageParts.Items[j]).Body.text); // Par exemple
        end;

        // Est-ce une pièce jointe ?
         if IdMessage1.MessageParts.Items[j] is TIdAttachment then
           With TIdAttachment(IdMessage1.MessageParts.Items[j]) do
           begin
             with OpenLoadStream do try
               ShowmessageFmt('Fichier joint: %s de %d Octets', [ContentTypeName, Size]);
             finally
               CloseLoadStream;
             end;

             if not FileExists(ExtractFilePath(Application.ExeName) + FileName) then
                 // On sauvegarde le fichier dans le répetoire de l' application
                 SaveTofile(ExtractFilePath(Application.ExeName) + Filename);
           end;
      end; // for j
   end; // for i


ps: Pensez à utiliser la balise de code (Icône flèche vers la bas puis cliquer sur Delphi) pour poster vos exemples de code ça facilite grandement la lecture.
Merci
Commenter la réponse de Cirec
cs_sagitarius 46 Messages postés samedi 26 août 2017Date d'inscription 4 avril 2018 Dernière intervention - Modifié par Cirec le 27/08/2017 à 20:26
0
Utile
bonjour Cirec, merci pour ton aide !!!
je sais pas, ça ne fonctionne toujours pas, je deviens fou !!!!

lorsque je click sur la ligne du listview, j'ai toujours un message d'erreur à la ligne dessous;
if idMsg.MessageParts.Count > 0 then ***


raised exception "ErangeError with message range check error"
soit il se passe rien

Suite à ton message sur INDY, j'ai réussi à trouver sur le net des fichiers, et je les ai mis dans ma clause Uses :
IdMessage, IdAttachment, IdText, IdAttachmentFile,IdAttachmentMemory, IdTStrings, IdMailBox
lorsque je compile le projet, il y à bien les (*.dcu), avec les autres fichiers de mon projet.

voici ma procedure
procedure TForm1.ListViewMailClick(Sender: TObject);
var
 i, j, Index: Integer;
begin
If Not idPop31.Connected Then idPop31.Connect;
Screen.Cursor:=crHourGlass;
//POP3.Retrieve(ListViewMail.Selected.Index + 1 , idMsg);
if (idPOP31.CheckMessages >= 1) then
///for i := 1 to idPop31.CheckMessages do
//IdMessage1.Clear;
//idPop31.Retrieve(i, IdMessage1);
if (IdMessage1.MessageParts.Count > 0) then
begin
for i := 1 to idPop31.CheckMessages do
  begin
    IdMessage1.Clear;
    idPop31.Retrieve(i,IdMessage1);
      for j := 0 to IdMessage1.MessageParts.count -1 do
      begin
        if IdMessage1.MessageParts.Items[j] is TIdText then
        begin
          if TIdText(IdMessage1.MessageParts.Items[j]).Body.text <> EmptyStr then
            Showmessage(TIdText(IdMessage1.MessageParts.Items[j]).Body.text);
        end;
         if IdMessage1.MessageParts.Items[j] is TIdAttachment then
           With TIdAttachment(IdMessage1.MessageParts.Items[j]) do
           begin
             with OpenLoadStream do try
               ShowmessageFmt('Fichier joint: %s de %d Octets', [ContentTypeName, Size]);
             finally
               CloseLoadStream;
             end;
             if not FileExists(ExtractFilePath(Application.ExeName) + FileName) then
                 // On sauvegarde le fichier dans le répetoire de l' application
                 SaveTofile(ExtractFilePath(Application.ExeName) + Filename);
           end;
      end; // for j
   end; // for i
end;
Screen.Cursor:= crDefault;
Application.ProcessMessages;
End;


j'ai repris ton code, renomer mes composants pour plus de facilité, mais ça ne marche pas, je ne trouve pas mon erreur,
merci beaucoup d'avance et excuses-moi pour le dérangement,
cordialement
Commenter la réponse de cs_sagitarius
Cirec 4217 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 3 avril 2018 Dernière intervention - 27 août 2017 à 20:45
0
Utile
1
tu as mal placé cette condition
if (IdMessage1.MessageParts.Count > 0) then

procedure TForm1.ListViewMailClick(Sender: TObject);
var
  i, j, Index       : Integer;
begin
  if not idPop31.Connected then idPop31.Connect;
  Screen.Cursor := crHourGlass;
//POP3.Retrieve(ListViewMail.Selected.Index + 1 , idMsg);
  if (idPOP31.CheckMessages >= 1) then
///for i := 1 to idPop31.CheckMessages do
//IdMessage1.Clear;
//idPop31.Retrieve(i, IdMessage1);
// ******* Modification ****** IdMessage1 n'est pas encore valide ici
//if (IdMessage1.MessageParts.Count > 0) then // **** supprimé
  begin
    for i := 1 to idPop31.CheckMessages do
    begin
      IdMessage1.Clear;
      idPop31.Retrieve(i, IdMessage1);
      // ****** modification ************
      if (IdMessage1.MessageParts.Count > 0) then  // déplacé ici
        for j := 0 to IdMessage1.MessageParts.count - 1 do
        begin
          if IdMessage1.MessageParts.Items[j] is TIdText then
          begin
            if TIdText(IdMessage1.MessageParts.Items[j]).Body.text <> EmptyStr then
              Showmessage(TIdText(IdMessage1.MessageParts.Items[j]).Body.text);
          end;
          if IdMessage1.MessageParts.Items[j] is TIdAttachment then
            with TIdAttachment(IdMessage1.MessageParts.Items[j]) do
            begin
              with OpenLoadStream do
              try
                ShowmessageFmt('Fichier joint: %s de %d Octets', [ContentTypeName, Size]);
              finally
                CloseLoadStream;
              end;
              if not FileExists(ExtractFilePath(Application.ExeName) + FileName) then
                 // On sauvegarde le fichier dans le répetoire de l' application
                SaveTofile(ExtractFilePath(Application.ExeName) + Filename);
            end;
        end; // for j
    end; // for i
  end;
  Screen.Cursor := crDefault;
  Application.ProcessMessages;
end;


cette fois ça doit/devrait aussi fonctionner chez toi ;)

ensuite, merci d'avoir essayé d'utiliser la balise code mais encore faut-il placer le code entre les balises et non à la fin ^^
< code delphi> mettre le code ici </code>

Cordialement,
cs_sagitarius 46 Messages postés samedi 26 août 2017Date d'inscription 4 avril 2018 Dernière intervention - 27 août 2017 à 22:08
bonsoir,
merci pour tout , mais ça ne marche pas, à chaque fois que je clic sur le listview, j'ai le même message d'erreur .
Toujours avec cette même ligne,
si je laisse la ligne supprimée, il ne se passe rien, avec la ligne déplacé, je n'ai que le message d'erreur. (sur toutes les lignes cliquées)

ça ne proviendrait pas des fichiers (.pas) qui ne sont pas installée dans le bon répertoire ou bien compilé avec le programme ???.
j'ai 24 messaages dans ma boîte mail bbox, dont certains sont non lus et d'autre avec fichiers joints.
je vais continuer
je ne comprends pas, je vais continuer à chercher
merci beaucoup pour ton aide,
bonne soirée
Commenter la réponse de Cirec
cs_sagitarius 46 Messages postés samedi 26 août 2017Date d'inscription 4 avril 2018 Dernière intervention - 28 août 2017 à 02:01
0
Utile
bonsoir,
ça y est !!! ça marche !!!
voivi mon code
procedure TForm1.ListViewMailClick(Sender: TObject);
var
  i, j, Index: Integer;
  Item : TListItem;
  Attachment: TIdAttachment;
  FileName: String;
begin
Screen.Cursor:=crHourGlass;
if not IdPop31.connected then
    idPop31.connect;
IdMessage1.Clear;
Memo1.Clear;
for i := 1 to idPop31.CheckMessages do <= 25 messages ***
  begin
/// modification de idPOP31
idPop31.Retrieve(ListViewMail.Selected.Index + 1 , idMessage1);
StaticText1.Caption:= 'De : '+ IdMessage1.From.Address;
StaticText2.caption:= 'À : '+ idMessage1.Recipients.EMailAddresses;
StaticText3.Caption:= 'Object : '+ idMessage1.Subject;
StaticText4.Caption:= 'Date : '+ FormatDateTime('dd/mm/yyyy à hh:mm', idMessage1.Date);
  if IdMessage1.MessageParts.Count > 0 then
    for j := 0 To (idMessage1.MessageParts.Count) -1 do
      begin
        if TIdText(IdMessage1.MessageParts.Items[j]).Body.text <> EmptyStr then
          begin
            Showmessage(TIdText(IdMessage1.MessageParts.Items[j]).Body.text); **** <= le message s'affiche 25 fois (idPop31.CheckMessages = 25 )
puis, il s'affiche en HTML 25 fois aussi
            Memo1.Lines.Add(TIdText(IdMessage1.MessageParts.Items[j]).Body.text)
// texte +code HTML dans le memo autant de fois  que idPOP31.checkMessages
          end;
          if IdMessage1.MessageParts.Items[j] is TIdAttachment then
            with TIdAttachment(IdMessage1.MessageParts.Items[j]) do
            begin
              with OpenLoadStream do
              try
                ShowmessageFmt('Fichier joint: %s de %d Octets', [ContentTypeName, Size]); --- MIME , size aucune info
              finally
                CloseLoadStream;
              end;
              //if not FileExists(ExtractFilePath(Application.ExeName) + FileName) then
               /// SaveTofile(ExtractFilePath(Application.ExeName) + Filename);
            end;
      end; //fin de boucle j
  end; // fin de boucle i
  Screen.Cursor:= crDefault;
End;

idPop31.Disconnect; /// sur le OnClose de FormClose()


Mais par contre, j'ai la même "raise exception" erreur lorsque je sélectionne une ligne avec fichier joint ou que le programme ne peut pas lire le mail
Voilà, un grand merci pour ton aide
cordialement
Commenter la réponse de cs_sagitarius
Cirec 4217 Messages postés vendredi 23 juillet 2004Date d'inscriptionModérateurStatut 3 avril 2018 Dernière intervention - 3 sept. 2017 à 16:19
0
Utile
1
re,

en relisant tes messages je me rend compte d'une chose qui pourrait bien expliquer ton souci.

tu as dit:
j'ai les fichiers , mais * .dcu*, pas les fichiers *.pas* ...
Suite à ton message sur INDY, j'ai réussi à trouver sur le net des fichiers, et je les ai mis dans ma clause Uses :
IdMessage, IdAttachment, IdText, IdAttachmentFile,IdAttachmentMemory, IdTStrings, IdMailBox
lorsque je compile le projet, il y à bien les (*.dcu), avec les autres fichiers de mon projet.

1°) tant tu possèdes les *.dcu c'est suffisant pas besoin des *.pas
2°) les *.pas que tu as trouvé sur le net ne sont peut être pas de la bonne version !
3°) les *.dcu qui en résultent ne sont certainement pas correcte.

il te faut donc retirer les *.pas et les *.dcu associés de Indy, ceux que tu as toi même ajoutés, du répertoire de ton projet. (par mesure de sécurité tu fais une copie du projet au cas ou une erreur se glisserait par là ;) )

Maintenant tu peux reconstruire (Maj+F9 très important) le code
Si Indy est correctement installé et son répertoire recensé dans l'IDE ton programme devrait fonctionner ;)

Cordialement,

cs_sagitarius 46 Messages postés samedi 26 août 2017Date d'inscription 4 avril 2018 Dernière intervention - 3 sept. 2017 à 21:37
bonsoir Cirec;
Un grand merci pour ta réoponse,
ça y est !!!!!!, j'ai réussi !!!!!!!!
des sauvegardes, ??? j'en ai fais plein !!, car j'ai fais pleins d'essais avant.
j'en avais mare de ne pas trouver, alors, vu ton message au sujet de la version indy, j'ai ré-installé delphi, cet après-midi, puis, lors de l'installation, j'ai sélectionné INDY 9, et j'ai récréé mon programme , effectivement, avec indy10, ça ne fonctionnait pas bien, je viens juste de finir ce soir, avant 20 heures.

voici le code:
for j := 0 to Pred(IdMessage1.MessageParts.Count) do
      begin
         if (IdMessage1.MessageParts.Items[j] is TIdAttachment) then
            begin
               Liste := ListViewAttachments.Items.Add;
               Liste.ImageIndex:= 2;
               Liste.Caption := (TIdAttachment(IdMessage1.MessageParts.Items[j]).Filename);
               FileNameString := (TIdAttachment(IdMessage1.MessageParts.Items[j]).StoredPathName);
               AssignFile(Fichier, FileNameString);
               Reset(Fichier);
               Size := FileSize(Fichier);
               Liste.SubItems.Add(IntToStr((size)Div 1024) +' ko');
            end
         else
            begin
               if IdMessage1.MessageParts.Items[j] is TIdText then
               begin
                RichEdit1.Lines.Add((TIdText(IdMessage1.MessageParts.Items[j]).Body.Text));
               end;
            end;
      end;

voilà, j'ai enfin réussi, j'avais ce code mais avec indy 10, ça marchait pas.
seuls petits problèmes :
- Ne réaffiche pas les fichiers joints type (*.mp3), je vais faire un mail avec fichier (*.pdf)

- Dans mons RichEdit, les "é", "è", "@"' et autres , ne s'affichent pas correctement dans le RichEdit, j'ai des caractères "caractères spéciaux" qui s'affichent à la place.
- ainsi que l'images insérée dans mon e-mail de test
- Le code html qui s'affiche aussi, j'ai une fonction, qui marchait bien, mais avec le nouveau code que j'utile avec le RichEdit, ça marche pas , j'ai rien du tout dedans, voici la fonction:

function StripHTML(S: string): string;
var
  TagBegin, TagEnd, TagLength: integer;
begin
  TagBegin := Pos( '<', S);
  while (TagBegin > 0) do begin
    TagEnd := Pos('>', S);
    TagLength := TagEnd - TagBegin + 1;
    Delete(S, TagBegin, TagLength);
    TagBegin:= Pos( '<', S);
  end;
  Result := S;
End;


- Pour les fichiers lus et non lus, j'insert une image, mais ça le fait pas toujours très bien.
Voilà, je cherche des solutions à ces petits problèmes, et j'urais fifni
bien cordialement
bonne soirée et bon codding !!!!
En te renouvellent mes remerciements
Éric
Commenter la réponse de Cirec

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.