How to capture sent items with Outlook addin across multiple accounts

Add-in Express™ Support Service
That's what is more important than anything else

How to capture sent items with Outlook addin across multiple accounts
 
Karim




Posts: 170
Joined: 2006-01-02
Hi,

With my Add ins i want catch event sent with count use.
how can capture sent event with Outlook addin across multiple accounts?
my code capture only my default count.




unit MyFirstAddIn_IMPL;

interface
uses
ComServ,Dialogs, adxAddIn, MyFirstAddIn_TLB, Classes, StdVcl,Outlook2000;
type
TMyAddIn = class(TadxAddin, IMyAddIn)
end;

TAddInModule = class(TadxCOMAddInModule)
procedure adxCOMAddInModuleAddInInitialize(Sender: TObject);
procedure adxCOMAddInModuleAddInFinalize(Sender: TObject);
private
FItems: TItems;
procedure DoItemAdd(ASender: TObject; const Item: IDispatch);
protected
public
end;

implementation

{$R *.dfm}

procedure TAddInModule.adxCOMAddInModuleAddInFinalize(Sender: TObject);
begin
if Assigned(FItems) then
FItems.Free;
end;

procedure TAddInModule.adxCOMAddInModuleAddInInitialize(Sender: TObject);
begin
FItems := TItems.Create(nil);
FItems.ConnectTo(OutlookApp.GetNamespace('MAPI').GetDefaultFolder(olFolderSentMail).Items);
FItems.OnItemAdd := DoItemAdd;
end;

procedure TAddInModule.DoItemAdd(ASender: TObject; const Item: IDispatch);
begin
showmessage('DoItemAdd');
end;

initialization
TadxFactory.Create(ComServer, TMyAddIn, CLASS_MyAddIn, TAddInModule);

end.


Thanks
Posted 19 Feb, 2015 09:04:10 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Karim,

You code intercept adding items to a given folder. If there are several accounts, the target folders may differ.
I would intercept the ItemSend event, see the Outlook Events component.

Or, you can use Namespace.Stores and Store.GetFolderFromId to find the Sent Items folders to which you can connect. These members are available since Outlook 2007-2010, see https://msdn.microsoft.com/en-us/library/office/ff864790%28v=office.15%29.aspx and https://msdn.microsoft.com/en-us/library/office/ff869924%28v=office.15%29.aspx.


Andrei Smolin
Add-in Express Team Leader
Posted 19 Feb, 2015 10:23:41 Top
Karim




Posts: 170
Joined: 2006-01-02
Hello Andrei,

I try something with my code but i have incompatible type when i use function connectTo.
Can help me please


unit MyFirstAddIn_IMPL;
interface
uses
ComServ,Dialogs, adxAddIn, MyFirstAddIn_TLB, Classes, StdVcl,outlook2000,Outlook2010,
adxHostAppEvents,Outlook_Tlb;

type
TMyAddIn = class(TadxAddin, IMyAddIn)
end;

TAddInModule = class(TadxCOMAddInModule)
adxOutlookAppEvents1: TadxOutlookAppEvents;
procedure adxCOMAddInModuleAddInFinalize(Sender: TObject);
procedure adxOutlookAppEvents1ItemSend(ASender: TObject;
const Item: IDispatch; var Cancel: WordBool);
private
FItems: TItems;
procedure DoItemAdd(ASender: TObject; const Item: IDispatch);
protected
public
end;

implementation

{$R *.dfm}

procedure TAddInModule.adxCOMAddInModuleAddInFinalize(Sender: TObject);
begin
if Assigned(FItems) then
FItems.Free;
end;

procedure TAddInModule.adxOutlookAppEvents1ItemSend(ASender: TObject;
const Item: IDispatch; var Cancel: WordBool);
var
ol2010: Outlook_Tlb._Application;
i: integer;
IMail: _MailItem;
Mail: TMailItem;
Inspector : outlook2000._Inspector;
objFolder : Outlook_Tlb.MAPIFolder;
objStore : Outlook_Tlb._store;
StoreFolder : String;

