⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 messageform.pas

📁 这是一套全面的网络组件
💻 PAS
字号:
unit MessageForm;

interface

uses
  Classes, Controls, Forms, StdCtrls, ComCtrls, {MessagePersister,}
  Menus, ImgList, Windows, Dialogs, DHTMLEDLib_TLB, ExtCtrls,
  ToolWin, MSHTML, {Variants, }OleCtrls, clMailMessage;

{$WARNINGS OFF}
  
type
  TfrmMessage = class(TForm)
    edtSubject: TEdit;
    edtFrom: TEdit;
    cmbPriority: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label6: TLabel;
    lvAttach: TListView;
    MessageParser: TclMailMessage;
    mnuAttach: TPopupMenu;
    mnuInsertFileAttachment: TMenuItem;
    mnuSaveFileAttachment: TMenuItem;
    mnuDeleteFileAttachment: TMenuItem;
    MessageImages: TImageList;
    SaveDialog: TSaveDialog;
    OpenDialog: TOpenDialog;
    pHtmlBody: TPanel;
    edtTo: TEdit;
    Label7: TLabel;
    edtCc: TEdit;
    Label8: TLabel;
    edtBcc: TEdit;
    MainMenu: TMainMenu;
    File1: TMenuItem;
    AppendMessage1: TMenuItem;
    N1: TMenuItem;
    Close1: TMenuItem;
    Edit1: TMenuItem;
    Cut1: TMenuItem;
    Copy1: TMenuItem;
    Paste1: TMenuItem;
    Insert1: TMenuItem;
    FileAttachment1: TMenuItem;
    Picture1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure MessageParserGetBodyStream(Sender: TObject;
      ABody: TclMessageBody; const AFileName: String; var AStream: TStream;
      var Handled: Boolean);
    procedure lvAttachContextPopup(Sender: TObject; MousePos: TPoint;
      var Handled: Boolean);
    procedure mnuInsertFileAttachmentClick(Sender: TObject);
    procedure mnuDeleteFileAttachmentClick(Sender: TObject);
    procedure mnuSaveFileAttachmentClick(Sender: TObject);
    procedure AppendMessage1Click(Sender: TObject);
    procedure Picture1Click(Sender: TObject);
    procedure Close1Click(Sender: TObject);
    procedure Cut1Click(Sender: TObject);
    procedure Copy1Click(Sender: TObject);
    procedure Paste1Click(Sender: TObject);
  private
    FReadOnly: Boolean;
    FSelectedAttachName: string;
    FMailMessage: TStrings;
    wbBody: TDHTMLEdit;
    procedure LoadBodies(ABodySrc: TStrings; ABodies: TclMessageBodies);
    procedure LoadAttachment(ABody: TclAttachmentBody);
    procedure LoadMessage(AMessage: TStrings);
    procedure StoreMessage(AMessage: TStrings);
    procedure UpdateControls;
    procedure GetAttachmentList(AList: TStrings);
    procedure GetImageList(AList: TStrings);
    procedure ClearMessageTempDir;
    procedure ShowBody(ABodySrc: TStrings);
    procedure ReplaceImageName(ABodySrc: TStrings; ABodies: TclMessageBodies);
    procedure ExecCommand(cmdID: OleVariant);
  public
    class function GetMessageTempDir: string;
    class function NewMessage(AMessage: TStrings; const AFrom: string): Boolean;
    class function ShowMessage(AMessage: TStrings; aReadOnly: boolean): Boolean;
  end;

implementation

uses
  SysUtils, FileCtrl, Graphics;

{$R *.dfm}

{ TfrmMessage }

class function TfrmMessage.ShowMessage(AMessage: TStrings; aReadOnly: boolean): Boolean;
var
  Dlg: TfrmMessage;
begin
  Dlg := TfrmMessage.Create(nil);
  try
    Dlg.FReadOnly := aReadOnly;
    Dlg.LoadMessage(AMessage);
    Dlg.ShowModal();
    if not Dlg.FReadOnly then
    begin
      Dlg.StoreMessage(AMessage);
    end;
    Result := (Dlg.ModalResult = mrYes);
  finally
    Dlg.Free();
  end;
end;

procedure TfrmMessage.FormCreate(Sender: TObject);
const
  PiorityMap: array[TclMessagePriority] of string = ('Low', 'Normal', 'High');
