不用安全认证只用如下即可实现:
if nmsmtp1.Connected then
  nmsmtp1.Disconnect
  else
  begin
    nmsmtp1.Host:=trim(DataModule1.ADOQuery42.fieldbyname('kty').asstring);
    nmsmtp1.UserID:=trim(DataModule1.ADOQuery42.fieldbyname('jsy').asstring);
    nmsmtp1.
    try
      nmsmtp1.Connect;
      statusbar1.panels[0].text:='Á¬½ÓÓʼþ·þÎñÆ÷³É¹¦£¡';
    except
      statusbar1.panels[0].text:='Á¬½ÓÓʼþ·þÎñÆ÷ʧ°Ü!Çë¼ì²éÄãµÄÓʼþ·þÎñÆ÷ÊÇ·ñÉèÖÃÕýÈ·,»òÍøÂçÊÇ·ñÒÑÁ¬Í¨.';
    end;
  end;   //连接.if nmsmtp1.Connected then
  begin
    NMSMTP1.EncodeType:= uuMime;
    NMSMTP1.PostMessage.FromAddress:=trim(DataModule1.ADOQuery42.fieldbyname('jsy').asstring);
    NMSMTP1.PostMessage.ToAddress.Text:=edit4.text;
    NMSMTP1.PostMessage.Body.Text:=Memo1.Text;
    NMSMTP1.PostMessage.Attachments.Text:=ListBox2.Items.Text;
    NMSMTP1.PostMessage.Subject:=Edit5.Text;
    NMSMTP1.SendMail;
  end
  else
    statusbar1.panels[0].text:='¾¯¸æ£ºµ±Ç°Ã»Á¬ÉÏÈκηþÎñÆ÷!';
   //发送.如要全安认证又如何实现呢? nmsmtp又没有nmpop的password属性.