begin
Inspector := OutlookApp.ActiveInspector;
Inspector.CurrentItem.QueryInterface(IID__MailItem, IMail);
ol2010:= self.OutlookApp.Application as Outlook_Tlb._Application;
for i := 1 to ol2010.Session.Accounts.Count do begin
begin
if (IMail.SendUsingAccount.DisplayName = ol2010.Session.Accounts.Item(I).DisplayName) then
begin
StoreFolder := ol2010.Session.Accounts.Item(I).DisplayName;
break;
end;
end;
end;

objstore := ol2010.Session.Stores.Item(ol2010.Session.Accounts.Item(I).DisplayName);
objFolder := objstore.Session.GetDefaultFolder(olFolderSentMail);

FItems := TItems.Create(nil);
FItems.ConnectTo(objFolder.Items); // <--- ??? error incompatible type Outlook2000._Items and Outlook_TLB._Items
FItems.OnItemAdd := DoItemAdd;

end;

procedure TAddInModule.DoItemAdd(ASender: TObject; const Item: IDispatch);
begin
showmessage('DoItemAdd');
end;

initialization
TadxFactory.Create(ComServer, TMyAddIn, CLASS_MyAddIn, TAddInModule);

end.
Posted 20 Feb, 2015 04:28:11 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Karim,

Cast objFolder.Items to outlook2000._Items.


Andrei Smolin
Add-in Express Team Leader
Posted 20 Feb, 2015 04:42:50 Top
Karim




Posts: 170
Joined: 2006-01-02
Hi,

I try FItems.ConnectTo(outlook2000._Items(objFolder.Items)) and now my addins test works !!!

Thanks a lot for your support.
Posted 20 Feb, 2015 04:56:08 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
You are welcome!


Andrei Smolin
Add-in Express Team Leader
Posted 20 Feb, 2015 05:31:01 Top
Karim




