title: Sending emails with Indy via a separate thread
body: <p>I've asked previous questions about sending emails with attachments with Indy via GMail and I'm pleased to say that basic code works properly. I have noticed, however, that sending attachments takes a few minutes and in that time, the program freezes (even though I added a TIdAntiFreeze component to the program). I thought that it would be a good idea to have the email sent by a separate thread, thus allowing the program to be responsive.</p>
  
  <p>I have been unable to find code on the web which shows how to send email from a thread and so I had to write my own code which only partially works.</p>
  
  <p>I removed the SMTP component from the form which sends email; instead I save the email component's data to disk (with the TIdMessage.SaveToFile method) and then create a non-modal dialog, which creates a thread which instantiates the needed components and sends the email. I would like to create event handlers for the SMTP and IdMessage components but don't know how to do this at runtime - the thread code can't access any form methods.</p>
  
  <p>Although I am showing my code, I would prefer to see something which works properly.</p>
  
  <pre><code>unit Manage77c;
  
  interface
  
  uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, SizeGrip, ManageForms, ExtCtrls, StdCtrls, IdBaseComponent,
   IdComponent, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase,
   IdMessageClient, IdSMTPBase, IdSMTP, IdIOHandler, IdIOHandlerSocket, IdSSL,
   IdIOHandlerStack, IdMessage, IdSSLOpenSSL;
  
  type
   TSendAMail = class(TForm)
   mem: TMemo;
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
  public
   constructor create (const s: string);
  end;
  
  implementation
  
  {$R *.dfm}
  
  var
   ahost, apassword, ausername, curstatus, fn: string;
   caller: thandle;
  
  function DoEmail (p: pointer): longint; stdcall;
  var
   ssl: TIdSSLIOHandlerSocketOpenSSL;
   email: TIdMessage;
  
  begin
   caller:= THandle (p);
   email:= TIdMessage.create;
   with email do
    begin
     loadfromfile (fn);
     // OnInitializeISO:= ??
    end;
  
   deletefile (fn); 
   ssl:= TIdSSLIOHandlerSocketOpenSSL.create;
   ssl.SSLOptions.SSLVersions:= [sslvTLSv1];
  
   with TIdSMTP.create do  
    try
     //OnStatus:= ??
     iohandler:= ssl;
     host:= ahost;
     password:= apassword;
     username:= ausername;
     port:= 587;
     useTLS:= utUseExplicitTLS;
     Connect;
     try
      Send (email);
     except
      on E:Exception do;
     end;
    finally
     Disconnect;
     free
    end;
   ssl.free;
   email.free;
   result:= 0
  end;
  
  constructor TSendAMail.Create (const s: string);
  var
   empty: boolean;
   thrid: dword;
  
  begin
   inherited create (nil);
   fn:= s;
   repeat
    with dm.qGetSMTP do  // this part gets the SMTP definitions from the database
     begin
      open;
      aHost:= fieldbyname ('smtphost').asstring;
      ausername:= fieldbyname ('smtpuser').asstring;
      apassword:= fieldbyname ('smtppass').asstring;
      close
     end;
  
    empty:= (ahost = '') or (ausername = '') or (apassword = '');
    if empty then
     with TGetSMTP.create (nil) do   // manage77a
      try
       execute
      finally
       free
      end;
   until not empty;
   CreateThread (nil, 0, @DoEmail, pointer (self.handle), 0, thrid);
   close
  end;
  
  procedure TSendAMail.FormClose(Sender: TObject; var Action: TCloseAction);
  begin
   action:= caFree
  end;
  
  end.
  </code></pre>