var
  i: TclMessagePriority;
begin
  wbBody := TDHTMLEdit.Create(nil);
  wbBody.ControlInterface._AddRef();
  wbBody.Parent := pHtmlBody;
  wbBody.Align := alClient;
  for i := Low(TclMessagePriority) to High(TclMessagePriority) do
  begin
    cmbPriority.Items.Add(PiorityMap[i]);
  end;
end;

procedure TfrmMessage.LoadAttachment(ABody: TclAttachmentBody);
var
  Item: TListItem;
begin
  Item := lvAttach.Items.Add();
  Item.Caption := ABody.FileName;
  Item.ImageIndex := 0;
end;

procedure TfrmMessage.GetAttachmentList(AList: TStrings);
var
  i: Integer;
begin
  AList.Clear();
  for i := 0 to lvAttach.Items.Count - 1 do
  begin
    AList.Add(GetMessageTempDir() + lvAttach.Items[i].Caption);
  end;
end;

procedure TfrmMessage.GetImageList(AList: TStrings);
var
  i: Integer;
  item: IHTMLElement;
  s: string;
begin
  AList.Clear();
  for i := 0 to wbBody.DOM.images.length - 1 do
  begin
    if (wbBody.DOM.images.item(i, 0).QueryInterface(IHTMLElement, item) = S_OK) then
    begin
      s := string(item.GetAttribute('src', 2));
      if (ExtractFileName(s) = s) then
      begin
        s := GetMessageTempDir() + ExtractFileName(s);
      end;
      AList.Add(s);
    end;
  end;
end;

procedure TfrmMessage.LoadBodies(ABodySrc: TStrings; ABodies: TclMessageBodies);
var
  i: Integer;
begin
  for i := 0 to ABodies.Count - 1 do
  begin
    if (ABodies[i] is TclMultipartBody) then
    begin
      LoadBodies(ABodySrc, (ABodies[i] as TclMultipartBody).Bodies);
    end else
    if (ABodies[i] is TclTextBody) then
    begin
      ABodySrc.Assign((ABodies[i] as TclTextBody).Strings);
    end else
    if (ABodies[i].ClassType = TclAttachmentBody) then
    begin
      LoadAttachment(ABodies[i] as TclAttachmentBody);
    end;
  end;
end;

procedure TfrmMessage.LoadMessage(AMessage: TStrings);
var
  BodySrc: TStrings;
begin
  FMailMessage := AMessage;
  MessageParser.MessageSource := AMessage;
  edtSubject.Text := MessageParser.Subject;
  edtFrom.Text := MessageParser.From;
  edtTo.Text := EmailListToString(MessageParser.ToList);
  edtCc.Text := EmailListToString(MessageParser.CCList);
  edtBcc.Text := EmailListToString(MessageParser.BCCList);
  cmbPriority.ItemIndex := Integer(MessageParser.Priority);
  lvAttach.Items.Clear();
  BodySrc := TStringList.Create();
  try
    LoadBodies(BodySrc, MessageParser.Bodies);
    ShowBody(BodySrc);
  finally
    BodySrc.Free();
  end;
end;

procedure TfrmMessage.ReplaceImageName(ABodySrc: TStrings; ABodies: TclMessageBodies);
var
  i: Integer;
begin
  for i := 0 to ABodies.Count - 1 do
  begin
    if (ABodies[i] is TclImageBody) then
    begin
      ABodySrc.Text := StringReplace(ABodySrc.Text, 'cid:' + (ABodies[i] as TclImageBody).ContentID,
        (ABodies[i] as TclImageBody).FileName, [rfReplaceAll, rfIgnoreCase]);
    end else
    if (ABodies[i] is TclMultipartBody) then
    begin
      ReplaceImageName(ABodySrc, (ABodies[i] as TclMultipartBody).Bodies);
    end;
  end;
end;

procedure TfrmMessage.ShowBody(ABodySrc: TStrings);
var
  PathIn, UserPrompt: OleVariant;
begin
  ReplaceImageName(ABodySrc, MessageParser.Bodies);
  ABodySrc.SaveToFile(GetMessageTempDir() + 'htmlbody.htm');
  PathIn := GetMessageTempDir() + 'htmlbody.htm';
  UserPrompt := False;
  wbBody.BrowseMode := FReadOnly;
  wbBody.LoadDocument(PathIn, UserPrompt);