Posts: 170
Joined: 2006-01-02
Hi Andrei,
Sorry, but my code not work :( because I still have the original problem with multiple accounts.
OnItemAdd catch only with default folder. I do not understand what's wrong



unit MyFirstAddIn_IMPL;
interface
uses
SysUtils,ComServ,Dialogs, adxAddIn, MyFirstAddIn_TLB, Classes, StdVcl,outlook2000,outlook2010,
adxHostAppEvents,Outlook_Tlb;

type
TMyAddIn = class(TadxAddin, IMyAddIn)
end;

TAddInModule = class(TadxCOMAddInModule)
adxOutlookAppEvents1: TadxOutlookAppEvents;
procedure adxCOMAddInModuleAddInFinalize(Sender: TObject);
procedure adxOutlookAppEvents1ItemSend(ASender: TObject;
const Item: IDispatch; var Cancel: WordBool);
private
FItems: TItems;
procedure DoItemAdd(ASender: TObject; const Item: IDispatch);
protected
public
end;

implementation

{$R *.dfm}

procedure TAddInModule.adxCOMAddInModuleAddInFinalize(Sender: TObject);
begin
if Assigned(FItems) then
FItems.Free;
end;

procedure TAddInModule.adxOutlookAppEvents1ItemSend(ASender: TObject;
const Item: IDispatch; var Cancel: WordBool);
var
ol2010: Outlook_Tlb._Application;
i: integer;
IMail: _MailItem;
Inspector : outlook2000._Inspector;
objFolder : Outlook_Tlb.MAPIFolder;
objStore : Outlook_Tlb._store;
StoreFolder : String;
begin

if Assigned(FItems) then
begin
FItems.OnItemAdd := nil;
FItems.Disconnect;
FreeAndNil(FItems);
end;

try
IMail := (Item as MailItem);
Inspector := OutlookApp.ActiveInspector;
Inspector.CurrentItem.QueryInterface(IID__MailItem, IMail);
ol2010:= self.OutlookApp.Application as Outlook_Tlb._Application;
for i := 1 to ol2010.Session.Accounts.Count do begin
begin
if (IMail.SendUsingAccount.DisplayName = ol2010.Session.Accounts.Item(I).DisplayName) then
begin
StoreFolder := ol2010.Session.Accounts.Item(I).DisplayName;
IMail.SendUsingAccount := ol2010.Session.Accounts.Item(I);
break;
end;
end;
end;
finally
IMail := nil;
end;

objStore := ol2010.Session.Stores.Item(StoreFolder);
objFolder := objstore.Session.GetDefaultFolder(olFolderSentMail);

FItems := TItems.Create(nil);
FItems.ConnectTo(outlook2000._Items(objFolder.Items));
FItems.OnItemAdd := DoItemAdd;

end;

procedure TAddInModule.DoItemAdd(ASender: TObject; const Item: IDispatch);
begin
showmessage('DoItemAdd');
end;

initialization
TadxFactory.Create(ComServer, TMyAddIn, CLASS_MyAddIn, TAddInModule);
end.
Posted 20 Feb, 2015 08:30:04 Top
Karim




Posts: 170
Joined: 2006-01-02
I found the solution !

in my code i replace :
objFolder := objstore.Session.GetDefaultFolder(olFolderSentMail);
by
objFolder := objStore.GetDefaultFolder(olFolderSentMail); //Version Added: Outlook 2010
Posted 20 Feb, 2015 09:29:32 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Karim,

Try getting the store using Account.DeliveryStore (OL2010+). Also note that MailItem.SendUsingAccount returns an Account object; you can use it directly, no loop required.

Also check if the folder full name is determined correctly.


Andrei Smolin
Add-in Express Team Leader
Posted 20 Feb, 2015 09:30:54 Top
Karim




Posts: 170
Joined: 2006-01-02
Hi Andrei,

I simplify my code and it works but i don't find how use Account.DeliveryStore

It's important ?


unit MyFirstAddIn_IMPL;
interface
uses
SysUtils,ComServ,Dialogs, adxAddIn, MyFirstAddIn_TLB, Classes, StdVcl,outlook2000,
adxHostAppEvents,Outlook_Tlb;

type
TMyAddIn = class(TadxAddin, IMyAddIn)
end;

TAddInModule = class(TadxCOMAddInModule)
adxOutlookAppEvents1: TadxOutlookAppEvents;
procedure adxCOMAddInModuleAddInFinalize(Sender: TObject);
procedure adxOutlookAppEvents1ItemSend(ASender: TObject;
const Item: IDispatch; var Cancel: WordBool);
private
FItems: TItems;
procedure DoItemAdd(ASender: TObject; const Item: IDispatch);
protected
public
end;

implementation

{$R *.dfm}

procedure TAddInModule.adxCOMAddInModuleAddInFinalize(Sender: TObject);
begin
if Assigned(FItems) then
FItems.Free;
end;

procedure TAddInModule.adxOutlookAppEvents1ItemSend(ASender: TObject;
const Item: IDispatch; var Cancel: WordBool);
var
ol2010: Outlook_Tlb._Application;
i: integer;
IMail: _MailItem;
Inspector : outlook2000._Inspector;
objFolder : Outlook_Tlb.MAPIFolder;
objStore : Outlook_Tlb._store;
objAccount : Outlook_Tlb._Account;
strStoreName : String;
begin

if Assigned(FItems) then
begin
FItems.OnItemAdd := nil;
FItems.Disconnect;
FreeAndNil(FItems);
end;

try
IMail := (Item as MailItem);
Inspector := OutlookApp.ActiveInspector;
Inspector.CurrentItem.QueryInterface(IID__MailItem, IMail);
ol2010:= self.OutlookApp.Application as Outlook_Tlb._Application;

strStoreName := IMail.SendUsingAccount.DisplayName;

finally
IMail := nil;
end;


objStore := ol2010.Session.Stores.Item(strStoreName);
objFolder := objStore.GetDefaultFolder(olFolderSentMail); //Version Added: Outlook 2010

FItems := TItems.Create(nil);
FItems.ConnectTo(outlook2000._Items(objFolder.Items));
FItems.OnItemAdd := DoItemAdd;

end;

procedure TAddInModule.DoItemAdd(ASender: TObject; const Item: IDispatch);
begin
showmessage('DoItemAdd');
end;

initialization
TadxFactory.Create(ComServer, TMyAddIn, CLASS_MyAddIn, TAddInModule);
end.
Posted 20 Feb, 2015 11:17:06 Top