用 Lazarus IDE 写一个邮件客户端软件,能收发邮件,编写邮件

发布于:2025-06-09 ⋅ 阅读:(14) ⋅ 点赞:(0)

下面是一个使用Lazarus IDE开发的基本邮件客户端实现方案,包含收发邮件和编写邮件的核心功能。我们将使用Synapse库(跨平台的网络通信库)来处理邮件协议。

步骤1:安装依赖

  1. 安装Synapse库:

    • 下载地址:https://sourceforge.net/projects/synalist/ , 下载 synalist-code-r278-trunk.zip
    • 解压后,在Lazarus中:Package > Open Package File > 选择synapse.lpk > Use > Install
  2. 安装OpenSSL库(用于加密连接):

    • Windows:下载预编译的DLL(libeay32.dll和ssleay32.dll)并放在项目目录
    • Linux:安装openssl开发包(如sudo apt-get install libssl-dev

步骤2:创建主窗体(frmMain)

unit mainform;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
  ComCtrls, Menus, smtpsend, pop3send, mimemess, mimepart, synautil;

type
  TAccountSettings = record
    SMTPHost: string;
    SMTPPort: string;
    POP3Host: string;
    POP3Port: string;
    Username: string;
    Password: string;
  end;

  { TfrmMain }

  TfrmMain = class(TForm)
    btnCompose: TButton;
    btnRefresh: TButton;
    lvEmails: TListView;
    memBody: TMemo;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    Panel1: TPanel;
    Panel2: TPanel;
    pmEmail: TPopupMenu;
    Splitter1: TSplitter;
    procedure btnComposeClick(Sender: TObject);
    procedure btnRefreshClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure lvEmailsSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
  private
    FAccount: TAccountSettings;
    procedure LoadEmails;
  public
    property Account: TAccountSettings read FAccount write FAccount;
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.lfm}

{ TfrmMain }

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  // 配置邮件账户(示例值,需替换为实际账户)
  FAccount.SMTPHost := 'smtp.example.com';
  FAccount.SMTPPort := '465';
  FAccount.POP3Host := 'pop.example.com';
  FAccount.POP3Port := '995';
  FAccount.Username := 'your@email.com';
  FAccount.Password := 'yourpassword';
end;

procedure TfrmMain.btnRefreshClick(Sender: TObject);
begin
  LoadEmails;
end;

procedure TfrmMain.btnComposeClick(Sender: TObject);
var
  frmCompose: TForm;
  edtTo, edtSubject: TEdit;
  memContent: TMemo;
  btnSend: TButton;
begin
  // 创建编写邮件窗体
  frmCompose := TForm.Create(Self);
  try
    frmCompose.Caption := '撰写邮件';
    frmCompose.SetBounds(100, 100, 600, 400);

    edtTo := TEdit.Create(frmCompose);
    edtTo.Parent := frmCompose;
    edtTo.SetBounds(10, 10, 580, 25);
    edtTo.TextHint := '收件人';

    edtSubject := TEdit.Create(frmCompose);
    edtSubject.Parent := frmCompose;
    edtSubject.SetBounds(10, 45, 580, 25);
    edtSubject.TextHint := '主题';

    memContent := TMemo.Create(frmCompose);
    memContent.Parent := frmCompose;
    memContent.SetBounds(10, 80, 580, 250);
    memContent.ScrollBars := ssVertical;

    btnSend := TButton.Create(frmCompose);
    btnSend.Parent := frmCompose;
    btnSend.SetBounds(500, 340, 90, 30);
    btnSend.Caption := '发送';
    btnSend.OnClick := procedure(Sender: TObject)
      var
        SMTP: TSMTPSend;
        Mime: TMimeMess;
      begin
        SMTP := TSMTPSend.Create;
        try
          SMTP.TargetHost := FAccount.SMTPHost;
          SMTP.TargetPort := FAccount.SMTPPort;
          SMTP.Username := FAccount.Username;
          SMTP.Password := FAccount.Password;
          SMTP.AutoTLS := True;
          SMTP.FullSSL := True; // 使用SSL加密

          if SMTP.Login then
          begin
            Mime := TMimeMess.Create;
            try
              Mime.Header.ToList.Text := edtTo.Text;
              Mime.Header.Subject := edtSubject.Text;
              Mime.Header.From := FAccount.Username;

              // 添加文本内容
              Mime.AddPartText(memContent.Lines, nil);
              Mime.EncodeMessage;

              if SMTP.MailFrom(FAccount.Username, Length(FAccount.Username)) and
                 SMTP.MailTo(edtTo.Text) and
                 SMTP.MailData(Mime.Lines) then
              begin
                ShowMessage('邮件发送成功!');
                frmCompose.Close;
              end
              else ShowMessage('发送失败: ' + SMTP.ResultString);
            finally
              Mime.Free;
            end;
          end
          else ShowMessage('SMTP登录失败: ' + SMTP.ResultString);
        finally
          SMTP.Free;
        end;
      end;

    frmCompose.ShowModal;
  finally
    frmCompose.Free;
  end;
