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

📄 jclmapi.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  if foUnreadOnly in FFindOptions then
    Inc(Flags, MAPI_UNREAD_ONLY);
  Res := MapiFindNext(FSessionHandle, 0, nil, PChar(FSeedMessageID), Flags, 0, MsgId);
  Result := (Res = SUCCESS_SUCCESS);
  if Result then
    SeedMessageID := MsgID
  else
  begin
    SeedMessageID := '';
    if Res <> MAPI_E_NO_MESSAGES then
      MapiCheck(Res, True);
  end;
end;

function TJclEmail.GetAttachments: TStrings;
begin
  Result := FAttachments;
end;

function TJclEmail.GetParentWnd: HWND;
begin
  if FParentWndValid then
    Result := FParentWnd
  else
    Result := GetMainAppWndFromPid(GetCurrentProcessId);
end;

function TJclEmail.GetUserLogged: Boolean;
begin
  Result := (FSessionHandle <> 0);
end;

function TJclEmail.InternalSendOrSave(Save, ShowDialog: Boolean): Boolean;
const
  RecipClasses: array [TJclEmailRecipKind] of DWORD =
    (MAPI_ORIG, MAPI_TO, MAPI_CC, MAPI_BCC);
var
  AttachArray: array of TMapiFileDesc;
  RecipArray: array of TMapiRecipDesc;
  RealAdresses: array of string;
  MapiMessage: TMapiMessage;
  Flags, Res: DWORD;
  I: Integer;
  MsgID: array [0..512] of AnsiChar;
  HtmlBodyFileName: string;