解决方案 »

  1.   

    不用安全认证只用如下即可实现:
    if nmsmtp1.Connected then
      nmsmtp1.Disconnect
      else
      begin
        nmsmtp1.Host:=trim(DataModule1.ADOQuery42.fieldbyname('kty').asstring);
        nmsmtp1.UserID:=trim(DataModule1.ADOQuery42.fieldbyname('jsy').asstring);
        try
          nmsmtp1.Connect;
          statusbar1.panels[0].text:='连接成功.;';
        except
          statusbar1.panels[0].text:='连接失败;¨.';
        end;
      end;   //连接.if nmsmtp1.Connected then
      begin
        NMSMTP1.EncodeType:= uuMime;
        NMSMTP1.PostMessage.FromAddress:=trim(DataModule1.ADOQuery42.fieldbyname('jsy').asstring);
        NMSMTP1.PostMessage.ToAddress.Text:=edit4.text;
        NMSMTP1.PostMessage.Body.Text:=Memo1.Text;
        NMSMTP1.PostMessage.Attachments.Text:=ListBox2.Items.Text;
        NMSMTP1.PostMessage.Subject:=Edit5.Text;
        NMSMTP1.SendMail;
      end
      else
        statusbar1.panels[0].text:='send fail!';
       //发送.如要全安认证又如何实现呢? nmsmtp又没有nmpop的password属性.
    sorry.上面写错了.
      

  2.   

    电子邮件发送过程都必须遵循SMTP协议。客户端和服务器通过该协议进行通信,由客户端发送出电子邮件,SMTP服务器通过网络上其他SMTP服务器,最终将邮件传递到收信人的邮件服务器。本程序作为电子邮件客户端程序,最基本的功能是要实现电子邮件发送,为了简化编程,使用了Delphi 5自带的TNMSMTP控件,该控件封装了对SMTP编程。由于该控件继承自TPowersock,因而必要时可以直接调用底层的Socket过程,又不失灵活性。
    例如,虽然TNMSMTP不直接支持“SMTP服务器认证功能”,但是,可以利用TNMSMTP的Connect事件和继承自TPowersock的Transaction方法,实现SMTP服务器认证。其原理在于,Connect事件发生在TNMSMTP与服务器连接成功之时,此时,使用Transaction方法发出SMTP服务器认证所规定的“AUTH LOGIN”命令,并输入经过BASE64编码后的用户名和密码,可以实现认证。因此,本程序实现了SMTP服务器认证。另外,TNMSMTP的SendStart事件在邮件发送开始时触发,在该事件中,可以通过修改TNMSMTP的FinalHeader属性值,实现修改电子邮件的邮件头信息。
    4.2.2电子邮件发送程序实现
    由于现在的SMTP的服务器都需要认证,而认证要发送的用户名和密码需要对用户名和密码进行BASE64编码,所以在这里我编了一个函数
       function EncodeString(Decoded:string):String;
    这个函数这要用来对认证要发送的密码进行BASE64编码,BASE64的编码程序原理在前面讲过了,在这里不在进行说明。
    本程序使用了自定义消息机制的消息传送机制。由于发送邮件也需要在登陆邮件服务器在后才进行操作,因此该消息在登陆服务器之后才进行操作,因此该消息在登陆服务器之后发送给主程序,触发自己实现的消息响音函数进行处理。
    使用者在编辑完邮件之后就可以点击“发送邮件”按钮进行发送邮件了。在发送之前,首先必须确定使用者是否已经填写好所有的必须信息,特别是收信人的信息,所有的信息都完备之后开始连接邮件服务器。“发送邮件”按钮的OnClick事件实现如下:
    procedure TForm1.ToolButton3Click(Sender: TObject);begin
        {验证用户输入信息}
        if txtTo.Text='' then
        begin
            ShowMessage('请输入收信人!');
            Exit;
        end;
    {设置SMTP服务器信息}
      NMSMTP1.Host := form2.smtpsever ;
      NMSMTP1.Port := form2.smtpport ;
      NMSMTP1.UserID:=form2.smtpUserName ;
     {报告当前状态}
      StatusBar1.SimpleText:='Connecting...';
      StatusBar1.Update;
     {连接服务器}
      NMSMTP1.Connect;
    end;
    如果连接邮件服务器成功,NMSMTP组建就会触发OnConnect事件,在该事件处理函数需要向主程序发送自定义消息并发送认证需要的密码,具体代码如下:
    procedure TForm1.NMSMTP1Connect(Sender: TObject);
    var
        strUserName,strPassword:string;
    begin    {对用户名和密码进行Base64编码}
           strUserName:=EncodeString(form2.smtpUserName);
           strPassword:=EncodeString(form2.smtpPassword);
           nmsmtp1.Transaction('auth login');   { 进行认证,输入编码后的用户名、密码}
           nmsmtp1.Transaction(strUserName);
           nmsmtp1.Transaction(strPassword);
      {报告状态}
         StatusBar1.SimpleText:='Connected';
         StatusBar1.Update;
        {发送自定义消息}
         SendMessage(Handle,WM_LOGIN,0,0);
    end;如果连接失败,就需要及时通知使用者,代码如下:
    procedure TForm1.NMSMTP1ConnectionFailed(Sender: TObject);
    begin
      ShowMessage('Connection Failed');
    end;
    在定义消息到主窗体之后,就会执行对应的自定义消息函数,在该函数中进行邮件发送的主要工作,包括发送之前的邮件信息填写。在发送完成之后还需要及时切断和邮件服务器的对话,具体代码如下:
    procedure TForm1.WMLOGIN(var Msg: TWM);
    begin
      //Send mail
    {填写邮件内容}
      NMSMTP1.SubType:=mthtml;
      //write receiver info
      NMSMTP1.PostMessage.FromAddress := form2.mailname ;
      NMSMTP1.PostMessage.FromName := form2.smtpUserName ;
      NMSMTP1.PostMessage.Subject := txtSubject.Text;
      NMSMTP1.PostMessage.ToAddress.Add(txtTo.Text);
      NMSMTP1.PostMessage.Attachments.AddStrings(Listbox1.Items);
      NMSMTP1.PostMessage.Body.Assign(memContents.Lines);
      {发送邮件}
      NMSMTP1.SendMail;
      {断开连接}
      NMSMTP1.Disconnect;
    end;
    如果断开连接操作成功,触发OnDisconnect事件,可以利用这个事件提示使用者邮件已经发送成功,具体代码如下:
    procedure TForm1.NMSMTP1Disconnect(Sender: TObject);
    begin
     If StatusBar1 <> nil then
        StatusBar1.SimpleText := 'Disconnected from server';
    end;在整个的过程中,还需要以下一个比较重要的信息。
    如果域名解析成功触发如下事件:
    procedure TForm1.NMSMTP1HostResolved(Sender: TComponent);
    begin
        StatusBar1.SimpleText := 'HostResolved';
    end;如果检测域名失败触发如下事件:
    procedure TForm1.NMSMTP1InvalidHost(var Handled: Boolean);
    begin
     StatusBar1.SimpleText := 'InvalidHost';
    end;在邮件即将开始发送之前会出发以下事件:
    procedure TForm1.NMSMTP1SendStart(Sender: TObject);
    begin
       StatusBar1.SimpleText := 'SendStart';
    end;在操作成功的时候会触发OnSuccess事件:
    procedure TForm1.NMSMTP1Success(Sender: TObject);
    begin
      StatusBar1.SimpleText := 'Success';
    end;整个程序还需要有邮件附件的增删功能。用户可以使用“添加附件”按钮来添加附件,该按钮的OnClick事件的程序段如下:
    procedure TForm1.ToolButton4Click(Sender: TObject);
    begin
        if OpenDialog1.Execute then
            ListBox1.Items.Add(
                OpenDialog1.FileName);
    end;用户在ListBox组件上可以选择需要删除的附件,使用键盘的“Delete”键删除,代码实现如下:
    procedure TForm1.ListBox1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    var
        idex:integer;
    begin
        //valid check
        if ListBox1.ItemIndex=-1 then
            exit;
        //key detect
        if Key<> VK_DELETE then
            exit;
        idex:=listbox1.ItemIndex;
        listbox1.Items.Delete(idex);
    end;
      

  3.   

    luo521(黑暗中的舞者) ,你好.我服!!!!!!
    有时间吗,我请你吃饭.
      

  4.   

    朋友,function EncodeString(Decoded:string):String;
    到底如何实现呵?
      

  5.   


    {对参数TMemoryStrema中的字节流进行Base64编码,编码后的结果
    保存在Encoded中,函数返回编码长度}
    function TForm1.EncodeBASE64(Encoded: TMemoryStream ; Decoded: TMemoryStream): Integer;
    const
      _Code64: String[64] =
        ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/');
    var
      I: LongInt;
      B: array[0..2279] of Byte;
      J, K, L, M, Quads: Integer;
      Stream: string[76];
      EncLine: String;
    begin  Encoded.Clear;  Stream := '';
      Quads := 0;  {为提高效率,每2280字节流为一组进行编码}
      J := Decoded.Size div 2280;  Decoded.Position := 0;  {对前J*2280个字节流进行编码}
      for I := 1 to J do
      begin
        Decoded.Read(B, 2280);    for M := 0 to 39 do
        begin
          for K := 0 to 18 do
          begin
            L:= 57*M + 3*K;        Stream[Quads+1] := _Code64[(B[L] div 4)+1];
            Stream[Quads+2] := _Code64[(B[L] mod 4)*16 + (B[L+1] div 16)+1];
            Stream[Quads+3] := _Code64[(B[L+1] mod 16)*4 + (B[L+2] div 64)+1];
            Stream[Quads+4] := _Code64[B[L+2] mod 64+1];        Inc(Quads, 4);        if Quads = 76 then
            begin
              Stream[0] := #76;
              EncLine := Stream+#13#10;
              Encoded.Write(EncLine[1], Length(EncLine));
              Quads := 0;
            end;
          end;
        end;
      end;  {对以2280为模的余数字节流进行编码}
      J := (Decoded.Size mod 2280) div 3;  for I := 1 to J do
      begin
        Decoded.Read(B, 3);    Stream[Quads+1] := _Code64[(B[0] div 4)+1];
        Stream[Quads+2] := _Code64[(B[0] mod 4)*16 + (B[1] div 16)+1];
        Stream[Quads+3] := _Code64[(B[1] mod 16)*4 + (B[2] div 64)+1];
        Stream[Quads+4] := _Code64[B[2] mod 64+1];    Inc(Quads, 4);    {每行76个字符}
        if Quads = 76 then
        begin
          Stream[0] := #76;
          EncLine := Stream+#13#10;
          Encoded.Write(EncLine[1], Length(EncLine));
          Quads := 0;
        end;
      end;
      {“=”补位}
      if (Decoded.Size mod 3) = 2 then
      begin
        Decoded.Read(B, 2);    Stream[Quads+1] := _Code64[(B[0] div 4)+1];
        Stream[Quads+2] := _Code64[(B[0] mod 4)*16 + (B[1] div 16)+1];
        Stream[Quads+3] := _Code64[(B[1] mod 16)*4 + 1];
        Stream[Quads+4] := '=';    Inc(Quads, 4);
      end;  if (Decoded.Size mod 3) = 1 then
      begin
        Decoded.Read(B, 1);    Stream[Quads+1] := _Code64[(B[0] div 4)+1];
        Stream[Quads+2] := _Code64[(B[0] mod 4)*16 + 1];
        Stream[Quads+3] := '=';
        Stream[Quads+4] := '=';
        Inc(Quads, 4);
      end;  Stream[0] := Chr(Quads);  if Quads > 0 then
      begin
        EncLine := Stream+#13#10;
        Encoded.Write(EncLine[1], Length(EncLine));
      end;  Result := Encoded.Size;
    end;{对参数Decoded字符串进行Base64编码,返回编码后的字符串}
    function TForm1.EncodeString(Decoded:string):String;
    var
        mmTemp,mmDecoded:TMemoryStream;
        strTemp:TStrings;
    begin
        mmTemp := TMemoryStream.Create;
        mmDecoded:=TMemoryStream.Create;
        strTemp:=TStringList.Create;    strTemp.Add(Decoded);
        strTemp.SaveToStream(mmTemp);
        mmTemp.Position := 0;    {剔除mmTemp从strTemp中带来的字符#13#10}
        mmDecoded.CopyFrom(mmTemp,mmTemp.Size-2);    {对mmDecoded进行Base64编码,由mmTemp返回编码后的结果}
        EncodeBASE64(mmTemp,mmDecoded);    {获得Base64编码后的字符串}
        mmTemp.Position:=0;
        strTemp.LoadFromStream(mmTemp);    {返回结果必须从strTemp[0]中获得,如果使用strTemp.Text会
        带来不必要的字符#13#10}
        Result:=strTemp[0];
    end;