end;

procedure TfrmMain.LoadEmails;
var
  POP3: TPOP3Send;
  Mime: TMimeMess;
  i: Integer;
  Item: TListItem;
begin
  lvEmails.Items.BeginUpdate;
  try
    lvEmails.Items.Clear;

    POP3 := TPOP3Send.Create;
    try
      POP3.TargetHost := FAccount.POP3Host;
      POP3.TargetPort := FAccount.POP3Port;
      POP3.Username := FAccount.Username;
      POP3.Password := FAccount.Password;
      POP3.AutoTLS := True;
      POP3.FullSSL := True; // 使用SSL加密

      if POP3.Login then
      begin
        for i := 1 to POP3.Stat do
        begin
          POP3.Top(i, 0); // 仅获取邮件头
          Mime := TMimeMess.Create;
          try
            Mime.Lines.Assign(POP3.FullResult);
            Mime.DecodeMessage;

            Item := lvEmails.Items.Add;
            Item.Caption := Mime.Header.Subject;
            Item.SubItems.Add(Mime.Header.From);
            Item.SubItems.Add(DateTimeToStr(Mime.Header.Date));
            Item.Data := Pointer(i); // 存储邮件索引
          finally
            Mime.Free;
          end;
        end;
      end
      else ShowMessage('POP3登录失败: ' + POP3.ResultString);
    finally
      POP3.Free;
    end;
  finally
    lvEmails.Items.EndUpdate;
  end;
end;

procedure TfrmMain.lvEmailsSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
var
  POP3: TPOP3Send;
  Mime: TMimeMess;
  MailIndex: Integer;
begin
  if not Selected then Exit;
  
  MailIndex := Integer(Item.Data);
  POP3 := TPOP3Send.Create;
  try
    POP3.TargetHost := FAccount.POP3Host;
    POP3.TargetPort := FAccount.POP3Port;
    POP3.Username := FAccount.Username;
    POP3.Password := FAccount.Password;
    POP3.AutoTLS := True;
    POP3.FullSSL := True;

    if POP3.Login and POP3.Retr(MailIndex) then
    begin
      Mime := TMimeMess.Create;
      try
        Mime.Lines.Assign(POP3.FullResult);
        Mime.DecodeMessage;
        memBody.Lines.Text := Mime.MessagePart.Lines.Text; // 显示纯文本部分
      finally
        Mime.Free;
      end;
    end;
  finally
    POP3.Free;
  end;
end;

end.

步骤3:程序入口(project.lpr)

program mailclient;

uses
  Interfaces,
  Forms,
  mainform;

{$R *.res}

begin
  RequireDerivedFormResource := True;
  Application.Initialize;
  Application.CreateForm(TfrmMain, frmMain);
  Application.Run;
end.

功能说明:

  1. 邮件接收

    • 使用POP3协议从服务器获取邮件列表
    • 显示邮件主题、发件人和日期
    • 点击邮件显示纯文本内容
  2. 邮件发送

    • 使用SMTP协议发送邮件
    • 支持SSL/TLS加密
    • 简单的撰写界面(收件人、主题、正文)
  3. 界面组件

    • 左侧:邮件列表(TListView)
    • 右侧:邮件内容(TMemo)
    • 顶部按钮:刷新列表和撰写邮件

使用方法:

  1. 替换FormCreate中的账户信息为实际邮箱服务商提供的数据
  2. 根据邮箱服务商要求调整端口号(常用端口):
    • SMTP SSL: 465/587
    • POP3 SSL: 995

扩展建议:

  1. 添加附件支持

    // 在发送邮件部分添加
    Mime.AddPartBinaryFromFile('附件路径', 'application/octet-stream');
    
  2. HTML邮件支持

    Mime.AddPartHTML(HTMLContent, nil);
    
  3. 多账户管理

    • 创建账户管理表单
    • 存储多个账户配置
    • 增加账户切换功能
  4. 错误处理增强

    • 添加超时处理
    • 网络异常捕获
    • 详细的错误日志
  5. 安全存储密码

    • 使用加密方式存储密码
    • 实现"记住密码"功能

这个实现提供了基本的邮件客户端功能,你可以根据需求继续扩展界面和功能(如文件夹管理、邮件搜索、联系人管理等)。实际使用时请注意邮箱服务商的安全策略(如部分邮箱需要开启"允许不安全应用"或设置专用密码)。