uRecvEmail.~pas
上传用户:yjb1804
上传日期:2021-01-30
资源大小:3105k
文件大小:21k
源码类别:

Email服务器

开发平台:

Delphi

  1. unit uRecvEmail;
  2. interface
  3. uses Windows, Messages, SysUtils, Variants, Classes, Forms,Mail2000,
  4.     uRulerMgr,IniFiles,uCommon;
  5. type
  6.   TOnErrorEvent=procedure (Sender:TObject;ErrMsg:string)of object;
  7.   TOnAttachFileRetrieveed=procedure (sender:TObject; FileName:string;FileStream:TMemoryStream;FCurNum,FTotal:Integer)of object;
  8.   TOnRetrieveed=procedure (sender:TObject;FCurNum,FTotal:Integer;UIDL:string)of object;
  9.   TOnGetUIDL=procedure (sender:TObject;UIDL:String;var Handle:Boolean) of object;
  10.   TOnFilter=procedure (Sender:TObject;Action:TRuleAction;EmailSubject:string;EmailFrom:string;var DeleteIt:Boolean;var Ignore:Boolean) of object;
  11.   TRecvEmail=class(TThread)
  12.   private
  13.     Fpop:TPOP2000;
  14.     FMsg:TMailMessage2000;
  15.     
  16.     FFilter:TRuleItems; //过滤规则
  17.     Fcont:TMemoryStream;
  18.     
  19.     FUIDL:String;
  20.     
  21.     FAction:TRuleAction;
  22.     FPop3LoginInfo:array of TPop3LoginInfo;
  23.     FOnComplete:TNotifyEvent;
  24.     FOnFilter:TOnFilter;
  25.     FOnGetUIDL:TOnGetUIDL;
  26.     FBeginWork,
  27.     FEndWork:TNotifyEvent;
  28.     
  29.     FHandle:Boolean;   //是否继续处理该邮件
  30.     FDeleteAfterRecv:Boolean;
  31.     FIsBusy:Boolean;
  32.     FFileName:string;
  33.     FFilterDelete:Boolean;
  34.     FFilterIgnore:Boolean;
  35.     FRecvEMailProgress,
  36.     FRecvMsgProgress:TProgressEvent;
  37.     FOnError:TOnErrorEvent;
  38.     FTotal1,FTotal2,
  39.     FCurrent1,FCurrent2:Integer;
  40.     FEMailTotal,
  41.     FEMailCur,
  42.     FAttchTotal,
  43.     FAttchCur:Integer;
  44.     
  45.     FErrorMsg:string;
  46.     FRetrieveAllMessage:Boolean;
  47.     FRetrieveMessageNum:Integer;
  48.     FOnRetrieveed:TOnRetrieveed;
  49.     FOnAttachFileRetrieveed:TOnAttachFileRetrieveed;
  50.     FBlackList,
  51.     FWhiteList:TStrings; //黑名单, 白名单
  52.     procedure SetFilter(const Value: TRuleItems);
  53.     procedure SetBlackList(const Value: TStrings);
  54.     procedure SetWhiteList(const Value: TStrings);
  55.   protected
  56.     procedure myEmailProgress(Sender: TObject; Total, Current: Integer);
  57.     procedure MyMsgProgress(Sender: TObject; Total, Current: Integer);
  58.     procedure DoEmailPrpgress;
  59.     procedure DoMsgProgress;
  60.     procedure DoOnError;
  61.     procedure DoOnRetrieveed;
  62.     procedure DoOnAttachFileRetrieveed;
  63.     procedure DoOnComplete;
  64.     procedure DoOnGetUIDL;
  65.     procedure DoFilter;
  66.     procedure DoBeginWork;
  67.     procedure DoEndWork;
  68.     procedure Decode(var Strm:TMemoryStream);
  69.     procedure Execute;override;
  70.     procedure ExtractFileContent(var Content:string);
  71.     function Filtered:Boolean;virtual;  //是否过滤该邮件
  72.     function FilteredByWhiteList:Boolean;
  73.     function FilteredByBlackList:Boolean;
  74.   public
  75.     constructor Create(APop3Server,AUserName,APassword:string);overload;
  76.     constructor Create(const S:array of string);overload;
  77.     destructor Destroy;override;
  78.     function EmailConut:Integer;
  79.     property OnRecvEMailProgress:TProgressEvent read FRecvEMailProgress write FRecvEMailProgress;
  80.     property OnRecvMsgProgress:TProgressEvent  read FRecvMsgProgress write FRecvMsgProgress;
  81.     property OnError:TOnErrorEvent  read FOnError write FOnError;
  82.     property  OnRetrieveed:TOnRetrieveed  read FOnRetrieveed write FOnRetrieveed;
  83.     property  OnAttachFileRetrieveed:TOnAttachFileRetrieveed read FOnAttachFileRetrieveed write FOnAttachFileRetrieveed;
  84.     property  OnComplete:TNotifyEvent  read FOnComplete write FOnComplete;
  85.     property  OnGetUIDL:TOnGetUIDL  read FOnGetUIDL write FOnGetUIDL;
  86.     property OnFilter:TOnFilter read FOnFilter write FOnFilter;
  87.     property  BeginWork:TNotifyEvent  read FBeginWork write FBeginWork;
  88.     property  EndWork:TNotifyEvent  read FEndWork write FEndWork;
  89.     
  90.     property  RetrieveAllMessage:Boolean  read FRetrieveAllMessage write FRetrieveAllMessage default False;
  91.     property RetrieveMessageNum:Integer  read FRetrieveMessageNum write FRetrieveMessageNum default 1;
  92.     property DeleteAfterRecv:Boolean  read FDeleteAfterRecv write FDeleteAfterRecv default False;
  93.     property  IsBusy:Boolean  read FIsBusy write FIsBusy default False;
  94.     property  Pop3:TPOP2000  read Fpop ;
  95.     property  Filter:TRuleItems read FFilter write SetFilter;
  96.     property  BlackList:TStrings  read FBlackList write SetBlackList;
  97.     property WhiteList:TStrings  read FWhiteList write SetWhiteList;
  98.   end;
  99.   
  100.   //加入新邮件到来时,使用UIDL接受邮件。
  101.   TRecvEmailExt=class(TRecvEmail)  
  102.   private
  103.      FNewEmailUIDLS:TStrings;
  104.     procedure SetNewEmailUIDLS(const Value: TStrings);
  105.   protected
  106.     procedure Execute;override;
  107.   public
  108.     constructor Create;
  109.     destructor Destroy;override;
  110.     property NewEmailUIDLS:TStrings read FNewEmailUIDLS write SetNewEmailUIDLS;
  111.   end;
  112. implementation
  113. uses  uEncrypt,RegExpr;
  114. { TRecvEmail }
  115. constructor TRecvEmail.Create(APop3Server,AUserName,APassword:string);
  116. begin
  117.   inherited Create(True);
  118.   FBlackList:=THashedStringList.Create;
  119.   FWhiteList:=THashedStringList.Create;
  120.   SetLength(FPop3LoginInfo,1);
  121.   FPop3LoginInfo[0].FPopServer:=APop3Server;
  122.   FPop3LoginInfo[0].FUserName:=AUserName;
  123.   FPop3LoginInfo[0].FPwd:=APassword;
  124.   FFilterDelete:=False;
  125.   FFilterIgnore:=False;
  126.   FFileName:='';
  127.   FFilter:=TRuleItems.Create;
  128.   Self.FreeOnTerminate:=True;
  129. end;
  130. constructor TRecvEmail.Create(const S: array of string);
  131. var
  132.   I:Integer;
  133.   List:TStrings;
  134. begin
  135.   inherited Create(True);
  136.   FBlackList:=THashedStringList.Create;
  137.   FWhiteList:=THashedStringList.Create;
  138.   SetLength(FPop3LoginInfo,Length(S));
  139.   List:=TStringList.Create;
  140.   try
  141.     for I:=0 to Length(S)-1 do
  142.     begin
  143.       Split(';',S[I],List);
  144.       FPop3LoginInfo[I].FPopServer:=List[0];
  145.       FPop3LoginInfo[I].FUserName:=List[1];
  146.       FPop3LoginInfo[I].FPwd:=List[2];
  147.     end;
  148.   finally
  149.     List.Free;
  150.   end;
  151.   FFilterDelete:=False;
  152.   FFilterIgnore:=False;
  153.   FFileName:='';
  154.   FFilter:=TRuleItems.Create;
  155.   Self.FreeOnTerminate:=True;
  156. end;
  157. procedure TRecvEmail.Decode(var Strm:TMemoryStream);
  158. var
  159.   MIME:TMIMECipher;
  160. begin
  161.   MIME:=TMIMECipher.Create;
  162.   try
  163.     MIME.DecodeStream(Strm);
  164.   finally
  165.     MIME.Free;
  166.   end;
  167. end;
  168. destructor TRecvEmail.Destroy;
  169. begin
  170.   FWhiteList.Free;
  171.   FBlackList.Free;
  172.   Filter.Free;
  173.   inherited;
  174. end;
  175. procedure TRecvEmail.DoBeginWork;
  176. begin
  177.   if Assigned(FBeginWork) then FBeginWork(self);
  178. end;
  179. procedure TRecvEmail.DoEmailPrpgress;
  180. begin
  181.   if Assigned(FRecvEMailProgress)  then FRecvEMailProgress(self,FTotal1,FCurrent1) ;
  182. end;
  183. procedure TRecvEmail.DoEndWork;
  184. begin
  185.   if Assigned(FEndWork) then FEndWork(self);
  186. end;
  187. procedure TRecvEmail.DoFilter;
  188. begin
  189.   if Assigned(FOnFilter) then FOnFilter(Self,FAction,Fpop.MailMessage.Subject,Fpop.MailMessage.FromAddress,FFilterDelete,FFilterIgnore);
  190. end;
  191. procedure TRecvEmail.DoMsgProgress;
  192. begin
  193.   if Assigned(FRecvMsgProgress)  then FRecvMsgProgress(self,FTotal2,FCurrent2) ;
  194. end;
  195. procedure TRecvEmail.DoOnAttachFileRetrieveed;
  196. begin
  197.   if Assigned(FOnAttachFileRetrieveed)  then FOnAttachFileRetrieveed(Self,FFileName,Fcont,FAttchCur,FAttchTotal);
  198. end;
  199. procedure TRecvEmail.DoOnComplete;
  200. begin
  201.   if Assigned(Foncomplete) then Foncomplete(Self);
  202. end;
  203. procedure TRecvEmail.DoOnError;
  204. begin
  205.   if Assigned(FonError)  then FonError(self,FErrorMsg) ;
  206. end;
  207. procedure TRecvEmail.DoOnGetUIDL;
  208. begin
  209.   FHandle:=False;
  210.   if Assigned(FOnGetUIDL) then FOnGetUIDL(Self,FUIDL,FHandle);
  211. end;
  212. procedure TRecvEmail.DoOnRetrieveed;
  213. begin
  214.   if Assigned(FOnRetrieveed) then FOnRetrieveed(Self,FEMailCur,FEMailTotal,FUIDL);
  215. end;
  216. function TRecvEmail.EmailConut: Integer;
  217. begin
  218.   //
  219.   Result:=0;
  220. end;
  221. procedure TRecvEmail.Execute;
  222. var
  223.   EMailCount,I,J:Integer;
  224.   
  225.   procedure  RecvAttch;
  226.   var
  227.     J:Integer;
  228.     S:string;
  229.   begin
  230.     if Fpop.MailMessage.AttachList.Count>1 then
  231.     begin
  232.       FAttchTotal:=Fpop.MailMessage.AttachList.Count;
  233.       if FAttchTotal>0 then
  234.       for J:=0 to FAttchTotal-1 do
  235.       begin
  236.         FAttchCur:=J+1;
  237.         S:=Fpop.MailMessage.AttachList[J].PartSource;
  238.         Fpop.MailMessage.Decode;
  239.         FFileName:=Fpop.MailMessage.AttachList[J].FileName;
  240.         Fcont:=TMemoryStream.Create;
  241.         try
  242.           Fcont.Position:=0;
  243.           Fpop.MailMessage.AttachList[J].Body.SaveToStream(Fcont);
  244.           Decode(Fcont);
  245.           if Self.Terminated then Exit;
  246.           Synchronize(DoOnAttachFileRetrieveed);
  247.           if Self.Terminated then Exit;
  248.         finally
  249.           Fcont.Free;
  250.         end;
  251.       end;
  252.     end;
  253.   end;
  254.   procedure ErrorNotify(Err:string);
  255.   begin
  256.     FErrorMsg:=Err;
  257.     if not Fpop.Quit then Fpop.Abort;
  258.     Synchronize(DoOnError);
  259.   end;
  260. begin
  261.   IsBusy:=True;
  262.   Fpop:=TPOP2000.Create(nil);
  263.   FMsg:=TMailMessage2000.Create(nil);
  264.   Fpop.MailMessage:=FMsg;
  265.   Fpop.OnProgress:=myEmailProgress;
  266.   Fpop.MailMessage.OnProgress:=MyMsgProgress;
  267.   Fpop.DeleteOnRetrieve:=DeleteAfterRecv;
  268.   Fpop.TimeOut:=65;
  269.   Synchronize(DoBeginWork);
  270.   try
  271.     for J:=0 to Length(FPop3LoginInfo)-1 do
  272.     begin
  273.       Fpop.Host:=FPop3LoginInfo[J].FPopServer;
  274.       Fpop.UserName:=FPop3LoginInfo[J].FUserName;
  275.       Fpop.Password:=FPop3LoginInfo[J].FPwd;
  276.       try
  277.         try
  278.           if not Fpop.Connect then
  279.             ErrorNotify('无法连接pop3服务器')
  280.           else
  281.           begin
  282.             if Self.Terminated then Exit;
  283.             if not Fpop.Login  then
  284.               ErrorNotify('无法登录pop3服务器')
  285.             else
  286.             begin
  287.               EMailCount:=Fpop.SessionMessageCount;
  288.               if EMailCount <1 then
  289.               begin
  290.                 FErrorMsg:='邮箱中没有邮件';
  291.                 Synchronize(DoOnError);
  292.                 Exit;
  293.               end;
  294.               if Self.Terminated then Exit;
  295.               FEMailTotal:=EMailCount;
  296.               if RetrieveAllMessage then
  297.               begin
  298.                  for I:=1 to EMailCount do
  299.                  begin
  300.                     FEMailCur:=I;
  301.                     
  302.                     if FilteredByWhiteList then continue;
  303.                     if FilteredByBlackList then continue;
  304.                     FFilterDelete:=False;
  305.                     FFilterIgnore:=False;
  306.                     Fpop.MailMessage.AttachList.Clear;
  307.                     
  308.                     FUIDL:=Fpop.GetUIDL(I);
  309.                     Synchronize(DoOnGetUIDL);
  310.                     if FHandle then Continue;
  311.                     if not Fpop.RetrieveMessage(I)then
  312.                     begin
  313.                       FErrorMsg:=Format('无法接收第%D封邮件 ',[I]);
  314.                       if not Fpop.Quit then Fpop.Abort;
  315.                       if Self.Terminated then Exit;
  316.                       Synchronize(DoOnError);
  317.                       Exit;
  318.                     end
  319.                     else
  320.                     begin
  321.                       Fpop.MailMessage.FindParts;
  322.                       if Filtered then  Synchronize(DoFilter); //如果匹配到过滤规则,则执行动作。
  323.                       if FFilterDelete then  // 执行"删除"动作
  324.                       begin
  325.                         Fpop.DeleteMessage(I);
  326.                         Continue;
  327.                       end;
  328.                       if FFilterIgnore then Continue; //执行 "忽略,不处理" 动作
  329.                       Synchronize(DoOnRetrieveed);
  330.                       if Self.Terminated then Exit;
  331.                       RecvAttch;
  332.                     end;
  333.                     Fpop.MailMessage.AttachList.Clear;   //added by wp 2009-12-31
  334.                     if Self.Terminated then Exit;
  335.                  end;
  336.               end
  337.               else
  338.               begin
  339.                 FEMailCur:=1;
  340.                 FUIDL:=Fpop.GetUIDL(RetrieveMessageNum);
  341.                 if FHandle then Exit;
  342.                 if not Fpop.RetrieveMessage(RetrieveMessageNum)then
  343.                   ErrorNotify(Format('无法接收第%D封邮件',[RetrieveMessageNum]))
  344.                 else
  345.                 begin
  346.                   Fpop.MailMessage.FindParts;
  347.                   if Filtered then Synchronize(DoFilter);   
  348.                   if FFilterDelete then
  349.                   begin
  350.                     Fpop.DeleteMessage(RetrieveMessageNum);
  351.                     Continue;
  352.                   end;
  353.                   if FFilterIgnore then Continue;
  354.                   Synchronize(DoOnRetrieveed);
  355.                   if Self.Terminated then Exit;
  356.                   RecvAttch;
  357.                 end;
  358.                 Fpop.MailMessage.AttachList.Clear;
  359.                 if Self.Terminated then Exit;
  360.               end;
  361.             end;
  362.           end;
  363.         except
  364.           on E:Exception do  ErrorNotify(e.Message);
  365.         end;
  366.       finally
  367.         FMsg.Free;
  368.         Fpop.Free;
  369.         IsBusy:=False;
  370.       end;
  371.     end;
  372.     Synchronize(DoOnComplete);
  373.   finally
  374.     IsBusy:=False;
  375.     Synchronize(DoEndWork);
  376.   end;
  377. end;
  378. procedure TRecvEmail.ExtractFileContent(var Content: string);
  379. var
  380.   I:Integer;
  381.   lst:TStringList;
  382. begin
  383.   I:=Pos(#$D#$A#$D#$A,Content);
  384.   if I=0 then Exit;
  385.   Delete(Content,1,I);
  386.   lst:=TStringList.Create;
  387.   try
  388.     lst.DelimitedText:='#$D#$A';
  389.     lst.Text:=Content;
  390.     Content:='';
  391.     for I:=0  to lst.Count-1 do
  392.       Content:=Content+lst.Strings[I]
  393.   finally
  394.     lst.Free;
  395.   end;
  396. end;
  397. function TRecvEmail.Filtered: Boolean;
  398. var
  399.   I,J:Integer;
  400.   reg:TRegExpr;
  401.   
  402.   function FilterPart(Str:string):Boolean;
  403.   begin
  404.     Result:=False;
  405.     case FFilter.Items[I].Rows[J].Compare of
  406.       rcContains:
  407.         if Pos(FFilter.Items[I].Rows[J].Text,Str)>0 then
  408.           Result:=True;
  409.       rcEquals:
  410.         if CompareStr(FFilter.Items[I].Rows[J].Text,Str)=0 then
  411.           Result:=True;
  412.       rcEmpty:
  413.           Result:=Str='';
  414.       rcRegExpr:
  415.       begin
  416.         try
  417.           reg.Expression:=FFilter.Items[I].Rows[J].Text;
  418.           Result:= reg.Exec(Str);
  419.         except
  420.           //raise Exception.Create('正则表达式错误,无法匹配!');
  421.         end;
  422.       end;
  423.     else ;
  424.     end;
  425.   end;
  426.   
  427. begin
  428.   Result:=False;
  429.   if FFilter=nil then Exit;
  430.   
  431.   reg:=TRegExpr.Create;
  432.   try
  433.     for I:=0 to FFilter.Count-1 do
  434.     begin
  435.       if not FFilter.Items[I].Enabled then  Continue; //该规则未被启用
  436.       if not FFilter.Items[I].AllAccount then
  437.         if CompareText(FFilter.Items[I].Account, Fpop.UserName)<>0 then Continue;//该规则只应用于本账号
  438.       FAction:=FFilter.Items[I].RulerAction;
  439.       for J:=0 to  FFilter.Items[I].Rows.Count-1 do   //该规则应用于所有账号
  440.       begin
  441.         if (not VarIsOrdinal(FFilter.Items[I].Rows[J].Area)) or (not VarIsOrdinal(FFilter.Items[I].Rows[J].Compare)) then Continue;
  442.         if (FFilter.Items[I].Rows[J].Compare<>rcEquals) and (FFilter.Items[I].Rows[J].Text='') then Continue;
  443.         case FFilter.Items[I].Rows[J].Area of
  444.           raSubject:
  445.           begin
  446.             Result:=FilterPart(Fpop.MailMessage.Subject);
  447.             if result then break;
  448.           end;
  449.           raTo:
  450.           begin
  451.             Result:=FilterPart(Fpop.MailMessage.ReceiptAddress);
  452.             if result then break;
  453.           end;
  454.           raFrom:
  455.           begin
  456.             Result:=FilterPart(Fpop.MailMessage.FromAddress);
  457.             if result then break;
  458.           end;
  459.           raCC:
  460.           begin
  461.             Result:=FilterPart(Fpop.MailMessage.CcList.AllAddresses);
  462.             if result then break;
  463.           end;
  464.           raCB:
  465.           begin
  466.             Result:=FilterPart(Fpop.MailMessage.BCcList.AllAddresses);
  467.             if result then break;
  468.           end;
  469.           raBody:
  470.           begin
  471.             Result:=FilterPart(Fpop.MailMessage.TextHtml.Text);
  472.             if result then break;
  473.           end;
  474.           raHeader:
  475.           begin
  476.             Result:=FilterPart(Fpop.MailMessage.Header.Text);
  477.             if result then break;
  478.           end;
  479.         else ;
  480.         end;
  481.       end
  482.     end;
  483.   finally
  484.     reg.Free;
  485.   end;
  486. end;
  487. function TRecvEmail.FilteredByBlackList: Boolean; //是否被白名单过滤掉了
  488. begin
  489.   result:=False;
  490.   if BlackList.Count>0 then
  491.   begin
  492.     Fpop.RetrieveHeader(FEMailCur,20);
  493.     if BlackList.IndexOf(UpperCase(Fpop.UserName))>-1 then Result:=True;  //在黑名单之内,不接收
  494.   end;
  495. end;
  496. function TRecvEmail.FilteredByWhiteList: Boolean;
  497. begin
  498.   result:=WhiteList.Count>0 ;
  499.   if result then
  500.   begin
  501.     Fpop.RetrieveHeader(FEMailCur,20);
  502.     if WhiteList.IndexOf(UpperCase(Fpop.UserName))<>-1 then Result:=False;  //在白名单之内
  503.   end
  504. end;
  505. procedure TRecvEmail.myEmailProgress(Sender: TObject; Total,
  506.   Current: Integer);
  507. begin
  508.   FTotal1:=Total;
  509.   FCurrent1:=Current;
  510.   Synchronize(DoEmailPrpgress);
  511. end;
  512. procedure TRecvEmail.MyMsgProgress(Sender: TObject; Total,
  513.   Current: Integer);
  514. begin
  515.   FTotal2:=Total;
  516.   FCurrent2:=Current;
  517.   Synchronize(DoMsgProgress);
  518. end;
  519. procedure TRecvEmail.SetBlackList(const Value: TStrings);
  520. begin
  521.   FBlackList.Assign(Value);
  522. end;
  523. procedure TRecvEmail.SetFilter(const Value: TRuleItems);
  524. begin
  525.   if FFilter<>Value then
  526.     FFilter.Assign(Value);
  527. end;
  528. procedure TRecvEmail.SetWhiteList(const Value: TStrings);
  529. begin
  530.   FWhiteList.Assign(Value);
  531. end;
  532. { TRecvEmailExt }
  533. constructor TRecvEmailExt.Create;
  534. begin
  535.   inherited Create('','','');
  536.   FNewEmailUIDLS:=TStringList.Create;
  537. end;
  538. destructor TRecvEmailExt.Destroy;
  539. begin
  540.   FNewEmailUIDLS.Free;
  541.   inherited;
  542. end;
  543. procedure TRecvEmailExt.Execute;
  544. var
  545.  J:Integer;
  546.   
  547.   procedure  RecvAttch;
  548.   var
  549.     J:Integer;
  550.     S:string;
  551.   begin
  552.     if Fpop.MailMessage.AttachList.Count<>0 then
  553.     begin
  554.       FAttchTotal:=Fpop.MailMessage.AttachList.Count;
  555.       for J:=0 to FAttchTotal-1 do
  556.       begin
  557.         FAttchCur:=J+1;
  558.         S:=Fpop.MailMessage.AttachList[J].PartSource;
  559.         Fpop.MailMessage.Decode;
  560.         FFileName:=Fpop.MailMessage.AttachList[J].FileName;
  561.         Fcont:=TMemoryStream.Create;
  562.         try
  563.           Fcont.Position:=0;
  564.           Fpop.MailMessage.AttachList[J].Body.SaveToStream(Fcont);
  565.           Decode(Fcont);
  566.           if Self.Terminated then Exit;
  567.           Synchronize(DoOnAttachFileRetrieveed);
  568.           if Self.Terminated then Exit;
  569.         finally
  570.           Fcont.Free;
  571.         end;
  572.       end;
  573.     end;
  574.   end;
  575.   procedure ErrorNotify(Err:string);
  576.   begin
  577.     FErrorMsg:=Err;
  578.     if not Fpop.Quit then Fpop.Abort;
  579.     Synchronize(DoOnError);
  580.   end;
  581. begin
  582.   IsBusy:=True;
  583.   Fpop:=TPOP2000.Create(nil);
  584.   FMsg:=TMailMessage2000.Create(nil);
  585.   Fpop.MailMessage:=FMsg;
  586.   Fpop.OnProgress:=myEmailProgress;
  587.   Fpop.MailMessage.OnProgress:=MyMsgProgress;
  588.   Fpop.DeleteOnRetrieve:=DeleteAfterRecv;
  589.   Fpop.TimeOut:=65;
  590.   Synchronize(DoBeginWork);
  591.   try
  592.     FEMailTotal:=NewEmailUIDLS.Count;
  593.     for J:=0 to FEMailTotal -1 do
  594.     begin
  595.       if not Fpop.Quit then Fpop.Abort;
  596.       Fpop.Host:=PPop3LoginInfo(NewEmailUIDLS.Objects[J]).FPopServer;
  597.       Fpop.UserName:=PPop3LoginInfo(NewEmailUIDLS.Objects[J]).FUserName;
  598.       Fpop.Password:=PPop3LoginInfo(NewEmailUIDLS.Objects[J]).FPwd;
  599.       Fpop.Port:=PPop3LoginInfo(NewEmailUIDLS.Objects[J]).FPort;
  600.       Dispose(PPop3LoginInfo(NewEmailUIDLS.Objects[J]));    //Free Memory ,these memory allocate in TCheckEmailThread class.
  601.       try
  602.         try
  603.           if not Fpop.Connect then
  604.             ErrorNotify('无法连接pop3服务器')
  605.           else
  606.           begin
  607.             if Self.Terminated then Exit;
  608.             if not Fpop.Login  then
  609.               ErrorNotify('无法登录pop3服务器')
  610.             else
  611.             begin
  612.               if Self.Terminated then Exit;
  613.               if FilteredByWhiteList then continue;
  614.               if FilteredByBlackList then continue;
  615.               FFilterDelete:=False;
  616.               FFilterIgnore:=False;
  617.               Fpop.MailMessage.AttachList.Clear;
  618.               FEMailCur:=J;
  619.               if not Fpop.RetrieveMessage(StrToInt(PartStr(NewEmailUIDLS[J],#32)))then //////////////////////////
  620.               begin
  621.                 FErrorMsg:=Format('无法接收第%D封邮件 ',[J]);
  622.                 if not Fpop.Quit then Fpop.Abort;
  623.                 if Self.Terminated then Exit;
  624.                 Synchronize(DoOnError);
  625.                 Exit;
  626.               end
  627.               else
  628.               begin
  629.                 Fpop.MailMessage.FindParts;
  630.                 if Filtered then  Synchronize(DoFilter); //如果匹配到过滤规则,则执行动作。
  631.                 if FFilterDelete then  // 执行"删除"动作
  632.                 begin
  633.                   Fpop.DeleteMessage(StrToInt(PartStr(NewEmailUIDLS[J],#32)));
  634.                   Continue;
  635.                 end;
  636.                 if FFilterIgnore then Continue; //执行 "忽略,不处理" 动作
  637.                 Synchronize(DoOnRetrieveed);
  638.                 if Self.Terminated then Exit;
  639.                 RecvAttch;
  640.               end;
  641.               if Self.Terminated then Exit;
  642.             end;
  643.           end;;
  644.         except
  645.           on E:Exception do  ErrorNotify(e.Message);
  646.         end;
  647.       finally
  648.         if  FMsg<>nil then
  649.         begin
  650.           FMsg.Free;
  651.           FMsg:=nil;
  652.         end;
  653.         Fpop.Free;
  654.       end;
  655.     end;
  656.     Synchronize(DoOnComplete);
  657.   finally
  658.     IsBusy:=False;
  659.     Synchronize(DoEndWork);
  660.   end;
  661. end;
  662. procedure TRecvEmailExt.SetNewEmailUIDLS(const Value: TStrings);
  663. begin
  664.   if FNewEmailUIDLS<>Value then
  665.     FNewEmailUIDLS.Assign(Value);
  666. end;
  667. end.