begin
  if not AnyClientInstalled then
    raise EJclMapiError.CreateRes(@RsMapiMailNoClient);

  HtmlBodyFileName := '';
  try
    if FHtmlBody then
    begin
      HtmlBodyFileName := FindUnusedFileName(PathAddSeparator(GetWindowsTempFolder) + 'JclMapi', 'htm', 'Temp');
      Attachments.Insert(0, HtmlBodyFileName);
      StringToFile(HtmlBodyFileName, Body);
    end;
    // Create attachments
    if Attachments.Count > 0 then
    begin
      SetLength(AttachArray, Attachments.Count);
      for I := 0 to Attachments.Count - 1 do
      begin
        if not FileExists(Attachments[I]) then
          MapiCheck(MAPI_E_ATTACHMENT_NOT_FOUND, False);
        Attachments[I] := ExpandFileName(Attachments[I]);
        FillChar(AttachArray[I], SizeOf(TMapiFileDesc), #0);
        AttachArray[I].nPosition := DWORD(-1);
        AttachArray[I].lpszFileName := nil;
        AttachArray[I].lpszPathName := PChar(Attachments[I]);
      end;
    end
    else
      AttachArray := nil;
    // Create recipients
    if Recipients.Count > 0 then
    begin
      SetLength(RecipArray, Recipients.Count);
      SetLength(RealAdresses, Recipients.Count);
      for I := 0 to Recipients.Count - 1 do
      begin
        FillChar(RecipArray[I], SizeOf(TMapiRecipDesc), #0);
        with RecipArray[I], Recipients[I] do
        begin
          ulRecipClass := RecipClasses[Kind];
          if Name = '' then // some clients requires Name item always filled
          begin
            if FAddress = '' then
              MapiCheck(MAPI_E_INVALID_RECIPS, False);
            lpszName := PChar(FAddress);
          end
          else
            lpszName := PChar(FName);
          if FAddressType <> '' then
            RealAdresses[I] := FAddressType + AddressTypeDelimiter + FAddress
          else
          if Recipients.AddressesType <> '' then
            RealAdresses[I] := Recipients.AddressesType + AddressTypeDelimiter + FAddress
          else
            RealAdresses[I] := FAddress;
          lpszAddress := PCharOrNil(RealAdresses[I]);
        end;
      end;
    end
    else
    begin
      if ShowDialog then
        RecipArray := nil
      else
        MapiCheck(MAPI_E_INVALID_RECIPS, False);
    end;
    // Load MAPI client library
    LoadClientLib;
    // Fill MapiMessage structure
    FillChar(MapiMessage, SizeOf(MapiMessage), #0);
    MapiMessage.lpszSubject := PChar(FSubject);
    if FHtmlBody then
      MapiMessage.lpszNoteText := #0
    else
      MapiMessage.lpszNoteText := PChar(FBody);
    MapiMessage.lpRecips := PMapiRecipDesc(RecipArray);
    MapiMessage.nRecipCount := Length(RecipArray);
    MapiMessage.lpFiles := PMapiFileDesc(AttachArray);
    MapiMessage.nFileCount := Length(AttachArray);
    Flags := LogonOptionsToFlags(ShowDialog);
    if Save then
    begin
      StrPLCopy(MsgID, SeedMessageID, SizeOf(MsgID));
      Res := MapiSaveMail(FSessionHandle, ParentWND, MapiMessage, Flags, 0, MsgID);
      if Res = SUCCESS_SUCCESS then
        SeedMessageID := MsgID;
    end
    else
      Res := MapiSendMail(FSessionHandle, ParentWND, MapiMessage, Flags, 0);
    Result := (MapiCheck(Res, True) = SUCCESS_SUCCESS);
  finally
    if HtmlBodyFileName <> '' then
    begin
      DeleteFile(HtmlBodyFileName);
      Attachments.Delete(0);
    end;
  end;
end;

procedure TJclEmail.LogOff;
begin
  if UserLogged then
  begin
    MapiCheck(MapiLogOff(FSessionHandle, ParentWND, 0, 0), True);
    FSessionHandle := 0;
  end;
end;

procedure TJclEmail.LogOn(const ProfileName, Password: string);
begin
  if not UserLogged then
  begin
    LoadClientLib;
    MapiCheck(MapiLogOn(ParentWND, PChar(ProfileName), PChar(Password),
      LogonOptionsToFlags(False), 0, @FSessionHandle), True);
  end; 
end;

function TJclEmail.LogonOptionsToFlags(ShowDialog: Boolean): DWORD;
begin
  Result := 0;
  if FSessionHandle = 0 then
  begin
    if loLogonUI in FLogonOptions then
      Inc(Result, MAPI_LOGON_UI);
    if loNewSession in FLogonOptions then
      Inc(Result, MAPI_NEW_SESSION);
    if loForceDownload in FLogonOptions then
      Inc(Result, MAPI_FORCE_DOWNLOAD);
  end;
  if ShowDialog then
    Inc(Result, MAPI_DIALOG);
end;

function TJclEmail.MessageReport(Strings: TStrings; MaxWidth: Integer; IncludeAddresses: Boolean): Integer;
const
  NameDelimiter = ', ';
var
  LabelsWidth: Integer;
  NamesList: array [TJclEmailRecipKind] of string;
  ReportKind: TJclEmailRecipKind;
  I, Cnt: Integer;
  BreakStr, S: string;
begin
  Cnt := Strings.Count;
  LabelsWidth := Length(RsMapiMailSubject);
  for ReportKind := Low(ReportKind) to High(ReportKind) do
  begin
    NamesList[ReportKind] := '';
    LabelsWidth := Max(LabelsWidth, Length(TJclEmailRecip.RecipKindToString(ReportKind)));
  end;
  BreakStr := AnsiCrLf + StringOfChar(' ', LabelsWidth + 2);
  for I := 0 to Recipients.Count - 1 do
    with Recipients[I] do
    begin
      if IncludeAddresses then
        S := AddressAndName
      else
        S := Name;
      NamesList[Kind] := NamesList[Kind] + S + NameDelimiter;
    end;

  Strings.BeginUpdate;
  try
    for ReportKind := Low(ReportKind) to High(ReportKind) do
      if NamesList[ReportKind] <> '' then
      begin
        S := StrPadRight(TJclEmailRecip.RecipKindToString(ReportKind), LabelsWidth, AnsiSpace) + ': ' +
          Copy(NamesList[ReportKind], 1, Length(NamesList[ReportKind]) - Length(NameDelimiter));
        Strings.Add(WrapText(S, BreakStr, [AnsiTab, AnsiSpace], MaxWidth));
      end;
    S := RsMapiMailSubject + ': ' + Subject;
    Strings.Add(WrapText(S, BreakStr, [AnsiTab, AnsiSpace], MaxWidth));
    Result := Strings.Count - Cnt;
    Strings.Add('');
    Strings.Add(WrapText(Body, AnsiCrLf, [AnsiTab, AnsiSpace, '-'], MaxWidth));
  finally
    Strings.EndUpdate;
  end;
end;

function TJclEmail.Read(const Options: TJclEmailReadOptions): Boolean;
var
  Flags: ULONG;
  Msg: PMapiMessage;
  I: Integer;
  Files: PMapiFileDesc;

  function CopyAndStrToInt(const S: string; Index, Count: Integer): Integer;
  begin
    Result := StrToIntDef(Copy(S, Index, Count), 0);
  end;

  function MessageDateToDate(const S: string): TDateTime;
  var
    T: TSystemTime;
  begin
    FillChar(T, SizeOf(T), #0);
    with T do
    begin
      wYear := CopyAndStrToInt(S, 1, 4);
      wMonth := CopyAndStrToInt(S, 6, 2);
      wDay := CopyAndStrToInt(S, 9, 2);
      wHour := CopyAndStrToInt(S, 12, 2);
      wMinute := CopyAndStrToInt(S, 15,2);
      Result := EncodeDate(wYear, wMonth, wDay) + EncodeTime(wHour, wMinute, wSecond, wMilliseconds);
    end;
  end;

begin
  Result := False;
  if not UserLogged then
    Exit;
  Clear;
  Flags := 0;
  if roHeaderOnly in Options then
    Inc(Flags, MAPI_ENVELOPE_ONLY);
  if not (roMarkAsRead in Options) then
    Inc(Flags, MAPI_PEEK);
  if not (roAttachments in Options) then
    Inc(Flags, MAPI_SUPPRESS_ATTACH);
  MapiCheck(MapiReadMail(SessionHandle, 0, PChar(FSeedMessageID), Flags, 0, Msg), True);
  if Msg <> nil then
  try
    DecodeRecips(Msg^.lpOriginator, 1);
    DecodeRecips(Msg^.lpRecips, Msg^.nRecipCount);
    FSubject := Msg^.lpszSubject;
    Body := AdjustLineBreaks(Msg^.lpszNoteText);
    Files := Msg^.lpFiles;
    if Files <> nil then
      for I := 0 to Msg^.nFileCount - 1 do
      begin
        if Files^.lpszPathName <> nil then
          Attachments.Add(Files^.lpszPathName)
        else
          Attachments.Add(Files^.lpszFileName);
        Inc(Files);
      end;
    FReadMsg.MessageType := Msg^.lpszMessageType;
    if Msg^.lpszDateReceived <> nil then
      FReadMsg.DateReceived := MessageDateToDate(Msg^.lpszDateReceived);
    FReadMsg.ConversationID := Msg^.lpszConversationID;
    FReadMsg.Flags := Msg^.flFlags;
    Result := True;
  finally
    MapiFreeBuffer(Msg);
  end;
end;

function TJclEmail.ResolveName(var Name, Address: string; ShowDialog: Boolean): Boolean;
var
  Recip: PMapiRecipDesc;
  Res, Flags: DWORD;
begin
  LoadClientLib;
  Flags := LogonOptionsToFlags(ShowDialog) or MAPI_AB_NOMODIFY;
  Recip := nil;
  Res := MapiResolveName(FSessionHandle, ParentWnd, PChar(Name), Flags, 0, Recip);
  Result := (MapiCheck(Res, True) = SUCCESS_SUCCESS) and (Recip <> nil);
  if Result then
  begin
    Address := Recip^.lpszAddress;
    Name := Recip^.lpszName;
    MapiFreeBuffer(Recip);
  end;
end;

procedure TJclEmail.RestoreTaskWindows;
begin
  RestoreTaskWindowsList(FTaskWindowList);
  FTaskWindowList := nil;
end;

function TJclEmail.Save: Boolean;
begin
  Result := InternalSendOrSave(True, False);
end;

procedure TJclEmail.SaveTaskWindows;
begin
  FTaskWindowList := SaveTaskWindowsList;
end;

function TJclEmail.Send(ShowDialog: Boolean): Boolean;
begin
  Result := InternalSendOrSave(False, ShowDialog);
end;

procedure TJclEmail.SetBody(const Value: string);
begin
  if Value = '' then
    FBody := ''
  else
    FBody := StrEnsureSuffix(AnsiCrLf, Value);
end;

procedure TJclEmail.SetParentWnd(const Value: HWND);
begin
  FParentWnd := Value;
  FParentWndValid := True;
end;

procedure TJclEmail.SortAttachments;
begin
  FAttachments.Sort;
end;

//=== Simple email send function =============================================

function SimpleSendHelper(const ARecipient, AName, ASubject, ABody: string; const AAttachment: string;
  AShowDialog: Boolean; AParentWND: HWND; const AProfileName, APassword, AAddressType: string): Boolean;
begin
  with TJclEmail.Create do
  try
    if AParentWND <> 0 then
      ParentWnd := AParentWND;
    if ARecipient <> '' then
      Recipients.Add(ARecipient, AName, rkTO, AAddressType);
    Subject := ASubject;
    Body := ABody;
    if AAttachment <> '' then
      Attachments.Add(AAttachment);
    if AProfileName <> '' then
      LogOn(AProfileName, APassword);
    Result := Send(AShowDialog);
  finally
    Free;
  end;
end;

function JclSimpleSendMail(const Recipient, Name, Subject, Body: string;
  const Attachment: string; ShowDialog: Boolean; ParentWND: HWND;
  const ProfileName: string; const Password: string): Boolean;
begin
  Result := SimpleSendHelper(Recipient, Name, Subject, Body, Attachment, ShowDialog, ParentWND,
    ProfileName, Password, MapiAddressTypeSMTP);
end;

function JclSimpleSendFax(const Recipient, Name, Subject, Body: string;
  const Attachment: string; ShowDialog: Boolean; ParentWND: HWND;
  const ProfileName: string; const Password: string): Boolean;
begin
  Result := SimpleSendHelper(Recipient, Name, Subject, Body, Attachment, ShowDialog, ParentWND,
    ProfileName, Password, MapiAddressTypeFAX);
end;

function JclSimpleBringUpSendMailDialog(const Subject, Body: string;
  const Attachment: string; ParentWND: HWND;
  const ProfileName: string; const Password: string): Boolean;
begin
  Result := SimpleSendHelper('', '', Subject, Body, Attachment, True, ParentWND,
    ProfileName, Password, MapiAddressTypeSMTP);
end;

// History:

// $Log: JclMapi.pas,v $
// Revision 1.14  2005/03/08 08:33:22  marquardt
// overhaul of exceptions and resourcestrings, minor style cleaning
//
// Revision 1.13  2005/02/25 07:20:15  marquardt
// add section lines
//
// Revision 1.12  2005/02/24 16:34:52  marquardt
// remove divider lines, add section lines (unfinished)
//
// Revision 1.11  2004/10/25 20:42:07  mthoma
// #0002255
//
// Revision 1.10  2004/10/17 21:29:23  mthoma
// Used version rev 1.2 to remove all rev 1.3 contributions.
//
// Revision 1.9  2004/10/17 21:00:15  mthoma
// cleaning
//
// Revision 1.8  2004/07/31 06:21:03  marquardt
// fixing TStringLists, adding BeginUpdate/EndUpdate, finalization improved
//
// Revision 1.7  2004/07/28 18:00:53  marquardt
// various style cleanings, some minor fixes
//
// Revision 1.6  2004/06/16 07:30:30  marquardt
// added tilde to all IFNDEF ENDIFs, inherited qualified
//
// Revision 1.5  2004/06/02 03:23:47  rrossmair
// cosmetic changes in several units (code formatting, help TODOs processed etc.)
//
// Revision 1.4  2004/05/05 07:33:49  rrossmair
// header updated according to new policy: initial developers & contributors listed
//
// Revision 1.3  2004/04/06 04:55:17
// adapt compiler conditions, add log entry
//

end.

⌨️ 快捷键说明

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