J'ai déjà posé des questions sur l'envoi d'emails avec des pièces jointes avec Indy via GMail et je suis heureux de dire que le code de base fonctionne correctement. J'ai remarqué, cependant, que l'envoi de pièces jointes prend quelques minutes et dans ce temps, le programme se fige (même si j'ai ajouté un composant TIdAntiFreeze au programme). J'ai pensé que ce serait une bonne idée de faire envoyer l'email par un thread séparé, permettant ainsi au programme d'être réactif.Envoyer des emails avec Indy via un fil séparé
J'ai été incapable de trouver du code sur le web qui montre comment envoyer des emails depuis un thread et j'ai donc dû écrire mon propre code qui ne fonctionne que partiellement. J'ai supprimé le composant SMTP du formulaire qui envoie le courrier électronique;
à la place, je sauvegarde les données du composant de messagerie sur le disque (avec la méthode TIdMessage.SaveToFile), puis crée une boîte de dialogue non modale, qui crée un thread qui instancie les composants nécessaires et envoie le courrier électronique. Je voudrais créer des gestionnaires d'événements pour les composants SMTP et IdMessage mais je ne sais pas comment faire cela au moment de l'exécution - le code thread ne peut accéder à aucune méthode de formulaire. Bien que je montre mon code, je préférerais voir quelque chose qui fonctionne correctement.
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.
Mettez votre formulaire sur un [ ' « TDataModule »'] (http://docwiki.embarcadero.com/RADStudio/XE3/fr/Using_Data_Modules) à la place. Il n'y a pas d'interaction avec l'interface graphique de toute façon. –