我在测试Delphi 2006 BDS应用程序中有以下代码:
procedure TForm1.Button1Click(Sender: TObject);
const
olMailItem = 0;
var
Outlook: OleVariant;
vMailItem: variant;
begin
Outlook := CreateOleObject('Outlook.Application');
vMailItem := Outlook.CreateItem(olMailItem);
try
vMailItem.Recipients.add('anemailaddress@gmail.com');
vMailItem.Display(True); -- outlook mail message is displayed modally
except
end;
VarClear(Outlook);
end;
我需要能够检测用户是否在Outlook屏幕中发送了电子邮件。我尝试了以下代码:
if vMailItem.Sent then
...
但收到错误消息'项目已被移动或删除'。我认为这是因为邮件项已移至已发送邮件文件夹。检测用户是否发送电子邮件的最佳方法是什么?此外,如果用户确实发送了电子邮件,那么我还需要能够查看电子邮件正文。
提前致谢。
答案 0 :(得分:3)
看起来你必须使用邮件项目的Send Event
。如果你使用早期绑定,将'outlook [*]。pas'文件中的一个放在'uses'子句中RAD Studio的'.. \ OCX \ Servers'文件夹中,那么这将更加容易,然后:< / p>
uses
..., outlook2000;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
OutlookApplication: TOutlookApplication;
procedure OnMailSend(Sender: TObject; var Cancel: WordBool);
public
end;
[...]
procedure TForm1.FormCreate(Sender: TObject);
begin
OutlookApplication := TOutlookApplication.Create(Self);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
MailItem: _MailItem;
Mail: TMailItem;
begin
MailItem := OutlookApplication.CreateItem(olMailItem) as _MailItem;
Mail := TMailItem.Create(nil);
try
Mail.ConnectTo(MailItem);
Mail.OnSend := OnMailSend;
MailItem.Recipients.Add('username@example.com');
MailItem.Display(True);
finally
Mail.Free;
end;
end;
procedure TForm1.OnMailSend(Sender: TObject; var Cancel: WordBool);
begin
ShowMessage((Sender as TMailItem).Body);
end;
使用后期绑定,您必须完成导入包装器所做的一些工作。最简单的例子可能是这样的:
type
TForm1 = class(TForm, IDispatch)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
FCookie: Integer;
FMailItem: OleVariant;
procedure MailSent;
protected
function QueryInterface(const IID: TGUID; out Obj): HResult; override;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
stdcall;
public
end;
[...]
uses
comobj;
const
DIID_ItemEvents: TGUID = '{0006303A-0000-0000-C000-000000000046}';
SendItemDispID = 61445;
function TForm1.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if IsEqualIID(IID, DIID_ItemEvents) and GetInterface(IDispatch, Obj) then
Result := S_OK
else
Result := inherited QueryInterface(IID, Obj);
end;
function TForm1.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
begin
Result := S_OK;
if DispID = SendItemDispID then
MailSent;
end;
procedure TForm1.Button1Click(Sender: TObject);
const
olMailItem = 0;
var
Outlook: OleVariant;
CPContainer: IConnectionPointContainer;
ConnectionPoint: IConnectionPoint;
begin
Outlook := CreateOleObject('Outlook.Application');
FMailItem := Outlook.CreateItem(olMailItem);
FMailItem.Recipients.add('username@example.com');
if Supports(FMailItem, IConnectionPointContainer, CPContainer) then begin
CPContainer.FindConnectionPoint(DIID_ItemEvents, ConnectionPoint);
if Assigned(ConnectionPoint) then
ConnectionPoint.Advise(Self, FCookie);
CPContainer := nil;
end;
FMailItem.Display(True);
if Assigned(ConnectionPoint) then begin
ConnectionPoint.Unadvise(FCookie);
ConnectionPoint := nil;
end;
VarClear(FMailItem);
VarClear(Outlook);
end;
procedure TForm1.MailSent;
begin
ShowMessage(FMailItem.Body);
end;
答案 1 :(得分:0)
我使用VBA提出了解决问题第一部分的解决方案。它基本上依赖于错误处理来确定是否发送了电子邮件。
Public Sub SendEmail()
On Error GoTo ErrorHandler
Dim objOutlook As Outlook.Application
Dim objMailItem As Outlook.MailItem
Do
Set objOutlook = New Outlook.Application
Set objMailItem = objOutlook.CreateItem(olMailItem)
With objMailItem
.BodyFormat = olFormatHTML
.To = "test@email.com"
.Subject = "Test"
.HTMLBody = "<html><body>Test</body></html>"
.Display True
If .Saved Then
MsgBox "Your email was saved, but not sent. Please click OK and then click the Send " & _
"button once the email is displayed. You can delete the saved email from your " & _
"Drafts folder at a later time.", vbOKOnly, "Error"
Else
MsgBox "Your email was not sent. Please click OK and then click the Send " & _
"button once the email is displayed.", vbOKOnly, "Error"
End If
End With
Loop While Not objMailItem.Sent
Set objMailItem = Nothing
Set objOutlook = Nothing
Exit Sub
ErrorHandler:
Select Case Err.DESCRIPTION
Case "The item has been moved or deleted.":
' The email was sent, so it's no longer available, just clean up and exit.
Set objMailItem = Nothing
Set objOutlook = Nothing
Case Else
With Err
.Raise .Number, .Source, .DESCRIPTION, .HelpFile, .HelpContext
End With
End Select
End Sub