end;

procedure TfrmMessage.StoreMessage(AMessage: TStrings);
var
  BodySrc, Images, Attach: TStrings;
  PathIn, UserPrompt: OleVariant;
begin
  if FReadOnly then Exit;
  BodySrc := TStringList.Create();
  Images := TStringList.Create();
  Attach := TStringList.Create();
  try
    GetImageList(Images);
    GetAttachmentList(Attach);
    PathIn := GetMessageTempDir() + 'htmlbody.htm';
    UserPrompt := False;
    wbBody.SaveDocument(PathIn, UserPrompt);
    while wbBody.Busy and not (csDestroying in ComponentState) do
      Application.ProcessMessages();
    BodySrc.LoadFromFile(GetMessageTempDir() + 'htmlbody.htm');
    MessageParser.BuildMessage(string(wbBody.DOM.body.innerText), BodySrc.Text, Images, Attach);
  finally
    Attach.Free();
    Images.Free();
    BodySrc.Free();
  end;
  MessageParser.Subject := edtSubject.Text;
  MessageParser.From := edtFrom.Text;
  StringToEmailList(edtTo.Text, MessageParser.ToList);
  StringToEmailList(edtCc.Text, MessageParser.CCList);
  StringToEmailList(edtBcc.Text, MessageParser.BCCList);
  MessageParser.Priority := TclMessagePriority(cmbPriority.ItemIndex);
  AMessage.Assign(MessageParser.MessageSource);
end;

procedure TfrmMessage.UpdateControls;
const
  FormCaption: array[Boolean] of string = ('Mail Message Editor', 'Mail Message Viewer');
  ColorMask: array[Boolean] of TColor = (clWindow, clBtnFace);
begin
  Caption := FormCaption[FReadOnly];
  edtFrom.ReadOnly := FReadOnly;
  edtSubject.ReadOnly := FReadOnly;
  edtTo.ReadOnly := FReadOnly;
  edtCc.ReadOnly := FReadOnly;
  edtBcc.ReadOnly := FReadOnly;
  cmbPriority.Enabled := not FReadOnly;
  edtSubject.Color := ColorMask[FReadOnly];
  edtFrom.Color := ColorMask[FReadOnly];
  edtTo.Color := ColorMask[FReadOnly];
  edtCc.Color := ColorMask[FReadOnly];
  edtBcc.Color := ColorMask[FReadOnly];
  AppendMessage1.Enabled := not FReadOnly;
  Cut1.Enabled := not FReadOnly;
  Paste1.Enabled := not FReadOnly;
  FileAttachment1.Enabled := not FReadOnly;
  Picture1.Enabled := not FReadOnly;
end;

procedure TfrmMessage.FormShow(Sender: TObject);
begin
  UpdateControls();
  FSelectedAttachName := '';
end;

class function TfrmMessage.NewMessage(AMessage: TStrings; const AFrom: string): Boolean;
var
  Dlg: TfrmMessage;
begin
  Dlg := TfrmMessage.Create(nil);
  try
    Dlg.FReadOnly := False;
    Dlg.LoadMessage(AMessage);
    Dlg.edtFrom.Text := AFrom;
    Dlg.ShowModal();
    if not Dlg.FReadOnly then
    begin
      Dlg.StoreMessage(AMessage);
    end;
//    AMessage.MarkedAsRead := True;
    Result := (Dlg.ModalResult = mrYes);
  finally
    Dlg.Free();
  end;
end;

procedure TfrmMessage.MessageParserGetBodyStream(Sender: TObject;
  ABody: TclMessageBody; const AFileName: String; var AStream: TStream;
  var Handled: Boolean);
begin
  if FReadOnly then
  begin
    if (FSelectedAttachName = AFileName) then
    begin
      SaveDialog.FileName := AFileName;
      if SaveDialog.Execute() then
      begin
        AStream := TFileStream.Create(SaveDialog.FileName, fmCreate);
      end;
      FSelectedAttachName := '';
    end else
    if (ABody is TclImageBody) then
    begin
      AStream := TFileStream.Create(GetMessageTempDir() + AFileName, fmCreate);
    end;
  end else
  begin
    AStream := TFileStream.Create(GetMessageTempDir() + AFileName, fmCreate);
  end;
  Handled := True;
end;

