Open eml files from Delphi


Hello,

Almost every mail clients as Thunderbird can save and opem eml files.

I need to open such an Eml file in Delphi (only for display, to show the Html contents of the email).
I know that I can open the default email client and pass the file as parameter but I need one that doesn't depend on this.


Can you help me in this? Thank you
starhuAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

BlueVDCommented:
Hello,

The most simple way to open EML files is by using Indy (TIdMessage)
Here's a small example:
procedure TForm.OpenButtonClick(Sender: TObject);
var
IndyStringList: TStringList;
IndyStream: TMemoryStream;
I: Integer;
const
CRLF = #13#10;
begin
if not OpenDialog1.Execute then
Exit;
IndyStringList := TStringList.Create;
IndyStream := TMemoryStream.Create;
try
IndyStringList.LoadFromFile(OpenDialog1.FileName);
IndyStringList.Add(CRLF + '.' + CRLF);
IndyStringList.SaveToStream(IndyStream);
IndyStream.Position := 0;
IdMessage.Clear;
IdMessage.LoadFromStream(IndyStream);
Memo1.Clear;
Memo1.Lines.Assign(IdMessage.Headers);
Memo2.Clear;
Memo2.Lines.Add(IdMessage.From.Text);
Memo2.Lines.Add(IdMessage.Recipients.EMailAddresses);
Memo2.Lines.Add(IdMessage.Subject);
Memo2.Lines.Add(DateTimeToStr(IdMessage.Date));
Memo2.Lines.Add('');
for I := 0 to IdMessage.MessageParts.Count - 1 do
if IdMessage.MessageParts.Items[i] is TidText then

Memo2.Lines.Add(TidText(IdMessage.MessageParts.Items[i]).Body.Text);
finally
IndyStringList.Free;
IndyStream.Free;
end;
end;

Open in new window


A few notes on this example: you should check each line if it starts with a dot character (since they as seen as message terminators) and replace them with double dots or any other character. Also, MIME encoded emails (the ones with html body) have the body of the email as the first atachment (you can easily find out how to read the atachments in the indy doc).
Good luck!
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
starhuAuthor Commented:
Thank you.

I haven't tried it yet but I suppose this won't show the html emails correctly.

I mean that TMemo cannot show formatted text ,  so the characters in bold, colors, tables etc. won't be seen.

Isn't there a way to show it in a TWebBrowser, for example?
0
BlueVDCommented:
Here's a procedure to load html code into a TWebBrowser via Streams (faster and less dirty than saving and dealing with temporary files):
procedure LoadStream(WebBrowser: TWebBrowser; Stream: TStream);
var
  PersistStreamInit: IPersistStreamInit;
  StreamAdapter: IStream;
  MemoryStream: TMemoryStream;
begin
  WebBrowser.Navigate('about:blank');
  repeat
    Application.ProcessMessages;
    Sleep(0);
  until
    WebBrowser.ReadyState = READYSTATE_COMPLETE;
  if WebBrowser.Document.QueryInterface(IPersistStreamInit, PersistStreamInit) = S_OK then
  begin
    if PersistStreamInit.InitNew = S_OK then
    begin
      MemoryStream := TMemoryStream.Create;
      try
        MemoryStream.CopyFrom(Stream, 0);
        MemoryStream.Position := 0;
      except
        MemoryStream.Free;
        raise;
      end;
      StreamAdapter := TStreamAdapter.Create(MemoryStream, soOwned);
      PersistStreamInit.Load(StreamAdapter);
    end;
  end;
end;

Open in new window

0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

starhuAuthor Commented:
So you mean to combine your 2 examples?

first this
"IndyStringList := TStringList.Create;
IndyStream := TMemoryStream.Create;
try
IndyStringList.LoadFromFile(OpenDialog1.FileName);
IndyStringList.Add(CRLF + '.' + CRLF);
IndyStringList.SaveToStream(IndyStream);
IndyStream.Position := 0;
IdMessage.Clear;
IdMessage.LoadFromStream(IndyStream);"

and then give the stream as parameter to procedure LoadStream(WebBrowser: TWebBrowser; Stream: TStream); ?
0
rinfoCommented:
Have you considered using chilkat  com object.
You can have an example code here on this link
http://www.example-code.com/delphi/parse-eml.asp
0
BlueVDCommented:
After you load the message from the tstringlist, you check the MIME to see if it's an encoded html email. If so, check the first attachment (whitch is the html message) and if everything is ok, use the LoadStream procedure to load it in the twebbrower instance
you could also load plaintext with the LoadStream procedure (twebbrowser would just render it as plain text, thought you might have to encode special characters like <> using &raquo; etc codes...)
0
starhuAuthor Commented:
I will try it, thank you and I will let you know the result
0
mlmccCommented:
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.