Delphi中的免费Mailitem

时间:2014-06-10 12:58:29

标签: delphi outlook-addin pascal

我有一个Mailitem并为此做出回复。 现在我注册一个OnSend EventHandler并以模态FALSE显示Item。 一切都按预期工作。 我的问题是我不知道如何释放MailItem。 如果我显示Item模态,我可以在函数末尾的finally块中释放它, 但如果我显示Item非模态,我的eventhanlder(AOnSend)显然永远不会被调用,因为带有已注册处理程序的mailitem将被丢弃。 但是简单地不调用MailItem.Free会产生Mem-Leak,所以我的问题:如何正确释放这个MailItem?

function InternalReply(AFolder, AMailID, ASender, ACC: String; AWithoutTo: TList<String>; AModal: Boolean; AOnSend: TMailItemSend; var AErrorText: String; AReplyAll: Boolean = FALSE): Boolean; overload;
var AOutlookApplication: TOutlookApplication;
    ANewInstance: Boolean;
    AMAPIFolder: MAPIFolder;
    AMailItem: MailItem;
    AMail: TMailItem;
begin
  AErrorText := '';
  AOutlookApplication := Nil;
  AMailItem := Nil;
  AMail := TMailItem.Create(Nil);
  try
    try
      Result := OpenOutlookInstance(AOutlookApplication, ANewInstance, AErrorText);
      if Result then begin
        AMAPIFolder := IntGetFolderByName(AOutlookApplication, UpperCase(AFolder), AErrorText);
        if Assigned(AMAPIFolder) then begin
          Result := IntGetMailFromMAPIFolderByID(AOutlookApplication, AMAPIFolder, AMailID, AMailItem, AErrorText);
          if Result and Assigned(AMailItem) then begin
            AMailItem := AMailItem.ReplyAll;
            if Assigned(AOnSend) then begin
              AMail.ConnectTo(AMailItem);
              AMail.OnSend := AOnSend;
            end;

            if Assigned(AMailItem) then begin
              ...
              AMailItem.Display(AModal);
            end
            else begin
              Result := TRUE;
            end;
          end
          else begin
            Result := FALSE;
            AErrorText := AErrorText + ' Mail not found! MailID: ' + AMailID;
          end;
        end
        else begin
          Result := FALSE;
          AErrorText := AErrorText + ' Folder not found! Name: ' + AFolder;
        end;
        CloseOutlookInstance(AOutlookApplication, ANewInstance, AErrorText);
      end;
    except
      on E: Exception do begin
        Result := FALSE;
        AErrorText := AErrorText + ' ' + 'Reply: Internal Error! Message: ' + E.Message;
      end;
    end;
  finally
    AMail.Free // IF I DO THIS THEN I LOSE MY HANDLER
  end;
end;

1 个答案:

答案 0 :(得分:0)

您可以为此目的使用全局对象容器:TObjectList

创建新邮件时,将其添加到容器中。 在OnSend事件处理程序中,您可以从容器中删除邮件。 如果您这样工作,您可以同时打开多个邮件:

uses
  Contnrs,
...

var 
  Mails : TObjectList;
...

// create the container at application startup
// do not forget to free the container at application termination
 Mails := TObjectList.Create; 

...

// create mail
function InternalReply()
...
 if Assigned(AOnSend) then begin
  AMail.ConnectTo(AMailItem);
  AMail.OnSend := AOnSend;
  // add it to the container
  Mails.Add(AMail); 
 end;
...
end;

// in your OnSend handler, remove mail from the list
// this will automatically free the mail
procedure AOnSend(Sender: TObject; var Cancel: WordBool);
begin
 ... 
 Mails.Remove(Sender); // sender is our Mail object
end;