Бесплатный Mailitem в Delphi
У меня есть Mailitem и я отвечаю на это. Теперь я регистрирую OnSend EventHandler и отображаю элемент с модальным значением FALSE. Все работает как хотелось. Моя проблема в том, что я не знаю, как освободить 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 ответ
Вы можете использовать контейнер глобальных объектов для этой цели: 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;