procedure TfrmMessage.lvAttachContextPopup(Sender: TObject;
  MousePos: TPoint; var Handled: Boolean);
begin
  mnuInsertFileAttachment.Enabled := not FReadOnly;
  mnuDeleteFileAttachment.Enabled := not FReadOnly and (lvAttach.Selected <> nil);
  mnuSaveFileAttachment.Enabled := FReadOnly and (lvAttach.Selected <> nil);
end;

procedure TfrmMessage.ClearMessageTempDir;
var
  Res: Integer;
  sr: TSearchRec;
  Attr: Integer;
  ADir: String;
  FileAttr: DWORD;
begin
  ADir := GetMessageTempDir();
  if not DirectoryExists(ADir) then Exit;
  Attr := faAnyFile and (not faDirectory);
  Res := SysUtils.FindFirst(ADir + '\*.*', Attr, sr);
  while (Res = 0) do
  begin
    FileAttr := GetFileAttributes(PChar(ADir + '\' + sr.FindData.cFileName));
    if ((FileAttr and FILE_ATTRIBUTE_READONLY) > 0) then
    begin
      SetFileAttributes(PChar(ADir + '\' + sr.FindData.cFileName), FileAttr xor FILE_ATTRIBUTE_READONLY);
    end;
    SysUtils.DeleteFile(ADir + '\' + sr.FindData.cFileName);
    Res := SysUtils.FindNext(sr);
  end;
  SysUtils.FindClose(sr);
end;

class function TfrmMessage.GetMessageTempDir: string;
var
  Buffer: array[0..MAX_PATH - 1] of Char;
begin
  SetString(Result, Buffer, GetTempPath(SizeOf(Buffer), Buffer));
  if (Result <> '') and (Result[Length(Result)] <> '\') then
  begin
    Result := Result + '\';
  end;
  Result := Result + 'CleverMailClient\';
  ForceDirectories(Result);
end;

procedure TfrmMessage.mnuInsertFileAttachmentClick(Sender: TObject);
var
  Item: TListItem;
  NewName: string;
begin
  if OpenDialog.Execute() then
  begin
    NewName := GetMessageTempDir() + ExtractFileName(OpenDialog.FileName);
    CopyFile(PChar(OpenDialog.FileName), PChar(NewName), False);
    Item := lvAttach.Items.Add();
    Item.Caption := ExtractFileName(OpenDialog.FileName);
    Item.ImageIndex := 0;
  end;
end;

procedure TfrmMessage.mnuDeleteFileAttachmentClick(Sender: TObject);
begin
  Assert(lvAttach.Selected <> nil);
  DeleteFile(GetMessageTempDir() + lvAttach.Selected.Caption);
  lvAttach.Selected.Delete();
end;

procedure TfrmMessage.mnuSaveFileAttachmentClick(Sender: TObject);
begin
  Assert(lvAttach.Selected <> nil);
  FSelectedAttachName := lvAttach.Selected.Caption;
  try
    MessageParser.MessageSource := FMailMessage;
  finally
    FSelectedAttachName := '';
  end;
end;

procedure TfrmMessage.FormDestroy(Sender: TObject);
begin
  ClearMessageTempDir();
  wbBody.Free();
end;

procedure TfrmMessage.AppendMessage1Click(Sender: TObject);
begin
  ModalResult := mrYes;
end;

procedure TfrmMessage.Close1Click(Sender: TObject);
begin
  ModalResult := mrOK;
end;

procedure TfrmMessage.ExecCommand(cmdID: OleVariant);
var
  pVar: OleVariant;
begin
  if not wbBody.Busy then
  begin
    try
      if ((wbBody.QueryStatus(CmdID) and DECMDF_ENABLED) = DECMDF_ENABLED) then
      begin
        pVar := 0;
        wbBody.ExecCommand(cmdID, 0, pVar);
      end;
    except
    end;
  end;
end;

procedure TfrmMessage.Cut1Click(Sender: TObject);
begin
  ExecCommand(DECMD_CUT);
end;

procedure TfrmMessage.Copy1Click(Sender: TObject);
begin
  ExecCommand(DECMD_COPY);
end;

procedure TfrmMessage.Paste1Click(Sender: TObject);
begin
  ExecCommand(DECMD_PASTE);
end;

procedure TfrmMessage.Picture1Click(Sender: TObject);
begin
  ExecCommand(DECMD_IMAGE);
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -